[igt-dev] [PATCH i-g-t 3/4] tests/gem_media_vme: Simple test to exercise the VME block

Chris Wilson chris at chris-wilson.co.uk
Tue Jan 8 14:23:24 UTC 2019


Quoting Tvrtko Ursulin (2019-01-08 11:24:49)
> From: Tony Ye <tony.ye at intel.com>
> 
> Simple test which exercises the VME fixed function block.
> 
> v2: (Tvrtko Ursulin)
>  * Small cleanups like copyright date, tabs, remove unused bits.
> 
> v3: (Tony Ye)
>  * Added curbe data entry for dst surface.
>  * Read the dst surface after the VME kernel being executed.
> 
> v4: (Tony Ye)
>  * Added the media_vme.gxa kernel source code and compile instructions.
> 
> v5: (Tvrtko Ursulin)
>  * Added hang detector.
> 
> Signed-off-by: Tony Ye <tony.ye at intel.com>
> Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin at intel.com>
> Cc: Tony Ye <tony.ye at intel.com>
> ---
>  lib/gpu_cmds.c                              | 136 ++++++++++++++++++++
>  lib/gpu_cmds.h                              |  20 ++-
>  lib/i915/shaders/media/README_media_vme.txt |  65 ++++++++++
>  lib/i915/shaders/media/media_vme.gxa        |  51 ++++++++
>  lib/intel_batchbuffer.c                     |   9 ++
>  lib/intel_batchbuffer.h                     |   7 +
>  lib/media_fill.c                            | 110 ++++++++++++++++
>  lib/media_fill.h                            |   6 +
>  lib/surfaceformat.h                         |   2 +
>  tests/Makefile.sources                      |   3 +
>  tests/i915/gem_media_vme.c                  | 118 +++++++++++++++++
>  tests/meson.build                           |   1 +
>  12 files changed, 526 insertions(+), 2 deletions(-)
>  create mode 100755 lib/i915/shaders/media/README_media_vme.txt
>  create mode 100755 lib/i915/shaders/media/media_vme.gxa
>  create mode 100644 tests/i915/gem_media_vme.c
> 
> diff --git a/lib/gpu_cmds.c b/lib/gpu_cmds.c
> index 556a94c6f0b6..b490a63bdfef 100644
> --- a/lib/gpu_cmds.c
> +++ b/lib/gpu_cmds.c
> @@ -52,6 +52,22 @@ gen7_fill_curbe_buffer_data(struct intel_batchbuffer *batch,
>         return offset;
>  }
>  
> +uint32_t
> +gen11_fill_curbe_buffer_data(struct intel_batchbuffer *batch)
> +{
> +       uint32_t *curbe_buffer;
> +       uint32_t offset;
> +
> +       curbe_buffer = intel_batchbuffer_subdata_alloc(batch,
> +                                                      sizeof(uint32_t) * 8,
> +                                                      64);
> +       offset = intel_batchbuffer_subdata_offset(batch, curbe_buffer);
> +       *curbe_buffer++ = 0;
> +       *curbe_buffer   = 1;
> +
> +       return offset;
> +}
> +
>  uint32_t
>  gen7_fill_surface_state(struct intel_batchbuffer *batch,
>                         const struct igt_buf *buf,
> @@ -119,6 +135,26 @@ gen7_fill_binding_table(struct intel_batchbuffer *batch,
>         return offset;
>  }
>  
> +uint32_t
> +gen11_fill_binding_table(struct intel_batchbuffer *batch,
> +                       const struct igt_buf *src,const struct igt_buf *dst)
> +{
> +       uint32_t *binding_table, offset;
> +
> +       binding_table = intel_batchbuffer_subdata_alloc(batch, 64, 64);
> +       offset = intel_batchbuffer_subdata_offset(batch, binding_table);
> +       binding_table[0] = gen11_fill_surface_state(batch, src,
> +                                               SURFACE_1D,SURFACEFORMAT_R32G32B32A32_FLOAT,
> +                                               0,0,
> +                                               0);
> +       binding_table[1] = gen11_fill_surface_state(batch, dst,
> +                                               SURFACE_BUFFER, SURFACEFORMAT_RAW,
> +                                               1,1,
> +                                               1);
> +
> +       return offset;
> +}
> +
>  uint32_t
>  gen7_fill_kernel(struct intel_batchbuffer *batch,
>                 const uint32_t kernel[][4],
> @@ -384,6 +420,71 @@ gen8_fill_surface_state(struct intel_batchbuffer *batch,
>         return offset;
>  }
>  
> +uint32_t
> +gen11_fill_surface_state(struct intel_batchbuffer *batch,
> +                       const struct igt_buf *buf,
> +                       uint32_t surface_type,
> +                       uint32_t format,
> +                       uint32_t vertical_alignment,
> +                       uint32_t horizontal_alignment,
> +                       int is_dst)
> +{
> +       struct gen8_surface_state *ss;
> +       uint32_t write_domain, read_domain, offset;
> +       int ret;
> +
> +       if (is_dst) {
> +               write_domain = read_domain = I915_GEM_DOMAIN_RENDER;
> +       } else {
> +               write_domain = 0;
> +               read_domain = I915_GEM_DOMAIN_SAMPLER;
> +       }
> +
> +       ss = intel_batchbuffer_subdata_alloc(batch, sizeof(*ss), 64);
> +       offset = intel_batchbuffer_subdata_offset(batch, ss);
> +
> +       ss->ss0.surface_type = surface_type;
> +       ss->ss0.surface_format = format;
> +       ss->ss0.render_cache_read_write = 1;
> +       ss->ss0.vertical_alignment = vertical_alignment; /* align 4 */
> +       ss->ss0.horizontal_alignment = horizontal_alignment; /* align 4 */
> +
> +       if (buf->tiling == I915_TILING_X)
> +               ss->ss0.tiled_mode = 2;
> +       else if (buf->tiling == I915_TILING_Y)
> +               ss->ss0.tiled_mode = 3;
> +       else
> +               ss->ss0.tiled_mode = 0;
> +
> +       ss->ss8.base_addr = buf->bo->offset;
> +
> +       ret = drm_intel_bo_emit_reloc(batch->bo,
> +                               intel_batchbuffer_subdata_offset(batch, ss) + 8 * 4,
> +                               buf->bo, 0, read_domain, write_domain);
> +       igt_assert(ret == 0);
> +
> +       if (is_dst) {
> +               ss->ss1.memory_object_control = 2;
> +               ss->ss2.height = 1;
> +               ss->ss2.width  = 95;
> +               ss->ss3.pitch  = 0;
> +               ss->ss7.shader_chanel_select_r = 4;
> +               ss->ss7.shader_chanel_select_g = 5;
> +               ss->ss7.shader_chanel_select_b = 6;
> +               ss->ss7.shader_chanel_select_a = 7;
> +       }
> +       else {
> +               ss->ss1.qpitch = 4040;
> +               ss->ss1.base_mip_level = 31;
> +               ss->ss2.height = 9216;
> +               ss->ss2.width  = 1019;
> +               ss->ss3.pitch  = 64;
> +               ss->ss5.mip_count = 2;
> +       }
> +
> +       return offset;
> +}
> +
>  uint32_t
>  gen8_fill_interface_descriptor(struct intel_batchbuffer *batch,
>                                const struct igt_buf *dst,
> @@ -419,6 +520,41 @@ gen8_fill_interface_descriptor(struct intel_batchbuffer *batch,
>         return offset;
>  }
>  
> +uint32_t
> +gen11_fill_interface_descriptor(struct intel_batchbuffer *batch,
> +                              const struct igt_buf *src,const struct igt_buf *dst,
> +                              const uint32_t kernel[][4],
> +                              size_t size)
> +{
> +       struct gen8_interface_descriptor_data *idd;
> +       uint32_t offset;
> +       uint32_t binding_table_offset, kernel_offset;
> +
> +       binding_table_offset = gen11_fill_binding_table(batch, src,dst);
> +       kernel_offset = gen7_fill_kernel(batch, kernel, size);
> +
> +       idd = intel_batchbuffer_subdata_alloc(batch, sizeof(*idd), 64);
> +       offset = intel_batchbuffer_subdata_offset(batch, idd);
> +
> +       idd->desc0.kernel_start_pointer = (kernel_offset >> 6);
> +
> +       idd->desc2.single_program_flow = 1;
> +       idd->desc2.floating_point_mode = GEN8_FLOATING_POINT_IEEE_754;
> +
> +       idd->desc3.sampler_count = 0;      /* 0 samplers used */
> +       idd->desc3.sampler_state_pointer = 0;
> +
> +       idd->desc4.binding_table_entry_count = 0;
> +       idd->desc4.binding_table_pointer = (binding_table_offset >> 5);
> +
> +       idd->desc5.constant_urb_entry_read_offset = 0;
> +       idd->desc5.constant_urb_entry_read_length = 1; /* grf 1 */
> +
> +       idd->desc6.num_threads_in_tg = 1;
> +
> +       return offset;
> +}
> +
>  void
>  gen8_emit_state_base_address(struct intel_batchbuffer *batch)
>  {
> diff --git a/lib/gpu_cmds.h b/lib/gpu_cmds.h
> index 79bc4d6473ba..ca671fb52daf 100644
> --- a/lib/gpu_cmds.h
> +++ b/lib/gpu_cmds.h
> @@ -43,6 +43,8 @@ gen7_render_flush(struct intel_batchbuffer *batch, uint32_t batch_end);
>  uint32_t
>  gen7_fill_curbe_buffer_data(struct intel_batchbuffer *batch,
>                         uint8_t color);
> +uint32_t
> +gen11_fill_curbe_buffer_data(struct intel_batchbuffer *batch);
>  
>  uint32_t
>  gen7_fill_surface_state(struct intel_batchbuffer *batch,
> @@ -53,6 +55,9 @@ gen7_fill_surface_state(struct intel_batchbuffer *batch,
>  uint32_t
>  gen7_fill_binding_table(struct intel_batchbuffer *batch,
>                         const struct igt_buf *dst);
> +uint32_t
> +gen11_fill_binding_table(struct intel_batchbuffer *batch,
> +                       const struct igt_buf *src,const struct igt_buf *dst);
>  
>  uint32_t
>  gen7_fill_kernel(struct intel_batchbuffer *batch,
> @@ -99,13 +104,24 @@ gen8_fill_surface_state(struct intel_batchbuffer *batch,
>                         const struct igt_buf *buf,
>                         uint32_t format,
>                         int is_dst);
> -
> +uint32_t
> +gen11_fill_surface_state(struct intel_batchbuffer *batch,
> +                       const struct igt_buf *buf,
> +                       uint32_t surface_type,
> +                       uint32_t format,
> +                       uint32_t vertical_alignment,
> +                       uint32_t horizontal_alignment,
> +                       int is_dst);
>  uint32_t
>  gen8_fill_interface_descriptor(struct intel_batchbuffer *batch,
>                                const struct igt_buf *dst,
>                                const uint32_t kernel[][4],
>                                size_t size);
> -
> +uint32_t
> +gen11_fill_interface_descriptor(struct intel_batchbuffer *batch,
> +                              const struct igt_buf *src,const struct igt_buf *dst,
> +                              const uint32_t kernel[][4],
> +                              size_t size);
>  void
>  gen8_emit_state_base_address(struct intel_batchbuffer *batch);
>  
> diff --git a/lib/i915/shaders/media/README_media_vme.txt b/lib/i915/shaders/media/README_media_vme.txt
> new file mode 100755
> index 000000000000..2470fdd89825
> --- /dev/null
> +++ b/lib/i915/shaders/media/README_media_vme.txt
> @@ -0,0 +1,65 @@
> +Step1: Building IGA (Intel Graphics Assembler)
> +========================================================================
> +
> +1. Download or clone IGC (Intel Graphics Compiler)
> +
> +   https://github.com/intel/intel-graphics-compiler.git
> +
> +2. Chdir into 'intel-graphics-compiler' (or any other workspace folder of choice)
> +
> +   It should read the following folder strucutre:
> +
> +   workspace
> +      |- visa
> +      |- IGC
> +      |- inc
> +      |- 3d
> +      |- skuwa
> +
> +3. Chdir into IGA sub-component
> +
> +   cd visa/iga
> +
> +4. Create build directory
> +
> +    mkdir build
> +
> +5. Change into build directory
> +
> +    cd build
> +
> +6. Run cmake
> +
> +   cmake ../
> +
> +7. Run make to build IGA project
> +
> +   make
> +
> +8. Get the output executable "iga64" in IGAExe folder
> +
> +   usage: ./iga64 OPTIONS ARGS
> +   where OPTIONS:
> +     -h     --help                     shows help on an option
> +     -d     --disassemble              disassembles the input file
> +     -a     --assemble                 assembles the input file
> +     -n     --numeric-labels           use numeric labels
> +     -p     --platform        DEVICE   specifies the platform (e.g. "GEN9")
> +     -o     --output          FILE     specifies the output file
> +
> +   EXAMPLES:
> +   ./iga64  file.gxa  -p=11 -a  -o file.krn
> +
> +Step2: Building ASM code
> +========================================================================
> +1. Command line to convert asm code to binary:
> +
> +   iga64 media_vme.gxa -p=11 -a -o media_vme.krn
> +
> +2. Pad 128 bytes zeros to the kernel:
> +
> +   dd if=/dev/zero bs=1 count=128 >> media_vme.krn
> +
> +3. Generate hexdump:
> +
> +   hexdump -v  -e '4/4 "0x%08x " "\n"' media_vme.krn > media_vme.hex
> diff --git a/lib/i915/shaders/media/media_vme.gxa b/lib/i915/shaders/media/media_vme.gxa
> new file mode 100755
> index 000000000000..93a0ed2f12d6
> --- /dev/null
> +++ b/lib/i915/shaders/media/media_vme.gxa
> @@ -0,0 +1,51 @@
> +/*
> +* Copyright (c) 2018, Intel Corporation
> +*
> +* Permission is hereby granted, free of charge, to any person obtaining a
> +* copy of this software and associated documentation files (the "Software"),
> +* to deal in the Software without restriction, including without limitation
> +* the rights to use, copy, modify, merge, publish, distribute, sublicense,
> +* and/or sell copies of the Software, and to permit persons to whom the
> +* Software is furnished to do so, subject to the following conditions:
> +*
> +* The above copyright notice and this permission notice shall be included
> +* in all copies or substantial portions of the Software.
> +*
> +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
> +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> +* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
> +* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
> +* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
> +* OTHER DEALINGS IN THE SOFTWARE.
> +*/
> +
> +       mov (8|M0)       r1.8<1>:w       0x20000000:v
> +       mov (8|M0)       r20.0<1>:w      0x1:v
> +(W)    mov (1|M0)       r1.2<1>:f       0x3818000C:f
> +       mov (8|M0)       r20.8<1>:w      0x10:v
> +       mov (8|M0)       r21.0<1>:w      0x10000:v
> +(W)    mov (1|M0)       r1.3<1>:f       0x22222222:f
> +       add (1|M0)       a0.0<1>:d       r1.0<0;1,0>:d     276307968:d
> +       mov (8|M0)       r2.0<1>:f       0x0:f
> +       mov (8|M0)       r5.0<1>:f       0x0:f
> +       mov (8|M0)       r6.0<1>:f       0x0:f
> +       mov (8|M0)       r9.0<1>:f       0x0:f
> +       mov (8|M0)       r3.0<1>:d       r1.8<8;8,1>:w
> +       mul (8|M0)       r4.0<1>:d       r1.2<0;1,0>:d     r20.0<8;8,1>:w
> +       mul (8|M0)       r7.0<1>:d       r20.8<8;8,1>:w    256:w
> +       mul (8|M0)       r8.0<1>:d       r1.3<0;1,0>:d     r21.0<8;8,1>:w
> +(W)    mov (1|M0)       r17.2<1>:f      0x0:f
> +       send (16|M0)     r10:uw          r2:f              0xD     a0.0{NoPreempt}
> +       mov (1|M0)       r10.14<1>:hf    0xBEEF:hf
> +(W)    add (1|M0)       a0.0<1>:ud      r1.1<0;1,0>:ud    0x20A0400:ud
> +       mov (1|M0)       r10.15<1>:hf    0xDEAD:hf
> +(W)    mov (1|M0)       r18.2<1>:f      0x8:f
> +(W)    mov (1|M0)       r19.2<1>:f      0xC:f
> +(W)    mov (8|M0)       r127.0<1>:f     r0.0<8;8,1>:f
> +(W)    sends (16|M0)    null:uw         r17               r10     0x10A    a0.0
> +(W)    add (1|M0)       a0.0<1>:ud      r1.1<0;1,0>:ud    0x20A0300:ud
> +(W)    sends (16|M0)    null:uw         r18               r14     0x8A     a0.0
> +(W)    add (1|M0)       a0.0<1>:ud      r1.1<0;1,0>:ud    0x20A0200:ud
> +(W)    sends (8|M0)     null:ud         r19               r16     0x4A     a0.0
> +(W)    send (8|M0)      null            r127:f            0x27    0x2000010 {EOT}
> diff --git a/lib/intel_batchbuffer.c b/lib/intel_batchbuffer.c
> index ad2e718f898c..22697c94fb13 100644
> --- a/lib/intel_batchbuffer.c
> +++ b/lib/intel_batchbuffer.c
> @@ -873,6 +873,15 @@ igt_fillfunc_t igt_get_media_fillfunc(int devid)
>         return fill;
>  }
>  
> +igt_vme_func_t igt_get_media_vme_func(int devid)
> +{
> +       igt_vme_func_t fill = NULL;
> +
> +       if (IS_GEN9(devid) || IS_GEN10(devid) || IS_GEN11(devid))
> +               fill = gen11_media_vme_func;
> +
> +       return fill;
> +}
>  /**
>   * igt_get_gpgpu_fillfunc:
>   * @devid: pci device id
> diff --git a/lib/intel_batchbuffer.h b/lib/intel_batchbuffer.h
> index ecc23f08da77..e5f6e6d045b8 100644
> --- a/lib/intel_batchbuffer.h
> +++ b/lib/intel_batchbuffer.h
> @@ -325,6 +325,13 @@ typedef void (*igt_fillfunc_t)(struct intel_batchbuffer *batch,
>  igt_fillfunc_t igt_get_media_fillfunc(int devid);
>  igt_fillfunc_t igt_get_gpgpu_fillfunc(int devid);
>  
> +typedef void (*igt_vme_func_t)(struct intel_batchbuffer *batch,
> +                              const struct igt_buf *src,
> +                              unsigned int width, unsigned int height,
> +                              const struct igt_buf *dst);
> +
> +igt_vme_func_t igt_get_media_vme_func(int devid);
> +
>  /**
>   * igt_media_spinfunc_t:
>   * @batch: batchbuffer object
> diff --git a/lib/media_fill.c b/lib/media_fill.c
> index 4942229505ff..b1e84727394a 100644
> --- a/lib/media_fill.c
> +++ b/lib/media_fill.c
> @@ -61,6 +61,46 @@ static const uint32_t gen8_media_kernel[][4] = {
>         { 0x07800031, 0x20000a40, 0x0e000e00, 0x82000010 },
>  };
>  
> +static const uint32_t gen11_media_vme_kernel[][4] = {
> +       { 0x00600001, 0x20302e68,  0x00000000,  0x20000000 },
> +       { 0x00600001, 0x22802e68,  0x00000000,  0x00000001 },
> +       { 0x00000001, 0x20284f2c,  0x00000000,  0x3818000c },
> +       { 0x00600001, 0x22902e68,  0x00000000,  0x00000010 },
> +       { 0x00600001, 0x22a02e68,  0x00000000,  0x00010000 },
> +       { 0x00000001, 0x202c4f2c,  0x00000000,  0x22222222 },
> +       { 0x00000040, 0x22000a20,  0x0e000020,  0x10782000 },
> +       { 0x00600001, 0x20404f28,  0x00000000,  0x00000000 },
> +       { 0x00600001, 0x20a04f28,  0x00000000,  0x00000000 },
> +       { 0x00600001, 0x20c04f28,  0x00000000,  0x00000000 },
> +       { 0x00600001, 0x21204f28,  0x00000000,  0x00000000 },
> +       { 0x00600001, 0x20601a28,  0x008d0030,  0x00000000 },
> +       { 0x00600041, 0x20800a28,  0x1a000028,  0x008d0280 },
> +       { 0x00600041, 0x20e01a28,  0x1e8d0290,  0x01000100 },
> +       { 0x00600041, 0x21000a28,  0x1a00002c,  0x008d02a0 },
> +       { 0x00000001, 0x22284f2c,  0x00000000,  0x00000000 },
> +       { 0x0d80c031, 0x21404a48,  0x00000040,  0x00000200 },
> +       { 0x00000001, 0x215c4708,  0x00000000,  0xbeefbeef },
> +       { 0x00000040, 0x22000204,  0x06000024,  0x020a0400 },
> +       { 0x00000001, 0x215e4708,  0x00000000,  0xdeaddead },
> +       { 0x00000001, 0x22484f2c,  0x00000000,  0x00000008 },
> +       { 0x00000001, 0x22684f2c,  0x00000000,  0x0000000c },
> +       { 0x00600001, 0x2fe04b2c,  0x008d0000,  0x00000000 },
> +       { 0x0a800033, 0x0000a054,  0x00002224,  0x00000000 },
> +       { 0x00000040, 0x22000204,  0x06000024,  0x020a0300 },
> +       { 0x0a800033, 0x0000e054,  0x00002242,  0x00000000 },
> +       { 0x00000040, 0x22000204,  0x06000024,  0x020a0200 },
> +       { 0x0a600033, 0x00010014,  0x00002261,  0x00000000 },
> +       { 0x07600031, 0x20004a04,  0x06000fe0,  0x82000010 },
> +       { 0x00000000, 0x00000000,  0x00000000,  0x00000000 },
> +       { 0x00000000, 0x00000000,  0x00000000,  0x00000000 },
> +       { 0x00000000, 0x00000000,  0x00000000,  0x00000000 },
> +       { 0x00000000, 0x00000000,  0x00000000,  0x00000000 },
> +       { 0x00000000, 0x00000000,  0x00000000,  0x00000000 },
> +       { 0x00000000, 0x00000000,  0x00000000,  0x00000000 },
> +       { 0x00000000, 0x00000000,  0x00000000,  0x00000000 },
> +       { 0x00000000, 0x00000000,  0x00000000,  0x00000000 },
> +};
> +
>  /*
>   * This sets up the media pipeline,
>   *
> @@ -245,3 +285,73 @@ gen9_media_fillfunc(struct intel_batchbuffer *batch,
>                               gen8_media_kernel, sizeof(gen8_media_kernel));
>  
>  }
> +
> +static void
> +__gen11_media_vme_func(struct intel_batchbuffer *batch,
> +                      const struct igt_buf *src,
> +                      unsigned int width, unsigned int height,
> +                      const struct igt_buf *dst,
> +                      const uint32_t kernel[][4],
> +                      size_t kernel_size)
> +{
> +       uint32_t curbe_buffer, interface_descriptor;
> +       uint32_t batch_end;
> +
> +       intel_batchbuffer_flush(batch);
> +
> +       /* setup states */
> +       batch->ptr = &batch->buffer[BATCH_STATE_SPLIT];
> +
> +       curbe_buffer = gen11_fill_curbe_buffer_data(batch);
> +       interface_descriptor = gen11_fill_interface_descriptor(batch, src, dst,
> +                                       kernel, kernel_size);
> +       assert(batch->ptr < &batch->buffer[4095]);
> +
> +       /* media pipeline */
> +       batch->ptr = batch->buffer;
> +       OUT_BATCH(GEN8_PIPELINE_SELECT | PIPELINE_SELECT_MEDIA |
> +                 GEN9_FORCE_MEDIA_AWAKE_ENABLE |
> +                 GEN9_SAMPLER_DOP_GATE_DISABLE |
> +                 GEN9_PIPELINE_SELECTION_MASK |
> +                 GEN9_SAMPLER_DOP_GATE_MASK |
> +                 GEN9_FORCE_MEDIA_AWAKE_MASK);
> +       gen9_emit_state_base_address(batch);
> +
> +       gen8_emit_vfe_state(batch, THREADS, MEDIA_URB_ENTRIES, MEDIA_URB_SIZE,
> +                           MEDIA_CURBE_SIZE);
> +
> +       gen7_emit_curbe_load(batch, curbe_buffer);
> +
> +       gen7_emit_interface_descriptor_load(batch, interface_descriptor);
> +
> +       gen7_emit_media_objects(batch, 0, 0, width, height);
> +
> +       OUT_BATCH(GEN8_PIPELINE_SELECT | PIPELINE_SELECT_MEDIA |
> +                 GEN9_FORCE_MEDIA_AWAKE_DISABLE |
> +                 GEN9_SAMPLER_DOP_GATE_ENABLE |
> +                 GEN9_PIPELINE_SELECTION_MASK |
> +                 GEN9_SAMPLER_DOP_GATE_MASK |
> +                 GEN9_FORCE_MEDIA_AWAKE_MASK);
> +
> +       OUT_BATCH(MI_BATCH_BUFFER_END);
> +
> +       batch_end = intel_batchbuffer_align(batch, 8);
> +       assert(batch_end < BATCH_STATE_SPLIT);
> +
> +       gen7_render_flush(batch, batch_end);
> +       intel_batchbuffer_reset(batch);
> +}
> +
> +void
> +gen11_media_vme_func(struct intel_batchbuffer *batch,
> +                    const struct igt_buf *src,
> +                    unsigned int width, unsigned int height,
> +                    const struct igt_buf *dst)
> +{
> +       __gen11_media_vme_func(batch,
> +                              src,
> +                              width, height,
> +                              dst,
> +                              gen11_media_vme_kernel,
> +                              sizeof(gen11_media_vme_kernel));
> +}
> diff --git a/lib/media_fill.h b/lib/media_fill.h
> index e365da9e47d2..1d5c5fa826a3 100644
> --- a/lib/media_fill.h
> +++ b/lib/media_fill.h
> @@ -49,4 +49,10 @@ gen9_media_fillfunc(struct intel_batchbuffer *batch,
>                     unsigned int width, unsigned int height,
>                     uint8_t color);
>  
> +void
> +gen11_media_vme_func(struct intel_batchbuffer *batch,
> +                    const struct igt_buf *src,
> +                    unsigned int width, unsigned int height,
> +                    const struct igt_buf *dst);
> +
>  #endif /* RENDE_MEDIA_FILL_H */
> diff --git a/lib/surfaceformat.h b/lib/surfaceformat.h
> index 5d7ed2cadc2d..32ea373262ca 100644
> --- a/lib/surfaceformat.h
> +++ b/lib/surfaceformat.h
> @@ -171,6 +171,8 @@
>  #define SURFACEFORMAT_R16G16B16_SSCALED        0x19E
>  #define SURFACEFORMAT_R16G16B16_USCALED        0x19F
>  
> +#define SURFACEFORMAT_RAW      0x1FF
> +
>  #define SURFACERETURNFORMAT_FLOAT32    0
>  #define SURFACERETURNFORMAT_S1 1
>  
> diff --git a/tests/Makefile.sources b/tests/Makefile.sources
> index 3dfeb5b67274..6dabb9dbf247 100644
> --- a/tests/Makefile.sources
> +++ b/tests/Makefile.sources
> @@ -302,6 +302,9 @@ gem_madvise_SOURCES = i915/gem_madvise.c
>  TESTS_progs += gem_media_fill
>  gem_media_fill_SOURCES = i915/gem_media_fill.c
>  
> +TESTS_progs += gem_media_vme
> +gem_media_vme_SOURCES = i915/gem_media_vme.c
> +
>  TESTS_progs += gem_mmap
>  gem_mmap_SOURCES = i915/gem_mmap.c
>  
> diff --git a/tests/i915/gem_media_vme.c b/tests/i915/gem_media_vme.c
> new file mode 100644
> index 000000000000..47e949c781f2
> --- /dev/null
> +++ b/tests/i915/gem_media_vme.c
> @@ -0,0 +1,118 @@
> +/*
> + * Copyright © 2018 Intel Corporation
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the next
> + * paragraph) shall be included in all copies or substantial portions of the
> + * Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> + * IN THE SOFTWARE.
> + */
> +#include "igt.h"
> +#include <stdbool.h>
> +#include <unistd.h>
> +#include <stdlib.h>
> +#include <sys/ioctl.h>
> +#include <stdio.h>
> +#include <string.h>
> +#include <fcntl.h>
> +#include <inttypes.h>
> +#include <errno.h>
> +#include <sys/stat.h>
> +#include <sys/time.h>
> +#include "drm.h"
> +#include "intel_bufmgr.h"
> +
> +IGT_TEST_DESCRIPTION("A very simple workload for the VME media block.");
> +
> +#define WIDTH  64
> +#define STRIDE (WIDTH)
> +#define HEIGHT 64
> +
> +#define INPUT_SIZE     (WIDTH * HEIGHT * sizeof(char) * 1.5)
> +#define OUTPUT_SIZE    (56*sizeof(int))
> +
> +static void
> +scratch_buf_init(drm_intel_bufmgr *bufmgr,
> +                struct igt_buf *buf,
> +                unsigned int size)
> +{
> +       drm_intel_bo *bo;
> +
> +       bo = drm_intel_bo_alloc(bufmgr, "", size, 4096);
> +       igt_assert(bo);
> +
> +       memset(buf, 0, sizeof(*buf));
> +
> +       buf->bo = bo;
> +       buf->tiling = I915_TILING_NONE;
> +       buf->size = size;
> +}
> +
> +static void scratch_buf_init_src(drm_intel_bufmgr *bufmgr, struct igt_buf *buf)
> +{
> +       scratch_buf_init(bufmgr, buf, INPUT_SIZE);
> +
> +       /*
> +        * Ideally we would read src surface from file "SourceFrameI.yu12".
> +        * But even without it, we can still triger the rcs0 resetting
> +        * with this vme kernel.
> +        */
> +
> +       buf->stride = STRIDE;
> +}
> +
> +static void scratch_buf_init_dst(drm_intel_bufmgr *bufmgr, struct igt_buf *buf)
> +{
> +       scratch_buf_init(bufmgr, buf, OUTPUT_SIZE);
> +
> +       buf->stride = 1;
> +}
> +
> +igt_simple_main
> +{
> +       int drm_fd;
> +       uint32_t devid;
> +       drm_intel_bufmgr *bufmgr;
> +       igt_vme_func_t media_vme;
> +       struct intel_batchbuffer *batch;
> +       struct igt_buf src, dst;
> +       uint8_t dst_linear[OUTPUT_SIZE];
> +
> +       drm_fd = drm_open_driver(DRIVER_INTEL);
> +       igt_require_gem(drm_fd);
> +
> +       devid = intel_get_drm_devid(drm_fd);
> +
> +       media_vme = igt_get_media_vme_func(devid);
> +       igt_require_f(media_vme, "no media-vme function\n");
> +
> +       bufmgr = drm_intel_bufmgr_gem_init(drm_fd, 4096);
> +       igt_assert(bufmgr);
> +
> +       batch = intel_batchbuffer_alloc(bufmgr, devid);
> +       igt_assert(batch);
> +
> +       scratch_buf_init_src(bufmgr, &src);
> +       scratch_buf_init_dst(bufmgr, &dst);
> +
> +       igt_fork_hang_detector(drm_fd);
> +
> +       media_vme(batch, &src, WIDTH, HEIGHT, &dst);
> +       gem_read(drm_fd, dst.bo->handle, 0,
> +                       dst_linear, sizeof(dst_linear));

Still think this should be gem_sync(bo->handle) to avoid any illusions
that the result is being checked.

I resisted one whole sentence of not saying libdrm_intel, flee!
-Chris


More information about the igt-dev mailing list