/ Core / Clockworks / CwCwGraphics-CommandBuffers.cpp
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  }