mirror of
https://github.com/PCSX2/pcsx2.git
synced 2025-12-16 04:08:48 +00:00
GS/VK: Support VK_KHR_swapchain_maintenance1
Co-Authored-By: refractionpcsx2 <6278726+refractionpcsx2@users.noreply.github.com>
This commit is contained in:
parent
323263eaec
commit
5c5e8594fd
@ -206,8 +206,7 @@ bool GSDeviceVK::SelectInstanceExtensions(ExtensionList* extension_list, const W
|
||||
if (enable_debug_utils && !SupportsExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, false))
|
||||
Console.Warning("VK: Debug report requested, but extension is not available.");
|
||||
|
||||
oe->vk_ext_swapchain_maintenance1 = (wi.type != WindowInfo::Type::Surfaceless &&
|
||||
SupportsExtension(VK_EXT_SURFACE_MAINTENANCE_1_EXTENSION_NAME, false));
|
||||
oe->vk_swapchain_maintenance1 = wi.type != WindowInfo::Type::Surfaceless;
|
||||
|
||||
// Needed for exclusive fullscreen control.
|
||||
SupportsExtension(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME, false);
|
||||
@ -411,6 +410,13 @@ bool GSDeviceVK::SelectDeviceExtensions(ExtensionList* extension_list, bool enab
|
||||
m_optional_extensions.vk_ext_line_rasterization = SupportsExtension(VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME, false);
|
||||
m_optional_extensions.vk_khr_driver_properties = SupportsExtension(VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME, false);
|
||||
|
||||
if (m_optional_extensions.vk_swapchain_maintenance1)
|
||||
{
|
||||
const bool khr_swapchain_maintenance1 = SupportsExtension(VK_KHR_SWAPCHAIN_MAINTENANCE_1_EXTENSION_NAME, false);
|
||||
m_optional_extensions.vk_swapchain_maintenance1 = khr_swapchain_maintenance1 ? khr_swapchain_maintenance1 : SupportsExtension(VK_EXT_SWAPCHAIN_MAINTENANCE_1_EXTENSION_NAME, false);
|
||||
m_optional_extensions.vk_swapchain_maintenance1_is_khr = khr_swapchain_maintenance1;
|
||||
}
|
||||
|
||||
// glslang generates debug info instructions before phi nodes at the beginning of blocks when non-semantic debug info
|
||||
// is enabled, triggering errors by spirv-val. Gate it by an environment variable if you want source debugging until
|
||||
// this is fixed.
|
||||
@ -420,10 +426,6 @@ bool GSDeviceVK::SelectDeviceExtensions(ExtensionList* extension_list, bool enab
|
||||
SupportsExtension(VK_KHR_SHADER_NON_SEMANTIC_INFO_EXTENSION_NAME, false);
|
||||
}
|
||||
|
||||
m_optional_extensions.vk_ext_swapchain_maintenance1 =
|
||||
m_optional_extensions.vk_ext_swapchain_maintenance1 &&
|
||||
SupportsExtension(VK_EXT_SWAPCHAIN_MAINTENANCE_1_EXTENSION_NAME, false);
|
||||
|
||||
#ifdef _WIN32
|
||||
m_optional_extensions.vk_ext_full_screen_exclusive =
|
||||
enable_surface && SupportsExtension(VK_EXT_FULL_SCREEN_EXCLUSIVE_EXTENSION_NAME, false);
|
||||
@ -611,8 +613,10 @@ bool GSDeviceVK::CreateDevice(VkSurfaceKHR surface, bool enable_validation_layer
|
||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT};
|
||||
VkPhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT attachment_feedback_loop_feature = {
|
||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_FEATURES_EXT};
|
||||
VkPhysicalDeviceSwapchainMaintenance1FeaturesEXT swapchain_maintenance1_feature = {
|
||||
VkPhysicalDeviceSwapchainMaintenance1FeaturesEXT swapchain_maintenance1_ext_feature = {
|
||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SWAPCHAIN_MAINTENANCE_1_FEATURES_EXT};
|
||||
VkPhysicalDeviceSwapchainMaintenance1FeaturesKHR swapchain_maintenance1_khr_feature = {
|
||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SWAPCHAIN_MAINTENANCE_1_FEATURES_KHR};
|
||||
|
||||
if (m_optional_extensions.vk_ext_provoking_vertex)
|
||||
{
|
||||
@ -634,10 +638,18 @@ bool GSDeviceVK::CreateDevice(VkSurfaceKHR surface, bool enable_validation_layer
|
||||
attachment_feedback_loop_feature.attachmentFeedbackLoopLayout = VK_TRUE;
|
||||
Vulkan::AddPointerToChain(&device_info, &attachment_feedback_loop_feature);
|
||||
}
|
||||
if (m_optional_extensions.vk_ext_swapchain_maintenance1)
|
||||
if (m_optional_extensions.vk_swapchain_maintenance1)
|
||||
{
|
||||
swapchain_maintenance1_feature.swapchainMaintenance1 = VK_TRUE;
|
||||
Vulkan::AddPointerToChain(&device_info, &swapchain_maintenance1_feature);
|
||||
if (m_optional_extensions.vk_swapchain_maintenance1_is_khr)
|
||||
{
|
||||
swapchain_maintenance1_khr_feature.swapchainMaintenance1 = VK_TRUE;
|
||||
Vulkan::AddPointerToChain(&device_info, &swapchain_maintenance1_khr_feature);
|
||||
}
|
||||
else
|
||||
{
|
||||
swapchain_maintenance1_ext_feature.swapchainMaintenance1 = VK_TRUE;
|
||||
Vulkan::AddPointerToChain(&device_info, &swapchain_maintenance1_ext_feature);
|
||||
}
|
||||
}
|
||||
|
||||
VkResult res = vkCreateDevice(m_physical_device, &device_info, nullptr, &m_device);
|
||||
@ -704,8 +716,10 @@ bool GSDeviceVK::ProcessDeviceExtensions()
|
||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT};
|
||||
VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT rasterization_order_access_feature = {
|
||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_FEATURES_EXT};
|
||||
VkPhysicalDeviceSwapchainMaintenance1FeaturesEXT swapchain_maintenance1_feature = {
|
||||
VkPhysicalDeviceSwapchainMaintenance1FeaturesEXT swapchain_maintenance1_ext_feature = {
|
||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SWAPCHAIN_MAINTENANCE_1_FEATURES_EXT, nullptr, VK_TRUE};
|
||||
VkPhysicalDeviceSwapchainMaintenance1FeaturesKHR swapchain_maintenance1_khr_feature = {
|
||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SWAPCHAIN_MAINTENANCE_1_FEATURES_KHR, nullptr, VK_TRUE};
|
||||
VkPhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT attachment_feedback_loop_feature = {
|
||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_FEATURES_EXT};
|
||||
|
||||
@ -718,8 +732,10 @@ bool GSDeviceVK::ProcessDeviceExtensions()
|
||||
Vulkan::AddPointerToChain(&features2, &rasterization_order_access_feature);
|
||||
if (m_optional_extensions.vk_ext_attachment_feedback_loop_layout)
|
||||
Vulkan::AddPointerToChain(&features2, &attachment_feedback_loop_feature);
|
||||
if (m_optional_extensions.vk_ext_swapchain_maintenance1)
|
||||
Vulkan::AddPointerToChain(&features2, &swapchain_maintenance1_feature);
|
||||
if (m_optional_extensions.vk_swapchain_maintenance1 && m_optional_extensions.vk_swapchain_maintenance1_is_khr)
|
||||
Vulkan::AddPointerToChain(&features2, &swapchain_maintenance1_khr_feature);
|
||||
if (m_optional_extensions.vk_swapchain_maintenance1 && !m_optional_extensions.vk_swapchain_maintenance1_is_khr)
|
||||
Vulkan::AddPointerToChain(&features2, &swapchain_maintenance1_ext_feature);
|
||||
|
||||
// query
|
||||
vkGetPhysicalDeviceFeatures2(m_physical_device, &features2);
|
||||
@ -794,8 +810,9 @@ bool GSDeviceVK::ProcessDeviceExtensions()
|
||||
m_optional_extensions.vk_ext_calibrated_timestamps = false;
|
||||
}
|
||||
|
||||
m_optional_extensions.vk_ext_swapchain_maintenance1 &=
|
||||
(swapchain_maintenance1_feature.swapchainMaintenance1 == VK_TRUE);
|
||||
m_optional_extensions.vk_swapchain_maintenance1 &= m_optional_extensions.vk_swapchain_maintenance1_is_khr ?
|
||||
(swapchain_maintenance1_khr_feature.swapchainMaintenance1 == VK_TRUE) :
|
||||
(swapchain_maintenance1_ext_feature.swapchainMaintenance1 == VK_TRUE);
|
||||
|
||||
Console.WriteLn(
|
||||
"VK_EXT_provoking_vertex is %s", m_optional_extensions.vk_ext_provoking_vertex ? "supported" : "NOT supported");
|
||||
@ -805,8 +822,9 @@ bool GSDeviceVK::ProcessDeviceExtensions()
|
||||
m_optional_extensions.vk_ext_calibrated_timestamps ? "supported" : "NOT supported");
|
||||
Console.WriteLn("VK_EXT_rasterization_order_attachment_access is %s",
|
||||
m_optional_extensions.vk_ext_rasterization_order_attachment_access ? "supported" : "NOT supported");
|
||||
Console.WriteLn("VK_EXT_swapchain_maintenance1 is %s",
|
||||
m_optional_extensions.vk_ext_swapchain_maintenance1 ? "supported" : "NOT supported");
|
||||
Console.WriteLn("VK_%s_swapchain_maintenance1 is %s",
|
||||
m_optional_extensions.vk_swapchain_maintenance1_is_khr ? "KHR" : "EXT",
|
||||
m_optional_extensions.vk_swapchain_maintenance1 ? "supported" : "NOT supported");
|
||||
Console.WriteLn("VK_EXT_full_screen_exclusive is %s",
|
||||
m_optional_extensions.vk_ext_full_screen_exclusive ? "supported" : "NOT supported");
|
||||
Console.WriteLn("VK_KHR_driver_properties is %s",
|
||||
|
||||
@ -41,7 +41,8 @@ public:
|
||||
bool vk_ext_rasterization_order_attachment_access : 1;
|
||||
bool vk_ext_full_screen_exclusive : 1;
|
||||
bool vk_ext_line_rasterization : 1;
|
||||
bool vk_ext_swapchain_maintenance1 : 1;
|
||||
bool vk_swapchain_maintenance1 : 1;
|
||||
bool vk_swapchain_maintenance1_is_khr : 1;
|
||||
bool vk_khr_driver_properties : 1;
|
||||
bool vk_khr_shader_non_semantic_info : 1;
|
||||
bool vk_ext_attachment_feedback_loop_layout : 1;
|
||||
|
||||
@ -241,4 +241,7 @@ VULKAN_DEVICE_ENTRY_POINT(vkCmdPushDescriptorSetKHR, false)
|
||||
// VK_EXT_swapchain_maintenance1
|
||||
VULKAN_DEVICE_ENTRY_POINT(vkReleaseSwapchainImagesEXT, false)
|
||||
|
||||
// VK_KHR_swapchain_maintenance1
|
||||
VULKAN_DEVICE_ENTRY_POINT(vkReleaseSwapchainImagesKHR, false)
|
||||
|
||||
#endif // VULKAN_DEVICE_ENTRY_POINT
|
||||
|
||||
@ -369,7 +369,7 @@ bool VKSwapChain::CreateSwapChain()
|
||||
VkSwapchainKHR old_swap_chain;
|
||||
// RDNA4 experences a 2s delay in the following 2-3 vkAcquireNextImageKHR calls if we pass the old swapchain to the new one.
|
||||
// Instead, pass null. This requires us to have freed the old image, which we already do with the swapchain maintenance extension.
|
||||
if (GSDeviceVK::GetInstance()->IsDeviceAMD() && GSDeviceVK::GetInstance()->GetOptionalExtensions().vk_ext_swapchain_maintenance1)
|
||||
if (GSDeviceVK::GetInstance()->IsDeviceAMD() && GSDeviceVK::GetInstance()->GetOptionalExtensions().vk_swapchain_maintenance1)
|
||||
{
|
||||
vkDestroySwapchainKHR(GSDeviceVK::GetInstance()->GetDevice(), m_swap_chain, nullptr);
|
||||
old_swap_chain = VK_NULL_HANDLE;
|
||||
@ -559,17 +559,29 @@ void VKSwapChain::ReleaseCurrentImage()
|
||||
return;
|
||||
|
||||
if ((m_image_acquire_result.value() == VK_SUCCESS || m_image_acquire_result.value() == VK_SUBOPTIMAL_KHR) &&
|
||||
GSDeviceVK::GetInstance()->GetOptionalExtensions().vk_ext_swapchain_maintenance1)
|
||||
GSDeviceVK::GetInstance()->GetOptionalExtensions().vk_swapchain_maintenance1)
|
||||
{
|
||||
GSDeviceVK::GetInstance()->WaitForGPUIdle();
|
||||
|
||||
const VkReleaseSwapchainImagesInfoEXT info = {.sType = VK_STRUCTURE_TYPE_RELEASE_SWAPCHAIN_IMAGES_INFO_EXT,
|
||||
.swapchain = m_swap_chain,
|
||||
.imageIndexCount = 1,
|
||||
.pImageIndices = &m_current_image};
|
||||
VkResult res = vkReleaseSwapchainImagesEXT(GSDeviceVK::GetInstance()->GetDevice(), &info);
|
||||
VkResult res;
|
||||
if (GSDeviceVK::GetInstance()->GetOptionalExtensions().vk_swapchain_maintenance1_is_khr)
|
||||
{
|
||||
const VkReleaseSwapchainImagesInfoKHR info = {.sType = VK_STRUCTURE_TYPE_RELEASE_SWAPCHAIN_IMAGES_INFO_KHR,
|
||||
.swapchain = m_swap_chain,
|
||||
.imageIndexCount = 1,
|
||||
.pImageIndices = &m_current_image};
|
||||
res = vkReleaseSwapchainImagesKHR(GSDeviceVK::GetInstance()->GetDevice(), &info);
|
||||
}
|
||||
else
|
||||
{
|
||||
const VkReleaseSwapchainImagesInfoEXT info = {.sType = VK_STRUCTURE_TYPE_RELEASE_SWAPCHAIN_IMAGES_INFO_EXT,
|
||||
.swapchain = m_swap_chain,
|
||||
.imageIndexCount = 1,
|
||||
.pImageIndices = &m_current_image};
|
||||
res = vkReleaseSwapchainImagesEXT(GSDeviceVK::GetInstance()->GetDevice(), &info);
|
||||
}
|
||||
if (res != VK_SUCCESS)
|
||||
LOG_VULKAN_ERROR(res, "vkReleaseSwapchainImagesEXT() failed: ");
|
||||
LOG_VULKAN_ERROR(res, "vkReleaseSwapchainImages() failed: ");
|
||||
}
|
||||
|
||||
m_image_acquire_result.reset();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user