CwCwGraphics-CommandBuffers.cpp
1 // this will be moved into its own class (CwRender) :D 2 #include <Clockworks/CwGraphics.hpp> 3 4 void CwGraphics::CreateFrameBuffers() { 5 ChainFrameBuffers.resize(ImageViews.size()); // try to aviod resizes when possible come back here latter 6 // 7 for (size_t i = 0; i < ImageViews.size(); ++i) { 8 VkImageView Attachments[] = {ImageViews[i]}; 9 10 VkFramebufferCreateInfo CInfo{}; 11 CInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO; 12 CInfo.renderPass = RenderPass; 13 CInfo.attachmentCount = 1; 14 CInfo.pAttachments = Attachments; 15 CInfo.width = ChainExtent.width; 16 CInfo.height = ChainExtent.height; 17 CInfo.layers = 1; 18 if (vkCreateFramebuffer(Dev, &CInfo, nullptr, &ChainFrameBuffers[i]) != VK_SUCCESS) { 19 throw std::runtime_error("CW-ERROR: Failed FrameBuffer Creation"); 20 } 21 } 22 } 23 void CwGraphics::CreateCommandBuffer() { 24 // Create CommandPool 25 VkCommandPoolCreateInfo PoolCreateInfo; 26 PoolCreateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; 27 PoolCreateInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; 28 PoolCreateInfo.queueFamilyIndex = FamIndices.GraphicsFam.value(); 29 30 if (vkCreateCommandPool(Dev, &PoolCreateInfo, nullptr, &CommandPool) != VK_SUCCESS) 31 throw std::runtime_error("Cw-ERROR: Failed to create CommandPool :( "); 32 33 // Create CommandBuffer 34 VkCommandBufferAllocateInfo AllocationInfo{}; 35 AllocationInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; 36 AllocationInfo.commandPool = CommandPool; 37 AllocationInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; 38 AllocationInfo.commandBufferCount = (uint32_t)MAX_FRAMES_IN_FLIGHT; 39 40 if (vkAllocateCommandBuffers(Dev, &AllocationInfo, CommandBuffers) != VK_SUCCESS) 41 throw std::runtime_error("CW-ERROR: Failed CommandBuffer Createion/Allocation"); 42 } 43 void CwGraphics::RecordCommandBuffer(VkCommandBuffer CommandBuffer, uint32_t ImageIndex) { 44 VkCommandBufferBeginInfo BeginInfo{}; 45 BeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; 46 47 if (vkBeginCommandBuffer(CommandBuffer, &BeginInfo) != VK_SUCCESS) throw std::runtime_error("CW-ERROR: Failed to Start command buffer :( \n"); 48 49 VkClearValue ClearColor = {0.0f, 0.0f, 0.0f, 1.0f}; 50 51 VkRenderPassBeginInfo RenderPassInfo{}; 52 RenderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; 53 RenderPassInfo.renderPass = RenderPass; 54 RenderPassInfo.framebuffer = ChainFrameBuffers[ImageIndex]; 55 RenderPassInfo.renderArea.offset = {0, 0}; 56 RenderPassInfo.renderArea.extent = ChainExtent; 57 RenderPassInfo.clearValueCount = 1; 58 RenderPassInfo.pClearValues = &ClearColor; 59 60 VkViewport Viewport{}; 61 Viewport.x = 0.0f; 62 Viewport.y = 0.0f; 63 Viewport.width = (float)ChainExtent.width; 64 Viewport.height = (float)ChainExtent.height; 65 Viewport.minDepth = 0.0f; 66 Viewport.maxDepth = 1.0f; 67 68 VkRect2D Scissor{}; 69 Scissor.offset = {0, 0}; 70 Scissor.extent = ChainExtent; 71 72 vkCmdSetViewport(CommandBuffer, 0, 1, &Viewport); 73 vkCmdSetScissor(CommandBuffer, 0, 1, &Scissor); 74 vkCmdBeginRenderPass(CommandBuffer, &RenderPassInfo, VK_SUBPASS_CONTENTS_INLINE); 75 vkCmdBindPipeline(CommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, GraphicsPipeline); 76 77 VkBuffer VBuffers[] = {VertexBuffer}; 78 VkDeviceSize Offsets[] = {0}; 79 vkCmdBindVertexBuffers(CommandBuffer, 0, 1, VBuffers, Offsets); 80 vkCmdDraw(CommandBuffer, static_cast<uint32_t>(Vertices.size()), 1, 0, 0); 81 82 vkCmdEndRenderPass(CommandBuffer); 83 84 if (vkEndCommandBuffer(CommandBuffer) != VK_SUCCESS) throw std::runtime_error("CW-ERROR: Failed to end command buffer :("); 85 } 86 void CwGraphics::CreateSynchronizationObjects() { 87 Semaphores.RenderFinished.resize(ChainImages.size()); 88 89 VkSemaphoreCreateInfo GenaricSemaphoreCreateInfo{}; 90 GenaricSemaphoreCreateInfo.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; 91 VkFenceCreateInfo FenceCreateInfo{}; 92 FenceCreateInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; 93 FenceCreateInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT; 94 95 for (int i = 0; i < ChainImages.size(); i++) 96 if (vkCreateSemaphore(Dev, &GenaricSemaphoreCreateInfo, nullptr, &Semaphores.RenderFinished[i]) != VK_SUCCESS) 97 throw std::runtime_error("CW-ERROR: Failed to create Semaphores/Fences :("); 98 99 for (int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) 100 if (vkCreateSemaphore(Dev, &GenaricSemaphoreCreateInfo, nullptr, &ImageAvailable[i]) != VK_SUCCESS) 101 throw std::runtime_error("CW-ERROR: Failed to create Semaphores/Fences :("); 102 for (int i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) 103 if (vkCreateFence(Dev, &FenceCreateInfo, nullptr, &FlightFence[i]) != VK_SUCCESS) 104 throw std::runtime_error("CW-ERROR: Failed to create Semaphores/Fences :("); 105 } 106 void CwGraphics::DrawFrame() { 107 vkWaitForFences(Dev, 1, &FlightFence[CurrentFrame], VK_TRUE, UINT64_MAX); 108 109 uint32_t ImageIndex{}; 110 111 VkResult SwapChainStatus = vkAcquireNextImageKHR(Dev, SwapChain, UINT64_MAX, ImageAvailable[CurrentFrame], VK_NULL_HANDLE, &ImageIndex); 112 113 if (SwapChainStatus == VK_ERROR_OUT_OF_DATE_KHR || SwapChainStatus == VK_SUBOPTIMAL_KHR || Window.FrameBufferResized) { 114 Window.FrameBufferResized = false; 115 std::cout << "CW-INFO: Resizing Window\n"; 116 RecreateChain(); 117 return; 118 } else if (SwapChainStatus != VK_SUCCESS) { 119 std::runtime_error("CW-ERROR: Failed to Fetch ChainImage :(\n"); 120 } 121 122 vkResetFences(Dev, 1, &FlightFence[CurrentFrame]); 123 124 vkResetCommandBuffer(CommandBuffers[CurrentFrame], /*VkCommandBufferResetFlagBits*/ 0); 125 RecordCommandBuffer(CommandBuffers[CurrentFrame], ImageIndex); 126 127 VkPipelineStageFlags WaitStages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT}; 128 VkSwapchainKHR SwapChains[] = {SwapChain}; 129 130 VkSubmitInfo SubmitInfo{}; 131 132 SubmitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; 133 134 SubmitInfo.waitSemaphoreCount = 1; 135 SubmitInfo.pWaitSemaphores = &ImageAvailable[CurrentFrame]; 136 SubmitInfo.pWaitDstStageMask = WaitStages; 137 SubmitInfo.commandBufferCount = 1; 138 SubmitInfo.pCommandBuffers = &CommandBuffers[CurrentFrame]; 139 140 SubmitInfo.signalSemaphoreCount = 1; 141 SubmitInfo.pSignalSemaphores = &Semaphores.RenderFinished[ImageIndex]; 142 143 if (vkQueueSubmit(GraphicsQueue, 1, &SubmitInfo, FlightFence[CurrentFrame]) != VK_SUCCESS) { 144 throw std::runtime_error("failed to submit draw command buffer!"); 145 } 146 147 VkPresentInfoKHR PresentInfo{}; 148 PresentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; 149 150 PresentInfo.waitSemaphoreCount = 1; 151 PresentInfo.pWaitSemaphores = &Semaphores.RenderFinished[ImageIndex]; 152 153 PresentInfo.swapchainCount = 1; 154 PresentInfo.pSwapchains = SwapChains; 155 PresentInfo.pImageIndices = &ImageIndex; 156 157 vkQueuePresentKHR(PresentQueue, &PresentInfo); 158 }