Skip to content

Commit f6e1a6e

Browse files
committed
Starting to clean up base class
1 parent 94f5da2 commit f6e1a6e

2 files changed

Lines changed: 75 additions & 133 deletions

File tree

base/vulkanexamplebase.cpp

Lines changed: 71 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -750,100 +750,67 @@ void VulkanExampleBase::drawUI(const VkCommandBuffer commandBuffer)
750750

751751
void VulkanExampleBase::prepareFrame(bool waitForFence)
752752
{
753-
if (useNewSync) {
754-
// Ensure command buffer execution has finished
755-
if (waitForFence) {
756-
VK_CHECK_RESULT(vkWaitForFences(device, 1, &waitFences[currentBuffer], VK_TRUE, UINT64_MAX));
757-
VK_CHECK_RESULT(vkResetFences(device, 1, &waitFences[currentBuffer]));
758-
}
759-
// Update UI if necessary
760-
updateOverlay();
761-
// Acquire the next image from the swap chain
762-
VkResult result = swapChain.acquireNextImage(presentCompleteSemaphores[currentBuffer], currentImageIndex);
763-
// Recreate the swapchain if it's no longer compatible with the surface (OUT_OF_DATE)
764-
// If no longer optimal (VK_SUBOPTIMAL_KHR), wait until submitFrame() in case number of swapchain images will change on resize
765-
if ((result == VK_ERROR_OUT_OF_DATE_KHR) || (result == VK_SUBOPTIMAL_KHR)) {
766-
if (result == VK_ERROR_OUT_OF_DATE_KHR) {
767-
windowResize();
768-
}
769-
return;
770-
}
771-
else {
772-
VK_CHECK_RESULT(result);
753+
// Ensure command buffer execution has finished
754+
if (waitForFence) {
755+
VK_CHECK_RESULT(vkWaitForFences(device, 1, &waitFences[currentBuffer], VK_TRUE, UINT64_MAX));
756+
VK_CHECK_RESULT(vkResetFences(device, 1, &waitFences[currentBuffer]));
757+
}
758+
// Update UI if necessary
759+
updateOverlay();
760+
// Acquire the next image from the swap chain
761+
VkResult result = swapChain.acquireNextImage(presentCompleteSemaphores[currentBuffer], currentImageIndex);
762+
// Recreate the swapchain if it's no longer compatible with the surface (OUT_OF_DATE)
763+
// If no longer optimal (VK_SUBOPTIMAL_KHR), wait until submitFrame() in case number of swapchain images will change on resize
764+
if ((result == VK_ERROR_OUT_OF_DATE_KHR) || (result == VK_SUBOPTIMAL_KHR)) {
765+
if (result == VK_ERROR_OUT_OF_DATE_KHR) {
766+
windowResize();
773767
}
768+
return;
774769
}
775770
else {
776-
// Acquire the next image from the swap chain
777-
VkResult result = swapChain.acquireNextImage(semaphores.presentComplete, currentBuffer);
778-
// Recreate the swapchain if it's no longer compatible with the surface (OUT_OF_DATE)
779-
// SRS - If no longer optimal (VK_SUBOPTIMAL_KHR), wait until submitFrame() in case number of swapchain images will change on resize
780-
if ((result == VK_ERROR_OUT_OF_DATE_KHR) || (result == VK_SUBOPTIMAL_KHR)) {
781-
if (result == VK_ERROR_OUT_OF_DATE_KHR) {
782-
windowResize();
783-
}
784-
return;
785-
}
786-
else {
787-
VK_CHECK_RESULT(result);
788-
}
771+
VK_CHECK_RESULT(result);
789772
}
790773
}
791774

792775
void VulkanExampleBase::submitFrame(VkCommandBuffer cmdBuffer, bool skipQueueSubmit)
793776
{
794-
if (useNewSync) {
795-
// @todo: make this an argument
796-
if (!skipQueueSubmit) {
797-
const VkPipelineStageFlags waitPipelineStage{ VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
798-
VkSubmitInfo submitInfo{ .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO };
799-
submitInfo.pWaitDstStageMask = &waitPipelineStage;
800-
submitInfo.commandBufferCount = 1;
801-
if (cmdBuffer != VK_NULL_HANDLE) {
802-
submitInfo.pCommandBuffers = &cmdBuffer;
803-
} else {
804-
submitInfo.pCommandBuffers = &drawCmdBuffers[currentBuffer];
805-
}
806-
submitInfo.pWaitSemaphores = &presentCompleteSemaphores[currentBuffer];
807-
submitInfo.waitSemaphoreCount = 1;
808-
submitInfo.pSignalSemaphores = &renderCompleteSemaphores[currentImageIndex];
809-
submitInfo.signalSemaphoreCount = 1;
810-
VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, waitFences[currentBuffer]));
811-
}
812-
813-
VkPresentInfoKHR presentInfo{ VK_STRUCTURE_TYPE_PRESENT_INFO_KHR };
814-
presentInfo.waitSemaphoreCount = 1;
815-
presentInfo.pWaitSemaphores = &renderCompleteSemaphores[currentImageIndex];
816-
presentInfo.swapchainCount = 1;
817-
presentInfo.pSwapchains = &swapChain.swapChain;
818-
presentInfo.pImageIndices = &currentImageIndex;
819-
VkResult result = vkQueuePresentKHR(queue, &presentInfo);
820-
// Recreate the swapchain if it's no longer compatible with the surface (OUT_OF_DATE) or no longer optimal for presentation (SUBOPTIMAL)
821-
if ((result == VK_ERROR_OUT_OF_DATE_KHR) || (result == VK_SUBOPTIMAL_KHR)) {
822-
windowResize();
823-
if (result == VK_ERROR_OUT_OF_DATE_KHR) {
824-
return;
825-
}
826-
}
827-
else {
828-
VK_CHECK_RESULT(result);
777+
// @todo: make this an argument
778+
if (!skipQueueSubmit) {
779+
const VkPipelineStageFlags waitPipelineStage{ VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
780+
VkSubmitInfo submitInfo{ .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO };
781+
submitInfo.pWaitDstStageMask = &waitPipelineStage;
782+
submitInfo.commandBufferCount = 1;
783+
if (cmdBuffer != VK_NULL_HANDLE) {
784+
submitInfo.pCommandBuffers = &cmdBuffer;
785+
} else {
786+
submitInfo.pCommandBuffers = &drawCmdBuffers[currentBuffer];
787+
}
788+
submitInfo.pWaitSemaphores = &presentCompleteSemaphores[currentBuffer];
789+
submitInfo.waitSemaphoreCount = 1;
790+
submitInfo.pSignalSemaphores = &renderCompleteSemaphores[currentImageIndex];
791+
submitInfo.signalSemaphoreCount = 1;
792+
VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, waitFences[currentBuffer]));
793+
}
794+
795+
VkPresentInfoKHR presentInfo{ VK_STRUCTURE_TYPE_PRESENT_INFO_KHR };
796+
presentInfo.waitSemaphoreCount = 1;
797+
presentInfo.pWaitSemaphores = &renderCompleteSemaphores[currentImageIndex];
798+
presentInfo.swapchainCount = 1;
799+
presentInfo.pSwapchains = &swapChain.swapChain;
800+
presentInfo.pImageIndices = &currentImageIndex;
801+
VkResult result = vkQueuePresentKHR(queue, &presentInfo);
802+
// Recreate the swapchain if it's no longer compatible with the surface (OUT_OF_DATE) or no longer optimal for presentation (SUBOPTIMAL)
803+
if ((result == VK_ERROR_OUT_OF_DATE_KHR) || (result == VK_SUBOPTIMAL_KHR)) {
804+
windowResize();
805+
if (result == VK_ERROR_OUT_OF_DATE_KHR) {
806+
return;
829807
}
830-
// Select the next frame to render to, based on the max. no. of concurrent frames
831-
currentBuffer = (currentBuffer + 1) % maxConcurrentFrames;
832808
}
833809
else {
834-
VkResult result = swapChain.queuePresent(queue, currentBuffer, semaphores.renderComplete);
835-
// Recreate the swapchain if it's no longer compatible with the surface (OUT_OF_DATE) or no longer optimal for presentation (SUBOPTIMAL)
836-
if ((result == VK_ERROR_OUT_OF_DATE_KHR) || (result == VK_SUBOPTIMAL_KHR)) {
837-
windowResize();
838-
if (result == VK_ERROR_OUT_OF_DATE_KHR) {
839-
return;
840-
}
841-
}
842-
else {
843-
VK_CHECK_RESULT(result);
844-
}
845-
VK_CHECK_RESULT(vkQueueWaitIdle(queue));
810+
VK_CHECK_RESULT(result);
846811
}
812+
// Select the next frame to render to, based on the max. no. of concurrent frames
813+
currentBuffer = (currentBuffer + 1) % maxConcurrentFrames;
847814
}
848815

849816
VulkanExampleBase::VulkanExampleBase()
@@ -1016,19 +983,15 @@ VulkanExampleBase::~VulkanExampleBase()
1016983

1017984
vkDestroyCommandPool(device, cmdPool, nullptr);
1018985

1019-
vkDestroySemaphore(device, semaphores.presentComplete, nullptr);
1020-
vkDestroySemaphore(device, semaphores.renderComplete, nullptr);
1021986
for (auto& fence : waitFences) {
1022987
vkDestroyFence(device, fence, nullptr);
1023988
}
1024989

1025-
if (useNewSync) {
1026-
for (size_t i = 0; i < presentCompleteSemaphores.size(); i++) {
1027-
vkDestroySemaphore(device, presentCompleteSemaphores[i], nullptr);
1028-
}
1029-
for (size_t i = 0; i < renderCompleteSemaphores.size(); i++) {
1030-
vkDestroySemaphore(device, renderCompleteSemaphores[i], nullptr);
1031-
}
990+
for (auto& semaphore : presentCompleteSemaphores) {
991+
vkDestroySemaphore(device, semaphore, nullptr);
992+
}
993+
for (auto& semaphore : renderCompleteSemaphores) {
994+
vkDestroySemaphore(device, semaphore, nullptr);
1032995
}
1033996

1034997
if (settings.overlay) {
@@ -1194,15 +1157,6 @@ bool VulkanExampleBase::initVulkan()
11941157

11951158
swapChain.setContext(instance, physicalDevice, device);
11961159

1197-
// Create synchronization objects
1198-
VkSemaphoreCreateInfo semaphoreCreateInfo = vks::initializers::semaphoreCreateInfo();
1199-
// Create a semaphore used to synchronize image presentation
1200-
// Ensures that the image is displayed before we start submitting new commands to the queue
1201-
VK_CHECK_RESULT(vkCreateSemaphore(device, &semaphoreCreateInfo, nullptr, &semaphores.presentComplete));
1202-
// Create a semaphore used to synchronize command submission
1203-
// Ensures that the image is not presented until all commands have been submitted and executed
1204-
VK_CHECK_RESULT(vkCreateSemaphore(device, &semaphoreCreateInfo, nullptr, &semaphores.renderComplete));
1205-
12061160
return true;
12071161
}
12081162

@@ -3091,8 +3045,6 @@ void VulkanExampleBase::keyPressed(uint32_t) {}
30913045

30923046
void VulkanExampleBase::mouseMoved(double x, double y, bool & handled) {}
30933047

3094-
void VulkanExampleBase::buildCommandBuffers() {}
3095-
30963048
void VulkanExampleBase::createSynchronizationPrimitives()
30973049
{
30983050
// Wait fences to sync command buffer access
@@ -3101,19 +3053,17 @@ void VulkanExampleBase::createSynchronizationPrimitives()
31013053
for (auto& fence : waitFences) {
31023054
VK_CHECK_RESULT(vkCreateFence(device, &fenceCreateInfo, nullptr, &fence));
31033055
}
3104-
if (useNewSync) {
3105-
// Used to ensure that image presentation is complete before starting to submit again
3106-
presentCompleteSemaphores.resize(maxConcurrentFrames);
3107-
for (auto& semaphore : presentCompleteSemaphores) {
3108-
VkSemaphoreCreateInfo semaphoreCI{ VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO };
3109-
VK_CHECK_RESULT(vkCreateSemaphore(device, &semaphoreCI, nullptr, &semaphore));
3110-
}
3111-
// Semaphore used to ensure that all commands submitted have been finished before submitting the image to the queue
3112-
renderCompleteSemaphores.resize(swapChain.images.size());
3113-
for (auto& semaphore : renderCompleteSemaphores) {
3114-
VkSemaphoreCreateInfo semaphoreCI{ VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO };
3115-
VK_CHECK_RESULT(vkCreateSemaphore(device, &semaphoreCI, nullptr, &semaphore));
3116-
}
3056+
// Used to ensure that image presentation is complete before starting to submit again
3057+
presentCompleteSemaphores.resize(maxConcurrentFrames);
3058+
for (auto& semaphore : presentCompleteSemaphores) {
3059+
VkSemaphoreCreateInfo semaphoreCI{ VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO };
3060+
VK_CHECK_RESULT(vkCreateSemaphore(device, &semaphoreCI, nullptr, &semaphore));
3061+
}
3062+
// Semaphore used to ensure that all commands submitted have been finished before submitting the image to the queue
3063+
renderCompleteSemaphores.resize(swapChain.images.size());
3064+
for (auto& semaphore : renderCompleteSemaphores) {
3065+
VkSemaphoreCreateInfo semaphoreCI{ VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO };
3066+
VK_CHECK_RESULT(vkCreateSemaphore(device, &semaphoreCI, nullptr, &semaphore));
31173067
}
31183068
}
31193069

@@ -3299,13 +3249,12 @@ void VulkanExampleBase::windowResize()
32993249
}
33003250
}
33013251

3302-
// Command buffers need to be recreated as they may store
3303-
// references to the recreated frame buffer
3304-
destroyCommandBuffers();
3305-
createCommandBuffers();
3306-
buildCommandBuffers();
3307-
3308-
// SRS - Recreate fences in case number of swapchain images has changed on resize
3252+
for (auto& semaphore : presentCompleteSemaphores) {
3253+
vkDestroySemaphore(device, semaphore, nullptr);
3254+
}
3255+
for (auto& semaphore : renderCompleteSemaphores) {
3256+
vkDestroySemaphore(device, semaphore, nullptr);
3257+
}
33093258
for (auto& fence : waitFences) {
33103259
vkDestroyFence(device, fence, nullptr);
33113260
}

base/vulkanexamplebase.h

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,6 @@ class VulkanExampleBase
138138
VkRenderPass renderPass{ VK_NULL_HANDLE };
139139
// List of available frame buffers (same as number of swap chain images)
140140
std::vector<VkFramebuffer>frameBuffers;
141-
// Active frame buffer index
142-
uint32_t currentBuffer = 0;
143141
// Descriptor set pool
144142
VkDescriptorPool descriptorPool{ VK_NULL_HANDLE };
145143
// List of shader modules created (stored for cleanup)
@@ -148,17 +146,14 @@ class VulkanExampleBase
148146
VkPipelineCache pipelineCache{ VK_NULL_HANDLE };
149147
// Wraps the swap chain to present images (framebuffers) to the windowing system
150148
VulkanSwapChain swapChain;
151-
// Synchronization semaphores
152-
struct {
153-
// Swap chain image presentation
154-
VkSemaphore presentComplete;
155-
// Command buffer submission and execution
156-
VkSemaphore renderComplete;
157-
} semaphores{};
158149

159150
// This sample will be using a new synchronisation setup, which is closer to what should be used with Vulkan
160151
bool useNewSync{ false };
152+
153+
// Synchronization related objects and variables
154+
// These are used to have multiple frame buffers "in flight" to get some CPU/GPU parallelism
161155
uint32_t currentImageIndex{ 0 };
156+
uint32_t currentBuffer = 0;
162157
std::vector<VkSemaphore> presentCompleteSemaphores{};
163158
std::vector<VkSemaphore> renderCompleteSemaphores{};
164159
std::vector<VkFence> waitFences;
@@ -382,8 +377,6 @@ class VulkanExampleBase
382377
virtual void mouseMoved(double x, double y, bool &handled);
383378
/** @brief (Virtual) Called when the window has been resized, can be used by the sample application to recreate resources */
384379
virtual void windowResized();
385-
/** @brief (Virtual) Called when resources have been recreated that require a rebuild of the command buffers (e.g. frame buffer), to be implemented by the sample application */
386-
virtual void buildCommandBuffers();
387380
/** @brief (Virtual) Setup default depth and stencil views */
388381
virtual void setupDepthStencil();
389382
/** @brief (Virtual) Setup default framebuffers for all requested swapchain images */

0 commit comments

Comments
 (0)