@@ -2683,8 +2683,10 @@ Error RenderingDeviceDriverVulkan::command_queue_execute_and_present(CommandQueu
26832683
26842684 if (p_cmd_buffers.size () > 0 ) {
26852685 thread_local LocalVector<VkCommandBuffer> command_buffers;
2686+ thread_local LocalVector<VkSemaphore> present_semaphores;
26862687 thread_local LocalVector<VkSemaphore> signal_semaphores;
26872688 command_buffers.clear ();
2689+ present_semaphores.clear ();
26882690 signal_semaphores.clear ();
26892691
26902692 for (uint32_t i = 0 ; i < p_cmd_buffers.size (); i++) {
@@ -2696,27 +2698,11 @@ Error RenderingDeviceDriverVulkan::command_queue_execute_and_present(CommandQueu
26962698 signal_semaphores.push_back (VkSemaphore (p_cmd_semaphores[i].id ));
26972699 }
26982700
2699- VkSemaphore present_semaphore = VK_NULL_HANDLE;
2700- if (p_swap_chains.size () > 0 ) {
2701- if (command_queue->present_semaphores .is_empty ()) {
2702- // Create the semaphores used for presentation if they haven't been created yet.
2703- VkSemaphore semaphore = VK_NULL_HANDLE;
2704- VkSemaphoreCreateInfo create_info = {};
2705- create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
2706-
2707- for (uint32_t i = 0 ; i < frame_count; i++) {
2708- err = vkCreateSemaphore (vk_device, &create_info, VKC::get_allocation_callbacks (VK_OBJECT_TYPE_SEMAPHORE), &semaphore);
2709- ERR_FAIL_COND_V (err != VK_SUCCESS, FAILED);
2710- command_queue->present_semaphores .push_back (semaphore);
2711- }
2712- }
2713-
2714- // If a presentation semaphore is required, cycle across the ones available on the queue. It is technically possible
2715- // and valid to reuse the same semaphore for this particular operation, but we create multiple ones anyway in case
2716- // some hardware expects multiple semaphores to be used.
2717- present_semaphore = command_queue->present_semaphores [command_queue->present_semaphore_index ];
2718- signal_semaphores.push_back (present_semaphore);
2719- command_queue->present_semaphore_index = (command_queue->present_semaphore_index + 1 ) % command_queue->present_semaphores .size ();
2701+ for (uint32_t i = 0 ; i < p_swap_chains.size (); i++) {
2702+ const SwapChain *swap_chain = (const SwapChain *)(p_swap_chains[i].id );
2703+ VkSemaphore semaphore = swap_chain->present_semaphores [swap_chain->image_index ];
2704+ present_semaphores.push_back (semaphore);
2705+ signal_semaphores.push_back (semaphore);
27202706 }
27212707
27222708 VkSubmitInfo submit_info = {};
@@ -2750,10 +2736,9 @@ Error RenderingDeviceDriverVulkan::command_queue_execute_and_present(CommandQueu
27502736 command_queue->pending_semaphores_for_fence .clear ();
27512737 }
27522738
2753- if (present_semaphore != VK_NULL_HANDLE ) {
2739+ if (!present_semaphores. is_empty () ) {
27542740 // If command buffers were executed, swap chains must wait on the present semaphore used by the command queue.
2755- wait_semaphores.clear ();
2756- wait_semaphores.push_back (present_semaphore);
2741+ wait_semaphores = present_semaphores;
27572742 }
27582743 }
27592744
@@ -2838,11 +2823,6 @@ void RenderingDeviceDriverVulkan::command_queue_free(CommandQueueID p_cmd_queue)
28382823
28392824 CommandQueue *command_queue = (CommandQueue *)(p_cmd_queue.id );
28402825
2841- // Erase all the semaphores used for presentation.
2842- for (VkSemaphore semaphore : command_queue->present_semaphores ) {
2843- vkDestroySemaphore (vk_device, semaphore, VKC::get_allocation_callbacks (VK_OBJECT_TYPE_SEMAPHORE));
2844- }
2845-
28462826 // Erase all the semaphores used for image acquisition.
28472827 for (VkSemaphore semaphore : command_queue->image_semaphores ) {
28482828 vkDestroySemaphore (vk_device, semaphore, VKC::get_allocation_callbacks (VK_OBJECT_TYPE_SEMAPHORE));
@@ -3024,6 +3004,12 @@ void RenderingDeviceDriverVulkan::_swap_chain_release(SwapChain *swap_chain) {
30243004
30253005 swap_chain->command_queues_acquired .clear ();
30263006 swap_chain->command_queues_acquired_semaphores .clear ();
3007+
3008+ for (VkSemaphore semaphore : swap_chain->present_semaphores ) {
3009+ vkDestroySemaphore (vk_device, semaphore, VKC::get_allocation_callbacks (VK_OBJECT_TYPE_SEMAPHORE));
3010+ }
3011+
3012+ swap_chain->present_semaphores .clear ();
30273013}
30283014
30293015RenderingDeviceDriver::SwapChainID RenderingDeviceDriverVulkan::swap_chain_create (RenderingContextDriver::SurfaceID p_surface) {
@@ -3360,6 +3346,17 @@ Error RenderingDeviceDriverVulkan::swap_chain_resize(CommandQueueID p_cmd_queue,
33603346 swap_chain->framebuffers .push_back (RDD::FramebufferID (framebuffer));
33613347 }
33623348
3349+ VkSemaphore vk_semaphore = VK_NULL_HANDLE;
3350+ for (uint32_t i = 0 ; i < image_count; i++) {
3351+ VkSemaphoreCreateInfo create_info = {};
3352+ create_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
3353+
3354+ err = vkCreateSemaphore (vk_device, &create_info, VKC::get_allocation_callbacks (VK_OBJECT_TYPE_SEMAPHORE), &vk_semaphore);
3355+ ERR_FAIL_COND_V (err != VK_SUCCESS, FAILED);
3356+
3357+ swap_chain->present_semaphores .push_back (vk_semaphore);
3358+ }
3359+
33633360 // Once everything's been created correctly, indicate the surface no longer needs to be resized.
33643361 context_driver->surface_set_needs_resize (swap_chain->surface , false );
33653362
0 commit comments