All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] vulkan: Add VK_EXT_calibrated_timestamps extension (radv and anv) [v2]
@ 2018-10-15 21:22 Keith Packard
  2018-10-15 21:36 ` Jason Ekstrand
                   ` (2 more replies)
  0 siblings, 3 replies; 28+ messages in thread
From: Keith Packard @ 2018-10-15 21:22 UTC (permalink / raw)
  To: mesa-dev; +Cc: dri-devel

Offers three clocks, device, clock monotonic and clock monotonic
raw. Could use some kernel support to reduce the deviation between
clock values.

v2:
	Ensure deviation is at least as big as the GPU time interval.

Signed-off-by: Keith Packard <keithp@keithp.com>
---
 src/amd/vulkan/radv_device.c       | 84 ++++++++++++++++++++++++++++
 src/amd/vulkan/radv_extensions.py  |  1 +
 src/intel/vulkan/anv_device.c      | 88 ++++++++++++++++++++++++++++++
 src/intel/vulkan/anv_extensions.py |  1 +
 src/intel/vulkan/anv_gem.c         | 13 +++++
 src/intel/vulkan/anv_private.h     |  2 +
 6 files changed, 189 insertions(+)

diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c
index 174922780fc..29f0afbc69b 100644
--- a/src/amd/vulkan/radv_device.c
+++ b/src/amd/vulkan/radv_device.c
@@ -4955,3 +4955,87 @@ radv_GetDeviceGroupPeerMemoryFeatures(
 	                       VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT |
 	                       VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT;
 }
+
+static const VkTimeDomainEXT radv_time_domains[] = {
+	VK_TIME_DOMAIN_DEVICE_EXT,
+	VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT,
+	VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT,
+};
+
+VkResult radv_GetPhysicalDeviceCalibrateableTimeDomainsEXT(
+	VkPhysicalDevice                             physicalDevice,
+	uint32_t                                     *pTimeDomainCount,
+	VkTimeDomainEXT                              *pTimeDomains)
+{
+	int d;
+	VK_OUTARRAY_MAKE(out, pTimeDomains, pTimeDomainCount);
+
+	for (d = 0; d < ARRAY_SIZE(radv_time_domains); d++) {
+		vk_outarray_append(&out, i) {
+			*i = radv_time_domains[d];
+		}
+	}
+
+	return vk_outarray_status(&out);
+}
+
+static uint64_t
+radv_clock_gettime(clockid_t clock_id)
+{
+	struct timespec current;
+	int ret;
+
+	ret = clock_gettime(clock_id, &current);
+	if (ret < 0 && clock_id == CLOCK_MONOTONIC_RAW)
+		ret = clock_gettime(CLOCK_MONOTONIC, &current);
+	if (ret < 0)
+		return 0;
+
+	return (uint64_t) current.tv_sec * 1000000000ULL + current.tv_nsec;
+}
+
+#define TIMESTAMP 0x2358
+
+VkResult radv_GetCalibratedTimestampsEXT(
+	VkDevice                                     _device,
+	uint32_t                                     timestampCount,
+	const VkCalibratedTimestampInfoEXT           *pTimestampInfos,
+	uint64_t                                     *pTimestamps,
+	uint64_t                                     *pMaxDeviation)
+{
+	RADV_FROM_HANDLE(radv_device, device, _device);
+	uint32_t clock_crystal_freq = device->physical_device->rad_info.clock_crystal_freq;
+	int d;
+	uint64_t begin, end;
+
+	begin = radv_clock_gettime(CLOCK_MONOTONIC_RAW);
+
+	for (d = 0; d < timestampCount; d++) {
+		switch (pTimestampInfos[d].timeDomain) {
+		case VK_TIME_DOMAIN_DEVICE_EXT:
+			/* XXX older kernels don't support this interface. */
+			pTimestamps[d] = device->ws->query_value(device->ws,
+								 RADEON_TIMESTAMP);
+			break;
+		case VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT:
+			pTimestamps[d] = radv_clock_gettime(CLOCK_MONOTONIC);
+			break;
+
+		case VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT:
+			pTimestamps[d] = begin;
+			break;
+		default:
+			pTimestamps[d] = 0;
+			break;
+		}
+	}
+
+	end = radv_clock_gettime(CLOCK_MONOTONIC_RAW);
+
+	uint64_t clock_period = end - begin;
+	uint64_t device_period = (1000000 + clock_crystal_freq - 1) / clock_crystal_freq;
+
+	*pMaxDeviation = clock_period > device_period ? clock_period : device_period;
+
+	return VK_SUCCESS;
+}
diff --git a/src/amd/vulkan/radv_extensions.py b/src/amd/vulkan/radv_extensions.py
index 5dcedae1c63..4c81d3f0068 100644
--- a/src/amd/vulkan/radv_extensions.py
+++ b/src/amd/vulkan/radv_extensions.py
@@ -92,6 +92,7 @@ EXTENSIONS = [
     Extension('VK_KHR_display',                          23, 'VK_USE_PLATFORM_DISPLAY_KHR'),
     Extension('VK_EXT_direct_mode_display',               1, 'VK_USE_PLATFORM_DISPLAY_KHR'),
     Extension('VK_EXT_acquire_xlib_display',              1, 'VK_USE_PLATFORM_XLIB_XRANDR_EXT'),
+    Extension('VK_EXT_calibrated_timestamps',             1, True),
     Extension('VK_EXT_conditional_rendering',             1, True),
     Extension('VK_EXT_conservative_rasterization',        1, 'device->rad_info.chip_class >= GFX9'),
     Extension('VK_EXT_display_surface_counter',           1, 'VK_USE_PLATFORM_DISPLAY_KHR'),
diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c
index a2551452eb1..6a6539c9685 100644
--- a/src/intel/vulkan/anv_device.c
+++ b/src/intel/vulkan/anv_device.c
@@ -3021,6 +3021,94 @@ void anv_DestroyFramebuffer(
    vk_free2(&device->alloc, pAllocator, fb);
 }
 
+static const VkTimeDomainEXT anv_time_domains[] = {
+   VK_TIME_DOMAIN_DEVICE_EXT,
+   VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT,
+   VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT,
+};
+
+VkResult anv_GetPhysicalDeviceCalibrateableTimeDomainsEXT(
+   VkPhysicalDevice                             physicalDevice,
+   uint32_t                                     *pTimeDomainCount,
+   VkTimeDomainEXT                              *pTimeDomains)
+{
+   int d;
+   VK_OUTARRAY_MAKE(out, pTimeDomains, pTimeDomainCount);
+
+   for (d = 0; d < ARRAY_SIZE(anv_time_domains); d++) {
+      vk_outarray_append(&out, i) {
+         *i = anv_time_domains[d];
+      }
+   }
+
+   return vk_outarray_status(&out);
+}
+
+static uint64_t
+anv_clock_gettime(clockid_t clock_id)
+{
+   struct timespec current;
+   int ret;
+
+   ret = clock_gettime(clock_id, &current);
+   if (ret < 0 && clock_id == CLOCK_MONOTONIC_RAW)
+      ret = clock_gettime(CLOCK_MONOTONIC, &current);
+   if (ret < 0)
+      return 0;
+
+   return (uint64_t) current.tv_sec * 1000000000ULL + current.tv_nsec;
+}
+
+#define TIMESTAMP 0x2358
+
+VkResult anv_GetCalibratedTimestampsEXT(
+   VkDevice                                     _device,
+   uint32_t                                     timestampCount,
+   const VkCalibratedTimestampInfoEXT           *pTimestampInfos,
+   uint64_t                                     *pTimestamps,
+   uint64_t                                     *pMaxDeviation)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   uint64_t timestamp_frequency = device->info.timestamp_frequency;
+   int  ret;
+   int d;
+   uint64_t begin, end;
+
+   begin = anv_clock_gettime(CLOCK_MONOTONIC_RAW);
+
+   for (d = 0; d < timestampCount; d++) {
+      switch (pTimestampInfos[d].timeDomain) {
+      case VK_TIME_DOMAIN_DEVICE_EXT:
+         /* XXX older kernels don't support this interface. */
+         ret = anv_gem_reg_read(device, TIMESTAMP | 1,
+                                &pTimestamps[d]);
+
+         if (ret != 0)
+            return VK_ERROR_DEVICE_LOST;
+         break;
+      case VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT:
+         pTimestamps[d] = anv_clock_gettime(CLOCK_MONOTONIC);
+         break;
+
+      case VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT:
+         pTimestamps[d] = begin;
+         break;
+      default:
+         pTimestamps[d] = 0;
+         break;
+      }
+   }
+
+   end = anv_clock_gettime(CLOCK_MONOTONIC_RAW);
+
+   uint64_t clock_period = end - begin;
+   uint64_t device_period = (1000000000 + timestamp_frequency - 1) / timestamp_frequency;
+
+   *pMaxDeviation = clock_period > device_period ? clock_period : device_period;
+
+   return VK_SUCCESS;
+}
+
 /* vk_icd.h does not declare this function, so we declare it here to
  * suppress Wmissing-prototypes.
  */
diff --git a/src/intel/vulkan/anv_extensions.py b/src/intel/vulkan/anv_extensions.py
index d4915c95013..a8535964da7 100644
--- a/src/intel/vulkan/anv_extensions.py
+++ b/src/intel/vulkan/anv_extensions.py
@@ -126,6 +126,7 @@ EXTENSIONS = [
     Extension('VK_EXT_vertex_attribute_divisor',          3, True),
     Extension('VK_EXT_post_depth_coverage',               1, 'device->info.gen >= 9'),
     Extension('VK_EXT_sampler_filter_minmax',             1, 'device->info.gen >= 9'),
+    Extension('VK_EXT_calibrated_timestamps',             1, True),
 ]
 
 class VkVersion:
diff --git a/src/intel/vulkan/anv_gem.c b/src/intel/vulkan/anv_gem.c
index c43b5ef9e06..1bdf040c1a3 100644
--- a/src/intel/vulkan/anv_gem.c
+++ b/src/intel/vulkan/anv_gem.c
@@ -423,6 +423,19 @@ anv_gem_fd_to_handle(struct anv_device *device, int fd)
    return args.handle;
 }
 
+int
+anv_gem_reg_read(struct anv_device *device, uint32_t offset, uint64_t *result)
+{
+   struct drm_i915_reg_read args = {
+      .offset = offset
+   };
+
+   int ret = anv_ioctl(device->fd, DRM_IOCTL_I915_REG_READ, &args);
+
+   *result = args.val;
+   return ret;
+}
+
 #ifndef SYNC_IOC_MAGIC
 /* duplicated from linux/sync_file.h to avoid build-time dependency
  * on new (v4.7) kernel headers.  Once distro's are mostly using
diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
index 599b903f25c..08376b00c8e 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -1103,6 +1103,8 @@ int anv_gem_get_aperture(int fd, uint64_t *size);
 int anv_gem_gpu_get_reset_stats(struct anv_device *device,
                                 uint32_t *active, uint32_t *pending);
 int anv_gem_handle_to_fd(struct anv_device *device, uint32_t gem_handle);
+int anv_gem_reg_read(struct anv_device *device,
+                     uint32_t offset, uint64_t *result);
 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_domain(struct anv_device *device, uint32_t gem_handle,
-- 
2.19.1

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* Re: [PATCH] vulkan: Add VK_EXT_calibrated_timestamps extension (radv and anv) [v2]
  2018-10-15 21:22 [PATCH] vulkan: Add VK_EXT_calibrated_timestamps extension (radv and anv) [v2] Keith Packard
@ 2018-10-15 21:36 ` Jason Ekstrand
  2018-10-15 21:38 ` Lionel Landwerlin
  2018-10-15 23:05 ` [PATCH] vulkan: Add VK_EXT_calibrated_timestamps extension (radv and anv) [v3] Keith Packard
  2 siblings, 0 replies; 28+ messages in thread
From: Jason Ekstrand @ 2018-10-15 21:36 UTC (permalink / raw)
  To: Keith Packard; +Cc: ML mesa-dev, Maling list - DRI developers


[-- Attachment #1.1: Type: text/plain, Size: 11262 bytes --]

On Mon, Oct 15, 2018 at 4:22 PM Keith Packard <keithp@keithp.com> wrote:

> Offers three clocks, device, clock monotonic and clock monotonic
> raw. Could use some kernel support to reduce the deviation between
> clock values.
>
> v2:
>         Ensure deviation is at least as big as the GPU time interval.
>
> Signed-off-by: Keith Packard <keithp@keithp.com>
> ---
>  src/amd/vulkan/radv_device.c       | 84 ++++++++++++++++++++++++++++
>  src/amd/vulkan/radv_extensions.py  |  1 +
>  src/intel/vulkan/anv_device.c      | 88 ++++++++++++++++++++++++++++++
>  src/intel/vulkan/anv_extensions.py |  1 +
>  src/intel/vulkan/anv_gem.c         | 13 +++++
>  src/intel/vulkan/anv_private.h     |  2 +
>  6 files changed, 189 insertions(+)
>
> diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c
> index 174922780fc..29f0afbc69b 100644
> --- a/src/amd/vulkan/radv_device.c
> +++ b/src/amd/vulkan/radv_device.c
> @@ -4955,3 +4955,87 @@ radv_GetDeviceGroupPeerMemoryFeatures(
>                                VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT |
>                                VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT;
>  }
> +
> +static const VkTimeDomainEXT radv_time_domains[] = {
> +       VK_TIME_DOMAIN_DEVICE_EXT,
> +       VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT,
> +       VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT,
> +};
> +
> +VkResult radv_GetPhysicalDeviceCalibrateableTimeDomainsEXT(
> +       VkPhysicalDevice                             physicalDevice,
> +       uint32_t                                     *pTimeDomainCount,
> +       VkTimeDomainEXT                              *pTimeDomains)
> +{
> +       int d;
> +       VK_OUTARRAY_MAKE(out, pTimeDomains, pTimeDomainCount);
> +
> +       for (d = 0; d < ARRAY_SIZE(radv_time_domains); d++) {
> +               vk_outarray_append(&out, i) {
> +                       *i = radv_time_domains[d];
> +               }
> +       }
> +
> +       return vk_outarray_status(&out);
> +}
> +
> +static uint64_t
> +radv_clock_gettime(clockid_t clock_id)
> +{
> +       struct timespec current;
> +       int ret;
> +
> +       ret = clock_gettime(clock_id, &current);
> +       if (ret < 0 && clock_id == CLOCK_MONOTONIC_RAW)
> +               ret = clock_gettime(CLOCK_MONOTONIC, &current);
> +       if (ret < 0)
> +               return 0;
> +
> +       return (uint64_t) current.tv_sec * 1000000000ULL + current.tv_nsec;
> +}
> +
> +#define TIMESTAMP 0x2358
> +
> +VkResult radv_GetCalibratedTimestampsEXT(
> +       VkDevice                                     _device,
> +       uint32_t                                     timestampCount,
> +       const VkCalibratedTimestampInfoEXT           *pTimestampInfos,
> +       uint64_t                                     *pTimestamps,
> +       uint64_t                                     *pMaxDeviation)
> +{
> +       RADV_FROM_HANDLE(radv_device, device, _device);
> +       uint32_t clock_crystal_freq =
> device->physical_device->rad_info.clock_crystal_freq;
> +       int d;
> +       uint64_t begin, end;
> +
> +       begin = radv_clock_gettime(CLOCK_MONOTONIC_RAW);
> +
> +       for (d = 0; d < timestampCount; d++) {
> +               switch (pTimestampInfos[d].timeDomain) {
> +               case VK_TIME_DOMAIN_DEVICE_EXT:
> +                       /* XXX older kernels don't support this interface.
> */
> +                       pTimestamps[d] =
> device->ws->query_value(device->ws,
> +
> RADEON_TIMESTAMP);
> +                       break;
> +               case VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT:
> +                       pTimestamps[d] =
> radv_clock_gettime(CLOCK_MONOTONIC);
> +                       break;
> +
> +               case VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT:
> +                       pTimestamps[d] = begin;
> +                       break;
> +               default:
> +                       pTimestamps[d] = 0;
> +                       break;
> +               }
> +       }
> +
> +       end = radv_clock_gettime(CLOCK_MONOTONIC_RAW);
> +
> +       uint64_t clock_period = end - begin;
> +       uint64_t device_period = (1000000 + clock_crystal_freq - 1) /
> clock_crystal_freq;
> +
> +       *pMaxDeviation = clock_period > device_period ? clock_period :
> device_period;
> +
> +       return VK_SUCCESS;
> +}
> diff --git a/src/amd/vulkan/radv_extensions.py
> b/src/amd/vulkan/radv_extensions.py
> index 5dcedae1c63..4c81d3f0068 100644
> --- a/src/amd/vulkan/radv_extensions.py
> +++ b/src/amd/vulkan/radv_extensions.py
> @@ -92,6 +92,7 @@ EXTENSIONS = [
>      Extension('VK_KHR_display',                          23,
> 'VK_USE_PLATFORM_DISPLAY_KHR'),
>      Extension('VK_EXT_direct_mode_display',               1,
> 'VK_USE_PLATFORM_DISPLAY_KHR'),
>      Extension('VK_EXT_acquire_xlib_display',              1,
> 'VK_USE_PLATFORM_XLIB_XRANDR_EXT'),
> +    Extension('VK_EXT_calibrated_timestamps',             1, True),
>      Extension('VK_EXT_conditional_rendering',             1, True),
>      Extension('VK_EXT_conservative_rasterization',        1,
> 'device->rad_info.chip_class >= GFX9'),
>      Extension('VK_EXT_display_surface_counter',           1,
> 'VK_USE_PLATFORM_DISPLAY_KHR'),
> diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c
> index a2551452eb1..6a6539c9685 100644
> --- a/src/intel/vulkan/anv_device.c
> +++ b/src/intel/vulkan/anv_device.c
> @@ -3021,6 +3021,94 @@ void anv_DestroyFramebuffer(
>     vk_free2(&device->alloc, pAllocator, fb);
>  }
>
> +static const VkTimeDomainEXT anv_time_domains[] = {
> +   VK_TIME_DOMAIN_DEVICE_EXT,
> +   VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT,
> +   VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT,
> +};
> +
> +VkResult anv_GetPhysicalDeviceCalibrateableTimeDomainsEXT(
> +   VkPhysicalDevice                             physicalDevice,
> +   uint32_t                                     *pTimeDomainCount,
> +   VkTimeDomainEXT                              *pTimeDomains)
> +{
> +   int d;
> +   VK_OUTARRAY_MAKE(out, pTimeDomains, pTimeDomainCount);
> +
> +   for (d = 0; d < ARRAY_SIZE(anv_time_domains); d++) {
> +      vk_outarray_append(&out, i) {
> +         *i = anv_time_domains[d];
> +      }
> +   }
> +
> +   return vk_outarray_status(&out);
> +}
> +
> +static uint64_t
> +anv_clock_gettime(clockid_t clock_id)
> +{
> +   struct timespec current;
> +   int ret;
> +
> +   ret = clock_gettime(clock_id, &current);
> +   if (ret < 0 && clock_id == CLOCK_MONOTONIC_RAW)
> +      ret = clock_gettime(CLOCK_MONOTONIC, &current);
> +   if (ret < 0)
> +      return 0;
> +
> +   return (uint64_t) current.tv_sec * 1000000000ULL + current.tv_nsec;
> +}
>

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.


> +
> +#define TIMESTAMP 0x2358
> +
> +VkResult anv_GetCalibratedTimestampsEXT(
> +   VkDevice                                     _device,
> +   uint32_t                                     timestampCount,
> +   const VkCalibratedTimestampInfoEXT           *pTimestampInfos,
> +   uint64_t                                     *pTimestamps,
> +   uint64_t                                     *pMaxDeviation)
> +{
> +   ANV_FROM_HANDLE(anv_device, device, _device);
> +   uint64_t timestamp_frequency = device->info.timestamp_frequency;
> +   int  ret;
> +   int d;
> +   uint64_t begin, end;
> +
> +   begin = anv_clock_gettime(CLOCK_MONOTONIC_RAW);
> +
> +   for (d = 0; d < timestampCount; d++) {
> +      switch (pTimestampInfos[d].timeDomain) {
> +      case VK_TIME_DOMAIN_DEVICE_EXT:
> +         /* XXX older kernels don't support this interface. */
>

I don't think we support kernels that old, so you can drop the comment.


> +         ret = anv_gem_reg_read(device, TIMESTAMP | 1,
> +                                &pTimestamps[d]);
> +
> +         if (ret != 0)
> +            return VK_ERROR_DEVICE_LOST;
>

If you're going to return device_lost, you should set device->lost = true;


> +         break;
> +      case VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT:
> +         pTimestamps[d] = anv_clock_gettime(CLOCK_MONOTONIC);
> +         break;
> +
> +      case VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT:
> +         pTimestamps[d] = begin;
> +         break;
> +      default:
> +         pTimestamps[d] = 0;
> +         break;
> +      }
> +   }
> +
> +   end = anv_clock_gettime(CLOCK_MONOTONIC_RAW);
> +
> +   uint64_t clock_period = end - begin;
> +   uint64_t device_period = (1000000000 + timestamp_frequency - 1) /
> timestamp_frequency;
>

I think you just want DIV_ROUND_UP(a, b)


> +
> +   *pMaxDeviation = clock_period > device_period ? clock_period :
> device_period;
>

MAX2(a, b) is your friend.


> +
> +   return VK_SUCCESS;
> +}
> +
>  /* vk_icd.h does not declare this function, so we declare it here to
>   * suppress Wmissing-prototypes.
>   */
> diff --git a/src/intel/vulkan/anv_extensions.py
> b/src/intel/vulkan/anv_extensions.py
> index d4915c95013..a8535964da7 100644
> --- a/src/intel/vulkan/anv_extensions.py
> +++ b/src/intel/vulkan/anv_extensions.py
> @@ -126,6 +126,7 @@ EXTENSIONS = [
>      Extension('VK_EXT_vertex_attribute_divisor',          3, True),
>      Extension('VK_EXT_post_depth_coverage',               1,
> 'device->info.gen >= 9'),
>      Extension('VK_EXT_sampler_filter_minmax',             1,
> 'device->info.gen >= 9'),
> +    Extension('VK_EXT_calibrated_timestamps',             1, True),
>  ]
>
>  class VkVersion:
> diff --git a/src/intel/vulkan/anv_gem.c b/src/intel/vulkan/anv_gem.c
> index c43b5ef9e06..1bdf040c1a3 100644
> --- a/src/intel/vulkan/anv_gem.c
> +++ b/src/intel/vulkan/anv_gem.c
> @@ -423,6 +423,19 @@ anv_gem_fd_to_handle(struct anv_device *device, int
> fd)
>     return args.handle;
>  }
>
> +int
> +anv_gem_reg_read(struct anv_device *device, uint32_t offset, uint64_t
> *result)
> +{
> +   struct drm_i915_reg_read args = {
> +      .offset = offset
> +   };
> +
> +   int ret = anv_ioctl(device->fd, DRM_IOCTL_I915_REG_READ, &args);
> +
> +   *result = args.val;
> +   return ret;
> +}
> +
>  #ifndef SYNC_IOC_MAGIC
>  /* duplicated from linux/sync_file.h to avoid build-time dependency
>   * on new (v4.7) kernel headers.  Once distro's are mostly using
> diff --git a/src/intel/vulkan/anv_private.h
> b/src/intel/vulkan/anv_private.h
> index 599b903f25c..08376b00c8e 100644
> --- a/src/intel/vulkan/anv_private.h
> +++ b/src/intel/vulkan/anv_private.h
> @@ -1103,6 +1103,8 @@ int anv_gem_get_aperture(int fd, uint64_t *size);
>  int anv_gem_gpu_get_reset_stats(struct anv_device *device,
>                                  uint32_t *active, uint32_t *pending);
>  int anv_gem_handle_to_fd(struct anv_device *device, uint32_t gem_handle);
> +int anv_gem_reg_read(struct anv_device *device,
> +                     uint32_t offset, uint64_t *result);
>  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_domain(struct anv_device *device, uint32_t gem_handle,
> --
> 2.19.1
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
>

[-- Attachment #1.2: Type: text/html, Size: 14713 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] vulkan: Add VK_EXT_calibrated_timestamps extension (radv and anv) [v2]
  2018-10-15 21:22 [PATCH] vulkan: Add VK_EXT_calibrated_timestamps extension (radv and anv) [v2] Keith Packard
  2018-10-15 21:36 ` Jason Ekstrand
@ 2018-10-15 21:38 ` Lionel Landwerlin
  2018-10-15 23:05 ` [PATCH] vulkan: Add VK_EXT_calibrated_timestamps extension (radv and anv) [v3] Keith Packard
  2 siblings, 0 replies; 28+ messages in thread
From: Lionel Landwerlin @ 2018-10-15 21:38 UTC (permalink / raw)
  To: Keith Packard, mesa-dev; +Cc: dri-devel

On 15/10/2018 22:22, Keith Packard wrote:
> +#define TIMESTAMP 0x2358
> +
> +VkResult radv_GetCalibratedTimestampsEXT(

Heh, I think you copied that define over from Anv ;)

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH] vulkan: Add VK_EXT_calibrated_timestamps extension (radv and anv) [v3]
  2018-10-15 21:22 [PATCH] vulkan: Add VK_EXT_calibrated_timestamps extension (radv and anv) [v2] Keith Packard
  2018-10-15 21:36 ` Jason Ekstrand
  2018-10-15 21:38 ` Lionel Landwerlin
@ 2018-10-15 23:05 ` Keith Packard
  2018-10-16  1:06   ` Jason Ekstrand
  2018-10-16  5:31   ` [PATCH] vulkan: Add VK_EXT_calibrated_timestamps extension (radv and anv) [v4] Keith Packard
  2 siblings, 2 replies; 28+ messages in thread
From: Keith Packard @ 2018-10-15 23:05 UTC (permalink / raw)
  To: mesa-dev; +Cc: dri-devel

Offers three clocks, device, clock monotonic and clock monotonic
raw. Could use some kernel support to reduce the deviation between
clock values.

v2:
	Ensure deviation is at least as big as the GPU time interval.

v3:
	Set device->lost when returning DEVICE_LOST.
	Use MAX2 and DIV_ROUND_UP instead of open coding these.
	Delete spurious TIMESTAMP in radv version.
	Suggested-by: Jason Ekstrand <jason@jlekstrand.net>
	Suggested-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>

Signed-off-by: Keith Packard <keithp@keithp.com>
---
 src/amd/vulkan/radv_device.c       | 81 +++++++++++++++++++++++++++
 src/amd/vulkan/radv_extensions.py  |  1 +
 src/intel/vulkan/anv_device.c      | 89 ++++++++++++++++++++++++++++++
 src/intel/vulkan/anv_extensions.py |  1 +
 src/intel/vulkan/anv_gem.c         | 13 +++++
 src/intel/vulkan/anv_private.h     |  2 +
 6 files changed, 187 insertions(+)

diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c
index 174922780fc..80050485e54 100644
--- a/src/amd/vulkan/radv_device.c
+++ b/src/amd/vulkan/radv_device.c
@@ -4955,3 +4955,84 @@ radv_GetDeviceGroupPeerMemoryFeatures(
 	                       VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT |
 	                       VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT;
 }
+
+static const VkTimeDomainEXT radv_time_domains[] = {
+	VK_TIME_DOMAIN_DEVICE_EXT,
+	VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT,
+	VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT,
+};
+
+VkResult radv_GetPhysicalDeviceCalibrateableTimeDomainsEXT(
+	VkPhysicalDevice                             physicalDevice,
+	uint32_t                                     *pTimeDomainCount,
+	VkTimeDomainEXT                              *pTimeDomains)
+{
+	int d;
+	VK_OUTARRAY_MAKE(out, pTimeDomains, pTimeDomainCount);
+
+	for (d = 0; d < ARRAY_SIZE(radv_time_domains); d++) {
+		vk_outarray_append(&out, i) {
+			*i = radv_time_domains[d];
+		}
+	}
+
+	return vk_outarray_status(&out);
+}
+
+static uint64_t
+radv_clock_gettime(clockid_t clock_id)
+{
+	struct timespec current;
+	int ret;
+
+	ret = clock_gettime(clock_id, &current);
+	if (ret < 0 && clock_id == CLOCK_MONOTONIC_RAW)
+		ret = clock_gettime(CLOCK_MONOTONIC, &current);
+	if (ret < 0)
+		return 0;
+
+	return (uint64_t) current.tv_sec * 1000000000ULL + current.tv_nsec;
+}
+
+VkResult radv_GetCalibratedTimestampsEXT(
+	VkDevice                                     _device,
+	uint32_t                                     timestampCount,
+	const VkCalibratedTimestampInfoEXT           *pTimestampInfos,
+	uint64_t                                     *pTimestamps,
+	uint64_t                                     *pMaxDeviation)
+{
+	RADV_FROM_HANDLE(radv_device, device, _device);
+	uint32_t clock_crystal_freq = device->physical_device->rad_info.clock_crystal_freq;
+	int d;
+	uint64_t begin, end;
+
+	begin = radv_clock_gettime(CLOCK_MONOTONIC_RAW);
+
+	for (d = 0; d < timestampCount; d++) {
+		switch (pTimestampInfos[d].timeDomain) {
+		case VK_TIME_DOMAIN_DEVICE_EXT:
+			pTimestamps[d] = device->ws->query_value(device->ws,
+								 RADEON_TIMESTAMP);
+			break;
+		case VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT:
+			pTimestamps[d] = radv_clock_gettime(CLOCK_MONOTONIC);
+			break;
+
+		case VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT:
+			pTimestamps[d] = begin;
+			break;
+		default:
+			pTimestamps[d] = 0;
+			break;
+		}
+	}
+
+	end = radv_clock_gettime(CLOCK_MONOTONIC_RAW);
+
+	uint64_t clock_period = end - begin;
+	uint64_t device_period = DIV_ROUND_UP(1000000, clock_crystal_freq);
+
+	*pMaxDeviation = MAX2(clock_period, device_period);
+
+	return VK_SUCCESS;
+}
diff --git a/src/amd/vulkan/radv_extensions.py b/src/amd/vulkan/radv_extensions.py
index 5dcedae1c63..4c81d3f0068 100644
--- a/src/amd/vulkan/radv_extensions.py
+++ b/src/amd/vulkan/radv_extensions.py
@@ -92,6 +92,7 @@ EXTENSIONS = [
     Extension('VK_KHR_display',                          23, 'VK_USE_PLATFORM_DISPLAY_KHR'),
     Extension('VK_EXT_direct_mode_display',               1, 'VK_USE_PLATFORM_DISPLAY_KHR'),
     Extension('VK_EXT_acquire_xlib_display',              1, 'VK_USE_PLATFORM_XLIB_XRANDR_EXT'),
+    Extension('VK_EXT_calibrated_timestamps',             1, True),
     Extension('VK_EXT_conditional_rendering',             1, True),
     Extension('VK_EXT_conservative_rasterization',        1, 'device->rad_info.chip_class >= GFX9'),
     Extension('VK_EXT_display_surface_counter',           1, 'VK_USE_PLATFORM_DISPLAY_KHR'),
diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c
index a2551452eb1..249d7f36f0f 100644
--- a/src/intel/vulkan/anv_device.c
+++ b/src/intel/vulkan/anv_device.c
@@ -3021,6 +3021,95 @@ void anv_DestroyFramebuffer(
    vk_free2(&device->alloc, pAllocator, fb);
 }
 
+static const VkTimeDomainEXT anv_time_domains[] = {
+   VK_TIME_DOMAIN_DEVICE_EXT,
+   VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT,
+   VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT,
+};
+
+VkResult anv_GetPhysicalDeviceCalibrateableTimeDomainsEXT(
+   VkPhysicalDevice                             physicalDevice,
+   uint32_t                                     *pTimeDomainCount,
+   VkTimeDomainEXT                              *pTimeDomains)
+{
+   int d;
+   VK_OUTARRAY_MAKE(out, pTimeDomains, pTimeDomainCount);
+
+   for (d = 0; d < ARRAY_SIZE(anv_time_domains); d++) {
+      vk_outarray_append(&out, i) {
+         *i = anv_time_domains[d];
+      }
+   }
+
+   return vk_outarray_status(&out);
+}
+
+static uint64_t
+anv_clock_gettime(clockid_t clock_id)
+{
+   struct timespec current;
+   int ret;
+
+   ret = clock_gettime(clock_id, &current);
+   if (ret < 0 && clock_id == CLOCK_MONOTONIC_RAW)
+      ret = clock_gettime(CLOCK_MONOTONIC, &current);
+   if (ret < 0)
+      return 0;
+
+   return (uint64_t) current.tv_sec * 1000000000ULL + current.tv_nsec;
+}
+
+#define TIMESTAMP 0x2358
+
+VkResult anv_GetCalibratedTimestampsEXT(
+   VkDevice                                     _device,
+   uint32_t                                     timestampCount,
+   const VkCalibratedTimestampInfoEXT           *pTimestampInfos,
+   uint64_t                                     *pTimestamps,
+   uint64_t                                     *pMaxDeviation)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   uint64_t timestamp_frequency = device->info.timestamp_frequency;
+   int  ret;
+   int d;
+   uint64_t begin, end;
+
+   begin = anv_clock_gettime(CLOCK_MONOTONIC_RAW);
+
+   for (d = 0; d < timestampCount; d++) {
+      switch (pTimestampInfos[d].timeDomain) {
+      case VK_TIME_DOMAIN_DEVICE_EXT:
+         ret = anv_gem_reg_read(device, TIMESTAMP | 1,
+                                &pTimestamps[d]);
+
+         if (ret != 0) {
+            device->lost = TRUE;
+            return VK_ERROR_DEVICE_LOST;
+         }
+         break;
+      case VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT:
+         pTimestamps[d] = anv_clock_gettime(CLOCK_MONOTONIC);
+         break;
+
+      case VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT:
+         pTimestamps[d] = begin;
+         break;
+      default:
+         pTimestamps[d] = 0;
+         break;
+      }
+   }
+
+   end = anv_clock_gettime(CLOCK_MONOTONIC_RAW);
+
+   uint64_t clock_period = end - begin;
+   uint64_t device_period = DIV_ROUND_UP(1000000000, timestamp_frequency);
+
+   *pMaxDeviation = MAX2(clock_period, device_period);
+
+   return VK_SUCCESS;
+}
+
 /* vk_icd.h does not declare this function, so we declare it here to
  * suppress Wmissing-prototypes.
  */
diff --git a/src/intel/vulkan/anv_extensions.py b/src/intel/vulkan/anv_extensions.py
index d4915c95013..a8535964da7 100644
--- a/src/intel/vulkan/anv_extensions.py
+++ b/src/intel/vulkan/anv_extensions.py
@@ -126,6 +126,7 @@ EXTENSIONS = [
     Extension('VK_EXT_vertex_attribute_divisor',          3, True),
     Extension('VK_EXT_post_depth_coverage',               1, 'device->info.gen >= 9'),
     Extension('VK_EXT_sampler_filter_minmax',             1, 'device->info.gen >= 9'),
+    Extension('VK_EXT_calibrated_timestamps',             1, True),
 ]
 
 class VkVersion:
diff --git a/src/intel/vulkan/anv_gem.c b/src/intel/vulkan/anv_gem.c
index c43b5ef9e06..1bdf040c1a3 100644
--- a/src/intel/vulkan/anv_gem.c
+++ b/src/intel/vulkan/anv_gem.c
@@ -423,6 +423,19 @@ anv_gem_fd_to_handle(struct anv_device *device, int fd)
    return args.handle;
 }
 
+int
+anv_gem_reg_read(struct anv_device *device, uint32_t offset, uint64_t *result)
+{
+   struct drm_i915_reg_read args = {
+      .offset = offset
+   };
+
+   int ret = anv_ioctl(device->fd, DRM_IOCTL_I915_REG_READ, &args);
+
+   *result = args.val;
+   return ret;
+}
+
 #ifndef SYNC_IOC_MAGIC
 /* duplicated from linux/sync_file.h to avoid build-time dependency
  * on new (v4.7) kernel headers.  Once distro's are mostly using
diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
index 599b903f25c..08376b00c8e 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -1103,6 +1103,8 @@ int anv_gem_get_aperture(int fd, uint64_t *size);
 int anv_gem_gpu_get_reset_stats(struct anv_device *device,
                                 uint32_t *active, uint32_t *pending);
 int anv_gem_handle_to_fd(struct anv_device *device, uint32_t gem_handle);
+int anv_gem_reg_read(struct anv_device *device,
+                     uint32_t offset, uint64_t *result);
 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_domain(struct anv_device *device, uint32_t gem_handle,
-- 
2.19.1

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* Re: [PATCH] vulkan: Add VK_EXT_calibrated_timestamps extension (radv and anv) [v3]
  2018-10-15 23:05 ` [PATCH] vulkan: Add VK_EXT_calibrated_timestamps extension (radv and anv) [v3] Keith Packard
@ 2018-10-16  1:06   ` Jason Ekstrand
  2018-10-16  5:31     ` [Mesa-dev] " Keith Packard
  2018-10-16  5:31   ` [PATCH] vulkan: Add VK_EXT_calibrated_timestamps extension (radv and anv) [v4] Keith Packard
  1 sibling, 1 reply; 28+ messages in thread
From: Jason Ekstrand @ 2018-10-16  1:06 UTC (permalink / raw)
  To: Keith Packard; +Cc: ML mesa-dev, Maling list - DRI developers


[-- Attachment #1.1: Type: text/plain, Size: 11175 bytes --]

On Mon, Oct 15, 2018 at 6:05 PM Keith Packard <keithp@keithp.com> wrote:

> Offers three clocks, device, clock monotonic and clock monotonic
> raw. Could use some kernel support to reduce the deviation between
> clock values.
>
> v2:
>         Ensure deviation is at least as big as the GPU time interval.
>
> v3:
>         Set device->lost when returning DEVICE_LOST.
>         Use MAX2 and DIV_ROUND_UP instead of open coding these.
>         Delete spurious TIMESTAMP in radv version.
>         Suggested-by: Jason Ekstrand <jason@jlekstrand.net>
>         Suggested-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
>
> Signed-off-by: Keith Packard <keithp@keithp.com>
> ---
>  src/amd/vulkan/radv_device.c       | 81 +++++++++++++++++++++++++++
>  src/amd/vulkan/radv_extensions.py  |  1 +
>  src/intel/vulkan/anv_device.c      | 89 ++++++++++++++++++++++++++++++
>  src/intel/vulkan/anv_extensions.py |  1 +
>  src/intel/vulkan/anv_gem.c         | 13 +++++
>  src/intel/vulkan/anv_private.h     |  2 +
>  6 files changed, 187 insertions(+)
>
> diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c
> index 174922780fc..80050485e54 100644
> --- a/src/amd/vulkan/radv_device.c
> +++ b/src/amd/vulkan/radv_device.c
> @@ -4955,3 +4955,84 @@ radv_GetDeviceGroupPeerMemoryFeatures(
>                                VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT |
>                                VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT;
>  }
> +
> +static const VkTimeDomainEXT radv_time_domains[] = {
> +       VK_TIME_DOMAIN_DEVICE_EXT,
> +       VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT,
> +       VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT,
> +};
> +
> +VkResult radv_GetPhysicalDeviceCalibrateableTimeDomainsEXT(
> +       VkPhysicalDevice                             physicalDevice,
> +       uint32_t                                     *pTimeDomainCount,
> +       VkTimeDomainEXT                              *pTimeDomains)
> +{
> +       int d;
> +       VK_OUTARRAY_MAKE(out, pTimeDomains, pTimeDomainCount);
> +
> +       for (d = 0; d < ARRAY_SIZE(radv_time_domains); d++) {
> +               vk_outarray_append(&out, i) {
> +                       *i = radv_time_domains[d];
> +               }
> +       }
> +
> +       return vk_outarray_status(&out);
> +}
> +
> +static uint64_t
> +radv_clock_gettime(clockid_t clock_id)
> +{
> +       struct timespec current;
> +       int ret;
> +
> +       ret = clock_gettime(clock_id, &current);
> +       if (ret < 0 && clock_id == CLOCK_MONOTONIC_RAW)
> +               ret = clock_gettime(CLOCK_MONOTONIC, &current);
> +       if (ret < 0)
> +               return 0;
> +
> +       return (uint64_t) current.tv_sec * 1000000000ULL + current.tv_nsec;
> +}
> +
> +VkResult radv_GetCalibratedTimestampsEXT(
> +       VkDevice                                     _device,
> +       uint32_t                                     timestampCount,
> +       const VkCalibratedTimestampInfoEXT           *pTimestampInfos,
> +       uint64_t                                     *pTimestamps,
> +       uint64_t                                     *pMaxDeviation)
> +{
> +       RADV_FROM_HANDLE(radv_device, device, _device);
> +       uint32_t clock_crystal_freq =
> device->physical_device->rad_info.clock_crystal_freq;
> +       int d;
> +       uint64_t begin, end;
> +
> +       begin = radv_clock_gettime(CLOCK_MONOTONIC_RAW);
> +
> +       for (d = 0; d < timestampCount; d++) {
> +               switch (pTimestampInfos[d].timeDomain) {
> +               case VK_TIME_DOMAIN_DEVICE_EXT:
> +                       pTimestamps[d] =
> device->ws->query_value(device->ws,
> +
> RADEON_TIMESTAMP);
> +                       break;
> +               case VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT:
> +                       pTimestamps[d] =
> radv_clock_gettime(CLOCK_MONOTONIC);
> +                       break;
> +
> +               case VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT:
> +                       pTimestamps[d] = begin;
> +                       break;
> +               default:
> +                       pTimestamps[d] = 0;
> +                       break;
> +               }
> +       }
> +
> +       end = radv_clock_gettime(CLOCK_MONOTONIC_RAW);
> +
> +       uint64_t clock_period = end - begin;
> +       uint64_t device_period = DIV_ROUND_UP(1000000, clock_crystal_freq);
> +
> +       *pMaxDeviation = MAX2(clock_period, device_period);
> +
> +       return VK_SUCCESS;
> +}
> diff --git a/src/amd/vulkan/radv_extensions.py
> b/src/amd/vulkan/radv_extensions.py
> index 5dcedae1c63..4c81d3f0068 100644
> --- a/src/amd/vulkan/radv_extensions.py
> +++ b/src/amd/vulkan/radv_extensions.py
> @@ -92,6 +92,7 @@ EXTENSIONS = [
>      Extension('VK_KHR_display',                          23,
> 'VK_USE_PLATFORM_DISPLAY_KHR'),
>      Extension('VK_EXT_direct_mode_display',               1,
> 'VK_USE_PLATFORM_DISPLAY_KHR'),
>      Extension('VK_EXT_acquire_xlib_display',              1,
> 'VK_USE_PLATFORM_XLIB_XRANDR_EXT'),
> +    Extension('VK_EXT_calibrated_timestamps',             1, True),
>      Extension('VK_EXT_conditional_rendering',             1, True),
>      Extension('VK_EXT_conservative_rasterization',        1,
> 'device->rad_info.chip_class >= GFX9'),
>      Extension('VK_EXT_display_surface_counter',           1,
> 'VK_USE_PLATFORM_DISPLAY_KHR'),
> diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c
> index a2551452eb1..249d7f36f0f 100644
> --- a/src/intel/vulkan/anv_device.c
> +++ b/src/intel/vulkan/anv_device.c
> @@ -3021,6 +3021,95 @@ void anv_DestroyFramebuffer(
>     vk_free2(&device->alloc, pAllocator, fb);
>  }
>
> +static const VkTimeDomainEXT anv_time_domains[] = {
> +   VK_TIME_DOMAIN_DEVICE_EXT,
> +   VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT,
> +   VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT,
> +};
> +
> +VkResult anv_GetPhysicalDeviceCalibrateableTimeDomainsEXT(
> +   VkPhysicalDevice                             physicalDevice,
> +   uint32_t                                     *pTimeDomainCount,
> +   VkTimeDomainEXT                              *pTimeDomains)
> +{
> +   int d;
> +   VK_OUTARRAY_MAKE(out, pTimeDomains, pTimeDomainCount);
> +
> +   for (d = 0; d < ARRAY_SIZE(anv_time_domains); d++) {
> +      vk_outarray_append(&out, i) {
> +         *i = anv_time_domains[d];
> +      }
> +   }
> +
> +   return vk_outarray_status(&out);
> +}
> +
> +static uint64_t
> +anv_clock_gettime(clockid_t clock_id)
> +{
> +   struct timespec current;
> +   int ret;
> +
> +   ret = clock_gettime(clock_id, &current);
> +   if (ret < 0 && clock_id == CLOCK_MONOTONIC_RAW)
> +      ret = clock_gettime(CLOCK_MONOTONIC, &current);
> +   if (ret < 0)
> +      return 0;
> +
> +   return (uint64_t) current.tv_sec * 1000000000ULL + current.tv_nsec;
> +}
> +
> +#define TIMESTAMP 0x2358
> +
> +VkResult anv_GetCalibratedTimestampsEXT(
> +   VkDevice                                     _device,
> +   uint32_t                                     timestampCount,
> +   const VkCalibratedTimestampInfoEXT           *pTimestampInfos,
> +   uint64_t                                     *pTimestamps,
> +   uint64_t                                     *pMaxDeviation)
> +{
> +   ANV_FROM_HANDLE(anv_device, device, _device);
> +   uint64_t timestamp_frequency = device->info.timestamp_frequency;
> +   int  ret;
> +   int d;
> +   uint64_t begin, end;
> +
> +   begin = anv_clock_gettime(CLOCK_MONOTONIC_RAW);
> +
> +   for (d = 0; d < timestampCount; d++) {
> +      switch (pTimestampInfos[d].timeDomain) {
> +      case VK_TIME_DOMAIN_DEVICE_EXT:
> +         ret = anv_gem_reg_read(device, TIMESTAMP | 1,
> +                                &pTimestamps[d]);
> +
> +         if (ret != 0) {
> +            device->lost = TRUE;
> +            return VK_ERROR_DEVICE_LOST;
> +         }
> +         break;
> +      case VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT:
> +         pTimestamps[d] = anv_clock_gettime(CLOCK_MONOTONIC);
> +         break;
> +
> +      case VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT:
> +         pTimestamps[d] = begin;
> +         break;
> +      default:
> +         pTimestamps[d] = 0;
> +         break;
> +      }
> +   }
> +
> +   end = anv_clock_gettime(CLOCK_MONOTONIC_RAW);
> +
> +   uint64_t clock_period = end - begin;
> +   uint64_t device_period = DIV_ROUND_UP(1000000000, timestamp_frequency);
> +
> +   *pMaxDeviation = MAX2(clock_period, device_period);
> +
> +   return VK_SUCCESS;
> +}
> +
>  /* vk_icd.h does not declare this function, so we declare it here to
>   * suppress Wmissing-prototypes.
>   */
> diff --git a/src/intel/vulkan/anv_extensions.py
> b/src/intel/vulkan/anv_extensions.py
> index d4915c95013..a8535964da7 100644
> --- a/src/intel/vulkan/anv_extensions.py
> +++ b/src/intel/vulkan/anv_extensions.py
> @@ -126,6 +126,7 @@ EXTENSIONS = [
>      Extension('VK_EXT_vertex_attribute_divisor',          3, True),
>      Extension('VK_EXT_post_depth_coverage',               1,
> 'device->info.gen >= 9'),
>      Extension('VK_EXT_sampler_filter_minmax',             1,
> 'device->info.gen >= 9'),
> +    Extension('VK_EXT_calibrated_timestamps',             1, True),
>  ]
>
>  class VkVersion:
> diff --git a/src/intel/vulkan/anv_gem.c b/src/intel/vulkan/anv_gem.c
> index c43b5ef9e06..1bdf040c1a3 100644
> --- a/src/intel/vulkan/anv_gem.c
> +++ b/src/intel/vulkan/anv_gem.c
> @@ -423,6 +423,19 @@ anv_gem_fd_to_handle(struct anv_device *device, int
> fd)
>     return args.handle;
>  }
>
> +int
> +anv_gem_reg_read(struct anv_device *device, uint32_t offset, uint64_t
> *result)
> +{
> +   struct drm_i915_reg_read args = {
> +      .offset = offset
> +   };
> +
> +   int ret = anv_ioctl(device->fd, DRM_IOCTL_I915_REG_READ, &args);
> +
> +   *result = args.val;
> +   return ret;
> +}
>

You need to add this to anv_gem_stubs.c as well or else the unit tests
won't build.  Sorry for not catching it earlier.  I'm always missing this
too.

With that fixed, the anv bits are

Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>


> +
>  #ifndef SYNC_IOC_MAGIC
>  /* duplicated from linux/sync_file.h to avoid build-time dependency
>   * on new (v4.7) kernel headers.  Once distro's are mostly using
> diff --git a/src/intel/vulkan/anv_private.h
> b/src/intel/vulkan/anv_private.h
> index 599b903f25c..08376b00c8e 100644
> --- a/src/intel/vulkan/anv_private.h
> +++ b/src/intel/vulkan/anv_private.h
> @@ -1103,6 +1103,8 @@ int anv_gem_get_aperture(int fd, uint64_t *size);
>  int anv_gem_gpu_get_reset_stats(struct anv_device *device,
>                                  uint32_t *active, uint32_t *pending);
>  int anv_gem_handle_to_fd(struct anv_device *device, uint32_t gem_handle);
> +int anv_gem_reg_read(struct anv_device *device,
> +                     uint32_t offset, uint64_t *result);
>  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_domain(struct anv_device *device, uint32_t gem_handle,
> --
> 2.19.1
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
>

[-- Attachment #1.2: Type: text/html, Size: 14421 bytes --]

[-- Attachment #2: Type: text/plain, Size: 157 bytes --]

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [Mesa-dev] [PATCH] vulkan: Add VK_EXT_calibrated_timestamps extension (radv and anv) [v3]
  2018-10-16  1:06   ` Jason Ekstrand
@ 2018-10-16  5:31     ` Keith Packard
  0 siblings, 0 replies; 28+ messages in thread
From: Keith Packard @ 2018-10-16  5:31 UTC (permalink / raw)
  To: Jason Ekstrand; +Cc: ML mesa-dev, Maling list - DRI developers


[-- Attachment #1.1: Type: text/plain, Size: 645 bytes --]

Jason Ekstrand <jason@jlekstrand.net> writes:


> You need to add this to anv_gem_stubs.c as well or else the unit tests
> won't build.  Sorry for not catching it earlier.  I'm always missing this
> too.

Well, that's a bit hard to test as -Dbuild-tests=true fails in a bunch
of glx tests, but I think I've got it.

> With that fixed, the anv bits are
>
> Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>

Thanks. I haven't heard from any radv developers, so I can either split
the patch apart or wait for another day or two. In any case, I'll post
v4 of the patch here with the anv_gem_reg_read addition made.

-- 
-keith

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH] vulkan: Add VK_EXT_calibrated_timestamps extension (radv and anv) [v4]
  2018-10-15 23:05 ` [PATCH] vulkan: Add VK_EXT_calibrated_timestamps extension (radv and anv) [v3] Keith Packard
  2018-10-16  1:06   ` Jason Ekstrand
@ 2018-10-16  5:31   ` Keith Packard
  2018-10-16  7:32     ` Samuel Pitoiset
                       ` (2 more replies)
  1 sibling, 3 replies; 28+ messages in thread
From: Keith Packard @ 2018-10-16  5:31 UTC (permalink / raw)
  To: mesa-dev; +Cc: Keith Packard, dri-devel

Offers three clocks, device, clock monotonic and clock monotonic
raw. Could use some kernel support to reduce the deviation between
clock values.

v2:
	Ensure deviation is at least as big as the GPU time interval.

v3:
	Set device->lost when returning DEVICE_LOST.
	Use MAX2 and DIV_ROUND_UP instead of open coding these.
	Delete spurious TIMESTAMP in radv version.
	Suggested-by: Jason Ekstrand <jason@jlekstrand.net>
	Suggested-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>

v4:
	Add anv_gem_reg_read to anv_gem_stubs.c
	Suggested-by: Jason Ekstrand <jason@jlekstrand.net>

Signed-off-by: Keith Packard <keithp@keithp.com>
---
 src/amd/vulkan/radv_device.c       | 81 +++++++++++++++++++++++++++
 src/amd/vulkan/radv_extensions.py  |  1 +
 src/intel/vulkan/anv_device.c      | 89 ++++++++++++++++++++++++++++++
 src/intel/vulkan/anv_extensions.py |  1 +
 src/intel/vulkan/anv_gem.c         | 13 +++++
 src/intel/vulkan/anv_gem_stubs.c   |  7 +++
 src/intel/vulkan/anv_private.h     |  2 +
 7 files changed, 194 insertions(+)

diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c
index 174922780fc..80050485e54 100644
--- a/src/amd/vulkan/radv_device.c
+++ b/src/amd/vulkan/radv_device.c
@@ -4955,3 +4955,84 @@ radv_GetDeviceGroupPeerMemoryFeatures(
 	                       VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT |
 	                       VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT;
 }
+
+static const VkTimeDomainEXT radv_time_domains[] = {
+	VK_TIME_DOMAIN_DEVICE_EXT,
+	VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT,
+	VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT,
+};
+
+VkResult radv_GetPhysicalDeviceCalibrateableTimeDomainsEXT(
+	VkPhysicalDevice                             physicalDevice,
+	uint32_t                                     *pTimeDomainCount,
+	VkTimeDomainEXT                              *pTimeDomains)
+{
+	int d;
+	VK_OUTARRAY_MAKE(out, pTimeDomains, pTimeDomainCount);
+
+	for (d = 0; d < ARRAY_SIZE(radv_time_domains); d++) {
+		vk_outarray_append(&out, i) {
+			*i = radv_time_domains[d];
+		}
+	}
+
+	return vk_outarray_status(&out);
+}
+
+static uint64_t
+radv_clock_gettime(clockid_t clock_id)
+{
+	struct timespec current;
+	int ret;
+
+	ret = clock_gettime(clock_id, &current);
+	if (ret < 0 && clock_id == CLOCK_MONOTONIC_RAW)
+		ret = clock_gettime(CLOCK_MONOTONIC, &current);
+	if (ret < 0)
+		return 0;
+
+	return (uint64_t) current.tv_sec * 1000000000ULL + current.tv_nsec;
+}
+
+VkResult radv_GetCalibratedTimestampsEXT(
+	VkDevice                                     _device,
+	uint32_t                                     timestampCount,
+	const VkCalibratedTimestampInfoEXT           *pTimestampInfos,
+	uint64_t                                     *pTimestamps,
+	uint64_t                                     *pMaxDeviation)
+{
+	RADV_FROM_HANDLE(radv_device, device, _device);
+	uint32_t clock_crystal_freq = device->physical_device->rad_info.clock_crystal_freq;
+	int d;
+	uint64_t begin, end;
+
+	begin = radv_clock_gettime(CLOCK_MONOTONIC_RAW);
+
+	for (d = 0; d < timestampCount; d++) {
+		switch (pTimestampInfos[d].timeDomain) {
+		case VK_TIME_DOMAIN_DEVICE_EXT:
+			pTimestamps[d] = device->ws->query_value(device->ws,
+								 RADEON_TIMESTAMP);
+			break;
+		case VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT:
+			pTimestamps[d] = radv_clock_gettime(CLOCK_MONOTONIC);
+			break;
+
+		case VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT:
+			pTimestamps[d] = begin;
+			break;
+		default:
+			pTimestamps[d] = 0;
+			break;
+		}
+	}
+
+	end = radv_clock_gettime(CLOCK_MONOTONIC_RAW);
+
+	uint64_t clock_period = end - begin;
+	uint64_t device_period = DIV_ROUND_UP(1000000, clock_crystal_freq);
+
+	*pMaxDeviation = MAX2(clock_period, device_period);
+
+	return VK_SUCCESS;
+}
diff --git a/src/amd/vulkan/radv_extensions.py b/src/amd/vulkan/radv_extensions.py
index 5dcedae1c63..4c81d3f0068 100644
--- a/src/amd/vulkan/radv_extensions.py
+++ b/src/amd/vulkan/radv_extensions.py
@@ -92,6 +92,7 @@ EXTENSIONS = [
     Extension('VK_KHR_display',                          23, 'VK_USE_PLATFORM_DISPLAY_KHR'),
     Extension('VK_EXT_direct_mode_display',               1, 'VK_USE_PLATFORM_DISPLAY_KHR'),
     Extension('VK_EXT_acquire_xlib_display',              1, 'VK_USE_PLATFORM_XLIB_XRANDR_EXT'),
+    Extension('VK_EXT_calibrated_timestamps',             1, True),
     Extension('VK_EXT_conditional_rendering',             1, True),
     Extension('VK_EXT_conservative_rasterization',        1, 'device->rad_info.chip_class >= GFX9'),
     Extension('VK_EXT_display_surface_counter',           1, 'VK_USE_PLATFORM_DISPLAY_KHR'),
diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c
index a2551452eb1..249d7f36f0f 100644
--- a/src/intel/vulkan/anv_device.c
+++ b/src/intel/vulkan/anv_device.c
@@ -3021,6 +3021,95 @@ void anv_DestroyFramebuffer(
    vk_free2(&device->alloc, pAllocator, fb);
 }
 
+static const VkTimeDomainEXT anv_time_domains[] = {
+   VK_TIME_DOMAIN_DEVICE_EXT,
+   VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT,
+   VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT,
+};
+
+VkResult anv_GetPhysicalDeviceCalibrateableTimeDomainsEXT(
+   VkPhysicalDevice                             physicalDevice,
+   uint32_t                                     *pTimeDomainCount,
+   VkTimeDomainEXT                              *pTimeDomains)
+{
+   int d;
+   VK_OUTARRAY_MAKE(out, pTimeDomains, pTimeDomainCount);
+
+   for (d = 0; d < ARRAY_SIZE(anv_time_domains); d++) {
+      vk_outarray_append(&out, i) {
+         *i = anv_time_domains[d];
+      }
+   }
+
+   return vk_outarray_status(&out);
+}
+
+static uint64_t
+anv_clock_gettime(clockid_t clock_id)
+{
+   struct timespec current;
+   int ret;
+
+   ret = clock_gettime(clock_id, &current);
+   if (ret < 0 && clock_id == CLOCK_MONOTONIC_RAW)
+      ret = clock_gettime(CLOCK_MONOTONIC, &current);
+   if (ret < 0)
+      return 0;
+
+   return (uint64_t) current.tv_sec * 1000000000ULL + current.tv_nsec;
+}
+
+#define TIMESTAMP 0x2358
+
+VkResult anv_GetCalibratedTimestampsEXT(
+   VkDevice                                     _device,
+   uint32_t                                     timestampCount,
+   const VkCalibratedTimestampInfoEXT           *pTimestampInfos,
+   uint64_t                                     *pTimestamps,
+   uint64_t                                     *pMaxDeviation)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   uint64_t timestamp_frequency = device->info.timestamp_frequency;
+   int  ret;
+   int d;
+   uint64_t begin, end;
+
+   begin = anv_clock_gettime(CLOCK_MONOTONIC_RAW);
+
+   for (d = 0; d < timestampCount; d++) {
+      switch (pTimestampInfos[d].timeDomain) {
+      case VK_TIME_DOMAIN_DEVICE_EXT:
+         ret = anv_gem_reg_read(device, TIMESTAMP | 1,
+                                &pTimestamps[d]);
+
+         if (ret != 0) {
+            device->lost = TRUE;
+            return VK_ERROR_DEVICE_LOST;
+         }
+         break;
+      case VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT:
+         pTimestamps[d] = anv_clock_gettime(CLOCK_MONOTONIC);
+         break;
+
+      case VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT:
+         pTimestamps[d] = begin;
+         break;
+      default:
+         pTimestamps[d] = 0;
+         break;
+      }
+   }
+
+   end = anv_clock_gettime(CLOCK_MONOTONIC_RAW);
+
+   uint64_t clock_period = end - begin;
+   uint64_t device_period = DIV_ROUND_UP(1000000000, timestamp_frequency);
+
+   *pMaxDeviation = MAX2(clock_period, device_period);
+
+   return VK_SUCCESS;
+}
+
 /* vk_icd.h does not declare this function, so we declare it here to
  * suppress Wmissing-prototypes.
  */
diff --git a/src/intel/vulkan/anv_extensions.py b/src/intel/vulkan/anv_extensions.py
index d4915c95013..a8535964da7 100644
--- a/src/intel/vulkan/anv_extensions.py
+++ b/src/intel/vulkan/anv_extensions.py
@@ -126,6 +126,7 @@ EXTENSIONS = [
     Extension('VK_EXT_vertex_attribute_divisor',          3, True),
     Extension('VK_EXT_post_depth_coverage',               1, 'device->info.gen >= 9'),
     Extension('VK_EXT_sampler_filter_minmax',             1, 'device->info.gen >= 9'),
+    Extension('VK_EXT_calibrated_timestamps',             1, True),
 ]
 
 class VkVersion:
diff --git a/src/intel/vulkan/anv_gem.c b/src/intel/vulkan/anv_gem.c
index c43b5ef9e06..1bdf040c1a3 100644
--- a/src/intel/vulkan/anv_gem.c
+++ b/src/intel/vulkan/anv_gem.c
@@ -423,6 +423,19 @@ anv_gem_fd_to_handle(struct anv_device *device, int fd)
    return args.handle;
 }
 
