Implement viewChanged() in multiple examples for proper window resize handling, fix triangle example resizing on macOS

This commit is contained in:
Stephen Saunders 2022-06-13 23:04:53 -04:00
parent b2f501dc98
commit 279c95422d
42 changed files with 240 additions and 37 deletions

View file

@ -109,7 +109,7 @@ public:
// Fences
// Used to check the completion of queue operations (e.g. command buffer execution)
std::vector<VkFence> waitFences;
std::vector<VkFence> queueCompleteFences;
VulkanExample() : VulkanExampleBase(ENABLE_VALIDATION)
{
@ -148,7 +148,7 @@ public:
vkDestroySemaphore(device, presentCompleteSemaphore, nullptr);
vkDestroySemaphore(device, renderCompleteSemaphore, nullptr);
for (auto& fence : waitFences)
for (auto& fence : queueCompleteFences)
{
vkDestroyFence(device, fence, nullptr);
}
@ -196,8 +196,8 @@ public:
fenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
// Create in signaled state so we don't wait on first render of each command buffer
fenceCreateInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
waitFences.resize(drawCmdBuffers.size());
for (auto& fence : waitFences)
queueCompleteFences.resize(drawCmdBuffers.size());
for (auto& fence : queueCompleteFences)
{
VK_CHECK_RESULT(vkCreateFence(device, &fenceCreateInfo, nullptr, &fence));
}
@ -337,6 +337,16 @@ public:
void draw()
{
#if defined(VK_USE_PLATFORM_MACOS_MVK)
// SRS - on macOS use swapchain helper function with common semaphores/fences for proper resize handling
// Get next image in the swap chain (back/front buffer)
prepareFrame();
// Use a fence to wait until the command buffer has finished execution before using it again
VK_CHECK_RESULT(vkWaitForFences(device, 1, &waitFences[currentBuffer], VK_TRUE, UINT64_MAX));
VK_CHECK_RESULT(vkResetFences(device, 1, &waitFences[currentBuffer]));
#else
// SRS - on other platforms use original bare code with local semaphores/fences for illustrative purposes
// Get next image in the swap chain (back/front buffer)
VkResult acquire = swapChain.acquireNextImage(presentCompleteSemaphore, &currentBuffer);
if (!((acquire == VK_SUCCESS) || (acquire == VK_SUBOPTIMAL_KHR))) {
@ -344,8 +354,9 @@ public:
}
// Use a fence to wait until the command buffer has finished execution before using it again
VK_CHECK_RESULT(vkWaitForFences(device, 1, &waitFences[currentBuffer], VK_TRUE, UINT64_MAX));
VK_CHECK_RESULT(vkResetFences(device, 1, &waitFences[currentBuffer]));
VK_CHECK_RESULT(vkWaitForFences(device, 1, &queueCompleteFences[currentBuffer], VK_TRUE, UINT64_MAX));
VK_CHECK_RESULT(vkResetFences(device, 1, &queueCompleteFences[currentBuffer]));
#endif
// Pipeline stage at which the queue submission will wait (via pWaitSemaphores)
VkPipelineStageFlags waitStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
@ -353,16 +364,29 @@ public:
VkSubmitInfo submitInfo = {};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
submitInfo.pWaitDstStageMask = &waitStageMask; // Pointer to the list of pipeline stages that the semaphore waits will occur at
submitInfo.pWaitSemaphores = &presentCompleteSemaphore; // Semaphore(s) to wait upon before the submitted command buffer starts executing
submitInfo.waitSemaphoreCount = 1; // One wait semaphore
submitInfo.pSignalSemaphores = &renderCompleteSemaphore; // Semaphore(s) to be signaled when command buffers have completed
submitInfo.signalSemaphoreCount = 1; // One signal semaphore
submitInfo.pCommandBuffers = &drawCmdBuffers[currentBuffer]; // Command buffers(s) to execute in this batch (submission)
submitInfo.commandBufferCount = 1; // One command buffer
#if defined(VK_USE_PLATFORM_MACOS_MVK)
// SRS - on macOS use swapchain helper function with common semaphores/fences for proper resize handling
submitInfo.pWaitSemaphores = &semaphores.presentComplete; // Semaphore(s) to wait upon before the submitted command buffer starts executing
submitInfo.pSignalSemaphores = &semaphores.renderComplete; // Semaphore(s) to be signaled when command buffers have completed
// Submit to the graphics queue passing a wait fence
VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, waitFences[currentBuffer]));
// Present the current buffer to the swap chain
submitFrame();
#else
// SRS - on other platforms use original bare code with local semaphores/fences for illustrative purposes
submitInfo.pWaitSemaphores = &presentCompleteSemaphore; // Semaphore(s) to wait upon before the submitted command buffer starts executing
submitInfo.pSignalSemaphores = &renderCompleteSemaphore; // Semaphore(s) to be signaled when command buffers have completed
// Submit to the graphics queue passing a wait fence
VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, queueCompleteFences[currentBuffer]));
// Present the current buffer to the swap chain
// Pass the semaphore signaled by the command buffer submission from the submit info as the wait semaphore for swap chain presentation
// This ensures that the image is not presented to the windowing system until all commands have been submitted
@ -370,7 +394,7 @@ public:
if (!((present == VK_SUCCESS) || (present == VK_SUBOPTIMAL_KHR))) {
VK_CHECK_RESULT(present);
}
#endif
}
// Prepare vertex and index buffers for an indexed triangle
@ -1235,7 +1259,7 @@ int main(const int argc, const char *argv[])
vulkanExample->setupWindow(nullptr);
vulkanExample->prepare();
vulkanExample->renderLoop();
delete(vulkanExample);
//delete(vulkanExample); // SRS - vulkanExample deleted by AppDelegate termination event handler
}
return 0;
}