mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-20 19:45:20 +00:00
vk: Allow swapchain create to fail with an error
This commit is contained in:
parent
7e6d6b45d4
commit
f8f5f9f418
2 changed files with 41 additions and 14 deletions
|
@ -551,7 +551,8 @@ VKGSRender::VKGSRender() : GSRender()
|
|||
|
||||
m_client_width = m_frame->client_width();
|
||||
m_client_height = m_frame->client_height();
|
||||
m_swap_chain->init_swapchain(m_client_width, m_client_height);
|
||||
if (!m_swap_chain->init_swapchain(m_client_width, m_client_height))
|
||||
present_surface_dirty_flag = true;
|
||||
|
||||
//create command buffer...
|
||||
m_command_buffer_pool.create((*m_device));
|
||||
|
@ -2405,10 +2406,13 @@ void VKGSRender::prepare_rtts()
|
|||
|
||||
void VKGSRender::reinitialize_swapchain()
|
||||
{
|
||||
const auto new_width = m_frame->client_width();
|
||||
const auto new_height = m_frame->client_height();
|
||||
|
||||
//Reject requests to acquire new swapchain if the window is minimized
|
||||
//The NVIDIA driver will spam VK_ERROR_OUT_OF_DATE_KHR if you try to acquire an image from the swapchain and the window is minimized
|
||||
//However, any attempt to actually renew the swapchain will crash the driver with VK_ERROR_DEVICE_LOST while the window is in this state
|
||||
if (m_frame->client_width() == 0 || m_frame->client_height() == 0)
|
||||
if (new_width == 0 || new_height == 0)
|
||||
return;
|
||||
|
||||
/**
|
||||
|
@ -2421,13 +2425,6 @@ void VKGSRender::reinitialize_swapchain()
|
|||
m_current_command_buffer->pending = true;
|
||||
m_current_command_buffer->reset();
|
||||
|
||||
//Will have to block until rendering is completed
|
||||
VkFence resize_fence = VK_NULL_HANDLE;
|
||||
VkFenceCreateInfo infos = {};
|
||||
infos.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
||||
|
||||
vkCreateFence((*m_device), &infos, nullptr, &resize_fence);
|
||||
|
||||
for (auto &ctx : frame_context_storage)
|
||||
{
|
||||
if (ctx.present_image == UINT32_MAX)
|
||||
|
@ -2446,9 +2443,16 @@ void VKGSRender::reinitialize_swapchain()
|
|||
m_framebuffers_to_clean.clear();
|
||||
|
||||
//Rebuild swapchain. Old swapchain destruction is handled by the init_swapchain call
|
||||
m_client_width = m_frame->client_width();
|
||||
m_client_height = m_frame->client_height();
|
||||
m_swap_chain->init_swapchain(m_client_width, m_client_height);
|
||||
if (!m_swap_chain->init_swapchain(new_width, new_height))
|
||||
{
|
||||
LOG_WARNING(RSX, "Swapchain initialization failed. Request ignored [%dx%d]", new_width, new_height);
|
||||
present_surface_dirty_flag = false;
|
||||
open_command_buffer();
|
||||
return;
|
||||
}
|
||||
|
||||
m_client_width = new_width;
|
||||
m_client_height = new_height;
|
||||
|
||||
//Prepare new swapchain images for use
|
||||
open_command_buffer();
|
||||
|
@ -2467,6 +2471,13 @@ void VKGSRender::reinitialize_swapchain()
|
|||
vk::get_image_subresource_range(0, 0, 1, 1, VK_IMAGE_ASPECT_COLOR_BIT));
|
||||
}
|
||||
|
||||
//Will have to block until rendering is completed
|
||||
VkFence resize_fence = VK_NULL_HANDLE;
|
||||
VkFenceCreateInfo infos = {};
|
||||
infos.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
|
||||
|
||||
vkCreateFence((*m_device), &infos, nullptr, &resize_fence);
|
||||
|
||||
//Flush the command buffer
|
||||
close_and_submit_command_buffer({}, resize_fence);
|
||||
CHECK_RESULT(vkWaitForFences((*m_device), 1, &resize_fence, VK_TRUE, UINT64_MAX));
|
||||
|
|
|
@ -809,7 +809,7 @@ namespace vk
|
|||
}
|
||||
}
|
||||
|
||||
void init_swapchain(u32 width, u32 height)
|
||||
bool init_swapchain(u32 width, u32 height)
|
||||
{
|
||||
VkSwapchainKHR old_swapchain = m_vk_swapchain;
|
||||
vk::physical_device& gpu = const_cast<vk::physical_device&>(dev.gpu());
|
||||
|
@ -817,8 +817,16 @@ namespace vk
|
|||
VkSurfaceCapabilitiesKHR surface_descriptors = {};
|
||||
CHECK_RESULT(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(gpu, m_surface, &surface_descriptors));
|
||||
|
||||
VkExtent2D swapchainExtent;
|
||||
if (surface_descriptors.maxImageExtent.width < width ||
|
||||
surface_descriptors.maxImageExtent.height < height)
|
||||
{
|
||||
LOG_ERROR(RSX, "Swapchain: Swapchain creation failed because dimensions cannot fit. Max = %d, %d, Requested = %d, %d",
|
||||
surface_descriptors.maxImageExtent.width, surface_descriptors.maxImageExtent.height, width, height);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
VkExtent2D swapchainExtent;
|
||||
if (surface_descriptors.currentExtent.width == (uint32_t)-1)
|
||||
{
|
||||
swapchainExtent.width = width;
|
||||
|
@ -826,6 +834,12 @@ namespace vk
|
|||
}
|
||||
else
|
||||
{
|
||||
if (surface_descriptors.currentExtent.width == 0 || surface_descriptors.currentExtent.height == 0)
|
||||
{
|
||||
LOG_WARNING(RSX, "Swapchain: Current surface extent is a null region. Is the window minimized?");
|
||||
return false;
|
||||
}
|
||||
|
||||
swapchainExtent = surface_descriptors.currentExtent;
|
||||
width = surface_descriptors.currentExtent.width;
|
||||
height = surface_descriptors.currentExtent.height;
|
||||
|
@ -932,6 +946,8 @@ namespace vk
|
|||
{
|
||||
m_swap_images[i].create(dev, swap_images[i], m_surface_format);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
u32 get_swap_image_count()
|
||||
|
|
Loading…
Add table
Reference in a new issue