mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-07 23:41:26 +12: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_width = m_frame->client_width();
|
||||||
m_client_height = m_frame->client_height();
|
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...
|
//create command buffer...
|
||||||
m_command_buffer_pool.create((*m_device));
|
m_command_buffer_pool.create((*m_device));
|
||||||
|
@ -2405,10 +2406,13 @@ void VKGSRender::prepare_rtts()
|
||||||
|
|
||||||
void VKGSRender::reinitialize_swapchain()
|
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
|
//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
|
//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
|
//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;
|
return;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -2421,13 +2425,6 @@ void VKGSRender::reinitialize_swapchain()
|
||||||
m_current_command_buffer->pending = true;
|
m_current_command_buffer->pending = true;
|
||||||
m_current_command_buffer->reset();
|
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)
|
for (auto &ctx : frame_context_storage)
|
||||||
{
|
{
|
||||||
if (ctx.present_image == UINT32_MAX)
|
if (ctx.present_image == UINT32_MAX)
|
||||||
|
@ -2446,9 +2443,16 @@ void VKGSRender::reinitialize_swapchain()
|
||||||
m_framebuffers_to_clean.clear();
|
m_framebuffers_to_clean.clear();
|
||||||
|
|
||||||
//Rebuild swapchain. Old swapchain destruction is handled by the init_swapchain call
|
//Rebuild swapchain. Old swapchain destruction is handled by the init_swapchain call
|
||||||
m_client_width = m_frame->client_width();
|
if (!m_swap_chain->init_swapchain(new_width, new_height))
|
||||||
m_client_height = m_frame->client_height();
|
{
|
||||||
m_swap_chain->init_swapchain(m_client_width, m_client_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
|
//Prepare new swapchain images for use
|
||||||
open_command_buffer();
|
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));
|
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
|
//Flush the command buffer
|
||||||
close_and_submit_command_buffer({}, resize_fence);
|
close_and_submit_command_buffer({}, resize_fence);
|
||||||
CHECK_RESULT(vkWaitForFences((*m_device), 1, &resize_fence, VK_TRUE, UINT64_MAX));
|
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;
|
VkSwapchainKHR old_swapchain = m_vk_swapchain;
|
||||||
vk::physical_device& gpu = const_cast<vk::physical_device&>(dev.gpu());
|
vk::physical_device& gpu = const_cast<vk::physical_device&>(dev.gpu());
|
||||||
|
@ -817,8 +817,16 @@ namespace vk
|
||||||
VkSurfaceCapabilitiesKHR surface_descriptors = {};
|
VkSurfaceCapabilitiesKHR surface_descriptors = {};
|
||||||
CHECK_RESULT(vkGetPhysicalDeviceSurfaceCapabilitiesKHR(gpu, m_surface, &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)
|
if (surface_descriptors.currentExtent.width == (uint32_t)-1)
|
||||||
{
|
{
|
||||||
swapchainExtent.width = width;
|
swapchainExtent.width = width;
|
||||||
|
@ -826,6 +834,12 @@ namespace vk
|
||||||
}
|
}
|
||||||
else
|
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;
|
swapchainExtent = surface_descriptors.currentExtent;
|
||||||
width = surface_descriptors.currentExtent.width;
|
width = surface_descriptors.currentExtent.width;
|
||||||
height = surface_descriptors.currentExtent.height;
|
height = surface_descriptors.currentExtent.height;
|
||||||
|
@ -932,6 +946,8 @@ namespace vk
|
||||||
{
|
{
|
||||||
m_swap_images[i].create(dev, swap_images[i], m_surface_format);
|
m_swap_images[i].create(dev, swap_images[i], m_surface_format);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 get_swap_image_count()
|
u32 get_swap_image_count()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue