|
@@ -2683,8 +2683,10 @@ Error RenderingDeviceDriverVulkan::command_queue_execute_and_present(CommandQueu
|
|
|
|
|
|
if (p_cmd_buffers.size() > 0) {
|
|
|
thread_local LocalVector<VkCommandBuffer> command_buffers;
|
|
|
+ thread_local LocalVector<VkSemaphore> present_semaphores;
|
|
|
thread_local LocalVector<VkSemaphore> signal_semaphores;
|
|
|
command_buffers.clear();
|
|
|
+ present_semaphores.clear();
|
|
|
signal_semaphores.clear();
|
|
|
|
|
|
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));
|
|
|
}
|
|
|
|
|
|
- VkSemaphore present_semaphore = VK_NULL_HANDLE;
|
|
|
- if (p_swap_chains.size() > 0) {
|
|
|
- if (command_queue->present_semaphores.is_empty()) {
|
|
|
- // Create the semaphores used for presentation if they haven't been created yet.
|
|
|
- VkSemaphore semaphore = VK_NULL_HANDLE;
|
|
|
- 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();
|
|
|
+ for (uint32_t i = 0; i < p_swap_chains.size(); i++) {
|
|
|
+ const SwapChain *swap_chain = (const SwapChain *)(p_swap_chains[i].id);
|
|
|
+ VkSemaphore semaphore = swap_chain->present_semaphores[swap_chain->image_index];
|
|
|
+ present_semaphores.push_back(semaphore);
|
|
|
+ signal_semaphores.push_back(semaphore);
|
|
|
}
|
|
|
|
|
|
VkSubmitInfo submit_info = {};
|
|
@@ -2750,10 +2736,9 @@ Error RenderingDeviceDriverVulkan::command_queue_execute_and_present(CommandQueu
|
|
|
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.
|
|
|
- wait_semaphores.clear();
|
|
|
- wait_semaphores.push_back(present_semaphore);
|
|
|
+ wait_semaphores = present_semaphores;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -2838,11 +2823,6 @@ void RenderingDeviceDriverVulkan::command_queue_free(CommandQueueID p_cmd_queue)
|
|
|
|
|
|
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.
|
|
|
for (VkSemaphore semaphore : command_queue->image_semaphores) {
|
|
|
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_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) {
|
|
@@ -3360,6 +3346,17 @@ Error RenderingDeviceDriverVulkan::swap_chain_resize(CommandQueueID p_cmd_queue,
|
|
|
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.
|
|
|
context_driver->surface_set_needs_resize(swap_chain->surface, false);
|
|
|
|