#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"
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)
{
assert(devinfo->num_slices <= ARRAY_SIZE(devinfo->num_subslices));
+ devinfo->chipset_id = devid;
return true;
}
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;
+}
*/
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;
/** @} */
};
return (1000000000ull * gpu_timestamp) / devinfo->timestamp_frequency;
}
+bool gen_get_device_info_from_fd(int fh, struct gen_device_info *devinfo);
+
#ifdef __cplusplus
}
#endif
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.
*/
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 =
}
}
-/**
- * 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, ...)
{
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) {