Kajetan Johannes Hammerle 2 месяцев назад
Родитель
Сommit
4077daea55
1 измененных файлов с 44 добавлено и 22 удалено
  1. 44 22
      src/VulkanWrapper.c

+ 44 - 22
src/VulkanWrapper.c

@@ -26,10 +26,17 @@ static VkRect2D scissor;
 static VkPipeline pipeline;
 static VkFramebuffer* framebuffers;
 static VkCommandPool commandPool;
-static VkCommandBuffer commandBuffer;
-static VkSemaphore imageAvailableSemaphore;
-static VkSemaphore renderFinishedSemaphore;
-static VkFence inFlightFence;
+static constexpr size_t MAX_FRAMES = 2;
+static size_t currentFrame = 0;
+
+typedef struct {
+    VkCommandBuffer commandBuffer;
+    VkSemaphore imageAvailableSemaphore;
+    VkSemaphore renderFinishedSemaphore;
+    VkFence inFlightFence;
+} Frame;
+
+static Frame frames[MAX_FRAMES];
 
 static int getSurfaceFormatPoints(const VkSurfaceFormatKHR* sf) {
     if(sf->format == VK_FORMAT_B8G8R8A8_UNORM &&
@@ -360,7 +367,7 @@ static bool initCommandPool() {
         .flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
         .queueFamilyIndex = graphicsFamily};
     VK_ASSERT(vkCreateCommandPool(device, &info, nullptr, &commandPool));
-    return initCommandVulkanBuffer(&commandBuffer, device, commandPool);
+    return false;
 }
 
 static bool fillCommandBuffer(VkCommandBuffer cb, u32 index) {
@@ -385,6 +392,19 @@ static bool fillCommandBuffer(VkCommandBuffer cb, u32 index) {
     return false;
 }
 
+static bool initFrames() {
+    for(size_t i = 0; i < MAX_FRAMES; i++) {
+        if(initCommandVulkanBuffer(
+               &frames[i].commandBuffer, device, commandPool) ||
+           initVulkanSemaphore(&frames[i].imageAvailableSemaphore, device) ||
+           initVulkanSemaphore(&frames[i].renderFinishedSemaphore, device) ||
+           initVulkanFence(&frames[i].inFlightFence, device)) {
+            return true;
+        }
+    }
+    return false;
+}
+
 bool initVulkan() {
     return initVulkanInstance() || initVulkanDebugging() ||
            initVulkanSurface(&surface, getWindow()) || initPhysicalDevice() ||
@@ -394,38 +414,36 @@ bool initVulkan() {
            initVulkanFramebuffers(
                &framebuffers, &images, device, renderPass, swapchainSize.width,
                swapchainSize.height) ||
-           initCommandPool() ||
-           initVulkanSemaphore(&imageAvailableSemaphore, device) ||
-           initVulkanSemaphore(&renderFinishedSemaphore, device) ||
-           initVulkanFence(&inFlightFence, device);
+           initCommandPool() || initFrames();
 }
 
 static bool render() {
-    VK_ASSERT(vkWaitForFences(device, 1, &inFlightFence, true, UINT64_MAX));
-    VK_ASSERT(vkResetFences(device, 1, &inFlightFence));
+    Frame* f = frames + currentFrame;
+    VK_ASSERT(vkWaitForFences(device, 1, &f->inFlightFence, true, UINT64_MAX));
+    VK_ASSERT(vkResetFences(device, 1, &f->inFlightFence));
 
     uint32_t imageIndex = 0;
     VK_ASSERT(vkAcquireNextImageKHR(
-        device, swapchain, UINT64_MAX, imageAvailableSemaphore, VK_NULL_HANDLE,
-        &imageIndex));
+        device, swapchain, UINT64_MAX, f->imageAvailableSemaphore,
+        VK_NULL_HANDLE, &imageIndex));
 
-    vkResetCommandBuffer(commandBuffer, 0);
-    fillCommandBuffer(commandBuffer, imageIndex);
+    vkResetCommandBuffer(f->commandBuffer, 0);
+    fillCommandBuffer(f->commandBuffer, imageIndex);
 
-    VkSemaphore waitSemaphores[] = {imageAvailableSemaphore};
+    VkSemaphore waitSemaphores[] = {f->imageAvailableSemaphore};
     VkPipelineStageFlags waitStages[] = {
         VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT};
-    VkSemaphore signalSemaphores[] = {renderFinishedSemaphore};
+    VkSemaphore signalSemaphores[] = {f->renderFinishedSemaphore};
     VkSubmitInfo info = {
         .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
         .waitSemaphoreCount = 1,
         .pWaitSemaphores = waitSemaphores,
         .pWaitDstStageMask = waitStages,
         .commandBufferCount = 1,
-        .pCommandBuffers = &commandBuffer,
+        .pCommandBuffers = &f->commandBuffer,
         .signalSemaphoreCount = 1,
         .pSignalSemaphores = signalSemaphores};
-    VK_ASSERT(vkQueueSubmit(graphicsQueue, 1, &info, inFlightFence));
+    VK_ASSERT(vkQueueSubmit(graphicsQueue, 1, &info, f->inFlightFence));
 
     VkPresentInfoKHR presentInfo = {
         .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
@@ -436,6 +454,7 @@ static bool render() {
         .pImageIndices = &imageIndex};
 
     VK_ASSERT(vkQueuePresentKHR(presentQueue, &presentInfo));
+    currentFrame = (currentFrame + 1) % MAX_FRAMES;
     return false;
 }
 
@@ -446,9 +465,12 @@ void renderVulkan() {
 void destroyVulkan(void) {
     if(device != VK_NULL_HANDLE) {
         vkDeviceWaitIdle(device);
-        destroyVulkanFence(inFlightFence, device);
-        destroyVulkanSemaphore(imageAvailableSemaphore, device);
-        destroyVulkanSemaphore(renderFinishedSemaphore, device);
+        for(size_t i = 0; i < MAX_FRAMES; i++) {
+            Frame* f = frames + i;
+            destroyVulkanFence(f->inFlightFence, device);
+            destroyVulkanSemaphore(f->imageAvailableSemaphore, device);
+            destroyVulkanSemaphore(f->renderFinishedSemaphore, device);
+        }
         vkDestroyCommandPool(device, commandPool, nullptr);
         destroyVulkanFramebuffers(&framebuffers, images.amount, device);
         vkDestroyPipeline(device, pipeline, nullptr);