+int
+anv_gem_reg_read(struct anv_device *device, uint32_t offset, uint64_t *result)
+{
+   struct drm_i915_reg_read args = {
+      .offset = offset
+   };
+
+   int ret = anv_ioctl(device->fd, DRM_IOCTL_I915_REG_READ, &args);
+
+   *result = args.val;
+   return ret;
+}
+
 #ifndef SYNC_IOC_MAGIC
 /* duplicated from linux/sync_file.h to avoid build-time dependency
  * on new (v4.7) kernel headers.  Once distro's are mostly using
diff --git a/src/intel/vulkan/anv_gem_stubs.c b/src/intel/vulkan/anv_gem_stubs.c
index 5093bd5db1a..8cc3ad1f22e 100644
--- a/src/intel/vulkan/anv_gem_stubs.c
+++ b/src/intel/vulkan/anv_gem_stubs.c
@@ -251,3 +251,10 @@ anv_gem_syncobj_wait(struct anv_device *device,
 {
    unreachable("Unused");
 }
+
+int
+anv_gem_reg_read(struct anv_device *device,
+                 uint32_t offset, uint64_t *result)
+{
+   unreachable("Unused");
+}
diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
index 599b903f25c..08376b00c8e 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -1103,6 +1103,8 @@ int anv_gem_get_aperture(int fd, uint64_t *size);
 int anv_gem_gpu_get_reset_stats(struct anv_device *device,
                                 uint32_t *active, uint32_t *pending);
 int anv_gem_handle_to_fd(struct anv_device *device, uint32_t gem_handle);
+int anv_gem_reg_read(struct anv_device *device,
+                     uint32_t offset, uint64_t *result);
 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_domain(struct anv_device *device, uint32_t gem_handle,
-- 
2.19.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* Re: [PATCH] vulkan: Add VK_EXT_calibrated_timestamps extension (radv and anv) [v4]
  2018-10-16  5:31   ` [PATCH] vulkan: Add VK_EXT_calibrated_timestamps extension (radv and anv) [v4] Keith Packard
@ 2018-10-16  7:32     ` Samuel Pitoiset
  2018-10-16  7:33     ` Bas Nieuwenhuizen
  2018-10-17 16:49     ` [PATCH] vulkan: Add VK_EXT_calibrated_timestamps extension (radv and anv) [v5] Keith Packard
  2 siblings, 0 replies; 28+ messages in thread
From: Samuel Pitoiset @ 2018-10-16  7:32 UTC (permalink / raw)
  To: Keith Packard, mesa-dev; +Cc: dri-devel

The RADV bits are:

Reviewed-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>

Thanks!

On 10/16/18 7:31 AM, Keith Packard wrote:
> Offers three clocks, device, clock monotonic and clock monotonic
> raw. Could use some kernel support to reduce the deviation between
> clock values.
> 
> v2:
> 	Ensure deviation is at least as big as the GPU time interval.
> 
> v3:
> 	Set device->lost when returning DEVICE_LOST.
> 	Use MAX2 and DIV_ROUND_UP instead of open coding these.
> 	Delete spurious TIMESTAMP in radv version.
> 	Suggested-by: Jason Ekstrand <jason@jlekstrand.net>
> 	Suggested-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
> 
> v4:
> 	Add anv_gem_reg_read to anv_gem_stubs.c
> 	Suggested-by: Jason Ekstrand <jason@jlekstrand.net>
> 
> Signed-off-by: Keith Packard <keithp@keithp.com>
> ---
>   src/amd/vulkan/radv_device.c       | 81 +++++++++++++++++++++++++++
>   src/amd/vulkan/radv_extensions.py  |  1 +
>   src/intel/vulkan/anv_device.c      | 89 ++++++++++++++++++++++++++++++
>   src/intel/vulkan/anv_extensions.py |  1 +
>   src/intel/vulkan/anv_gem.c         | 13 +++++
>   src/intel/vulkan/anv_gem_stubs.c   |  7 +++
>   src/intel/vulkan/anv_private.h     |  2 +
>   7 files changed, 194 insertions(+)
> 
> diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c
> index 174922780fc..80050485e54 100644
> --- a/src/amd/vulkan/radv_device.c
> +++ b/src/amd/vulkan/radv_device.c
> @@ -4955,3 +4955,84 @@ radv_GetDeviceGroupPeerMemoryFeatures(
>   	                       VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT |
>   	                       VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT;
>   }
> +
> +static const VkTimeDomainEXT radv_time_domains[] = {
> +	VK_TIME_DOMAIN_DEVICE_EXT,
> +	VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT,
> +	VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT,
> +};
> +
> +VkResult radv_GetPhysicalDeviceCalibrateableTimeDomainsEXT(
> +	VkPhysicalDevice                             physicalDevice,
> +	uint32_t                                     *pTimeDomainCount,
> +	VkTimeDomainEXT                              *pTimeDomains)
> +{
> +	int d;
> +	VK_OUTARRAY_MAKE(out, pTimeDomains, pTimeDomainCount);
> +
> +	for (d = 0; d < ARRAY_SIZE(radv_time_domains); d++) {
> +		vk_outarray_append(&out, i) {
> +			*i = radv_time_domains[d];
> +		}
> +	}
> +
> +	return vk_outarray_status(&out);
> +}
> +
> +static uint64_t
> +radv_clock_gettime(clockid_t clock_id)
> +{
> +	struct timespec current;
> +	int ret;
> +
> +	ret = clock_gettime(clock_id, &current);
> +	if (ret < 0 && clock_id == CLOCK_MONOTONIC_RAW)
> +		ret = clock_gettime(CLOCK_MONOTONIC, &current);
> +	if (ret < 0)
> +		return 0;
> +
> +	return (uint64_t) current.tv_sec * 1000000000ULL + current.tv_nsec;
> +}
> +
> +VkResult radv_GetCalibratedTimestampsEXT(
> +	VkDevice                                     _device,
> +	uint32_t                                     timestampCount,
> +	const VkCalibratedTimestampInfoEXT           *pTimestampInfos,
> +	uint64_t                                     *pTimestamps,
> +	uint64_t                                     *pMaxDeviation)
> +{
> +	RADV_FROM_HANDLE(radv_device, device, _device);
> +	uint32_t clock_crystal_freq = device->physical_device->rad_info.clock_crystal_freq;
> +	int d;
> +	uint64_t begin, end;
> +
> +	begin = radv_clock_gettime(CLOCK_MONOTONIC_RAW);
> +
> +	for (d = 0; d < timestampCount; d++) {
> +		switch (pTimestampInfos[d].timeDomain) {
> +		case VK_TIME_DOMAIN_DEVICE_EXT:
> +			pTimestamps[d] = device->ws->query_value(device->ws,
> +								 RADEON_TIMESTAMP);
> +			break;
> +		case VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT:
> +			pTimestamps[d] = radv_clock_gettime(CLOCK_MONOTONIC);
> +			break;
> +
> +		case VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT:
> +			pTimestamps[d] = begin;
> +			break;
> +		default:
> +			pTimestamps[d] = 0;
> +			break;
> +		}
> +	}
> +
> +	end = radv_clock_gettime(CLOCK_MONOTONIC_RAW);
> +
> +	uint64_t clock_period = end - begin;
> +	uint64_t device_period = DIV_ROUND_UP(1000000, clock_crystal_freq);
> +
> +	*pMaxDeviation = MAX2(clock_period, device_period);
> +
> +	return VK_SUCCESS;
> +}
> diff --git a/src/amd/vulkan/radv_extensions.py b/src/amd/vulkan/radv_extensions.py
> index 5dcedae1c63..4c81d3f0068 100644
> --- a/src/amd/vulkan/radv_extensions.py
> +++ b/src/amd/vulkan/radv_extensions.py
> @@ -92,6 +92,7 @@ EXTENSIONS = [
>       Extension('VK_KHR_display',                          23, 'VK_USE_PLATFORM_DISPLAY_KHR'),
>       Extension('VK_EXT_direct_mode_display',               1, 'VK_USE_PLATFORM_DISPLAY_KHR'),
>       Extension('VK_EXT_acquire_xlib_display',              1, 'VK_USE_PLATFORM_XLIB_XRANDR_EXT'),
> +    Extension('VK_EXT_calibrated_timestamps',             1, True),
>       Extension('VK_EXT_conditional_rendering',             1, True),
>       Extension('VK_EXT_conservative_rasterization',        1, 'device->rad_info.chip_class >= GFX9'),
>       Extension('VK_EXT_display_surface_counter',           1, 'VK_USE_PLATFORM_DISPLAY_KHR'),
> diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c
> index a2551452eb1..249d7f36f0f 100644
> --- a/src/intel/vulkan/anv_device.c
> +++ b/src/intel/vulkan/anv_device.c
> @@ -3021,6 +3021,95 @@ void anv_DestroyFramebuffer(
>      vk_free2(&device->alloc, pAllocator, fb);
>   }
>   
> +static const VkTimeDomainEXT anv_time_domains[] = {
> +   VK_TIME_DOMAIN_DEVICE_EXT,
> +   VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT,
> +   VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT,
> +};
> +
> +VkResult anv_GetPhysicalDeviceCalibrateableTimeDomainsEXT(
> +   VkPhysicalDevice                             physicalDevice,
> +   uint32_t                                     *pTimeDomainCount,
> +   VkTimeDomainEXT                              *pTimeDomains)
> +{
> +   int d;
> +   VK_OUTARRAY_MAKE(out, pTimeDomains, pTimeDomainCount);
> +
> +   for (d = 0; d < ARRAY_SIZE(anv_time_domains); d++) {
> +      vk_outarray_append(&out, i) {
> +         *i = anv_time_domains[d];
> +      }
> +   }
> +
> +   return vk_outarray_status(&out);
> +}
> +
> +static uint64_t
> +anv_clock_gettime(clockid_t clock_id)
> +{
> +   struct timespec current;
> +   int ret;
> +
> +   ret = clock_gettime(clock_id, &current);
> +   if (ret < 0 && clock_id == CLOCK_MONOTONIC_RAW)
> +      ret = clock_gettime(CLOCK_MONOTONIC, &current);
> +   if (ret < 0)
> +      return 0;
> +
> +   return (uint64_t) current.tv_sec * 1000000000ULL + current.tv_nsec;
> +}
> +
> +#define TIMESTAMP 0x2358
> +
> +VkResult anv_GetCalibratedTimestampsEXT(
> +   VkDevice                                     _device,
> +   uint32_t                                     timestampCount,
> +   const VkCalibratedTimestampInfoEXT           *pTimestampInfos,
> +   uint64_t                                     *pTimestamps,
> +   uint64_t                                     *pMaxDeviation)
> +{
> +   ANV_FROM_HANDLE(anv_device, device, _device);
> +   uint64_t timestamp_frequency = device->info.timestamp_frequency;
> +   int  ret;
> +   int d;
> +   uint64_t begin, end;
> +
> +   begin = anv_clock_gettime(CLOCK_MONOTONIC_RAW);
> +
> +   for (d = 0; d < timestampCount; d++) {
> +      switch (pTimestampInfos[d].timeDomain) {
> +      case VK_TIME_DOMAIN_DEVICE_EXT:
> +         ret = anv_gem_reg_read(device, TIMESTAMP | 1,
> +                                &pTimestamps[d]);
> +
> +         if (ret != 0) {
> +            device->lost = TRUE;
> +            return VK_ERROR_DEVICE_LOST;
> +         }
> +         break;
> +      case VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT:
> +         pTimestamps[d] = anv_clock_gettime(CLOCK_MONOTONIC);
> +         break;
> +
> +      case VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT:
> +         pTimestamps[d] = begin;
> +         break;
> +      default:
> +         pTimestamps[d] = 0;
> +         break;
> +      }
> +   }
> +
> +   end = anv_clock_gettime(CLOCK_MONOTONIC_RAW);
> +
> +   uint64_t clock_period = end - begin;
> +   uint64_t device_period = DIV_ROUND_UP(1000000000, timestamp_frequency);
> +
> +   *pMaxDeviation = MAX2(clock_period, device_period);
> +
> +   return VK_SUCCESS;
> +}
> +
>   /* vk_icd.h does not declare this function, so we declare it here to
>    * suppress Wmissing-prototypes.
>    */
> diff --git a/src/intel/vulkan/anv_extensions.py b/src/intel/vulkan/anv_extensions.py
> index d4915c95013..a8535964da7 100644
> --- a/src/intel/vulkan/anv_extensions.py
> +++ b/src/intel/vulkan/anv_extensions.py
> @@ -126,6 +126,7 @@ EXTENSIONS = [
>       Extension('VK_EXT_vertex_attribute_divisor',          3, True),
>       Extension('VK_EXT_post_depth_coverage',               1, 'device->info.gen >= 9'),
>       Extension('VK_EXT_sampler_filter_minmax',             1, 'device->info.gen >= 9'),
> +    Extension('VK_EXT_calibrated_timestamps',             1, True),
>   ]
>   
>   class VkVersion:
> diff --git a/src/intel/vulkan/anv_gem.c b/src/intel/vulkan/anv_gem.c
> index c43b5ef9e06..1bdf040c1a3 100644
> --- a/src/intel/vulkan/anv_gem.c
> +++ b/src/intel/vulkan/anv_gem.c
> @@ -423,6 +423,19 @@ anv_gem_fd_to_handle(struct anv_device *device, int fd)
>      return args.handle;
>   }
>   
> +int
> +anv_gem_reg_read(struct anv_device *device, uint32_t offset, uint64_t *result)
> +{
> +   struct drm_i915_reg_read args = {
> +      .offset = offset
> +   };
> +
> +   int ret = anv_ioctl(device->fd, DRM_IOCTL_I915_REG_READ, &args);
> +
> +   *result = args.val;
> +   return ret;
> +}
> +
>   #ifndef SYNC_IOC_MAGIC
>   /* duplicated from linux/sync_file.h to avoid build-time dependency
>    * on new (v4.7) kernel headers.  Once distro's are mostly using
> diff --git a/src/intel/vulkan/anv_gem_stubs.c b/src/intel/vulkan/anv_gem_stubs.c
> index 5093bd5db1a..8cc3ad1f22e 100644
> --- a/src/intel/vulkan/anv_gem_stubs.c
> +++ b/src/intel/vulkan/anv_gem_stubs.c
> @@ -251,3 +251,10 @@ anv_gem_syncobj_wait(struct anv_device *device,
>   {
>      unreachable("Unused");
>   }
> +
> +int
> +anv_gem_reg_read(struct anv_device *device,
> +                 uint32_t offset, uint64_t *result)
> +{
> +   unreachable("Unused");
> +}
> diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
> index 599b903f25c..08376b00c8e 100644
> --- a/src/intel/vulkan/anv_private.h
> +++ b/src/intel/vulkan/anv_private.h
> @@ -1103,6 +1103,8 @@ int anv_gem_get_aperture(int fd, uint64_t *size);
>   int anv_gem_gpu_get_reset_stats(struct anv_device *device,
>                                   uint32_t *active, uint32_t *pending);
>   int anv_gem_handle_to_fd(struct anv_device *device, uint32_t gem_handle);
> +int anv_gem_reg_read(struct anv_device *device,
> +                     uint32_t offset, uint64_t *result);
>   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_domain(struct anv_device *device, uint32_t gem_handle,
> 
_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] vulkan: Add VK_EXT_calibrated_timestamps extension (radv and anv) [v4]
  2018-10-16  5:31   ` [PATCH] vulkan: Add VK_EXT_calibrated_timestamps extension (radv and anv) [v4] Keith Packard
  2018-10-16  7:32     ` Samuel Pitoiset
@ 2018-10-16  7:33     ` Bas Nieuwenhuizen
  2018-10-16 19:34       ` Keith Packard
  2018-10-17 16:49     ` [PATCH] vulkan: Add VK_EXT_calibrated_timestamps extension (radv and anv) [v5] Keith Packard
  2 siblings, 1 reply; 28+ messages in thread
From: Bas Nieuwenhuizen @ 2018-10-16  7:33 UTC (permalink / raw)
  To: Keith Packard; +Cc: mesa-dev, ML dri-devel

On Tue, Oct 16, 2018 at 7:31 AM Keith Packard <keithp@keithp.com> wrote:
>
> Offers three clocks, device, clock monotonic and clock monotonic
> raw. Could use some kernel support to reduce the deviation between
> clock values.
>
> v2:
>         Ensure deviation is at least as big as the GPU time interval.
>
> v3:
>         Set device->lost when returning DEVICE_LOST.
>         Use MAX2 and DIV_ROUND_UP instead of open coding these.
>         Delete spurious TIMESTAMP in radv version.
>         Suggested-by: Jason Ekstrand <jason@jlekstrand.net>
>         Suggested-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
>
> v4:
>         Add anv_gem_reg_read to anv_gem_stubs.c
>         Suggested-by: Jason Ekstrand <jason@jlekstrand.net>
>
> Signed-off-by: Keith Packard <keithp@keithp.com>
> ---
>  src/amd/vulkan/radv_device.c       | 81 +++++++++++++++++++++++++++
>  src/amd/vulkan/radv_extensions.py  |  1 +
>  src/intel/vulkan/anv_device.c      | 89 ++++++++++++++++++++++++++++++
>  src/intel/vulkan/anv_extensions.py |  1 +
>  src/intel/vulkan/anv_gem.c         | 13 +++++
>  src/intel/vulkan/anv_gem_stubs.c   |  7 +++
>  src/intel/vulkan/anv_private.h     |  2 +
>  7 files changed, 194 insertions(+)
>
> diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c
> index 174922780fc..80050485e54 100644
> --- a/src/amd/vulkan/radv_device.c
> +++ b/src/amd/vulkan/radv_device.c
> @@ -4955,3 +4955,84 @@ radv_GetDeviceGroupPeerMemoryFeatures(
>                                VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT |
>                                VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT;
>  }
> +
> +static const VkTimeDomainEXT radv_time_domains[] = {
> +       VK_TIME_DOMAIN_DEVICE_EXT,
> +       VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT,
> +       VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT,
> +};
> +
> +VkResult radv_GetPhysicalDeviceCalibrateableTimeDomainsEXT(
> +       VkPhysicalDevice                             physicalDevice,
> +       uint32_t                                     *pTimeDomainCount,
> +       VkTimeDomainEXT                              *pTimeDomains)
> +{
> +       int d;
> +       VK_OUTARRAY_MAKE(out, pTimeDomains, pTimeDomainCount);
> +
> +       for (d = 0; d < ARRAY_SIZE(radv_time_domains); d++) {
> +               vk_outarray_append(&out, i) {
> +                       *i = radv_time_domains[d];
> +               }
> +       }
> +
> +       return vk_outarray_status(&out);
> +}
> +
> +static uint64_t
> +radv_clock_gettime(clockid_t clock_id)
> +{
> +       struct timespec current;
> +       int ret;
> +
> +       ret = clock_gettime(clock_id, &current);
> +       if (ret < 0 && clock_id == CLOCK_MONOTONIC_RAW)
> +               ret = clock_gettime(CLOCK_MONOTONIC, &current);
> +       if (ret < 0)
> +               return 0;
> +
> +       return (uint64_t) current.tv_sec * 1000000000ULL + current.tv_nsec;
> +}
> +
> +VkResult radv_GetCalibratedTimestampsEXT(
> +       VkDevice                                     _device,
> +       uint32_t                                     timestampCount,
> +       const VkCalibratedTimestampInfoEXT           *pTimestampInfos,
> +       uint64_t                                     *pTimestamps,
> +       uint64_t                                     *pMaxDeviation)
> +{
> +       RADV_FROM_HANDLE(radv_device, device, _device);
> +       uint32_t clock_crystal_freq = device->physical_device->rad_info.clock_crystal_freq;
> +       int d;
> +       uint64_t begin, end;
> +
> +       begin = radv_clock_gettime(CLOCK_MONOTONIC_RAW);
> +
> +       for (d = 0; d < timestampCount; d++) {
> +               switch (pTimestampInfos[d].timeDomain) {
> +               case VK_TIME_DOMAIN_DEVICE_EXT:
> +                       pTimestamps[d] = device->ws->query_value(device->ws,
> +                                                                RADEON_TIMESTAMP);
> +                       break;
> +               case VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT:
> +                       pTimestamps[d] = radv_clock_gettime(CLOCK_MONOTONIC);
> +                       break;
> +
> +               case VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT:
> +                       pTimestamps[d] = begin;
> +                       break;
> +               default:
> +                       pTimestamps[d] = 0;
> +                       break;
> +               }
> +       }
> +
> +       end = radv_clock_gettime(CLOCK_MONOTONIC_RAW);
> +
> +       uint64_t clock_period = end - begin;
> +       uint64_t device_period = DIV_ROUND_UP(1000000, clock_crystal_freq);
> +
> +       *pMaxDeviation = MAX2(clock_period, device_period);

Should this not be a sum? Those deviations can happen independently
from each other, so worst case both deviations happen in the same
direction which causes the magnitude to be combined.

With that change:

Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>

> +
> +       return VK_SUCCESS;
> +}
> diff --git a/src/amd/vulkan/radv_extensions.py b/src/amd/vulkan/radv_extensions.py
> index 5dcedae1c63..4c81d3f0068 100644
> --- a/src/amd/vulkan/radv_extensions.py
> +++ b/src/amd/vulkan/radv_extensions.py
> @@ -92,6 +92,7 @@ EXTENSIONS = [
>      Extension('VK_KHR_display',                          23, 'VK_USE_PLATFORM_DISPLAY_KHR'),
>      Extension('VK_EXT_direct_mode_display',               1, 'VK_USE_PLATFORM_DISPLAY_KHR'),
>      Extension('VK_EXT_acquire_xlib_display',              1, 'VK_USE_PLATFORM_XLIB_XRANDR_EXT'),
> +    Extension('VK_EXT_calibrated_timestamps',             1, True),
>      Extension('VK_EXT_conditional_rendering',             1, True),
>      Extension('VK_EXT_conservative_rasterization',        1, 'device->rad_info.chip_class >= GFX9'),
>      Extension('VK_EXT_display_surface_counter',           1, 'VK_USE_PLATFORM_DISPLAY_KHR'),
> diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c
> index a2551452eb1..249d7f36f0f 100644
> --- a/src/intel/vulkan/anv_device.c
> +++ b/src/intel/vulkan/anv_device.c
> @@ -3021,6 +3021,95 @@ void anv_DestroyFramebuffer(
>     vk_free2(&device->alloc, pAllocator, fb);
>  }
>
> +static const VkTimeDomainEXT anv_time_domains[] = {
> +   VK_TIME_DOMAIN_DEVICE_EXT,
> +   VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT,
> +   VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT,
> +};
> +
> +VkResult anv_GetPhysicalDeviceCalibrateableTimeDomainsEXT(
> +   VkPhysicalDevice                             physicalDevice,
> +   uint32_t                                     *pTimeDomainCount,
> +   VkTimeDomainEXT                              *pTimeDomains)
> +{
> +   int d;
> +   VK_OUTARRAY_MAKE(out, pTimeDomains, pTimeDomainCount);
> +
> +   for (d = 0; d < ARRAY_SIZE(anv_time_domains); d++) {
> +      vk_outarray_append(&out, i) {
> +         *i = anv_time_domains[d];
> +      }
> +   }
> +
> +   return vk_outarray_status(&out);
> +}
> +
> +static uint64_t
> +anv_clock_gettime(clockid_t clock_id)
> +{
> +   struct timespec current;
> +   int ret;
> +
> +   ret = clock_gettime(clock_id, &current);
> +   if (ret < 0 && clock_id == CLOCK_MONOTONIC_RAW)
> +      ret = clock_gettime(CLOCK_MONOTONIC, &current);
> +   if (ret < 0)
> +      return 0;
> +
> +   return (uint64_t) current.tv_sec * 1000000000ULL + current.tv_nsec;
> +}
> +
> +#define TIMESTAMP 0x2358
> +
> +VkResult anv_GetCalibratedTimestampsEXT(
> +   VkDevice                                     _device,
> +   uint32_t                                     timestampCount,
> +   const VkCalibratedTimestampInfoEXT           *pTimestampInfos,
> +   uint64_t                                     *pTimestamps,
> +   uint64_t                                     *pMaxDeviation)
> +{
> +   ANV_FROM_HANDLE(anv_device, device, _device);
> +   uint64_t timestamp_frequency = device->info.timestamp_frequency;
> +   int  ret;
> +   int d;
> +   uint64_t begin, end;
> +
> +   begin = anv_clock_gettime(CLOCK_MONOTONIC_RAW);
> +
> +   for (d = 0; d < timestampCount; d++) {
> +      switch (pTimestampInfos[d].timeDomain) {
> +      case VK_TIME_DOMAIN_DEVICE_EXT:
> +         ret = anv_gem_reg_read(device, TIMESTAMP | 1,
> +                                &pTimestamps[d]);
> +
> +         if (ret != 0) {
> +            device->lost = TRUE;
> +            return VK_ERROR_DEVICE_LOST;
> +         }
> +         break;
> +      case VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT:
> +         pTimestamps[d] = anv_clock_gettime(CLOCK_MONOTONIC);
> +         break;
> +
> +      case VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT:
> +         pTimestamps[d] = begin;
> +         break;
> +      default:
> +         pTimestamps[d] = 0;
> +         break;
> +      }
> +   }
> +
> +   end = anv_clock_gettime(CLOCK_MONOTONIC_RAW);
> +
> +   uint64_t clock_period = end - begin;
> +   uint64_t device_period = DIV_ROUND_UP(1000000000, timestamp_frequency);
> +
> +   *pMaxDeviation = MAX2(clock_period, device_period);
> +
> +   return VK_SUCCESS;
> +}
> +
>  /* vk_icd.h does not declare this function, so we declare it here to
>   * suppress Wmissing-prototypes.
>   */
> diff --git a/src/intel/vulkan/anv_extensions.py b/src/intel/vulkan/anv_extensions.py
> index d4915c95013..a8535964da7 100644
> --- a/src/intel/vulkan/anv_extensions.py
> +++ b/src/intel/vulkan/anv_extensions.py
> @@ -126,6 +126,7 @@ EXTENSIONS = [
>      Extension('VK_EXT_vertex_attribute_divisor',          3, True),
>      Extension('VK_EXT_post_depth_coverage',               1, 'device->info.gen >= 9'),
>      Extension('VK_EXT_sampler_filter_minmax',             1, 'device->info.gen >= 9'),
> +    Extension('VK_EXT_calibrated_timestamps',             1, True),
>  ]
>
>  class VkVersion:
> diff --git a/src/intel/vulkan/anv_gem.c b/src/intel/vulkan/anv_gem.c
> index c43b5ef9e06..1bdf040c1a3 100644
> --- a/src/intel/vulkan/anv_gem.c
> +++ b/src/intel/vulkan/anv_gem.c
> @@ -423,6 +423,19 @@ anv_gem_fd_to_handle(struct anv_device *device, int fd)
>     return args.handle;
>  }
>
> +int
> +anv_gem_reg_read(struct anv_device *device, uint32_t offset, uint64_t *result)
> +{
> +   struct drm_i915_reg_read args = {
> +      .offset = offset
> +   };
> +
> +   int ret = anv_ioctl(device->fd, DRM_IOCTL_I915_REG_READ, &args);
> +
> +   *result = args.val;
> +   return ret;
> +}
> +
>  #ifndef SYNC_IOC_MAGIC
>  /* duplicated from linux/sync_file.h to avoid build-time dependency
>   * on new (v4.7) kernel headers.  Once distro's are mostly using
> diff --git a/src/intel/vulkan/anv_gem_stubs.c b/src/intel/vulkan/anv_gem_stubs.c
> index 5093bd5db1a..8cc3ad1f22e 100644
> --- a/src/intel/vulkan/anv_gem_stubs.c
> +++ b/src/intel/vulkan/anv_gem_stubs.c
> @@ -251,3 +251,10 @@ anv_gem_syncobj_wait(struct anv_device *device,
>  {
>     unreachable("Unused");
>  }
> +
> +int
> +anv_gem_reg_read(struct anv_device *device,
> +                 uint32_t offset, uint64_t *result)
> +{
> +   unreachable("Unused");
> +}
> diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
> index 599b903f25c..08376b00c8e 100644
> --- a/src/intel/vulkan/anv_private.h
> +++ b/src/intel/vulkan/anv_private.h
> @@ -1103,6 +1103,8 @@ int anv_gem_get_aperture(int fd, uint64_t *size);
>  int anv_gem_gpu_get_reset_stats(struct anv_device *device,
>                                  uint32_t *active, uint32_t *pending);
>  int anv_gem_handle_to_fd(struct anv_device *device, uint32_t gem_handle);
> +int anv_gem_reg_read(struct anv_device *device,
> +                     uint32_t offset, uint64_t *result);
>  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_domain(struct anv_device *device, uint32_t gem_handle,
> --
> 2.19.1
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] vulkan: Add VK_EXT_calibrated_timestamps extension (radv and anv) [v4]
  2018-10-16  7:33     ` Bas Nieuwenhuizen
@ 2018-10-16 19:34       ` Keith Packard
  2018-10-16 19:44         ` Jason Ekstrand
  0 siblings, 1 reply; 28+ messages in thread
From: Keith Packard @ 2018-10-16 19:34 UTC (permalink / raw)
  To: Bas Nieuwenhuizen; +Cc: mesa-dev, ML dri-devel


[-- Attachment #1.1: Type: text/plain, Size: 1887 bytes --]

Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl> writes:

>> +       end = radv_clock_gettime(CLOCK_MONOTONIC_RAW);
>> +
>> +       uint64_t clock_period = end - begin;
>> +       uint64_t device_period = DIV_ROUND_UP(1000000, clock_crystal_freq);
>> +
>> +       *pMaxDeviation = MAX2(clock_period, device_period);
>
> Should this not be a sum? Those deviations can happen independently
> from each other, so worst case both deviations happen in the same
> direction which causes the magnitude to be combined.

This use of MAX2 comes right from one of the issues raised during work
on the extension:

 8) Can the maximum deviation reported ever be zero?

 RESOLVED: Unless the tick of each clock corresponding to the set of
 time domains coincides and all clocks can literally be sampled
 simutaneously, there isn’t really a possibility for the maximum
 deviation to be zero, so by convention the maximum deviation is always
 at least the maximum of the length of the ticks of the set of time
 domains calibrated and thus can never be zero.

I can't wrap my brain around this entirely, but I think that this says
that the deviation reported is supposed to only reflect the fact that we
aren't sampling the clocks at the same time, and so there may be a
'tick' of error for any sampled clock.

If you look at the previous issue in the spec, that actually has the
pseudo code I used in this implementation for computing maxDeviation
which doesn't include anything about the time period of the GPU.

Jason suggested using the GPU period as the minimum value for
maxDeviation at the GPU time period to make sure we never accidentally
returned zero, as that is forbidden by the spec. We might be able to use
1 instead, but it won't matter in practice as the time it takes to
actually sample all of the clocks is far longer than a GPU tick.

-- 
-keith

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] vulkan: Add VK_EXT_calibrated_timestamps extension (radv and anv) [v4]
  2018-10-16 19:34       ` Keith Packard
@ 2018-10-16 19:44         ` Jason Ekstrand
  2018-10-16 21:07           ` Keith Packard
  0 siblings, 1 reply; 28+ messages in thread
From: Jason Ekstrand @ 2018-10-16 19:44 UTC (permalink / raw)
  To: Keith Packard; +Cc: ML mesa-dev, Maling list - DRI developers


[-- Attachment #1.1: Type: text/plain, Size: 2629 bytes --]

On Tue, Oct 16, 2018 at 2:35 PM Keith Packard <keithp@keithp.com> wrote:

> Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl> writes:
>
> >> +       end = radv_clock_gettime(CLOCK_MONOTONIC_RAW);
> >> +
> >> +       uint64_t clock_period = end - begin;
> >> +       uint64_t device_period = DIV_ROUND_UP(1000000,
> clock_crystal_freq);
> >> +
> >> +       *pMaxDeviation = MAX2(clock_period, device_period);
> >
> > Should this not be a sum? Those deviations can happen independently
> > from each other, so worst case both deviations happen in the same
> > direction which causes the magnitude to be combined.
>
> This use of MAX2 comes right from one of the issues raised during work
> on the extension:
>
>  8) Can the maximum deviation reported ever be zero?
>
>  RESOLVED: Unless the tick of each clock corresponding to the set of
>  time domains coincides and all clocks can literally be sampled
>  simutaneously, there isn’t really a possibility for the maximum
>  deviation to be zero, so by convention the maximum deviation is always
>  at least the maximum of the length of the ticks of the set of time
>  domains calibrated and thus can never be zero.
>
> I can't wrap my brain around this entirely, but I think that this says
> that the deviation reported is supposed to only reflect the fact that we
> aren't sampling the clocks at the same time, and so there may be a
> 'tick' of error for any sampled clock.
>
> If you look at the previous issue in the spec, that actually has the
> pseudo code I used in this implementation for computing maxDeviation
> which doesn't include anything about the time period of the GPU.
>
> Jason suggested using the GPU period as the minimum value for
> maxDeviation at the GPU time period to make sure we never accidentally
> returned zero, as that is forbidden by the spec. We might be able to use
> 1 instead, but it won't matter in practice as the time it takes to
> actually sample all of the clocks is far longer than a GPU tick.
>

I think what Bas is getting at is that there are two problems:

 1) We are not sampling at exactly the same time
 2) The two clocks may not tick at exactly the same time.

Even if I can simultaneously sample the CPU and GPU clocks, their
oscilators are not aligned and I my sample may be at the begining of the
CPU tick and the end of the GPU tick.  If I had sampled 75ns earlier, I
could have gotten lower CPU time but the same GPU time (most intel GPUs
have about an 80ns tick).

If we want to be conservative, I suspect Bas may be right that adding is
the safer thing to do.

--Jason

[-- Attachment #1.2: Type: text/html, Size: 3224 bytes --]

[-- Attachment #2: Type: text/plain, Size: 157 bytes --]

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] vulkan: Add VK_EXT_calibrated_timestamps extension (radv and anv) [v4]
  2018-10-16 19:44         ` Jason Ekstrand
@ 2018-10-16 21:07           ` Keith Packard
  2018-10-16 21:33             ` Jason Ekstrand
  2018-10-16 21:38             ` Bas Nieuwenhuizen
  0 siblings, 2 replies; 28+ messages in thread
From: Keith Packard @ 2018-10-16 21:07 UTC (permalink / raw)
  To: Jason Ekstrand; +Cc: ML mesa-dev, Maling list - DRI developers


[-- Attachment #1.1: Type: text/plain, Size: 3783 bytes --]

Jason Ekstrand <jason@jlekstrand.net> writes:

> I think what Bas is getting at is that there are two problems:
>
>  1) We are not sampling at exactly the same time
>  2) The two clocks may not tick at exactly the same time.

Thanks for the clarification.

> If we want to be conservative, I suspect Bas may be right that adding is
> the safer thing to do.

Yes, it's certainly safe to increase the value of
maxDeviation. Currently, the time it takes to sample all of the clocks
is far larger than the GPU tick, so adding that in would not have a huge
impact on the value returned to the application.

I'd like to dig in a little further and actually understand if the
current computation (which is derived directly from the Vulkan spec) is
wrong, and if so, whether the spec needs to be adjusted.

I think the question is what 'maxDeviation' is supposed to
represent. All the spec says is:

 * pMaxDeviation is a pointer to a 64-bit unsigned integer value in
   which the strictly positive maximum deviation, in nanoseconds, of the
   calibrated timestamp values is returned.

I interpret this as the maximum error in sampling the individual clocks,
which is to say that the clock values are guaranteed to have been
sampled within this interval of each other.

So, if we have a monotonic clock and GPU clock:

          0 1 2 3 4 5 6 7 8 9 a b c d e f
Monotonic -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-

          0         1         2         3
GPU       -----_____-----_____-----_____-----_____


gpu_period in this case is 5 ticks of the monotonic clock.

Now, I perform three operations:

        start = read(monotonic)
        gpu   = read(GPU)
        end   = read(monotonic)

Let's say that:

        start = 2
        GPU = 1 * 5 = 5 monotonic equivalent ticks
        end = b

So, the question is only how large the error between GPU and start could
possibly be. Certainly the GPU clock was sampled some time between
when monotonic tick 2 started and monotonic tick b ended. But, we have
no idea what phase the GPU clock was in when sampled.

Let's imagine we manage to sample the GPU clock immediately after the
first monotonic sample. I'll shift the offset of the monotonic and GPU
clocks to retain the same values (start = 2, GPU = 1), but now
the GPU clock is being sampled immediately after monotonic time 2:

                w x y z 0 1 2 3 4 5 6 7 8 9 a b c d e f
Monotonic       -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-

          0         1         2         3
GPU       -----_____-----_____-----_____-----_____


In this case, the GPU tick started at monotonic time y, nearly 5
monotonic ticks earlier than the measured monotonic time, so the
deviation between GPU and monotonic would be 5 ticks.

If we sample the GPU clock immediately before the second monotonic
sample, then that GPU tick either starts earlier than the range, in
which case the above evaluation holds, or the GPU tick is entirely
contained within the range:

          0 1 2 3 4 5 6 7 8 9 a b c d e f
Monotonic -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-

           z         0         1         2         3
GPU      __-----_____-----_____-----_____-----_____-----

In this case, the deviation between the first monotonic sample (that
returned to the application as the monotonic time) and the GPU sample is
the whole interval of measurement (b - 2).

I think I've just managed to convince myself that Jason's first
suggestion (max2(sample interval, gpu interval)) is correct, although I
think we should add '1' to the interval to account for sampling phase
errors in the monotonic clock. As that's measured in ns, and I'm
currently getting values in the µs range, that's a small error in
comparison.

-- 
-keith

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] vulkan: Add VK_EXT_calibrated_timestamps extension (radv and anv) [v4]
  2018-10-16 21:07           ` Keith Packard
@ 2018-10-16 21:33             ` Jason Ekstrand
  2018-10-16 21:51               ` Keith Packard
  2018-10-16 21:38             ` Bas Nieuwenhuizen
  1 sibling, 1 reply; 28+ messages in thread
From: Jason Ekstrand @ 2018-10-16 21:33 UTC (permalink / raw)
  To: Keith Packard; +Cc: ML mesa-dev, Maling list - DRI developers


[-- Attachment #1.1: Type: text/plain, Size: 4288 bytes --]

On Tue, Oct 16, 2018 at 4:07 PM Keith Packard <keithp@keithp.com> wrote:

> Jason Ekstrand <jason@jlekstrand.net> writes:
>
> > I think what Bas is getting at is that there are two problems:
> >
> >  1) We are not sampling at exactly the same time
> >  2) The two clocks may not tick at exactly the same time.
>
> Thanks for the clarification.
>
> > If we want to be conservative, I suspect Bas may be right that adding is
> > the safer thing to do.
>
> Yes, it's certainly safe to increase the value of
> maxDeviation. Currently, the time it takes to sample all of the clocks
> is far larger than the GPU tick, so adding that in would not have a huge
> impact on the value returned to the application.
>
> I'd like to dig in a little further and actually understand if the
> current computation (which is derived directly from the Vulkan spec) is
> wrong, and if so, whether the spec needs to be adjusted.
>
> I think the question is what 'maxDeviation' is supposed to
> represent. All the spec says is:
>
>  * pMaxDeviation is a pointer to a 64-bit unsigned integer value in
>    which the strictly positive maximum deviation, in nanoseconds, of the
>    calibrated timestamp values is returned.
>
> I interpret this as the maximum error in sampling the individual clocks,
> which is to say that the clock values are guaranteed to have been
> sampled within this interval of each other.
>
> So, if we have a monotonic clock and GPU clock:
>
>           0 1 2 3 4 5 6 7 8 9 a b c d e f
> Monotonic -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
>
>           0         1         2         3
> GPU       -----_____-----_____-----_____-----_____
>
>
> gpu_period in this case is 5 ticks of the monotonic clock.
>
> Now, I perform three operations:
>
>         start = read(monotonic)
>         gpu   = read(GPU)
>         end   = read(monotonic)
>
> Let's say that:
>
>         start = 2
>         GPU = 1 * 5 = 5 monotonic equivalent ticks
>         end = b
>
> So, the question is only how large the error between GPU and start could
> possibly be. Certainly the GPU clock was sampled some time between
> when monotonic tick 2 started and monotonic tick b ended. But, we have
> no idea what phase the GPU clock was in when sampled.
>
> Let's imagine we manage to sample the GPU clock immediately after the
> first monotonic sample. I'll shift the offset of the monotonic and GPU
> clocks to retain the same values (start = 2, GPU = 1), but now
> the GPU clock is being sampled immediately after monotonic time 2:
>
>                 w x y z 0 1 2 3 4 5 6 7 8 9 a b c d e f
> Monotonic       -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
>
>           0         1         2         3
> GPU       -----_____-----_____-----_____-----_____
>
>
> In this case, the GPU tick started at monotonic time y, nearly 5
> monotonic ticks earlier than the measured monotonic time, so the
> deviation between GPU and monotonic would be 5 ticks.
>
> If we sample the GPU clock immediately before the second monotonic
> sample, then that GPU tick either starts earlier than the range, in
> which case the above evaluation holds, or the GPU tick is entirely
> contained within the range:
>
>           0 1 2 3 4 5 6 7 8 9 a b c d e f
> Monotonic -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
>
>            z         0         1         2         3
> GPU      __-----_____-----_____-----_____-----_____-----
>
> In this case, the deviation between the first monotonic sample (that
> returned to the application as the monotonic time) and the GPU sample is
> the whole interval of measurement (b - 2).
>
> I think I've just managed to convince myself that Jason's first
> suggestion (max2(sample interval, gpu interval)) is correct, although I
> think we should add '1' to the interval to account for sampling phase
> errors in the monotonic clock. As that's measured in ns, and I'm
> currently getting values in the µs range, that's a small error in
> comparison.
>

You've got me almost convinced as well.  Thanks for the diagrams!  I think
instead of adding 1 perhaps what we want is

max2(sample_interval_ns, gpu_tick_ns + monotonic_tick_ns)

Where monotonic_tick_ns is maybe as low as 1.  Am I following you correctly?

--Jason

[-- Attachment #1.2: Type: text/html, Size: 5114 bytes --]

[-- Attachment #2: Type: text/plain, Size: 157 bytes --]

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] vulkan: Add VK_EXT_calibrated_timestamps extension (radv and anv) [v4]
  2018-10-16 21:07           ` Keith Packard
  2018-10-16 21:33             ` Jason Ekstrand
@ 2018-10-16 21:38             ` Bas Nieuwenhuizen
  2018-10-16 22:06               ` Keith Packard
  1 sibling, 1 reply; 28+ messages in thread
From: Bas Nieuwenhuizen @ 2018-10-16 21:38 UTC (permalink / raw)
  To: Keith Packard; +Cc: mesa-dev, ML dri-devel

On Tue, Oct 16, 2018 at 11:07 PM Keith Packard <keithp@keithp.com> wrote:
>
> Jason Ekstrand <jason@jlekstrand.net> writes:
>
> > I think what Bas is getting at is that there are two problems:
> >
> >  1) We are not sampling at exactly the same time
> >  2) The two clocks may not tick at exactly the same time.
>
> Thanks for the clarification.
>
> > If we want to be conservative, I suspect Bas may be right that adding is
> > the safer thing to do.
>
> Yes, it's certainly safe to increase the value of
> maxDeviation. Currently, the time it takes to sample all of the clocks
> is far larger than the GPU tick, so adding that in would not have a huge
> impact on the value returned to the application.
>
> I'd like to dig in a little further and actually understand if the
> current computation (which is derived directly from the Vulkan spec) is
> wrong, and if so, whether the spec needs to be adjusted.
>
> I think the question is what 'maxDeviation' is supposed to
> represent. All the spec says is:
>
>  * pMaxDeviation is a pointer to a 64-bit unsigned integer value in
>    which the strictly positive maximum deviation, in nanoseconds, of the
>    calibrated timestamp values is returned.
>
> I interpret this as the maximum error in sampling the individual clocks,
> which is to say that the clock values are guaranteed to have been
> sampled within this interval of each other.

With this interpretation I don't think you need to account for period at all?

>
> So, if we have a monotonic clock and GPU clock:
>
>           0 1 2 3 4 5 6 7 8 9 a b c d e f
> Monotonic -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
>
>           0         1         2         3
> GPU       -----_____-----_____-----_____-----_____
>
>
> gpu_period in this case is 5 ticks of the monotonic clock.
>
> Now, I perform three operations:
>
>         start = read(monotonic)
>         gpu   = read(GPU)
>         end   = read(monotonic)
>
> Let's say that:
>
>         start = 2
>         GPU = 1 * 5 = 5 monotonic equivalent ticks
>         end = b
>
> So, the question is only how large the error between GPU and start could
> possibly be. Certainly the GPU clock was sampled some time between
> when monotonic tick 2 started and monotonic tick b ended. But, we have
> no idea what phase the GPU clock was in when sampled.
>
> Let's imagine we manage to sample the GPU clock immediately after the
> first monotonic sample. I'll shift the offset of the monotonic and GPU
> clocks to retain the same values (start = 2, GPU = 1), but now
> the GPU clock is being sampled immediately after monotonic time 2:
>
>                 w x y z 0 1 2 3 4 5 6 7 8 9 a b c d e f
> Monotonic       -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
>
>           0         1         2         3
> GPU       -----_____-----_____-----_____-----_____
>
>
> In this case, the GPU tick started at monotonic time y, nearly 5
> monotonic ticks earlier than the measured monotonic time, so the
> deviation between GPU and monotonic would be 5 ticks.

Well the complication here is that in the MONOTONIC (not
MONOTONIC_RAW) case the CPU measurement can happen at the end of the
MONOTONIC_RAW interval (as the order of measurements is based on
argument order), so you can get a tick that started `period` (5 in
this case) monotonic ticks before the start of the interval and a CPU
measurement at the end of the interval.

>
> If we sample the GPU clock immediately before the second monotonic
> sample, then that GPU tick either starts earlier than the range, in
> which case the above evaluation holds, or the GPU tick is entirely
> contained within the range:
>
>           0 1 2 3 4 5 6 7 8 9 a b c d e f
> Monotonic -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
>
>            z         0         1         2         3
> GPU      __-----_____-----_____-----_____-----_____-----
>
> In this case, the deviation between the first monotonic sample (that
> returned to the application as the monotonic time) and the GPU sample is
> the whole interval of measurement (b - 2).
>
> I think I've just managed to convince myself that Jason's first
> suggestion (max2(sample interval, gpu interval)) is correct, although I
> think we should add '1' to the interval to account for sampling phase
> errors in the monotonic clock. As that's measured in ns, and I'm
> currently getting values in the µs range, that's a small error in
> comparison.
>
> --
> -keith
_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] vulkan: Add VK_EXT_calibrated_timestamps extension (radv and anv) [v4]
  2018-10-16 21:33             ` Jason Ekstrand
@ 2018-10-16 21:51               ` Keith Packard
  0 siblings, 0 replies; 28+ messages in thread
From: Keith Packard @ 2018-10-16 21:51 UTC (permalink / raw)
  To: Jason Ekstrand; +Cc: ML mesa-dev, Maling list - DRI developers


[-- Attachment #1.1: Type: text/plain, Size: 685 bytes --]

Jason Ekstrand <jason@jlekstrand.net> writes:


> You've got me almost convinced as well.  Thanks for the diagrams!  I think
> instead of adding 1 perhaps what we want is
>
> max2(sample_interval_ns, gpu_tick_ns + monotonic_tick_ns)
>
> Where monotonic_tick_ns is maybe as low as 1.  Am I following you correctly?

Not quite; I was thinking that because the sample_interval_ns is
measured by sampling the monotonic clock twice, the actual interval can
be up to 1 tick longer, so

max2(sample_interval_ns + monotonic_tick_ns, gpu_tick_ns)

The gpu_tick_ns is computed, not measured, and so accurately reflects
the maximum deviation in the measurements.

-- 
-keith

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] vulkan: Add VK_EXT_calibrated_timestamps extension (radv and anv) [v4]
  2018-10-16 21:38             ` Bas Nieuwenhuizen
@ 2018-10-16 22:06               ` Keith Packard
  2018-10-16 22:28                 ` Bas Nieuwenhuizen
  2018-10-17  1:55                 ` Jason Ekstrand
  0 siblings, 2 replies; 28+ messages in thread
From: Keith Packard @ 2018-10-16 22:06 UTC (permalink / raw)
  To: Bas Nieuwenhuizen; +Cc: mesa-dev, ML dri-devel, Jason Ekstrand


[-- Attachment #1.1: Type: text/plain, Size: 1793 bytes --]

Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl> writes:

> Well the complication here is that in the MONOTONIC (not
> MONOTONIC_RAW) case the CPU measurement can happen at the end of the
> MONOTONIC_RAW interval (as the order of measurements is based on
> argument order), so you can get a tick that started `period` (5 in
> this case) monotonic ticks before the start of the interval and a CPU
> measurement at the end of the interval.

Ah, that's an excellent point. Let's split out raw and monotonic and
take a look. You want the GPU sampled at the start of the raw interval
and monotonic sampled at the end, I think?

                 w x y z 0 1 2 3 4 5 6 7 8 9 a b c d e f
Raw              -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-

          0         1         2         3
GPU       -----_____-----_____-----_____-----_____

                                    x y z 0 1 2 3 4 5 6 7 8 9 a b c
Monotonic                           -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-

Interval                     <----------------->
Deviation           <-------------------------->

        start = read(raw)       2
        gpu   = read(GPU)       1
        mono  = read(monotonic) 2
        end   = read(raw)       b

In this case, the error between the monotonic pulse and the GPU is
interval + gpu_period (probably plus one to include the measurement
error of the raw clock).

Thanks for finding this case.

Now, I guess the question is whether we want to try and find the
smallest maxDeviation possible for each query. For instance, if the
application asks only for raw and gpu, the max_deviation could be
max2(interval+1,gpu_period), but if it asks for monotonic and gpu, it
would be interval+1+gpu_period. I'm not seeing a simple definition
here...

-- 
-keith

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] vulkan: Add VK_EXT_calibrated_timestamps extension (radv and anv) [v4]
  2018-10-16 22:06               ` Keith Packard
@ 2018-10-16 22:28                 ` Bas Nieuwenhuizen
  2018-10-16 22:56                   ` Keith Packard
  2018-10-17  1:55                 ` Jason Ekstrand
  1 sibling, 1 reply; 28+ messages in thread
From: Bas Nieuwenhuizen @ 2018-10-16 22:28 UTC (permalink / raw)
  To: Keith Packard; +Cc: mesa-dev, ML dri-devel, Jason Ekstrand

On Wed, Oct 17, 2018 at 12:06 AM Keith Packard <keithp@keithp.com> wrote:
>
> Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl> writes:
>
> > Well the complication here is that in the MONOTONIC (not
> > MONOTONIC_RAW) case the CPU measurement can happen at the end of the
> > MONOTONIC_RAW interval (as the order of measurements is based on
> > argument order), so you can get a tick that started `period` (5 in
> > this case) monotonic ticks before the start of the interval and a CPU
> > measurement at the end of the interval.
>
> Ah, that's an excellent point. Let's split out raw and monotonic and
> take a look. You want the GPU sampled at the start of the raw interval
> and monotonic sampled at the end, I think?
>
>                  w x y z 0 1 2 3 4 5 6 7 8 9 a b c d e f
> Raw              -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
>
>           0         1         2         3
> GPU       -----_____-----_____-----_____-----_____
>
>                                     x y z 0 1 2 3 4 5 6 7 8 9 a b c
> Monotonic                           -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
>
> Interval                     <----------------->
> Deviation           <-------------------------->
>
>         start = read(raw)       2
>         gpu   = read(GPU)       1
>         mono  = read(monotonic) 2
>         end   = read(raw)       b
>
> In this case, the error between the monotonic pulse and the GPU is
> interval + gpu_period (probably plus one to include the measurement
> error of the raw clock).
>
> Thanks for finding this case.
>
> Now, I guess the question is whether we want to try and find the
> smallest maxDeviation possible for each query. For instance, if the
> application asks only for raw and gpu, the max_deviation could be
> max2(interval+1,gpu_period), but if it asks for monotonic and gpu, it
> would be interval+1+gpu_period. I'm not seeing a simple definition
> here...

You can make the monotonic case the same as the raw case if you make
sure to always sample the CPU first by e.g. splitting the loops into
two and doing CPU in the first and GPU in the second. That way you
make the case above impossible.

That said "start of the interval of the tick" is kinda arbitrary and
you could pick random other points on that interval, so depending on
what requirements you put on it (i.e. can the chosen position be
different per call, consistent but implicit or explicitly picked which
might be leaked through the interface) the max deviation changes. So
depending on interpretation this thing can be very moot ...


>
> --
> -keith
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] vulkan: Add VK_EXT_calibrated_timestamps extension (radv and anv) [v4]
  2018-10-16 22:28                 ` Bas Nieuwenhuizen
@ 2018-10-16 22:56                   ` Keith Packard
  2018-10-17  2:18                     ` Jason Ekstrand
  0 siblings, 1 reply; 28+ messages in thread
From: Keith Packard @ 2018-10-16 22:56 UTC (permalink / raw)
  To: Bas Nieuwenhuizen; +Cc: mesa-dev, ML dri-devel


[-- Attachment #1.1: Type: text/plain, Size: 1067 bytes --]

Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl> writes:

> You can make the monotonic case the same as the raw case if you make
> sure to always sample the CPU first by e.g. splitting the loops into
> two and doing CPU in the first and GPU in the second. That way you
> make the case above impossible.

Right, I had thought of that, and it probably solves the problem for
us. If more time domains are added, things become 'more complicated'
though.

> That said "start of the interval of the tick" is kinda arbitrary and
> you could pick random other points on that interval, so depending on
> what requirements you put on it (i.e. can the chosen position be
> different per call, consistent but implicit or explicitly picked which
> might be leaked through the interface) the max deviation changes. So
> depending on interpretation this thing can be very moot ...

It doesn't really matter what phase you use; the timer increments
periodically, and what really matters is the time when that happens
relative to other clocks changing.

-- 
-keith

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

[-- Attachment #2: Type: text/plain, Size: 157 bytes --]

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] vulkan: Add VK_EXT_calibrated_timestamps extension (radv and anv) [v4]
  2018-10-16 22:06               ` Keith Packard
  2018-10-16 22:28                 ` Bas Nieuwenhuizen
@ 2018-10-17  1:55                 ` Jason Ekstrand
  2018-10-17  5:01                   ` Keith Packard
  1 sibling, 1 reply; 28+ messages in thread
From: Jason Ekstrand @ 2018-10-17  1:55 UTC (permalink / raw)
  To: Keith Packard; +Cc: ML mesa-dev, Maling list - DRI developers


[-- Attachment #1.1: Type: text/plain, Size: 2379 bytes --]

On Tue, Oct 16, 2018 at 5:06 PM Keith Packard <keithp@keithp.com> wrote:

> Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl> writes:
>
> > Well the complication here is that in the MONOTONIC (not
> > MONOTONIC_RAW) case the CPU measurement can happen at the end of the
> > MONOTONIC_RAW interval (as the order of measurements is based on
> > argument order), so you can get a tick that started `period` (5 in
> > this case) monotonic ticks before the start of the interval and a CPU
> > measurement at the end of the interval.
>
> Ah, that's an excellent point. Let's split out raw and monotonic and
> take a look. You want the GPU sampled at the start of the raw interval
> and monotonic sampled at the end, I think?
>
>                  w x y z 0 1 2 3 4 5 6 7 8 9 a b c d e f
> Raw              -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
>
>           0         1         2         3
> GPU       -----_____-----_____-----_____-----_____
>
>                                     x y z 0 1 2 3 4 5 6 7 8 9 a b c
> Monotonic                           -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
>
> Interval                     <----------------->
> Deviation           <-------------------------->
>
>         start = read(raw)       2
>         gpu   = read(GPU)       1
>         mono  = read(monotonic) 2
>         end   = read(raw)       b
>
> In this case, the error between the monotonic pulse and the GPU is
> interval + gpu_period (probably plus one to include the measurement
> error of the raw clock).
>

I'm very confused by this case.  Why is monotonic timeline delayed?  It
seems to me like it's only the monotonic sampling that's delayed and the
result is that mono ends up closer to end than start so the sampled value
would be something like 9 or a rather than 2?

I think we can model this fairly simply as two components:

 1) The size of the sampling window; this is "end - start +
monotonic_raw_tick"
 2) The maximum phase shift of any sample.  The only issue here is that a
tick may have started before the sampling window so we need to add on the
maximum tick size.  The worst case bound for this is when the early sampled
clock is sampled at the end of a tick and the late sampled clock is sampled
at the beginning of a tick.

The result is that we're looking at something like "end - start +
monotonic_raw_tick + max(gpu_tick, monotonic_tick)"  Have I just come
full-circle?

[-- Attachment #1.2: Type: text/html, Size: 3103 bytes --]

[-- Attachment #2: Type: text/plain, Size: 157 bytes --]

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] vulkan: Add VK_EXT_calibrated_timestamps extension (radv and anv) [v4]
  2018-10-16 22:56                   ` Keith Packard
@ 2018-10-17  2:18                     ` Jason Ekstrand
  2018-10-17  5:14                       ` Keith Packard
  0 siblings, 1 reply; 28+ messages in thread
From: Jason Ekstrand @ 2018-10-17  2:18 UTC (permalink / raw)
  To: Keith Packard; +Cc: ML mesa-dev, Maling list - DRI developers


[-- Attachment #1.1: Type: text/plain, Size: 3191 bytes --]

On Tue, Oct 16, 2018 at 5:56 PM Keith Packard <keithp@keithp.com> wrote:

> Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl> writes:
>
> > You can make the monotonic case the same as the raw case if you make
> > sure to always sample the CPU first by e.g. splitting the loops into
> > two and doing CPU in the first and GPU in the second. That way you
> > make the case above impossible.
>
> Right, I had thought of that, and it probably solves the problem for
> us. If more time domains are added, things become 'more complicated'
> though.
>

Doing all of the CPU sampling on one side or the other of the GPU sampling
would probably reduce our window.


> > That said "start of the interval of the tick" is kinda arbitrary and
> > you could pick random other points on that interval, so depending on
> > what requirements you put on it (i.e. can the chosen position be
> > different per call, consistent but implicit or explicitly picked which
> > might be leaked through the interface) the max deviation changes. So
> > depending on interpretation this thing can be very moot ...
>
> It doesn't really matter what phase you use; the timer increments
> periodically, and what really matters is the time when that happens
> relative to other clocks changing.
>

Agreed.

Thinking about this a bit more, I think it helps to consider each clock to
be a real number that's changing continuously in time and what you actually
measure is floor(x / P(x)) where P(x) is the period of x in nanoseconds..
(or ceil; it doesn't matter so long as you're consistent.)  At any given
point, the clocks do have an exact value relative to each other.  When you
sample, you grab floor(M / P(M)), floor(G / P(G)), and floor(R / P(R)) all
in some interval of size I.  The delta between the real values sampled is
most I but the sampling takes a floor operation, so the actual value of any
given clock C may be as much as P(C) greater than what was sampled but it
cannot be lower (assuming the floor convention).  This leaves us with a
delta of I + max(P(M), P(R), P(G)).  In particular, any two real-number
valued times are, instantaneously, within that interval.

The next question becomes, if I sample again and assume zero clock drift,
what are the bounds on the next sampling.  Above, we calculated the maximum
delta between real-valued clocks.  However, because we're sampling again,
we may end up with more phase shift issues and any clock may, again, be off
by as much as P(C).  However, again assuming no drift, no clock is going to
be off with respect to itself; just sampled at a different phase so I think
the most delta you can see between two clocks in the two samplings is the
sum of their periods.  So if the delta we're looking for is a delta for a
theoretical second sampling, I think it's I plus the maximum of the sums of
all pairs of periods.

Personally, I'm completely content to have the delta just be a the first
one: a bound on the difference between any two real-valued times.  At this
point, I can guarantee you that far more thought has been put into this
mesa-dev discussion than was put into the spec and I think we're rapidly
getting to the point of diminishing returns. :-)

--Jason

[-- Attachment #1.2: Type: text/html, Size: 3928 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] vulkan: Add VK_EXT_calibrated_timestamps extension (radv and anv) [v4]
  2018-10-17  1:55                 ` Jason Ekstrand
@ 2018-10-17  5:01                   ` Keith Packard
  0 siblings, 0 replies; 28+ messages in thread
From: Keith Packard @ 2018-10-17  5:01 UTC (permalink / raw)
  To: Jason Ekstrand; +Cc: ML mesa-dev, Maling list - DRI developers


[-- Attachment #1.1: Type: text/plain, Size: 288 bytes --]

Jason Ekstrand <jason@jlekstrand.net> writes:


> The result is that we're looking at something like "end - start +
> monotonic_raw_tick + max(gpu_tick, monotonic_tick)"  Have I just come
> full-circle?

Yes.  As monotonic_raw_tick and monotonic_tick are both 1...

-- 
-keith

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

[-- Attachment #2: Type: text/plain, Size: 157 bytes --]

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] vulkan: Add VK_EXT_calibrated_timestamps extension (radv and anv) [v4]
  2018-10-17  2:18                     ` Jason Ekstrand
@ 2018-10-17  5:14                       ` Keith Packard
  2018-10-17 15:34                         ` Jason Ekstrand
  0 siblings, 1 reply; 28+ messages in thread
From: Keith Packard @ 2018-10-17  5:14 UTC (permalink / raw)
  To: Jason Ekstrand; +Cc: ML mesa-dev, Maling list - DRI developers


[-- Attachment #1.1: Type: text/plain, Size: 1158 bytes --]

Jason Ekstrand <jason@jlekstrand.net> writes:

> Doing all of the CPU sampling on one side or the other of the GPU sampling
> would probably reduce our window.

True, although as I said, it's taking several µs to get through the
loop, and the gpu clock tick is far smaller than that, so even adding
the two values together to make it fit the current implementation won't
make the deviation that much larger.

> This leaves us with a delta of I + max(P(M), P(R), P(G)).  In
> particular, any two real-number valued times are, instantaneously,
> within that interval.

That, at least, would be easy to compute, and scale nicely if we added
more clocks in the future.

> Personally, I'm completely content to have the delta just be a the first
> one: a bound on the difference between any two real-valued times.  At this
> point, I can guarantee you that far more thought has been put into this
> mesa-dev discussion than was put into the spec and I think we're rapidly
> getting to the point of diminishing returns. :-)

It seems likely. How about we do the above computation for the current
code and leave it at that?

-- 
-keith

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

[-- Attachment #2: Type: text/plain, Size: 157 bytes --]

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [PATCH] vulkan: Add VK_EXT_calibrated_timestamps extension (radv and anv) [v4]
  2018-10-17  5:14                       ` Keith Packard
@ 2018-10-17 15:34                         ` Jason Ekstrand
  0 siblings, 0 replies; 28+ messages in thread
From: Jason Ekstrand @ 2018-10-17 15:34 UTC (permalink / raw)
  To: Keith Packard; +Cc: ML mesa-dev, Maling list - DRI developers


[-- Attachment #1.1: Type: text/plain, Size: 1639 bytes --]

On Wed, Oct 17, 2018 at 12:14 AM Keith Packard <keithp@keithp.com> wrote:

> Jason Ekstrand <jason@jlekstrand.net> writes:
>
> > Doing all of the CPU sampling on one side or the other of the GPU
> sampling
> > would probably reduce our window.
>
> True, although as I said, it's taking several µs to get through the
> loop, and the gpu clock tick is far smaller than that, so even adding
> the two values together to make it fit the current implementation won't
> make the deviation that much larger.
>
> > This leaves us with a delta of I + max(P(M), P(R), P(G)).  In
> > particular, any two real-number valued times are, instantaneously,
> > within that interval.
>
> That, at least, would be easy to compute, and scale nicely if we added
> more clocks in the future.
>
> > Personally, I'm completely content to have the delta just be a the first
> > one: a bound on the difference between any two real-valued times.  At
> this
> > point, I can guarantee you that far more thought has been put into this
> > mesa-dev discussion than was put into the spec and I think we're rapidly
> > getting to the point of diminishing returns. :-)
>
> It seems likely. How about we do the above computation for the current
> code and leave it at that?
>

Sounds like a plan.  Note that I should be computed as I = end - start +
monotonic_raw_tick_ns to ensure we get a big enough interval.  Given that
monotonic_raw_tick_ns is likely 1, this doesn't expand things much.

I think a comment is likely also in order.  Probably not containing the
entire e-mail thread but maybe some of my reasoning above?

--Jason

[-- Attachment #1.2: Type: text/html, Size: 2106 bytes --]

[-- Attachment #2: Type: text/plain, Size: 157 bytes --]

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

^ permalink raw reply	[flat|nested] 28+ messages in thread

* [PATCH] vulkan: Add VK_EXT_calibrated_timestamps extension (radv and anv) [v5]
  2018-10-16  5:31   ` [PATCH] vulkan: Add VK_EXT_calibrated_timestamps extension (radv and anv) [v4] Keith Packard
  2018-10-16  7:32     ` Samuel Pitoiset
  2018-10-16  7:33     ` Bas Nieuwenhuizen
@ 2018-10-17 16:49     ` Keith Packard
  2018-10-17 17:06       ` Jason Ekstrand
  2018-10-17 22:49       ` Bas Nieuwenhuizen
  2 siblings, 2 replies; 28+ messages in thread
From: Keith Packard @ 2018-10-17 16:49 UTC (permalink / raw)
  To: mesa-dev; +Cc: dri-devel

Offers three clocks, device, clock monotonic and clock monotonic
raw. Could use some kernel support to reduce the deviation between
clock values.

v2:
	Ensure deviation is at least as big as the GPU time interval.

v3:
	Set device->lost when returning DEVICE_LOST.
	Use MAX2 and DIV_ROUND_UP instead of open coding these.
	Delete spurious TIMESTAMP in radv version.

	Suggested-by: Jason Ekstrand <jason@jlekstrand.net>
	Suggested-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>

v4:
	Add anv_gem_reg_read to anv_gem_stubs.c

	Suggested-by: Jason Ekstrand <jason@jlekstrand.net>

v5:
	Adjust maxDeviation computation to max(sampled_clock_period) +
	sample_interval.

	Suggested-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
	Suggested-by: Jason Ekstrand <jason@jlekstrand.net>

Signed-off-by: Keith Packard <keithp@keithp.com>
---
 src/amd/vulkan/radv_device.c       | 119 +++++++++++++++++++++++++++
 src/amd/vulkan/radv_extensions.py  |   1 +
 src/intel/vulkan/anv_device.c      | 127 +++++++++++++++++++++++++++++
 src/intel/vulkan/anv_extensions.py |   1 +
 src/intel/vulkan/anv_gem.c         |  13 +++
 src/intel/vulkan/anv_gem_stubs.c   |   7 ++
 src/intel/vulkan/anv_private.h     |   2 +
 7 files changed, 270 insertions(+)

diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c
index 174922780fc..4a705a724ef 100644
--- a/src/amd/vulkan/radv_device.c
+++ b/src/amd/vulkan/radv_device.c
@@ -4955,3 +4955,122 @@ radv_GetDeviceGroupPeerMemoryFeatures(
 	                       VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT |
 	                       VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT;
 }
+
+static const VkTimeDomainEXT radv_time_domains[] = {
+	VK_TIME_DOMAIN_DEVICE_EXT,
+	VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT,
+	VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT,
+};
+
+VkResult radv_GetPhysicalDeviceCalibrateableTimeDomainsEXT(
+	VkPhysicalDevice                             physicalDevice,
+	uint32_t                                     *pTimeDomainCount,
+	VkTimeDomainEXT                              *pTimeDomains)
+{
+	int d;
+	VK_OUTARRAY_MAKE(out, pTimeDomains, pTimeDomainCount);
+
+	for (d = 0; d < ARRAY_SIZE(radv_time_domains); d++) {
+		vk_outarray_append(&out, i) {
+			*i = radv_time_domains[d];
+		}
+	}
+
+	return vk_outarray_status(&out);
+}
+
+static uint64_t
+radv_clock_gettime(clockid_t clock_id)
+{
+	struct timespec current;
+	int ret;
+
+	ret = clock_gettime(clock_id, &current);
+	if (ret < 0 && clock_id == CLOCK_MONOTONIC_RAW)
+		ret = clock_gettime(CLOCK_MONOTONIC, &current);
+	if (ret < 0)
+		return 0;
+
+	return (uint64_t) current.tv_sec * 1000000000ULL + current.tv_nsec;
+}
+
+VkResult radv_GetCalibratedTimestampsEXT(
+	VkDevice                                     _device,
+	uint32_t                                     timestampCount,
+	const VkCalibratedTimestampInfoEXT           *pTimestampInfos,
+	uint64_t                                     *pTimestamps,
+	uint64_t                                     *pMaxDeviation)
+{
+	RADV_FROM_HANDLE(radv_device, device, _device);
+	uint32_t clock_crystal_freq = device->physical_device->rad_info.clock_crystal_freq;
+	int d;
+	uint64_t begin, end;
+        uint64_t max_clock_period = 0;
+
+	begin = radv_clock_gettime(CLOCK_MONOTONIC_RAW);
+
+	for (d = 0; d < timestampCount; d++) {
+		switch (pTimestampInfos[d].timeDomain) {
+		case VK_TIME_DOMAIN_DEVICE_EXT:
+			pTimestamps[d] = device->ws->query_value(device->ws,
+								 RADEON_TIMESTAMP);
+                        uint64_t device_period = DIV_ROUND_UP(1000000, clock_crystal_freq);
+                        max_clock_period = MAX2(max_clock_period, device_period);
+			break;
+		case VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT:
+			pTimestamps[d] = radv_clock_gettime(CLOCK_MONOTONIC);
+                        max_clock_period = MAX2(max_clock_period, 1);
+			break;
+
+		case VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT:
+			pTimestamps[d] = begin;
+			break;
+		default:
+			pTimestamps[d] = 0;
+			break;
+		}
+	}
+
+	end = radv_clock_gettime(CLOCK_MONOTONIC_RAW);
+
+        /*
+         * The maximum deviation is the sum of the interval over which we
+         * perform the sampling and the maximum period of any sampled
+         * clock. That's because the maximum skew between any two sampled
+         * clock edges is when the sampled clock with the largest period is
+         * sampled at the end of that period but right at the beginning of the
+         * sampling interval and some other clock is sampled right at the
+         * begining of its sampling period and right at the end of the
+         * sampling interval. Let's assume the GPU has the longest clock
+         * period and that the application is sampling GPU and monotonic:
+         *
+         *                               s                 e
+         *			 w x y z 0 1 2 3 4 5 6 7 8 9 a b c d e f
+         *	Raw              -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
+         *
+         *                               g
+         *		  0         1         2         3
+         *	GPU       -----_____-----_____-----_____-----_____
+         *
+         *                                                m
+         *					    x y z 0 1 2 3 4 5 6 7 8 9 a b c
+         *	Monotonic                           -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
+         *
+         *	Interval                     <----------------->
+         *	Deviation           <-------------------------->
+         *
+         *		s  = read(raw)       2
+         *		g  = read(GPU)       1
+         *		m  = read(monotonic) 2
+         *		e  = read(raw)       b
+         *
+         * We round the sample interval up by one tick to cover sampling error
+         * in the interval clock
+         */
+
+        uint64_t sample_interval = end - begin + 1;
+
+        *pMaxDeviation = sample_interval + max_clock_period;
+
+	return VK_SUCCESS;
+}
diff --git a/src/amd/vulkan/radv_extensions.py b/src/amd/vulkan/radv_extensions.py
index 5dcedae1c63..4c81d3f0068 100644
--- a/src/amd/vulkan/radv_extensions.py
+++ b/src/amd/vulkan/radv_extensions.py
@@ -92,6 +92,7 @@ EXTENSIONS = [
     Extension('VK_KHR_display',                          23, 'VK_USE_PLATFORM_DISPLAY_KHR'),
     Extension('VK_EXT_direct_mode_display',               1, 'VK_USE_PLATFORM_DISPLAY_KHR'),
     Extension('VK_EXT_acquire_xlib_display',              1, 'VK_USE_PLATFORM_XLIB_XRANDR_EXT'),
+    Extension('VK_EXT_calibrated_timestamps',             1, True),
     Extension('VK_EXT_conditional_rendering',             1, True),
     Extension('VK_EXT_conservative_rasterization',        1, 'device->rad_info.chip_class >= GFX9'),
     Extension('VK_EXT_display_surface_counter',           1, 'VK_USE_PLATFORM_DISPLAY_KHR'),
diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c
index a2551452eb1..076ff3a57f6 100644
--- a/src/intel/vulkan/anv_device.c
+++ b/src/intel/vulkan/anv_device.c
@@ -3021,6 +3021,133 @@ void anv_DestroyFramebuffer(
    vk_free2(&device->alloc, pAllocator, fb);
 }
 
+static const VkTimeDomainEXT anv_time_domains[] = {
+   VK_TIME_DOMAIN_DEVICE_EXT,
+   VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT,
+   VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT,
+};
+
+VkResult anv_GetPhysicalDeviceCalibrateableTimeDomainsEXT(
+   VkPhysicalDevice                             physicalDevice,
+   uint32_t                                     *pTimeDomainCount,
+   VkTimeDomainEXT                              *pTimeDomains)
+{
+   int d;
+   VK_OUTARRAY_MAKE(out, pTimeDomains, pTimeDomainCount);
+
+   for (d = 0; d < ARRAY_SIZE(anv_time_domains); d++) {
+      vk_outarray_append(&out, i) {
+         *i = anv_time_domains[d];
+      }
+   }
+
+   return vk_outarray_status(&out);
+}
+
+static uint64_t
+anv_clock_gettime(clockid_t clock_id)
+{
+   struct timespec current;
+   int ret;
+
+   ret = clock_gettime(clock_id, &current);
+   if (ret < 0 && clock_id == CLOCK_MONOTONIC_RAW)
+      ret = clock_gettime(CLOCK_MONOTONIC, &current);
+   if (ret < 0)
+      return 0;
+
+   return (uint64_t) current.tv_sec * 1000000000ULL + current.tv_nsec;
+}
+
+#define TIMESTAMP 0x2358
+
+VkResult anv_GetCalibratedTimestampsEXT(
+   VkDevice                                     _device,
+   uint32_t                                     timestampCount,
+   const VkCalibratedTimestampInfoEXT           *pTimestampInfos,
+   uint64_t                                     *pTimestamps,
+   uint64_t                                     *pMaxDeviation)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   uint64_t timestamp_frequency = device->info.timestamp_frequency;
+   int  ret;
+   int d;
+   uint64_t begin, end;
+   uint64_t max_clock_period = 0;
+
+   begin = anv_clock_gettime(CLOCK_MONOTONIC_RAW);
+
+   for (d = 0; d < timestampCount; d++) {
+      switch (pTimestampInfos[d].timeDomain) {
+      case VK_TIME_DOMAIN_DEVICE_EXT:
+         ret = anv_gem_reg_read(device, TIMESTAMP | 1,
+                                &pTimestamps[d]);
+
+         if (ret != 0) {
+            device->lost = TRUE;
+            return VK_ERROR_DEVICE_LOST;
+         }
+         uint64_t device_period = DIV_ROUND_UP(1000000000, timestamp_frequency);
+         max_clock_period = MAX2(max_clock_period, device_period);
+         break;
+      case VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT:
+         pTimestamps[d] = anv_clock_gettime(CLOCK_MONOTONIC);
+         max_clock_period = MAX2(max_clock_period, 1);
+         break;
+
+      case VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT:
+         pTimestamps[d] = begin;
+         break;
+      default:
+         pTimestamps[d] = 0;
+         break;
+      }
+   }
+
+   end = anv_clock_gettime(CLOCK_MONOTONIC_RAW);
+
+    /*
+     * The maximum deviation is the sum of the interval over which we
+     * perform the sampling and the maximum period of any sampled
+     * clock. That's because the maximum skew between any two sampled
+     * clock edges is when the sampled clock with the largest period is
+     * sampled at the end of that period but right at the beginning of the
+     * sampling interval and some other clock is sampled right at the
+     * begining of its sampling period and right at the end of the
+     * sampling interval. Let's assume the GPU has the longest clock
+     * period and that the application is sampling GPU and monotonic:
+     *
+     *                               s                 e
+     *			 w x y z 0 1 2 3 4 5 6 7 8 9 a b c d e f
+     *	Raw              -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
+     *
+     *                               g
+     *		  0         1         2         3
+     *	GPU       -----_____-----_____-----_____-----_____
+     *
+     *                                                m
+     *					    x y z 0 1 2 3 4 5 6 7 8 9 a b c
+     *	Monotonic                           -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
+     *
+     *	Interval                     <----------------->
+     *	Deviation           <-------------------------->
+     *
+     *		s  = read(raw)       2
+     *		g  = read(GPU)       1
+     *		m  = read(monotonic) 2
+     *		e  = read(raw)       b
+     *
+     * We round the sample interval up by one tick to cover sampling error
+     * in the interval clock
+     */
+
+   uint64_t sample_interval = end - begin + 1;
+
+   *pMaxDeviation = sample_interval + max_clock_period;
+
+   return VK_SUCCESS;
+}
+
 /* vk_icd.h does not declare this function, so we declare it here to
  * suppress Wmissing-prototypes.
  */
