mirror of https://github.com/PCSX2/pcsx2.git
GS/Vulkan: Release swap chain images on acquire fail
This commit is contained in:
parent
57d225437e
commit
4924d8c984
|
@ -96,10 +96,11 @@ GSDeviceVK::GSDeviceVK()
|
||||||
|
|
||||||
GSDeviceVK::~GSDeviceVK() = default;
|
GSDeviceVK::~GSDeviceVK() = default;
|
||||||
|
|
||||||
VkInstance GSDeviceVK::CreateVulkanInstance(const WindowInfo& wi, bool enable_debug_utils, bool enable_validation_layer)
|
VkInstance GSDeviceVK::CreateVulkanInstance(const WindowInfo& wi, OptionalExtensions* oe, bool enable_debug_utils,
|
||||||
|
bool enable_validation_layer)
|
||||||
{
|
{
|
||||||
ExtensionList enabled_extensions;
|
ExtensionList enabled_extensions;
|
||||||
if (!SelectInstanceExtensions(&enabled_extensions, wi, enable_debug_utils))
|
if (!SelectInstanceExtensions(&enabled_extensions, wi, oe, enable_debug_utils))
|
||||||
return VK_NULL_HANDLE;
|
return VK_NULL_HANDLE;
|
||||||
|
|
||||||
// Remember to manually update this every release. We don't pull in svnrev.h here, because
|
// Remember to manually update this every release. We don't pull in svnrev.h here, because
|
||||||
|
@ -143,7 +144,8 @@ VkInstance GSDeviceVK::CreateVulkanInstance(const WindowInfo& wi, bool enable_de
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GSDeviceVK::SelectInstanceExtensions(ExtensionList* extension_list, const WindowInfo& wi, bool enable_debug_utils)
|
bool GSDeviceVK::SelectInstanceExtensions(ExtensionList* extension_list, const WindowInfo& wi, OptionalExtensions* oe,
|
||||||
|
bool enable_debug_utils)
|
||||||
{
|
{
|
||||||
u32 extension_count = 0;
|
u32 extension_count = 0;
|
||||||
VkResult res = vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, nullptr);
|
VkResult res = vkEnumerateInstanceExtensionProperties(nullptr, &extension_count, nullptr);
|
||||||
|
@ -204,6 +206,9 @@ bool GSDeviceVK::SelectInstanceExtensions(ExtensionList* extension_list, const W
|
||||||
if (enable_debug_utils && !SupportsExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, false))
|
if (enable_debug_utils && !SupportsExtension(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, false))
|
||||||
Console.Warning("Vulkan: Debug report requested, but extension is not available.");
|
Console.Warning("Vulkan: 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));
|
||||||
|
|
||||||
// Needed for exclusive fullscreen control.
|
// Needed for exclusive fullscreen control.
|
||||||
SupportsExtension(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME, false);
|
SupportsExtension(VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME, false);
|
||||||
|
|
||||||
|
@ -276,7 +281,7 @@ GSDeviceVK::GPUList GSDeviceVK::EnumerateGPUs(VkInstance instance)
|
||||||
{
|
{
|
||||||
if (std::find_if(available_extension_list.begin(), available_extension_list.end(), [required_extension_name](const VkExtensionProperties& ext) {
|
if (std::find_if(available_extension_list.begin(), available_extension_list.end(), [required_extension_name](const VkExtensionProperties& ext) {
|
||||||
return (std::strcmp(required_extension_name, ext.extensionName) == 0);
|
return (std::strcmp(required_extension_name, ext.extensionName) == 0);
|
||||||
}) == available_extension_list.end())
|
}) == available_extension_list.end())
|
||||||
{
|
{
|
||||||
Console.Warning(fmt::format("Ignoring Vulkan GPU '{}' because is is missing required extension {}",
|
Console.Warning(fmt::format("Ignoring Vulkan GPU '{}' because is is missing required extension {}",
|
||||||
props.deviceName, required_extension_name));
|
props.deviceName, required_extension_name));
|
||||||
|
@ -388,6 +393,10 @@ bool GSDeviceVK::SelectDeviceExtensions(ExtensionList* extension_list, bool enab
|
||||||
SupportsExtension(VK_KHR_SHADER_NON_SEMANTIC_INFO_EXTENSION_NAME, false);
|
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
|
#ifdef _WIN32
|
||||||
m_optional_extensions.vk_ext_full_screen_exclusive =
|
m_optional_extensions.vk_ext_full_screen_exclusive =
|
||||||
enable_surface && SupportsExtension(VK_EXT_FULL_SCREEN_EXCLUSIVE_EXTENSION_NAME, false);
|
enable_surface && SupportsExtension(VK_EXT_FULL_SCREEN_EXCLUSIVE_EXTENSION_NAME, false);
|
||||||
|
@ -573,6 +582,8 @@ bool GSDeviceVK::CreateDevice(VkSurfaceKHR surface, bool enable_validation_layer
|
||||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_FEATURES_EXT};
|
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_FEATURES_EXT};
|
||||||
VkPhysicalDeviceLineRasterizationFeaturesEXT line_rasterization_feature = {
|
VkPhysicalDeviceLineRasterizationFeaturesEXT line_rasterization_feature = {
|
||||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT};
|
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT};
|
||||||
|
VkPhysicalDeviceSwapchainMaintenance1FeaturesEXT swapchain_maintenance1_feature = {
|
||||||
|
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SWAPCHAIN_MAINTENANCE_1_FEATURES_EXT};
|
||||||
|
|
||||||
if (m_optional_extensions.vk_ext_provoking_vertex)
|
if (m_optional_extensions.vk_ext_provoking_vertex)
|
||||||
{
|
{
|
||||||
|
@ -589,6 +600,11 @@ bool GSDeviceVK::CreateDevice(VkSurfaceKHR surface, bool enable_validation_layer
|
||||||
rasterization_order_access_feature.rasterizationOrderColorAttachmentAccess = VK_TRUE;
|
rasterization_order_access_feature.rasterizationOrderColorAttachmentAccess = VK_TRUE;
|
||||||
Vulkan::AddPointerToChain(&device_info, &rasterization_order_access_feature);
|
Vulkan::AddPointerToChain(&device_info, &rasterization_order_access_feature);
|
||||||
}
|
}
|
||||||
|
if (m_optional_extensions.vk_ext_swapchain_maintenance1)
|
||||||
|
{
|
||||||
|
swapchain_maintenance1_feature.swapchainMaintenance1 = VK_TRUE;
|
||||||
|
Vulkan::AddPointerToChain(&device_info, &swapchain_maintenance1_feature);
|
||||||
|
}
|
||||||
|
|
||||||
VkResult res = vkCreateDevice(m_physical_device, &device_info, nullptr, &m_device);
|
VkResult res = vkCreateDevice(m_physical_device, &device_info, nullptr, &m_device);
|
||||||
if (res != VK_SUCCESS)
|
if (res != VK_SUCCESS)
|
||||||
|
@ -654,6 +670,8 @@ bool GSDeviceVK::ProcessDeviceExtensions()
|
||||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT};
|
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_LINE_RASTERIZATION_FEATURES_EXT};
|
||||||
VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT rasterization_order_access_feature = {
|
VkPhysicalDeviceRasterizationOrderAttachmentAccessFeaturesEXT rasterization_order_access_feature = {
|
||||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_FEATURES_EXT};
|
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_FEATURES_EXT};
|
||||||
|
VkPhysicalDeviceSwapchainMaintenance1FeaturesEXT swapchain_maintenance1_feature = {
|
||||||
|
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SWAPCHAIN_MAINTENANCE_1_FEATURES_EXT, nullptr, VK_TRUE};
|
||||||
|
|
||||||
// add in optional feature structs
|
// add in optional feature structs
|
||||||
if (m_optional_extensions.vk_ext_provoking_vertex)
|
if (m_optional_extensions.vk_ext_provoking_vertex)
|
||||||
|
@ -662,6 +680,8 @@ bool GSDeviceVK::ProcessDeviceExtensions()
|
||||||
Vulkan::AddPointerToChain(&features2, &line_rasterization_feature);
|
Vulkan::AddPointerToChain(&features2, &line_rasterization_feature);
|
||||||
if (m_optional_extensions.vk_ext_rasterization_order_attachment_access)
|
if (m_optional_extensions.vk_ext_rasterization_order_attachment_access)
|
||||||
Vulkan::AddPointerToChain(&features2, &rasterization_order_access_feature);
|
Vulkan::AddPointerToChain(&features2, &rasterization_order_access_feature);
|
||||||
|
if (m_optional_extensions.vk_ext_swapchain_maintenance1)
|
||||||
|
Vulkan::AddPointerToChain(&features2, &swapchain_maintenance1_feature);
|
||||||
|
|
||||||
// query
|
// query
|
||||||
vkGetPhysicalDeviceFeatures2(m_physical_device, &features2);
|
vkGetPhysicalDeviceFeatures2(m_physical_device, &features2);
|
||||||
|
@ -739,6 +759,9 @@ bool GSDeviceVK::ProcessDeviceExtensions()
|
||||||
m_optional_extensions.vk_ext_calibrated_timestamps = false;
|
m_optional_extensions.vk_ext_calibrated_timestamps = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_optional_extensions.vk_ext_swapchain_maintenance1 &=
|
||||||
|
(swapchain_maintenance1_feature.swapchainMaintenance1 == VK_TRUE);
|
||||||
|
|
||||||
Console.WriteLn(
|
Console.WriteLn(
|
||||||
"VK_EXT_provoking_vertex is %s", m_optional_extensions.vk_ext_provoking_vertex ? "supported" : "NOT supported");
|
"VK_EXT_provoking_vertex is %s", m_optional_extensions.vk_ext_provoking_vertex ? "supported" : "NOT supported");
|
||||||
Console.WriteLn(
|
Console.WriteLn(
|
||||||
|
@ -747,6 +770,8 @@ bool GSDeviceVK::ProcessDeviceExtensions()
|
||||||
m_optional_extensions.vk_ext_calibrated_timestamps ? "supported" : "NOT supported");
|
m_optional_extensions.vk_ext_calibrated_timestamps ? "supported" : "NOT supported");
|
||||||
Console.WriteLn("VK_EXT_rasterization_order_attachment_access is %s",
|
Console.WriteLn("VK_EXT_rasterization_order_attachment_access is %s",
|
||||||
m_optional_extensions.vk_ext_rasterization_order_attachment_access ? "supported" : "NOT supported");
|
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_EXT_full_screen_exclusive is %s",
|
Console.WriteLn("VK_EXT_full_screen_exclusive is %s",
|
||||||
m_optional_extensions.vk_ext_full_screen_exclusive ? "supported" : "NOT supported");
|
m_optional_extensions.vk_ext_full_screen_exclusive ? "supported" : "NOT supported");
|
||||||
Console.WriteLn("VK_KHR_driver_properties is %s",
|
Console.WriteLn("VK_KHR_driver_properties is %s",
|
||||||
|
@ -1197,16 +1222,17 @@ void GSDeviceVK::SubmitCommandBuffer(VKSwapChain* present_swap_chain)
|
||||||
present_swap_chain->GetRenderingFinishedSemaphorePtr(), 1, present_swap_chain->GetSwapChainPtr(),
|
present_swap_chain->GetRenderingFinishedSemaphorePtr(), 1, present_swap_chain->GetSwapChainPtr(),
|
||||||
present_swap_chain->GetCurrentImageIndexPtr(), nullptr};
|
present_swap_chain->GetCurrentImageIndexPtr(), nullptr};
|
||||||
|
|
||||||
present_swap_chain->ReleaseCurrentImage();
|
present_swap_chain->ResetImageAcquireResult();
|
||||||
|
|
||||||
const VkResult res = vkQueuePresentKHR(m_present_queue, &present_info);
|
const VkResult res = vkQueuePresentKHR(m_present_queue, &present_info);
|
||||||
if (res != VK_SUCCESS)
|
if (res != VK_SUCCESS && res != VK_SUBOPTIMAL_KHR)
|
||||||
{
|
{
|
||||||
// VK_ERROR_OUT_OF_DATE_KHR is not fatal, just means we need to recreate our swap chain.
|
// VK_ERROR_OUT_OF_DATE_KHR is not fatal, just means we need to recreate our swap chain.
|
||||||
if (res != VK_ERROR_OUT_OF_DATE_KHR && res != VK_SUBOPTIMAL_KHR)
|
if (res == VK_ERROR_OUT_OF_DATE_KHR)
|
||||||
|
ResizeWindow(0, 0, m_window_info.surface_scale);
|
||||||
|
else
|
||||||
LOG_VULKAN_ERROR(res, "vkQueuePresentKHR failed: ");
|
LOG_VULKAN_ERROR(res, "vkQueuePresentKHR failed: ");
|
||||||
|
|
||||||
m_last_present_failed = true;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1926,7 +1952,8 @@ void GSDeviceVK::GetAdaptersAndFullscreenModes(
|
||||||
{
|
{
|
||||||
if (Vulkan::LoadVulkanLibrary(nullptr))
|
if (Vulkan::LoadVulkanLibrary(nullptr))
|
||||||
{
|
{
|
||||||
const VkInstance instance = CreateVulkanInstance(WindowInfo(), false, false);
|
OptionalExtensions oe = {};
|
||||||
|
const VkInstance instance = CreateVulkanInstance(WindowInfo(), &oe, false, false);
|
||||||
if (instance != VK_NULL_HANDLE)
|
if (instance != VK_NULL_HANDLE)
|
||||||
{
|
{
|
||||||
if (Vulkan::LoadVulkanInstanceFunctions(instance))
|
if (Vulkan::LoadVulkanInstanceFunctions(instance))
|
||||||
|
@ -2136,7 +2163,7 @@ bool GSDeviceVK::UpdateWindow()
|
||||||
void GSDeviceVK::ResizeWindow(s32 new_window_width, s32 new_window_height, float new_window_scale)
|
void GSDeviceVK::ResizeWindow(s32 new_window_width, s32 new_window_height, float new_window_scale)
|
||||||
{
|
{
|
||||||
if (!m_swap_chain || (m_swap_chain->GetWidth() == static_cast<u32>(new_window_width) &&
|
if (!m_swap_chain || (m_swap_chain->GetWidth() == static_cast<u32>(new_window_width) &&
|
||||||
m_swap_chain->GetHeight() == static_cast<u32>(new_window_height)))
|
m_swap_chain->GetHeight() == static_cast<u32>(new_window_height)))
|
||||||
{
|
{
|
||||||
// skip unnecessary resizes
|
// skip unnecessary resizes
|
||||||
m_window_info.surface_scale = new_window_scale;
|
m_window_info.surface_scale = new_window_scale;
|
||||||
|
@ -2413,7 +2440,7 @@ bool GSDeviceVK::CreateDeviceAndSwapChain()
|
||||||
if (!AcquireWindow(true))
|
if (!AcquireWindow(true))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
m_instance = CreateVulkanInstance(m_window_info, enable_debug_utils, enable_validation_layer);
|
m_instance = CreateVulkanInstance(m_window_info, &m_optional_extensions, enable_debug_utils, enable_validation_layer);
|
||||||
if (m_instance == VK_NULL_HANDLE)
|
if (m_instance == VK_NULL_HANDLE)
|
||||||
{
|
{
|
||||||
if (enable_debug_utils || enable_validation_layer)
|
if (enable_debug_utils || enable_validation_layer)
|
||||||
|
@ -2421,7 +2448,7 @@ bool GSDeviceVK::CreateDeviceAndSwapChain()
|
||||||
// Try again without the validation layer.
|
// Try again without the validation layer.
|
||||||
enable_debug_utils = false;
|
enable_debug_utils = false;
|
||||||
enable_validation_layer = false;
|
enable_validation_layer = false;
|
||||||
m_instance = CreateVulkanInstance(m_window_info, enable_debug_utils, enable_validation_layer);
|
m_instance = CreateVulkanInstance(m_window_info, &m_optional_extensions, enable_debug_utils, enable_validation_layer);
|
||||||
if (m_instance == VK_NULL_HANDLE)
|
if (m_instance == VK_NULL_HANDLE)
|
||||||
{
|
{
|
||||||
Host::ReportErrorAsync(
|
Host::ReportErrorAsync(
|
||||||
|
@ -5714,7 +5741,7 @@ void GSDeviceVK::RenderHW(GSHWDrawConfig& config)
|
||||||
BeginRenderPass(rp, render_area);
|
BeginRenderPass(rp, render_area);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::StencilOne)
|
if (config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::StencilOne)
|
||||||
{
|
{
|
||||||
const VkClearAttachment ca = {VK_IMAGE_ASPECT_STENCIL_BIT, 0u, {.depthStencil = {0.0f, 1u}}};
|
const VkClearAttachment ca = {VK_IMAGE_ASPECT_STENCIL_BIT, 0u, {.depthStencil = {0.0f, 1u}}};
|
||||||
|
|
|
@ -41,6 +41,7 @@ public:
|
||||||
bool vk_ext_rasterization_order_attachment_access : 1;
|
bool vk_ext_rasterization_order_attachment_access : 1;
|
||||||
bool vk_ext_full_screen_exclusive : 1;
|
bool vk_ext_full_screen_exclusive : 1;
|
||||||
bool vk_ext_line_rasterization : 1;
|
bool vk_ext_line_rasterization : 1;
|
||||||
|
bool vk_ext_swapchain_maintenance1 : 1;
|
||||||
bool vk_khr_driver_properties : 1;
|
bool vk_khr_driver_properties : 1;
|
||||||
bool vk_khr_shader_non_semantic_info : 1;
|
bool vk_khr_shader_non_semantic_info : 1;
|
||||||
};
|
};
|
||||||
|
@ -125,7 +126,8 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Helper method to create a Vulkan instance.
|
// Helper method to create a Vulkan instance.
|
||||||
static VkInstance CreateVulkanInstance(const WindowInfo& wi, bool enable_debug_utils, bool enable_validation_layer);
|
static VkInstance CreateVulkanInstance(const WindowInfo& wi, OptionalExtensions* oe, bool enable_debug_utils,
|
||||||
|
bool enable_validation_layer);
|
||||||
|
|
||||||
// Returns a list of Vulkan-compatible GPUs.
|
// Returns a list of Vulkan-compatible GPUs.
|
||||||
using GPUList = std::vector<std::pair<VkPhysicalDevice, std::string>>;
|
using GPUList = std::vector<std::pair<VkPhysicalDevice, std::string>>;
|
||||||
|
@ -173,7 +175,8 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
using ExtensionList = std::vector<const char*>;
|
using ExtensionList = std::vector<const char*>;
|
||||||
static bool SelectInstanceExtensions(ExtensionList* extension_list, const WindowInfo& wi, bool enable_debug_utils);
|
static bool SelectInstanceExtensions(ExtensionList* extension_list, const WindowInfo& wi, OptionalExtensions* oe,
|
||||||
|
bool enable_debug_utils);
|
||||||
bool SelectDeviceExtensions(ExtensionList* extension_list, bool enable_surface);
|
bool SelectDeviceExtensions(ExtensionList* extension_list, bool enable_surface);
|
||||||
bool SelectDeviceFeatures();
|
bool SelectDeviceFeatures();
|
||||||
bool CreateDevice(VkSurfaceKHR surface, bool enable_validation_layer);
|
bool CreateDevice(VkSurfaceKHR surface, bool enable_validation_layer);
|
||||||
|
|
|
@ -238,4 +238,7 @@ VULKAN_DEVICE_ENTRY_POINT(vkGetCalibratedTimestampsEXT, false)
|
||||||
// VK_KHR_push_descriptor
|
// VK_KHR_push_descriptor
|
||||||
VULKAN_DEVICE_ENTRY_POINT(vkCmdPushDescriptorSetKHR, false)
|
VULKAN_DEVICE_ENTRY_POINT(vkCmdPushDescriptorSetKHR, false)
|
||||||
|
|
||||||
|
// VK_EXT_swapchain_maintenance1
|
||||||
|
VULKAN_DEVICE_ENTRY_POINT(vkReleaseSwapchainImagesEXT, false)
|
||||||
|
|
||||||
#endif // VULKAN_DEVICE_ENTRY_POINT
|
#endif // VULKAN_DEVICE_ENTRY_POINT
|
||||||
|
|
|
@ -544,12 +544,35 @@ VkResult VKSwapChain::AcquireNextImage()
|
||||||
}
|
}
|
||||||
|
|
||||||
void VKSwapChain::ReleaseCurrentImage()
|
void VKSwapChain::ReleaseCurrentImage()
|
||||||
|
{
|
||||||
|
if (!m_image_acquire_result.has_value())
|
||||||
|
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()->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);
|
||||||
|
if (res != VK_SUCCESS)
|
||||||
|
LOG_VULKAN_ERROR(res, "vkReleaseSwapchainImagesEXT() failed: ");
|
||||||
|
}
|
||||||
|
|
||||||
|
m_image_acquire_result.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VKSwapChain::ResetImageAcquireResult()
|
||||||
{
|
{
|
||||||
m_image_acquire_result.reset();
|
m_image_acquire_result.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VKSwapChain::ResizeSwapChain(u32 new_width, u32 new_height, float new_scale)
|
bool VKSwapChain::ResizeSwapChain(u32 new_width, u32 new_height, float new_scale)
|
||||||
{
|
{
|
||||||
|
ReleaseCurrentImage();
|
||||||
DestroySwapChainImages();
|
DestroySwapChainImages();
|
||||||
|
|
||||||
if (new_width != 0 && new_height != 0)
|
if (new_width != 0 && new_height != 0)
|
||||||
|
@ -578,6 +601,7 @@ bool VKSwapChain::SetPresentMode(VkPresentModeKHR present_mode)
|
||||||
|
|
||||||
// Recreate the swap chain with the new present mode.
|
// Recreate the swap chain with the new present mode.
|
||||||
INFO_LOG("Recreating swap chain to change present mode.");
|
INFO_LOG("Recreating swap chain to change present mode.");
|
||||||
|
ReleaseCurrentImage();
|
||||||
DestroySwapChainImages();
|
DestroySwapChainImages();
|
||||||
if (!CreateSwapChain())
|
if (!CreateSwapChain())
|
||||||
{
|
{
|
||||||
|
|
|
@ -68,6 +68,7 @@ public:
|
||||||
VkFormat GetTextureFormat() const;
|
VkFormat GetTextureFormat() const;
|
||||||
VkResult AcquireNextImage();
|
VkResult AcquireNextImage();
|
||||||
void ReleaseCurrentImage();
|
void ReleaseCurrentImage();
|
||||||
|
void ResetImageAcquireResult();
|
||||||
|
|
||||||
bool RecreateSurface(const WindowInfo& new_wi);
|
bool RecreateSurface(const WindowInfo& new_wi);
|
||||||
bool ResizeSwapChain(u32 new_width = 0, u32 new_height = 0, float new_scale = 1.0f);
|
bool ResizeSwapChain(u32 new_width = 0, u32 new_height = 0, float new_scale = 1.0f);
|
||||||
|
|
Loading…
Reference in New Issue