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:
parent
1186f6ea69
commit
96e1c945f2
|
@ -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,
|
||||
×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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 =
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue