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);
|
Error err = _update_swap_chain(&window);
|
||||||
ERR_FAIL_COND_V(err != OK, ERR_CANT_CREATE);
|
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;
|
windows[p_window_id] = window;
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
@ -1760,9 +1749,6 @@ VkFramebuffer VulkanContext::window_get_framebuffer(DisplayServer::WindowID p_wi
|
|||||||
void VulkanContext::window_destroy(DisplayServer::WindowID p_window_id) {
|
void VulkanContext::window_destroy(DisplayServer::WindowID p_window_id) {
|
||||||
ERR_FAIL_COND(!windows.has(p_window_id));
|
ERR_FAIL_COND(!windows.has(p_window_id));
|
||||||
_clean_up_swap_chain(&windows[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);
|
vkDestroySurfaceKHR(inst, windows[p_window_id].surface, nullptr);
|
||||||
windows.erase(p_window_id);
|
windows.erase(p_window_id);
|
||||||
@ -1792,6 +1778,17 @@ Error VulkanContext::_clean_up_swap_chain(Window *window) {
|
|||||||
if (separate_present_queue) {
|
if (separate_present_queue) {
|
||||||
vkDestroyCommandPool(device, window->present_cmd_pool, nullptr);
|
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;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2175,6 +2172,17 @@ Error VulkanContext::_update_swap_chain(Window *window) {
|
|||||||
// Reset current buffer.
|
// Reset current buffer.
|
||||||
window->current_buffer = 0;
|
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;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user