diff options
Diffstat (limited to 'main.cpp')
| -rw-r--r-- | main.cpp | 67 |
1 files changed, 42 insertions, 25 deletions
@@ -112,11 +112,12 @@ private: std::vector<VkFramebuffer> swapChainFramebuffers; VkCommandPool commandPool; - VkCommandBuffer commandBuffer; - VkSemaphore imageAvailableSemaphore; - VkSemaphore renderFinishedSemaphore; - VkFence inFlightFence; + uint32_t currentFrame = 0; + std::vector<VkCommandBuffer> commandBuffers; + std::vector<VkSemaphore> imageAvailableSemaphores; + std::vector<VkSemaphore> renderFinishedSemaphores; + std::vector<VkFence> inFlightFences; void initWindow() { glfwInit(); @@ -169,11 +170,15 @@ private: createGraphicsPipeline(); // 08 Graphics Pipeline -> Introduction createFramebuffers(); // 12 Drawing -> Framebuffers createCommandPool(); // 13 Drawing -> Commmand Buffers - createCommandBuffer(); // -- + createCommandBuffers(); // -- createSyncObjects (); // 14 Drawing -> Rendering } void createSyncObjects() { + imageAvailableSemaphores.resize(MAX_FRAMES_IN_FLIGHT); + renderFinishedSemaphores.resize(MAX_FRAMES_IN_FLIGHT); + inFlightFences.resize(MAX_FRAMES_IN_FLIGHT); + VkSemaphoreCreateInfo semaphoreInfo{}; semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; @@ -181,10 +186,13 @@ private: fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT; - if (vkCreateSemaphore(device, &semaphoreInfo, nullptr, &imageAvailableSemaphore) != VK_SUCCESS || - vkCreateSemaphore(device, &semaphoreInfo, nullptr, &renderFinishedSemaphore) != VK_SUCCESS || - vkCreateFence(device, &fenceInfo, nullptr, &inFlightFence) != VK_SUCCESS) { - throw std::runtime_error("failed to create semaphores!"); + for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) { + if (vkCreateSemaphore(device, &semaphoreInfo, nullptr, &imageAvailableSemaphores[i]) != VK_SUCCESS || + vkCreateSemaphore(device, &semaphoreInfo, nullptr, &renderFinishedSemaphores[i]) != VK_SUCCESS || + vkCreateFence(device, &fenceInfo, nullptr, &inFlightFences[i]) != VK_SUCCESS) { + + throw std::runtime_error("failed to create synchronization objects for a frame!"); + } } } @@ -236,14 +244,16 @@ private: } } - void createCommandBuffer() { + void createCommandBuffers() { + commandBuffers.resize(MAX_FRAMES_IN_FLIGHT); + VkCommandBufferAllocateInfo allocInfo{}; allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; allocInfo.commandPool = commandPool; allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; - allocInfo.commandBufferCount = 1; + allocInfo.commandBufferCount = (uint32_t) commandBuffers.size(); - if (vkAllocateCommandBuffers(device, &allocInfo, &commandBuffer) != VK_SUCCESS) { + if (vkAllocateCommandBuffers(device, &allocInfo, commandBuffers.data()) != VK_SUCCESS) { throw std::runtime_error("failed to allocate command buffers!"); } } @@ -528,6 +538,8 @@ private: imageCount = swapChainSupport.capabilities.maxImageCount; } + std::cout << "swap chain image count: (" << swapChainSupport.capabilities.minImageCount << " - " << swapChainSupport.capabilities.maxImageCount << ") -> " << imageCount << std::endl; + VkSwapchainCreateInfoKHR createInfo{}; createInfo.sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR; createInfo.surface = surface; @@ -692,28 +704,29 @@ private: void drawFrame() { - vkWaitForFences(device, 1, &inFlightFence, VK_TRUE, UINT64_MAX); - vkResetFences(device, 1, &inFlightFence); + vkWaitForFences(device, 1, &inFlightFences[currentFrame], VK_TRUE, UINT64_MAX); + vkResetFences(device, 1, &inFlightFences[currentFrame]); uint32_t imageIndex; - vkAcquireNextImageKHR(device, swapChain, UINT64_MAX, imageAvailableSemaphore, VK_NULL_HANDLE, &imageIndex); - vkResetCommandBuffer(commandBuffer, 0); - recordCommandBuffer(commandBuffer, imageIndex); + vkAcquireNextImageKHR(device, swapChain, UINT64_MAX, imageAvailableSemaphores[currentFrame], VK_NULL_HANDLE, &imageIndex); + vkResetCommandBuffer(commandBuffers[currentFrame], 0); + recordCommandBuffer(commandBuffers[currentFrame], imageIndex); + + VkSemaphore waitSemaphores[] = {imageAvailableSemaphores[currentFrame]}; + VkSemaphore signalSemaphores[] = {renderFinishedSemaphores[currentFrame]}; + VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT}; VkSubmitInfo submitInfo{}; submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - VkSemaphore waitSemaphores[] = {imageAvailableSemaphore}; - VkSemaphore signalSemaphores[] = {renderFinishedSemaphore}; - VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT}; submitInfo.waitSemaphoreCount = 1; submitInfo.pWaitSemaphores = waitSemaphores; submitInfo.pWaitDstStageMask = waitStages; submitInfo.signalSemaphoreCount = 1; submitInfo.pSignalSemaphores = signalSemaphores; submitInfo.commandBufferCount = 1; - submitInfo.pCommandBuffers = &commandBuffer; + submitInfo.pCommandBuffers = &commandBuffers[currentFrame]; - if (vkQueueSubmit(graphicsQueue, 1, &submitInfo, inFlightFence) != VK_SUCCESS) { + if (vkQueueSubmit(graphicsQueue, 1, &submitInfo, inFlightFences[currentFrame]) != VK_SUCCESS) { throw std::runtime_error("failed to submit draw command buffer!"); } @@ -728,6 +741,8 @@ private: presentInfo.pResults = nullptr; // Optional vkQueuePresentKHR(presentQueue, &presentInfo); + + currentFrame = (currentFrame + 1) % MAX_FRAMES_IN_FLIGHT; } void createInstance() { @@ -954,9 +969,11 @@ private: } void cleanup() { - vkDestroySemaphore(device, imageAvailableSemaphore, nullptr); - vkDestroySemaphore(device, renderFinishedSemaphore, nullptr); - vkDestroyFence(device, inFlightFence, nullptr); + for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) { + vkDestroySemaphore(device, renderFinishedSemaphores[i], nullptr); + vkDestroySemaphore(device, imageAvailableSemaphores[i], nullptr); + vkDestroyFence(device, inFlightFences[i], nullptr); + } vkDestroyCommandPool(device, commandPool, nullptr); for (auto framebuffer : swapChainFramebuffers) { vkDestroyFramebuffer(device, framebuffer, nullptr); |
