Mesa (main): intel: Add intel_gem_create_context_engines

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Fri Dec 3 01:14:03 UTC 2021


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

Author: Jordan Justen <jordan.l.justen at intel.com>
Date:   Tue Aug 31 02:29:41 2021 -0700

intel: Add intel_gem_create_context_engines

Engines based contexts operate somewhat different for executing
batches. Previously, we would specify a bitmask value such as
I915_EXEC_RENDER to specify to run the batch on the render ring.

With engines contexts, instead this becomes an array of "engines", and
when the context is created we specify the class and instance of the
engine.

Each index in the array has a separate hardware-context. Previously we
had to create separate kernel level contexts to create multiple
hardware contexts, but now a single kernel context can own multiple
hardware contexts.

Another forward looking advantage to using the engines based contexts
is that the kernel does not plan to add new supported I915_EXEC_FOO
masks, whereas they instead plan to add new I915_ENGINE_CLASS_FOO
engine classes. Therefore some rings may only be usable with an engine
based class.

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/intel/common/intel_gem.c     | 86 ++++++++++++++++++++++++++++++++++++++++
 src/intel/common/intel_gem.h     |  3 ++
 src/intel/vulkan/anv_device.c    |  6 +--
 src/intel/vulkan/anv_gem.c       | 84 ---------------------------------------
 src/intel/vulkan/anv_gem_stubs.c |  9 -----
 src/intel/vulkan/anv_private.h   |  4 --
 6 files changed, 92 insertions(+), 100 deletions(-)

diff --git a/src/intel/common/intel_gem.c b/src/intel/common/intel_gem.c
index 8634486be15..267d0657315 100644
--- a/src/intel/common/intel_gem.c
+++ b/src/intel/common/intel_gem.c
@@ -68,3 +68,89 @@ intel_gem_count_engines(const struct drm_i915_query_engine_info *info,
    }
    return count;
 }
+
+int
+intel_gem_create_context_engines(int fd,
+                                 const struct drm_i915_query_engine_info *info,
+                                 int num_engines, uint16_t *engine_classes)
+{
+   assert(info != NULL);
+   const size_t engine_inst_sz = 2 * sizeof(__u16); /* 1 class, 1 instance */
+   const size_t engines_param_size =
+      sizeof(__u64) /* extensions */ + num_engines * engine_inst_sz;
+
+   void *engines_param = malloc(engines_param_size);
+   assert(engines_param);
+   *(__u64*)engines_param = 0;
+   __u16 *class_inst_ptr = (__u16*)(((__u64*)engines_param) + 1);
+
+   /* For each type of drm_i915_gem_engine_class of interest, we keep track of
+    * the previous engine instance used.
+    */
+   int last_engine_idx[] = {
+      [I915_ENGINE_CLASS_RENDER] = -1,
+   };
+
+   int i915_engine_counts[] = {
+      [I915_ENGINE_CLASS_RENDER] =
+         intel_gem_count_engines(info, I915_ENGINE_CLASS_RENDER),
+   };
+
+   /* For each queue, we look for the next instance that matches the class we
+    * need.
+    */
+   for (int i = 0; i < num_engines; i++) {
+      uint16_t engine_class = engine_classes[i];
+      assert(engine_class == I915_ENGINE_CLASS_RENDER);
+      if (i915_engine_counts[engine_class] <= 0) {
+         free(engines_param);
+         return -1;
+      }
+
+      /* Run through the engines reported by the kernel looking for the next
+       * matching instance. We loop in case we want to create multiple
+       * contexts on an engine instance.
+       */
+      int engine_instance = -1;
+      for (int i = 0; i < info->num_engines; i++) {
+         int *idx = &last_engine_idx[engine_class];
+         if (++(*idx) >= info->num_engines)
+            *idx = 0;
+         if (info->engines[*idx].engine.engine_class == engine_class) {
+            engine_instance = info->engines[*idx].engine.engine_instance;
+            break;
+         }
+      }
+      if (engine_instance < 0) {
+         free(engines_param);
+         return -1;
+      }
+
+      *class_inst_ptr++ = engine_class;
+      *class_inst_ptr++ = engine_instance;
+   }
+
+   assert((uintptr_t)engines_param + engines_param_size ==
+          (uintptr_t)class_inst_ptr);
+
+   struct drm_i915_gem_context_create_ext_setparam set_engines = {
+      .base = {
+         .name = I915_CONTEXT_CREATE_EXT_SETPARAM,
+      },
+      .param = {
+         .param = I915_CONTEXT_PARAM_ENGINES,
+         .value = (uintptr_t)engines_param,
+         .size = engines_param_size,
+      }
+   };
+   struct drm_i915_gem_context_create_ext create = {
+      .flags = I915_CONTEXT_CREATE_FLAGS_USE_EXTENSIONS,
+      .extensions = (uintptr_t)&set_engines,
+   };
+   int ret = intel_ioctl(fd, DRM_IOCTL_I915_GEM_CONTEXT_CREATE_EXT, &create);
+   free(engines_param);
+   if (ret == -1)
+      return -1;
+
+   return create.ctx_id;
+}
diff --git a/src/intel/common/intel_gem.h b/src/intel/common/intel_gem.h
index 31380b714a9..12481e2dad6 100644
--- a/src/intel/common/intel_gem.h
+++ b/src/intel/common/intel_gem.h
@@ -148,5 +148,8 @@ bool intel_gem_supports_syncobj_wait(int fd);
 
 int intel_gem_count_engines(const struct drm_i915_query_engine_info *info,
                             enum drm_i915_gem_engine_class engine_class);
