Handle VkPhysicalDevicePresentWaitFeaturesKHR

Advertises support for present wait in vkGetPhysicalDeviceFeatures2KHR when all surface extensions are supported. If there are unsupported extensions, present wait feature advertisement is left to lower layers.
This commit is contained in:
Alex Bates 2025-04-01 09:29:51 +00:00 committed by Iason Paraskevopoulos
parent 0562f6c433
commit 4eb145cf8b
5 changed files with 65 additions and 43 deletions

View file

@ -289,7 +289,7 @@ if (VULKAN_WSI_LAYER_EXPERIMENTAL)
target_sources(${PROJECT_NAME} PUBLIC ${PROJECT_SOURCE_DIR}/wsi/extensions/present_timing.cpp) target_sources(${PROJECT_NAME} PUBLIC ${PROJECT_SOURCE_DIR}/wsi/extensions/present_timing.cpp)
add_definitions("-DVULKAN_WSI_LAYER_EXPERIMENTAL=1") add_definitions("-DVULKAN_WSI_LAYER_EXPERIMENTAL=1")
else() 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_present_timing|VK_KHR_present_wait/d' ${CMAKE_CURRENT_BINARY_DIR}/VkLayer_window_system_integration.json)
add_definitions("-DVULKAN_WSI_LAYER_EXPERIMENTAL=0") add_definitions("-DVULKAN_WSI_LAYER_EXPERIMENTAL=0")
endif() endif()

View file

