Skip to content

Commit 452bf87

Browse files
committed
Fix swapchain semaphore handling
1 parent 7942b79 commit 452bf87

1 file changed

Lines changed: 48 additions & 30 deletions

File tree

src/VulkanSample.cpp

Lines changed: 48 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,11 @@ static VkCommandBuffer g_MainCommandBuffers[COMMAND_BUFFER_COUNT];
8989
static VkFence g_MainCommandBufferExecutedFances[COMMAND_BUFFER_COUNT];
9090
VkFence g_ImmediateFence;
9191
static uint32_t g_NextCommandBufferIndex;
92-
static VkSemaphore g_hImageAvailableSemaphore;
93-
static VkSemaphore g_hRenderFinishedSemaphore;
92+
// Notice we need as many semaphores as there are swapchain images
93+
static std::vector<VkSemaphore> g_hImageAvailableSemaphores;
94+
static std::vector<VkSemaphore> g_hRenderFinishedSemaphores;
95+
static uint32_t g_SwapchainImageCount = 0;
96+
static uint32_t g_SwapchainImageIndex = 0;
9497
static uint32_t g_GraphicsQueueFamilyIndex = UINT_MAX;
9598
static uint32_t g_PresentQueueFamilyIndex = UINT_MAX;
9699
static uint32_t g_SparseBindingQueueFamilyIndex = UINT_MAX;
@@ -937,16 +940,16 @@ static void CreateSwapchain()
937940
VkPresentModeKHR presentMode = ChooseSwapPresentMode();
938941
g_Extent = ChooseSwapExtent();
939942

940-
uint32_t imageCount = g_SurfaceCapabilities.minImageCount + 1;
943+
g_SwapchainImageCount = g_SurfaceCapabilities.minImageCount + 1;
941944
if((g_SurfaceCapabilities.maxImageCount > 0) &&
942-
(imageCount > g_SurfaceCapabilities.maxImageCount))
945+
(g_SwapchainImageCount > g_SurfaceCapabilities.maxImageCount))
943946
{
944-
imageCount = g_SurfaceCapabilities.maxImageCount;
947+
g_SwapchainImageCount = g_SurfaceCapabilities.maxImageCount;
945948
}
946949

947950
VkSwapchainCreateInfoKHR swapChainInfo = { VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR };
948951
swapChainInfo.surface = g_hSurface;
949-
swapChainInfo.minImageCount = imageCount;
952+
swapChainInfo.minImageCount = g_SwapchainImageCount;
950953
swapChainInfo.imageFormat = g_SurfaceFormat.format;
951954
swapChainInfo.imageColorSpace = g_SurfaceFormat.colorSpace;
952955
swapChainInfo.imageExtent = g_Extent;
@@ -1300,35 +1303,45 @@ static void CreateSwapchain()
13001303
ERR_GUARD_VULKAN( vkCreateFramebuffer(g_hDevice, &framebufferInfo, g_Allocs, &g_Framebuffers[i]) );
13011304
}
13021305

1303-
// Create semaphores
1306+
// Destroy the old semaphores and create new ones
13041307

1305-
if(g_hImageAvailableSemaphore != VK_NULL_HANDLE)
1306-
{
1307-
vkDestroySemaphore(g_hDevice, g_hImageAvailableSemaphore, g_Allocs);
1308-
g_hImageAvailableSemaphore = VK_NULL_HANDLE;
1308+
if (g_hImageAvailableSemaphores.size() < g_SwapchainImageCount) {
1309+
g_hImageAvailableSemaphores.resize(g_SwapchainImageCount);
13091310
}
1310-
if(g_hRenderFinishedSemaphore != VK_NULL_HANDLE)
1311-
{
1312-
vkDestroySemaphore(g_hDevice, g_hRenderFinishedSemaphore, g_Allocs);
1313-
g_hRenderFinishedSemaphore = VK_NULL_HANDLE;
1311+
if (g_hRenderFinishedSemaphores.size() < g_SwapchainImageCount) {
1312+
g_hRenderFinishedSemaphores.resize(g_SwapchainImageCount);
13141313
}
13151314

13161315
VkSemaphoreCreateInfo semaphoreInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO };
1317-
ERR_GUARD_VULKAN( vkCreateSemaphore(g_hDevice, &semaphoreInfo, g_Allocs, &g_hImageAvailableSemaphore) );
1318-
ERR_GUARD_VULKAN( vkCreateSemaphore(g_hDevice, &semaphoreInfo, g_Allocs, &g_hRenderFinishedSemaphore) );
1316+
1317+
for (std::size_t swapchain_img_index = 0; swapchain_img_index < g_SwapchainImageCount; swapchain_img_index++) {
1318+
if (g_hImageAvailableSemaphores.at(swapchain_img_index) != VK_NULL_HANDLE) {
1319+
vkDestroySemaphore(g_hDevice, g_hImageAvailableSemaphores[swapchain_img_index], g_Allocs);
1320+
g_hImageAvailableSemaphores[swapchain_img_index] = VK_NULL_HANDLE;
1321+
}
1322+
if (g_hRenderFinishedSemaphores.at(swapchain_img_index) != VK_NULL_HANDLE) {
1323+
vkDestroySemaphore(g_hDevice, g_hRenderFinishedSemaphores[swapchain_img_index], g_Allocs);
1324+
g_hRenderFinishedSemaphores[swapchain_img_index] = VK_NULL_HANDLE;
1325+
}
1326+
}
1327+
1328+
for (std::size_t swapchain_img_index = 0; swapchain_img_index < g_SwapchainImageCount; swapchain_img_index++) {
1329+
ERR_GUARD_VULKAN(vkCreateSemaphore(g_hDevice, &semaphoreInfo, g_Allocs, &g_hImageAvailableSemaphores[swapchain_img_index]));
1330+
ERR_GUARD_VULKAN(vkCreateSemaphore(g_hDevice, &semaphoreInfo, g_Allocs, &g_hRenderFinishedSemaphores[swapchain_img_index]));
1331+
}
13191332
}
13201333

