diff options
author | Matias N. Goldberg <dark_sylinc@yahoo.com.ar> | 2023-08-12 20:32:28 -0300 |
---|---|---|
committer | Matias N. Goldberg <dark_sylinc@yahoo.com.ar> | 2023-08-15 20:57:49 -0300 |
commit | 0b09fdd96cd515ecddee3fe59fcff5a6d509f545 (patch) | |
tree | ba378f22977f81b24436cdcd01804aa323144982 /drivers/vulkan | |
parent | 4714e95896c8db02616ea6ec7f9aff92dec1cae4 (diff) | |
download | redot-engine-0b09fdd96cd515ecddee3fe59fcff5a6d509f545.tar.gz |
Fix validation error when resizing window
Sometimes when resizing the window we may get the following validation
error:
ERROR: VALIDATION - Message Id Number: -370888023 | Message Id Name:
VUID-vkAcquireNextImageKHR-semaphore-01286
Validation Error: [ VUID-vkAcquireNextImageKHR-semaphore-01286 ]
Object 0: handle = 0xdcc8fd0000000012, type = VK_OBJECT_TYPE_SEMAPHORE;
| MessageID = 0xe9e4b2a9 | vkAcquireNextImageKHR: Semaphore must not be
currently signaled or in a wait state. The Vulkan spec states: If
semaphore is not VK_NULL_HANDLE it must be unsignaled
(https://vulkan.lunarg.com/doc/view/1.2.198.1/linux/1.2-extensions/vkspec.html#VUID-vkAcquireNextImageKHR-semaphore-01286)
In VulkanContext::prepare_buffers the problem was that
vkAcquireNextImageKHR returned VK_SUBOPTIMAL_KHR but it already signaled
the semaphore (because it is possible to continue normally with a
VK_SUBOPTIMAL_KHR result).
Then we recreate the swapchain and reuse the
w->image_acquired_semaphores[frame_index] which is in an inconsistent
state.
Fixed by recreating the semamphores along the swapchain.
Fix #80570
Diffstat (limited to 'drivers/vulkan')
-rw-r--r-- | drivers/vulkan/vulkan_context.cpp | 36 |
1 files changed, 22 insertions, 14 deletions
diff --git a/drivers/vulkan/vulkan_context.cpp b/drivers/vulkan/vulkan_context.cpp index c167caeb7c..89a56bae03 100644 --- a/drivers/vulkan/vulkan_context.cpp +++ b/drivers/vulkan/vulkan_context.cpp @@ -1700,17 +1700,6 @@ Error VulkanContext::_window_create(DisplayServer::WindowID p_window_id, Display Error err = _update_swap_chain(&window); ERR_FAIL_COND_V(err != OK, ERR_CANT_CREATE); - VkSemaphoreCreateInfo semaphoreCreateInfo = { - /*sType*/ VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, - /*pNext*/ nullptr, - /*flags*/ 0, - }; - - for (uint32_t i = 0; i < FRAME_LAG; i++) { - VkResult vkerr = vkCreateSemaphore(device, &semaphoreCreateInfo, nullptr, &window.image_acquired_semaphores[i]); - ERR_FAIL_COND_V(vkerr, ERR_CANT_CREATE); - } - windows[p_window_id] = window; return OK; } @@ -1760,9 +1749,6 @@ VkFramebuffer VulkanContext::window_get_framebuffer(DisplayServer::WindowID p_wi void VulkanContext::window_destroy(DisplayServer::WindowID p_window_id) { ERR_FAIL_COND(!windows.has(p_window_id)); _clean_up_swap_chain(&windows[p_window_id]); - for (uint32_t i = 0; i < FRAME_LAG; i++) { - vkDestroySemaphore(device, windows[p_window_id].image_acquired_semaphores[i], nullptr); - } vkDestroySurfaceKHR(inst, windows[p_window_id].surface, nullptr); windows.erase(p_window_id); @@ -1792,6 +1778,17 @@ Error VulkanContext::_clean_up_swap_chain(Window *window) { if (separate_present_queue) { vkDestroyCommandPool(device, window->present_cmd_pool, nullptr); } + + for (uint32_t i = 0; i < FRAME_LAG; i++) { + // Destroy the semaphores now (we'll re-create it later if we have to). + // We must do this because the semaphore cannot be reused if it's in a signaled state + // (which happens if vkAcquireNextImageKHR returned VK_ERROR_OUT_OF_DATE_KHR or VK_SUBOPTIMAL_KHR) + // The only way to reset it would be to present the swapchain... the one we just destroyed. + // And the API has no way to "unsignal" the semaphore. + vkDestroySemaphore(device, window->image_acquired_semaphores[i], nullptr); + window->image_acquired_semaphores[i] = 0; + } + return OK; } @@ -2175,6 +2172,17 @@ Error VulkanContext::_update_swap_chain(Window *window) { // Reset current buffer. window->current_buffer = 0; + VkSemaphoreCreateInfo semaphoreCreateInfo = { + /*sType*/ VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, + /*pNext*/ nullptr, + /*flags*/ 0, + }; + + for (uint32_t i = 0; i < FRAME_LAG; i++) { + VkResult vkerr = vkCreateSemaphore(device, &semaphoreCreateInfo, nullptr, &window->image_acquired_semaphores[i]); + ERR_FAIL_COND_V(vkerr, ERR_CANT_CREATE); + } + return OK; } |