@ -53,6 +53,13 @@
"vkGetSwapchainTimeDomainPropertiesEXT", "vkGetSwapchainTimeDomainPropertiesEXT",
"vkGetPastPresentationTimingEXT" "vkGetPastPresentationTimingEXT"
] ]
},
{
"name": "VK_KHR_present_wait",
"spec_version": "1",
"entrypoints": [
"vkWaitForPresentKHR"
]
} }
], ],
"disable_environment": { "disable_environment": {

View file

@ -41,7 +41,6 @@
#include "util/log.hpp" #include "util/log.hpp"
#include "util/macros.hpp" #include "util/macros.hpp"
#include "util/helpers.hpp" #include "util/helpers.hpp"
#include "wsi/unsupported_surfaces.hpp"
#define VK_LAYER_API_VERSION VK_MAKE_VERSION(1, 2, VK_HEADER_VERSION) #define VK_LAYER_API_VERSION VK_MAKE_VERSION(1, 2, VK_HEADER_VERSION)
@ -155,18 +154,6 @@ VKAPI_ATTR VkResult create_instance(const VkInstanceCreateInfo *pCreateInfo, con
modified_info.ppEnabledExtensionNames = modified_enabled_extensions.data(); modified_info.ppEnabledExtensionNames = modified_enabled_extensions.data();
modified_info.enabledExtensionCount = modified_enabled_extensions.size(); modified_info.enabledExtensionCount = modified_enabled_extensions.size();
bool maintainance1_support = true;
/* Loop through unsupported extensions and check if they exist in enabled extensions */
for (const auto &unsupported_surface_ext : wsi::unsupported_surfaces_ext_array)
{
if (extensions.contains(unsupported_surface_ext))
{
maintainance1_support = false;
WSI_LOG_ERROR(
"Warning: Swapchain maintenance feature is unsupported for the current surface and ICD configuration.\n");
}
}
/* Advance the link info for the next element on the chain. */ /* Advance the link info for the next element on the chain. */
layer_link_info->u.pLayerInfo = layer_link_info->u.pLayerInfo->pNext; layer_link_info->u.pLayerInfo = layer_link_info->u.pLayerInfo->pNext;
@ -201,8 +188,6 @@ VKAPI_ATTR VkResult create_instance(const VkInstanceCreateInfo *pCreateInfo, con
TRY_LOG_CALL(instance_private_data::associate(*pInstance, std::move(*table), loader_callback, TRY_LOG_CALL(instance_private_data::associate(*pInstance, std::move(*table), loader_callback,
layer_platforms_to_enable, api_version, instance_allocator)); layer_platforms_to_enable, api_version, instance_allocator));
/* Set the swapchain maintenance flag to true or false based on the enabled extensions checked above*/
instance_private_data::get(*pInstance).set_maintainance1_support(maintainance1_support);
/* /*
* Store the enabled instance extensions in order to return nullptr in * Store the enabled instance extensions in order to return nullptr in
* vkGetInstanceProcAddr for functions of disabled extensions. * vkGetInstanceProcAddr for functions of disabled extensions.
@ -477,13 +462,23 @@ wsi_layer_vkGetPhysicalDeviceFeatures2KHR(VkPhysicalDevice physicalDevice,
VkPhysicalDeviceFeatures2 *pFeatures) VWL_API_POST VkPhysicalDeviceFeatures2 *pFeatures) VWL_API_POST
{ {
auto &instance = layer::instance_private_data::get(physicalDevice); auto &instance = layer::instance_private_data::get(physicalDevice);
auto *physical_device_swapchain_maintenance1_features =
util::find_extension<VkPhysicalDeviceSwapchainMaintenance1FeaturesEXT>( auto *swapchain_maintenance1_features = util::find_extension<VkPhysicalDeviceSwapchainMaintenance1FeaturesEXT>(
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SWAPCHAIN_MAINTENANCE_1_FEATURES_EXT, pFeatures->pNext); VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SWAPCHAIN_MAINTENANCE_1_FEATURES_EXT, pFeatures->pNext);
if (physical_device_swapchain_maintenance1_features != nullptr) if (swapchain_maintenance1_features != nullptr)
{ {
physical_device_swapchain_maintenance1_features->swapchainMaintenance1 = false; swapchain_maintenance1_features->swapchainMaintenance1 = VK_FALSE;
} }
#if VULKAN_WSI_LAYER_EXPERIMENTAL
auto *present_wait_features = util::find_extension<VkPhysicalDevicePresentWaitFeaturesKHR>(
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_WAIT_FEATURES_KHR, pFeatures->pNext);
if (present_wait_features != nullptr)
{
present_wait_features->presentWait = VK_FALSE;
}
#endif
instance.disp.GetPhysicalDeviceFeatures2KHR(physicalDevice, pFeatures); instance.disp.GetPhysicalDeviceFeatures2KHR(physicalDevice, pFeatures);
auto *image_compression_control_swapchain_features = auto *image_compression_control_swapchain_features =
@ -499,12 +494,21 @@ wsi_layer_vkGetPhysicalDeviceFeatures2KHR(VkPhysicalDevice physicalDevice,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_ID_FEATURES_KHR, pFeatures->pNext); VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_ID_FEATURES_KHR, pFeatures->pNext);
if (present_id_features != nullptr) if (present_id_features != nullptr)
{ {
present_id_features->presentId = true; present_id_features->presentId = VK_TRUE;
} }
wsi::set_swapchain_maintenance1_state(physicalDevice, physical_device_swapchain_maintenance1_features); wsi::set_swapchain_maintenance1_state(physicalDevice, swapchain_maintenance1_features);
#if VULKAN_WSI_LAYER_EXPERIMENTAL #if VULKAN_WSI_LAYER_EXPERIMENTAL
if (present_wait_features != nullptr)
{
/* If there is an surface extension in use that is unsupported by the layer, defer to the ICD */
if (!instance.is_unsupported_surface_extension_enabled())
{
present_wait_features->presentWait = VK_TRUE;
}
}
auto *present_timing_features = util::find_extension<VkPhysicalDevicePresentTimingFeaturesEXT>( auto *present_timing_features = util::find_extension<VkPhysicalDevicePresentTimingFeaturesEXT>(
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_TIMING_FEATURES_EXT, pFeatures->pNext); VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENT_TIMING_FEATURES_EXT, pFeatures->pNext);
if (present_timing_features != nullptr) if (present_timing_features != nullptr)

View file

@ -27,6 +27,7 @@
#include "private_data.hpp" #include "private_data.hpp"
#include "wsi/wsi_factory.hpp" #include "wsi/wsi_factory.hpp"
#include "wsi/surface.hpp" #include "wsi/surface.hpp"
#include "wsi/unsupported_surfaces.hpp"
#include "util/unordered_map.hpp" #include "util/unordered_map.hpp"
#include "util/log.hpp" #include "util/log.hpp"
#include "util/helpers.hpp" #include "util/helpers.hpp"
@ -385,7 +386,22 @@ bool instance_private_data::has_frame_boundary_support(VkPhysicalDevice phys_dev
VkResult instance_private_data::set_instance_enabled_extensions(const char *const *extension_names, VkResult instance_private_data::set_instance_enabled_extensions(const char *const *extension_names,
size_t extension_count) size_t extension_count)
{ {
return enabled_extensions.add(extension_names, extension_count); VkResult result = enabled_extensions.add(extension_names, extension_count);
/* Check for unsupported surface extension */
has_enabled_unsupported_extension = false;
for (const auto &unsupported_surface_ext : wsi::unsupported_surfaces_ext_array)
{
if (enabled_extensions.contains(unsupported_surface_ext))
{
has_enabled_unsupported_extension = true;
WSI_LOG_ERROR(
"Warning: Swapchain maintenance feature is unsupported for the current surface and ICD configuration.\n");
break;
}
}
return result;
} }
bool instance_private_data::is_instance_extension_enabled(const char *extension_name) const bool instance_private_data::is_instance_extension_enabled(const char *extension_name) const
@ -393,16 +409,6 @@ bool instance_private_data::is_instance_extension_enabled(const char *extension_
return enabled_extensions.contains(extension_name); return enabled_extensions.contains(extension_name);
} }
void instance_private_data::set_maintainance1_support(bool enabled_unsupport_ext)
{
enabled_unsupported_swapchain_maintenance1_extensions = enabled_unsupport_ext;
}
bool instance_private_data::get_maintainance1_support()
{
return enabled_unsupported_swapchain_maintenance1_extensions;
}
device_private_data::device_private_data(instance_private_data &inst_data, VkPhysicalDevice phys_dev, VkDevice dev, device_private_data::device_private_data(instance_private_data &inst_data, VkPhysicalDevice phys_dev, VkDevice dev,
device_dispatch_table table, PFN_vkSetDeviceLoaderData set_loader_data, device_dispatch_table table, PFN_vkSetDeviceLoaderData set_loader_data,
const util::allocator &alloc) const util::allocator &alloc)

View file

@ -634,7 +634,7 @@ public:
/** /**
* @brief Check whether an instance extension is enabled. * @brief Check whether an instance extension is enabled.
* *
* param extension_name Extension's name. * @param extension_name Extension's name.
* *
* @return true if is enabled, false otherwise. * @return true if is enabled, false otherwise.
*/ */
@ -644,12 +644,14 @@ public:
const uint32_t api_version; const uint32_t api_version;
/** /**
* @brief Set if swapchain maintainance1 support is enabled. * @brief Check whether there is an enabled surface extension that is not supported by the layer.
*
* @param enabled_unsupport_ext True if it is enabled, false otherwise.
* *
* @return true if there is an unsupported, enabled surface extension
*/ */
void set_maintainance1_support(bool enabled_unsupport_ext); bool is_unsupported_surface_extension_enabled() const
{
return has_enabled_unsupported_extension;
}
/** /**
* @brief Check if swapchain maintainance1 support is enabled. * @brief Check if swapchain maintainance1 support is enabled.
@ -657,7 +659,10 @@ public:
* @return true if it is enabled, false otherwise. * @return true if it is enabled, false otherwise.
* *
*/ */
bool get_maintainance1_support(); bool get_maintainance1_support() const
{
return !has_enabled_unsupported_extension;
}
private: private:
/* Allow util::allocator to access the private constructor */ /* Allow util::allocator to access the private constructor */
@ -711,9 +716,9 @@ private:
util::extension_list enabled_extensions; util::extension_list enabled_extensions;
/** /**
* @brief True if unsupported extensions are enabled. * @brief True if any unsupported extensions are enabled.
*/ */
bool enabled_unsupported_swapchain_maintenance1_extensions; bool has_enabled_unsupported_extension;
}; };
/** /**