<div dir="ltr"><div class="gmail_quote"><div dir="ltr">On Mon, Oct 15, 2018 at 4:22 PM Keith Packard <<a href="mailto:keithp@keithp.com">keithp@keithp.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Offers three clocks, device, clock monotonic and clock monotonic<br>
raw. Could use some kernel support to reduce the deviation between<br>
clock values.<br>
<br>
v2:<br>
Ensure deviation is at least as big as the GPU time interval.<br>
<br>
Signed-off-by: Keith Packard <<a href="mailto:keithp@keithp.com" target="_blank">keithp@keithp.com</a>><br>
---<br>
src/amd/vulkan/radv_device.c | 84 ++++++++++++++++++++++++++++<br>
src/amd/vulkan/radv_extensions.py | 1 +<br>
src/intel/vulkan/anv_device.c | 88 ++++++++++++++++++++++++++++++<br>
src/intel/vulkan/anv_extensions.py | 1 +<br>
src/intel/vulkan/anv_gem.c | 13 +++++<br>
src/intel/vulkan/anv_private.h | 2 +<br>
6 files changed, 189 insertions(+)<br>
<br>
diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c<br>
index 174922780fc..29f0afbc69b 100644<br>
--- a/src/amd/vulkan/radv_device.c<br>
+++ b/src/amd/vulkan/radv_device.c<br>
@@ -4955,3 +4955,87 @@ radv_GetDeviceGroupPeerMemoryFeatures(<br>
VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT |<br>
VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT;<br>
}<br>
+<br>
+static const VkTimeDomainEXT radv_time_domains[] = {<br>
+ VK_TIME_DOMAIN_DEVICE_EXT,<br>
+ VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT,<br>
+ VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT,<br>
+};<br>
+<br>
+VkResult radv_GetPhysicalDeviceCalibrateableTimeDomainsEXT(<br>
+ VkPhysicalDevice physicalDevice,<br>
+ uint32_t *pTimeDomainCount,<br>
+ VkTimeDomainEXT *pTimeDomains)<br>
+{<br>
+ int d;<br>
+ VK_OUTARRAY_MAKE(out, pTimeDomains, pTimeDomainCount);<br>
+<br>
+ for (d = 0; d < ARRAY_SIZE(radv_time_domains); d++) {<br>
+ vk_outarray_append(&out, i) {<br>
+ *i = radv_time_domains[d];<br>
+ }<br>
+ }<br>
+<br>
+ return vk_outarray_status(&out);<br>
+}<br>
+<br>
+static uint64_t<br>
+radv_clock_gettime(clockid_t clock_id)<br>
+{<br>
+ struct timespec current;<br>
+ int ret;<br>
+<br>
+ ret = clock_gettime(clock_id, ¤t);<br>
+ if (ret < 0 && clock_id == CLOCK_MONOTONIC_RAW)<br>
+ ret = clock_gettime(CLOCK_MONOTONIC, ¤t);<br>
+ if (ret < 0)<br>
+ return 0;<br>
+<br>
+ return (uint64_t) current.tv_sec * 1000000000ULL + current.tv_nsec;<br>
+}<br>
+<br>
+#define TIMESTAMP 0x2358<br>
+<br>
+VkResult radv_GetCalibratedTimestampsEXT(<br>
+ VkDevice _device,<br>
+ uint32_t timestampCount,<br>
+ const VkCalibratedTimestampInfoEXT *pTimestampInfos,<br>
+ uint64_t *pTimestamps,<br>
+ uint64_t *pMaxDeviation)<br>
+{<br>
+ RADV_FROM_HANDLE(radv_device, device, _device);<br>
+ uint32_t clock_crystal_freq = device->physical_device->rad_info.clock_crystal_freq;<br>
+ int d;<br>
+ uint64_t begin, end;<br>
+<br>
+ begin = radv_clock_gettime(CLOCK_MONOTONIC_RAW);<br>
+<br>
+ for (d = 0; d < timestampCount; d++) {<br>
+ switch (pTimestampInfos[d].timeDomain) {<br>
+ case VK_TIME_DOMAIN_DEVICE_EXT:<br>
+ /* XXX older kernels don't support this interface. */<br>
+ pTimestamps[d] = device->ws->query_value(device->ws,<br>
+ RADEON_TIMESTAMP);<br>
+ break;<br>
+ case VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT:<br>
+ pTimestamps[d] = radv_clock_gettime(CLOCK_MONOTONIC);<br>
+ break;<br>
+<br>
+ case VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT:<br>
+ pTimestamps[d] = begin;<br>
+ break;<br>
+ default:<br>
+ pTimestamps[d] = 0;<br>
+ break;<br>
+ }<br>
+ }<br>
+<br>
+ end = radv_clock_gettime(CLOCK_MONOTONIC_RAW);<br>
+<br>
+ uint64_t clock_period = end - begin;<br>
+ uint64_t device_period = (1000000 + clock_crystal_freq - 1) / clock_crystal_freq;<br>
+<br>
+ *pMaxDeviation = clock_period > device_period ? clock_period : device_period;<br>
+<br>
+ return VK_SUCCESS;<br>
+}<br>
diff --git a/src/amd/vulkan/radv_extensions.py b/src/amd/vulkan/radv_extensions.py<br>
index 5dcedae1c63..4c81d3f0068 100644<br>
--- a/src/amd/vulkan/radv_extensions.py<br>
+++ b/src/amd/vulkan/radv_extensions.py<br>
@@ -92,6 +92,7 @@ EXTENSIONS = [<br>
Extension('VK_KHR_display', 23, 'VK_USE_PLATFORM_DISPLAY_KHR'),<br>
Extension('VK_EXT_direct_mode_display', 1, 'VK_USE_PLATFORM_DISPLAY_KHR'),<br>
Extension('VK_EXT_acquire_xlib_display', 1, 'VK_USE_PLATFORM_XLIB_XRANDR_EXT'),<br>
+ Extension('VK_EXT_calibrated_timestamps', 1, True),<br>
Extension('VK_EXT_conditional_rendering', 1, True),<br>
Extension('VK_EXT_conservative_rasterization', 1, 'device->rad_info.chip_class >= GFX9'),<br>
Extension('VK_EXT_display_surface_counter', 1, 'VK_USE_PLATFORM_DISPLAY_KHR'),<br>
diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c<br>
index a2551452eb1..6a6539c9685 100644<br>
--- a/src/intel/vulkan/anv_device.c<br>
+++ b/src/intel/vulkan/anv_device.c<br>
@@ -3021,6 +3021,94 @@ void anv_DestroyFramebuffer(<br>
vk_free2(&device->alloc, pAllocator, fb);<br>
}<br>
<br>
+static const VkTimeDomainEXT anv_time_domains[] = {<br>
+ VK_TIME_DOMAIN_DEVICE_EXT,<br>
+ VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT,<br>
+ VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT,<br>
+};<br>
+<br>
+VkResult anv_GetPhysicalDeviceCalibrateableTimeDomainsEXT(<br>
+ VkPhysicalDevice physicalDevice,<br>
+ uint32_t *pTimeDomainCount,<br>
+ VkTimeDomainEXT *pTimeDomains)<br>
+{<br>
+ int d;<br>
+ VK_OUTARRAY_MAKE(out, pTimeDomains, pTimeDomainCount);<br>
+<br>
+ for (d = 0; d < ARRAY_SIZE(anv_time_domains); d++) {<br>
+ vk_outarray_append(&out, i) {<br>
+ *i = anv_time_domains[d];<br>
+ }<br>
+ }<br>
+<br>
+ return vk_outarray_status(&out);<br>
+}<br>
+<br>
+static uint64_t<br>
+anv_clock_gettime(clockid_t clock_id)<br>
+{<br>
+ struct timespec current;<br>
+ int ret;<br>
+<br>
+ ret = clock_gettime(clock_id, ¤t);<br>
+ if (ret < 0 && clock_id == CLOCK_MONOTONIC_RAW)<br>
+ ret = clock_gettime(CLOCK_MONOTONIC, ¤t);<br>
+ if (ret < 0)<br>
+ return 0;<br>
+<br>
+ return (uint64_t) current.tv_sec * 1000000000ULL + current.tv_nsec;<br>
+}<br></blockquote><div><br></div><div>One lf these days, we should unify these. I know this is at least the second copy in anv and we've got it hand-rolled a couple other places. I don't care too much today though so meh.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br>
+#define TIMESTAMP 0x2358<br>
+<br>
+VkResult anv_GetCalibratedTimestampsEXT(<br>
+ VkDevice _device,<br>
+ uint32_t timestampCount,<br>
+ const VkCalibratedTimestampInfoEXT *pTimestampInfos,<br>
+ uint64_t *pTimestamps,<br>
+ uint64_t *pMaxDeviation)<br>
+{<br>
+ ANV_FROM_HANDLE(anv_device, device, _device);<br>
+ uint64_t timestamp_frequency = device->info.timestamp_frequency;<br>
+ int ret;<br>
+ int d;<br>
+ uint64_t begin, end;<br>
+<br>
+ begin = anv_clock_gettime(CLOCK_MONOTONIC_RAW);<br>
+<br>
+ for (d = 0; d < timestampCount; d++) {<br>
+ switch (pTimestampInfos[d].timeDomain) {<br>
+ case VK_TIME_DOMAIN_DEVICE_EXT:<br>
+ /* XXX older kernels don't support this interface. */<br></blockquote><div><br></div><div>I don't think we support kernels that old, so you can drop the comment.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+ ret = anv_gem_reg_read(device, TIMESTAMP | 1,<br>
+ &pTimestamps[d]);<br>
+<br>
+ if (ret != 0)<br>
+ return VK_ERROR_DEVICE_LOST;<br></blockquote><div><br></div>If you're going to return device_lost, you should set device->lost = true;</div><div class="gmail_quote"><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+ break;<br>
+ case VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT:<br>
+ pTimestamps[d] = anv_clock_gettime(CLOCK_MONOTONIC);<br>
+ break;<br>
+<br>
+ case VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT:<br>
+ pTimestamps[d] = begin;<br>
+ break;<br>
+ default:<br>
+ pTimestamps[d] = 0;<br>
+ break;<br>
+ }<br>
+ }<br>
+<br>
+ end = anv_clock_gettime(CLOCK_MONOTONIC_RAW);<br>
+<br>
+ uint64_t clock_period = end - begin;<br>
+ uint64_t device_period = (1000000000 + timestamp_frequency - 1) / timestamp_frequency;<br></blockquote><div><br></div><div>I think you just want DIV_ROUND_UP(a, b)<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br>
+ *pMaxDeviation = clock_period > device_period ? clock_period : device_period;<br></blockquote><div><br></div><div>MAX2(a, b) is your friend.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+<br>
+ return VK_SUCCESS;<br>
+}<br>
+<br>
/* vk_icd.h does not declare this function, so we declare it here to<br>
* suppress Wmissing-prototypes.<br>
*/<br>
diff --git a/src/intel/vulkan/anv_extensions.py b/src/intel/vulkan/anv_extensions.py<br>
index d4915c95013..a8535964da7 100644<br>
--- a/src/intel/vulkan/anv_extensions.py<br>
+++ b/src/intel/vulkan/anv_extensions.py<br>
@@ -126,6 +126,7 @@ EXTENSIONS = [<br>
Extension('VK_EXT_vertex_attribute_divisor', 3, True),<br>
Extension('VK_EXT_post_depth_coverage', 1, 'device->info.gen >= 9'),<br>
Extension('VK_EXT_sampler_filter_minmax', 1, 'device->info.gen >= 9'),<br>
+ Extension('VK_EXT_calibrated_timestamps', 1, True),<br>
]<br>
<br>
class VkVersion:<br>
diff --git a/src/intel/vulkan/anv_gem.c b/src/intel/vulkan/anv_gem.c<br>
index c43b5ef9e06..1bdf040c1a3 100644<br>
--- a/src/intel/vulkan/anv_gem.c<br>
+++ b/src/intel/vulkan/anv_gem.c<br>
@@ -423,6 +423,19 @@ anv_gem_fd_to_handle(struct anv_device *device, int fd)<br>
return args.handle;<br>
}<br>
<br>
+int<br>
+anv_gem_reg_read(struct anv_device *device, uint32_t offset, uint64_t *result)<br>
+{<br>
+ struct drm_i915_reg_read args = {<br>
+ .offset = offset<br>
+ };<br>
+<br>
+ int ret = anv_ioctl(device->fd, DRM_IOCTL_I915_REG_READ, &args);<br>
+<br>
+ *result = args.val;<br>
+ return ret;<br>
+}<br>
+<br>
#ifndef SYNC_IOC_MAGIC<br>
/* duplicated from linux/sync_file.h to avoid build-time dependency<br>
* on new (v4.7) kernel headers. Once distro's are mostly using<br>
diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h<br>
index 599b903f25c..08376b00c8e 100644<br>
--- a/src/intel/vulkan/anv_private.h<br>
+++ b/src/intel/vulkan/anv_private.h<br>
@@ -1103,6 +1103,8 @@ int anv_gem_get_aperture(int fd, uint64_t *size);<br>
int anv_gem_gpu_get_reset_stats(struct anv_device *device,<br>
uint32_t *active, uint32_t *pending);<br>
int anv_gem_handle_to_fd(struct anv_device *device, uint32_t gem_handle);<br>
+int anv_gem_reg_read(struct anv_device *device,<br>
+ uint32_t offset, uint64_t *result);<br>
uint32_t anv_gem_fd_to_handle(struct anv_device *device, int fd);<br>
int anv_gem_set_caching(struct anv_device *device, uint32_t gem_handle, uint32_t caching);<br>
int anv_gem_set_domain(struct anv_device *device, uint32_t gem_handle,<br>
-- <br>
2.19.1<br>
<br>
_______________________________________________<br>
dri-devel mailing list<br>
<a href="mailto:dri-devel@lists.freedesktop.org" target="_blank">dri-devel@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/dri-devel" rel="noreferrer" target="_blank">https://lists.freedesktop.org/mailman/listinfo/dri-devel</a><br>
</blockquote></div></div>