+int intel_gem_create_context_engines(int fd,
+                                     const struct drm_i915_query_engine_info *info,
+                                     int num_engines, uint16_t *engine_classes);
 
 #endif /* INTEL_GEM_H */
diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c
index d6fc0268bdd..bcaddf88a99 100644
--- a/src/intel/vulkan/anv_device.c
+++ b/src/intel/vulkan/anv_device.c
@@ -3063,9 +3063,9 @@ VkResult anv_CreateDevice(
             engine_classes[engine_count++] = queue_family->engine_class;
       }
       device->context_id =
-         anv_gem_create_context_engines(device,
-                                        physical_device->engine_info,
-                                        engine_count, engine_classes);
+         intel_gem_create_context_engines(device->fd,
+                                          physical_device->engine_info,
+                                          engine_count, engine_classes);
    } else {
       assert(num_queues == 1);
       device->context_id = anv_gem_create_context(device);
diff --git a/src/intel/vulkan/anv_gem.c b/src/intel/vulkan/anv_gem.c
index cabce04e123..cdfac0b1786 100644
--- a/src/intel/vulkan/anv_gem.c
+++ b/src/intel/vulkan/anv_gem.c
@@ -337,90 +337,6 @@ anv_gem_create_context(struct anv_device *device)
    return create.ctx_id;
 }
 
