Mesa (main): iris: Create an IRIS_BATCH_BLITTER for using the BLT command streamer

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Mon Jan 24 23:47:36 UTC 2022


Module: Mesa
Branch: main
Commit: a90a1f15a7c8943893e76a202f65bdac8c3e6b49
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=a90a1f15a7c8943893e76a202f65bdac8c3e6b49

Author: Kenneth Graunke <kenneth at whitecape.org>
Date:   Fri Aug 28 15:08:29 2020 -0700

iris: Create an IRIS_BATCH_BLITTER for using the BLT command streamer

We removed all the hardware blitter support from i965 years ago because
the blitter was not worth using (limited functionality, bad performance,
extra synchronization, and worse).  However, on Tigerlake there are new
blitter commands that are actually fast and allow us to do proper
asynchronous copies while 3D is busy doing other work.

So, reintroduce the blitter.  We'll want to use it.

Reviewed-by: Caio Oliveira <caio.oliveira at intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14687>

---

 src/gallium/drivers/iris/iris_batch.c   | 76 ++++++++++++++++++---------------
 src/gallium/drivers/iris/iris_batch.h   |  1 +
 src/gallium/drivers/iris/iris_bufmgr.h  |  2 +-
 src/gallium/drivers/iris/iris_context.c |  2 +
 4 files changed, 46 insertions(+), 35 deletions(-)

diff --git a/src/gallium/drivers/iris/iris_batch.c b/src/gallium/drivers/iris/iris_batch.c
index 432cc5a4c33..e1f7e53884c 100644
--- a/src/gallium/drivers/iris/iris_batch.c
+++ b/src/gallium/drivers/iris/iris_batch.c
@@ -234,6 +234,8 @@ iris_init_batch(struct iris_context *ice,
       batch->decoder.dynamic_base = IRIS_MEMZONE_DYNAMIC_START;
       batch->decoder.instruction_base = IRIS_MEMZONE_SHADER_START;
       batch->decoder.max_vbo_decoded_lines = 32;
+      if (batch->name == IRIS_BATCH_BLITTER)
+         batch->decoder.engine = I915_ENGINE_CLASS_COPY;
    }
 
    iris_init_batch_measure(ice, batch);
@@ -256,12 +258,15 @@ iris_init_non_engine_contexts(struct iris_context *ice, int priority)
       assert(batch->ctx_id);
       iris_hw_context_set_priority(screen->bufmgr, batch->ctx_id, priority);
    }
+
+   ice->batches[IRIS_BATCH_BLITTER].exec_flags = I915_EXEC_BLT;
 }
 
 static int
 iris_create_engines_context(struct iris_context *ice, int priority)
 {
    struct iris_screen *screen = (void *) ice->ctx.screen;
+   const struct intel_device_info *devinfo = &screen->devinfo;
    int fd = iris_bufmgr_get_fd(screen->bufmgr);
 
    struct drm_i915_query_engine_info *engines_info =
@@ -275,14 +280,18 @@ iris_create_engines_context(struct iris_context *ice, int priority)
       return -1;
    }
 
-   STATIC_ASSERT(IRIS_BATCH_COUNT == 2);
+   STATIC_ASSERT(IRIS_BATCH_COUNT == 3);
    uint16_t engine_classes[IRIS_BATCH_COUNT] = {
       [IRIS_BATCH_RENDER] = I915_ENGINE_CLASS_RENDER,
       [IRIS_BATCH_COMPUTE] = I915_ENGINE_CLASS_RENDER,
+      [IRIS_BATCH_BLITTER] = I915_ENGINE_CLASS_COPY,
    };
 
+   /* Blitter is only supported on Gfx12+ */
+   unsigned num_batches = IRIS_BATCH_COUNT - (devinfo->ver >= 12 ? 0 : 1);
+
    int engines_ctx =
