i965: Move device info initialization to common code
authorMark Janes <mark.a.janes@intel.com>
Wed, 24 Jul 2019 20:48:03 +0000 (13:48 -0700)
committerMark Janes <mark.a.janes@intel.com>
Thu, 1 Aug 2019 23:39:44 +0000 (16:39 -0700)
With perf queries, initializing the device info is much more complex
than just getting a PCI ID and calling gen_get_device_info.  This commit
adds a new gen_get_device_info_from_fd helper in common code which does
all of the requisite kernel queries to get device info including all of
the topology information.

Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
src/intel/dev/gen_device_info.c
src/intel/dev/gen_device_info.h
src/mesa/drivers/dri/i965/brw_performance_query.c
src/mesa/drivers/dri/i965/intel_screen.c

index 6f3b6ff35b6894aa90700567d77e46e38c5cadc2..79ec4e0262d1348b147c5a321e5224142a04a1ad 100644 (file)
@@ -29,6 +29,7 @@
 #include <unistd.h>
 #include "gen_device_info.h"
 #include "compiler/shader_enums.h"
+#include "intel/common/gen_gem.h"
 #include "util/bitscan.h"
 #include "util/macros.h"
 
@@ -1182,6 +1183,24 @@ gen_device_info_update_from_topology(struct gen_device_info *devinfo,
    devinfo->num_eu_per_subslice = DIV_ROUND_UP(n_eus, n_subslices);
 }
 
+static bool
+getparam(int fd, uint32_t param, int *value)
+{
+   int tmp;
+
+   struct drm_i915_getparam gp = {
+      .param = param,
+      .value = &tmp,
+   };
+
+   int ret = gen_ioctl(fd, DRM_IOCTL_I915_GETPARAM, &gp);
+   if (ret != 0)
+      return false;
+
+   *value = tmp;
+   return true;
+}
+
 bool
 gen_get_device_info(int devid, struct gen_device_info *devinfo)
 {
@@ -1229,6 +1248,7 @@ gen_get_device_info(int devid, struct gen_device_info *devinfo)
 
    assert(devinfo->num_slices <= ARRAY_SIZE(devinfo->num_subslices));
 
+   devinfo->chipset_id = devid;
    return true;
 }
 
@@ -1243,3 +1263,109 @@ gen_get_device_name(int devid)
       return NULL;
    }
 }
+
+/**
+ * for gen8/gen9, SLICE_MASK/SUBSLICE_MASK can be used to compute the topology
+ * (kernel 4.13+)
+ */
+static bool
+getparam_topology(struct gen_device_info *devinfo, int fd)
+{
+   int slice_mask = 0;
+   if (!getparam(fd, I915_PARAM_SLICE_MASK, &slice_mask))
+      return false;
+
+   int n_eus;
+   if (!getparam(fd, I915_PARAM_EU_TOTAL, &n_eus))
+      return false;
+
+   int subslice_mask = 0;
+   if (!getparam(fd, I915_PARAM_SUBSLICE_MASK, &subslice_mask))
+      return false;
+
+   return gen_device_info_update_from_masks(devinfo,
+                                            slice_mask,
+                                            subslice_mask,
+                                            n_eus);
+}
+
+/**
+ * preferred API for updating the topology in devinfo (kernel 4.17+)
+ */
+static bool
+query_topology(struct gen_device_info *devinfo, int fd)
+{
+   struct drm_i915_query_item item = {
+      .query_id = DRM_I915_QUERY_TOPOLOGY_INFO,
+   };
+   struct drm_i915_query query = {
+      .num_items = 1,
+      .items_ptr = (uintptr_t) &item,
+   };
+
+   if (gen_ioctl(fd, DRM_IOCTL_I915_QUERY, &query))
+      return false;
+
+   struct drm_i915_query_topology_info *topo_info =
+      (struct drm_i915_query_topology_info *) calloc(1, item.length);
+   item.data_ptr = (uintptr_t) topo_info;
+
+   if (gen_ioctl(fd, DRM_IOCTL_I915_QUERY, &query) ||
+       item.length <= 0)
+      return false;
+
+   gen_device_info_update_from_topology(devinfo,
+                                        topo_info);
+
+   free(topo_info);
+
+   return true;
+
+}
+
+bool
+gen_get_device_info_from_fd(int fd, struct gen_device_info *devinfo)
+{
+   int devid = gen_get_pci_device_id_override();
+   if (devid > 0) {
+      if (!gen_get_device_info(devid, devinfo))
+         return false;
+      devinfo->no_hw = true;
+   } else {
+      /* query the device id */
+      if (!getparam(fd, I915_PARAM_CHIPSET_ID, &devid))
+         return false;
+      if (!gen_get_device_info(devid, devinfo))
+         return false;
+      devinfo->no_hw = false;
+   }
+
+   /* remaining initializion queries the kernel for device info */
+   if (devinfo->no_hw)
+      return true;
+
+   int timestamp_frequency;
+   if (getparam(fd, I915_PARAM_CS_TIMESTAMP_FREQUENCY,
+                &timestamp_frequency))
+      devinfo->timestamp_frequency = timestamp_frequency;
+   else if (devinfo->gen >= 10)
+      /* gen10 and later requires the timestamp_frequency to be updated */
+      return false;
+
+   if (!getparam(fd, I915_PARAM_REVISION, &devinfo->revision))
+       return false;
+
+   if (!query_topology(devinfo, fd)) {
+      if (devinfo->gen >= 10) {
+         /* topology uAPI required for CNL+ (kernel 4.17+) */
+         return false;
+      }
+
+      /* else use the kernel 4.13+ api for gen8+.  For older kernels, topology
+       * will be wrong, affecting GPU metrics. In this case, fail silently.
+       */
+      getparam_topology(devinfo, fd);
+   }
+
+   return true;
+}
index 6199290f9953ae50bd75ba7da2c4618f38f573ec..d1c7230b0ffb514ffa4cf20a898adf94828af0be 100644 (file)
@@ -248,6 +248,15 @@ struct gen_device_info
     */
    int simulator_id;
 
