diff mbox

[6/7] vulkan: Add new VK_MESA_query_timestamp extension

Message ID 20180210044516.16944-7-keithp@keithp.com
State New, archived
Headers show

Commit Message

Keith Packard Feb. 10, 2018, 4:45 a.m. UTC
This extension adds a single function to query the current GPU
timestamp, just like glGetInteger64v(GL_TIMESTAMP, &timestamp). This
function is needed to complete the implementation of
GOOGLE_display_timing, which needs to be able to coorelate GPU and CPU
timestamps.

Signed-off-by: Keith Packard <keithp@keithp.com>
---
 include/vulkan/vulkan.h                         |  6 ++++++
 src/Makefile.am                                 |  1 +
 src/amd/vulkan/Makefile.am                      |  3 +++
 src/amd/vulkan/meson.build                      |  8 ++++----
 src/amd/vulkan/radv_device.c                    |  8 ++++++++
 src/amd/vulkan/radv_extensions.py               |  1 +
 src/intel/Makefile.vulkan.am                    |  7 +++++++
 src/intel/vulkan/anv_extensions.py              |  1 +
 src/intel/vulkan/anv_gem.c                      | 13 +++++++++++++
 src/intel/vulkan/anv_private.h                  |  1 +
 src/intel/vulkan/genX_query.c                   | 15 +++++++++++++++
 src/intel/vulkan/meson.build                    | 12 ++++++------
 src/vulkan/meson.build                          |  1 +
 src/vulkan/registry/vk_mesa_query_timestamp.xml | 22 ++++++++++++++++++++++
 14 files changed, 89 insertions(+), 10 deletions(-)
 create mode 100644 src/vulkan/registry/vk_mesa_query_timestamp.xml

Comments

