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
This commit is contained in:
parent
4714e95896
commit
0b09fdd96c
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue