From 96e1c945f2bc4047a603753ae10fc4f27754361c Mon Sep 17 00:00:00 2001 From: Mark Janes Date: Wed, 24 Jul 2019 13:48:03 -0700 Subject: [PATCH] i965: Move device info initialization to common code 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 Reviewed-by: Lionel Landwerlin --- src/intel/dev/gen_device_info.c | 126 ++++++++++++++++++ src/intel/dev/gen_device_info.h | 11 ++ .../drivers/dri/i965/brw_performance_query.c | 84 +----------- src/mesa/drivers/dri/i965/intel_screen.c | 36 +---- 4 files changed, 143 insertions(+), 114 deletions(-) diff --git a/src/intel/dev/gen_device_info.c b/src/intel/dev/gen_device_info.c index 6f3b6ff35b6..79ec4e0262d 100644 --- a/src/intel/dev/gen_device_info.c +++ b/src/intel/dev/gen_device_info.c @@ -29,6 +29,7 @@ #include #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, + ×tamp_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; +} diff --git a/src/intel/dev/gen_device_info.h b/src/intel/dev/gen_device_info.h index 6199290f995..d1c7230b0ff 100644 --- a/src/intel/dev/gen_device_info.h +++ b/src/intel/dev/gen_device_info.h @@ -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 diff --git a/src/mesa/drivers/dri/i965/brw_performance_query.c b/src/mesa/drivers/dri/i965/brw_performance_query.c index a04bf65e1ca..bb8c2bf0fea 100644 --- a/src/mesa/drivers/dri/i965/brw_performance_query.c +++ b/src/mesa/drivers/dri/i965/brw_performance_query.c @@ -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 = diff --git a/src/mesa/drivers/dri/i965/intel_screen.c b/src/mesa/drivers/dri/i965/intel_screen.c index 2bc2e41178d..6c4d7c5be27 100644 --- a/src/mesa/drivers/dri/i965/intel_screen.c +++ b/src/mesa/drivers/dri/i965/intel_screen.c @@ -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) {