vulkan: Add VK_GOOGLE_display_timing extension (x11+display, anv+radv) [v7]
PATCH 1/1 vulkan: Add VK_GOOGLE_display_timing extension (x11+display, anv+radv) [v7]
This adds support for the VK_GOOGLE_display timing extension, which provides two things:
1) Detailed information about when frames are displayed, including slack time between GPU execution and display frame.
2) Absolute time control over swapchain queue processing. This allows the application to request frames be displayed at specific absolute times, using the same timebase as that provided in vblank events.
Support for this extension has been implemented for the x11 and display backends; adding support to other backends should be reasonable straightforward for one familiar with those systems and should not require any additional device-specific code.
v2:
Adjust GOOGLE_display_timing earliest value. The earliestPresentTime for an image cannot be before the previous image was displayed, or even a frame later (in FIFO mode).
Make GOOGLE_display_timing use render completed time. Switch from VK_PIPELINE_TOP_OF_PIPE_BIT to VK_PIPELINE_STAGE_ALL_COMMANDS_BIT so that the time reported to applications as the end of rendering reflects the latest possible value to ensure that applications don't underestimate the amount of work done in the frame.
v3:
Adopt Jason Ekstrand's coding conventions. Declare variables at first use, eliminate extra whitespace between types and names. Wrap lines to 80 columns.
v4:
Adapt to changes in MESA_query_timestamp extension
v5:
Squash core bits and anv/radv wrappers into a single patch
v6:
Switch from MESA_query_timestamp to EXT_calibrated_timestamps
v7:
Ensure we target frame no earlier than desired. This means rounding the target frame up, rather than selecting the nearest one.
--- src/amd/vulkan/radv_extensions.py | 1 + src/amd/vulkan/radv_wsi.c | 33 +++ src/intel/vulkan/anv_extensions.py | 1 + src/intel/vulkan/anv_wsi.c | 33 +++ src/vulkan/wsi/wsi_common.c | 303 +++++++++++++++++++++++++++- src/vulkan/wsi/wsi_common.h | 32 +++ src/vulkan/wsi/wsi_common_display.c | 165 ++++++++++++++- src/vulkan/wsi/wsi_common_private.h | 35 ++++ src/vulkan/wsi/wsi_common_x11.c | 71 ++++++- 9 files changed, 662 insertions(+), 12 deletions(-)
src/amd/vulkan/radv_extensions.py +1 -0
@@ -119,6 +119,7 @@ EXTENSIONS = [ Extension('VK_AMD_shader_trinary_minmax', 1, True), Extension('VK_GOOGLE_decorate_string', 1, True), Extension('VK_GOOGLE_hlsl_functionality1', 1, True), + Extension('VK_GOOGLE_display_timing', 1, True), ] class VkVersion:
src/amd/vulkan/radv_wsi.c +33 -0
@@ -295,3 +295,36 @@ VkResult radv_GetPhysicalDevicePresentRectanglesKHR( surface, pRectCount, pRects); } + +/* VK_GOOGLE_display_timing */ +VkResult +radv_GetRefreshCycleDurationGOOGLE ( +VkDevice _device, +VkSwapchainKHR swapchain, +VkRefreshCycleDurationGOOGLE *pDisplayTimingProperties) +{ +RADV_FROM_HANDLE (radv_device, device, _device); +struct radv_physical_device *pdevice = device->physical_device; + +return wsi_common_get_refresh_cycle_duration (&pdevice->wsi_device, + _device, + swapchain, + pDisplayTimingProperties); +} + +VkResult +radv_GetPastPresentationTimingGOOGLE (VkDevice _device, +VkSwapchainKHR swapchain, +uint32_t *pPresentationTimingCount, +VkPastPresentationTimingGOOGLE + *pPresentationTimings) +{ +RADV_FROM_HANDLE (radv_device, device, _device); +struct radv_physical_device *pdevice = device->physical_device; + +return wsi_common_get_past_presentation_timing (&pdevice->wsi_device, + _device, + swapchain, + pPresentationTimingCount, + pPresentationTimings); +}
src/intel/vulkan/anv_extensions.py +1 -0
@@ -130,6 +130,7 @@ EXTENSIONS = [ Extension('VK_EXT_calibrated_timestamps', 1, True), Extension('VK_GOOGLE_decorate_string', 1, True), Extension('VK_GOOGLE_hlsl_functionality1', 1, True), + Extension('VK_GOOGLE_display_timing', 1, True), ] class VkVersion:
src/intel/vulkan/anv_wsi.c +33 -0
@@ -305,3 +305,36 @@ VkResult anv_GetPhysicalDevicePresentRectanglesKHR( surface, pRectCount, pRects); } + +/* VK_GOOGLE_display_timing */ +VkResult +anv_GetRefreshCycleDurationGOOGLE (VkDevice _device, +VkSwapchainKHR swapchain, +VkRefreshCycleDurationGOOGLE + *pDisplayTimingProperties) +{ +ANV_FROM_HANDLE (anv_device, device, _device); + +return wsi_common_get_refresh_cycle_duration (&device->instance-> + physicalDevice.wsi_device, + _device, + swapchain, + pDisplayTimingProperties); +} + +VkResult +anv_GetPastPresentationTimingGOOGLE (VkDevice _device, +VkSwapchainKHR swapchain, +uint32_t *pPresentationTimingCount, +VkPastPresentationTimingGOOGLE + *pPresentationTimings) +{ +ANV_FROM_HANDLE (anv_device, device, _device); + +return wsi_common_get_past_presentation_timing (&device->instance-> + physicalDevice.wsi_device, + _device, + swapchain, + pPresentationTimingCount, + pPresentationTimings); +}
src/vulkan/wsi/wsi_common.c +300 -3
397 lines not on this page · raw message
src/vulkan/wsi/wsi_common.h +32 -0
@@ -96,6 +96,7 @@ struct wsi_device {VkPhysicalDevice pdevice;VkPhysicalDeviceMemoryProperties memory_props;uint32_t queue_family_count; +float timestamp_period;VkPhysicalDevicePCIBusInfoPropertiesEXT pci_bus_info;
@@ -109,14 +110,18 @@ struct wsi_device {WSI_CB (BindImageMemory);WSI_CB (BeginCommandBuffer);WSI_CB (CmdCopyImageToBuffer); +WSI_CB (CmdResetQueryPool); +WSI_CB (CmdWriteTimestamp);WSI_CB (CreateBuffer);WSI_CB (CreateCommandPool);WSI_CB (CreateFence);WSI_CB (CreateImage); +WSI_CB (CreateQueryPool);WSI_CB (DestroyBuffer);WSI_CB (DestroyCommandPool);WSI_CB (DestroyFence);WSI_CB (DestroyImage); +WSI_CB (DestroyQueryPool);WSI_CB (EndCommandBuffer);WSI_CB (FreeMemory);WSI_CB (FreeCommandBuffers);
@@ -124,10 +129,14 @@ struct wsi_device {WSI_CB (GetImageMemoryRequirements);WSI_CB (GetImageSubresourceLayout);WSI_CB (GetMemoryFdKHR); +WSI_CB (GetPhysicalDeviceProperties);WSI_CB (GetPhysicalDeviceFormatProperties);WSI_CB (GetPhysicalDeviceFormatProperties2KHR); +WSI_CB (GetPhysicalDeviceQueueFamilyProperties); +WSI_CB (GetQueryPoolResults);WSI_CB (ResetFences);WSI_CB (QueueSubmit); +WSI_CB (GetCalibratedTimestampsEXT);WSI_CB (WaitForFences);#undef WSI_CB
@@ -241,4 +250,27 @@ wsi_common_queue_present(const struct wsi_device *wsi,int queue_family_index, const VkPresentInfoKHR *pPresentInfo); +VkResult +wsi_common_convert_timestamp (const struct wsi_device *wsi, +VkDevice device_h, +VkSurfaceKHR surface_h, +uint64_t monotonic_timestamp, +uint64_t *surface_timestamp); + +/* VK_GOOGLE_display_timing */ +VkResult +wsi_common_get_refresh_cycle_duration (const struct wsi_device *wsi, +VkDevice device_h, +VkSwapchainKHR swapchain, +VkRefreshCycleDurationGOOGLE + *pDisplayTimingProperties); + +VkResult +wsi_common_get_past_presentation_timing (const struct wsi_device *wsi, +VkDevice device_h, +VkSwapchainKHR swapchain, +uint32_t *pPresentationTimingCount, +VkPastPresentationTimingGOOGLE + *pPresentationTimings); +#endif
src/vulkan/wsi/wsi_common_display.c +159 -6
295 lines not on this page · raw message
src/vulkan/wsi/wsi_common_private.h +35 -0
@@ -25,6 +25,13 @@#include "wsi_common.h" +struct wsi_timing { +bool complete; +bool consumed; +uint64_t target_msc; +VkPastPresentationTimingGOOGLE timing; +}; +struct wsi_image {VkImage image;VkDeviceMemory memory;
@@ -41,8 +48,16 @@ struct wsi_image {uint32_t offsets[4 ];uint32_t row_pitches[4 ];int fds[4 ]; + +VkQueryPool query_pool; + +VkCommandBuffer timestamp_buffer; + +struct wsi_timing *timing; }; +#define WSI_TIMING_HISTORY 16 +struct wsi_swapchain {const struct wsi_device *wsi;
@@ -54,6 +69,16 @@ struct wsi_swapchain {bool use_prime_blit; +uint32_t timing_insert; +uint32_t timing_count; + +struct wsi_timing timing[WSI_TIMING_HISTORY ]; + +uint64_t frame_msc; +uint64_t frame_ust; + +float timestamp_period; +/* Command pools, one per queue family */ VkCommandPool *cmd_pools;
@@ -67,6 +92,10 @@ struct wsi_swapchain {VkResult (*queue_present)(struct wsi_swapchain *swap_chain,uint32_t image_index,const VkPresentRegionKHR *damage); +VkResult (*get_refresh_cycle_duration)(struct wsi_swapchain *swap_chain, +VkRefreshCycleDurationGOOGLE + *pDisplayTimingProperties); + };bool
@@ -100,6 +129,12 @@ wsi_destroy_image(const struct wsi_swapchain *chain, struct wsi_image *image); +void +wsi_mark_timing (struct wsi_swapchain *swapchain, +struct wsi_image *image, +uint64_t ust, +uint64_t msc); +struct wsi_interface { VkResult (*get_support)(VkIcdSurfaceBase *surface, struct wsi_device *wsi_device,
src/vulkan/wsi/wsi_common_x11.c +68 -3
136 lines not on this page · raw message
Signature · 7 lines
2.19.1 _______________________________________________ dri-devel mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/dri-devel