[Mesa-dev] [PATCH 2/3] iris: Create a composite context for both compute and render pipelines

Chris Wilson chris at chris-wilson.co.uk
Mon Mar 25 10:58:59 UTC 2019


iris currently uses two distinct GEM contexts to have distinct logical
HW contexts for the compute and render pipelines. However, using two
distinct GEM contexts implies that they are distinct timelines, yet as
they are a single GL context that implies they belong to a single
timeline from the client perspective. Currently, fences are occasionally
inserted to order the two timelines. Using 2 GEM contexts, also implies
that we keep 2 ppGTT for identical buffer state. If we can create a
single GEM context, with the right capabilities, we can have a single
VM, a single timeline, but 2 logical HW contexts for the 2 pipelines.

This is allowed through the new context interface that allows VM to be
shared, timelines to be specified, and for the logical contexts to be
constructed as the user desires.

Cc: Joonas Lahtinen <joonas.lahtinen at linux.intel.com>
Cc: Kenneth Graunke <kenneth at whitecape.org>
---
 src/gallium/drivers/iris/iris_batch.c   | 16 ++-----
 src/gallium/drivers/iris/iris_batch.h   |  5 +--
 src/gallium/drivers/iris/iris_context.c | 56 ++++++++++++++++++++++++-
 3 files changed, 60 insertions(+), 17 deletions(-)

diff --git a/src/gallium/drivers/iris/iris_batch.c b/src/gallium/drivers/iris/iris_batch.c
index 556422c38bc..40bcd939795 100644
--- a/src/gallium/drivers/iris/iris_batch.c
+++ b/src/gallium/drivers/iris/iris_batch.c
@@ -164,24 +164,16 @@ iris_init_batch(struct iris_batch *batch,
                 struct iris_vtable *vtbl,
                 struct pipe_debug_callback *dbg,
                 struct iris_batch *all_batches,
-                enum iris_batch_name name,
-                uint8_t engine,
-                int priority)
+                uint32_t hw_id,
+                enum iris_batch_name name)
 {
    batch->screen = screen;
    batch->vtbl = vtbl;
    batch->dbg = dbg;
    batch->name = name;
 
-   /* engine should be one of I915_EXEC_RENDER, I915_EXEC_BLT, etc. */
-   assert((engine & ~I915_EXEC_RING_MASK) == 0);
-   assert(util_bitcount(engine) == 1);
-   batch->engine = engine;
-
-   batch->hw_ctx_id = iris_create_hw_context(screen->bufmgr);
-   assert(batch->hw_ctx_id);
-
-   iris_hw_context_set_priority(screen->bufmgr, batch->hw_ctx_id, priority);
+   batch->hw_ctx_id = hw_id;
+   batch->engine = name;
 
    util_dynarray_init(&batch->exec_fences, ralloc_context(NULL));
    util_dynarray_init(&batch->syncpts, ralloc_context(NULL));
diff --git a/src/gallium/drivers/iris/iris_batch.h b/src/gallium/drivers/iris/iris_batch.h
index 2a68103c379..db1a4cbbe11 100644
--- a/src/gallium/drivers/iris/iris_batch.h
+++ b/src/gallium/drivers/iris/iris_batch.h
@@ -131,9 +131,8 @@ void iris_init_batch(struct iris_batch *batch,
                      struct iris_vtable *vtbl,
                      struct pipe_debug_callback *dbg,
                      struct iris_batch *all_batches,
-                     enum iris_batch_name name,
-                     uint8_t ring,
-                     int priority);
+                     uint32_t hw_id,
+                     enum iris_batch_name name);
 void iris_chain_to_new_batch(struct iris_batch *batch);
 void iris_batch_free(struct iris_batch *batch);
 void iris_batch_maybe_flush(struct iris_batch *batch, unsigned estimate);
diff --git a/src/gallium/drivers/iris/iris_context.c b/src/gallium/drivers/iris/iris_context.c
index a1d11755a24..aeb608c70bd 100644
--- a/src/gallium/drivers/iris/iris_context.c
+++ b/src/gallium/drivers/iris/iris_context.c
@@ -143,6 +143,57 @@ iris_destroy_context(struct pipe_context *ctx)
       unreachable("Unknown hardware generation"); \
    }
 
+static void create_hw_contexts(struct iris_screen *screen,
+                               uint32_t *hw_id,
+                               int priority)
+{
+#define RCS0 {0, 0}
+   I915_DEFINE_CONTEXT_PARAM_ENGINES(engines, 2) = {
+      .class_instance = { RCS0, RCS0 }
+   };
+   struct drm_i915_gem_context_create_ext_setparam p_engines = {
+      .base = {
+         .name = I915_CONTEXT_CREATE_EXT_SETPARAM,
+	 .next_extension = 0, /* end of chain */
+      },
+      .param = {
+         .param = I915_CONTEXT_PARAM_ENGINES,
+         .value = (uintptr_t)&engines,
+         .size = sizeof(engines),
+      },
+   };
+   struct drm_i915_gem_context_create_ext_setparam p_prio = {
+      .base = {
+         .name =I915_CONTEXT_CREATE_EXT_SETPARAM,
+         .next_extension = (uintptr_t)&p_engines,
+      },
+      .param = {
+         .param = I915_CONTEXT_PARAM_PRIORITY,
+         .value = priority,
+      },
+   };
+   struct drm_i915_gem_context_create_ext arg = {
+      .flags = I915_CONTEXT_CREATE_FLAGS_SINGLE_TIMELINE |
+	       I915_CONTEXT_CREATE_FLAGS_USE_EXTENSIONS,
+      .extensions = (uintptr_t)&p_prio,
+   };
+
+   if (drm_ioctl(screen->fd,
+                 DRM_IOCTL_I915_GEM_CONTEXT_CREATE_EXT,
+                 &arg) == 0) {
+      for (int i = 0; i < IRIS_BATCH_COUNT; i++)
+         hw_id[i] = arg.ctx_id;
+      return;
+   }
+
+   /* No fancy new features; create two contexts instead */
+   for (int i = 0; i < IRIS_BATCH_COUNT; i++) {
+      hw_id[i] = iris_create_hw_context(screen->bufmgr);
+      assert(hw_id[i]);
+
+      iris_hw_context_set_priority(screen->bufmgr, hw_id[i], priority);
+   }
+}
 /**
  * Create a context.
  *
@@ -154,6 +205,7 @@ iris_create_context(struct pipe_screen *pscreen, void *priv, unsigned flags)
    struct iris_screen *screen = (struct iris_screen*)pscreen;
    const struct gen_device_info *devinfo = &screen->devinfo;
    struct iris_context *ice = rzalloc(NULL, struct iris_context);
+   uint32_t hw_id[IRIS_BATCH_COUNT];
 
    if (!ice)
       return NULL;
@@ -210,10 +262,10 @@ iris_create_context(struct pipe_screen *pscreen, void *priv, unsigned flags)
    if (flags & PIPE_CONTEXT_LOW_PRIORITY)
       priority = GEN_CONTEXT_LOW_PRIORITY;
 
+   create_hw_contexts(screen, hw_id, priority);
    for (int i = 0; i < IRIS_BATCH_COUNT; i++) {
       iris_init_batch(&ice->batches[i], screen, &ice->vtbl, &ice->dbg,
-                      ice->batches, (enum iris_batch_name) i,
-                      I915_EXEC_RENDER, priority);
+                      ice->batches, hw_id[i], (enum iris_batch_name) i);
    }
 
    ice->vtbl.init_render_context(screen, &ice->batches[IRIS_BATCH_RENDER],
-- 
2.20.1



More information about the mesa-dev mailing list