diff options
| author | 2016-12-29 11:07:26 -0700 | |
|---|---|---|
| committer | 2017-01-09 09:26:43 -0700 | |
| commit | 4c8bb2a95d7849c79dea889f1be59281f4e374bf (patch) | |
| tree | fb3f78bfb6a3945cbd5067f935aadc1ba11101c4 | |
| parent | 4b002d8fceb8129cb398c63d437324ed36db385d (diff) | |
Stubbed implementation of VK_GOOGLE_display_timing extension.
This provides the header changes and most of the "boilerplate" changes to add
the VK_GOOGLE_display_timing extension to Vulkan. Future changes will modify
and integrate with the Surface, FrameEvents, and SurfaceFlinger code.
Test: Manually tested that existing apps won't tickle the new-extension paths.
Change-Id: Iec46b1cab4b2561702ebac9a4ae7587584793192
| -rw-r--r-- | vulkan/api/vulkan.api | 69 | ||||
| -rw-r--r-- | vulkan/include/vulkan/vulkan.h | 47 | ||||
| -rw-r--r-- | vulkan/libvulkan/api_gen.cpp | 10 | ||||
| -rw-r--r-- | vulkan/libvulkan/api_gen.h | 2 | ||||
| -rw-r--r-- | vulkan/libvulkan/code-generator.tmpl | 3 | ||||
| -rw-r--r-- | vulkan/libvulkan/driver_gen.cpp | 33 | ||||
| -rw-r--r-- | vulkan/libvulkan/driver_gen.h | 1 | ||||
| -rw-r--r-- | vulkan/libvulkan/swapchain.cpp | 80 | ||||
| -rw-r--r-- | vulkan/libvulkan/swapchain.h | 2 |
9 files changed, 242 insertions, 5 deletions
diff --git a/vulkan/api/vulkan.api b/vulkan/api/vulkan.api index 1264a4e56c..ed89fc6241 100644 --- a/vulkan/api/vulkan.api +++ b/vulkan/api/vulkan.api @@ -81,6 +81,9 @@ define NULL_HANDLE 0 @extension("VK_ANDROID_native_buffer") define VK_ANDROID_NATIVE_BUFFER_SPEC_VERSION 6 @extension("VK_ANDROID_native_buffer") define VK_ANDROID_NATIVE_BUFFER_NAME "VK_ANDROID_native_buffer" +@extension("VK_GOOGLE_display_timing") define VK_GOOGLE_DISPLAY_TIMING_SPEC_VERSION 1 +@extension("VK_GOOGLE_display_timing") define VK_GOOGLE_DISPLAY_TIMING_NAME "VK_GOOGLE_display_timing" + @extension("VK_EXT_debug_report") define VK_EXT_DEBUG_REPORT_SPEC_VERSION 4 @extension("VK_EXT_debug_report") define VK_EXT_DEBUG_REPORT_NAME "VK_EXT_debug_report" @@ -753,6 +756,9 @@ enum VkStructureType { VK_STRUCTURE_TYPE_NATIVE_BUFFER_ANDROID = 1000010000, VK_STRUCTURE_TYPE_SWAPCHAIN_IMAGE_CREATE_INFO_ANDROID = 1000010001, + //@extension("VK_GOOGLE_display_timing") + VK_STRUCTURE_TYPE_PRESENT_TIMES_GOOGLE = 1000092000, + //@extension("VK_EXT_debug_report") VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT = 1000011000, @@ -2916,6 +2922,34 @@ class VkSwapchainImageCreateInfoANDROID { VkStructureType sType const void* pNext VkSwapchainImageUsageFlagBitsANDROID flags + +@extension("VK_GOOGLE_display_timing") +class VkRefreshCycleDurationGOOGLE { + uint64_t minRefreshDuration + uint64_t maxRefreshDuration +} + +@extension("VK_GOOGLE_display_timing") +class VkPastPresentationTimingGOOGLE { + uint32_t presentID + uint64_t desiredPresentTime + uint64_t actualPresentTime + uint64_t earliestPresentTime + uint64_t presentMargin +} + +@extension("VK_GOOGLE_display_timing") +class VkPresentTimeGOOGLE { + uint32_t presentID + uint64_t desiredPresentTime +} + +@extension("VK_GOOGLE_display_timing") +class VkPresentTimesInfoGOOGLE { + VkStructureType sType + const void* pNext + uint32_t swapchainCount + const VkPresentTimeGOOGLE* pTimes } @extension("VK_EXT_debug_report") @@ -5835,6 +5869,41 @@ cmd VkResult vkQueueSignalReleaseImageANDROID( return ? } +@extension("VK_GOOGLE_display_timing") +cmd VkResult vkGetRefreshCycleDurationGOOGLE( + VkDevice device, + VkSwapchainKHR swapchain, + VkRefreshCycleDurationGOOGLE* pDisplayTimingProperties) { + deviceObject := GetDevice(device) + swapchainObject := GetSwapchain(swapchain) + + displayTimingProperties := ? + pDisplayTimingProperties[0] = displayTimingProperties + + return ? +} + +@extension("VK_GOOGLE_display_timing") +cmd VkResult vkGetPastPresentationTimingGOOGLE( + VkDevice device, + VkSwapchainKHR swapchain, + u32* pPresentationTimingCount, + VkPastPresentationTimingGOOGLE* pPresentationTimings) { + deviceObject := GetDevice(device) + + count := as!u32(?) + pPresentationTimingCount[0] = count + presentationTimings := pPresentationTimings[0:count] + + for i in (0 .. count) { + presentationTiming := ? + presentationTimings[i] = presentationTiming + State.Timings[presentationTiming] = new!PresentationTiming(device: device) + } + + return ? +} + @extension("VK_EXT_debug_report") @external type void* PFN_vkDebugReportCallbackEXT @extension("VK_EXT_debug_report") diff --git a/vulkan/include/vulkan/vulkan.h b/vulkan/include/vulkan/vulkan.h index 6a02b9b9bc..6ddce8ff84 100644 --- a/vulkan/include/vulkan/vulkan.h +++ b/vulkan/include/vulkan/vulkan.h @@ -242,6 +242,7 @@ typedef enum VkStructureType { VK_STRUCTURE_TYPE_CMD_RESERVE_SPACE_FOR_COMMANDS_INFO_NVX = 1000086003, VK_STRUCTURE_TYPE_DEVICE_GENERATED_COMMANDS_LIMITS_NVX = 1000086004, VK_STRUCTURE_TYPE_DEVICE_GENERATED_COMMANDS_FEATURES_NVX = 1000086005, + VK_STRUCTURE_TYPE_PRESENT_TIMES_GOOGLE = 1000092000, VK_STRUCTURE_TYPE_BEGIN_RANGE = VK_STRUCTURE_TYPE_APPLICATION_INFO, VK_STRUCTURE_TYPE_END_RANGE = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO, VK_STRUCTURE_TYPE_RANGE_SIZE = (VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO - VK_STRUCTURE_TYPE_APPLICATION_INFO + 1), @@ -4126,6 +4127,52 @@ typedef struct VkDedicatedAllocationMemoryAllocateInfoNV { } VkDedicatedAllocationMemoryAllocateInfoNV; +#define VK_GOOGLE_display_timing 1 +#define VK_GOOGLE_DISPLAY_TIMING_SPEC_VERSION 1 +#define VK_GOOGLE_DISPLAY_TIMING_EXTENSION_NAME "VK_GOOGLE_display_timing" + +typedef struct VkRefreshCycleDurationGOOGLE { + uint64_t minRefreshDuration; + uint64_t maxRefreshDuration; +} VkRefreshCycleDurationGOOGLE; + +typedef struct VkPastPresentationTimingGOOGLE { + uint32_t presentID; + uint64_t desiredPresentTime; + uint64_t actualPresentTime; + uint64_t earliestPresentTime; + uint64_t presentMargin; +} VkPastPresentationTimingGOOGLE; + +typedef struct VkPresentTimeGOOGLE { + uint32_t presentID; + uint64_t desiredPresentTime; +} VkPresentTimeGOOGLE; + +typedef struct VkPresentTimesInfoGOOGLE { + VkStructureType sType; + const void* pNext; + uint32_t swapchainCount; + const VkPresentTimeGOOGLE* pTimes; +} VkPresentTimesInfoGOOGLE; + + +typedef VkResult (VKAPI_PTR *PFN_vkGetRefreshCycleDurationGOOGLE)(VkDevice device, VkSwapchainKHR swapchain, VkRefreshCycleDurationGOOGLE* pDisplayTimingProperties); +typedef VkResult (VKAPI_PTR *PFN_vkGetPastPresentationTimingGOOGLE)(VkDevice device, VkSwapchainKHR swapchain, uint32_t* pPresentationTimingCount, VkPastPresentationTimingGOOGLE* pPresentationTimings); + +#ifndef VK_NO_PROTOTYPES +VKAPI_ATTR VkResult VKAPI_CALL vkGetRefreshCycleDurationGOOGLE( + VkDevice device, + VkSwapchainKHR swapchain, + VkRefreshCycleDurationGOOGLE* pDisplayTimingProperties); + +VKAPI_ATTR VkResult VKAPI_CALL vkGetPastPresentationTimingGOOGLE( + VkDevice device, + VkSwapchainKHR swapchain, + uint32_t* pPresentationTimingCount, + VkPastPresentationTimingGOOGLE* pPresentationTimings); +#endif + #define VK_AMD_draw_indirect_count 1 #define VK_AMD_DRAW_INDIRECT_COUNT_SPEC_VERSION 1 diff --git a/vulkan/libvulkan/api_gen.cpp b/vulkan/libvulkan/api_gen.cpp index ca2a579b64..b4e256a8e8 100644 --- a/vulkan/libvulkan/api_gen.cpp +++ b/vulkan/libvulkan/api_gen.cpp @@ -425,6 +425,8 @@ VKAPI_ATTR VkResult GetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapch VKAPI_ATTR VkResult AcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t* pImageIndex); VKAPI_ATTR VkResult QueuePresentKHR(VkQueue queue, const VkPresentInfoKHR* pPresentInfo); VKAPI_ATTR VkResult CreateAndroidSurfaceKHR(VkInstance instance, const VkAndroidSurfaceCreateInfoKHR* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface); +VKAPI_ATTR VkResult GetRefreshCycleDurationGOOGLE(VkDevice device, VkSwapchainKHR swapchain, VkRefreshCycleDurationGOOGLE* pDisplayTimingProperties); +VKAPI_ATTR VkResult GetPastPresentationTimingGOOGLE(VkDevice device, VkSwapchainKHR swapchain, uint32_t* pPresentationTimingCount, VkPastPresentationTimingGOOGLE* pPresentationTimings); VKAPI_ATTR VkResult EnumeratePhysicalDevices(VkInstance instance, uint32_t* pPhysicalDeviceCount, VkPhysicalDevice* pPhysicalDevices) { return GetData(instance).dispatch.EnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices); @@ -1208,6 +1210,14 @@ VKAPI_ATTR VkResult CreateAndroidSurfaceKHR(VkInstance instance, const VkAndroid return GetData(instance).dispatch.CreateAndroidSurfaceKHR(instance, pCreateInfo, pAllocator, pSurface); } +VKAPI_ATTR VkResult GetRefreshCycleDurationGOOGLE(VkDevice device, VkSwapchainKHR swapchain, VkRefreshCycleDurationGOOGLE* pDisplayTimingProperties) { + return GetData(device).dispatch.GetRefreshCycleDurationGOOGLE(device, swapchain, pDisplayTimingProperties); +} + +VKAPI_ATTR VkResult GetPastPresentationTimingGOOGLE(VkDevice device, VkSwapchainKHR swapchain, uint32_t* pPresentationTimingCount, VkPastPresentationTimingGOOGLE* pPresentationTimings) { + return GetData(device).dispatch.GetPastPresentationTimingGOOGLE(device, swapchain, pPresentationTimingCount, pPresentationTimings); +} + } // anonymous namespace diff --git a/vulkan/libvulkan/api_gen.h b/vulkan/libvulkan/api_gen.h index 7f8d274b60..918c1f5e07 100644 --- a/vulkan/libvulkan/api_gen.h +++ b/vulkan/libvulkan/api_gen.h @@ -177,6 +177,8 @@ struct DeviceDispatchTable { PFN_vkGetSwapchainImagesKHR GetSwapchainImagesKHR; PFN_vkAcquireNextImageKHR AcquireNextImageKHR; PFN_vkQueuePresentKHR QueuePresentKHR; + PFN_vkGetRefreshCycleDurationGOOGLE GetRefreshCycleDurationGOOGLE; + PFN_vkGetPastPresentationTimingGOOGLE GetPastPresentationTimingGOOGLE; // clang-format on }; diff --git a/vulkan/libvulkan/code-generator.tmpl b/vulkan/libvulkan/code-generator.tmpl index b27b36c2b3..2c70d465cc 100644 --- a/vulkan/libvulkan/code-generator.tmpl +++ b/vulkan/libvulkan/code-generator.tmpl @@ -700,6 +700,8 @@ VK_KHR_android_surface VK_KHR_incremental_present VK_KHR_surface VK_KHR_swapchain +VK_KHR_incremental_present +VK_GOOGLE_display_timing {{end}} @@ -1147,6 +1149,7 @@ VK_KHR_swapchain {{else if eq $ext "VK_KHR_swapchain"}}true {{else if eq $ext "VK_KHR_android_surface"}}true {{else if eq $ext "VK_KHR_incremental_present"}}true + {{else if eq $ext "VK_GOOGLE_display_timing"}}true {{end}} {{end}} diff --git a/vulkan/libvulkan/driver_gen.cpp b/vulkan/libvulkan/driver_gen.cpp index c59ba2488b..e27b3d17ca 100644 --- a/vulkan/libvulkan/driver_gen.cpp +++ b/vulkan/libvulkan/driver_gen.cpp @@ -73,6 +73,24 @@ VKAPI_ATTR VkResult checkedQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR } } +VKAPI_ATTR VkResult checkedGetRefreshCycleDurationGOOGLE(VkDevice device, VkSwapchainKHR swapchain, VkRefreshCycleDurationGOOGLE* pDisplayTimingProperties) { + if (GetData(device).hook_extensions[ProcHook::GOOGLE_display_timing]) { + return GetRefreshCycleDurationGOOGLE(device, swapchain, pDisplayTimingProperties); + } else { + Logger(device).Err(device, "VK_GOOGLE_display_timing not enabled. vkGetRefreshCycleDurationGOOGLE not executed."); + return VK_SUCCESS; + } +} + +VKAPI_ATTR VkResult checkedGetPastPresentationTimingGOOGLE(VkDevice device, VkSwapchainKHR swapchain, uint32_t* pPresentationTimingCount, VkPastPresentationTimingGOOGLE* pPresentationTimings) { + if (GetData(device).hook_extensions[ProcHook::GOOGLE_display_timing]) { + return GetPastPresentationTimingGOOGLE(device, swapchain, pPresentationTimingCount, pPresentationTimings); + } else { + Logger(device).Err(device, "VK_GOOGLE_display_timing not enabled. vkGetPastPresentationTimingGOOGLE not executed."); + return VK_SUCCESS; + } +} + // clang-format on const ProcHook g_proc_hooks[] = { @@ -218,6 +236,13 @@ const ProcHook g_proc_hooks[] = { nullptr, }, { + "vkGetPastPresentationTimingGOOGLE", + ProcHook::DEVICE, + ProcHook::GOOGLE_display_timing, + reinterpret_cast<PFN_vkVoidFunction>(GetPastPresentationTimingGOOGLE), + reinterpret_cast<PFN_vkVoidFunction>(checkedGetPastPresentationTimingGOOGLE), + }, + { "vkGetPhysicalDeviceSurfaceCapabilitiesKHR", ProcHook::INSTANCE, ProcHook::KHR_surface, @@ -246,6 +271,13 @@ const ProcHook g_proc_hooks[] = { nullptr, }, { + "vkGetRefreshCycleDurationGOOGLE", + ProcHook::DEVICE, + ProcHook::GOOGLE_display_timing, + reinterpret_cast<PFN_vkVoidFunction>(GetRefreshCycleDurationGOOGLE), + reinterpret_cast<PFN_vkVoidFunction>(checkedGetRefreshCycleDurationGOOGLE), + }, + { "vkGetSwapchainGrallocUsage2ANDROID", ProcHook::DEVICE, ProcHook::ANDROID_native_buffer, @@ -302,6 +334,7 @@ ProcHook::Extension GetProcHookExtension(const char* name) { if (strcmp(name, "VK_KHR_android_surface") == 0) return ProcHook::KHR_android_surface; if (strcmp(name, "VK_KHR_surface") == 0) return ProcHook::KHR_surface; if (strcmp(name, "VK_KHR_swapchain") == 0) return ProcHook::KHR_swapchain; + if (strcmp(name, "VK_GOOGLE_display_timing") == 0) return ProcHook::GOOGLE_display_timing; // clang-format on return ProcHook::EXTENSION_UNKNOWN; } diff --git a/vulkan/libvulkan/driver_gen.h b/vulkan/libvulkan/driver_gen.h index 0228ef252d..167f88cc3b 100644 --- a/vulkan/libvulkan/driver_gen.h +++ b/vulkan/libvulkan/driver_gen.h @@ -38,6 +38,7 @@ struct ProcHook { KHR_android_surface, KHR_surface, KHR_swapchain, + GOOGLE_display_timing, EXTENSION_CORE, // valid bit EXTENSION_COUNT, diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp index 3e87abf3c8..807b81a8ed 100644 --- a/vulkan/libvulkan/swapchain.cpp +++ b/vulkan/libvulkan/swapchain.cpp @@ -122,10 +122,13 @@ Surface* SurfaceFromHandle(VkSurfaceKHR handle) { struct Swapchain { Swapchain(Surface& surface_, uint32_t num_images_) - : surface(surface_), num_images(num_images_) {} + : surface(surface_), + num_images(num_images_), + frame_timestamps_enabled(false) {} Surface& surface; uint32_t num_images; + bool frame_timestamps_enabled; struct Image { Image() : image(VK_NULL_HANDLE), dequeue_fence(-1), dequeued(false) {} @@ -728,6 +731,9 @@ void DestroySwapchainKHR(VkDevice device, bool active = swapchain->surface.swapchain_handle == swapchain_handle; ANativeWindow* window = active ? swapchain->surface.window.get() : nullptr; + if (swapchain->frame_timestamps_enabled) { + native_window_enable_frame_timestamps(window, false); + } for (uint32_t i = 0; i < swapchain->num_images; i++) ReleaseSwapchainImage(device, window, -1, swapchain->images[i]); if (active) @@ -868,7 +874,8 @@ VkResult QueuePresentKHR(VkQueue queue, const VkPresentInfoKHR* present_info) { VkResult final_result = VK_SUCCESS; // Look at the pNext chain for supported extension structs: - const VkPresentRegionsKHR* present_regions = NULL; + const VkPresentRegionsKHR* present_regions = nullptr; + const VkPresentTimesInfoGOOGLE* present_times = nullptr; const VkPresentRegionsKHR* next = reinterpret_cast<const VkPresentRegionsKHR*>(present_info->pNext); while (next) { @@ -876,6 +883,10 @@ VkResult QueuePresentKHR(VkQueue queue, const VkPresentInfoKHR* present_info) { case VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR: present_regions = next; break; + case VK_STRUCTURE_TYPE_PRESENT_TIMES_GOOGLE: + present_times = + reinterpret_cast<const VkPresentTimesInfoGOOGLE*>(next); + break; default: ALOGV("QueuePresentKHR ignoring unrecognized pNext->sType = %x", next->sType); @@ -887,10 +898,16 @@ VkResult QueuePresentKHR(VkQueue queue, const VkPresentInfoKHR* present_info) { present_regions && present_regions->swapchainCount != present_info->swapchainCount, "VkPresentRegions::swapchainCount != VkPresentInfo::swapchainCount"); + ALOGV_IF(present_times && + present_times->swapchainCount != present_info->swapchainCount, + "VkPresentTimesInfoGOOGLE::swapchainCount != " + "VkPresentInfo::swapchainCount"); const VkPresentRegionKHR* regions = - (present_regions) ? present_regions->pRegions : NULL; + (present_regions) ? present_regions->pRegions : nullptr; + const VkPresentTimeGOOGLE* times = + (present_times) ? present_times->pTimes : nullptr; const VkAllocationCallbacks* allocator = &GetData(device).allocator; - android_native_rect_t* rects = NULL; + android_native_rect_t* rects = nullptr; uint32_t nrects = 0; for (uint32_t sc = 0; sc < present_info->swapchainCount; sc++) { @@ -898,7 +915,8 @@ VkResult QueuePresentKHR(VkQueue queue, const VkPresentInfoKHR* present_info) { *SwapchainFromHandle(present_info->pSwapchains[sc]); uint32_t image_idx = present_info->pImageIndices[sc]; Swapchain::Image& img = swapchain.images[image_idx]; - const VkPresentRegionKHR* region = (regions) ? ®ions[sc] : NULL; + const VkPresentRegionKHR* region = (regions) ? ®ions[sc] : nullptr; + const VkPresentTimeGOOGLE* time = (times) ? ×[sc] : nullptr; VkResult swapchain_result = VK_SUCCESS; VkResult result; int err; @@ -955,6 +973,19 @@ VkResult QueuePresentKHR(VkQueue queue, const VkPresentInfoKHR* present_info) { } native_window_set_surface_damage(window, rects, rcount); } + if (time) { + if (!swapchain.frame_timestamps_enabled) { + native_window_enable_frame_timestamps(window, true); + swapchain.frame_timestamps_enabled = true; + } + // TODO(ianelliott): need to store the presentID (and + // desiredPresentTime), so it can be later correlated to + // this present. Probably modify the following function + // (and below) to plumb a path to store it in FrameEvents + // code, on the producer side. + native_window_set_buffers_timestamp( + window, static_cast<int64_t>(time->desiredPresentTime)); + } err = window->queueBuffer(window, img.buffer.get(), fence); // queueBuffer always closes fence, even on error if (err != 0) { @@ -992,5 +1023,44 @@ VkResult QueuePresentKHR(VkQueue queue, const VkPresentInfoKHR* present_info) { return final_result; } +VKAPI_ATTR +VkResult GetRefreshCycleDurationGOOGLE( + VkDevice, + VkSwapchainKHR, + VkRefreshCycleDurationGOOGLE* pDisplayTimingProperties) { + VkResult result = VK_SUCCESS; + + // TODO(ianelliott): FULLY IMPLEMENT THIS FUNCTION!!! + pDisplayTimingProperties->minRefreshDuration = 16666666666; + pDisplayTimingProperties->maxRefreshDuration = 16666666666; + + return result; +} + +VKAPI_ATTR +VkResult GetPastPresentationTimingGOOGLE( + VkDevice, + VkSwapchainKHR swapchain_handle, + uint32_t* count, + VkPastPresentationTimingGOOGLE* timings) { + Swapchain& swapchain = *SwapchainFromHandle(swapchain_handle); + ANativeWindow* window = swapchain.surface.window.get(); + VkResult result = VK_SUCCESS; + + if (!swapchain.frame_timestamps_enabled) { + native_window_enable_frame_timestamps(window, true); + swapchain.frame_timestamps_enabled = true; + } + + // TODO(ianelliott): FULLY IMPLEMENT THIS FUNCTION!!! + if (timings) { + *count = 0; + } else { + *count = 0; + } + + return result; +} + } // namespace driver } // namespace vulkan diff --git a/vulkan/libvulkan/swapchain.h b/vulkan/libvulkan/swapchain.h index 2c60c496c4..8aac427b7f 100644 --- a/vulkan/libvulkan/swapchain.h +++ b/vulkan/libvulkan/swapchain.h @@ -34,6 +34,8 @@ VKAPI_ATTR void DestroySwapchainKHR(VkDevice device, VkSwapchainKHR swapchain_ha VKAPI_ATTR VkResult GetSwapchainImagesKHR(VkDevice device, VkSwapchainKHR swapchain_handle, uint32_t* count, VkImage* images); VKAPI_ATTR VkResult AcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain_handle, uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t* image_index); VKAPI_ATTR VkResult QueuePresentKHR(VkQueue queue, const VkPresentInfoKHR* present_info); +VKAPI_ATTR VkResult GetRefreshCycleDurationGOOGLE(VkDevice device, VkSwapchainKHR swapchain, VkRefreshCycleDurationGOOGLE* pDisplayTimingProperties); +VKAPI_ATTR VkResult GetPastPresentationTimingGOOGLE(VkDevice device, VkSwapchainKHR swapchain, uint32_t* pPresentationTimingCount, VkPastPresentationTimingGOOGLE* pPresentationTimings); // clang-format on } // namespace driver |