diff --git a/src/intel/vulkan/anv_extensions.py b/src/intel/vulkan/anv_extensions.py
index d4915c95013..a8535964da7 100644
--- a/src/intel/vulkan/anv_extensions.py
+++ b/src/intel/vulkan/anv_extensions.py
@@ -126,6 +126,7 @@ EXTENSIONS = [
     Extension('VK_EXT_vertex_attribute_divisor',          3, True),
     Extension('VK_EXT_post_depth_coverage',               1, 'device->info.gen >= 9'),
     Extension('VK_EXT_sampler_filter_minmax',             1, 'device->info.gen >= 9'),
+    Extension('VK_EXT_calibrated_timestamps',             1, True),
 ]
 
 class VkVersion:
diff --git a/src/intel/vulkan/anv_gem.c b/src/intel/vulkan/anv_gem.c
index c43b5ef9e06..1bdf040c1a3 100644
--- a/src/intel/vulkan/anv_gem.c
+++ b/src/intel/vulkan/anv_gem.c
@@ -423,6 +423,19 @@ anv_gem_fd_to_handle(struct anv_device *device, int fd)
    return args.handle;
 }
 
+int
+anv_gem_reg_read(struct anv_device *device, uint32_t offset, uint64_t *result)
+{
+   struct drm_i915_reg_read args = {
+      .offset = offset
+   };
+
+   int ret = anv_ioctl(device->fd, DRM_IOCTL_I915_REG_READ, &args);
+
+   *result = args.val;
+   return ret;
+}
+
 #ifndef SYNC_IOC_MAGIC
 /* duplicated from linux/sync_file.h to avoid build-time dependency
  * on new (v4.7) kernel headers.  Once distro's are mostly using
diff --git a/src/intel/vulkan/anv_gem_stubs.c b/src/intel/vulkan/anv_gem_stubs.c
index 5093bd5db1a..8cc3ad1f22e 100644
--- a/src/intel/vulkan/anv_gem_stubs.c
+++ b/src/intel/vulkan/anv_gem_stubs.c
@@ -251,3 +251,10 @@ anv_gem_syncobj_wait(struct anv_device *device,
 {
    unreachable("Unused");
 }
+
+int
+anv_gem_reg_read(struct anv_device *device,
+                 uint32_t offset, uint64_t *result)
+{
+   unreachable("Unused");
+}
diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
index 599b903f25c..08376b00c8e 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -1103,6 +1103,8 @@ int anv_gem_get_aperture(int fd, uint64_t *size);
 int anv_gem_gpu_get_reset_stats(struct anv_device *device,
                                 uint32_t *active, uint32_t *pending);
 int anv_gem_handle_to_fd(struct anv_device *device, uint32_t gem_handle);
+int anv_gem_reg_read(struct anv_device *device,
+                     uint32_t offset, uint64_t *result);
 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_domain(struct anv_device *device, uint32_t gem_handle,
-- 
2.19.1

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

^ permalink raw reply related	[flat|nested] 28+ messages in thread

* Re: [PATCH] vulkan: Add VK_EXT_calibrated_timestamps extension (radv and anv) [v5]
  2018-10-17 16:49     ` [PATCH] vulkan: Add VK_EXT_calibrated_timestamps extension (radv and anv) [v5] Keith Packard
@ 2018-10-17 17:06       ` Jason Ekstrand
  2018-10-17 17:24         ` [Mesa-dev] " Keith Packard
  2018-10-17 22:49       ` Bas Nieuwenhuizen
  1 sibling, 1 reply; 28+ messages in thread
From: Jason Ekstrand @ 2018-10-17 17:06 UTC (permalink / raw)
  To: Keith Packard; +Cc: ML mesa-dev, Maling list - DRI developers


[-- Attachment #1.1: Type: text/plain, Size: 15857 bytes --]

I like it

Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>

On Wed, Oct 17, 2018 at 11:49 AM Keith Packard <keithp@keithp.com> wrote:

> Offers three clocks, device, clock monotonic and clock monotonic
> raw. Could use some kernel support to reduce the deviation between
> clock values.
>
> v2:
>         Ensure deviation is at least as big as the GPU time interval.
>
> v3:
>         Set device->lost when returning DEVICE_LOST.
>         Use MAX2 and DIV_ROUND_UP instead of open coding these.
>         Delete spurious TIMESTAMP in radv version.
>
>         Suggested-by: Jason Ekstrand <jason@jlekstrand.net>
>         Suggested-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
>
> v4:
>         Add anv_gem_reg_read to anv_gem_stubs.c
>
>         Suggested-by: Jason Ekstrand <jason@jlekstrand.net>
>
> v5:
>         Adjust maxDeviation computation to max(sampled_clock_period) +
>         sample_interval.
>
>         Suggested-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
>         Suggested-by: Jason Ekstrand <jason@jlekstrand.net>
>
> Signed-off-by: Keith Packard <keithp@keithp.com>
> ---
>  src/amd/vulkan/radv_device.c       | 119 +++++++++++++++++++++++++++
>  src/amd/vulkan/radv_extensions.py  |   1 +
>  src/intel/vulkan/anv_device.c      | 127 +++++++++++++++++++++++++++++
>  src/intel/vulkan/anv_extensions.py |   1 +
>  src/intel/vulkan/anv_gem.c         |  13 +++
>  src/intel/vulkan/anv_gem_stubs.c   |   7 ++
>  src/intel/vulkan/anv_private.h     |   2 +
>  7 files changed, 270 insertions(+)
>
> diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c
> index 174922780fc..4a705a724ef 100644
> --- a/src/amd/vulkan/radv_device.c
> +++ b/src/amd/vulkan/radv_device.c
> @@ -4955,3 +4955,122 @@ radv_GetDeviceGroupPeerMemoryFeatures(
>                                VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT |
>                                VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT;
>  }
> +
> +static const VkTimeDomainEXT radv_time_domains[] = {
> +       VK_TIME_DOMAIN_DEVICE_EXT,
> +       VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT,
> +       VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT,
> +};
> +
> +VkResult radv_GetPhysicalDeviceCalibrateableTimeDomainsEXT(
> +       VkPhysicalDevice                             physicalDevice,
> +       uint32_t                                     *pTimeDomainCount,
> +       VkTimeDomainEXT                              *pTimeDomains)
> +{
> +       int d;
> +       VK_OUTARRAY_MAKE(out, pTimeDomains, pTimeDomainCount);
> +
> +       for (d = 0; d < ARRAY_SIZE(radv_time_domains); d++) {
> +               vk_outarray_append(&out, i) {
> +                       *i = radv_time_domains[d];
> +               }
> +       }
> +
> +       return vk_outarray_status(&out);
> +}
> +
> +static uint64_t
> +radv_clock_gettime(clockid_t clock_id)
> +{
> +       struct timespec current;
> +       int ret;
> +
> +       ret = clock_gettime(clock_id, &current);
> +       if (ret < 0 && clock_id == CLOCK_MONOTONIC_RAW)
> +               ret = clock_gettime(CLOCK_MONOTONIC, &current);
> +       if (ret < 0)
> +               return 0;
> +
> +       return (uint64_t) current.tv_sec * 1000000000ULL + current.tv_nsec;
> +}
> +
> +VkResult radv_GetCalibratedTimestampsEXT(
> +       VkDevice                                     _device,
> +       uint32_t                                     timestampCount,
> +       const VkCalibratedTimestampInfoEXT           *pTimestampInfos,
> +       uint64_t                                     *pTimestamps,
> +       uint64_t                                     *pMaxDeviation)
> +{
> +       RADV_FROM_HANDLE(radv_device, device, _device);
> +       uint32_t clock_crystal_freq =
> device->physical_device->rad_info.clock_crystal_freq;
> +       int d;
> +       uint64_t begin, end;
> +        uint64_t max_clock_period = 0;
> +
> +       begin = radv_clock_gettime(CLOCK_MONOTONIC_RAW);
> +
> +       for (d = 0; d < timestampCount; d++) {
> +               switch (pTimestampInfos[d].timeDomain) {
> +               case VK_TIME_DOMAIN_DEVICE_EXT:
> +                       pTimestamps[d] =
> device->ws->query_value(device->ws,
> +
> RADEON_TIMESTAMP);
> +                        uint64_t device_period = DIV_ROUND_UP(1000000,
> clock_crystal_freq);
> +                        max_clock_period = MAX2(max_clock_period,
> device_period);
> +                       break;
> +               case VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT:
> +                       pTimestamps[d] =
> radv_clock_gettime(CLOCK_MONOTONIC);
> +                        max_clock_period = MAX2(max_clock_period, 1);
> +                       break;
> +
> +               case VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT:
> +                       pTimestamps[d] = begin;
> +                       break;
> +               default:
> +                       pTimestamps[d] = 0;
> +                       break;
> +               }
> +       }
> +
> +       end = radv_clock_gettime(CLOCK_MONOTONIC_RAW);
> +
> +        /*
> +         * The maximum deviation is the sum of the interval over which we
> +         * perform the sampling and the maximum period of any sampled
> +         * clock. That's because the maximum skew between any two sampled
> +         * clock edges is when the sampled clock with the largest period
> is
> +         * sampled at the end of that period but right at the beginning
> of the
> +         * sampling interval and some other clock is sampled right at the
> +         * begining of its sampling period and right at the end of the
> +         * sampling interval. Let's assume the GPU has the longest clock
> +         * period and that the application is sampling GPU and monotonic:
> +         *
> +         *                               s                 e
> +         *                      w x y z 0 1 2 3 4 5 6 7 8 9 a b c d e f
> +         *     Raw              -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
> +         *
> +         *                               g
> +         *               0         1         2         3
> +         *     GPU       -----_____-----_____-----_____-----_____
> +         *
> +         *                                                m
> +         *                                         x y z 0 1 2 3 4 5 6 7
> 8 9 a b c
> +         *     Monotonic
>  -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
> +         *
> +         *     Interval                     <----------------->
> +         *     Deviation           <-------------------------->
> +         *
> +         *             s  = read(raw)       2
> +         *             g  = read(GPU)       1
> +         *             m  = read(monotonic) 2
> +         *             e  = read(raw)       b
> +         *
> +         * We round the sample interval up by one tick to cover sampling
> error
> +         * in the interval clock
> +         */
> +
> +        uint64_t sample_interval = end - begin + 1;
> +
> +        *pMaxDeviation = sample_interval + max_clock_period;
> +
> +       return VK_SUCCESS;
> +}
> diff --git a/src/amd/vulkan/radv_extensions.py
> b/src/amd/vulkan/radv_extensions.py
> index 5dcedae1c63..4c81d3f0068 100644
> --- a/src/amd/vulkan/radv_extensions.py
> +++ b/src/amd/vulkan/radv_extensions.py
> @@ -92,6 +92,7 @@ EXTENSIONS = [
>      Extension('VK_KHR_display',                          23,
> 'VK_USE_PLATFORM_DISPLAY_KHR'),
>      Extension('VK_EXT_direct_mode_display',               1,
> 'VK_USE_PLATFORM_DISPLAY_KHR'),
>      Extension('VK_EXT_acquire_xlib_display',              1,
> 'VK_USE_PLATFORM_XLIB_XRANDR_EXT'),
> +    Extension('VK_EXT_calibrated_timestamps',             1, True),
>      Extension('VK_EXT_conditional_rendering',             1, True),
>      Extension('VK_EXT_conservative_rasterization',        1,
> 'device->rad_info.chip_class >= GFX9'),
>      Extension('VK_EXT_display_surface_counter',           1,
> 'VK_USE_PLATFORM_DISPLAY_KHR'),
> diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c
> index a2551452eb1..076ff3a57f6 100644
> --- a/src/intel/vulkan/anv_device.c
> +++ b/src/intel/vulkan/anv_device.c
> @@ -3021,6 +3021,133 @@ void anv_DestroyFramebuffer(
>     vk_free2(&device->alloc, pAllocator, fb);
>  }
>
> +static const VkTimeDomainEXT anv_time_domains[] = {
> +   VK_TIME_DOMAIN_DEVICE_EXT,
> +   VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT,
> +   VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT,
> +};
> +
> +VkResult anv_GetPhysicalDeviceCalibrateableTimeDomainsEXT(
> +   VkPhysicalDevice                             physicalDevice,
> +   uint32_t                                     *pTimeDomainCount,
> +   VkTimeDomainEXT                              *pTimeDomains)
> +{
> +   int d;
> +   VK_OUTARRAY_MAKE(out, pTimeDomains, pTimeDomainCount);
> +
> +   for (d = 0; d < ARRAY_SIZE(anv_time_domains); d++) {
> +      vk_outarray_append(&out, i) {
> +         *i = anv_time_domains[d];
> +      }
> +   }
> +
> +   return vk_outarray_status(&out);
> +}
> +
> +static uint64_t
> +anv_clock_gettime(clockid_t clock_id)
> +{
> +   struct timespec current;
> +   int ret;
> +
> +   ret = clock_gettime(clock_id, &current);
> +   if (ret < 0 && clock_id == CLOCK_MONOTONIC_RAW)
> +      ret = clock_gettime(CLOCK_MONOTONIC, &current);
> +   if (ret < 0)
> +      return 0;
> +
> +   return (uint64_t) current.tv_sec * 1000000000ULL + current.tv_nsec;
> +}
> +
> +#define TIMESTAMP 0x2358
> +
> +VkResult anv_GetCalibratedTimestampsEXT(
> +   VkDevice                                     _device,
> +   uint32_t                                     timestampCount,
> +   const VkCalibratedTimestampInfoEXT           *pTimestampInfos,
> +   uint64_t                                     *pTimestamps,
> +   uint64_t                                     *pMaxDeviation)
> +{
> +   ANV_FROM_HANDLE(anv_device, device, _device);
> +   uint64_t timestamp_frequency = device->info.timestamp_frequency;
> +   int  ret;
> +   int d;
> +   uint64_t begin, end;
> +   uint64_t max_clock_period = 0;
> +
> +   begin = anv_clock_gettime(CLOCK_MONOTONIC_RAW);
> +
> +   for (d = 0; d < timestampCount; d++) {
> +      switch (pTimestampInfos[d].timeDomain) {
> +      case VK_TIME_DOMAIN_DEVICE_EXT:
> +         ret = anv_gem_reg_read(device, TIMESTAMP | 1,
> +                                &pTimestamps[d]);
> +
> +         if (ret != 0) {
> +            device->lost = TRUE;
> +            return VK_ERROR_DEVICE_LOST;
> +         }
> +         uint64_t device_period = DIV_ROUND_UP(1000000000,
> timestamp_frequency);
> +         max_clock_period = MAX2(max_clock_period, device_period);
> +         break;
> +      case VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT:
> +         pTimestamps[d] = anv_clock_gettime(CLOCK_MONOTONIC);
> +         max_clock_period = MAX2(max_clock_period, 1);
> +         break;
> +
> +      case VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT:
> +         pTimestamps[d] = begin;
> +         break;
> +      default:
> +         pTimestamps[d] = 0;
> +         break;
> +      }
> +   }
> +
> +   end = anv_clock_gettime(CLOCK_MONOTONIC_RAW);
> +
> +    /*
> +     * The maximum deviation is the sum of the interval over which we
> +     * perform the sampling and the maximum period of any sampled
> +     * clock. That's because the maximum skew between any two sampled
> +     * clock edges is when the sampled clock with the largest period is
> +     * sampled at the end of that period but right at the beginning of the
> +     * sampling interval and some other clock is sampled right at the
> +     * begining of its sampling period and right at the end of the
> +     * sampling interval. Let's assume the GPU has the longest clock
> +     * period and that the application is sampling GPU and monotonic:
> +     *
> +     *                               s                 e
> +     *                  w x y z 0 1 2 3 4 5 6 7 8 9 a b c d e f
> +     * Raw              -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
> +     *
> +     *                               g
> +     *           0         1         2         3
> +     * GPU       -----_____-----_____-----_____-----_____
> +     *
> +     *                                                m
> +     *                                     x y z 0 1 2 3 4 5 6 7 8 9 a b c
> +     * Monotonic                           -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
> +     *
> +     * Interval                     <----------------->
> +     * Deviation           <-------------------------->
> +     *
> +     *         s  = read(raw)       2
> +     *         g  = read(GPU)       1
> +     *         m  = read(monotonic) 2
> +     *         e  = read(raw)       b
> +     *
> +     * We round the sample interval up by one tick to cover sampling error
> +     * in the interval clock
> +     */
> +
> +   uint64_t sample_interval = end - begin + 1;
> +
> +   *pMaxDeviation = sample_interval + max_clock_period;
> +
> +   return VK_SUCCESS;
> +}
> +
>  /* vk_icd.h does not declare this function, so we declare it here to
>   * suppress Wmissing-prototypes.
>   */
> diff --git a/src/intel/vulkan/anv_extensions.py
> b/src/intel/vulkan/anv_extensions.py
> index d4915c95013..a8535964da7 100644
> --- a/src/intel/vulkan/anv_extensions.py
> +++ b/src/intel/vulkan/anv_extensions.py
> @@ -126,6 +126,7 @@ EXTENSIONS = [
>      Extension('VK_EXT_vertex_attribute_divisor',          3, True),
>      Extension('VK_EXT_post_depth_coverage',               1,
> 'device->info.gen >= 9'),
>      Extension('VK_EXT_sampler_filter_minmax',             1,
> 'device->info.gen >= 9'),
> +    Extension('VK_EXT_calibrated_timestamps',             1, True),
>  ]
>
>  class VkVersion:
> diff --git a/src/intel/vulkan/anv_gem.c b/src/intel/vulkan/anv_gem.c
> index c43b5ef9e06..1bdf040c1a3 100644
> --- a/src/intel/vulkan/anv_gem.c
> +++ b/src/intel/vulkan/anv_gem.c
> @@ -423,6 +423,19 @@ anv_gem_fd_to_handle(struct anv_device *device, int
> fd)
>     return args.handle;
>  }
>
> +int
> +anv_gem_reg_read(struct anv_device *device, uint32_t offset, uint64_t
> *result)
> +{
> +   struct drm_i915_reg_read args = {
> +      .offset = offset
> +   };
> +
> +   int ret = anv_ioctl(device->fd, DRM_IOCTL_I915_REG_READ, &args);
> +
> +   *result = args.val;
> +   return ret;
> +}
> +
>  #ifndef SYNC_IOC_MAGIC
>  /* duplicated from linux/sync_file.h to avoid build-time dependency
>   * on new (v4.7) kernel headers.  Once distro's are mostly using
> diff --git a/src/intel/vulkan/anv_gem_stubs.c
> b/src/intel/vulkan/anv_gem_stubs.c
> index 5093bd5db1a..8cc3ad1f22e 100644
> --- a/src/intel/vulkan/anv_gem_stubs.c
> +++ b/src/intel/vulkan/anv_gem_stubs.c
> @@ -251,3 +251,10 @@ anv_gem_syncobj_wait(struct anv_device *device,
>  {
>     unreachable("Unused");
>  }
> +
> +int
> +anv_gem_reg_read(struct anv_device *device,
> +                 uint32_t offset, uint64_t *result)
> +{
> +   unreachable("Unused");
> +}
> diff --git a/src/intel/vulkan/anv_private.h
> b/src/intel/vulkan/anv_private.h
> index 599b903f25c..08376b00c8e 100644
> --- a/src/intel/vulkan/anv_private.h
> +++ b/src/intel/vulkan/anv_private.h
> @@ -1103,6 +1103,8 @@ int anv_gem_get_aperture(int fd, uint64_t *size);
>  int anv_gem_gpu_get_reset_stats(struct anv_device *device,
>                                  uint32_t *active, uint32_t *pending);
>  int anv_gem_handle_to_fd(struct anv_device *device, uint32_t gem_handle);
> +int anv_gem_reg_read(struct anv_device *device,
> +                     uint32_t offset, uint64_t *result);
>  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_domain(struct anv_device *device, uint32_t gem_handle,
> --
> 2.19.1
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
>

[-- Attachment #1.2: Type: text/html, Size: 20131 bytes --]

[-- Attachment #2: Type: text/plain, Size: 157 bytes --]

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [Mesa-dev] [PATCH] vulkan: Add VK_EXT_calibrated_timestamps extension (radv and anv) [v5]
  2018-10-17 17:06       ` Jason Ekstrand
@ 2018-10-17 17:24         ` Keith Packard
  0 siblings, 0 replies; 28+ messages in thread
From: Keith Packard @ 2018-10-17 17:24 UTC (permalink / raw)
  To: Jason Ekstrand; +Cc: ML mesa-dev, Maling list - DRI developers


[-- Attachment #1.1: Type: text/plain, Size: 146 bytes --]

Jason Ekstrand <jason@jlekstrand.net> writes:

> I like it

When the comments are longer than the code, you know you're done?

-- 
-keith

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [Mesa-dev] [PATCH] vulkan: Add VK_EXT_calibrated_timestamps extension (radv and anv) [v5]
  2018-10-17 16:49     ` [PATCH] vulkan: Add VK_EXT_calibrated_timestamps extension (radv and anv) [v5] Keith Packard
  2018-10-17 17:06       ` Jason Ekstrand
@ 2018-10-17 22:49       ` Bas Nieuwenhuizen
  2018-10-18  3:14         ` Keith Packard
  1 sibling, 1 reply; 28+ messages in thread
From: Bas Nieuwenhuizen @ 2018-10-17 22:49 UTC (permalink / raw)
  To: Keith Packard; +Cc: mesa-dev, ML dri-devel

Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
On Wed, Oct 17, 2018 at 6:49 PM Keith Packard <keithp@keithp.com> wrote:
>
> Offers three clocks, device, clock monotonic and clock monotonic
> raw. Could use some kernel support to reduce the deviation between
> clock values.
>
> v2:
>         Ensure deviation is at least as big as the GPU time interval.
>
> v3:
>         Set device->lost when returning DEVICE_LOST.
>         Use MAX2 and DIV_ROUND_UP instead of open coding these.
>         Delete spurious TIMESTAMP in radv version.
>
>         Suggested-by: Jason Ekstrand <jason@jlekstrand.net>
>         Suggested-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
>
> v4:
>         Add anv_gem_reg_read to anv_gem_stubs.c
>
>         Suggested-by: Jason Ekstrand <jason@jlekstrand.net>
>
> v5:
>         Adjust maxDeviation computation to max(sampled_clock_period) +
>         sample_interval.
>
>         Suggested-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>
>         Suggested-by: Jason Ekstrand <jason@jlekstrand.net>
>
> Signed-off-by: Keith Packard <keithp@keithp.com>
> ---
>  src/amd/vulkan/radv_device.c       | 119 +++++++++++++++++++++++++++
>  src/amd/vulkan/radv_extensions.py  |   1 +
>  src/intel/vulkan/anv_device.c      | 127 +++++++++++++++++++++++++++++
>  src/intel/vulkan/anv_extensions.py |   1 +
>  src/intel/vulkan/anv_gem.c         |  13 +++
>  src/intel/vulkan/anv_gem_stubs.c   |   7 ++
>  src/intel/vulkan/anv_private.h     |   2 +
>  7 files changed, 270 insertions(+)
>
> diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c
> index 174922780fc..4a705a724ef 100644
> --- a/src/amd/vulkan/radv_device.c
> +++ b/src/amd/vulkan/radv_device.c
> @@ -4955,3 +4955,122 @@ radv_GetDeviceGroupPeerMemoryFeatures(
>                                VK_PEER_MEMORY_FEATURE_GENERIC_SRC_BIT |
>                                VK_PEER_MEMORY_FEATURE_GENERIC_DST_BIT;
>  }
> +
> +static const VkTimeDomainEXT radv_time_domains[] = {
> +       VK_TIME_DOMAIN_DEVICE_EXT,
> +       VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT,
> +       VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT,
> +};
> +
> +VkResult radv_GetPhysicalDeviceCalibrateableTimeDomainsEXT(
> +       VkPhysicalDevice                             physicalDevice,
> +       uint32_t                                     *pTimeDomainCount,
> +       VkTimeDomainEXT                              *pTimeDomains)
> +{
> +       int d;
> +       VK_OUTARRAY_MAKE(out, pTimeDomains, pTimeDomainCount);
> +
> +       for (d = 0; d < ARRAY_SIZE(radv_time_domains); d++) {
> +               vk_outarray_append(&out, i) {
> +                       *i = radv_time_domains[d];
> +               }
> +       }
> +
> +       return vk_outarray_status(&out);
> +}
> +
> +static uint64_t
> +radv_clock_gettime(clockid_t clock_id)
> +{
> +       struct timespec current;
> +       int ret;
> +
> +       ret = clock_gettime(clock_id, &current);
> +       if (ret < 0 && clock_id == CLOCK_MONOTONIC_RAW)
> +               ret = clock_gettime(CLOCK_MONOTONIC, &current);
> +       if (ret < 0)
> +               return 0;
> +
> +       return (uint64_t) current.tv_sec * 1000000000ULL + current.tv_nsec;
> +}
> +
> +VkResult radv_GetCalibratedTimestampsEXT(
> +       VkDevice                                     _device,
> +       uint32_t                                     timestampCount,
> +       const VkCalibratedTimestampInfoEXT           *pTimestampInfos,
> +       uint64_t                                     *pTimestamps,
> +       uint64_t                                     *pMaxDeviation)
> +{
> +       RADV_FROM_HANDLE(radv_device, device, _device);
> +       uint32_t clock_crystal_freq = device->physical_device->rad_info.clock_crystal_freq;
> +       int d;
> +       uint64_t begin, end;
> +        uint64_t max_clock_period = 0;
> +
> +       begin = radv_clock_gettime(CLOCK_MONOTONIC_RAW);
> +
> +       for (d = 0; d < timestampCount; d++) {
> +               switch (pTimestampInfos[d].timeDomain) {
> +               case VK_TIME_DOMAIN_DEVICE_EXT:
> +                       pTimestamps[d] = device->ws->query_value(device->ws,
> +                                                                RADEON_TIMESTAMP);
> +                        uint64_t device_period = DIV_ROUND_UP(1000000, clock_crystal_freq);
> +                        max_clock_period = MAX2(max_clock_period, device_period);
> +                       break;
> +               case VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT:
> +                       pTimestamps[d] = radv_clock_gettime(CLOCK_MONOTONIC);
> +                        max_clock_period = MAX2(max_clock_period, 1);
> +                       break;
> +
> +               case VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT:
> +                       pTimestamps[d] = begin;
> +                       break;
> +               default:
> +                       pTimestamps[d] = 0;
> +                       break;
> +               }
> +       }
> +
> +       end = radv_clock_gettime(CLOCK_MONOTONIC_RAW);
> +
> +        /*
> +         * The maximum deviation is the sum of the interval over which we
> +         * perform the sampling and the maximum period of any sampled
> +         * clock. That's because the maximum skew between any two sampled
> +         * clock edges is when the sampled clock with the largest period is
> +         * sampled at the end of that period but right at the beginning of the
> +         * sampling interval and some other clock is sampled right at the
> +         * begining of its sampling period and right at the end of the
> +         * sampling interval. Let's assume the GPU has the longest clock
> +         * period and that the application is sampling GPU and monotonic:
> +         *
> +         *                               s                 e
> +         *                      w x y z 0 1 2 3 4 5 6 7 8 9 a b c d e f
> +         *     Raw              -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
> +         *
> +         *                               g
> +         *               0         1         2         3
> +         *     GPU       -----_____-----_____-----_____-----_____
> +         *
> +         *                                                m
> +         *                                         x y z 0 1 2 3 4 5 6 7 8 9 a b c
> +         *     Monotonic                           -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
> +         *
> +         *     Interval                     <----------------->
> +         *     Deviation           <-------------------------->
> +         *
> +         *             s  = read(raw)       2
> +         *             g  = read(GPU)       1
> +         *             m  = read(monotonic) 2
> +         *             e  = read(raw)       b
> +         *
> +         * We round the sample interval up by one tick to cover sampling error
> +         * in the interval clock
> +         */
> +
> +        uint64_t sample_interval = end - begin + 1;
> +
> +        *pMaxDeviation = sample_interval + max_clock_period;
> +
> +       return VK_SUCCESS;
> +}
> diff --git a/src/amd/vulkan/radv_extensions.py b/src/amd/vulkan/radv_extensions.py
> index 5dcedae1c63..4c81d3f0068 100644
> --- a/src/amd/vulkan/radv_extensions.py
> +++ b/src/amd/vulkan/radv_extensions.py
> @@ -92,6 +92,7 @@ EXTENSIONS = [
>      Extension('VK_KHR_display',                          23, 'VK_USE_PLATFORM_DISPLAY_KHR'),
>      Extension('VK_EXT_direct_mode_display',               1, 'VK_USE_PLATFORM_DISPLAY_KHR'),
>      Extension('VK_EXT_acquire_xlib_display',              1, 'VK_USE_PLATFORM_XLIB_XRANDR_EXT'),
> +    Extension('VK_EXT_calibrated_timestamps',             1, True),
>      Extension('VK_EXT_conditional_rendering',             1, True),
>      Extension('VK_EXT_conservative_rasterization',        1, 'device->rad_info.chip_class >= GFX9'),
>      Extension('VK_EXT_display_surface_counter',           1, 'VK_USE_PLATFORM_DISPLAY_KHR'),
> diff --git a/src/intel/vulkan/anv_device.c b/src/intel/vulkan/anv_device.c
> index a2551452eb1..076ff3a57f6 100644
> --- a/src/intel/vulkan/anv_device.c
> +++ b/src/intel/vulkan/anv_device.c
> @@ -3021,6 +3021,133 @@ void anv_DestroyFramebuffer(
>     vk_free2(&device->alloc, pAllocator, fb);
>  }
>
> +static const VkTimeDomainEXT anv_time_domains[] = {
> +   VK_TIME_DOMAIN_DEVICE_EXT,
> +   VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT,
> +   VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT,
> +};
> +
> +VkResult anv_GetPhysicalDeviceCalibrateableTimeDomainsEXT(
> +   VkPhysicalDevice                             physicalDevice,
> +   uint32_t                                     *pTimeDomainCount,
> +   VkTimeDomainEXT                              *pTimeDomains)
> +{
> +   int d;
> +   VK_OUTARRAY_MAKE(out, pTimeDomains, pTimeDomainCount);
> +
> +   for (d = 0; d < ARRAY_SIZE(anv_time_domains); d++) {
> +      vk_outarray_append(&out, i) {
> +         *i = anv_time_domains[d];
> +      }
> +   }
> +
> +   return vk_outarray_status(&out);
> +}
> +
> +static uint64_t
> +anv_clock_gettime(clockid_t clock_id)
> +{
> +   struct timespec current;
> +   int ret;
> +
> +   ret = clock_gettime(clock_id, &current);
> +   if (ret < 0 && clock_id == CLOCK_MONOTONIC_RAW)
> +      ret = clock_gettime(CLOCK_MONOTONIC, &current);
> +   if (ret < 0)
> +      return 0;
> +
> +   return (uint64_t) current.tv_sec * 1000000000ULL + current.tv_nsec;
> +}
> +
> +#define TIMESTAMP 0x2358
> +
> +VkResult anv_GetCalibratedTimestampsEXT(
> +   VkDevice                                     _device,
> +   uint32_t                                     timestampCount,
> +   const VkCalibratedTimestampInfoEXT           *pTimestampInfos,
> +   uint64_t                                     *pTimestamps,
> +   uint64_t                                     *pMaxDeviation)
> +{
> +   ANV_FROM_HANDLE(anv_device, device, _device);
> +   uint64_t timestamp_frequency = device->info.timestamp_frequency;
> +   int  ret;
> +   int d;
> +   uint64_t begin, end;
> +   uint64_t max_clock_period = 0;
> +
> +   begin = anv_clock_gettime(CLOCK_MONOTONIC_RAW);
> +
> +   for (d = 0; d < timestampCount; d++) {
> +      switch (pTimestampInfos[d].timeDomain) {
> +      case VK_TIME_DOMAIN_DEVICE_EXT:
> +         ret = anv_gem_reg_read(device, TIMESTAMP | 1,
> +                                &pTimestamps[d]);
> +
> +         if (ret != 0) {
> +            device->lost = TRUE;
> +            return VK_ERROR_DEVICE_LOST;
> +         }
> +         uint64_t device_period = DIV_ROUND_UP(1000000000, timestamp_frequency);
> +         max_clock_period = MAX2(max_clock_period, device_period);
> +         break;
> +      case VK_TIME_DOMAIN_CLOCK_MONOTONIC_EXT:
> +         pTimestamps[d] = anv_clock_gettime(CLOCK_MONOTONIC);
> +         max_clock_period = MAX2(max_clock_period, 1);
> +         break;
> +
> +      case VK_TIME_DOMAIN_CLOCK_MONOTONIC_RAW_EXT:
> +         pTimestamps[d] = begin;
> +         break;
> +      default:
> +         pTimestamps[d] = 0;
> +         break;
> +      }
> +   }
> +
> +   end = anv_clock_gettime(CLOCK_MONOTONIC_RAW);
> +
> +    /*
> +     * The maximum deviation is the sum of the interval over which we
> +     * perform the sampling and the maximum period of any sampled
> +     * clock. That's because the maximum skew between any two sampled
> +     * clock edges is when the sampled clock with the largest period is
> +     * sampled at the end of that period but right at the beginning of the
> +     * sampling interval and some other clock is sampled right at the
> +     * begining of its sampling period and right at the end of the
> +     * sampling interval. Let's assume the GPU has the longest clock
> +     * period and that the application is sampling GPU and monotonic:
> +     *
> +     *                               s                 e
> +     *                  w x y z 0 1 2 3 4 5 6 7 8 9 a b c d e f
> +     * Raw              -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
> +     *
> +     *                               g
> +     *           0         1         2         3
> +     * GPU       -----_____-----_____-----_____-----_____
> +     *
> +     *                                                m
> +     *                                     x y z 0 1 2 3 4 5 6 7 8 9 a b c
> +     * Monotonic                           -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
> +     *
> +     * Interval                     <----------------->
> +     * Deviation           <-------------------------->
> +     *
> +     *         s  = read(raw)       2
> +     *         g  = read(GPU)       1
> +     *         m  = read(monotonic) 2
> +     *         e  = read(raw)       b
> +     *
> +     * We round the sample interval up by one tick to cover sampling error
> +     * in the interval clock
> +     */
> +
> +   uint64_t sample_interval = end - begin + 1;
> +
> +   *pMaxDeviation = sample_interval + max_clock_period;
> +
> +   return VK_SUCCESS;
> +}
> +
>  /* vk_icd.h does not declare this function, so we declare it here to
>   * suppress Wmissing-prototypes.
>   */
> diff --git a/src/intel/vulkan/anv_extensions.py b/src/intel/vulkan/anv_extensions.py
> index d4915c95013..a8535964da7 100644
> --- a/src/intel/vulkan/anv_extensions.py
> +++ b/src/intel/vulkan/anv_extensions.py
> @@ -126,6 +126,7 @@ EXTENSIONS = [
>      Extension('VK_EXT_vertex_attribute_divisor',          3, True),
>      Extension('VK_EXT_post_depth_coverage',               1, 'device->info.gen >= 9'),
>      Extension('VK_EXT_sampler_filter_minmax',             1, 'device->info.gen >= 9'),
> +    Extension('VK_EXT_calibrated_timestamps',             1, True),
>  ]
>
>  class VkVersion:
> diff --git a/src/intel/vulkan/anv_gem.c b/src/intel/vulkan/anv_gem.c
> index c43b5ef9e06..1bdf040c1a3 100644
> --- a/src/intel/vulkan/anv_gem.c
> +++ b/src/intel/vulkan/anv_gem.c
> @@ -423,6 +423,19 @@ anv_gem_fd_to_handle(struct anv_device *device, int fd)
>     return args.handle;
>  }
>
> +int
> +anv_gem_reg_read(struct anv_device *device, uint32_t offset, uint64_t *result)
> +{
> +   struct drm_i915_reg_read args = {
> +      .offset = offset
> +   };
> +
> +   int ret = anv_ioctl(device->fd, DRM_IOCTL_I915_REG_READ, &args);
> +
> +   *result = args.val;
> +   return ret;
> +}
> +
>  #ifndef SYNC_IOC_MAGIC
>  /* duplicated from linux/sync_file.h to avoid build-time dependency
>   * on new (v4.7) kernel headers.  Once distro's are mostly using
> diff --git a/src/intel/vulkan/anv_gem_stubs.c b/src/intel/vulkan/anv_gem_stubs.c
> index 5093bd5db1a..8cc3ad1f22e 100644
> --- a/src/intel/vulkan/anv_gem_stubs.c
> +++ b/src/intel/vulkan/anv_gem_stubs.c
> @@ -251,3 +251,10 @@ anv_gem_syncobj_wait(struct anv_device *device,
>  {
>     unreachable("Unused");
>  }
> +
> +int
> +anv_gem_reg_read(struct anv_device *device,
> +                 uint32_t offset, uint64_t *result)
> +{
> +   unreachable("Unused");
> +}
> diff --git a/src/intel/vulkan/anv_private.h b/src/intel/vulkan/anv_private.h
> index 599b903f25c..08376b00c8e 100644
> --- a/src/intel/vulkan/anv_private.h
> +++ b/src/intel/vulkan/anv_private.h
> @@ -1103,6 +1103,8 @@ int anv_gem_get_aperture(int fd, uint64_t *size);
>  int anv_gem_gpu_get_reset_stats(struct anv_device *device,
>                                  uint32_t *active, uint32_t *pending);
>  int anv_gem_handle_to_fd(struct anv_device *device, uint32_t gem_handle);
> +int anv_gem_reg_read(struct anv_device *device,
> +                     uint32_t offset, uint64_t *result);
>  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_domain(struct anv_device *device, uint32_t gem_handle,
> --
> 2.19.1
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 28+ messages in thread

* Re: [Mesa-dev] [PATCH] vulkan: Add VK_EXT_calibrated_timestamps extension (radv and anv) [v5]
  2018-10-17 22:49       ` Bas Nieuwenhuizen
@ 2018-10-18  3:14         ` Keith Packard
  0 siblings, 0 replies; 28+ messages in thread
From: Keith Packard @ 2018-10-18  3:14 UTC (permalink / raw)
  To: Bas Nieuwenhuizen; +Cc: mesa-dev, ML dri-devel


[-- Attachment #1.1: Type: text/plain, Size: 213 bytes --]

Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl> writes:

> Reviewed-by: Bas Nieuwenhuizen <bas@basnieuwenhuizen.nl>

Thanks to you, Jason and Lionel for reviewing the code and helping
improve it.

-- 
-keith

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]

[-- Attachment #2: Type: text/plain, Size: 160 bytes --]

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 28+ messages in thread

end of thread, other threads:[~2018-10-18  3:14 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-10-15 21:22 [PATCH] vulkan: Add VK_EXT_calibrated_timestamps extension (radv and anv) [v2] Keith Packard
2018-10-15 21:36 ` Jason Ekstrand
2018-10-15 21:38 ` Lionel Landwerlin
2018-10-15 23:05 ` [PATCH] vulkan: Add VK_EXT_calibrated_timestamps extension (radv and anv) [v3] Keith Packard
2018-10-16  1:06   ` Jason Ekstrand
2018-10-16  5:31     ` [Mesa-dev] " Keith Packard
2018-10-16  5:31   ` [PATCH] vulkan: Add VK_EXT_calibrated_timestamps extension (radv and anv) [v4] Keith Packard
2018-10-16  7:32     ` Samuel Pitoiset
2018-10-16  7:33     ` Bas Nieuwenhuizen
2018-10-16 19:34       ` Keith Packard
2018-10-16 19:44         ` Jason Ekstrand
2018-10-16 21:07           ` Keith Packard
2018-10-16 21:33             ` Jason Ekstrand
2018-10-16 21:51               ` Keith Packard
2018-10-16 21:38             ` Bas Nieuwenhuizen
2018-10-16 22:06               ` Keith Packard
2018-10-16 22:28                 ` Bas Nieuwenhuizen
2018-10-16 22:56                   ` Keith Packard
2018-10-17  2:18                     ` Jason Ekstrand
2018-10-17  5:14                       ` Keith Packard
2018-10-17 15:34                         ` Jason Ekstrand
2018-10-17  1:55                 ` Jason Ekstrand
2018-10-17  5:01                   ` Keith Packard
2018-10-17 16:49     ` [PATCH] vulkan: Add VK_EXT_calibrated_timestamps extension (radv and anv) [v5] Keith Packard
2018-10-17 17:06       ` Jason Ekstrand
2018-10-17 17:24         ` [Mesa-dev] " Keith Packard
2018-10-17 22:49       ` Bas Nieuwenhuizen
2018-10-18  3:14         ` Keith Packard

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.