55#include " logger.h"
66#include " vulkan_base/vulkan_base.h"
77
8+ #define FRAMES_IN_FLIGHT 2
9+
810VulkanContext* context;
911VkSurfaceKHR surface;
1012VulkanSwapchain swapchain;
1113VkRenderPass renderPass;
1214std::vector<VkFramebuffer> framebuffers;
1315VulkanPipeline pipeline;
14- VkCommandPool commandPool ;
15- VkCommandBuffer commandBuffer ;
16- VkFence fence ;
17- VkSemaphore acquireSemaphore ;
18- VkSemaphore releaseSemaphore ;
16+ VkCommandPool commandPools[FRAMES_IN_FLIGHT] ;
17+ VkCommandBuffer commandBuffers[FRAMES_IN_FLIGHT] ;
18+ VkFence fences[FRAMES_IN_FLIGHT] ;
19+ VkSemaphore acquireSemaphores[FRAMES_IN_FLIGHT] ;
20+ VkSemaphore releaseSemaphores[FRAMES_IN_FLIGHT] ;
1921
2022bool handleMessage () {
2123 SDL_Event event;
@@ -55,29 +57,29 @@ void initApplication(SDL_Window* window) {
5557
5658 pipeline = createPipeline (context, " ../shaders/triangle_vert.spv" , " ../shaders/triangle_frag.spv" , renderPass, swapchain.width , swapchain.height );
5759
58- {
60+ for ( uint32_t i = 0 ; i < ARRAY_COUNT (fences); ++i) {
5961 VkFenceCreateInfo createInfo = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO };
6062 createInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT;
61- VKA (vkCreateFence (context->device , &createInfo, 0 , &fence ));
63+ VKA (vkCreateFence (context->device , &createInfo, 0 , &fences[i] ));
6264 }
63- {
65+ for ( uint32_t i = 0 ; i < ARRAY_COUNT (acquireSemaphores); ++i) {
6466 VkSemaphoreCreateInfo createInfo = { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO };
65- VKA (vkCreateSemaphore (context->device , &createInfo, 0 , &acquireSemaphore ));
66- VKA (vkCreateSemaphore (context->device , &createInfo, 0 , &releaseSemaphore ));
67+ VKA (vkCreateSemaphore (context->device , &createInfo, 0 , &acquireSemaphores[i] ));
68+ VKA (vkCreateSemaphore (context->device , &createInfo, 0 , &releaseSemaphores[i] ));
6769 }
6870
69- {
71+ for ( uint32_t i = 0 ; i < ARRAY_COUNT (commandPools); ++i) {
7072 VkCommandPoolCreateInfo createInfo = { VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO };
7173 createInfo.flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT;
7274 createInfo.queueFamilyIndex = context->graphicsQueue .familyIndex ;
73- VKA (vkCreateCommandPool (context->device , &createInfo, 0 , &commandPool ));
75+ VKA (vkCreateCommandPool (context->device , &createInfo, 0 , &commandPools[i] ));
7476 }
75- {
77+ for ( uint32_t i = 0 ; i < ARRAY_COUNT (commandPools); ++i) {
7678 VkCommandBufferAllocateInfo allocateInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO };
77- allocateInfo.commandPool = commandPool ;
79+ allocateInfo.commandPool = commandPools[i] ;
7880 allocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
7981 allocateInfo.commandBufferCount = 1 ;
80- VKA (vkAllocateCommandBuffers (context->device , &allocateInfo, &commandBuffer ));
82+ VKA (vkAllocateCommandBuffers (context->device , &allocateInfo, &commandBuffers[i] ));
8183 }
8284}
8385
@@ -86,16 +88,19 @@ void renderApplication() {
8688 greenChannel += 0 .01f ;
8789 if (greenChannel > 1 .0f ) greenChannel = 0 .0f ;
8890 uint32_t imageIndex = 0 ;
89- VK (vkAcquireNextImageKHR (context->device , swapchain.swapchain , UINT64_MAX, acquireSemaphore, 0 , &imageIndex));
91+ static uint32_t frameIndex = 0 ;
92+ VK (vkAcquireNextImageKHR (context->device , swapchain.swapchain , UINT64_MAX, acquireSemaphores[frameIndex], 0 , &imageIndex));
9093
91- VKA (vkWaitForFences (context->device , 1 , &fence , VK_TRUE, UINT64_MAX));
92- VKA (vkResetFences (context->device , 1 , &fence ));
93- VKA (vkResetCommandPool (context->device , commandPool , 0 ));
94+ VKA (vkWaitForFences (context->device , 1 , &fences[frameIndex] , VK_TRUE, UINT64_MAX));
95+ VKA (vkResetFences (context->device , 1 , &fences[frameIndex] ));
96+ VKA (vkResetCommandPool (context->device , commandPools[frameIndex] , 0 ));
9497
9598 VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO };
9699 beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
97- VKA (vkBeginCommandBuffer (commandBuffer, &beginInfo));
98100 {
101+ VkCommandBuffer commandBuffer = commandBuffers[frameIndex];
102+ VKA (vkBeginCommandBuffer (commandBuffer, &beginInfo));
103+
99104 VkClearValue clearValue = {0 .0f , greenChannel, 1 .0f , 1 .0f };
100105 VkRenderPassBeginInfo beginInfo = { VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO };
101106 beginInfo.renderPass = renderPass;
@@ -109,34 +114,43 @@ void renderApplication() {
109114 vkCmdDraw (commandBuffer, 3 , 1 , 0 , 0 );
110115
111116 vkCmdEndRenderPass (commandBuffer);
112- }
113- VKA (vkEndCommandBuffer (commandBuffer));
114117
118+ VKA (vkEndCommandBuffer (commandBuffer));
119+ }
120+
115121 VkSubmitInfo submitInfo = { VK_STRUCTURE_TYPE_SUBMIT_INFO };
116122 submitInfo.commandBufferCount = 1 ;
117- submitInfo.pCommandBuffers = &commandBuffer ;
123+ submitInfo.pCommandBuffers = &commandBuffers[frameIndex] ;
118124 submitInfo.waitSemaphoreCount = 1 ;
119- submitInfo.pWaitSemaphores = &acquireSemaphore ;
125+ submitInfo.pWaitSemaphores = &acquireSemaphores[frameIndex] ;
120126 VkPipelineStageFlags waitMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
121127 submitInfo.pWaitDstStageMask = &waitMask;
122128 submitInfo.signalSemaphoreCount = 1 ;
123- submitInfo.pSignalSemaphores = &releaseSemaphore ;
124- VKA (vkQueueSubmit (context->graphicsQueue .queue , 1 , &submitInfo, fence ));
129+ submitInfo.pSignalSemaphores = &releaseSemaphores[frameIndex] ;
130+ VKA (vkQueueSubmit (context->graphicsQueue .queue , 1 , &submitInfo, fences[frameIndex] ));
125131
126132 VkPresentInfoKHR presentInfo = { VK_STRUCTURE_TYPE_PRESENT_INFO_KHR };
127133 presentInfo.swapchainCount = 1 ;
128134 presentInfo.pSwapchains = &swapchain.swapchain ;
129135 presentInfo.pImageIndices = &imageIndex;
130136 presentInfo.waitSemaphoreCount = 1 ;
131- presentInfo.pWaitSemaphores = &releaseSemaphore ;
137+ presentInfo.pWaitSemaphores = &releaseSemaphores[frameIndex] ;
132138 VK (vkQueuePresentKHR (context->graphicsQueue .queue , &presentInfo));
139+
140+ frameIndex = (frameIndex + 1 ) % FRAMES_IN_FLIGHT;
133141}
134142
135143void shutdownApplication () {
136144 VKA (vkDeviceWaitIdle (context->device ));
137145
138- VK (vkDestroyFence (context->device , fence, 0 ));
139- VK (vkDestroyCommandPool (context->device , commandPool, 0 ));
146+ for (uint32_t i = 0 ; i < FRAMES_IN_FLIGHT; ++i) {
147+ VK (vkDestroyFence (context->device , fences[i], 0 ));
148+ VK (vkDestroySemaphore (context->device , acquireSemaphores[i], 0 ));
149+ VK (vkDestroySemaphore (context->device , releaseSemaphores[i], 0 ));
150+ }
151+ for (uint32_t i = 0 ; i < ARRAY_COUNT (commandPools); ++i) {
152+ VK (vkDestroyCommandPool (context->device , commandPools[i], 0 ));
153+ }
140154
141155 destroyPipeline (context, &pipeline);
142156
0 commit comments