iris: more blitting code to make readpixels work
authorKenneth Graunke <kenneth@whitecape.org>
Sun, 22 Apr 2018 05:20:32 +0000 (22:20 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Thu, 21 Feb 2019 18:26:06 +0000 (10:26 -0800)
src/gallium/drivers/iris/iris_blit.c
src/gallium/drivers/iris/iris_blorp.c
src/gallium/drivers/iris/iris_context.c
src/gallium/drivers/iris/iris_context.h

index e7ffe31ee4b9361b8337e92aadd0a46aedb7a5de..9c328ac12f1f5d795896611c1cd92c93d9129584 100644 (file)
 #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,
index 516a30d03bc9e4e3553ed730625fbf9f95d4b89e..7995325239e178d8921e86eaccd7586b71737972 100644 (file)
@@ -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;
 }
index c6b1c3525fcc47eea7b3e33b1823795af7fe8dc3..417a09f64eef17be6eec0df868a0a16540e36d02 100644 (file)
@@ -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);
 
index 6478e3a87c16942c389a84a0455efbc5a65578bb..1e7e60cc3a3a2ef6ffe3b0a363aa7141665bdcb8 100644 (file)
@@ -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;