intel: Share code to read render timestamp

Timestamp read is not in any hot path so there is no down-sides in
share the same function between iris, crocus, anv and hasvk.

Also while at it also dropping the functions to read MMIO from kernel,
the only use is read render timestamp so we don't need it.

v2:
- fix compilaton of ds

Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18920>
This commit is contained in:
José Roberto de Souza
2022-09-30 10:18:13 -07:00
parent 3047195c62
commit 1e87834980
19 changed files with 49 additions and 108 deletions

View File

@@ -1604,16 +1604,6 @@ crocus_destroy_hw_context(struct crocus_bufmgr *bufmgr, uint32_t ctx_id)
} }
} }
int
crocus_reg_read(struct crocus_bufmgr *bufmgr, uint32_t offset, uint64_t *result)
{
struct drm_i915_reg_read reg_read = { .offset = offset };
int ret = intel_ioctl(bufmgr->fd, DRM_IOCTL_I915_REG_READ, &reg_read);
*result = reg_read.val;
return ret;
}
static int static int
gem_param(int fd, int name) gem_param(int fd, int name)
{ {

View File

@@ -351,9 +351,6 @@ int crocus_bo_export_gem_handle_for_device(struct crocus_bo *bo, int drm_fd,
uint32_t crocus_bo_export_gem_handle(struct crocus_bo *bo); uint32_t crocus_bo_export_gem_handle(struct crocus_bo *bo);
int crocus_reg_read(struct crocus_bufmgr *bufmgr, uint32_t offset,
uint64_t *out);
int drm_ioctl(int fd, unsigned long request, void *arg); int drm_ioctl(int fd, unsigned long request, void *arg);
#endif /* CROCUS_BUFMGR_H */ #endif /* CROCUS_BUFMGR_H */

View File

@@ -612,10 +612,11 @@ static uint64_t
crocus_get_timestamp(struct pipe_screen *pscreen) crocus_get_timestamp(struct pipe_screen *pscreen)
{ {
struct crocus_screen *screen = (struct crocus_screen *) pscreen; struct crocus_screen *screen = (struct crocus_screen *) pscreen;
const unsigned TIMESTAMP = 0x2358;
uint64_t result; uint64_t result;
crocus_reg_read(screen->bufmgr, TIMESTAMP | 1, &result); if (!intel_gem_read_render_timestamp(crocus_bufmgr_get_fd(screen->bufmgr),
&result))
return 0;
result = intel_device_info_timebase_scale(&screen->devinfo, result); result = intel_device_info_timebase_scale(&screen->devinfo, result);
result &= (1ull << TIMESTAMP_BITS) - 1; result &= (1ull << TIMESTAMP_BITS) - 1;

View File

@@ -2261,16 +2261,6 @@ iris_destroy_kernel_context(struct iris_bufmgr *bufmgr, uint32_t ctx_id)
} }
} }
int
iris_reg_read(struct iris_bufmgr *bufmgr, uint32_t offset, uint64_t *result)
{
struct drm_i915_reg_read reg_read = { .offset = offset };
int ret = intel_ioctl(bufmgr->fd, DRM_IOCTL_I915_REG_READ, &reg_read);
*result = reg_read.val;
return ret;
}
static struct intel_buffer * static struct intel_buffer *
intel_aux_map_buffer_alloc(void *driver_ctx, uint32_t size) intel_aux_map_buffer_alloc(void *driver_ctx, uint32_t size)
{ {

View File

@@ -529,8 +529,6 @@ int iris_bo_export_gem_handle_for_device(struct iris_bo *bo, int drm_fd,
uint32_t iris_bo_export_gem_handle(struct iris_bo *bo); uint32_t iris_bo_export_gem_handle(struct iris_bo *bo);
int iris_reg_read(struct iris_bufmgr *bufmgr, uint32_t offset, uint64_t *out);
/** /**
* Returns the BO's address relative to the appropriate base address. * Returns the BO's address relative to the appropriate base address.
* *

View File

@@ -618,10 +618,11 @@ static uint64_t
iris_get_timestamp(struct pipe_screen *pscreen) iris_get_timestamp(struct pipe_screen *pscreen)
{ {
struct iris_screen *screen = (struct iris_screen *) pscreen; struct iris_screen *screen = (struct iris_screen *) pscreen;
const unsigned TIMESTAMP = 0x2358;
uint64_t result; uint64_t result;
iris_reg_read(screen->bufmgr, TIMESTAMP | 1, &result); if (!intel_gem_read_render_timestamp(iris_bufmgr_get_fd(screen->bufmgr),
&result))
return 0;
result = intel_device_info_timebase_scale(&screen->devinfo, result); result = intel_device_info_timebase_scale(&screen->devinfo, result);
result &= (1ull << TIMESTAMP_BITS) - 1; result &= (1ull << TIMESTAMP_BITS) - 1;

View File

@@ -23,6 +23,8 @@
#include "intel_gem.h" #include "intel_gem.h"
#include "drm-uapi/i915_drm.h" #include "drm-uapi/i915_drm.h"
#define RCS_TIMESTAMP 0x2358
bool bool
intel_gem_supports_syncobj_wait(int fd) intel_gem_supports_syncobj_wait(int fd)
{ {
@@ -152,3 +154,15 @@ intel_gem_create_context_engines(int fd,
return create.ctx_id; return create.ctx_id;
} }
bool intel_gem_read_render_timestamp(int fd, uint64_t *value)
{
struct drm_i915_reg_read reg_read = {
.offset = RCS_TIMESTAMP | I915_REG_READ_8B_WA,
};
int ret = intel_ioctl(fd, DRM_IOCTL_I915_REG_READ, &reg_read);
if (ret == 0)
*value = reg_read.val;
return ret == 0;
}

View File

@@ -24,6 +24,10 @@
#ifndef INTEL_GEM_H #ifndef INTEL_GEM_H
#define INTEL_GEM_H #define INTEL_GEM_H
#ifdef __cplusplus
extern "C" {
#endif
#include "drm-uapi/i915_drm.h" #include "drm-uapi/i915_drm.h"
#include <assert.h> #include <assert.h>
@@ -76,19 +80,6 @@ intel_ioctl(int fd, unsigned long request, void *arg)
return ret; return ret;
} }
static inline uint64_t
intel_read_gpu_timestamp(int fd)
{
struct drm_i915_reg_read reg_read = {};
const uint64_t render_ring_timestamp = 0x2358;
reg_read.offset = render_ring_timestamp | I915_REG_READ_8B_WA;
if (intel_ioctl(fd, DRM_IOCTL_I915_REG_READ, &reg_read) < 0)
return 0;
return reg_read.val;
}
/** /**
* A wrapper around DRM_IOCTL_I915_QUERY * A wrapper around DRM_IOCTL_I915_QUERY
* *
@@ -171,4 +162,10 @@ int intel_gem_create_context_engines(int fd,
const struct drm_i915_query_engine_info *info, const struct drm_i915_query_engine_info *info,
int num_engines, uint16_t *engine_classes); int num_engines, uint16_t *engine_classes);
bool intel_gem_read_render_timestamp(int fd, uint64_t *value);
#ifdef __cplusplus
}
#endif
#endif /* INTEL_GEM_H */ #endif /* INTEL_GEM_H */

View File

@@ -155,8 +155,9 @@ sync_timestamp(IntelRenderpassDataSource::TraceContext &ctx,
struct intel_ds_device *device) struct intel_ds_device *device)
{ {
uint64_t cpu_ts = perfetto::base::GetBootTimeNs().count(); uint64_t cpu_ts = perfetto::base::GetBootTimeNs().count();
uint64_t gpu_ts = intel_device_info_timebase_scale(&device->info, uint64_t gpu_ts;
intel_read_gpu_timestamp(device->fd)); intel_gem_read_render_timestamp(device->fd, &gpu_ts);
gpu_ts = intel_device_info_timebase_scale(&device->info, gpu_ts);
if (cpu_ts < device->next_clock_sync_ns) if (cpu_ts < device->next_clock_sync_ns)
return; return;

View File

@@ -161,7 +161,8 @@ void IntelDriver::enable_perfcnt(uint64_t sampling_period_ns)
{ {
this->sampling_period_ns = sampling_period_ns; this->sampling_period_ns = sampling_period_ns;
gpu_timestamp_udw = intel_read_gpu_timestamp(drm_device.fd) & ~perf->cfg->oa_timestamp_mask; intel_gem_read_render_timestamp(drm_device.fd, &gpu_timestamp_udw);
gpu_timestamp_udw &= ~perf->cfg->oa_timestamp_mask;
if (!perf->open(sampling_period_ns, selected_query)) { if (!perf->open(sampling_period_ns, selected_query)) {
PPS_LOG_FATAL("Failed to open intel perf"); PPS_LOG_FATAL("Failed to open intel perf");
} }
@@ -213,8 +214,11 @@ std::vector<PerfRecord> IntelDriver::parse_perf_records(const std::vector<uint8_
* do it now. If we see a roll over the lower 32bits capture it * do it now. If we see a roll over the lower 32bits capture it
* again. * again.
*/ */
if (gpu_timestamp_udw == 0 || (gpu_timestamp_udw | gpu_timestamp_ldw) < last_gpu_timestamp) if (gpu_timestamp_udw == 0 ||
gpu_timestamp_udw = intel_read_gpu_timestamp(drm_device.fd) & ~perf->cfg->oa_timestamp_mask; (gpu_timestamp_udw | gpu_timestamp_ldw) < last_gpu_timestamp) {
intel_gem_read_render_timestamp(drm_device.fd, &gpu_timestamp_udw);
gpu_timestamp_udw &= ~perf->cfg->oa_timestamp_mask;
}
uint64_t gpu_timestamp = gpu_timestamp_udw | gpu_timestamp_ldw; uint64_t gpu_timestamp = gpu_timestamp_udw | gpu_timestamp_ldw;
@@ -329,8 +333,9 @@ uint32_t IntelDriver::gpu_clock_id() const
uint64_t IntelDriver::gpu_timestamp() const uint64_t IntelDriver::gpu_timestamp() const
{ {
return intel_device_info_timebase_scale(&perf->devinfo, uint64_t timestamp;
intel_read_gpu_timestamp(drm_device.fd)); intel_gem_read_render_timestamp(drm_device.fd, &timestamp);
return intel_device_info_timebase_scale(&perf->devinfo, timestamp);
} }
} // namespace pps } // namespace pps

View File

@@ -37,7 +37,7 @@ libintel_driver_ds = static_library(
'intel-driver-ds', 'intel-driver-ds',
sources : ['intel_driver_ds.cc', intel_tracepoint_files], sources : ['intel_driver_ds.cc', intel_tracepoint_files],
include_directories : [inc_src, inc_include, inc_intel, inc_mapi, inc_mesa], include_directories : [inc_src, inc_include, inc_intel, inc_mapi, inc_mesa],
link_with : [libintel_perf, libintel_dev], link_with : [libintel_perf, libintel_dev, libintel_common],
dependencies : libintel_driver_ds_deps, dependencies : libintel_driver_ds_deps,
override_options : ['cpp_std=c++17'], override_options : ['cpp_std=c++17'],
gnu_symbol_visibility : 'hidden', gnu_symbol_visibility : 'hidden',
@@ -59,7 +59,7 @@ if with_perfetto and (with_datasources.contains('intel') or with_datasources.con
'pps-intel', 'pps-intel',
sources: pps_intel_sources, sources: pps_intel_sources,
include_directories: [inc_tool, inc_src, inc_include, inc_intel], include_directories: [inc_tool, inc_src, inc_include, inc_intel],
link_with: [libintel_perf, libintel_dev], link_with: [libintel_perf, libintel_dev, libintel_common],
dependencies: [dep_perfetto, dep_libdrm, idep_mesautil], dependencies: [dep_perfetto, dep_libdrm, idep_mesautil],
override_options: ['cpp_std=c++17'] override_options: ['cpp_std=c++17']
) )

View File

@@ -88,9 +88,6 @@ static const driOptionDescription anv_dri_options[] = {
*/ */
#define MAX_DEBUG_MESSAGE_LENGTH 4096 #define MAX_DEBUG_MESSAGE_LENGTH 4096
/* Render engine timestamp register */
#define TIMESTAMP 0x2358
/* The "RAW" clocks on Linux are called "FAST" on FreeBSD */ /* The "RAW" clocks on Linux are called "FAST" on FreeBSD */
#if !defined(CLOCK_MONOTONIC_RAW) && defined(CLOCK_MONOTONIC_FAST) #if !defined(CLOCK_MONOTONIC_RAW) && defined(CLOCK_MONOTONIC_FAST)
#define CLOCK_MONOTONIC_RAW CLOCK_MONOTONIC_FAST #define CLOCK_MONOTONIC_RAW CLOCK_MONOTONIC_FAST
@@ -913,8 +910,7 @@ anv_physical_device_try_create(struct vk_instance *vk_instance,
/* Check if we can read the GPU timestamp register from the CPU */ /* Check if we can read the GPU timestamp register from the CPU */
uint64_t u64_ignore; uint64_t u64_ignore;
device->has_reg_timestamp = anv_gem_reg_read(fd, TIMESTAMP | I915_REG_READ_8B_WA, device->has_reg_timestamp = intel_gem_read_render_timestamp(fd, &u64_ignore);
&u64_ignore) == 0;
device->always_flush_cache = INTEL_DEBUG(DEBUG_STALL) || device->always_flush_cache = INTEL_DEBUG(DEBUG_STALL) ||
driQueryOptionb(&instance->dri_options, "always_flush_cache"); driQueryOptionb(&instance->dri_options, "always_flush_cache");
@@ -4705,7 +4701,6 @@ VkResult anv_GetCalibratedTimestampsEXT(
{ {
ANV_FROM_HANDLE(anv_device, device, _device); ANV_FROM_HANDLE(anv_device, device, _device);
uint64_t timestamp_frequency = device->info->timestamp_frequency; uint64_t timestamp_frequency = device->info->timestamp_frequency;
int ret;
int d; int d;
uint64_t begin, end; uint64_t begin, end;
uint64_t max_clock_period = 0; uint64_t max_clock_period = 0;
@@ -4719,10 +4714,7 @@ VkResult anv_GetCalibratedTimestampsEXT(
for (d = 0; d < timestampCount; d++) { for (d = 0; d < timestampCount; d++) {
switch (pTimestampInfos[d].timeDomain) { switch (pTimestampInfos[d].timeDomain) {
case VK_TIME_DOMAIN_DEVICE_EXT: case VK_TIME_DOMAIN_DEVICE_EXT:
ret = anv_gem_reg_read(device->fd, TIMESTAMP | I915_REG_READ_8B_WA, if (!intel_gem_read_render_timestamp(device->fd, &pTimestamps[d])) {
&pTimestamps[d]);
if (ret != 0) {
return vk_device_set_lost(&device->vk, "Failed to read the " return vk_device_set_lost(&device->vk, "Failed to read the "
"TIMESTAMP register: %m"); "TIMESTAMP register: %m");
} }

View File

@@ -385,19 +385,6 @@ anv_gem_fd_to_handle(struct anv_device *device, int fd)
return args.handle; return args.handle;
} }
int
anv_gem_reg_read(int fd, uint32_t offset, uint64_t *result)
{
struct drm_i915_reg_read args = {
.offset = offset
};
int ret = intel_ioctl(fd, DRM_IOCTL_I915_REG_READ, &args);
*result = args.val;
return ret;
}
struct drm_i915_query_engine_info * struct drm_i915_query_engine_info *
anv_gem_get_engine_info(int fd) anv_gem_get_engine_info(int fd)
{ {

View File

@@ -179,9 +179,3 @@ anv_gem_get_engine_info(int fd)
{ {
unreachable("Unused"); unreachable("Unused");
} }
int
anv_gem_reg_read(int fd, uint32_t offset, uint64_t *result)
{
unreachable("Unused");
}

View File

@@ -1370,7 +1370,6 @@ int anv_gem_get_tiling(struct anv_device *device, uint32_t gem_handle);
int anv_gem_context_get_reset_stats(int fd, int context, int anv_gem_context_get_reset_stats(int fd, int context,
uint32_t *active, uint32_t *pending); uint32_t *active, uint32_t *pending);
int anv_gem_handle_to_fd(struct anv_device *device, uint32_t gem_handle); int anv_gem_handle_to_fd(struct anv_device *device, uint32_t gem_handle);
int anv_gem_reg_read(int fd, uint32_t offset, uint64_t *result);
uint32_t anv_gem_fd_to_handle(struct anv_device *device, int fd); uint32_t anv_gem_fd_to_handle(struct anv_device *device, int fd);
int anv_gem_set_caching(struct anv_device *device, uint32_t gem_handle, uint32_t caching); int anv_gem_set_caching(struct anv_device *device, uint32_t gem_handle, uint32_t caching);
int anv_i915_query(int fd, uint64_t query_id, void *buffer, int anv_i915_query(int fd, uint64_t query_id, void *buffer,

View File

@@ -946,8 +946,7 @@ anv_physical_device_try_create(struct vk_instance *vk_instance,
/* Check if we can read the GPU timestamp register from the CPU */ /* Check if we can read the GPU timestamp register from the CPU */
uint64_t u64_ignore; uint64_t u64_ignore;
device->has_reg_timestamp = anv_gem_reg_read(fd, TIMESTAMP | I915_REG_READ_8B_WA, device->has_reg_timestamp = intel_gem_read_render_timestamp(fd, &u64_ignore);
&u64_ignore) == 0;
device->always_flush_cache = INTEL_DEBUG(DEBUG_STALL) || device->always_flush_cache = INTEL_DEBUG(DEBUG_STALL) ||
driQueryOptionb(&instance->dri_options, "always_flush_cache"); driQueryOptionb(&instance->dri_options, "always_flush_cache");
@@ -4453,7 +4452,6 @@ VkResult anv_GetCalibratedTimestampsEXT(
{ {
ANV_FROM_HANDLE(anv_device, device, _device); ANV_FROM_HANDLE(anv_device, device, _device);
uint64_t timestamp_frequency = device->info->timestamp_frequency; uint64_t timestamp_frequency = device->info->timestamp_frequency;
int ret;
int d; int d;
uint64_t begin, end; uint64_t begin, end;
uint64_t max_clock_period = 0; uint64_t max_clock_period = 0;
@@ -4467,10 +4465,7 @@ VkResult anv_GetCalibratedTimestampsEXT(
for (d = 0; d < timestampCount; d++) { for (d = 0; d < timestampCount; d++) {
switch (pTimestampInfos[d].timeDomain) { switch (pTimestampInfos[d].timeDomain) {
case VK_TIME_DOMAIN_DEVICE_EXT: case VK_TIME_DOMAIN_DEVICE_EXT:
ret = anv_gem_reg_read(device->fd, TIMESTAMP | I915_REG_READ_8B_WA, if (!intel_gem_read_render_timestamp(device->fd, &pTimestamps[d])) {
&pTimestamps[d]);
if (ret != 0) {
return vk_device_set_lost(&device->vk, "Failed to read the " return vk_device_set_lost(&device->vk, "Failed to read the "
"TIMESTAMP register: %m"); "TIMESTAMP register: %m");
} }

View File

@@ -385,19 +385,6 @@ anv_gem_fd_to_handle(struct anv_device *device, int fd)
return args.handle; return args.handle;
} }
int
anv_gem_reg_read(int fd, uint32_t offset, uint64_t *result)
{
struct drm_i915_reg_read args = {
.offset = offset
};
int ret = intel_ioctl(fd, DRM_IOCTL_I915_REG_READ, &args);
*result = args.val;
return ret;
}
struct drm_i915_query_engine_info * struct drm_i915_query_engine_info *
anv_gem_get_engine_info(int fd) anv_gem_get_engine_info(int fd)
{ {

View File

@@ -179,9 +179,3 @@ anv_gem_get_engine_info(int fd)
{ {
unreachable("Unused"); unreachable("Unused");
} }
int
anv_gem_reg_read(int fd, uint32_t offset, uint64_t *result)
{
unreachable("Unused");
}

View File

@@ -1435,7 +1435,6 @@ int anv_gem_get_tiling(struct anv_device *device, uint32_t gem_handle);
int anv_gem_context_get_reset_stats(int fd, int context, int anv_gem_context_get_reset_stats(int fd, int context,
uint32_t *active, uint32_t *pending); uint32_t *active, uint32_t *pending);
int anv_gem_handle_to_fd(struct anv_device *device, uint32_t gem_handle); int anv_gem_handle_to_fd(struct anv_device *device, uint32_t gem_handle);
int anv_gem_reg_read(int fd, uint32_t offset, uint64_t *result);
uint32_t anv_gem_fd_to_handle(struct anv_device *device, int fd); uint32_t anv_gem_fd_to_handle(struct anv_device *device, int fd);
int anv_gem_set_caching(struct anv_device *device, uint32_t gem_handle, uint32_t caching); int anv_gem_set_caching(struct anv_device *device, uint32_t gem_handle, uint32_t caching);
int anv_i915_query(int fd, uint64_t query_id, void *buffer, int anv_i915_query(int fd, uint64_t query_id, void *buffer,