[igt-dev] [PATCH i-g-t 1/3] lib/rendercopy: Add AUX page table support

Chris Wilson chris at chris-wilson.co.uk
Mon Nov 4 11:28:11 UTC 2019


Quoting Imre Deak (2019-11-01 20:13:09)
> On GEN12+ the AUX CCS surfaces required by the render and media
> compression must be specified by a 3 level page table directory, which
> translates the main surface graphics address to the AUX CCS surface
> graphics address. For this purpose add support for creating a GEM buffer
> to translate the linear surface address range to the linear AUX surface
> address range.
> 
> The buffers containing the main surface must be pinned down, since the
> directory table entry indices depend on the surface address, and they
> must be 64kB aligned. The page table can be relocated OTOH, so allow
> that and emit the required relocation entries.
> 
> Cc: Mika Kahola <mika.kahola at intel.com>
> Cc: Brian Welty <brian.welty at intel.com>
> Cc: Chris Wilson <chris at chris-wilson.co.uk>
> Cc: Ville Syrjälä <ville.syrjala at linux.intel.com>
> Signed-off-by: Imre Deak <imre.deak at intel.com>
> ---
>  lib/igt_aux_pgtable.c | 381 ++++++++++++++++++++++++++++++++++++++++++
>  lib/igt_aux_pgtable.h |  21 +++

This is not igt, but an libdrm_intel wrapper.

Missing the autotools support.

