From baf3cddd81564c2815e62242fbcc138b6a83cfa2 Mon Sep 17 00:00:00 2001 From: Nigel Barink Date: Sun, 14 May 2023 16:47:37 +0200 Subject: [PATCH] 2 Frames in flight --- Hello_triangle/main.cpp | 73 ++++++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 33 deletions(-) diff --git a/Hello_triangle/main.cpp b/Hello_triangle/main.cpp index cd4b247..217ca7e 100644 --- a/Hello_triangle/main.cpp +++ b/Hello_triangle/main.cpp @@ -17,9 +17,9 @@ #include #include - const uint32_t WIDTH = 800; const uint32_t HEIGHT = 600; +const int MAX_FRAMES_IN_FLIGHT = 2; const std::vector validationLayers ={ "VK_LAYER_KHRONOS_validation" @@ -65,12 +65,12 @@ const std::vector deviceExtensions = { VkPipeline graphicsPipeline; std::vector swapchainFrameBuffers; VkCommandPool commandPool; - VkCommandBuffer commandBuffer; - VkSemaphore imageAvailableSemaphore; - VkSemaphore renderFinishedSemaphore; - VkFence inFlightFence; - + std::vector commandBuffers; + std::vector imageAvailableSemaphores; + std::vector renderFinishedSemaphores; + std::vector inFlightFences; + uint32_t currentFrame = 0; struct SwapChainSupportDetails { VkSurfaceCapabilitiesKHR capabilities; @@ -100,11 +100,15 @@ const std::vector deviceExtensions = { createGraphicsPipeline(); createFramebuffers(); createCommandPool(); - createCommandBuffer(); + createCommandBuffers(); createSyncObjects(); } 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; @@ -112,12 +116,17 @@ const std::vector deviceExtensions = { 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 semaphores!"); + } } + + } @@ -169,14 +178,16 @@ const std::vector deviceExtensions = { } - 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!"); } } @@ -559,7 +570,6 @@ const std::vector deviceExtensions = { return buffer; } - void pickPhysicalDevice() { uint32_t deviceCount = 0; vkEnumeratePhysicalDevices(instance, &deviceCount, nullptr); @@ -675,7 +685,6 @@ const std::vector deviceExtensions = { return details; } - VkResult CreateDebugUtilsMessengerEXT(VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugUtilsMessengerEXT* pDebugMessenger) { auto func = (PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr(instance, "vkCreateDebugUtilsMessengerEXT"); if (func != nullptr) { @@ -739,7 +748,6 @@ const std::vector deviceExtensions = { return requiredExtensions.empty(); } - std::vector getRequiredExtensions() { uint32_t glfwExtensionCount = 0; const char** glfwExtensions; @@ -857,34 +865,33 @@ const std::vector deviceExtensions = { vkDeviceWaitIdle(device); } - 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); + vkAcquireNextImageKHR(device, swapChain, UINT64_MAX, imageAvailableSemaphores[currentFrame], VK_NULL_HANDLE, &imageIndex); - vkResetCommandBuffer(commandBuffer, 0); - recordCommandBuffer(commandBuffer, imageIndex); + vkResetCommandBuffer(commandBuffers[currentFrame], 0); + recordCommandBuffer(commandBuffers[currentFrame], imageIndex); VkSubmitInfo submitInfo{}; submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - VkSemaphore waitSemaphores[] = { imageAvailableSemaphore }; + VkSemaphore waitSemaphores[] = { imageAvailableSemaphores[currentFrame]}; VkPipelineStageFlags waitstages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT }; submitInfo.waitSemaphoreCount = 1; submitInfo.pWaitSemaphores = waitSemaphores; submitInfo.pWaitDstStageMask = waitstages; submitInfo.commandBufferCount = 1; - submitInfo.pCommandBuffers = &commandBuffer; + submitInfo.pCommandBuffers = &commandBuffers[currentFrame]; - VkSemaphore signalSemaphore[] = { renderFinishedSemaphore }; + VkSemaphore signalSemaphore[] = { renderFinishedSemaphores[currentFrame]}; submitInfo.signalSemaphoreCount = 1; submitInfo.pSignalSemaphores = signalSemaphore; - 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"); } @@ -901,17 +908,18 @@ const std::vector deviceExtensions = { vkQueuePresentKHR(presentQueue, &presentInfo); - + currentFrame = (currentFrame + 1) % MAX_FRAMES_IN_FLIGHT; } - void cleanup(){ + for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) { + vkDestroySemaphore(device, imageAvailableSemaphores[i], nullptr); + vkDestroySemaphore(device, renderFinishedSemaphores[i], nullptr); + vkDestroyFence(device, inFlightFences[i], nullptr); - vkDestroySemaphore(device, imageAvailableSemaphore, nullptr); - vkDestroySemaphore(device, renderFinishedSemaphore, nullptr); - vkDestroyFence(device, inFlightFence, nullptr); + } vkDestroyCommandPool(device, commandPool, nullptr); @@ -951,7 +959,6 @@ const std::vector deviceExtensions = { createInfo.pfnUserCallback = debugCallback; } - void DestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerEXT debugMessenger, const VkAllocationCallbacks* pAllocator) { auto func = (PFN_vkDestroyDebugUtilsMessengerEXT) vkGetInstanceProcAddr(instance, "vkDestroyDebugUtilsMessengerEXT"); if (func != nullptr) {