13211334
static void DestroySwapchain(bool destroyActualSwapchain)
13221335
{
1323-
if(g_hImageAvailableSemaphore != VK_NULL_HANDLE)
1324-
{
1325-
vkDestroySemaphore(g_hDevice, g_hImageAvailableSemaphore, g_Allocs);
1326-
g_hImageAvailableSemaphore = VK_NULL_HANDLE;
1327-
}
1328-
if(g_hRenderFinishedSemaphore != VK_NULL_HANDLE)
1329-
{
1330-
vkDestroySemaphore(g_hDevice, g_hRenderFinishedSemaphore, g_Allocs);
1331-
g_hRenderFinishedSemaphore = VK_NULL_HANDLE;
1336+
for (std::size_t swapchain_img_index = 0; swapchain_img_index < g_SwapchainImageCount; swapchain_img_index++) {
1337+
if (g_hImageAvailableSemaphores.at(swapchain_img_index) != VK_NULL_HANDLE) {
1338+
vkDestroySemaphore(g_hDevice, g_hImageAvailableSemaphores[swapchain_img_index], g_Allocs);
1339+
g_hImageAvailableSemaphores[swapchain_img_index] = VK_NULL_HANDLE;
1340+
}
1341+
if (g_hRenderFinishedSemaphores.at(swapchain_img_index) != VK_NULL_HANDLE) {
1342+
vkDestroySemaphore(g_hDevice, g_hRenderFinishedSemaphores[swapchain_img_index], g_Allocs);
1343+
g_hRenderFinishedSemaphores[swapchain_img_index] = VK_NULL_HANDLE;
1344+
}
13321345
}
13331346

13341347
for(size_t i = g_Framebuffers.size(); i--; )
@@ -2306,7 +2319,7 @@ static void DrawFrame()
23062319

23072320
// Acquire swapchain image
23082321
uint32_t imageIndex = 0;
2309-
VkResult res = vkAcquireNextImageKHR(g_hDevice, g_hSwapchain, UINT64_MAX, g_hImageAvailableSemaphore, VK_NULL_HANDLE, &imageIndex);
2322+
VkResult res = vkAcquireNextImageKHR(g_hDevice, g_hSwapchain, UINT64_MAX, g_hImageAvailableSemaphores.at(g_SwapchainImageIndex), VK_NULL_HANDLE, &imageIndex);
23102323
if(res == VK_ERROR_OUT_OF_DATE_KHR)
23112324
{
23122325
RecreateSwapChain();
@@ -2384,9 +2397,9 @@ static void DrawFrame()
23842397

23852398
// Submit command buffer
23862399

2387-
VkSemaphore submitWaitSemaphores[] = { g_hImageAvailableSemaphore };
2400+
VkSemaphore submitWaitSemaphores[] = { g_hImageAvailableSemaphores.at(g_SwapchainImageIndex)};
23882401
VkPipelineStageFlags submitWaitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
2389-
VkSemaphore submitSignalSemaphores[] = { g_hRenderFinishedSemaphore };
2402+
VkSemaphore submitSignalSemaphores[] = { g_hRenderFinishedSemaphores.at(g_SwapchainImageIndex)};
23902403
VkSubmitInfo submitInfo = { VK_STRUCTURE_TYPE_SUBMIT_INFO };
23912404
submitInfo.waitSemaphoreCount = 1;
23922405
submitInfo.pWaitSemaphores = submitWaitSemaphores;
@@ -2397,7 +2410,7 @@ static void DrawFrame()
23972410
submitInfo.pSignalSemaphores = submitSignalSemaphores;
23982411
ERR_GUARD_VULKAN( vkQueueSubmit(g_hGraphicsQueue, 1, &submitInfo, hCommandBufferExecutedFence) );
23992412

2400-
VkSemaphore presentWaitSemaphores[] = { g_hRenderFinishedSemaphore };
2413+
VkSemaphore presentWaitSemaphores[] = { g_hRenderFinishedSemaphores.at(g_SwapchainImageIndex) };
24012414

24022415
VkSwapchainKHR swapchains[] = { g_hSwapchain };
24032416
VkPresentInfoKHR presentInfo = { VK_STRUCTURE_TYPE_PRESENT_INFO_KHR };
@@ -2414,6 +2427,11 @@ static void DrawFrame()
24142427
}
24152428
else
24162429
ERR_GUARD_VULKAN(res);
2430+
2431+
g_SwapchainImageIndex++;
2432+
if (g_SwapchainImageIndex >= g_SwapchainImageCount) {
2433+
g_SwapchainImageIndex = 0;
2434+
}
24172435
}
24182436

24192437
static void HandlePossibleSizeChange()

0 commit comments

Comments
 (0)