You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-05 12:10:55 +00:00
Rework semaphores for presentation to be created per swap chain image to fix validation error.
This commit is contained in:
@@ -2683,8 +2683,10 @@ Error RenderingDeviceDriverVulkan::command_queue_execute_and_present(CommandQueu
|
|||||||
|
|
||||||
if (p_cmd_buffers.size() > 0) {
|
if (p_cmd_buffers.size() > 0) {
|
||||||
thread_local LocalVector<VkCommandBuffer> command_buffers;
|
thread_local LocalVector<VkCommandBuffer> command_buffers;
|
||||||
|
thread_local LocalVector<VkSemaphore> present_semaphores;
|
||||||
thread_local LocalVector<VkSemaphore> signal_semaphores;
|
thread_local LocalVector<VkSemaphore> signal_semaphores;
|
||||||
command_buffers.clear();
|
command_buffers.clear();
|
||||||
|
present_semaphores.clear();
|
||||||
signal_semaphores.clear();
|
signal_semaphores.clear();
|
||||||
|
|
||||||
for (uint32_t i = 0; i < p_cmd_buffers.size(); i++) {
|
for (uint32_t i = 0; i < p_cmd_buffers.size(); i++) {
|
||||||
@@ -2696,27 +2698,11 @@ Error RenderingDeviceDriverVulkan::command_queue_execute_and_present(CommandQueu
|
|||||||
signal_semaphores.push_back(VkSemaphore(p_cmd_semaphores[i].id));
|
signal_semaphores.push_back(VkSemaphore(p_cmd_semaphores[i].id));
|
||||||
}
|
}
|
||||||
|
|
||||||
VkSemaphore present_semaphore = VK_NULL_HANDLE;
|
for (uint32_t i = 0; i < p_swap_chains.size(); i++) {
|
||||||
if (p_swap_chains.size() > 0) {
|
const SwapChain *swap_chain = (const SwapChain *)(p_swap_chains[i].id);
|
||||||
if (command_queue->present_semaphores.is_empty()) {
|
VkSemaphore semaphore = swap_chain->present_semaphores[swap_chain->image_index];
|
||||||
// Create the semaphores used for presentation if they haven't been created yet.
|
present_semaphores.push_back(semaphore);
|
||||||
VkSemaphore semaphore = VK_NULL_HANDLE;
|
signal_semaphores.push_back(semaphore);
|
||||||
VkSemaphoreCreateInfo create_info = {};
|
|
||||||
create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < frame_count; i++) {
|
|
||||||
err = vkCreateSemaphore(vk_device, &create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_SEMAPHORE), &semaphore);
|
|
||||||
ERR_FAIL_COND_V(err != VK_SUCCESS, FAILED);
|
|
||||||
command_queue->present_semaphores.push_back(semaphore);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If a presentation semaphore is required, cycle across the ones available on the queue. It is technically possible
|
|
||||||
// and valid to reuse the same semaphore for this particular operation, but we create multiple ones anyway in case
|
|
||||||
// some hardware expects multiple semaphores to be used.
|
|
||||||
present_semaphore = command_queue->present_semaphores[command_queue->present_semaphore_index];
|
|
||||||
signal_semaphores.push_back(present_semaphore);
|
|
||||||
command_queue->present_semaphore_index = (command_queue->present_semaphore_index + 1) % command_queue->present_semaphores.size();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VkSubmitInfo submit_info = {};
|
VkSubmitInfo submit_info = {};
|
||||||
@@ -2750,10 +2736,9 @@ Error RenderingDeviceDriverVulkan::command_queue_execute_and_present(CommandQueu
|
|||||||
command_queue->pending_semaphores_for_fence.clear();
|
command_queue->pending_semaphores_for_fence.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (present_semaphore != VK_NULL_HANDLE) {
|
if (!present_semaphores.is_empty()) {
|
||||||
// If command buffers were executed, swap chains must wait on the present semaphore used by the command queue.
|
// If command buffers were executed, swap chains must wait on the present semaphore used by the command queue.
|
||||||
wait_semaphores.clear();
|
wait_semaphores = present_semaphores;
|
||||||
wait_semaphores.push_back(present_semaphore);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2838,11 +2823,6 @@ void RenderingDeviceDriverVulkan::command_queue_free(CommandQueueID p_cmd_queue)
|
|||||||
|
|
||||||
CommandQueue *command_queue = (CommandQueue *)(p_cmd_queue.id);
|
CommandQueue *command_queue = (CommandQueue *)(p_cmd_queue.id);
|
||||||
|
|
||||||
// Erase all the semaphores used for presentation.
|
|
||||||
for (VkSemaphore semaphore : command_queue->present_semaphores) {
|
|
||||||
vkDestroySemaphore(vk_device, semaphore, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_SEMAPHORE));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Erase all the semaphores used for image acquisition.
|
// Erase all the semaphores used for image acquisition.
|
||||||
for (VkSemaphore semaphore : command_queue->image_semaphores) {
|
for (VkSemaphore semaphore : command_queue->image_semaphores) {
|
||||||
vkDestroySemaphore(vk_device, semaphore, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_SEMAPHORE));
|
vkDestroySemaphore(vk_device, semaphore, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_SEMAPHORE));
|
||||||
@@ -3024,6 +3004,12 @@ void RenderingDeviceDriverVulkan::_swap_chain_release(SwapChain *swap_chain) {
|
|||||||
|
|
||||||
swap_chain->command_queues_acquired.clear();
|
swap_chain->command_queues_acquired.clear();
|
||||||
swap_chain->command_queues_acquired_semaphores.clear();
|
swap_chain->command_queues_acquired_semaphores.clear();
|
||||||
|
|
||||||
|
for (VkSemaphore semaphore : swap_chain->present_semaphores) {
|
||||||
|
vkDestroySemaphore(vk_device, semaphore, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_SEMAPHORE));
|
||||||
|
}
|
||||||
|
|
||||||
|
swap_chain->present_semaphores.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderingDeviceDriver::SwapChainID RenderingDeviceDriverVulkan::swap_chain_create(RenderingContextDriver::SurfaceID p_surface) {
|
RenderingDeviceDriver::SwapChainID RenderingDeviceDriverVulkan::swap_chain_create(RenderingContextDriver::SurfaceID p_surface) {
|
||||||
@@ -3360,6 +3346,17 @@ Error RenderingDeviceDriverVulkan::swap_chain_resize(CommandQueueID p_cmd_queue,
|
|||||||
swap_chain->framebuffers.push_back(RDD::FramebufferID(framebuffer));
|
swap_chain->framebuffers.push_back(RDD::FramebufferID(framebuffer));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VkSemaphore vk_semaphore = VK_NULL_HANDLE;
|
||||||
|
for (uint32_t i = 0; i < image_count; i++) {
|
||||||
|
VkSemaphoreCreateInfo create_info = {};
|
||||||
|
create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
|
||||||
|
|
||||||
|
err = vkCreateSemaphore(vk_device, &create_info, VKC::get_allocation_callbacks(VK_OBJECT_TYPE_SEMAPHORE), &vk_semaphore);
|
||||||
|
ERR_FAIL_COND_V(err != VK_SUCCESS, FAILED);
|
||||||
|
|
||||||
|
swap_chain->present_semaphores.push_back(vk_semaphore);
|
||||||
|
}
|
||||||
|
|
||||||
// Once everything's been created correctly, indicate the surface no longer needs to be resized.
|
// Once everything's been created correctly, indicate the surface no longer needs to be resized.
|
||||||
context_driver->surface_set_needs_resize(swap_chain->surface, false);
|
context_driver->surface_set_needs_resize(swap_chain->surface, false);
|
||||||
|
|
||||||
|
|||||||
@@ -302,7 +302,6 @@ public:
|
|||||||
// ----- QUEUE -----
|
// ----- QUEUE -----
|
||||||
private:
|
private:
|
||||||
struct CommandQueue {
|
struct CommandQueue {
|
||||||
LocalVector<VkSemaphore> present_semaphores;
|
|
||||||
LocalVector<VkSemaphore> image_semaphores;
|
LocalVector<VkSemaphore> image_semaphores;
|
||||||
LocalVector<SwapChain *> image_semaphores_swap_chains;
|
LocalVector<SwapChain *> image_semaphores_swap_chains;
|
||||||
LocalVector<uint32_t> pending_semaphores_for_execute;
|
LocalVector<uint32_t> pending_semaphores_for_execute;
|
||||||
@@ -311,7 +310,6 @@ private:
|
|||||||
LocalVector<Pair<Fence *, uint32_t>> image_semaphores_for_fences;
|
LocalVector<Pair<Fence *, uint32_t>> image_semaphores_for_fences;
|
||||||
uint32_t queue_family = 0;
|
uint32_t queue_family = 0;
|
||||||
uint32_t queue_index = 0;
|
uint32_t queue_index = 0;
|
||||||
uint32_t present_semaphore_index = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -361,6 +359,7 @@ private:
|
|||||||
VkColorSpaceKHR color_space = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
|
VkColorSpaceKHR color_space = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
|
||||||
TightLocalVector<VkImage> images;
|
TightLocalVector<VkImage> images;
|
||||||
TightLocalVector<VkImageView> image_views;
|
TightLocalVector<VkImageView> image_views;
|
||||||
|
TightLocalVector<VkSemaphore> present_semaphores;
|
||||||
TightLocalVector<FramebufferID> framebuffers;
|
TightLocalVector<FramebufferID> framebuffers;
|
||||||
LocalVector<CommandQueue *> command_queues_acquired;
|
LocalVector<CommandQueue *> command_queues_acquired;
|
||||||
LocalVector<uint32_t> command_queues_acquired_semaphores;
|
LocalVector<uint32_t> command_queues_acquired_semaphores;
|
||||||
|
|||||||
Reference in New Issue
Block a user