From a2941de5de10807ae27a6f77a1770bbfe955a18f Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Mon, 5 Nov 2018 21:34:50 -0500 Subject: [PATCH] Add configurable number of frame resources to create --- include/renderer.h | 4 +++- src/dofpass.cpp | 8 ++++---- src/imguipass.cpp | 16 ++++++++-------- src/postpass.cpp | 2 +- src/renderer.cpp | 18 ++++++++++-------- src/worldpass.cpp | 2 +- 6 files changed, 27 insertions(+), 23 deletions(-) diff --git a/include/renderer.h b/include/renderer.h index 493afb2..d6dd0ba 100644 --- a/include/renderer.h +++ b/include/renderer.h @@ -7,12 +7,14 @@ #include "dofpass.h" #include "imguipass.h" +constexpr int numFrameResources = 2; + struct RenderTarget { VkSurfaceKHR surface = nullptr; VkSwapchainKHR swapchain = nullptr; VkExtent2D extent = {}; - uint32_t numImages = 0, currentImage = 0; + uint32_t numImages = 0, imageIndex = 0, currentResource = 0; // swapwchain VkImage* swapchainImages = nullptr; diff --git a/src/dofpass.cpp b/src/dofpass.cpp index c7dd1ef..7368b1b 100644 --- a/src/dofpass.cpp +++ b/src/dofpass.cpp @@ -46,7 +46,7 @@ void DoFPass::render(VkCommandBuffer commandBuffer, Camera& camera, RenderTarget VkRenderPassBeginInfo renderPassBeginInfo = {}; renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; - renderPassBeginInfo.framebuffer = target->farFieldFramebuffers[target->currentImage]; + renderPassBeginInfo.framebuffer = target->farFieldFramebuffers[target->currentResource]; renderPassBeginInfo.renderPass = renderPass_; renderPassBeginInfo.renderArea.extent.width = target->extent.width / dofFramebufferDownscaleFactor; renderPassBeginInfo.renderArea.extent.height = target->extent.height / dofFramebufferDownscaleFactor; @@ -63,7 +63,7 @@ void DoFPass::render(VkCommandBuffer commandBuffer, Camera& camera, RenderTarget dpack[3] = target->extent.height / dofFramebufferDownscaleFactor; vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_); - vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout_, 0, 1, &target->dofSets[target->currentImage], 0, nullptr); + vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout_, 0, 1, &target->dofSets[target->currentResource], 0, nullptr); vkCmdPushConstants(commandBuffer, pipelineLayout_, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(glm::vec4), &dpack); @@ -73,12 +73,12 @@ void DoFPass::render(VkCommandBuffer commandBuffer, Camera& camera, RenderTarget vkCmdEndRenderPass(commandBuffer); //near field - renderPassBeginInfo.framebuffer = target->nearFieldFramebuffers[target->currentImage]; + renderPassBeginInfo.framebuffer = target->nearFieldFramebuffers[target->currentResource]; vkCmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_); - vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout_, 0, 1, &target->dofSets[target->currentImage], 0, nullptr); + vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout_, 0, 1, &target->dofSets[target->currentResource], 0, nullptr); vkCmdPushConstants(commandBuffer, pipelineLayout_, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(glm::vec4), &dpack); diff --git a/src/imguipass.cpp b/src/imguipass.cpp index 6ac176b..09358fc 100644 --- a/src/imguipass.cpp +++ b/src/imguipass.cpp @@ -27,22 +27,22 @@ ImGuiPass::~ImGuiPass() { void ImGuiPass::render(VkCommandBuffer commandBuffer, RenderTarget* target) { ImDrawData* drawData = ImGui::GetDrawData(); - VkBuffer& vertexBuffer = target->imguiVertexBuffers[target->currentImage]; - VkDeviceMemory& vertexMemory = target->imguiVertexMemorys[target->currentImage]; + VkBuffer& vertexBuffer = target->imguiVertexBuffers[target->currentResource]; + VkDeviceMemory& vertexMemory = target->imguiVertexMemorys[target->currentResource]; - VkBuffer& indexBuffer = target->imguiIndexBuffers[target->currentImage]; - VkDeviceMemory& indexMemory = target->imguiIndexMemorys[target->currentImage]; + VkBuffer& indexBuffer = target->imguiIndexBuffers[target->currentResource]; + VkDeviceMemory& indexMemory = target->imguiIndexMemorys[target->currentResource]; const size_t vertexSize = drawData->TotalVtxCount * sizeof(ImDrawVert); - if(vertexSize > target->imguiVertexBufferSizes[target->currentImage]) { + if(vertexSize > target->imguiVertexBufferSizes[target->currentResource]) { createBuffer(vertexBuffer, vertexMemory, vertexSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT); - target->imguiVertexBufferSizes[target->currentImage] = vertexSize; + target->imguiVertexBufferSizes[target->currentResource] = vertexSize; } const size_t indexSize = drawData->TotalIdxCount * sizeof(ImDrawIdx); - if(indexSize > target->imguiIndexBufferSizes[target->currentImage]) { + if(indexSize > target->imguiIndexBufferSizes[target->currentResource]) { createBuffer(indexBuffer, indexMemory, indexSize, VK_BUFFER_USAGE_INDEX_BUFFER_BIT); - target->imguiIndexBufferSizes[target->currentImage] = indexSize; + target->imguiIndexBufferSizes[target->currentResource] = indexSize; } if(vertexSize == 0 || indexSize == 0) diff --git a/src/postpass.cpp b/src/postpass.cpp index bca810f..7283f70 100644 --- a/src/postpass.cpp +++ b/src/postpass.cpp @@ -21,7 +21,7 @@ PostPass::~PostPass() { void PostPass::render(VkCommandBuffer commandBuffer, RenderTarget* target) { vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_); - vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout_, 0, 1, &target->postSets[target->currentImage], 0, nullptr); + vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout_, 0, 1, &target->postSets[target->currentResource], 0, nullptr); vkCmdDraw(commandBuffer, 3, 1, 0, 0); } diff --git a/src/renderer.cpp b/src/renderer.cpp index 1ffa27d..f4803a7 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -53,12 +53,14 @@ Renderer::~Renderer() { } void Renderer::render(World& world, Camera& camera, RenderTarget* target) { - vkAcquireNextImageKHR(device_, target->swapchain, UINT64_MAX, target->imageAvailableSemaphore, nullptr, &target->currentImage); + vkAcquireNextImageKHR(device_, target->swapchain, UINT64_MAX, target->imageAvailableSemaphore, nullptr, &target->imageIndex); - vkWaitForFences(device_, 1, &target->fences[target->currentImage], VK_TRUE, UINT64_MAX); - vkResetFences(device_, 1, &target->fences[target->currentImage]); + target->currentResource = (target->imageIndex + 1) % numFrameResources; + + vkWaitForFences(device_, 1, &target->fences[target->currentResource], VK_TRUE, UINT64_MAX); + vkResetFences(device_, 1, &target->fences[target->currentResource]); - VkCommandBuffer commandBuffer = target->commandBuffers[target->currentImage]; + VkCommandBuffer commandBuffer = target->commandBuffers[target->currentResource]; VkCommandBufferBeginInfo beginInfo = {}; beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; @@ -88,7 +90,7 @@ void Renderer::render(World& world, Camera& camera, RenderTarget* target) { VkRenderPassBeginInfo renderPassBeginInfo = {}; renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; - renderPassBeginInfo.framebuffer = target->swapchainFramebuffers[target->currentImage]; + renderPassBeginInfo.framebuffer = target->swapchainFramebuffers[target->currentResource]; renderPassBeginInfo.renderPass = presentationRenderPass_; renderPassBeginInfo.renderArea.extent = target->extent; renderPassBeginInfo.clearValueCount = 1; @@ -115,7 +117,7 @@ void Renderer::render(World& world, Camera& camera, RenderTarget* target) { submitInfo.signalSemaphoreCount = 1; submitInfo.pSignalSemaphores = &target->renderFinishedSemaphore; - vkQueueSubmit(graphicsQueue_, 1, &submitInfo, target->fences[target->currentImage]); + vkQueueSubmit(graphicsQueue_, 1, &submitInfo, target->fences[target->currentResource]); VkPresentInfoKHR presentInfo = {}; presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; @@ -123,7 +125,7 @@ void Renderer::render(World& world, Camera& camera, RenderTarget* target) { presentInfo.pWaitSemaphores = &target->renderFinishedSemaphore; presentInfo.swapchainCount = 1; presentInfo.pSwapchains = &target->swapchain; - presentInfo.pImageIndices = &target->currentImage; + presentInfo.pImageIndices = &target->imageIndex; vkQueuePresentKHR(graphicsQueue_, &presentInfo); } @@ -187,7 +189,7 @@ RenderTarget* Renderer::createSurfaceRenderTarget(VkSurfaceKHR surface, RenderTa target->swapchainImages = new VkImage[swapchainImageCount]; vkGetSwapchainImagesKHR(device_, target->swapchain, &swapchainImageCount, target->swapchainImages); - + // create frame resources target->swapchainImageViews = new VkImageView[swapchainImageCount]; target->swapchainFramebuffers = new VkFramebuffer[swapchainImageCount]; diff --git a/src/worldpass.cpp b/src/worldpass.cpp index 2d7a8ca..5d68935 100644 --- a/src/worldpass.cpp +++ b/src/worldpass.cpp @@ -52,7 +52,7 @@ void WorldPass::render(VkCommandBuffer commandBuffer, World& world, Camera& came VkRenderPassBeginInfo renderPassBeginInfo = {}; renderPassBeginInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; - renderPassBeginInfo.framebuffer = target->offscreenFramebuffers[target->currentImage]; + renderPassBeginInfo.framebuffer = target->offscreenFramebuffers[target->currentResource]; renderPassBeginInfo.renderPass = renderPass_; renderPassBeginInfo.renderArea.extent = target->extent; renderPassBeginInfo.clearValueCount = clearColor.size();