VulkanDevice: Use KHR variants of surface/swapchain maintenance

AMD doesn't support the EXT variant.
This commit is contained in:
Stenzek 2025-12-23 16:43:19 +10:00
parent 41a000c0f1
commit a1aa038623
No known key found for this signature in database
6 changed files with 31 additions and 17 deletions

View File

@ -382,8 +382,11 @@ bool VulkanDevice::EnableOptionalDeviceExtensions(VkPhysicalDevice physical_devi
if (m_optional_extensions.vk_khr_maintenance5)
AddExtension(VK_KHR_MAINTENANCE_5_EXTENSION_NAME);
m_optional_extensions.vk_ext_swapchain_maintenance1 =
enable_surface && SupportsAndAddExtension(VK_EXT_SWAPCHAIN_MAINTENANCE_1_EXTENSION_NAME);
// Driver support for swapchain maintenance is a mess... try KHR first, then EXT.
m_optional_extensions.vk_khr_swapchain_maintenance1 =
enable_surface && VulkanLoader::GetOptionalExtensions().vk_khr_surface_maintenance1 &&
(SupportsAndAddExtension(VK_KHR_SWAPCHAIN_MAINTENANCE_1_EXTENSION_NAME) ||
SupportsAndAddExtension(VK_EXT_SWAPCHAIN_MAINTENANCE_1_EXTENSION_NAME));
}
// Enable the features we use.
@ -405,13 +408,13 @@ bool VulkanDevice::EnableOptionalDeviceExtensions(VkPhysicalDevice physical_devi
LOG_EXT("VK_EXT_fragment_shader_interlock", vk_ext_fragment_shader_interlock);
LOG_EXT("VK_EXT_memory_budget", vk_ext_memory_budget);
LOG_EXT("VK_EXT_rasterization_order_attachment_access", vk_ext_rasterization_order_attachment_access);
LOG_EXT("VK_EXT_swapchain_maintenance1", vk_ext_swapchain_maintenance1);
LOG_EXT("VK_KHR_driver_properties", vk_khr_driver_properties);
LOG_EXT("VK_KHR_dynamic_rendering", vk_khr_dynamic_rendering);
LOG_EXT("VK_KHR_dynamic_rendering_local_read", vk_khr_dynamic_rendering_local_read);
LOG_EXT("VK_KHR_maintenance4", vk_khr_maintenance4);
LOG_EXT("VK_KHR_maintenance5", vk_khr_maintenance5);
LOG_EXT("VK_KHR_push_descriptor", vk_khr_push_descriptor);
LOG_EXT("VK_KHR_swapchain_maintenance1", vk_khr_swapchain_maintenance1);
#ifdef _WIN32
m_optional_extensions.vk_ext_full_screen_exclusive =
@ -557,7 +560,7 @@ bool VulkanDevice::CreateDevice(VkPhysicalDevice physical_device, VkSurfaceKHR s
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_FEATURES, nullptr, VK_TRUE};
VkPhysicalDeviceDynamicRenderingLocalReadFeaturesKHR dynamic_rendering_local_read_feature = {
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DYNAMIC_RENDERING_LOCAL_READ_FEATURES_KHR, nullptr, VK_TRUE};
VkPhysicalDeviceSwapchainMaintenance1FeaturesEXT swapchain_maintenance1_feature = {
VkPhysicalDeviceSwapchainMaintenance1FeaturesKHR swapchain_maintenance1_feature = {
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SWAPCHAIN_MAINTENANCE_1_FEATURES_EXT, nullptr, VK_TRUE};
VkPhysicalDeviceFragmentShaderInterlockFeaturesEXT fragment_shader_interlock_feature = {
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_INTERLOCK_FEATURES_EXT, nullptr, VK_FALSE, VK_TRUE, VK_FALSE};
@ -568,7 +571,7 @@ bool VulkanDevice::CreateDevice(VkPhysicalDevice physical_device, VkSurfaceKHR s
if (m_optional_extensions.vk_ext_rasterization_order_attachment_access)
Vulkan::AddPointerToChain(&device_info, &rasterization_order_access_feature);
if (m_optional_extensions.vk_ext_swapchain_maintenance1)
if (m_optional_extensions.vk_khr_swapchain_maintenance1)
Vulkan::AddPointerToChain(&device_info, &swapchain_maintenance1_feature);
if (m_optional_extensions.vk_khr_dynamic_rendering)
{

View File

@ -47,7 +47,6 @@ public:
bool vk_ext_full_screen_exclusive : 1;
bool vk_ext_memory_budget : 1;
bool vk_ext_rasterization_order_attachment_access : 1;
bool vk_ext_swapchain_maintenance1 : 1;
bool vk_khr_driver_properties : 1;
bool vk_khr_dynamic_rendering : 1;
bool vk_khr_dynamic_rendering_local_read : 1;
@ -55,6 +54,7 @@ public:
bool vk_khr_maintenance5 : 1;
bool vk_khr_push_descriptor : 1;
bool vk_khr_shader_non_semantic_info : 1;
bool vk_khr_swapchain_maintenance1 : 1;
};
using ExtensionList = std::vector<const char*>;

View File

@ -246,6 +246,9 @@ VULKAN_DEVICE_ENTRY_POINT(vkCmdEndRenderingKHR, false)
// VK_KHR_push_descriptor
VULKAN_DEVICE_ENTRY_POINT(vkCmdPushDescriptorSetKHR, false)
// VK_KHR_swapchain_maintenance1
VULKAN_DEVICE_ENTRY_POINT(vkReleaseSwapchainImagesKHR, false)
// VK_EXT_external_memory_host
VULKAN_DEVICE_ENTRY_POINT(vkGetMemoryHostPointerPropertiesEXT, false)

View File

@ -315,7 +315,14 @@ bool VulkanLoader::LoadDeviceFunctions(VkDevice device, Error* error)
#include "vulkan_entry_points.inl"
#undef VULKAN_DEVICE_ENTRY_POINT
return !required_functions_missing;
if (required_functions_missing)
return false;
// Alias for swapchain maintenance.
if (!vkReleaseSwapchainImagesKHR)
vkReleaseSwapchainImagesKHR = vkReleaseSwapchainImagesEXT;
return true;
}
void VulkanLoader::ResetDeviceFunctions()
@ -578,8 +585,9 @@ bool VulkanLoader::SelectInstanceExtensions(VulkanDevice::ExtensionList* extensi
s_locals.optional_extensions.vk_khr_get_surface_capabilities2 =
(wtype != WindowInfoType::Surfaceless &&
SupportsExtension(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME, false));
s_locals.optional_extensions.vk_ext_surface_maintenance1 =
(wtype != WindowInfoType::Surfaceless && SupportsExtension(VK_EXT_SURFACE_MAINTENANCE_1_EXTENSION_NAME, false));
s_locals.optional_extensions.vk_khr_surface_maintenance1 =
(wtype != WindowInfoType::Surfaceless && (SupportsExtension(VK_KHR_SURFACE_MAINTENANCE_1_EXTENSION_NAME, false) ||
SupportsExtension(VK_EXT_SURFACE_MAINTENANCE_1_EXTENSION_NAME, false)));
s_locals.optional_extensions.vk_khr_get_physical_device_properties2 =
SupportsExtension(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME, false);
@ -588,9 +596,9 @@ bool VulkanLoader::SelectInstanceExtensions(VulkanDevice::ExtensionList* extensi
s_locals.optional_extensions.field ? Log::Color::StrongGreen : Log::Color::StrongOrange, name " is {}", \
s_locals.optional_extensions.field ? "supported" : "NOT supported")
LOG_EXT("VK_EXT_surface_maintenance1", vk_ext_surface_maintenance1);
LOG_EXT("VK_KHR_get_physical_device_properties2", vk_khr_get_physical_device_properties2);
LOG_EXT("VK_KHR_get_surface_capabilities2", vk_khr_get_surface_capabilities2);
LOG_EXT("VK_KHR_surface_maintenance1", vk_khr_surface_maintenance1);
#undef LOG_EXT

View File

@ -21,9 +21,9 @@ using GPUList = std::vector<std::pair<VkPhysicalDevice, GPUDevice::AdapterInfo>>
/// @brief Optional extensions for an instance.
struct OptionalExtensions
{
bool vk_ext_surface_maintenance1 : 1;
bool vk_khr_get_surface_capabilities2 : 1;
bool vk_khr_get_physical_device_properties2 : 1;
bool vk_khr_surface_maintenance1 : 1;
};
/// Creates the shared Vulkan instance. If debug_instance is changed, the instance will be recreated.

View File

@ -357,11 +357,11 @@ bool VulkanSwapChain::CreateSwapChain(VulkanDevice& dev, Error* error)
// The present mode can alter the number of images required. Use VK_KHR_get_surface_capabilities2 to confirm it.
const VulkanLoader::OptionalExtensions& optional_extensions = VulkanLoader::GetOptionalExtensions();
if (optional_extensions.vk_khr_get_surface_capabilities2 && optional_extensions.vk_ext_surface_maintenance1)
if (optional_extensions.vk_khr_get_surface_capabilities2 && optional_extensions.vk_khr_surface_maintenance1)
{
VkPhysicalDeviceSurfaceInfo2KHR dsi = {
.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR, .pNext = nullptr, .surface = m_surface};
VkSurfacePresentModeEXT dsi_pm = {
VkSurfacePresentModeKHR dsi_pm = {
.sType = VK_STRUCTURE_TYPE_SURFACE_PRESENT_MODE_EXT, .pNext = nullptr, .presentMode = present_mode.value()};
Vulkan::AddPointerToChain(&dsi, &dsi_pm);
res = vkGetPhysicalDeviceSurfaceCapabilities2KHR(physdev, &dsi, &surface_caps);
@ -816,18 +816,18 @@ void VulkanSwapChain::ReleaseCurrentImage()
return;
if ((m_image_acquire_result.value() == VK_SUCCESS || m_image_acquire_result.value() == VK_SUBOPTIMAL_KHR) &&
VulkanDevice::GetInstance().GetOptionalExtensions().vk_ext_swapchain_maintenance1)
VulkanDevice::GetInstance().GetOptionalExtensions().vk_khr_swapchain_maintenance1)
{
VulkanDevice::GetInstance().WaitForGPUIdle();
const VkReleaseSwapchainImagesInfoEXT info = {.sType = VK_STRUCTURE_TYPE_RELEASE_SWAPCHAIN_IMAGES_INFO_EXT,
const VkReleaseSwapchainImagesInfoKHR info = {.sType = VK_STRUCTURE_TYPE_RELEASE_SWAPCHAIN_IMAGES_INFO_EXT,
.pNext = nullptr,
.swapchain = m_swap_chain,
.imageIndexCount = 1,
.pImageIndices = &m_current_image};
VkResult res = vkReleaseSwapchainImagesEXT(VulkanDevice::GetInstance().GetVulkanDevice(), &info);
VkResult res = vkReleaseSwapchainImagesKHR(VulkanDevice::GetInstance().GetVulkanDevice(), &info);
if (res != VK_SUCCESS)
LOG_VULKAN_ERROR(res, "vkReleaseSwapchainImagesEXT() failed: ");
LOG_VULKAN_ERROR(res, "vkReleaseSwapchainImagesKHR() failed: ");
}
m_image_acquire_result.reset();