Mesa (main): iris/batch: Add support for engines contexts
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Fri Dec 3 01:14:04 UTC 2021
Module: Mesa
Branch: main
Commit: 5c4c8bdc4c54a1f3d7e496e52476124366e6e7d6
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=5c4c8bdc4c54a1f3d7e496e52476124366e6e7d6
Author: Jordan Justen <jordan.l.justen at intel.com>
Date: Tue Aug 31 13:37:12 2021 -0700
iris/batch: Add support for engines contexts
As described in "intel: Add intel_gem_create_context_engines", this
should make it easier to support an I915_ENGINE_CLASS_FOO engine in
the future. For example, maybe something like:
https://gitlab.freedesktop.org/drm/igt-gpu-tools/-/commit/98c3bbd5b54eb9914329155bfeddd0ad88f96ad2
Reworks:
* Tweak engine counting logic (s-b Ken)
* Tweak init of engine_classes in iris_init_engines_context (s-b Ken)
* Add STATIC_ASSERT on engine_classes (Jordan)
* Paulo: Call iris_hw_context_set_unrecoverable() for engines context
* Rename to has_engines_context (s-b Paulo)
* Jordan: Handle creating a new engines context when the context needs
to be replaced.
* Ken: Tweak context destroy code paths.
* Call iris_lost_context_state on every batch. (s-b Ken)
Signed-off-by: Jordan Justen <jordan.l.justen at intel.com>
Reviewed-by: Paulo Zanoni <paulo.r.zanoni at intel.com>
Reviewed-by: Kenneth Graunke <kenneth at whitecape.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12692>
---
src/gallium/drivers/iris/iris_batch.c | 116 ++++++++++++++++++++++++++++++----
src/gallium/drivers/iris/iris_batch.h | 1 +
2 files changed, 105 insertions(+), 12 deletions(-)
diff --git a/src/gallium/drivers/iris/iris_batch.c b/src/gallium/drivers/iris/iris_batch.c
index 6b297a1dbe5..6a999123b84 100644
--- a/src/gallium/drivers/iris/iris_batch.c
+++ b/src/gallium/drivers/iris/iris_batch.c
@@ -180,6 +180,12 @@ iris_init_batch(struct iris_context *ice,
struct iris_batch *batch = &ice->batches[name];
struct iris_screen *screen = (void *) ice->ctx.screen;
+ /* Note: ctx_id, exec_flags and has_engines_context fields are initialized
+ * at an earlier phase when contexts are created.
+ *
+ * Ref: iris_init_engines_context(), iris_init_non_engine_contexts()
+ */
+
batch->screen = screen;
batch->dbg = &ice->dbg;
batch->reset = &ice->reset;
@@ -243,15 +249,75 @@ iris_init_non_engine_contexts(struct iris_context *ice, int priority)
struct iris_batch *batch = &ice->batches[i];
batch->ctx_id = iris_create_hw_context(screen->bufmgr);
batch->exec_flags = I915_EXEC_RENDER;
+ batch->has_engines_context = false;
assert(batch->ctx_id);
iris_hw_context_set_priority(screen->bufmgr, batch->ctx_id, priority);
}
}
+static int
+iris_create_engines_context(struct iris_context *ice, int priority)
+{
+ struct iris_screen *screen = (void *) ice->ctx.screen;
+ int fd = iris_bufmgr_get_fd(screen->bufmgr);
+
+ struct drm_i915_query_engine_info *engines_info =
+ intel_i915_query_alloc(fd, DRM_I915_QUERY_ENGINE_INFO);
+
+ if (!engines_info)
+ return -1;
+
+ if (intel_gem_count_engines(engines_info, I915_ENGINE_CLASS_RENDER) < 1) {
+ free(engines_info);
+ return -1;
+ }
+
+ STATIC_ASSERT(IRIS_BATCH_COUNT == 2);
+ uint16_t engine_classes[IRIS_BATCH_COUNT] = {
+ [IRIS_BATCH_RENDER] = I915_ENGINE_CLASS_RENDER,
+ [IRIS_BATCH_COMPUTE] = I915_ENGINE_CLASS_RENDER,
+ };
+
+ int engines_ctx =
+ intel_gem_create_context_engines(fd, engines_info, IRIS_BATCH_COUNT,
+ engine_classes);
+
+ if (engines_ctx < 0) {
+ free(engines_info);
+ return -1;
+ }
+
+ iris_hw_context_set_unrecoverable(screen->bufmgr, engines_ctx);
+
+ free(engines_info);
+ return engines_ctx;
+}
+
+static bool
+iris_init_engines_context(struct iris_context *ice, int priority)
+{
+ int engines_ctx = iris_create_engines_context(ice, priority);
+ if (engines_ctx < 0)
+ return false;
+
+ struct iris_screen *screen = (void *) ice->ctx.screen;
+ iris_hw_context_set_priority(screen->bufmgr, engines_ctx, priority);
+
+ for (int i = 0; i < IRIS_BATCH_COUNT; i++) {
+ struct iris_batch *batch = &ice->batches[i];
+ batch->ctx_id = engines_ctx;
+ batch->exec_flags = i;
+ batch->has_engines_context = true;
+ }
+
+ return true;
+}
+
void
iris_init_batches(struct iris_context *ice, int priority)
{
- iris_init_non_engine_contexts(ice, priority);
+ if (!iris_init_engines_context(ice, priority))
+ iris_init_non_engine_contexts(ice, priority);
for (int i = 0; i < IRIS_BATCH_COUNT; i++)
iris_init_batch(ice, (enum iris_batch_name) i);
}
@@ -488,7 +554,9 @@ iris_batch_free(struct iris_batch *batch)
batch->map = NULL;
batch->map_next = NULL;
- iris_destroy_kernel_context(bufmgr, batch->ctx_id);
+ /* iris_destroy_batches() will destroy engines contexts. */
+ if (!batch->has_engines_context)
+ iris_destroy_kernel_context(bufmgr, batch->ctx_id);
iris_destroy_batch_measure(batch->measure);
batch->measure = NULL;
@@ -502,6 +570,15 @@ iris_batch_free(struct iris_batch *batch)
void
iris_destroy_batches(struct iris_context *ice)
{
+ /* If we are using an engines context, then a single kernel context is
+ * created, with multiple hardware contexts. So, we only need to destroy
+ * the context on the first batch.
+ */
+ if (ice->batches[0].has_engines_context) {
+ iris_destroy_kernel_context(ice->batches[0].screen->bufmgr,
+ ice->batches[0].ctx_id);
+ }
+
for (int i = 0; i < IRIS_BATCH_COUNT; i++)
iris_batch_free(&ice->batches[i]);
}
@@ -616,20 +693,35 @@ iris_finish_batch(struct iris_batch *batch)
* Replace our current GEM context with a new one (in case it got banned).
*/
static bool
-replace_hw_ctx(struct iris_batch *batch)
+replace_kernel_ctx(struct iris_batch *batch)
{
struct iris_screen *screen = batch->screen;
struct iris_bufmgr *bufmgr = screen->bufmgr;
- uint32_t new_ctx = iris_clone_hw_context(bufmgr, batch->ctx_id);
- if (!new_ctx)
- return false;
+ if (batch->has_engines_context) {
+ struct iris_context *ice = batch->ice;
+ int priority = iris_kernel_context_get_priority(bufmgr, batch->ctx_id);
+ uint32_t old_ctx = batch->ctx_id;
+ int new_ctx = iris_create_engines_context(ice, priority);
+ if (new_ctx < 0)
+ return false;
+ for (int i = 0; i < IRIS_BATCH_COUNT; i++) {
+ ice->batches[i].ctx_id = new_ctx;
+ /* Notify the context that state must be re-initialized. */
+ iris_lost_context_state(&ice->batches[i]);
+ }
+ iris_destroy_kernel_context(bufmgr, old_ctx);
+ } else {
+ uint32_t new_ctx = iris_clone_hw_context(bufmgr, batch->ctx_id);
+ if (!new_ctx)
+ return false;
- iris_destroy_kernel_context(bufmgr, batch->ctx_id);
- batch->ctx_id = new_ctx;
+ iris_destroy_kernel_context(bufmgr, batch->ctx_id);
+ batch->ctx_id = new_ctx;
- /* Notify the context that state must be re-initialized. */
- iris_lost_context_state(batch);
+ /* Notify the context that state must be re-initialized. */
+ iris_lost_context_state(batch);
+ }
return true;
}
@@ -662,7 +754,7 @@ iris_batch_check_for_reset(struct iris_batch *batch)
* Throw it away and start with a fresh context. Ideally this may
* catch the problem before our next execbuf fails with -EIO.
*/
- replace_hw_ctx(batch);
+ replace_kernel_ctx(batch);
}
return status;
@@ -970,7 +1062,7 @@ _iris_batch_flush(struct iris_batch *batch, const char *file, int line)
* dubiously claim success...
* Also handle ENOMEM here.
*/
- if ((ret == -EIO || ret == -ENOMEM) && replace_hw_ctx(batch)) {
+ if ((ret == -EIO || ret == -ENOMEM) && replace_kernel_ctx(batch)) {
if (batch->reset->reset) {
/* Tell gallium frontends the device is lost and it was our fault. */
batch->reset->reset(batch->reset->data, PIPE_GUILTY_CONTEXT_RESET);
diff --git a/src/gallium/drivers/iris/iris_batch.h b/src/gallium/drivers/iris/iris_batch.h
index 09691efe0f3..6a5767985d9 100644
--- a/src/gallium/drivers/iris/iris_batch.h
+++ b/src/gallium/drivers/iris/iris_batch.h
@@ -81,6 +81,7 @@ struct iris_batch {
uint32_t ctx_id;
uint32_t exec_flags;
+ bool has_engines_context;
/** A list of all BOs referenced by this batch */
struct iris_bo **exec_bos;
More information about the mesa-commit
mailing list