Skip to content

Commit 83ba068

Browse files
committed
Merge pull request godotengine#106407 from DarioSamo/present-validation-error
Rework semaphores for presentation to be created per swap chain image to fix validation error.
2 parents 6a410e3 + ad22f65 commit 83ba068

File tree

2 files changed

+27
-31
lines changed

2 files changed

+27
-31
lines changed

drivers/vulkan/rendering_device_driver_vulkan.cpp

Lines changed: 26 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -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

30293015
RenderingDeviceDriver::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

drivers/vulkan/rendering_device_driver_vulkan.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,6 @@ class RenderingDeviceDriverVulkan : public RenderingDeviceDriver {
302302
// ----- QUEUE -----
303303
private:
304304
struct CommandQueue {
305-
LocalVector<VkSemaphore> present_semaphores;
306305
LocalVector<VkSemaphore> image_semaphores;
307306
LocalVector<SwapChain *> image_semaphores_swap_chains;
308307
LocalVector<uint32_t> pending_semaphores_for_execute;
@@ -311,7 +310,6 @@ class RenderingDeviceDriverVulkan : public RenderingDeviceDriver {
311310
LocalVector<Pair<Fence *, uint32_t>> image_semaphores_for_fences;
312311
uint32_t queue_family = 0;
313312
uint32_t queue_index = 0;
314-
uint32_t present_semaphore_index = 0;
315313
};
316314

317315
public:
@@ -361,6 +359,7 @@ class RenderingDeviceDriverVulkan : public RenderingDeviceDriver {
361359
VkColorSpaceKHR color_space = VK_COLOR_SPACE_SRGB_NONLINEAR_KHR;
362360
TightLocalVector<VkImage> images;
363361
TightLocalVector<VkImageView> image_views;
362+
TightLocalVector<VkSemaphore> present_semaphores;
364363
TightLocalVector<FramebufferID> framebuffers;
365364
LocalVector<CommandQueue *> command_queues_acquired;
366365
LocalVector<uint32_t> command_queues_acquired_semaphores;

0 commit comments

Comments
 (0)