diff --git a/CMakeLists.txt b/CMakeLists.txt index d7e1bfd..2431174 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -59,6 +59,7 @@ option(BUILD_WSI_WAYLAND "Build with support for VK_KHR_wayland_surface" OFF) option(BUILD_WSI_DISPLAY "Build with support for VK_KHR_display" OFF) option(BUILD_WSI_IMAGE_COMPRESSION_CONTROL_SWAPCHAIN "Build with support for VK_EXT_image_compression_control_swapchain" OFF) option(BUILD_WSI_DISPLAY_SUPPORT_FORMAT_MODIFIERS "Build with support for format modifiers in VK_KHR_display" ON) +option(VULKAN_WSI_LAYER_EXPERIMENTAL "Enable the Vulkan WSI Experimental features" OFF) set(SELECT_EXTERNAL_ALLOCATOR "none" CACHE STRING "Select an external system allocator (none, ion)") set(EXTERNAL_WSIALLOC_LIBRARY "" CACHE STRING "External implementation of the wsialloc interface to use") @@ -237,9 +238,11 @@ add_library(${PROJECT_NAME} SHARED wsi/wsi_factory.cpp) if (VULKAN_WSI_LAYER_EXPERIMENTAL) target_sources(${PROJECT_NAME} PUBLIC ${PROJECT_SOURCE_DIR}/layer/present_timing.cpp) + add_definitions("-DVULKAN_WSI_LAYER_EXPERIMENTAL=1") else() list(APPEND JSON_COMMANDS COMMAND sed -i '/VK_EXT_present_timing/d' ${CMAKE_CURRENT_BINARY_DIR}/VkLayer_window_system_integration.json) list(APPEND JSON_COMMANDS COMMAND sed -i '/VK_EXT_swapchain_maintenance1/d' ${CMAKE_CURRENT_BINARY_DIR}/VkLayer_window_system_integration.json) + add_definitions("-DVULKAN_WSI_LAYER_EXPERIMENTAL=0") endif() target_compile_definitions(${PROJECT_NAME} PRIVATE ${WSI_DEFINES}) diff --git a/layer/layer.cpp b/layer/layer.cpp index 116b818..76c078c 100644 --- a/layer/layer.cpp +++ b/layer/layer.cpp @@ -41,6 +41,10 @@ #include "util/macros.hpp" #include "util/helpers.hpp" +#if VULKAN_WSI_LAYER_EXPERIMENTAL +#include "wsi_layer_experimental.hpp" +#endif + #define VK_LAYER_API_VERSION VK_MAKE_VERSION(1, 2, VK_HEADER_VERSION) namespace layer @@ -450,6 +454,15 @@ wsi_layer_vkGetPhysicalDeviceFeatures2KHR(VkPhysicalDevice physicalDevice, { physical_device_swapchain_maintenance1_features->swapchainMaintenance1 = true; } + + auto *present_timing_features = util::find_extension( + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_TIMING_FEATURES_EXT, pFeatures->pNext); + if (present_timing_features != nullptr) + { + present_timing_features->presentTiming = VK_TRUE; + present_timing_features->presentAtAbsoluteTime = VK_TRUE; + present_timing_features->presentAtRelativeTime = VK_TRUE; + } #endif } diff --git a/layer/surface_api.cpp b/layer/surface_api.cpp index 854e94c..c9793f4 100644 --- a/layer/surface_api.cpp +++ b/layer/surface_api.cpp @@ -63,13 +63,21 @@ wsi_layer_vkGetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDe wsi::surface_properties *props = wsi::get_surface_properties(instance, pSurfaceInfo->surface); assert(props != nullptr); +#if VULKAN_WSI_LAYER_EXPERIMENTAL + auto *surf_caps_ext = util::find_extension( + VK_STRUCTURE_TYPE_PRESENT_TIMING_SURFACE_CAPABILITIES_EXT, pSurfaceCapabilities); + if (surf_caps_ext != nullptr) + { + props->get_present_timing_surface_caps(surf_caps_ext); + } +#endif + auto shared_present_surface_cap_struct = util::find_extension( VK_STRUCTURE_TYPE_SHARED_PRESENT_SURFACE_CAPABILITIES_KHR, pSurfaceCapabilities); if (shared_present_surface_cap_struct != nullptr) { shared_present_surface_cap_struct->sharedPresentSupportedUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; } - return props->get_surface_capabilities(physicalDevice, pSurfaceInfo, pSurfaceCapabilities); } diff --git a/layer/wsi_layer_experimental.hpp b/layer/wsi_layer_experimental.hpp index 73340ae..81deedb 100644 --- a/layer/wsi_layer_experimental.hpp +++ b/layer/wsi_layer_experimental.hpp @@ -51,6 +51,8 @@ #define VK_STRUCTURE_TYPE_PRESENT_TIMING_INFO_EXT ((VkStructureType)1000208010) #define VK_STRUCTURE_TYPE_PRESENT_TIMINGS_INFO_EXT ((VkStructureType)1000208011) +typedef VkFlags VkPresentStageFlagsEXT; + typedef struct VkPhysicalDevicePresentTimingFeaturesEXT { VkStructureType sType; @@ -131,14 +133,14 @@ typedef struct VkPastPresentationTimingPropertiesEXT uint64_t timeDomainsCounter; uint32_t presentationTimingCount; VkPastPresentationTimingEXT *pPresentationTimings; -}; +} VkPastPresentationTimingPropertiesEXT; typedef struct VkPastPresentationTimingInfoEXT { VkStructureType sType; const void *pNext; VkSwapchainKHR swapchain; -}; +} VkPastPresentationTimingInfoEXT; typedef union VkPresentTimeEXT { diff --git a/wsi/display/surface_properties.cpp b/wsi/display/surface_properties.cpp index 59e4b70..8191cac 100644 --- a/wsi/display/surface_properties.cpp +++ b/wsi/display/surface_properties.cpp @@ -498,6 +498,18 @@ bool surface_properties::is_surface_extension_enabled(const layer::instance_priv return instance_data.is_instance_extension_enabled(VK_KHR_SURFACE_EXTENSION_NAME); } +#if VULKAN_WSI_LAYER_EXPERIMENTAL +void surface_properties::get_present_timing_surface_caps( + VkPresentTimingSurfaceCapabilitiesEXT *present_timing_surface_caps) +{ + present_timing_surface_caps->presentTimingSupported = VK_FALSE; + present_timing_surface_caps->presentAtAbsoluteTimeSupported = VK_FALSE; + present_timing_surface_caps->presentAtRelativeTimeSupported = VK_FALSE; + present_timing_surface_caps->presentStageQueries = 0; + present_timing_surface_caps->presentStageTargets = 0; +} +#endif + surface_properties &surface_properties::get_instance() { static surface_properties instance; diff --git a/wsi/display/surface_properties.hpp b/wsi/display/surface_properties.hpp index 317f761..6716469 100644 --- a/wsi/display/surface_properties.hpp +++ b/wsi/display/surface_properties.hpp @@ -62,6 +62,10 @@ public: bool is_surface_extension_enabled(const layer::instance_private_data &instance_data) override; +#if VULKAN_WSI_LAYER_EXPERIMENTAL + void get_present_timing_surface_caps(VkPresentTimingSurfaceCapabilitiesEXT *present_timing_surface_caps) override; +#endif + static surface_properties &get_instance(); private: diff --git a/wsi/headless/surface_properties.cpp b/wsi/headless/surface_properties.cpp index b56f5a5..ffee087 100644 --- a/wsi/headless/surface_properties.cpp +++ b/wsi/headless/surface_properties.cpp @@ -215,5 +215,21 @@ bool surface_properties::is_compatible_present_modes(VkPresentModeKHR present_mo return m_compatible_present_modes.is_compatible_present_modes(present_mode_a, present_mode_b); } +#if VULKAN_WSI_LAYER_EXPERIMENTAL +void surface_properties::get_present_timing_surface_caps( + VkPresentTimingSurfaceCapabilitiesEXT *present_timing_surface_caps) +{ + present_timing_surface_caps->presentTimingSupported = VK_TRUE; + present_timing_surface_caps->presentAtAbsoluteTimeSupported = VK_TRUE; + present_timing_surface_caps->presentAtRelativeTimeSupported = VK_TRUE; + present_timing_surface_caps->presentStageQueries = + VK_PRESENT_STAGE_QUEUE_OPERATIONS_END_BIT_EXT | VK_PRESENT_STAGE_IMAGE_LATCHED_BIT_EXT | + VK_PRESENT_STAGE_IMAGE_FIRST_PIXEL_OUT_BIT_EXT | VK_PRESENT_STAGE_IMAGE_FIRST_PIXEL_VISIBLE_BIT_EXT; + present_timing_surface_caps->presentStageTargets = VK_PRESENT_STAGE_IMAGE_LATCHED_BIT_EXT | + VK_PRESENT_STAGE_IMAGE_FIRST_PIXEL_OUT_BIT_EXT | + VK_PRESENT_STAGE_IMAGE_FIRST_PIXEL_VISIBLE_BIT_EXT; +} +#endif + } /* namespace headless */ } /* namespace wsi */ diff --git a/wsi/headless/surface_properties.hpp b/wsi/headless/surface_properties.hpp index 3a9db84..955166e 100644 --- a/wsi/headless/surface_properties.hpp +++ b/wsi/headless/surface_properties.hpp @@ -62,6 +62,10 @@ public: bool is_compatible_present_modes(VkPresentModeKHR present_mode_a, VkPresentModeKHR present_mode_b) override; +#if VULKAN_WSI_LAYER_EXPERIMENTAL + void get_present_timing_surface_caps(VkPresentTimingSurfaceCapabilitiesEXT *present_timing_surface_caps) override; +#endif + private: /* List of supported presentation modes */ std::array m_supported_modes; diff --git a/wsi/surface_properties.hpp b/wsi/surface_properties.hpp index c13f542..5b3c140 100644 --- a/wsi/surface_properties.hpp +++ b/wsi/surface_properties.hpp @@ -38,6 +38,10 @@ #include "util/format_modifiers.hpp" #include "util/drm/drm_utils.hpp" +#if VULKAN_WSI_LAYER_EXPERIMENTAL +#include "layer/wsi_layer_experimental.hpp" +#endif + namespace wsi { @@ -110,6 +114,13 @@ public: virtual bool is_compatible_present_modes(VkPresentModeKHR present_mode_a, VkPresentModeKHR present_mode_b) = 0; +#if VULKAN_WSI_LAYER_EXPERIMENTAL + /** + * @brief Get the present timing surface capabilities for the specific VkSurface type. + */ + virtual void get_present_timing_surface_caps(VkPresentTimingSurfaceCapabilitiesEXT *present_timing_surface_caps) = 0; +#endif + private: /** * @brief Set which presentation modes are compatible with each other for a particular surface diff --git a/wsi/wayland/surface_properties.cpp b/wsi/wayland/surface_properties.cpp index b5463f2..f1752a1 100644 --- a/wsi/wayland/surface_properties.cpp +++ b/wsi/wayland/surface_properties.cpp @@ -417,5 +417,17 @@ bool surface_properties::is_compatible_present_modes(VkPresentModeKHR present_mo return m_compatible_present_modes.is_compatible_present_modes(present_mode_a, present_mode_b); } +#if VULKAN_WSI_LAYER_EXPERIMENTAL +void surface_properties::get_present_timing_surface_caps( + VkPresentTimingSurfaceCapabilitiesEXT *present_timing_surface_caps) +{ + present_timing_surface_caps->presentTimingSupported = VK_TRUE; + present_timing_surface_caps->presentAtAbsoluteTimeSupported = VK_FALSE; + present_timing_surface_caps->presentAtRelativeTimeSupported = VK_FALSE; + present_timing_surface_caps->presentStageQueries = VK_PRESENT_STAGE_QUEUE_OPERATIONS_END_BIT_EXT; + present_timing_surface_caps->presentStageTargets = 0; +} +#endif + } // namespace wayland } // namespace wsi diff --git a/wsi/wayland/surface_properties.hpp b/wsi/wayland/surface_properties.hpp index c9349bb..cb14c93 100644 --- a/wsi/wayland/surface_properties.hpp +++ b/wsi/wayland/surface_properties.hpp @@ -74,6 +74,9 @@ public: bool is_compatible_present_modes(VkPresentModeKHR present_mode_a, VkPresentModeKHR present_mode_b) override; +#if VULKAN_WSI_LAYER_EXPERIMENTAL + void get_present_timing_surface_caps(VkPresentTimingSurfaceCapabilitiesEXT *present_timing_surface_caps) override; +#endif private: surface_properties();