+   /**
+    * holds the pci device id
+    */
+   uint32_t chipset_id;
+
+   /**
+    * no_hw is true when the chipset_id pci device id has been overridden
+    */
+   bool no_hw;
    /** @} */
 };
 
@@ -283,6 +292,8 @@ gen_device_info_timebase_scale(const struct gen_device_info *devinfo,
    return (1000000000ull * gpu_timestamp) / devinfo->timestamp_frequency;
 }
 
+bool gen_get_device_info_from_fd(int fh, struct gen_device_info *devinfo);
+
 #ifdef __cplusplus
 }
 #endif
index a04bf65e1caf1989fae3d38c67ad2cedbfa7f8d3..bb8c2bf0fea2b12fcfc44756745bec34c0343e60 100644 (file)
@@ -1682,67 +1682,6 @@ init_pipeline_statistic_query_registers(struct brw_context *brw)
    query->data_size = sizeof(uint64_t) * query->n_counters;
 }
 
-static bool
-query_topology(struct brw_context *brw)
-{
-   __DRIscreen *screen = brw->screen->driScrnPriv;
-   struct drm_i915_query_item item = {
-      .query_id = DRM_I915_QUERY_TOPOLOGY_INFO,
-   };
-   struct drm_i915_query query = {
-      .num_items = 1,
-      .items_ptr = (uintptr_t) &item,
-   };
-
-   if (drmIoctl(screen->fd, DRM_IOCTL_I915_QUERY, &query))
-      return false;
-
-   struct drm_i915_query_topology_info *topo_info =
-      (struct drm_i915_query_topology_info *) calloc(1, item.length);
-   item.data_ptr = (uintptr_t) topo_info;
-
-   if (drmIoctl(screen->fd, DRM_IOCTL_I915_QUERY, &query) ||
-       item.length <= 0)
-      return false;
-
-   gen_device_info_update_from_topology(&brw->screen->devinfo,
-                                        topo_info);
-
-   free(topo_info);
-
-   return true;
-}
-
-static bool
-getparam_topology(struct brw_context *brw)
-{
-   __DRIscreen *screen = brw->screen->driScrnPriv;
-   drm_i915_getparam_t gp;
-   int ret;
-
-   int slice_mask = 0;
-   gp.param = I915_PARAM_SLICE_MASK;
-   gp.value = &slice_mask;
-   ret = drmIoctl(screen->fd, DRM_IOCTL_I915_GETPARAM, &gp);
-   if (ret)
-      return false;
-
-   int subslice_mask = 0;
-   gp.param = I915_PARAM_SUBSLICE_MASK;
-   gp.value = &subslice_mask;
-   ret = drmIoctl(screen->fd, DRM_IOCTL_I915_GETPARAM, &gp);
-   if (ret)
-      return false;
-
-   if (!gen_device_info_update_from_masks(&brw->screen->devinfo,
-                                          slice_mask,
-                                          subslice_mask,
-                                          brw->screen->eu_total))
-      return false;
-
-   return true;
-}
-
 /* gen_device_info will have incorrect default topology values for unsupported kernels.
  * verify kernel support to ensure OA metrics are accurate.
  */
