diff --git a/layer/layer.cpp b/layer/layer.cpp index ae32e63..2aa3afe 100644 --- a/layer/layer.cpp +++ b/layer/layer.cpp @@ -673,10 +673,19 @@ wsi_layer_vkGetDeviceProcAddr(VkDevice device, const char *funcName) VWL_API_POS { GET_PROC_ADDR(vkReleaseSwapchainImagesEXT); } + + /* VK_KHR_present_wait */ if (device_data.is_device_extension_enabled(VK_KHR_PRESENT_WAIT_EXTENSION_NAME)) { GET_PROC_ADDR(vkWaitForPresentKHR); } +#if VULKAN_WSI_LAYER_EXPERIMENTAL + /* VK_KHR_present_wait2 */ + if (device_data.is_device_extension_enabled(VK_KHR_PRESENT_WAIT_2_EXTENSION_NAME)) + { + GET_PROC_ADDR(vkWaitForPresent2KHR); + } +#endif return device_data.disp.get_user_enabled_entrypoint(device, funcName); } diff --git a/layer/present_wait_api.cpp b/layer/present_wait_api.cpp index 759c177..9349c4a 100644 --- a/layer/present_wait_api.cpp +++ b/layer/present_wait_api.cpp @@ -34,7 +34,7 @@ #include "present_wait_api.hpp" /** - * @brief Implements vkSetSwapchainPresentTimingQueueSizeEXT Vulkan entrypoint. + * @brief Implements vkWaitForPresentKHR Vulkan entrypoint. */ VWL_VKAPI_CALL(VkResult) wsi_layer_vkWaitForPresentKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t present_id, @@ -51,5 +51,32 @@ wsi_layer_vkWaitForPresentKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_ auto *sc = reinterpret_cast(swapchain); auto *ext = sc->get_swapchain_extension(true); + assert(!ext->is_present_wait2()); + return ext->wait_for_present_id(present_id, timeout); } + +#if VULKAN_WSI_LAYER_EXPERIMENTAL +/** + * @brief Implements vkWaitForPresent2KHR Vulkan entrypoint. + */ +VWL_VKAPI_CALL(VkResult) +wsi_layer_vkWaitForPresent2KHR(VkDevice device, VkSwapchainKHR swapchain, + const VkPresentWait2InfoKHR *pPresentWait2Info) VWL_API_POST +{ + assert(swapchain != VK_NULL_HANDLE); + + auto &device_data = layer::device_private_data::get(device); + if (!device_data.layer_owns_swapchain(swapchain)) + { + return device_data.disp.WaitForPresent2KHR(device, swapchain, pPresentWait2Info); + } + + auto *sc = reinterpret_cast(swapchain); + auto *ext = sc->get_swapchain_extension(true); + + assert(ext->is_present_wait2()); + + return ext->wait_for_present_id(pPresentWait2Info->presentId, pPresentWait2Info->timeout); +} +#endif diff --git a/layer/present_wait_api.hpp b/layer/present_wait_api.hpp index d7fe31f..65f54b7 100644 --- a/layer/present_wait_api.hpp +++ b/layer/present_wait_api.hpp @@ -33,3 +33,9 @@ VWL_VKAPI_CALL(VkResult) wsi_layer_vkWaitForPresentKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t present_id, uint64_t timeout) VWL_API_POST; + +#if VULKAN_WSI_LAYER_EXPERIMENTAL +VWL_VKAPI_CALL(VkResult) +wsi_layer_vkWaitForPresent2KHR(VkDevice device, VkSwapchainKHR swapchain, + const VkPresentWait2InfoKHR *pPresentWait2Info) VWL_API_POST; +#endif diff --git a/layer/private_data.hpp b/layer/private_data.hpp index 13e965c..e197984 100644 --- a/layer/private_data.hpp +++ b/layer/private_data.hpp @@ -384,7 +384,9 @@ private: EP(GetSwapchainTimeDomainPropertiesEXT, VK_EXT_PRESENT_TIMING_EXTENSION_NAME, API_VERSION_MAX, false, ) \ EP(GetSwapchainTimingPropertiesEXT, VK_EXT_PRESENT_TIMING_EXTENSION_NAME, API_VERSION_MAX, false, ) \ EP(SetSwapchainPresentTimingQueueSizeEXT, VK_EXT_PRESENT_TIMING_EXTENSION_NAME, API_VERSION_MAX, false, ) \ - EP(GetPastPresentationTimingEXT, VK_EXT_PRESENT_TIMING_EXTENSION_NAME, API_VERSION_MAX, false, ) + EP(GetPastPresentationTimingEXT, VK_EXT_PRESENT_TIMING_EXTENSION_NAME, API_VERSION_MAX, false, ) \ + /* VK_KHR_present_wait2 */ \ + EP(WaitForPresent2KHR, VK_KHR_PRESENT_WAIT_2_EXTENSION_NAME, API_VERSION_MAX, false, ) #else #define DEVICE_ENTRYPOINTS_LIST_EXPERIMENTAL(EP) #endif diff --git a/wsi/display/present_wait_display.cpp b/wsi/display/present_wait_display.cpp index e78ab96..75fa619 100644 --- a/wsi/display/present_wait_display.cpp +++ b/wsi/display/present_wait_display.cpp @@ -35,8 +35,8 @@ namespace wsi namespace display { -wsi_ext_present_wait_display::wsi_ext_present_wait_display(wsi_ext_present_id &present_id_extension) - : wsi_ext_present_wait(present_id_extension) +wsi_ext_present_wait_display::wsi_ext_present_wait_display(wsi_ext_present_id &present_id_extension, bool present_wait2) + : wsi_ext_present_wait(present_id_extension, present_wait2) { } diff --git a/wsi/display/present_wait_display.hpp b/wsi/display/present_wait_display.hpp index 0d358d0..d249353 100644 --- a/wsi/display/present_wait_display.hpp +++ b/wsi/display/present_wait_display.hpp @@ -51,10 +51,11 @@ public: * @brief Constructs present ID class. * * @param present_id_extension Present ID extension that this class will use to query - * the last delivered present ID for the swapchain. This extension pointer must outlive - * this class. + * the last delivered present ID for the swapchain. This extension pointer must outlive + * this class. + * @param present_wait2 Indication for using/not using the Present Wait2 extension. */ - wsi_ext_present_wait_display(wsi_ext_present_id &present_id_extension); + wsi_ext_present_wait_display(wsi_ext_present_id &present_id_extension, bool present_wait2); private: /** diff --git a/wsi/display/swapchain.cpp b/wsi/display/swapchain.cpp index 47d08c9..5c56a7c 100644 --- a/wsi/display/swapchain.cpp +++ b/wsi/display/swapchain.cpp @@ -102,15 +102,19 @@ VkResult swapchain::add_required_extensions(VkDevice device, const VkSwapchainCr } } - if (m_device_data.is_present_wait_enabled() + bool present_wait2; #if VULKAN_WSI_LAYER_EXPERIMENTAL - || (swapchain_create_info->flags & - (VK_SWAPCHAIN_CREATE_PRESENT_ID_2_BIT_KHR | VK_SWAPCHAIN_CREATE_PRESENT_WAIT_2_BIT_KHR)) + constexpr VkSwapchainCreateFlagsKHR present_wait2_mask = + (VK_SWAPCHAIN_CREATE_PRESENT_ID_2_BIT_KHR | VK_SWAPCHAIN_CREATE_PRESENT_WAIT_2_BIT_KHR); + present_wait2 = (swapchain_create_info->flags & present_wait2_mask) == present_wait2_mask; +#else + present_wait2 = false; #endif - ) + + if (m_device_data.is_present_wait_enabled() || present_wait2) { - if (!add_swapchain_extension( - m_allocator.make_unique(*get_swapchain_extension(true)))) + if (!add_swapchain_extension(m_allocator.make_unique( + *get_swapchain_extension(true), present_wait2))) { return VK_ERROR_OUT_OF_HOST_MEMORY; } diff --git a/wsi/extensions/present_wait.cpp b/wsi/extensions/present_wait.cpp index 7b571fc..aefcb5e 100644 --- a/wsi/extensions/present_wait.cpp +++ b/wsi/extensions/present_wait.cpp @@ -34,8 +34,9 @@ namespace wsi { -wsi_ext_present_wait::wsi_ext_present_wait(wsi_ext_present_id &present_id_extension) +wsi_ext_present_wait::wsi_ext_present_wait(wsi_ext_present_id &present_id_extension, bool present_wait2) : m_present_id_ext(present_id_extension) + , m_present_wait2(present_wait2) { } diff --git a/wsi/extensions/present_wait.hpp b/wsi/extensions/present_wait.hpp index 00ffad3..00fc342 100644 --- a/wsi/extensions/present_wait.hpp +++ b/wsi/extensions/present_wait.hpp @@ -58,8 +58,9 @@ public: * @param present_id_extension Present ID extension that this class will use to query * the last delivered present ID for the swapchain. This extension pointer must outlive * this class. + * @param present_wait2 Indication for using/not using the Present Wait2 extension. */ - wsi_ext_present_wait(wsi_ext_present_id &present_id_extension); + wsi_ext_present_wait(wsi_ext_present_id &present_id_extension, bool present_wait2); /** * @brief Waits for present ID to be updated. @@ -71,6 +72,14 @@ public: */ VkResult wait_for_present_id(uint64_t present_id, uint64_t timeout_in_ns); + /** + * @brief Getter for the present_wait2. + */ + bool is_present_wait2() const + { + return m_present_wait2; + }; + protected: /** * @brief Backend specific implementation that will wait for the present ID to @@ -86,6 +95,12 @@ protected: * @brief Present ID extension pointer. */ wsi_ext_present_id &m_present_id_ext; + +private: + /** + * @brief Present Wait2 indication. + */ + bool m_present_wait2{ false }; }; } /* namespace wsi */ diff --git a/wsi/headless/present_wait_headless.cpp b/wsi/headless/present_wait_headless.cpp index fa96f8a..c46e641 100644 --- a/wsi/headless/present_wait_headless.cpp +++ b/wsi/headless/present_wait_headless.cpp @@ -35,8 +35,9 @@ namespace wsi namespace headless { -wsi_ext_present_wait_headless::wsi_ext_present_wait_headless(wsi_ext_present_id &present_id_extension) - : wsi_ext_present_wait(present_id_extension) +wsi_ext_present_wait_headless::wsi_ext_present_wait_headless(wsi_ext_present_id &present_id_extension, + bool present_wait2) + : wsi_ext_present_wait(present_id_extension, present_wait2) { } diff --git a/wsi/headless/present_wait_headless.hpp b/wsi/headless/present_wait_headless.hpp index 4dfe5c2..60532ff 100644 --- a/wsi/headless/present_wait_headless.hpp +++ b/wsi/headless/present_wait_headless.hpp @@ -51,10 +51,11 @@ public: * @brief Constructs present ID class. * * @param present_id_extension Present ID extension that this class will use to query - * the last delivered present ID for the swapchain. This extension pointer must outlive - * this class. + * the last delivered present ID for the swapchain. This extension pointer must outlive + * this class. + * @param present_wait2 Indication for using/not using the Present Wait2 extension. */ - wsi_ext_present_wait_headless(wsi_ext_present_id &present_id_extension); + wsi_ext_present_wait_headless(wsi_ext_present_id &present_id_extension, bool present_wait2); private: /** diff --git a/wsi/headless/swapchain.cpp b/wsi/headless/swapchain.cpp index 95e582f..4f8ac49 100644 --- a/wsi/headless/swapchain.cpp +++ b/wsi/headless/swapchain.cpp @@ -109,15 +109,19 @@ VkResult swapchain::add_required_extensions(VkDevice device, const VkSwapchainCr } #endif - if (m_device_data.is_present_wait_enabled() + bool present_wait2; #if VULKAN_WSI_LAYER_EXPERIMENTAL - || (swapchain_create_info->flags & - (VK_SWAPCHAIN_CREATE_PRESENT_ID_2_BIT_KHR | VK_SWAPCHAIN_CREATE_PRESENT_WAIT_2_BIT_KHR)) + constexpr VkSwapchainCreateFlagsKHR present_wait2_mask = + (VK_SWAPCHAIN_CREATE_PRESENT_ID_2_BIT_KHR | VK_SWAPCHAIN_CREATE_PRESENT_WAIT_2_BIT_KHR); + present_wait2 = (swapchain_create_info->flags & present_wait2_mask) == present_wait2_mask; +#else + present_wait2 = false; #endif - ) + + if (m_device_data.is_present_wait_enabled() || present_wait2) { if (!add_swapchain_extension(m_allocator.make_unique( - *get_swapchain_extension(true)))) + *get_swapchain_extension(true), present_wait2))) { return VK_ERROR_OUT_OF_HOST_MEMORY; } diff --git a/wsi/wayland/present_wait_wayland.cpp b/wsi/wayland/present_wait_wayland.cpp index 6f5af61..0312b22 100644 --- a/wsi/wayland/present_wait_wayland.cpp +++ b/wsi/wayland/present_wait_wayland.cpp @@ -38,8 +38,8 @@ namespace wsi namespace wayland { -wsi_ext_present_wait_wayland::wsi_ext_present_wait_wayland(wsi_ext_present_id &present_id_extension) - : wsi_ext_present_wait(present_id_extension) +wsi_ext_present_wait_wayland::wsi_ext_present_wait_wayland(wsi_ext_present_id &present_id_extension, bool present_wait2) + : wsi_ext_present_wait(present_id_extension, present_wait2) { } diff --git a/wsi/wayland/present_wait_wayland.hpp b/wsi/wayland/present_wait_wayland.hpp index fe29aba..265cbff 100644 --- a/wsi/wayland/present_wait_wayland.hpp +++ b/wsi/wayland/present_wait_wayland.hpp @@ -52,10 +52,11 @@ public: * @brief Constructs present ID class. * * @param present_id_extension Present ID extension that this class will use to query - * the last delivered present ID for the swapchain. This extension pointer must outlive - * this class. + * the last delivered present ID for the swapchain. This extension pointer must outlive + * this class. + * @param present_wait2 Indication for using/not using the Present Wait2 extension. */ - wsi_ext_present_wait_wayland(wsi_ext_present_id &present_id_extension); + wsi_ext_present_wait_wayland(wsi_ext_present_id &present_id_extension, bool present_wait2); /** * @brief Set the wayland dispatch object. diff --git a/wsi/wayland/swapchain.cpp b/wsi/wayland/swapchain.cpp index 8a8f9a0..c300f14 100644 --- a/wsi/wayland/swapchain.cpp +++ b/wsi/wayland/swapchain.cpp @@ -113,15 +113,19 @@ VkResult swapchain::add_required_extensions(VkDevice device, const VkSwapchainCr } } - if (m_device_data.is_present_wait_enabled() + bool present_wait2; #if VULKAN_WSI_LAYER_EXPERIMENTAL - || (swapchain_create_info->flags & - (VK_SWAPCHAIN_CREATE_PRESENT_ID_2_BIT_KHR | VK_SWAPCHAIN_CREATE_PRESENT_WAIT_2_BIT_KHR)) + constexpr VkSwapchainCreateFlagsKHR present_wait2_mask = + (VK_SWAPCHAIN_CREATE_PRESENT_ID_2_BIT_KHR | VK_SWAPCHAIN_CREATE_PRESENT_WAIT_2_BIT_KHR); + present_wait2 = (swapchain_create_info->flags & present_wait2_mask) == present_wait2_mask; +#else + present_wait2 = false; #endif - ) + + if (m_device_data.is_present_wait_enabled() || present_wait2) { - if (!add_swapchain_extension( - m_allocator.make_unique(*get_swapchain_extension(true)))) + if (!add_swapchain_extension(m_allocator.make_unique( + *get_swapchain_extension(true), present_wait2))) { return VK_ERROR_OUT_OF_HOST_MEMORY; }