Dylan Baker Feb. 13, 2018, 12:20 a.m. UTC | #1
Quoting Keith Packard (2018-02-09 20:45:15)
> This extension adds a single function to query the current GPU
> timestamp, just like glGetInteger64v(GL_TIMESTAMP, &timestamp). This
> function is needed to complete the implementation of
> GOOGLE_display_timing, which needs to be able to coorelate GPU and CPU
> timestamps.
> 
> Signed-off-by: Keith Packard <keithp@keithp.com>
> ---
>  include/vulkan/vulkan.h                         |  6 ++++++
>  src/Makefile.am                                 |  1 +
>  src/amd/vulkan/Makefile.am                      |  3 +++
>  src/amd/vulkan/meson.build                      |  8 ++++----
>  src/amd/vulkan/radv_device.c                    |  8 ++++++++
>  src/amd/vulkan/radv_extensions.py               |  1 +
>  src/intel/Makefile.vulkan.am                    |  7 +++++++
>  src/intel/vulkan/anv_extensions.py              |  1 +
>  src/intel/vulkan/anv_gem.c                      | 13 +++++++++++++
>  src/intel/vulkan/anv_private.h                  |  1 +
>  src/intel/vulkan/genX_query.c                   | 15 +++++++++++++++
>  src/intel/vulkan/meson.build                    | 12 ++++++------
>  src/vulkan/meson.build                          |  1 +
>  src/vulkan/registry/vk_mesa_query_timestamp.xml | 22 ++++++++++++++++++++++
>  14 files changed, 89 insertions(+), 10 deletions(-)
>  create mode 100644 src/vulkan/registry/vk_mesa_query_timestamp.xml
> 
> diff --git a/include/vulkan/vulkan.h b/include/vulkan/vulkan.h
> index d3e2e246cf3..5523eb7586f 100644
> --- a/include/vulkan/vulkan.h
> +++ b/include/vulkan/vulkan.h
> @@ -7025,6 +7025,12 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryHostPointerPropertiesEXT(
>      VkMemoryHostPointerPropertiesEXT*           pMemoryHostPointerProperties);
>  #endif
>  
> +typedef VkResult (VKAPI_PTR *PFN_vkQueryCurrentTimestampMESA)(VkDevice device, uint64_t *timestamp);
> +
> +VKAPI_ATTR VkResult VKAPI_CALL vkQueryCurrentTimestampMESA(
> +    VkDevice                                    _device,
> +    uint64_t                                    *timestamp);
> +
>  #ifdef __cplusplus
>  }
>  #endif
> diff --git a/src/Makefile.am b/src/Makefile.am
> index 014ffaf3e29..74ff305d7c6 100644
> --- a/src/Makefile.am
> +++ b/src/Makefile.am
> @@ -68,6 +68,7 @@ endif
>  
>  EXTRA_DIST += vulkan/registry/vk.xml
>  EXTRA_DIST += vulkan/registry/vk_android_native_buffer.xml
> +EXTRA_DIST += vulkan/registry/vk_mesa_query_timestamp.xml
>  
>  if HAVE_AMD_DRIVERS
>  SUBDIRS += amd
> diff --git a/src/amd/vulkan/Makefile.am b/src/amd/vulkan/Makefile.am
> index 94ece06e99e..0626fa2b3b3 100644
> --- a/src/amd/vulkan/Makefile.am
> +++ b/src/amd/vulkan/Makefile.am
> @@ -129,12 +129,14 @@ libvulkan_radeon_la_SOURCES = $(VULKAN_GEM_FILES)
>  
>  vulkan_api_xml = $(top_srcdir)/src/vulkan/registry/vk.xml
>  vk_android_native_buffer_xml = $(top_srcdir)/src/vulkan/registry/vk_android_native_buffer.xml
> +vk_mesa_query_timestamp_xml = $(top_srcdir)/src/vulkan/registry/vk_mesa_query_timestamps.xml
>  
>  radv_entrypoints.c: radv_entrypoints_gen.py radv_extensions.py $(vulkan_api_xml)
>         $(MKDIR_GEN)
>         $(AM_V_GEN)$(PYTHON2) $(srcdir)/radv_entrypoints_gen.py \
>                 --xml $(vulkan_api_xml) \
>                 --xml $(vk_android_native_buffer_xml) \
> +               --xml $(vk_mesa_query_timestamp_xml) \
>                 --outdir $(builddir)
>  radv_entrypoints.h: radv_entrypoints.c
>  
> @@ -144,6 +146,7 @@ radv_extensions.c: radv_extensions.py \
>         $(AM_V_GEN)$(PYTHON2) $(srcdir)/radv_extensions.py \
>                 --xml $(vulkan_api_xml) \
>                 --xml $(vk_android_native_buffer_xml) \
> +               --xml $(vk_mesa_query_timestamp_xml) \
>                 --out $@
>  
>  vk_format_table.c: vk_format_table.py \
> diff --git a/src/amd/vulkan/meson.build b/src/amd/vulkan/meson.build
> index 0b92a1763a1..34f578476c0 100644
> --- a/src/amd/vulkan/meson.build
> +++ b/src/amd/vulkan/meson.build
> @@ -20,10 +20,10 @@
>  
>  radv_entrypoints = custom_target(
>    'radv_entrypoints.[ch]',
> -  input : ['radv_entrypoints_gen.py', vk_api_xml],
> +  input : ['radv_entrypoints_gen.py', vk_api_xml, vk_android_native_buffer_xml, vk_mesa_query_timestamp_xml],

some of these lines look a little long, 
input : [
    'radv_entrypoints_gen.py', vk_api_xml, vk_android_native_buffer_xml,
    vk_mesa_query_timestamp_xml,
],

>    output : ['radv_entrypoints.h', 'radv_entrypoints.c'],
>    command : [
> -    prog_python2, '@INPUT0@', '--xml', '@INPUT1@', '--outdir',
> +    prog_python2, '@INPUT0@', '--xml', '@INPUT1@', '--xml', '@INPUT2@', '--xml', '@INPUT3@', '--outdir',
>      meson.current_build_dir()
>    ],
>    depend_files : files('radv_extensions.py'),
> @@ -31,10 +31,10 @@ radv_entrypoints = custom_target(
>  
>  radv_extensions_c = custom_target(
>    'radv_extensions.c',
> -  input : ['radv_extensions.py', vk_api_xml, vk_android_native_buffer_xml],
> +  input : ['radv_extensions.py', vk_api_xml, vk_android_native_buffer_xml, vk_mesa_query_timestamp_xml],
>    output : ['radv_extensions.c'],
>    command : [
> -    prog_python2, '@INPUT0@', '--xml', '@INPUT1@', '--xml', '@INPUT2@', '--out', '@OUTPUT@',
> +    prog_python2, '@INPUT0@', '--xml', '@INPUT1@', '--xml', '@INPUT2@', '--xml', '@INPUT3@', '--out', '@OUTPUT@',
>    ],
>  )
>  
> diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c
> index adf33eb35dc..6c13efba9e0 100644
> --- a/src/amd/vulkan/radv_device.c
> +++ b/src/amd/vulkan/radv_device.c
> @@ -4084,3 +4084,11 @@ radv_DebugReportMessageEXT(VkInstance _instance,
>         vk_debug_report(&instance->debug_report_callbacks, flags, objectType,
>                         object, location, messageCode, pLayerPrefix, pMessage);
>  }
> +
> +VkResult radv_QueryCurrentTimestampMESA(VkDevice _device, uint64_t *timestamp)
> +{
> +       RADV_FROM_HANDLE(radv_device, device, _device);
> +
> +       *timestamp = device->ws->query_value(device->ws, RADEON_TIMESTAMP);
> +       return VK_SUCCESS;
> +}
> diff --git a/src/amd/vulkan/radv_extensions.py b/src/amd/vulkan/radv_extensions.py
> index 775d1ed4be6..fed198df412 100644
> --- a/src/amd/vulkan/radv_extensions.py
> +++ b/src/amd/vulkan/radv_extensions.py
> @@ -95,6 +95,7 @@ EXTENSIONS = [
>      Extension('VK_AMD_draw_indirect_count',               1, True),
>      Extension('VK_AMD_rasterization_order',               1, 'device->rad_info.chip_class >= VI && device->rad_info.max_se >= 2'),
>      Extension('VK_AMD_shader_info',                       1, True),
> +    Extension('VK_MESA_query_timestamp',                  1, True),
>  ]
>  
>  class VkVersion:
> diff --git a/src/intel/Makefile.vulkan.am b/src/intel/Makefile.vulkan.am
> index 0f0d3815097..d7890022abe 100644
> --- a/src/intel/Makefile.vulkan.am
> +++ b/src/intel/Makefile.vulkan.am
> @@ -24,36 +24,43 @@
>  # out and we'll fail at `make dist'
>  vulkan_api_xml = $(top_srcdir)/src/vulkan/registry/vk.xml
>  vk_android_native_buffer_xml = $(top_srcdir)/src/vulkan/registry/vk_android_native_buffer.xml
> +vk_mesa_query_timestamp_xml = $(top_srcdir)/src/vulkan/registry/vk_mesa_query_timestamps.xml
>  
>  vulkan/anv_entrypoints.c: vulkan/anv_entrypoints_gen.py \
>                           vulkan/anv_extensions.py \
>                           $(vulkan_api_xml) \
> +                         $(vk_mesa_query_timestamp_xml) \
>                           $(vk_android_native_buffer_xml)
>         $(MKDIR_GEN)
>         $(AM_V_GEN)$(PYTHON2) $(srcdir)/vulkan/anv_entrypoints_gen.py \
>                 --xml $(vulkan_api_xml) \
>                 --xml $(vk_android_native_buffer_xml) \
> +               --xml $(vk_mesa_query_timestamp_xml) \
>                 --outdir $(builddir)/vulkan
>  vulkan/anv_entrypoints.h: vulkan/anv_entrypoints.c
>  
>  vulkan/anv_extensions.c: vulkan/anv_extensions_gen.py \
>                          vulkan/anv_extensions.py \
>                          $(vulkan_api_xml) \
> +                        $(vk_mesa_query_timestamp_xml) \
>                          $(vk_android_native_buffer_xml)
>         $(MKDIR_GEN)
>         $(AM_V_GEN)$(PYTHON2) $(srcdir)/vulkan/anv_extensions_gen.py \
>                 --xml $(vulkan_api_xml) \
>                 --xml $(vk_android_native_buffer_xml) \
> +               --xml $(vk_mesa_query_timestamp_xml) \
>                 --out-c $@
>  
>  vulkan/anv_extensions.h: vulkan/anv_extensions_gen.py \
>                          vulkan/anv_extensions.py \
>                          $(vulkan_api_xml) \
> +                        $(vk_mesa_query_timestamp_xml) \
>                          $(vk_android_native_buffer_xml)
>         $(MKDIR_GEN)
>         $(AM_V_GEN)$(PYTHON2) $(srcdir)/vulkan/anv_extensions_gen.py \
>                 --xml $(vulkan_api_xml) \
>                 --xml $(vk_android_native_buffer_xml) \
> +               --xml $(vk_mesa_query_timestamp_xml) \
>                 --out-h $@
>  
>  BUILT_SOURCES += $(VULKAN_GENERATED_FILES)
> diff --git a/src/intel/vulkan/anv_extensions.py b/src/intel/vulkan/anv_extensions.py
> index f44598b305a..dd4d5a1f970 100644
> --- a/src/intel/vulkan/anv_extensions.py
> +++ b/src/intel/vulkan/anv_extensions.py
> @@ -91,6 +91,7 @@ EXTENSIONS = [
>      Extension('VK_EXT_external_memory_dma_buf',           1, True),
>      Extension('VK_EXT_display_surface_counter',           1, 'VK_USE_PLATFORM_DISPLAY_KHR'),
>      Extension('VK_EXT_display_control',                   1, 'VK_USE_PLATFORM_DISPLAY_KHR'),
> +    Extension('VK_MESA_query_timestamp',                  1, True),
>  ]
>  
>  class VkVersion:
> diff --git a/src/intel/vulkan/anv_gem.c b/src/intel/vulkan/anv_gem.c
> index 34c09891086..588b323d113 100644
> --- a/src/intel/vulkan/anv_gem.c
> +++ b/src/intel/vulkan/anv_gem.c
> @@ -418,6 +418,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 1d3e5fcd921..337d8ca3f15 100644
> --- a/src/intel/vulkan/anv_private.h
> +++ b/src/intel/vulkan/anv_private.h
> @@ -932,6 +932,7 @@ bool anv_gem_supports_48b_addresses(int fd);
>  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,
> diff --git a/src/intel/vulkan/genX_query.c b/src/intel/vulkan/genX_query.c
> index 4efcc57e475..d2de7e5f45e 100644
> --- a/src/intel/vulkan/genX_query.c
> +++ b/src/intel/vulkan/genX_query.c
> @@ -546,6 +546,21 @@ void genX(CmdWriteTimestamp)(
>     }
>  }
>  
> +VkResult genX(QueryCurrentTimestampMESA)(
> +   VkDevice                                     _device,
> +   uint64_t                                     *timestamp)
> +{
> +   ANV_FROM_HANDLE(anv_device, device, _device);
> +   int  ret;
> +
> +   /* XXX older kernels don't support this interface. */
> +   ret = anv_gem_reg_read(device, TIMESTAMP | 1, timestamp);
> +
> +   if (ret != 0)
> +      return VK_ERROR_DEVICE_LOST;
> +   return VK_SUCCESS;
> +}
> +
>  #if GEN_GEN > 7 || GEN_IS_HASWELL
>  
>  static uint32_t
> diff --git a/src/intel/vulkan/meson.build b/src/intel/vulkan/meson.build
> index d3ab5ac8a64..d4622ffdfdf 100644
> --- a/src/intel/vulkan/meson.build
> +++ b/src/intel/vulkan/meson.build
> @@ -20,11 +20,11 @@
>  
>  anv_entrypoints = custom_target(
>    'anv_entrypoints.[ch]',
> -  input : ['anv_entrypoints_gen.py', vk_api_xml, vk_android_native_buffer_xml,
> +  input : ['anv_entrypoints_gen.py', vk_api_xml, vk_android_native_buffer_xml, vk_mesa_query_timestamp_xml,
>             'anv_extensions.py'],

Same with this, could you also fix my bad indentation here?

>    output : ['anv_entrypoints.h', 'anv_entrypoints.c'],
>    command : [
> -    prog_python2, '@INPUT0@', '--xml', '@INPUT1@', '--xml', '@INPUT2@',
> +    prog_python2, '@INPUT0@', '--xml', '@INPUT1@', '--xml', '@INPUT2@', '--xml', '@INPUT3@',
>      '--outdir', meson.current_build_dir(),
>    ],
>    depend_files : files('anv_extensions.py'),
> @@ -32,22 +32,22 @@ anv_entrypoints = custom_target(
>  
>  anv_extensions_c = custom_target(
>    'anv_extensions.c',
> -  input : ['anv_extensions_gen.py', vk_api_xml, vk_android_native_buffer_xml,
> +  input : ['anv_extensions_gen.py', vk_api_xml, vk_android_native_buffer_xml, vk_mesa_query_timestamp_xml,
>             'anv_extensions.py'],
>    output : 'anv_extensions.c',
>    command : [
> -    prog_python2, '@INPUT0@', '--xml', '@INPUT1@', '--xml', '@INPUT2@',
> +    prog_python2, '@INPUT0@', '--xml', '@INPUT1@', '--xml', '@INPUT2@', '--xml', '@INPUT3@',
>      '--out-c', '@OUTPUT@',
>    ],
>  )
>  
>  anv_extensions_h = custom_target(
>    'anv_extensions.h',
> -  input : ['anv_extensions_gen.py', vk_api_xml, vk_android_native_buffer_xml,
> +  input : ['anv_extensions_gen.py', vk_api_xml, vk_android_native_buffer_xml, vk_mesa_query_timestamp_xml,
>             'anv_extensions.py'],
>    output : 'anv_extensions.h',
>    command : [
> -    prog_python2, '@INPUT0@', '--xml', '@INPUT1@', '--xml', '@INPUT2@',
> +    prog_python2, '@INPUT0@', '--xml', '@INPUT1@', '--xml', '@INPUT2@', '--xml', '@INPUT3@',
>      '--out-h', '@OUTPUT@',
>    ],
>  )
> diff --git a/src/vulkan/meson.build b/src/vulkan/meson.build
> index 3908005b8a0..6ab0966b7c5 100644
> --- a/src/vulkan/meson.build
> +++ b/src/vulkan/meson.build
> @@ -20,6 +20,7 @@
>  
>  vk_api_xml = files('registry/vk.xml')
>  vk_android_native_buffer_xml = files('registry/vk_android_native_buffer.xml')
> +vk_mesa_query_timestamp_xml = files('registry/vk_mesa_query_timestamp.xml')
>  
>  inc_vulkan_util = include_directories('util')
>  inc_vulkan_wsi = include_directories('wsi')
> diff --git a/src/vulkan/registry/vk_mesa_query_timestamp.xml b/src/vulkan/registry/vk_mesa_query_timestamp.xml
> new file mode 100644
> index 00000000000..7fd4d974872
> --- /dev/null
> +++ b/src/vulkan/registry/vk_mesa_query_timestamp.xml
> @@ -0,0 +1,22 @@
> +<?xml version="1.0" encoding="UTF-8"?>
> +<registry>
> +    <commands>
> +        <command>
> +            <proto><type>VkResult</type> <name>vkQueryCurrentTimestampMESA</name></proto>
> +            <param><type>VkDevice</type> <name>device</name></param>
> +            <param><type>uint64_t</type>* <name>pTimestamp</name></param>
> +        </command>
> +    </commands>
> +    <extensions>
> +        <extension name="VK_MESA_query_timestamp" number="200"
> +                  type="device" author="MESA"
> +                  contact="Keith Packard @keithp"
> +                  supported="vulkan">
> +            <require>
> +                <enum value="1"                                         name="VK_MESA_QUERY_TIMESTAMP_SPEC_VERSION"/>
> +                <enum value="&quot;VK_MESA_query_timestamp&quot;"       name="VK_MESA_QUERY_TIMESTAMP_NAME"/>
> +                <command name="vkQueryCurrentTimestampMESA"/>
> +            </require>
> +        </extension>
> +    </extensions>
> +</registry>
> -- 
> 2.15.1
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel
Lionel Landwerlin Feb. 13, 2018, 10:49 a.m. UTC | #2
On 13/02/18 00:20, Dylan Baker wrote:
> Quoting Keith Packard (2018-02-09 20:45:15)
>> This extension adds a single function to query the current GPU
>> timestamp, just like glGetInteger64v(GL_TIMESTAMP, &timestamp). This
>> function is needed to complete the implementation of
>> GOOGLE_display_timing, which needs to be able to coorelate GPU and CPU
>> timestamps.

I'm assuming the correlation is done outside the vulkan driver? With a 
clock_gettime() maybe?

If that's the case, I'm afraid this will be highly inaccurate.
The kernel might execute other tasks when the ioctl() happens and that 
might introduce (in my experience) a few milliseconds of delay.

I think if you want to do something like that, this has to be 
implemented in the kernel, making sure you disable interruptions while 
doing the correlation.

>>
>> Signed-off-by: Keith Packard <keithp@keithp.com>
>> ---
>>   include/vulkan/vulkan.h                         |  6 ++++++
>>   src/Makefile.am                                 |  1 +
>>   src/amd/vulkan/Makefile.am                      |  3 +++
>>   src/amd/vulkan/meson.build                      |  8 ++++----
>>   src/amd/vulkan/radv_device.c                    |  8 ++++++++
>>   src/amd/vulkan/radv_extensions.py               |  1 +
>>   src/intel/Makefile.vulkan.am                    |  7 +++++++
>>   src/intel/vulkan/anv_extensions.py              |  1 +
>>   src/intel/vulkan/anv_gem.c                      | 13 +++++++++++++
>>   src/intel/vulkan/anv_private.h                  |  1 +
>>   src/intel/vulkan/genX_query.c                   | 15 +++++++++++++++
>>   src/intel/vulkan/meson.build                    | 12 ++++++------
>>   src/vulkan/meson.build                          |  1 +
>>   src/vulkan/registry/vk_mesa_query_timestamp.xml | 22 ++++++++++++++++++++++
>>   14 files changed, 89 insertions(+), 10 deletions(-)
>>   create mode 100644 src/vulkan/registry/vk_mesa_query_timestamp.xml
>>
>> diff --git a/include/vulkan/vulkan.h b/include/vulkan/vulkan.h
>> index d3e2e246cf3..5523eb7586f 100644
>> --- a/include/vulkan/vulkan.h
>> +++ b/include/vulkan/vulkan.h
>> @@ -7025,6 +7025,12 @@ VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryHostPointerPropertiesEXT(
>>       VkMemoryHostPointerPropertiesEXT*           pMemoryHostPointerProperties);
>>   #endif
>>   
>> +typedef VkResult (VKAPI_PTR *PFN_vkQueryCurrentTimestampMESA)(VkDevice device, uint64_t *timestamp);
>> +
>> +VKAPI_ATTR VkResult VKAPI_CALL vkQueryCurrentTimestampMESA(
>> +    VkDevice                                    _device,
>> +    uint64_t                                    *timestamp);
>> +
>>   #ifdef __cplusplus
>>   }
>>   #endif
>> diff --git a/src/Makefile.am b/src/Makefile.am
>> index 014ffaf3e29..74ff305d7c6 100644
>> --- a/src/Makefile.am
>> +++ b/src/Makefile.am
>> @@ -68,6 +68,7 @@ endif
>>   
>>   EXTRA_DIST += vulkan/registry/vk.xml
>>   EXTRA_DIST += vulkan/registry/vk_android_native_buffer.xml
>> +EXTRA_DIST += vulkan/registry/vk_mesa_query_timestamp.xml
>>   
>>   if HAVE_AMD_DRIVERS
>>   SUBDIRS += amd
>> diff --git a/src/amd/vulkan/Makefile.am b/src/amd/vulkan/Makefile.am
>> index 94ece06e99e..0626fa2b3b3 100644
>> --- a/src/amd/vulkan/Makefile.am
>> +++ b/src/amd/vulkan/Makefile.am
>> @@ -129,12 +129,14 @@ libvulkan_radeon_la_SOURCES = $(VULKAN_GEM_FILES)
>>   
>>   vulkan_api_xml = $(top_srcdir)/src/vulkan/registry/vk.xml
>>   vk_android_native_buffer_xml = $(top_srcdir)/src/vulkan/registry/vk_android_native_buffer.xml
>> +vk_mesa_query_timestamp_xml = $(top_srcdir)/src/vulkan/registry/vk_mesa_query_timestamps.xml
>>   
>>   radv_entrypoints.c: radv_entrypoints_gen.py radv_extensions.py $(vulkan_api_xml)
>>          $(MKDIR_GEN)
>>          $(AM_V_GEN)$(PYTHON2) $(srcdir)/radv_entrypoints_gen.py \
>>                  --xml $(vulkan_api_xml) \
>>                  --xml $(vk_android_native_buffer_xml) \
>> +               --xml $(vk_mesa_query_timestamp_xml) \
>>                  --outdir $(builddir)
>>   radv_entrypoints.h: radv_entrypoints.c
>>   
>> @@ -144,6 +146,7 @@ radv_extensions.c: radv_extensions.py \
>>          $(AM_V_GEN)$(PYTHON2) $(srcdir)/radv_extensions.py \
>>                  --xml $(vulkan_api_xml) \
>>                  --xml $(vk_android_native_buffer_xml) \
>> +               --xml $(vk_mesa_query_timestamp_xml) \
>>                  --out $@
>>   
>>   vk_format_table.c: vk_format_table.py \
>> diff --git a/src/amd/vulkan/meson.build b/src/amd/vulkan/meson.build
>> index 0b92a1763a1..34f578476c0 100644
>> --- a/src/amd/vulkan/meson.build
>> +++ b/src/amd/vulkan/meson.build
>> @@ -20,10 +20,10 @@
>>   
>>   radv_entrypoints = custom_target(
>>     'radv_entrypoints.[ch]',
>> -  input : ['radv_entrypoints_gen.py', vk_api_xml],
>> +  input : ['radv_entrypoints_gen.py', vk_api_xml, vk_android_native_buffer_xml, vk_mesa_query_timestamp_xml],
> some of these lines look a little long,
> input : [
>      'radv_entrypoints_gen.py', vk_api_xml, vk_android_native_buffer_xml,
>      vk_mesa_query_timestamp_xml,
> ],
>
>>     output : ['radv_entrypoints.h', 'radv_entrypoints.c'],
>>     command : [
>> -    prog_python2, '@INPUT0@', '--xml', '@INPUT1@', '--outdir',
>> +    prog_python2, '@INPUT0@', '--xml', '@INPUT1@', '--xml', '@INPUT2@', '--xml', '@INPUT3@', '--outdir',
>>       meson.current_build_dir()
>>     ],
>>     depend_files : files('radv_extensions.py'),
>> @@ -31,10 +31,10 @@ radv_entrypoints = custom_target(
>>   
>>   radv_extensions_c = custom_target(
>>     'radv_extensions.c',
>> -  input : ['radv_extensions.py', vk_api_xml, vk_android_native_buffer_xml],
>> +  input : ['radv_extensions.py', vk_api_xml, vk_android_native_buffer_xml, vk_mesa_query_timestamp_xml],
>>     output : ['radv_extensions.c'],
>>     command : [
>> -    prog_python2, '@INPUT0@', '--xml', '@INPUT1@', '--xml', '@INPUT2@', '--out', '@OUTPUT@',
>> +    prog_python2, '@INPUT0@', '--xml', '@INPUT1@', '--xml', '@INPUT2@', '--xml', '@INPUT3@', '--out', '@OUTPUT@',
>>     ],
>>   )
>>   
>> diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c
>> index adf33eb35dc..6c13efba9e0 100644
>> --- a/src/amd/vulkan/radv_device.c
>> +++ b/src/amd/vulkan/radv_device.c
>> @@ -4084,3 +4084,11 @@ radv_DebugReportMessageEXT(VkInstance _instance,
>>          vk_debug_report(&instance->debug_report_callbacks, flags, objectType,
>>                          object, location, messageCode, pLayerPrefix, pMessage);
>>   }
>> +
>> +VkResult radv_QueryCurrentTimestampMESA(VkDevice _device, uint64_t *timestamp)
>> +{
>> +       RADV_FROM_HANDLE(radv_device, device, _device);
>> +
>> +       *timestamp = device->ws->query_value(device->ws, RADEON_TIMESTAMP);
>> +       return VK_SUCCESS;
>> +}
>> diff --git a/src/amd/vulkan/radv_extensions.py b/src/amd/vulkan/radv_extensions.py
>> index 775d1ed4be6..fed198df412 100644
>> --- a/src/amd/vulkan/radv_extensions.py
>> +++ b/src/amd/vulkan/radv_extensions.py
>> @@ -95,6 +95,7 @@ EXTENSIONS = [
>>       Extension('VK_AMD_draw_indirect_count',               1, True),
>>       Extension('VK_AMD_rasterization_order',               1, 'device->rad_info.chip_class >= VI && device->rad_info.max_se >= 2'),
>>       Extension('VK_AMD_shader_info',                       1, True),
>> +    Extension('VK_MESA_query_timestamp',                  1, True),
>>   ]
>>   
>>   class VkVersion:
>> diff --git a/src/intel/Makefile.vulkan.am b/src/intel/Makefile.vulkan.am
>> index 0f0d3815097..d7890022abe 100644
>> --- a/src/intel/Makefile.vulkan.am
>> +++ b/src/intel/Makefile.vulkan.am
>> @@ -24,36 +24,43 @@
>>   # out and we'll fail at `make dist'
>>   vulkan_api_xml = $(top_srcdir)/src/vulkan/registry/vk.xml
>>   vk_android_native_buffer_xml = $(top_srcdir)/src/vulkan/registry/vk_android_native_buffer.xml
>> +vk_mesa_query_timestamp_xml = $(top_srcdir)/src/vulkan/registry/vk_mesa_query_timestamps.xml
>>   
>>   vulkan/anv_entrypoints.c: vulkan/anv_entrypoints_gen.py \
>>                            vulkan/anv_extensions.py \
>>                            $(vulkan_api_xml) \
>> +                         $(vk_mesa_query_timestamp_xml) \
>>                            $(vk_android_native_buffer_xml)
>>          $(MKDIR_GEN)
>>          $(AM_V_GEN)$(PYTHON2) $(srcdir)/vulkan/anv_entrypoints_gen.py \
>>                  --xml $(vulkan_api_xml) \
>>                  --xml $(vk_android_native_buffer_xml) \
>> +               --xml $(vk_mesa_query_timestamp_xml) \
>>                  --outdir $(builddir)/vulkan
>>   vulkan/anv_entrypoints.h: vulkan/anv_entrypoints.c
>>   
>>   vulkan/anv_extensions.c: vulkan/anv_extensions_gen.py \
>>                           vulkan/anv_extensions.py \
>>                           $(vulkan_api_xml) \
>> +                        $(vk_mesa_query_timestamp_xml) \
>>                           $(vk_android_native_buffer_xml)
>>          $(MKDIR_GEN)
>>          $(AM_V_GEN)$(PYTHON2) $(srcdir)/vulkan/anv_extensions_gen.py \
>>                  --xml $(vulkan_api_xml) \
>>                  --xml $(vk_android_native_buffer_xml) \
>> +               --xml $(vk_mesa_query_timestamp_xml) \
>>                  --out-c $@
>>   
>>   vulkan/anv_extensions.h: vulkan/anv_extensions_gen.py \
>>                           vulkan/anv_extensions.py \
>>                           $(vulkan_api_xml) \
>> +                        $(vk_mesa_query_timestamp_xml) \
>>                           $(vk_android_native_buffer_xml)
>>          $(MKDIR_GEN)
>>          $(AM_V_GEN)$(PYTHON2) $(srcdir)/vulkan/anv_extensions_gen.py \
>>                  --xml $(vulkan_api_xml) \
>>                  --xml $(vk_android_native_buffer_xml) \
>> +               --xml $(vk_mesa_query_timestamp_xml) \
>>                  --out-h $@
>>   
>>   BUILT_SOURCES += $(VULKAN_GENERATED_FILES)
>> diff --git a/src/intel/vulkan/anv_extensions.py b/src/intel/vulkan/anv_extensions.py
>> index f44598b305a..dd4d5a1f970 100644
>> --- a/src/intel/vulkan/anv_extensions.py
>> +++ b/src/intel/vulkan/anv_extensions.py
>> @@ -91,6 +91,7 @@ EXTENSIONS = [
>>       Extension('VK_EXT_external_memory_dma_buf',           1, True),
>>       Extension('VK_EXT_display_surface_counter',           1, 'VK_USE_PLATFORM_DISPLAY_KHR'),
>>       Extension('VK_EXT_display_control',                   1, 'VK_USE_PLATFORM_DISPLAY_KHR'),
>> +    Extension('VK_MESA_query_timestamp',                  1, True),
>>   ]
>>   
>>   class VkVersion:
>> diff --git a/src/intel/vulkan/anv_gem.c b/src/intel/vulkan/anv_gem.c
>> index 34c09891086..588b323d113 100644
>> --- a/src/intel/vulkan/anv_gem.c
>> +++ b/src/intel/vulkan/anv_gem.c
>> @@ -418,6 +418,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 1d3e5fcd921..337d8ca3f15 100644
>> --- a/src/intel/vulkan/anv_private.h
>> +++ b/src/intel/vulkan/anv_private.h
>> @@ -932,6 +932,7 @@ bool anv_gem_supports_48b_addresses(int fd);
>>   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,
>> diff --git a/src/intel/vulkan/genX_query.c b/src/intel/vulkan/genX_query.c
>> index 4efcc57e475..d2de7e5f45e 100644
>> --- a/src/intel/vulkan/genX_query.c
>> +++ b/src/intel/vulkan/genX_query.c
>> @@ -546,6 +546,21 @@ void genX(CmdWriteTimestamp)(
>>      }
>>   }
>>   
>> +VkResult genX(QueryCurrentTimestampMESA)(
>> +   VkDevice                                     _device,
>> +   uint64_t                                     *timestamp)
>> +{
>> +   ANV_FROM_HANDLE(anv_device, device, _device);
>> +   int  ret;
>> +
>> +   /* XXX older kernels don't support this interface. */
>> +   ret = anv_gem_reg_read(device, TIMESTAMP | 1, timestamp);
>> +
>> +   if (ret != 0)
>> +      return VK_ERROR_DEVICE_LOST;
>> +   return VK_SUCCESS;
>> +}
>> +
>>   #if GEN_GEN > 7 || GEN_IS_HASWELL
>>   
>>   static uint32_t
>> diff --git a/src/intel/vulkan/meson.build b/src/intel/vulkan/meson.build
>> index d3ab5ac8a64..d4622ffdfdf 100644
>> --- a/src/intel/vulkan/meson.build
>> +++ b/src/intel/vulkan/meson.build
>> @@ -20,11 +20,11 @@
>>   
>>   anv_entrypoints = custom_target(
>>     'anv_entrypoints.[ch]',
>> -  input : ['anv_entrypoints_gen.py', vk_api_xml, vk_android_native_buffer_xml,
>> +  input : ['anv_entrypoints_gen.py', vk_api_xml, vk_android_native_buffer_xml, vk_mesa_query_timestamp_xml,
>>              'anv_extensions.py'],
> Same with this, could you also fix my bad indentation here?
>
>>     output : ['anv_entrypoints.h', 'anv_entrypoints.c'],
>>     command : [
>> -    prog_python2, '@INPUT0@', '--xml', '@INPUT1@', '--xml', '@INPUT2@',
>> +    prog_python2, '@INPUT0@', '--xml', '@INPUT1@', '--xml', '@INPUT2@', '--xml', '@INPUT3@',
>>       '--outdir', meson.current_build_dir(),
>>     ],
>>     depend_files : files('anv_extensions.py'),
>> @@ -32,22 +32,22 @@ anv_entrypoints = custom_target(
>>   
>>   anv_extensions_c = custom_target(
>>     'anv_extensions.c',
>> -  input : ['anv_extensions_gen.py', vk_api_xml, vk_android_native_buffer_xml,
>> +  input : ['anv_extensions_gen.py', vk_api_xml, vk_android_native_buffer_xml, vk_mesa_query_timestamp_xml,
>>              'anv_extensions.py'],
>>     output : 'anv_extensions.c',
>>     command : [
>> -    prog_python2, '@INPUT0@', '--xml', '@INPUT1@', '--xml', '@INPUT2@',
>> +    prog_python2, '@INPUT0@', '--xml', '@INPUT1@', '--xml', '@INPUT2@', '--xml', '@INPUT3@',
>>       '--out-c', '@OUTPUT@',
>>     ],
>>   )
>>   
>>   anv_extensions_h = custom_target(
>>     'anv_extensions.h',
>> -  input : ['anv_extensions_gen.py', vk_api_xml, vk_android_native_buffer_xml,
>> +  input : ['anv_extensions_gen.py', vk_api_xml, vk_android_native_buffer_xml, vk_mesa_query_timestamp_xml,
>>              'anv_extensions.py'],
>>     output : 'anv_extensions.h',
>>     command : [
>> -    prog_python2, '@INPUT0@', '--xml', '@INPUT1@', '--xml', '@INPUT2@',
>> +    prog_python2, '@INPUT0@', '--xml', '@INPUT1@', '--xml', '@INPUT2@', '--xml', '@INPUT3@',
>>       '--out-h', '@OUTPUT@',
>>     ],
>>   )
>> diff --git a/src/vulkan/meson.build b/src/vulkan/meson.build
>> index 3908005b8a0..6ab0966b7c5 100644
>> --- a/src/vulkan/meson.build
>> +++ b/src/vulkan/meson.build
>> @@ -20,6 +20,7 @@
>>   
>>   vk_api_xml = files('registry/vk.xml')
>>   vk_android_native_buffer_xml = files('registry/vk_android_native_buffer.xml')
>> +vk_mesa_query_timestamp_xml = files('registry/vk_mesa_query_timestamp.xml')
>>   
>>   inc_vulkan_util = include_directories('util')
>>   inc_vulkan_wsi = include_directories('wsi')
>> diff --git a/src/vulkan/registry/vk_mesa_query_timestamp.xml b/src/vulkan/registry/vk_mesa_query_timestamp.xml
>> new file mode 100644
>> index 00000000000..7fd4d974872
>> --- /dev/null
>> +++ b/src/vulkan/registry/vk_mesa_query_timestamp.xml
>> @@ -0,0 +1,22 @@
>> +<?xml version="1.0" encoding="UTF-8"?>
>> +<registry>
>> +    <commands>
>> +        <command>
>> +            <proto><type>VkResult</type> <name>vkQueryCurrentTimestampMESA</name></proto>
>> +            <param><type>VkDevice</type> <name>device</name></param>
>> +            <param><type>uint64_t</type>* <name>pTimestamp</name></param>
>> +        </command>
>> +    </commands>
>> +    <extensions>
>> +        <extension name="VK_MESA_query_timestamp" number="200"
>> +                  type="device" author="MESA"
>> +                  contact="Keith Packard @keithp"
>> +                  supported="vulkan">
>> +            <require>
>> +                <enum value="1"                                         name="VK_MESA_QUERY_TIMESTAMP_SPEC_VERSION"/>
>> +                <enum value="&quot;VK_MESA_query_timestamp&quot;"       name="VK_MESA_QUERY_TIMESTAMP_NAME"/>
>> +                <command name="vkQueryCurrentTimestampMESA"/>
>> +            </require>
>> +        </extension>
>> +    </extensions>
>> +</registry>
>> -- 
>> 2.15.1
>>
>> _______________________________________________
>> dri-devel mailing list
>> dri-devel@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/dri-devel
>>
>>
>> _______________________________________________
>> mesa-dev mailing list
>> mesa-dev@lists.freedesktop.org
>> https://lists.freedesktop.org/mailman/listinfo/mesa-dev
Keith Packard Feb. 13, 2018, 9:11 p.m. UTC | #3
Lionel Landwerlin <lionel.g.landwerlin@intel.com> writes:

> I'm assuming the correlation is done outside the vulkan driver? With a 
> clock_gettime() maybe?
>
> If that's the case, I'm afraid this will be highly inaccurate.
> The kernel might execute other tasks when the ioctl() happens and that 
> might introduce (in my experience) a few milliseconds of delay.

Yes, I agree. The trouble is that the window system layer works in one
time base while the rendering layer works in the other, so there's no
one driver which has access to both values, at least in Mesa.

> I think if you want to do something like that, this has to be 
> implemented in the kernel, making sure you disable interruptions while 
> doing the correlation.

That was my thinking originally, until I realized that there wasn't a
single place which knew of the two clocks.

Suggestions are welcome; I just don't know how the rendering driver is
supposed to know what timebase the window system is running in?
diff mbox

Patch

diff --git a/include/vulkan/vulkan.h b/include/vulkan/vulkan.h
index d3e2e246cf3..5523eb7586f 100644
--- a/include/vulkan/vulkan.h
+++ b/include/vulkan/vulkan.h
@@ -7025,6 +7025,12 @@  VKAPI_ATTR VkResult VKAPI_CALL vkGetMemoryHostPointerPropertiesEXT(
     VkMemoryHostPointerPropertiesEXT*           pMemoryHostPointerProperties);
 #endif
 
+typedef VkResult (VKAPI_PTR *PFN_vkQueryCurrentTimestampMESA)(VkDevice device, uint64_t *timestamp);
+
+VKAPI_ATTR VkResult VKAPI_CALL vkQueryCurrentTimestampMESA(
+    VkDevice                                    _device,
+    uint64_t                                    *timestamp);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/Makefile.am b/src/Makefile.am
index 014ffaf3e29..74ff305d7c6 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -68,6 +68,7 @@  endif
 
 EXTRA_DIST += vulkan/registry/vk.xml
 EXTRA_DIST += vulkan/registry/vk_android_native_buffer.xml
+EXTRA_DIST += vulkan/registry/vk_mesa_query_timestamp.xml
 
 if HAVE_AMD_DRIVERS
 SUBDIRS += amd
diff --git a/src/amd/vulkan/Makefile.am b/src/amd/vulkan/Makefile.am
index 94ece06e99e..0626fa2b3b3 100644
--- a/src/amd/vulkan/Makefile.am
+++ b/src/amd/vulkan/Makefile.am
@@ -129,12 +129,14 @@  libvulkan_radeon_la_SOURCES = $(VULKAN_GEM_FILES)
 
 vulkan_api_xml = $(top_srcdir)/src/vulkan/registry/vk.xml
 vk_android_native_buffer_xml = $(top_srcdir)/src/vulkan/registry/vk_android_native_buffer.xml
+vk_mesa_query_timestamp_xml = $(top_srcdir)/src/vulkan/registry/vk_mesa_query_timestamps.xml
 
 radv_entrypoints.c: radv_entrypoints_gen.py radv_extensions.py $(vulkan_api_xml)
 	$(MKDIR_GEN)
 	$(AM_V_GEN)$(PYTHON2) $(srcdir)/radv_entrypoints_gen.py \
 		--xml $(vulkan_api_xml) \
 		--xml $(vk_android_native_buffer_xml) \
+		--xml $(vk_mesa_query_timestamp_xml) \
 		--outdir $(builddir)
 radv_entrypoints.h: radv_entrypoints.c
 
@@ -144,6 +146,7 @@  radv_extensions.c: radv_extensions.py \
 	$(AM_V_GEN)$(PYTHON2) $(srcdir)/radv_extensions.py \
 		--xml $(vulkan_api_xml) \
 		--xml $(vk_android_native_buffer_xml) \
+		--xml $(vk_mesa_query_timestamp_xml) \
 		--out $@
 
 vk_format_table.c: vk_format_table.py \
diff --git a/src/amd/vulkan/meson.build b/src/amd/vulkan/meson.build
index 0b92a1763a1..34f578476c0 100644
--- a/src/amd/vulkan/meson.build
+++ b/src/amd/vulkan/meson.build
@@ -20,10 +20,10 @@ 
 
 radv_entrypoints = custom_target(
   'radv_entrypoints.[ch]',
-  input : ['radv_entrypoints_gen.py', vk_api_xml],
+  input : ['radv_entrypoints_gen.py', vk_api_xml, vk_android_native_buffer_xml, vk_mesa_query_timestamp_xml],
   output : ['radv_entrypoints.h', 'radv_entrypoints.c'],
   command : [
-    prog_python2, '@INPUT0@', '--xml', '@INPUT1@', '--outdir',
+    prog_python2, '@INPUT0@', '--xml', '@INPUT1@', '--xml', '@INPUT2@', '--xml', '@INPUT3@', '--outdir',
     meson.current_build_dir()
   ],
   depend_files : files('radv_extensions.py'),
@@ -31,10 +31,10 @@  radv_entrypoints = custom_target(
 
 radv_extensions_c = custom_target(
   'radv_extensions.c',
-  input : ['radv_extensions.py', vk_api_xml, vk_android_native_buffer_xml],
+  input : ['radv_extensions.py', vk_api_xml, vk_android_native_buffer_xml, vk_mesa_query_timestamp_xml],
   output : ['radv_extensions.c'],
   command : [
-    prog_python2, '@INPUT0@', '--xml', '@INPUT1@', '--xml', '@INPUT2@', '--out', '@OUTPUT@',
+    prog_python2, '@INPUT0@', '--xml', '@INPUT1@', '--xml', '@INPUT2@', '--xml', '@INPUT3@', '--out', '@OUTPUT@',
   ],
 )
 
diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c
index adf33eb35dc..6c13efba9e0 100644
--- a/src/amd/vulkan/radv_device.c
+++ b/src/amd/vulkan/radv_device.c
@@ -4084,3 +4084,11 @@  radv_DebugReportMessageEXT(VkInstance _instance,
 	vk_debug_report(&instance->debug_report_callbacks, flags, objectType,
 	                object, location, messageCode, pLayerPrefix, pMessage);
 }
+
+VkResult radv_QueryCurrentTimestampMESA(VkDevice _device, uint64_t *timestamp)
+{
+	RADV_FROM_HANDLE(radv_device, device, _device);
+
+	*timestamp = device->ws->query_value(device->ws, RADEON_TIMESTAMP);
+	return VK_SUCCESS;
+}
diff --git a/src/amd/vulkan/radv_extensions.py b/src/amd/vulkan/radv_extensions.py
index 775d1ed4be6..fed198df412 100644
--- a/src/amd/vulkan/radv_extensions.py
+++ b/src/amd/vulkan/radv_extensions.py
@@ -95,6 +95,7 @@  EXTENSIONS = [
     Extension('VK_AMD_draw_indirect_count',               1, True),
     Extension('VK_AMD_rasterization_order',               1, 'device->rad_info.chip_class >= VI && device->rad_info.max_se >= 2'),
     Extension('VK_AMD_shader_info',                       1, True),
+    Extension('VK_MESA_query_timestamp',                  1, True),
 ]
 
 class VkVersion:
diff --git a/src/intel/Makefile.vulkan.am b/src/intel/Makefile.vulkan.am
index 0f0d3815097..d7890022abe 100644
--- a/src/intel/Makefile.vulkan.am
+++ b/src/intel/Makefile.vulkan.am
@@ -24,36 +24,43 @@ 
 # out and we'll fail at `make dist'
 vulkan_api_xml = $(top_srcdir)/src/vulkan/registry/vk.xml
 vk_android_native_buffer_xml = $(top_srcdir)/src/vulkan/registry/vk_android_native_buffer.xml
+vk_mesa_query_timestamp_xml = $(top_srcdir)/src/vulkan/registry/vk_mesa_query_timestamps.xml
 
 vulkan/anv_entrypoints.c: vulkan/anv_entrypoints_gen.py \
 			  vulkan/anv_extensions.py \
 			  $(vulkan_api_xml) \
+			  $(vk_mesa_query_timestamp_xml) \
 			  $(vk_android_native_buffer_xml)
 	$(MKDIR_GEN)
 	$(AM_V_GEN)$(PYTHON2) $(srcdir)/vulkan/anv_entrypoints_gen.py \
 		--xml $(vulkan_api_xml) \
 		--xml $(vk_android_native_buffer_xml) \
+		--xml $(vk_mesa_query_timestamp_xml) \
 		--outdir $(builddir)/vulkan
 vulkan/anv_entrypoints.h: vulkan/anv_entrypoints.c
 
 vulkan/anv_extensions.c: vulkan/anv_extensions_gen.py \
 			 vulkan/anv_extensions.py \
 			 $(vulkan_api_xml) \
+			 $(vk_mesa_query_timestamp_xml) \
 			 $(vk_android_native_buffer_xml)
 	$(MKDIR_GEN)
 	$(AM_V_GEN)$(PYTHON2) $(srcdir)/vulkan/anv_extensions_gen.py \
 		--xml $(vulkan_api_xml) \
 		--xml $(vk_android_native_buffer_xml) \
+		--xml $(vk_mesa_query_timestamp_xml) \
 		--out-c $@
 
 vulkan/anv_extensions.h: vulkan/anv_extensions_gen.py \
 			 vulkan/anv_extensions.py \
 			 $(vulkan_api_xml) \
+			 $(vk_mesa_query_timestamp_xml) \
 			 $(vk_android_native_buffer_xml)
 	$(MKDIR_GEN)
 	$(AM_V_GEN)$(PYTHON2) $(srcdir)/vulkan/anv_extensions_gen.py \
 		--xml $(vulkan_api_xml) \
 		--xml $(vk_android_native_buffer_xml) \
+		--xml $(vk_mesa_query_timestamp_xml) \
 		--out-h $@
 
 BUILT_SOURCES += $(VULKAN_GENERATED_FILES)
diff --git a/src/intel/vulkan/anv_extensions.py b/src/intel/vulkan/anv_extensions.py
index f44598b305a..dd4d5a1f970 100644
--- a/src/intel/vulkan/anv_extensions.py
+++ b/src/intel/vulkan/anv_extensions.py
@@ -91,6 +91,7 @@  EXTENSIONS = [
     Extension('VK_EXT_external_memory_dma_buf',           1, True),
     Extension('VK_EXT_display_surface_counter',           1, 'VK_USE_PLATFORM_DISPLAY_KHR'),
     Extension('VK_EXT_display_control',                   1, 'VK_USE_PLATFORM_DISPLAY_KHR'),
+    Extension('VK_MESA_query_timestamp',                  1, True),
 ]
 
 class VkVersion:
diff --git a/src/intel/vulkan/anv_gem.c b/src/intel/vulkan/anv_gem.c
index 34c09891086..588b323d113 100644
--- a/src/intel/vulkan/anv_gem.c
+++ b/src/intel/vulkan/anv_gem.c
@@ -418,6 +418,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 1d3e5fcd921..337d8ca3f15 100644
--- a/src/intel/vulkan/anv_private.h
+++ b/src/intel/vulkan/anv_private.h
@@ -932,6 +932,7 @@  bool anv_gem_supports_48b_addresses(int fd);
 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,
diff --git a/src/intel/vulkan/genX_query.c b/src/intel/vulkan/genX_query.c
index 4efcc57e475..d2de7e5f45e 100644
--- a/src/intel/vulkan/genX_query.c
+++ b/src/intel/vulkan/genX_query.c
@@ -546,6 +546,21 @@  void genX(CmdWriteTimestamp)(
    }
 }
 
+VkResult genX(QueryCurrentTimestampMESA)(
+   VkDevice                                     _device,
+   uint64_t                                     *timestamp)
+{
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   int  ret;
+
+   /* XXX older kernels don't support this interface. */
+   ret = anv_gem_reg_read(device, TIMESTAMP | 1, timestamp);
+
+   if (ret != 0)
+      return VK_ERROR_DEVICE_LOST;
+   return VK_SUCCESS;
+}
+
 #if GEN_GEN > 7 || GEN_IS_HASWELL
 
 static uint32_t
diff --git a/src/intel/vulkan/meson.build b/src/intel/vulkan/meson.build
index d3ab5ac8a64..d4622ffdfdf 100644
--- a/src/intel/vulkan/meson.build
+++ b/src/intel/vulkan/meson.build
@@ -20,11 +20,11 @@ 
 
 anv_entrypoints = custom_target(
   'anv_entrypoints.[ch]',
-  input : ['anv_entrypoints_gen.py', vk_api_xml, vk_android_native_buffer_xml,
+  input : ['anv_entrypoints_gen.py', vk_api_xml, vk_android_native_buffer_xml, vk_mesa_query_timestamp_xml,
            'anv_extensions.py'],
   output : ['anv_entrypoints.h', 'anv_entrypoints.c'],
   command : [
-    prog_python2, '@INPUT0@', '--xml', '@INPUT1@', '--xml', '@INPUT2@',
+    prog_python2, '@INPUT0@', '--xml', '@INPUT1@', '--xml', '@INPUT2@', '--xml', '@INPUT3@',
     '--outdir', meson.current_build_dir(),
   ],
   depend_files : files('anv_extensions.py'),
@@ -32,22 +32,22 @@  anv_entrypoints = custom_target(
 
 anv_extensions_c = custom_target(
   'anv_extensions.c',
-  input : ['anv_extensions_gen.py', vk_api_xml, vk_android_native_buffer_xml,
+  input : ['anv_extensions_gen.py', vk_api_xml, vk_android_native_buffer_xml, vk_mesa_query_timestamp_xml,
            'anv_extensions.py'],
   output : 'anv_extensions.c',
   command : [
-    prog_python2, '@INPUT0@', '--xml', '@INPUT1@', '--xml', '@INPUT2@',
+    prog_python2, '@INPUT0@', '--xml', '@INPUT1@', '--xml', '@INPUT2@', '--xml', '@INPUT3@',
     '--out-c', '@OUTPUT@',
   ],
 )
 
 anv_extensions_h = custom_target(
   'anv_extensions.h',
-  input : ['anv_extensions_gen.py', vk_api_xml, vk_android_native_buffer_xml,
+  input : ['anv_extensions_gen.py', vk_api_xml, vk_android_native_buffer_xml, vk_mesa_query_timestamp_xml,
            'anv_extensions.py'],
   output : 'anv_extensions.h',
   command : [
-    prog_python2, '@INPUT0@', '--xml', '@INPUT1@', '--xml', '@INPUT2@',
+    prog_python2, '@INPUT0@', '--xml', '@INPUT1@', '--xml', '@INPUT2@', '--xml', '@INPUT3@',
     '--out-h', '@OUTPUT@',
   ],
 )
diff --git a/src/vulkan/meson.build b/src/vulkan/meson.build
index 3908005b8a0..6ab0966b7c5 100644
--- a/src/vulkan/meson.build
+++ b/src/vulkan/meson.build
@@ -20,6 +20,7 @@ 
 
 vk_api_xml = files('registry/vk.xml')
 vk_android_native_buffer_xml = files('registry/vk_android_native_buffer.xml')
+vk_mesa_query_timestamp_xml = files('registry/vk_mesa_query_timestamp.xml')
 
 inc_vulkan_util = include_directories('util')
 inc_vulkan_wsi = include_directories('wsi')
diff --git a/src/vulkan/registry/vk_mesa_query_timestamp.xml b/src/vulkan/registry/vk_mesa_query_timestamp.xml
new file mode 100644
index 00000000000..7fd4d974872
--- /dev/null
+++ b/src/vulkan/registry/vk_mesa_query_timestamp.xml
@@ -0,0 +1,22 @@ 
+<?xml version="1.0" encoding="UTF-8"?>
+<registry>
+    <commands>
+        <command>
+            <proto><type>VkResult</type> <name>vkQueryCurrentTimestampMESA</name></proto>
+            <param><type>VkDevice</type> <name>device</name></param>
+            <param><type>uint64_t</type>* <name>pTimestamp</name></param>
+        </command>
+    </commands>
+    <extensions>
+        <extension name="VK_MESA_query_timestamp" number="200"
+		   type="device" author="MESA"
+		   contact="Keith Packard @keithp"
+		   supported="vulkan">
+            <require>
+                <enum value="1"                                         name="VK_MESA_QUERY_TIMESTAMP_SPEC_VERSION"/>
+                <enum value="&quot;VK_MESA_query_timestamp&quot;"       name="VK_MESA_QUERY_TIMESTAMP_NAME"/>
+                <command name="vkQueryCurrentTimestampMESA"/>
+            </require>
+        </extension>
+    </extensions>
+</registry>