-int
-anv_gem_create_context_engines(struct anv_device *device,
-                               const struct drm_i915_query_engine_info *info,
-                               int num_engines, uint16_t *engine_classes)
-{
-   const size_t engine_inst_sz = 2 * sizeof(__u16); /* 1 class, 1 instance */
-   const size_t engines_param_size =
-      sizeof(__u64) /* extensions */ + num_engines * engine_inst_sz;
-
-   void *engines_param = malloc(engines_param_size);
-   assert(engines_param);
-   *(__u64*)engines_param = 0;
-   __u16 *class_inst_ptr = (__u16*)(((__u64*)engines_param) + 1);
-
-   /* For each type of drm_i915_gem_engine_class of interest, we keep track of
-    * the previous engine instance used.
-    */
-   int last_engine_idx[] = {
-      [I915_ENGINE_CLASS_RENDER] = -1,
-   };
-
-   int i915_engine_counts[] = {
-      [I915_ENGINE_CLASS_RENDER] =
-         intel_gem_count_engines(info, I915_ENGINE_CLASS_RENDER),
-   };
-
-   /* For each queue, we look for the next instance that matches the class we
-    * need.
-    */
-   for (int i = 0; i < num_engines; i++) {
-      uint16_t engine_class = engine_classes[i];
-      if (i915_engine_counts[engine_class] <= 0) {
-         free(engines_param);
-         return -1;
-      }
-
-      /* Run through the engines reported by the kernel looking for the next
-       * matching instance. We loop in case we want to create multiple
-       * contexts on an engine instance.
-       */
-      int engine_instance = -1;
-      for (int i = 0; i < info->num_engines; i++) {
-         int *idx = &last_engine_idx[engine_class];
-         if (++(*idx) >= info->num_engines)
-            *idx = 0;
-         if (info->engines[*idx].engine.engine_class == engine_class) {
-            engine_instance = info->engines[*idx].engine.engine_instance;
-            break;
-         }
-      }
-      if (engine_instance < 0) {
-         free(engines_param);
-         return -1;
-      }
-
-      *class_inst_ptr++ = engine_class;
-      *class_inst_ptr++ = engine_instance;
-   }
-
-   assert((uintptr_t)engines_param + engines_param_size ==
-          (uintptr_t)class_inst_ptr);
-
-   struct drm_i915_gem_context_create_ext_setparam set_engines = {
-      .base = {
-         .name = I915_CONTEXT_CREATE_EXT_SETPARAM,
-      },
-      .param = {
-	 .param = I915_CONTEXT_PARAM_ENGINES,
-         .value = (uintptr_t)engines_param,
-         .size = engines_param_size,
-      }
-   };
-   struct drm_i915_gem_context_create_ext create = {
-      .flags = I915_CONTEXT_CREATE_FLAGS_USE_EXTENSIONS,
-      .extensions = (uintptr_t)&set_engines,
-   };
-   int ret = intel_ioctl(device->fd, DRM_IOCTL_I915_GEM_CONTEXT_CREATE_EXT, &create);
-   free(engines_param);
-   if (ret == -1)
-      return -1;
-
-   return create.ctx_id;
-}
-
 int
 anv_gem_destroy_context(struct anv_device *device, int context)
 {
diff --git a/src/intel/vulkan/anv_gem_stubs.c b/src/intel/vulkan/anv_gem_stubs.c
index 7f4a7960c02..6dc971522af 100644
--- a/src/intel/vulkan/anv_gem_stubs.c
+++ b/src/intel/vulkan/anv_gem_stubs.c
@@ -193,15 +193,6 @@ anv_i915_query(int fd, uint64_t query_id, void *buffer,
    unreachable("Unused");
 }
 
-int
-anv_gem_create_context_engines(struct anv_device *device,
-                               const struct drm_i915_query_engine_info *info,
-                               int num_engines,
-                               uint16_t *engine_classes)
-{
-   unreachable("Unused");
-}
-
 struct drm_i915_query_engine_info *
 anv_gem_get_engine_info(int fd)
 {
diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
index 45813225e06..d91339d8a3f 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -1365,10 +1365,6 @@ int anv_gem_execbuffer(struct anv_device *device,
 int anv_gem_set_tiling(struct anv_device *device, uint32_t gem_handle,
                        uint32_t stride, uint32_t tiling);
 int anv_gem_create_context(struct anv_device *device);
-int anv_gem_create_context_engines(struct anv_device *device,
-                                   const struct drm_i915_query_engine_info *info,
-                                   int num_engines,
-                                   uint16_t *engine_classes);
 bool anv_gem_has_context_priority(int fd, int priority);
 int anv_gem_destroy_context(struct anv_device *device, int context);
 int anv_gem_set_context_param(int fd, int context, uint32_t param,



More information about the mesa-commit mailing list