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:
@@ -29,6 +29,7 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include "gen_device_info.h"
|
#include "gen_device_info.h"
|
||||||
#include "compiler/shader_enums.h"
|
#include "compiler/shader_enums.h"
|
||||||
|
#include "intel/common/gen_gem.h"
|
||||||
#include "util/bitscan.h"
|
#include "util/bitscan.h"
|
||||||
#include "util/macros.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);
|
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
|
bool
|
||||||
gen_get_device_info(int devid, struct gen_device_info *devinfo)
|
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));
|
assert(devinfo->num_slices <= ARRAY_SIZE(devinfo->num_subslices));
|
||||||
|
|
||||||
|
devinfo->chipset_id = devid;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1243,3 +1263,109 @@ gen_get_device_name(int devid)
|
|||||||
return NULL;
|
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;
|
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;
|
return (1000000000ull * gpu_timestamp) / devinfo->timestamp_frequency;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool gen_get_device_info_from_fd(int fh, struct gen_device_info *devinfo);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@@ -1682,67 +1682,6 @@ init_pipeline_statistic_query_registers(struct brw_context *brw)
|
|||||||
query->data_size = sizeof(uint64_t) * query->n_counters;
|
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.
|
/* gen_device_info will have incorrect default topology values for unsupported kernels.
|
||||||
* verify kernel support to ensure OA metrics are accurate.
|
* 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);
|
brw->perfquery.perf = gen_perf_new(brw, drmIoctl);
|
||||||
|
|
||||||
init_pipeline_statistic_query_registers(brw);
|
init_pipeline_statistic_query_registers(brw);
|
||||||
brw_perf_query_register_mdapi_statistic_query(brw);
|
|
||||||
|
|
||||||
if (!oa_metrics_kernel_support(screen->fd, devinfo))
|
if ((oa_metrics_kernel_support(screen->fd, devinfo)) &&
|
||||||
return false;
|
(gen_perf_load_oa_metrics(brw->perfquery.perf, screen->fd, devinfo)))
|
||||||
|
|
||||||
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))
|
|
||||||
brw_perf_query_register_mdapi_oa_query(brw);
|
brw_perf_query_register_mdapi_oa_query(brw);
|
||||||
|
|
||||||
brw->perfquery.unaccumulated =
|
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
|
static void
|
||||||
shader_debug_log_mesa(void *data, const char *fmt, ...)
|
shader_debug_log_mesa(void *data, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
@@ -2513,22 +2491,16 @@ __DRIconfig **intelInitScreen2(__DRIscreen *dri_screen)
|
|||||||
screen->driScrnPriv = dri_screen;
|
screen->driScrnPriv = dri_screen;
|
||||||
dri_screen->driverPrivate = (void *) screen;
|
dri_screen->driverPrivate = (void *) screen;
|
||||||
|
|
||||||
screen->deviceID = gen_get_pci_device_id_override();
|
if (!gen_get_device_info_from_fd(dri_screen->fd, &screen->devinfo))
|
||||||
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))
|
|
||||||
return NULL;
|
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))
|
if (!intel_init_bufmgr(screen))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
const struct gen_device_info *devinfo = &screen->devinfo;
|
|
||||||
|
|
||||||
brw_process_intel_debug_variable();
|
brw_process_intel_debug_variable();
|
||||||
|
|
||||||
if ((INTEL_DEBUG & DEBUG_SHADER_TIME) && devinfo->gen < 7) {
|
if ((INTEL_DEBUG & DEBUG_SHADER_TIME) && devinfo->gen < 7) {
|
||||||
|
Reference in New Issue
Block a user