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 <kenneth@whitecape.org>
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
This commit is contained in:
Mark Janes 2019-07-24 13:48:03 -07:00
parent 1186f6ea69
commit 96e1c945f2
4 changed files with 143 additions and 114 deletions

View 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;
}

View 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

View 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 =

View 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) {