>  lib/intel_reg.h       |   3 +
>  lib/meson.build       |   1 +
>  lib/rendercopy_gen9.c | 121 +++++++++++++-
>  5 files changed, 521 insertions(+), 6 deletions(-)
>  create mode 100644 lib/igt_aux_pgtable.c
>  create mode 100644 lib/igt_aux_pgtable.h
> 
> diff --git a/lib/igt_aux_pgtable.c b/lib/igt_aux_pgtable.c
> new file mode 100644
> index 00000000..aaa24cfd
> --- /dev/null
> +++ b/lib/igt_aux_pgtable.c
> @@ -0,0 +1,381 @@
> +#include <stdint.h>
> +#include <stdbool.h>
> +
> +#include "drmtest.h"
> +#include "igt_aux_pgtable.h"
> +#include "intel_bufmgr.h"
> +#include "intel_batchbuffer.h"
> +#include "ioctl_wrappers.h"
> +
> +#include "i915/gem_mman.h"
> +
> +#define BITS_PER_LONG          (sizeof(long) * 8)
> +#define BITMASK(e, s)          ((~0UL << (s)) & \
> +                                (~0UL >> (BITS_PER_LONG - 1 - (e))))
> +
> +#define ALIGN_DOWN(x, a)       ALIGN((x) - ((a) - 1), (a))
> +
> +#define CL_SIZE                        64
> +/*
> + * The size of a block on the CCS surface that is covered/pointed to by one
> + * L1 AUX pagetable entry. This size corresponds to the 1<<8 alignment of the
> + * pointers in the L1 entry.
> + */
> +#define CCS_BLOCK_SIZE         (4 * CL_SIZE)
> +/*
> + * 256 bytes per CCS block size *
> + * 8   bits per byte /
> + * 2   bits per surface CL *
> + * 64  bytes per surface CL
> + */
> +#define SURFACE_BLOCK_SIZE     (CCS_BLOCK_SIZE * 8 / 2 * CL_SIZE)
> +#define AUX_PGTABLE_VALID      1
> +#define AUX_PGTABLE_LEVELS     3
> +
> +#define ADDRESS_BITS           48
> +
> +#define max(a, b)              ((a) > (b) ? (a) : (b))
> +
> +struct pgtable_level_desc {
> +       int idx_shift;
> +       int idx_bits;
> +       int entry_ptr_shift;
> +       int table_size;
> +};
> +
> +struct pgtable_level_info {
> +       const struct pgtable_level_desc *desc;
> +       int table_count;
> +       int alloc_base;
> +       int alloc_ptr;
> +};
> +
> +struct pgtable {
> +       int levels;
> +       struct pgtable_level_info *level_info;
> +       int size;
> +       int max_align;
> +       drm_intel_bo *bo;
> +};
> +
> +static const struct pgtable_level_desc aux_pgtable_desc[AUX_PGTABLE_LEVELS] = {
> +       {
> +               .idx_shift = 16,
> +               .idx_bits = 8,
> +               .entry_ptr_shift = 8,
> +               .table_size = 8 * 1024,
> +       },
> +       {
> +               .idx_shift = 24,
> +               .idx_bits = 12,
> +               .entry_ptr_shift = 13,
> +               .table_size = 32 * 1024,
> +       },
> +       {
> +               .idx_shift = 36,
> +               .idx_bits = 12,
> +               .entry_ptr_shift = 15,
> +               .table_size = 32 * 1024,
> +       },
> +};
> +
> +static int
> +pgt_table_count(int address_bits,
> +               const struct igt_aux_pgtable_range *ranges, int range_count)
> +{
> +       uint64_t end;
> +       int count;
> +       int i;
> +
> +       count = 0;
> +       end = 0;
> +       for (i = 0; i < range_count; i++) {
> +               const struct igt_aux_pgtable_range *r = &ranges[i];
> +               uint64_t start;
> +
> +               /* We require ranges to be sorted. */
> +               igt_assert(i == 0 ||
> +                          r->surface_base >= ranges[i - 1].surface_base +
> +                                             ranges[i - 1].surface_size);
> +
> +               start = ALIGN_DOWN(r->surface_base, 1UL << address_bits);
> +               /* Avoid double counting for overlapping aligned ranges. */
> +               start = max(start, end);
> +
> +               end = ALIGN(r->surface_base + r->surface_size,
> +                           1UL << address_bits);
> +               igt_assert(end >= start);
> +
> +               count += (end - start) >> address_bits;
> +       }
> +
> +       return count;
> +}
> +
> +static void
> +pgt_calc_size(struct pgtable *pgt,
> +             const struct igt_aux_pgtable_range *ranges, int range_count)
> +{
> +       int level;
> +
> +       pgt->size = 0;
> +
> +       for (level = pgt->levels; level > 0; level--) {
> +               struct pgtable_level_info *li = &pgt->level_info[level - 1];
> +
> +               li->alloc_base = ALIGN(pgt->size, li->desc->table_size);
> +               li->alloc_ptr = li->alloc_base;
> +
> +               li->table_count = pgt_table_count(li->desc->idx_shift +
> +                                                 li->desc->idx_bits,
> +                                                 ranges, range_count);
> +
> +               pgt->size = li->alloc_base +
> +                           li->table_count * li->desc->table_size;
> +       }
> +}
> +
> +static uint64_t pgt_alloc_table(struct pgtable *pgt, int level)
> +{
> +       struct pgtable_level_info *li = &pgt->level_info[level - 1];
> +       uint64_t table;
> +
> +       table = li->alloc_ptr;
> +       li->alloc_ptr += li->desc->table_size;
> +
> +       igt_assert(li->alloc_ptr <=
> +                  li->alloc_base + li->table_count * li->desc->table_size);
> +
> +       return table;
> +}
> +
> +static int pgt_address_index(struct pgtable *pgt, int level, uint64_t address)
> +{
> +       const struct pgtable_level_desc *ld = pgt->level_info[level - 1].desc;
> +       uint64_t mask = BITMASK(ld->idx_shift + ld->idx_bits - 1,
> +                               ld->idx_shift);
> +
> +       return (address & mask) >> ld->idx_shift;
> +}
> +
> +static uint64_t ptr_mask(struct pgtable *pgt, int level)
> +{
> +       const struct pgtable_level_desc *ld = pgt->level_info[level - 1].desc;
> +
> +       return BITMASK(ADDRESS_BITS - 1, ld->entry_ptr_shift);
> +}
> +
> +static uint64_t pgt_entry_ptr(struct pgtable *pgt, int level, uint64_t entry)
> +{
> +       return entry & ptr_mask(pgt, level);
> +}
> +
> +static uint64_t pgt_mkentry(struct pgtable *pgt, int level, uint64_t ptr,
> +                           uint64_t flags)
> +{
> +       igt_assert(!(ptr & ~ptr_mask(pgt, level)));
> +
> +       return ptr | flags;
> +}
> +
> +static uint64_t
> +pgt_get_table(struct pgtable *pgt, uint64_t parent_table,
> +             int level, uint64_t address, uint64_t flags)
> +{
> +       uint64_t *table_ptr = pgt->bo->virtual + parent_table;
> +       int entry_idx = pgt_address_index(pgt, level, address);
> +       uint64_t *entry_ptr;
> +
> +       entry_ptr = &table_ptr[entry_idx];
> +       if (!*entry_ptr) {
> +               uint64_t child_table = pgt_alloc_table(pgt, level - 1);
> +
> +               *entry_ptr = pgt_mkentry(pgt, level, child_table, flags);
> +
> +               drm_intel_bo_emit_reloc(pgt->bo,
> +                                       parent_table + entry_idx * sizeof(uint64_t),
> +                                       pgt->bo, *entry_ptr,
> +                                       I915_GEM_DOMAIN_INSTRUCTION, 0);

This is missing setting the correct value into the table, and so may be
skipped by relocation pass inside execbuf.

> +       }
> +
> +       return pgt_entry_ptr(pgt, level, *entry_ptr);
> +}
> +
> +static void
> +pgt_set_l1_entry(struct pgtable *pgt, uint64_t l1_table,
> +                uint64_t address, uint64_t ptr, uint64_t flags)
> +{
> +       uint64_t *l1_table_ptr;
> +       uint64_t *l1_entry_ptr;
> +
> +       l1_table_ptr = pgt->bo->virtual + l1_table;
> +       l1_entry_ptr = &l1_table_ptr[pgt_address_index(pgt, 1, address)];
> +       *l1_entry_ptr = pgt_mkentry(pgt, 1, ptr, flags);
> +}
> +
> +static uint64_t pgt_get_l1_flags(const struct igt_aux_pgtable_range *range)
> +{
> +       /*
> +        * The offset of .tile_mode isn't specifed by bspec, it's what Mesa
> +        * uses.
> +        */
> +       union {
> +               struct {
> +                       uint64_t        valid:1;
> +                       uint64_t        compression_mod:2;
> +                       uint64_t        lossy_compression:1;
> +                       uint64_t        pad:4;
> +                       uint64_t        addr:40;
> +                       uint64_t        pad2:4;
> +                       uint64_t        tile_mode:2;
> +                       uint64_t        depth:3;
> +                       uint64_t        ycr:1;
> +                       uint64_t        format:6;
> +               } e;
> +               uint64_t l;
> +       } entry = {
> +               .e = {
> +                       .valid = 1,
> +                       .tile_mode = range->tiling == I915_TILING_Y ? 1 : 0,
> +                       .depth = 5,             /* 32bpp */
> +                       .format = 0xA,          /* B8G8R8A8_UNORM */
> +               }
> +       };
> +
> +       /*
> +        * TODO: Clarify if Yf is supported and if we need to differentiate
> +        *       Ys and Yf.
> +        *       Add support for more formats.
> +        */
> +       igt_assert(range->tiling == I915_TILING_Y ||
> +                  range->tiling == I915_TILING_Yf ||
> +                  range->tiling == I915_TILING_Ys);
> +
> +       igt_assert(range->bpp == 32);
> +
> +       return entry.l;
> +}
> +
> +static uint64_t pgt_get_lx_flags(void)
> +{
> +       union {
> +               struct {
> +                       uint64_t        valid:1;
> +                       uint64_t        addr:47;
> +                       uint64_t        pad:16;
> +               } e;
> +               uint64_t l;
> +       } entry = {
> +               .e = {
> +                       .valid = 1,
> +               }
> +       };
> +
> +       return entry.l;
> +}
> +
> +static void
> +pgt_populate_entries_for_range(struct pgtable *pgt,
> +                              const struct igt_aux_pgtable_range *range,
> +                              drm_intel_bo *bo,
> +                              uint64_t top_table)
> +{
> +       uint64_t surface_addr = range->surface_base;
> +       uint64_t surface_end = surface_addr + range->surface_size;
> +       uint64_t aux_addr = range->aux_base;
> +       uint64_t l1_flags = pgt_get_l1_flags(range);
> +       uint64_t lx_flags = pgt_get_lx_flags();
> +
> +       pgt->bo = bo;
> +
> +       for (; surface_addr < surface_end;
> +            surface_addr += SURFACE_BLOCK_SIZE, aux_addr += CCS_BLOCK_SIZE) {
> +               uint64_t table = top_table;
> +               int level;
> +
> +               for (level = pgt->levels; level > 1; level--)
> +                       table = pgt_get_table(pgt, table, level,
> +                                             surface_addr, lx_flags);
> +
> +               pgt_set_l1_entry(pgt, table, surface_addr, aux_addr, l1_flags);
> +       }
> +}
> +
> +static void pgt_populate_entries(struct pgtable *pgt,
> +                                const struct igt_aux_pgtable_range *ranges,
> +                                int range_count,
> +                                drm_intel_bo *gem_bo)
> +{
> +       uint64_t top_table;
> +       int i;
> +
> +       igt_assert(gem_bo->size >= pgt->size);
> +       memset(gem_bo->virtual, 0, pgt->size);
> +
> +       top_table = pgt_alloc_table(pgt, pgt->levels);
> +       /* Top level table must be at offset 0. */
> +       igt_assert(top_table == 0);
> +
> +       for (i = 0; i < range_count; i++)
> +               pgt_populate_entries_for_range(pgt, &ranges[i], gem_bo,
> +                                              top_table);
> +}
> +
> +static struct pgtable *
> +pgt_create(const struct pgtable_level_desc *level_descs, int levels,
> +          const struct igt_aux_pgtable_range *ranges, int range_count)
> +{
> +       struct pgtable *pgt;
> +       int level;
> +
> +       pgt = calloc(1, sizeof(*pgt));
> +       igt_assert(pgt);
> +
> +       pgt->levels = levels;
> +
> +       pgt->level_info = calloc(levels, sizeof(*pgt->level_info));
> +       igt_assert(pgt->level_info);
> +
> +       for (level = 0; level < pgt->levels; level++) {
> +               struct pgtable_level_info *li = &pgt->level_info[level];
> +
> +               li->desc = &level_descs[level];
> +               if (li->desc->table_size > pgt->max_align)
> +                       pgt->max_align = li->desc->table_size;
> +       }
> +
> +       pgt_calc_size(pgt, ranges, range_count);
> +
> +       return pgt;
> +}
> +
> +static void pgt_destroy(struct pgtable *pgt)
> +{
> +       free(pgt->level_info);
> +       free(pgt);
> +}
> +
> +drm_intel_bo *
> +igt_aux_pgtable_create(drm_intel_bufmgr *bufmgr,
> +                      const struct igt_aux_pgtable_range *ranges,
> +                      int range_count)
> +{
> +       struct pgtable *pgt;
> +       drm_intel_bo *gem_bo;
> +
> +       pgt = pgt_create(aux_pgtable_desc, AUX_PGTABLE_LEVELS,
> +                        ranges, range_count);
> +
> +       gem_bo = drm_intel_bo_alloc_for_render(bufmgr,
> +                                              "aux pgt",
> +                                              pgt->size, pgt->max_align);
> +       igt_assert(gem_bo);
> +
> +       igt_assert(drm_intel_bo_map(gem_bo, true) == 0);
> +       pgt_populate_entries(pgt, ranges, range_count, gem_bo);
> +       igt_assert(drm_intel_bo_unmap(gem_bo) == 0);
> +
> +       pgt_destroy(pgt);
> +
> +       return gem_bo;
> +}
> diff --git a/lib/igt_aux_pgtable.h b/lib/igt_aux_pgtable.h
> new file mode 100644
> index 00000000..64c6b21f
> --- /dev/null
> +++ b/lib/igt_aux_pgtable.h
> @@ -0,0 +1,21 @@
> +#ifndef _IGT_AUX_PGTABLE_H_
> +#define _IGT_AUX_PGTABLE_H_
> +
> +#include "intel_bufmgr.h"
> +
> +struct igt_aux_pgtable;
> +
> +struct igt_aux_pgtable_range {
> +       uint64_t surface_base;
> +       uint64_t surface_size;
> +       uint64_t aux_base;
> +       uint32_t tiling;
> +       int bpp;
> +};
> +
> +drm_intel_bo *
> +igt_aux_pgtable_create(drm_intel_bufmgr *bufmgr,
> +                      const struct igt_aux_pgtable_range *ranges,
> +                      int range_count);
> +
> +#endif
> diff --git a/lib/intel_reg.h b/lib/intel_reg.h
> index 069440cb..e7263ce1 100644
> --- a/lib/intel_reg.h
> +++ b/lib/intel_reg.h
> @@ -673,6 +673,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
>  #define RING_VALID          0x00000001
>  #define RING_INVALID        0x00000000
>  
> +#define GEN12_GFX_AUX_TABLE_BASE_ADDR  0x4200
> +
>  
>  
>  /* BitBlt Instructions
> @@ -2570,6 +2572,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
>  
>  #define MI_LOAD_SCAN_LINES_INCL                (0x12<<23)
>  #define MI_LOAD_REGISTER_IMM           ((0x22 << 23) | 1)
> +#define MI_LOAD_REGISTER_MEM           ((0x29 << 23) | (4 - 2))
>  
>  /* Flush */
>  #define MI_FLUSH                       (0x04<<23)
> diff --git a/lib/meson.build b/lib/meson.build
> index 221ae28c..2135ddf3 100644
> --- a/lib/meson.build
> +++ b/lib/meson.build
> @@ -46,6 +46,7 @@ lib_sources = [
>         'sw_sync.c',
>         'intel_reg_map.c',
>         'intel_iosf.c',
> +       'igt_aux_pgtable.c',
>         'igt_kms.c',
>         'igt_fb.c',
>         'igt_core.c',
> diff --git a/lib/rendercopy_gen9.c b/lib/rendercopy_gen9.c
> index 694eb3cf..31e38c2b 100644
> --- a/lib/rendercopy_gen9.c
> +++ b/lib/rendercopy_gen9.c
> @@ -15,6 +15,7 @@
>  #include <i915_drm.h>
>  
>  #include "drmtest.h"
> +#include "igt_aux_pgtable.h"
>  #include "intel_bufmgr.h"
>  #include "intel_batchbuffer.h"
>  #include "intel_io.h"
> @@ -972,19 +973,113 @@ static void gen8_emit_primitive(struct intel_batchbuffer *batch, uint32_t offset
>  
>  #define BATCH_STATE_SPLIT 2048
>  
> +static void
> +gen12_emit_aux_pgtable_state(struct intel_batchbuffer *batch, uint32_t state)
> +{
> +       if (!state)
> +               return;
> +
> +       OUT_BATCH(MI_LOAD_REGISTER_MEM);
> +       OUT_BATCH(GEN12_GFX_AUX_TABLE_BASE_ADDR);
> +       OUT_RELOC(batch->bo, I915_GEM_DOMAIN_INSTRUCTION, 0, state);
> +       OUT_BATCH(MI_NOOP);
> +
> +       OUT_BATCH(MI_LOAD_REGISTER_MEM);
> +       OUT_BATCH(GEN12_GFX_AUX_TABLE_BASE_ADDR + 4);
> +       OUT_RELOC(batch->bo, I915_GEM_DOMAIN_INSTRUCTION, 0, state + 4);
> +       OUT_BATCH(MI_NOOP);

Extra MI_NOOP.

> +}
> +
> +static int add_aux_pgtable_range(const struct igt_buf *buf,
> +                                struct igt_aux_pgtable_range *range,
> +                                uint64_t *pin_offset)
> +{
> +       if (!buf->aux.stride)
> +               return 0;
> +
> +       drm_intel_bo_set_softpin_offset(buf->bo, *pin_offset);
> +       igt_assert(buf->bo->offset64 == *pin_offset);
> +
> +       range->surface_base = *pin_offset;
> +       range->surface_size = buf->size;
> +       range->aux_base = *pin_offset + buf->aux.offset;
> +       range->tiling = buf->tiling;
> +       range->bpp = buf->bpp;
> +
> +       /* The GEN12+ compressed main surface must be 64kB aligned.  */
> +       *pin_offset = ALIGN(*pin_offset + buf->bo->size, 0x10000);
> +
> +       return 1;
> +}
> +
> +static drm_intel_bo *
> +gen12_create_aux_pgtable_bo(drm_intel_bufmgr *bufmgr,
> +                           const struct igt_buf *dst_buf,
> +                           const struct igt_buf *src_buf)
> +{
> +       struct igt_aux_pgtable_range ranges[2];
> +       int range_count;
> +       uint64_t pin_offset;
> +       drm_intel_bo *gem_bo;
> +
> +       range_count = 0;
> +       pin_offset = 0;
> +
> +       range_count += add_aux_pgtable_range(dst_buf,
> +                                            &ranges[range_count], &pin_offset);
> +       range_count += add_aux_pgtable_range(src_buf,
> +                                            &ranges[range_count], &pin_offset);
> +
> +       if (!range_count)
> +               return NULL;
> +
> +       gem_bo = igt_aux_pgtable_create(bufmgr, ranges, range_count);
> +       igt_assert(gem_bo);
> +
> +       return gem_bo;
> +}
> +
> +static uint32_t
> +gen12_create_aux_pgtable_state(struct intel_batchbuffer *batch,
> +                              drm_intel_bo *aux_pgtable_bo)
> +{
> +       uint64_t *pgtable_ptr;
> +       uint32_t pgtable_ptr_offset;
> +       int ret;
> +
> +       if (!aux_pgtable_bo)
> +               return 0;
> +
> +       pgtable_ptr = intel_batchbuffer_subdata_alloc(batch,
> +                                                     sizeof(*pgtable_ptr),
> +                                                     sizeof(*pgtable_ptr));
> +       pgtable_ptr_offset = intel_batchbuffer_subdata_offset(batch,
> +                                                             pgtable_ptr);
> +
> +       ret = drm_intel_bo_emit_reloc(batch->bo, pgtable_ptr_offset,
> +                                     aux_pgtable_bo, 0,
> +                                     I915_GEM_DOMAIN_RENDER, 0);
> +       assert(ret == 0);
> +
> +       return pgtable_ptr_offset;
> +}
> +
>  static
>  void _gen9_render_copyfunc(struct intel_batchbuffer *batch,
>                           drm_intel_context *context,
>                           const struct igt_buf *src, unsigned src_x,
>                           unsigned src_y, unsigned width, unsigned height,
>                           const struct igt_buf *dst, unsigned dst_x,
> -                         unsigned dst_y, const uint32_t ps_kernel[][4],
> +                         unsigned dst_y,
> +                         drm_intel_bo *aux_pgtable_bo,
> +                         const uint32_t ps_kernel[][4],
>                           uint32_t ps_kernel_size)
>  {
>         uint32_t ps_sampler_state, ps_kernel_off, ps_binding_table;
>         uint32_t scissor_state;
>         uint32_t vertex_buffer;
>         uint32_t batch_end;
> +       uint32_t aux_pgtable_state;
>  
>         igt_assert(src->bpp == dst->bpp);
>         intel_batchbuffer_flush_with_context(batch, context);
> @@ -1007,6 +1102,10 @@ void _gen9_render_copyfunc(struct intel_batchbuffer *batch,
>         viewport.cc_state = gen6_create_cc_viewport(batch);
>         viewport.sf_clip_state = gen7_create_sf_clip_viewport(batch);
>         scissor_state = gen6_create_scissor_rect(batch);
> +
> +       aux_pgtable_state = gen12_create_aux_pgtable_state(batch,
> +                                                          aux_pgtable_bo);
> +
>         /* TODO: theree is other state which isn't setup */
>  
>         assert(batch->ptr < &batch->buffer[4095]);
> @@ -1018,6 +1117,8 @@ void _gen9_render_copyfunc(struct intel_batchbuffer *batch,
>         OUT_BATCH(G4X_PIPELINE_SELECT | PIPELINE_SELECT_3D |
>                                 GEN9_PIPELINE_SELECTION_MASK);
>  
> +       gen12_emit_aux_pgtable_state(batch, aux_pgtable_state);
> +
>         gen8_emit_sip(batch);
>  
>         gen7_emit_push_constants(batch);
> @@ -1092,8 +1193,8 @@ void gen9_render_copyfunc(struct intel_batchbuffer *batch,
>  
>  {
>         _gen9_render_copyfunc(batch, context, src, src_x, src_y,
> -                         width, height, dst, dst_x, dst_y, ps_kernel_gen9,
> -                         sizeof(ps_kernel_gen9));
> +                         width, height, dst, dst_x, dst_y, NULL,
> +                         ps_kernel_gen9, sizeof(ps_kernel_gen9));
>  }
>  
>  void gen11_render_copyfunc(struct intel_batchbuffer *batch,
> @@ -1104,8 +1205,8 @@ void gen11_render_copyfunc(struct intel_batchbuffer *batch,
>  
>  {
>         _gen9_render_copyfunc(batch, context, src, src_x, src_y,
> -                         width, height, dst, dst_x, dst_y, ps_kernel_gen11,
> -                         sizeof(ps_kernel_gen11));
> +                         width, height, dst, dst_x, dst_y, NULL,
> +                         ps_kernel_gen11, sizeof(ps_kernel_gen11));
>  }
>  
>  void gen12_render_copyfunc(struct intel_batchbuffer *batch,
> @@ -1115,7 +1216,15 @@ void gen12_render_copyfunc(struct intel_batchbuffer *batch,
>                            const struct igt_buf *dst, unsigned dst_x, unsigned dst_y)
>  
>  {
> +       drm_intel_bo *aux_pgtable_bo;
> +
> +       aux_pgtable_bo = gen12_create_aux_pgtable_bo(batch->bufmgr, dst, src);
> +
>         _gen9_render_copyfunc(batch, context, src, src_x, src_y,
> -                         width, height, dst, dst_x, dst_y, gen12_render_copy,
> +                         width, height, dst, dst_x, dst_y,
> +                         aux_pgtable_bo,
> +                         gen12_render_copy,
>                           sizeof(gen12_render_copy));
> +
> +       drm_intel_bo_unreference(aux_pgtable_bo);
>  }
> -- 
> 2.17.1
> 


More information about the igt-dev mailing list