OSDN Git Service

drm/i915/uapi: Add DRM_I915_QUERY_GEOMETRY_SUBSLICES
authorMatt Atwood <matthew.s.atwood@intel.com>
Thu, 14 Apr 2022 19:22:30 +0000 (12:22 -0700)
committerMatt Roper <matthew.d.roper@intel.com>
Fri, 15 Apr 2022 15:00:55 +0000 (08:00 -0700)
Newer platforms have DSS that aren't necessarily available for both
geometry and compute, two queries will need to exist. This introduces
the first, when passing a valid engine class and engine instance in the
flags returns a topology describing geometry.

Based on past discussion, we currently only support this new query item
on Xe_HP and beyond; earlier platforms do not need to worry about
geometry and compute pipelines having access to different topology and
should continue to use the existing topology query.

v2: fix white space errors
v3: change flags from hosting 2 8 bit numbers to holding a
i915_engine_class_instance struct
v4: add error if non rcs engine passed.
v5 (by MattR):
 - Improve kerneldoc and cross references to related structs/enums.
   (Daniel)
 - Clarify that geometry query is only supported on render engines
   (Francisco)
 - Clarify that the new query is only supported on Xe_HP+.
 - Fix checkpatch warnings.

Cc: Ashutosh Dixit <ashutosh.dixit@intel.com>
Cc: Matt Roper <matthew.d.roper@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Francisco Jerez <currojerez@riseup.net>
UMD (mesa): https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14143
Testcase: igt@i915_query@test-query-geometry-subslices
Signed-off-by: Matt Atwood <matthew.s.atwood@intel.com>
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
Reviewed-by: Francisco Jerez <currojerez@riseup.net>
Link: https://patchwork.freedesktop.org/patch/msgid/20220414192230.749771-4-matthew.d.roper@intel.com
drivers/gpu/drm/i915/i915_query.c
include/uapi/drm/i915_drm.h

index b5ca00c..7584cec 100644 (file)
@@ -9,6 +9,7 @@
 #include "i915_drv.h"
 #include "i915_perf.h"
 #include "i915_query.h"
+#include "gt/intel_engine_user.h"
 #include <uapi/drm/i915_drm.h>
 
 static int copy_query_item(void *query_hdr, size_t query_sz,
@@ -28,36 +29,30 @@ static int copy_query_item(void *query_hdr, size_t query_sz,
        return 0;
 }
 
-static int query_topology_info(struct drm_i915_private *dev_priv,
-                              struct drm_i915_query_item *query_item)
+static int fill_topology_info(const struct sseu_dev_info *sseu,
+                             struct drm_i915_query_item *query_item,
+                             const u8 *subslice_mask)
 {
-       const struct sseu_dev_info *sseu = &to_gt(dev_priv)->info.sseu;
        struct drm_i915_query_topology_info topo;
        u32 slice_length, subslice_length, eu_length, total_length;
        int ret;
 
-       if (query_item->flags != 0)
-               return -EINVAL;
+       BUILD_BUG_ON(sizeof(u8) != sizeof(sseu->slice_mask));
 
        if (sseu->max_slices == 0)
                return -ENODEV;
 
-       BUILD_BUG_ON(sizeof(u8) != sizeof(sseu->slice_mask));
-
        slice_length = sizeof(sseu->slice_mask);
        subslice_length = sseu->max_slices * sseu->ss_stride;
        eu_length = sseu->max_slices * sseu->max_subslices * sseu->eu_stride;
        total_length = sizeof(topo) + slice_length + subslice_length +
                       eu_length;
 
-       ret = copy_query_item(&topo, sizeof(topo), total_length,
-                             query_item);
+       ret = copy_query_item(&topo, sizeof(topo), total_length, query_item);
+
        if (ret != 0)
                return ret;
 
-       if (topo.flags != 0)
-               return -EINVAL;
-
        memset(&topo, 0, sizeof(topo));
        topo.max_slices = sseu->max_slices;
        topo.max_subslices = sseu->max_subslices;
@@ -69,27 +64,64 @@ static int query_topology_info(struct drm_i915_private *dev_priv,
        topo.eu_stride = sseu->eu_stride;
 
        if (copy_to_user(u64_to_user_ptr(query_item->data_ptr),
-                          &topo, sizeof(topo)))
+                        &topo, sizeof(topo)))
                return -EFAULT;
 
        if (copy_to_user(u64_to_user_ptr(query_item->data_ptr + sizeof(topo)),
-                          &sseu->slice_mask, slice_length))
+                        &sseu->slice_mask, slice_length))
                return -EFAULT;
 
        if (copy_to_user(u64_to_user_ptr(query_item->data_ptr +
-                                          sizeof(topo) + slice_length),
-                          sseu->subslice_mask, subslice_length))
+                                        sizeof(topo) + slice_length),
+                        subslice_mask, subslice_length))
                return -EFAULT;
 
        if (copy_to_user(u64_to_user_ptr(query_item->data_ptr +
-                                          sizeof(topo) +
-                                          slice_length + subslice_length),
-                          sseu->eu_mask, eu_length))
+                                        sizeof(topo) +
+                                        slice_length + subslice_length),
+                        sseu->eu_mask, eu_length))
                return -EFAULT;
 
        return total_length;
 }
 