@@ -1797,28 +1736,9 @@ brw_init_perf_query_info(struct gl_context *ctx)
    brw->perfquery.perf = gen_perf_new(brw, drmIoctl);
 
    init_pipeline_statistic_query_registers(brw);
-   brw_perf_query_register_mdapi_statistic_query(brw);
-
-   if (!oa_metrics_kernel_support(screen->fd, devinfo))
-      return false;
-
-   if (!query_topology(brw)) {
-      /* We need the i915 query uAPI on CNL+ (kernel 4.17+). */
-      if (devinfo->gen >= 10)
-         return false;
-
-      if (!getparam_topology(brw)) {
-         /* We need the SLICE_MASK/SUBSLICE_MASK on gen8+ (kernel 4.13+). */
-         if (devinfo->gen >= 8)
-            return false;
-
-         /* On Haswell, the values are already computed for us in
-          * gen_device_info.
-          */
-      }
-   }
 
-   if (gen_perf_load_oa_metrics(brw->perfquery.perf, screen->fd, devinfo))
+   if ((oa_metrics_kernel_support(screen->fd, devinfo)) &&
+       (gen_perf_load_oa_metrics(brw->perfquery.perf, screen->fd, devinfo)))
       brw_perf_query_register_mdapi_oa_query(brw);
 
    brw->perfquery.unaccumulated =
index 2bc2e41178de297efa5b89021de56cc8527cdc1d..6c4d7c5be272581d2f275bc5b7f48f0384776ae2 100644 (file)
@@ -2413,28 +2413,6 @@ set_max_gl_versions(struct intel_screen *screen)
    }
 }
 
-/**
- * Return the revision (generally the revid field of the PCI header) of the
- * graphics device.
- */
-static int
-intel_device_get_revision(int fd)
-{
-   struct drm_i915_getparam gp;
-   int revision;
-   int ret;
-
-   memset(&gp, 0, sizeof(gp));
-   gp.param = I915_PARAM_REVISION;
-   gp.value = &revision;
-
-   ret = drmCommandWriteRead(fd, DRM_I915_GETPARAM, &gp, sizeof(gp));
-   if (ret)
-      revision = -1;
-
-   return revision;
-}
-
 static void
 shader_debug_log_mesa(void *data, const char *fmt, ...)
 {
@@ -2513,22 +2491,16 @@ __DRIconfig **intelInitScreen2(__DRIscreen *dri_screen)
    screen->driScrnPriv = dri_screen;
    dri_screen->driverPrivate = (void *) screen;
 
-   screen->deviceID = gen_get_pci_device_id_override();
-   if (screen->deviceID < 0)
-      screen->deviceID = intel_get_integer(screen, I915_PARAM_CHIPSET_ID);
-   else
-      screen->no_hw = true;
-
-   if (!gen_get_device_info(screen->deviceID, &screen->devinfo))
+   if (!gen_get_device_info_from_fd(dri_screen->fd, &screen->devinfo))
       return NULL;
 
-   screen->devinfo.revision = intel_device_get_revision(dri_screen->fd);
+   const struct gen_device_info *devinfo = &screen->devinfo;
+   screen->deviceID = devinfo->chipset_id;
+   screen->no_hw = devinfo->no_hw;
 
    if (!intel_init_bufmgr(screen))
        return NULL;
 
-   const struct gen_device_info *devinfo = &screen->devinfo;
-
    brw_process_intel_debug_variable();
 
    if ((INTEL_DEBUG & DEBUG_SHADER_TIME) && devinfo->gen < 7) {