-      intel_gem_create_context_engines(fd, engines_info, IRIS_BATCH_COUNT,
+      intel_gem_create_context_engines(fd, engines_info, num_batches,
                                        engine_classes);
 
    if (engines_ctx < 0) {
@@ -822,49 +831,47 @@ update_bo_syncobjs(struct iris_batch *batch, struct iris_bo *bo, bool write)
    struct iris_bo_screen_deps *deps = &bo->deps[screen->id];
    int batch_idx = batch->name;
 
-#if IRIS_BATCH_COUNT == 2
-   /* Due to the above, we exploit the fact that IRIS_NUM_BATCHES is actually
-    * 2, which means there's only one other batch we need to care about.
-    */
-   int other_batch_idx = 1 - batch_idx;
-#else
-   /* For IRIS_BATCH_COUNT == 3 we can do:
-    *   int other_batch_idxs[IRIS_BATCH_COUNT - 1] = {
-    *      (batch_idx ^ 1) & 1,
-    *      (batch_idx ^ 2) & 2,
-    *   };
-    * For IRIS_BATCH_COUNT == 4 we can do:
+   /* Someday if IRIS_BATCH_COUNT increases to 4, we could do:
+    *
     *   int other_batch_idxs[IRIS_BATCH_COUNT - 1] = {
     *      (batch_idx + 1) & 3,
     *      (batch_idx + 2) & 3,
     *      (batch_idx + 3) & 3,
     *   };
     */
-#error "Implement me."
-#endif
+   STATIC_ASSERT(IRIS_BATCH_COUNT == 3);
+   int other_batch_idxs[IRIS_BATCH_COUNT - 1] = {
+      (batch_idx ^ 1) & 1,
+      (batch_idx ^ 2) & 2,
+   };
 
-   /* If it is being written to by others, wait on it. */
-   if (deps->write_syncobjs[other_batch_idx])
-      move_syncobj_to_batch(batch, &deps->write_syncobjs[other_batch_idx],
-                            I915_EXEC_FENCE_WAIT);
+   for (unsigned i = 0; i < ARRAY_SIZE(other_batch_idxs); i++) {
+      unsigned other_batch_idx = other_batch_idxs[i];
 
-   struct iris_syncobj *batch_syncobj = iris_batch_get_signal_syncobj(batch);
+      /* If it is being written to by others, wait on it. */
+      if (deps->write_syncobjs[other_batch_idx])
+         move_syncobj_to_batch(batch, &deps->write_syncobjs[other_batch_idx],
+                               I915_EXEC_FENCE_WAIT);
 
-   if (write) {
-      /* If we're writing to it, set our batch's syncobj as write_syncobj so
-       * others can wait on us. Also wait every reader we care about before
-       * writing.
-       */
-      iris_syncobj_reference(bufmgr, &deps->write_syncobjs[batch_idx],
-                              batch_syncobj);
+      struct iris_syncobj *batch_syncobj =
+         iris_batch_get_signal_syncobj(batch);
 
-      move_syncobj_to_batch(batch, &deps->read_syncobjs[other_batch_idx],
-                           I915_EXEC_FENCE_WAIT);
+      if (write) {
+         /* If we're writing to it, set our batch's syncobj as write_syncobj
+          * so others can wait on us. Also wait every reader we care about
+          * before writing.
+          */
+         iris_syncobj_reference(bufmgr, &deps->write_syncobjs[batch_idx],
+                                 batch_syncobj);
 
-   } else {
-      /* If we're reading, replace the other read from our batch index. */
-      iris_syncobj_reference(bufmgr, &deps->read_syncobjs[batch_idx],
-                             batch_syncobj);
+         move_syncobj_to_batch(batch, &deps->read_syncobjs[other_batch_idx],
+                              I915_EXEC_FENCE_WAIT);
+
+      } else {
+         /* If we're reading, replace the other read from our batch index. */
+         iris_syncobj_reference(bufmgr, &deps->read_syncobjs[batch_idx],
+                                batch_syncobj);
+      }
    }
 }
 
@@ -995,6 +1002,7 @@ iris_batch_name_to_string(enum iris_batch_name name)
    const char *names[IRIS_BATCH_COUNT] = {
       [IRIS_BATCH_RENDER]  = "render",
       [IRIS_BATCH_COMPUTE] = "compute",
+      [IRIS_BATCH_BLITTER] = "blitter",
    };
    return names[name];
 }
diff --git a/src/gallium/drivers/iris/iris_batch.h b/src/gallium/drivers/iris/iris_batch.h
index 55db669643d..1b5b4638753 100644
--- a/src/gallium/drivers/iris/iris_batch.h
+++ b/src/gallium/drivers/iris/iris_batch.h
@@ -57,6 +57,7 @@ struct iris_context;
 enum iris_batch_name {
    IRIS_BATCH_RENDER,
    IRIS_BATCH_COMPUTE,
+   IRIS_BATCH_BLITTER,
 };
 
 struct iris_batch {
diff --git a/src/gallium/drivers/iris/iris_bufmgr.h b/src/gallium/drivers/iris/iris_bufmgr.h
index 8ecea2e51e7..24cd418965d 100644
--- a/src/gallium/drivers/iris/iris_bufmgr.h
+++ b/src/gallium/drivers/iris/iris_bufmgr.h
@@ -146,7 +146,7 @@ enum iris_heap {
 
 extern const char *iris_heap_to_string[];
 
-#define IRIS_BATCH_COUNT 2
+#define IRIS_BATCH_COUNT 3
 
 struct iris_bo_screen_deps {
    struct iris_syncobj *write_syncobjs[IRIS_BATCH_COUNT];
diff --git a/src/gallium/drivers/iris/iris_context.c b/src/gallium/drivers/iris/iris_context.c
index 3d5c75489de..1a92df1a5e6 100644
--- a/src/gallium/drivers/iris/iris_context.c
+++ b/src/gallium/drivers/iris/iris_context.c
@@ -71,6 +71,8 @@ iris_lost_context_state(struct iris_batch *batch)
       batch->screen->vtbl.init_render_context(batch);
    } else if (batch->name == IRIS_BATCH_COMPUTE) {
       batch->screen->vtbl.init_compute_context(batch);
+   } else if (batch->name == IRIS_BATCH_BLITTER) {
+      /* No state to set up */
    } else {
       unreachable("unhandled batch reset");
    }



More information about the mesa-commit mailing list