+static int query_topology_info(struct drm_i915_private *dev_priv,
+                              struct drm_i915_query_item *query_item)
+{
+       const struct sseu_dev_info *sseu = &to_gt(dev_priv)->info.sseu;
+
+       if (query_item->flags != 0)
+               return -EINVAL;
+
+       return fill_topology_info(sseu, query_item, sseu->subslice_mask);
+}
+
+static int query_geometry_subslices(struct drm_i915_private *i915,
+                                   struct drm_i915_query_item *query_item)
+{
+       const struct sseu_dev_info *sseu;
+       struct intel_engine_cs *engine;
+       struct i915_engine_class_instance classinstance;
+
+       if (GRAPHICS_VER_FULL(i915) < IP_VER(12, 50))
+               return -ENODEV;
+
+       classinstance = *((struct i915_engine_class_instance *)&query_item->flags);
+
+       engine = intel_engine_lookup_user(i915, (u8)classinstance.engine_class,
+                                         (u8)classinstance.engine_instance);
+
+       if (!engine)
+               return -EINVAL;
+
+       if (engine->class != RENDER_CLASS)
+               return -EINVAL;
+
+       sseu = &engine->gt->info.sseu;
+
+       return fill_topology_info(sseu, query_item, sseu->geometry_subslice_mask);
+}
+
 static int
 query_engine_info(struct drm_i915_private *i915,
                  struct drm_i915_query_item *query_item)
@@ -508,6 +540,7 @@ static int (* const i915_query_funcs[])(struct drm_i915_private *dev_priv,
        query_perf_config,
        query_memregion_info,
        query_hwconfig_blob,
+       query_geometry_subslices,
 };
 
 int i915_query_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
index 097a793..35ca528 100644 (file)
@@ -172,7 +172,9 @@ enum drm_i915_gem_engine_class {
        I915_ENGINE_CLASS_INVALID       = -1
 };
 
-/*
+/**
+ * struct i915_engine_class_instance - Engine class/instance identifier
+ *
  * There may be more than one engine fulfilling any role within the system.
  * Each engine of a class is given a unique instance number and therefore
  * any engine can be specified by its class:instance tuplet. APIs that allow
@@ -180,10 +182,21 @@ enum drm_i915_gem_engine_class {
  * for this identification.
  */
 struct i915_engine_class_instance {
-       __u16 engine_class; /* see enum drm_i915_gem_engine_class */
-       __u16 engine_instance;
+       /**
+        * @engine_class:
+        *
+        * Engine class from enum drm_i915_gem_engine_class
+        */
+       __u16 engine_class;
 #define I915_ENGINE_CLASS_INVALID_NONE -1
 #define I915_ENGINE_CLASS_INVALID_VIRTUAL -2
+
+       /**
+        * @engine_instance:
+        *
+        * Engine instance.
+        */
+       __u16 engine_instance;
 };
 
 /**
@@ -2735,6 +2748,7 @@ struct drm_i915_query_item {
         *  - %DRM_I915_QUERY_PERF_CONFIG (see struct drm_i915_query_perf_config)
         *  - %DRM_I915_QUERY_MEMORY_REGIONS (see struct drm_i915_query_memory_regions)
         *  - %DRM_I915_QUERY_HWCONFIG_BLOB (see `GuC HWCONFIG blob uAPI`)
+        *  - %DRM_I915_QUERY_GEOMETRY_SUBSLICES (see struct drm_i915_query_topology_info)
         */
        __u64 query_id;
 #define DRM_I915_QUERY_TOPOLOGY_INFO           1
@@ -2742,6 +2756,7 @@ struct drm_i915_query_item {
 #define DRM_I915_QUERY_PERF_CONFIG             3
 #define DRM_I915_QUERY_MEMORY_REGIONS          4
 #define DRM_I915_QUERY_HWCONFIG_BLOB           5
+#define DRM_I915_QUERY_GEOMETRY_SUBSLICES      6
 /* Must be kept compact -- no holes and well documented */
 
        /**
@@ -2765,6 +2780,9 @@ struct drm_i915_query_item {
         *      - %DRM_I915_QUERY_PERF_CONFIG_LIST
         *      - %DRM_I915_QUERY_PERF_CONFIG_DATA_FOR_UUID
         *      - %DRM_I915_QUERY_PERF_CONFIG_FOR_UUID
+        *
+        * When &query_id == %DRM_I915_QUERY_GEOMETRY_SUBSLICES must contain
+        * a struct i915_engine_class_instance that references a render engine.
         */
        __u32 flags;
 #define DRM_I915_QUERY_PERF_CONFIG_LIST          1
@@ -3051,7 +3069,8 @@ struct drm_i915_query_engine_info {
 /**
  * struct drm_i915_query_perf_config
  *
- * Data written by the kernel with query %DRM_I915_QUERY_PERF_CONFIG.
+ * Data written by the kernel with query %DRM_I915_QUERY_PERF_CONFIG and
+ * %DRM_I915_QUERY_GEOMETRY_SUBSLICES.
  */
 struct drm_i915_query_perf_config {
        union {