1
0

2 Frames in flight

This commit is contained in:
2023-05-14 16:47:37 +02:00
parent 7c96a274f9
commit baf3cddd81

View File

@@ -17,9 +17,9 @@
#include <set> #include <set>
#include <fstream> #include <fstream>
const uint32_t WIDTH = 800; const uint32_t WIDTH = 800;
const uint32_t HEIGHT = 600; const uint32_t HEIGHT = 600;
const int MAX_FRAMES_IN_FLIGHT = 2;
const std::vector<const char*> validationLayers ={ const std::vector<const char*> validationLayers ={
"VK_LAYER_KHRONOS_validation" "VK_LAYER_KHRONOS_validation"
@@ -65,12 +65,12 @@ const std::vector<const char*> deviceExtensions = {
VkPipeline graphicsPipeline; VkPipeline graphicsPipeline;
std::vector<VkFramebuffer> swapchainFrameBuffers; std::vector<VkFramebuffer> swapchainFrameBuffers;
VkCommandPool commandPool; VkCommandPool commandPool;
VkCommandBuffer commandBuffer; std::vector<VkCommandBuffer> commandBuffers;
VkSemaphore imageAvailableSemaphore; std::vector<VkSemaphore> imageAvailableSemaphores;
VkSemaphore renderFinishedSemaphore; std::vector<VkSemaphore> renderFinishedSemaphores;
VkFence inFlightFence; std::vector<VkFence> inFlightFences;
uint32_t currentFrame = 0;
struct SwapChainSupportDetails { struct SwapChainSupportDetails {
VkSurfaceCapabilitiesKHR capabilities; VkSurfaceCapabilitiesKHR capabilities;
@@ -100,11 +100,15 @@ const std::vector<const char*> deviceExtensions = {
createGraphicsPipeline(); createGraphicsPipeline();
createFramebuffers(); createFramebuffers();
createCommandPool(); createCommandPool();
createCommandBuffer(); createCommandBuffers();
createSyncObjects(); createSyncObjects();
} }
void createSyncObjects() { void createSyncObjects() {
imageAvailableSemaphores.resize(MAX_FRAMES_IN_FLIGHT);
renderFinishedSemaphores.resize(MAX_FRAMES_IN_FLIGHT);
inFlightFences.resize(MAX_FRAMES_IN_FLIGHT);
VkSemaphoreCreateInfo semaphoreInfo{}; VkSemaphoreCreateInfo semaphoreInfo{};
semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; semaphoreInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO;
@@ -112,12 +116,17 @@ const std::vector<const char*> deviceExtensions = {
fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT; fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
if (vkCreateSemaphore(device, &semaphoreInfo, nullptr, &imageAvailableSemaphore) != VK_SUCCESS || for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) {
vkCreateSemaphore(device, &semaphoreInfo, nullptr, &renderFinishedSemaphore) != VK_SUCCESS ||
vkCreateFence(device, &fenceInfo, nullptr, &inFlightFence) != VK_SUCCESS) { if (vkCreateSemaphore(device, &semaphoreInfo, nullptr, &imageAvailableSemaphores[i]) != VK_SUCCESS ||
throw std::runtime_error("failed to create semaphores!"); 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<const char*> deviceExtensions = {
} }
void createCommandBuffer() { void createCommandBuffers() {
commandBuffers.resize(MAX_FRAMES_IN_FLIGHT);
VkCommandBufferAllocateInfo allocInfo{}; VkCommandBufferAllocateInfo allocInfo{};
allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
allocInfo.commandPool = commandPool; allocInfo.commandPool = commandPool;
allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; 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!"); throw std::runtime_error("failed to allocate command buffers!");
} }
} }
@@ -559,7 +570,6 @@ const std::vector<const char*> deviceExtensions = {
return buffer; return buffer;
} }
void pickPhysicalDevice() { void pickPhysicalDevice() {
uint32_t deviceCount = 0; uint32_t deviceCount = 0;
vkEnumeratePhysicalDevices(instance, &deviceCount, nullptr); vkEnumeratePhysicalDevices(instance, &deviceCount, nullptr);
@@ -675,7 +685,6 @@ const std::vector<const char*> deviceExtensions = {
return details; return details;
} }
VkResult CreateDebugUtilsMessengerEXT(VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugUtilsMessengerEXT* pDebugMessenger) { VkResult CreateDebugUtilsMessengerEXT(VkInstance instance, const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDebugUtilsMessengerEXT* pDebugMessenger) {
auto func = (PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr(instance, "vkCreateDebugUtilsMessengerEXT"); auto func = (PFN_vkCreateDebugUtilsMessengerEXT)vkGetInstanceProcAddr(instance, "vkCreateDebugUtilsMessengerEXT");
if (func != nullptr) { if (func != nullptr) {
@@ -739,7 +748,6 @@ const std::vector<const char*> deviceExtensions = {
return requiredExtensions.empty(); return requiredExtensions.empty();
} }
std::vector<const char*> getRequiredExtensions() { std::vector<const char*> getRequiredExtensions() {
uint32_t glfwExtensionCount = 0; uint32_t glfwExtensionCount = 0;
const char** glfwExtensions; const char** glfwExtensions;
@@ -857,34 +865,33 @@ const std::vector<const char*> deviceExtensions = {
vkDeviceWaitIdle(device); vkDeviceWaitIdle(device);
} }
void drawFrame() { void drawFrame() {
vkWaitForFences(device, 1, &inFlightFence, VK_TRUE, UINT64_MAX); vkWaitForFences(device, 1, &inFlightFences[currentFrame], VK_TRUE, UINT64_MAX);
vkResetFences(device, 1, &inFlightFence); vkResetFences(device, 1, &inFlightFences[currentFrame]);
uint32_t imageIndex; 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); vkResetCommandBuffer(commandBuffers[currentFrame], 0);
recordCommandBuffer(commandBuffer, imageIndex); recordCommandBuffer(commandBuffers[currentFrame], imageIndex);
VkSubmitInfo submitInfo{}; VkSubmitInfo submitInfo{};
submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
VkSemaphore waitSemaphores[] = { imageAvailableSemaphore }; VkSemaphore waitSemaphores[] = { imageAvailableSemaphores[currentFrame]};
VkPipelineStageFlags waitstages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT }; VkPipelineStageFlags waitstages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT };
submitInfo.waitSemaphoreCount = 1; submitInfo.waitSemaphoreCount = 1;
submitInfo.pWaitSemaphores = waitSemaphores; submitInfo.pWaitSemaphores = waitSemaphores;
submitInfo.pWaitDstStageMask = waitstages; submitInfo.pWaitDstStageMask = waitstages;
submitInfo.commandBufferCount = 1; submitInfo.commandBufferCount = 1;
submitInfo.pCommandBuffers = &commandBuffer; submitInfo.pCommandBuffers = &commandBuffers[currentFrame];
VkSemaphore signalSemaphore[] = { renderFinishedSemaphore }; VkSemaphore signalSemaphore[] = { renderFinishedSemaphores[currentFrame]};
submitInfo.signalSemaphoreCount = 1; submitInfo.signalSemaphoreCount = 1;
submitInfo.pSignalSemaphores = signalSemaphore; 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"); throw std::runtime_error("failed to submit draw command buffer");
} }
@@ -901,17 +908,18 @@ const std::vector<const char*> deviceExtensions = {
vkQueuePresentKHR(presentQueue, &presentInfo); vkQueuePresentKHR(presentQueue, &presentInfo);
currentFrame = (currentFrame + 1) % MAX_FRAMES_IN_FLIGHT;
} }
void cleanup(){ 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); vkDestroyCommandPool(device, commandPool, nullptr);
@@ -951,7 +959,6 @@ const std::vector<const char*> deviceExtensions = {
createInfo.pfnUserCallback = debugCallback; createInfo.pfnUserCallback = debugCallback;
} }
void DestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerEXT debugMessenger, const VkAllocationCallbacks* pAllocator) { void DestroyDebugUtilsMessengerEXT(VkInstance instance, VkDebugUtilsMessengerEXT debugMessenger, const VkAllocationCallbacks* pAllocator) {
auto func = (PFN_vkDestroyDebugUtilsMessengerEXT) vkGetInstanceProcAddr(instance, "vkDestroyDebugUtilsMessengerEXT"); auto func = (PFN_vkDestroyDebugUtilsMessengerEXT) vkGetInstanceProcAddr(instance, "vkDestroyDebugUtilsMessengerEXT");
if (func != nullptr) { if (func != nullptr) {