From 698d45b72571ec62406a187a16169551def390f5 Mon Sep 17 00:00:00 2001 From: Kenneth Graunke Date: Sat, 21 Apr 2018 22:20:32 -0700 Subject: [PATCH] iris: more blitting code to make readpixels work --- src/gallium/drivers/iris/iris_blit.c | 77 ++++++++++++++++++++++++- src/gallium/drivers/iris/iris_blorp.c | 65 +++++++++++++++++---- src/gallium/drivers/iris/iris_context.c | 1 + src/gallium/drivers/iris/iris_context.h | 3 + 4 files changed, 135 insertions(+), 11 deletions(-) diff --git a/src/gallium/drivers/iris/iris_blit.c b/src/gallium/drivers/iris/iris_blit.c index e7ffe31ee4b..9c328ac12f1 100644 --- a/src/gallium/drivers/iris/iris_blit.c +++ b/src/gallium/drivers/iris/iris_blit.c @@ -27,15 +27,90 @@ #include "pipe/p_screen.h" #include "util/u_inlines.h" #include "util/ralloc.h" +#include "intel/blorp/blorp.h" #include "iris_context.h" #include "iris_resource.h" #include "iris_screen.h" static void -iris_blit(struct pipe_context *ctx, const struct pipe_blit_info *info) +blorp_surf_for_resource(struct blorp_surf *surf, + struct pipe_resource *p_res, + enum isl_aux_usage aux_usage, + bool is_render_target) +{ + struct iris_resource *res = (void *) p_res; + + *surf = (struct blorp_surf) { + .surf = &res->surf, + .addr = (struct blorp_address) { + .buffer = res->bo, + .offset = 0, // XXX: ??? + .reloc_flags = is_render_target ? EXEC_OBJECT_WRITE : 0, + .mocs = I915_MOCS_CACHED, // XXX: BDW MOCS, PTE MOCS + }, + .aux_usage = aux_usage, + }; + + assert(surf->aux_usage == ISL_AUX_USAGE_NONE); +} + +static enum isl_format +iris_get_blorp_format(enum pipe_format pf) { + switch (pf) { + case PIPE_FORMAT_Z24_UNORM_S8_UINT: + return ISL_FORMAT_R24_UNORM_X8_TYPELESS; + case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: + return ISL_FORMAT_R32_FLOAT; + default: + return iris_isl_format_for_pipe_format(pf); + } } +static void +iris_blit(struct pipe_context *ctx, const struct pipe_blit_info *info) +{ + struct iris_context *ice = (void *) ctx; + struct blorp_surf src_surf, dst_surf; + blorp_surf_for_resource(&src_surf, info->src.resource, ISL_AUX_USAGE_NONE, + false); + blorp_surf_for_resource(&dst_surf, info->dst.resource, ISL_AUX_USAGE_NONE, + true); + + enum isl_format src_isl_format = iris_get_blorp_format(info->src.format); + enum isl_format dst_isl_format = iris_get_blorp_format(info->dst.format); + + // XXX: ??? + unsigned dst_layer = 0; + unsigned src_layer = 0; + + struct isl_swizzle src_isl_swizzle = ISL_SWIZZLE_IDENTITY; + + int src_x0 = info->src.box.x; + int src_x1 = info->src.box.x + info->src.box.width; + int src_y0 = info->src.box.y; + int src_y1 = info->src.box.y + info->src.box.height; + int dst_x0 = info->dst.box.x; + int dst_x1 = info->dst.box.x + info->dst.box.width; + int dst_y0 = info->dst.box.y; + int dst_y1 = info->dst.box.y + info->dst.box.height; + bool mirror_x = false; + bool mirror_y = false; + GLenum filter = + info->filter == PIPE_TEX_FILTER_LINEAR ? GL_LINEAR : GL_NEAREST; + + struct blorp_batch blorp_batch; + blorp_batch_init(&ice->blorp, &blorp_batch, &ice->render_batch, 0); + blorp_blit(&blorp_batch, &src_surf, info->src.level, src_layer, + src_isl_format, src_isl_swizzle, + &dst_surf, info->dst.level, dst_layer, + dst_isl_format, ISL_SWIZZLE_IDENTITY, + src_x0, src_y0, src_x1, src_y1, + dst_x0, dst_y0, dst_x1, dst_y1, + filter, mirror_x, mirror_y); + + blorp_batch_finish(&blorp_batch); +} static boolean iris_generate_mipmap(struct pipe_context *ctx, diff --git a/src/gallium/drivers/iris/iris_blorp.c b/src/gallium/drivers/iris/iris_blorp.c index 516a30d03bc..7995325239e 100644 --- a/src/gallium/drivers/iris/iris_blorp.c +++ b/src/gallium/drivers/iris/iris_blorp.c @@ -60,27 +60,37 @@ blorp_emit_dwords(struct blorp_batch *blorp_batch, unsigned n) } static uint64_t -blorp_emit_reloc(struct blorp_batch *blorp_batch, UNUSED void *location, - struct blorp_address addr, uint32_t delta) +combine_and_pin_address(struct blorp_batch *blorp_batch, + struct blorp_address addr) { struct iris_batch *batch = blorp_batch->driver_batch; struct iris_bo *bo = addr.buffer; - uint64_t result = addr.offset + delta; - if (bo) { - iris_use_pinned_bo(batch, bo, addr.reloc_flags & RELOC_WRITE); - /* Assume this is a general address, not relative to a base. */ - result += bo->gtt_offset; - } + iris_use_pinned_bo(batch, bo, addr.reloc_flags & RELOC_WRITE); - return result; + /* Assume this is a general address, not relative to a base. */ + return bo->gtt_offset + addr.offset; +} + +static uint64_t +blorp_emit_reloc(struct blorp_batch *blorp_batch, UNUSED void *location, + struct blorp_address addr, uint32_t delta) +{ + return combine_and_pin_address(blorp_batch, addr) + delta; } static void blorp_surface_reloc(struct blorp_batch *blorp_batch, uint32_t ss_offset, struct blorp_address addr, uint32_t delta) { - /* Don't do anything, blorp_alloc_binding_table already added the BO. */ + /* Let blorp_get_surface_address do the pinning. */ +} + +static uint64_t +blorp_get_surface_address(struct blorp_batch *blorp_batch, + struct blorp_address addr) +{ + return combine_and_pin_address(blorp_batch, addr); } UNUSED static struct blorp_address @@ -151,6 +161,36 @@ blorp_alloc_vertex_buffer(struct blorp_batch *blorp_batch, return map; } +/** + * See vf_invalidate_for_vb_48b_transitions in iris_state.c. + * XXX: actually add this + */ +static void +blorp_vf_invalidate_for_vb_48b_transitions(struct blorp_batch *batch, + const struct blorp_address *addrs, + unsigned num_vbs) +{ +#if 0 + struct iris_context *ice = blorp_batch->blorp->driver_ctx; + struct iris_batch *batch = blorp_batch->driver_batch; + bool need_invalidate = false; + + for (unsigned i = 0; i < num_vbs; i++) { + struct iris_bo *bo = addrs[i].buffer; + uint16_t high_bits = bo ? bo->gtt_offset >> 32u : 0; + + if (high_bits != ice->state.last_vbo_high_bits[i]) { + need_invalidate = true; + ice->state.last_vbo_high_bits[i] = high_bits; + } + } + + if (need_invalidate) { + iris_emit_pipe_control_flush(batch, PIPE_CONTROL_VF_CACHE_INVALIDATE); + } +#endif +} + static struct blorp_address blorp_get_workaround_page(struct blorp_batch *blorp_batch) { @@ -279,5 +319,10 @@ iris_blorp_exec(struct blorp_batch *blorp_batch, void genX(init_blorp)(struct iris_context *ice) { + struct iris_screen *screen = (struct iris_screen *)ice->ctx.screen; + + blorp_init(&ice->blorp, ice, &screen->isl_dev); + ice->blorp.compiler = screen->compiler; + ice->vtbl.blorp_exec = iris_blorp_exec; } diff --git a/src/gallium/drivers/iris/iris_context.c b/src/gallium/drivers/iris/iris_context.c index c6b1c3525fc..417a09f64ee 100644 --- a/src/gallium/drivers/iris/iris_context.c +++ b/src/gallium/drivers/iris/iris_context.c @@ -147,6 +147,7 @@ iris_create_context(struct pipe_screen *pscreen, void *priv, unsigned flags) IRIS_RESOURCE_FLAG_DYNAMIC_MEMZONE); genX_call(devinfo, init_state, ice); + genX_call(devinfo, init_blorp, ice); ice->vtbl.init_render_context(screen, &ice->render_batch, &ice->vtbl, &ice->dbg); diff --git a/src/gallium/drivers/iris/iris_context.h b/src/gallium/drivers/iris/iris_context.h index 6478e3a87c1..1e7e60cc3a3 100644 --- a/src/gallium/drivers/iris/iris_context.h +++ b/src/gallium/drivers/iris/iris_context.h @@ -26,6 +26,7 @@ #include "pipe/p_context.h" #include "pipe/p_state.h" #include "util/u_debug.h" +#include "intel/blorp/blorp.h" #include "intel/common/gen_debug.h" #include "intel/compiler/brw_compiler.h" #include "iris_batch.h" @@ -249,6 +250,8 @@ struct iris_context { unsigned urb_size; } shaders; + struct blorp_context blorp; + /** The main batch for rendering */ struct iris_batch render_batch; -- 2.30.2