SimpleGL  1.1.0
A framework for platform independent rendering
command_buffer.cpp
Go to the documentation of this file.
1 
9 
10 #include <stdexcept>
11 #include <vector>
12 
16 
17 using namespace std;
18 
19 namespace sgl {
20 
21  CommandPool::CommandPool(void) {
22  VkDevice device = VulkanContext::getCurrent()->getDevice()->getHandle();
23  QueueFamilyIndices queueFamilyIndices = VulkanContext::getCurrent()->getPhysicalDevice()->getQueueFamilyIndices();
24 
25  /* Initialize a command pool create info */
26  VkCommandPoolCreateInfo createInfo = {};
27  createInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
28  createInfo.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT;
29  createInfo.queueFamilyIndex = static_cast<uint32_t> (queueFamilyIndices.graphics);
30 
31  /* Create the command pool */
32  if (vkCreateCommandPool(device, &createInfo, nullptr, &handle) != VK_SUCCESS) {
33  throw runtime_error("Could not create a command pool!");
34  }
35  }
36 
37  CommandPool::~CommandPool(void) {
38  VkDevice device = VulkanContext::getCurrent()->getDevice()->getHandle();
39 
40  /* Destroy the command pool */
41  vkDestroyCommandPool(device, handle, nullptr);
42  }
43 
44  VkCommandPool CommandPool::getHandle() {
45  return handle;
46  }
47 
48  CommandBuffer::CommandBuffer(void) {
49  VkDevice device = VulkanContext::getCurrent()->getDevice()->getHandle();
50  VkCommandPool commandPool = VulkanContext::getCurrent()->getCommandPool()->getHandle();
51 
52  /* Initialize a command buffer allocate info */
53  VkCommandBufferAllocateInfo allocateInfo = {};
54  allocateInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
55  allocateInfo.commandPool = commandPool;
56  allocateInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
57  allocateInfo.commandBufferCount = 1;
58 
59  /* Allocate the command buffer */
60  if (vkAllocateCommandBuffers(device, &allocateInfo, &handle) != VK_SUCCESS) {
61  throw runtime_error("Could not allocate the command buffers!");
62  }
63  }
64 
65  CommandBuffer::~CommandBuffer(void) {
66  VkDevice device = VulkanContext::getCurrent()->getDevice()->getHandle();
67  VkCommandPool commandPool = VulkanContext::getCurrent()->getCommandPool()->getHandle();
68 
69  /* Free command buffer */
70  vkFreeCommandBuffers(device, commandPool, 1, &handle);
71  }
72 
73  VkCommandBuffer CommandBuffer::getHandle() {
74  return handle;
75  }
76 
77  void CommandBuffer::begin() {
78  VkDevice device = VulkanContext::getCurrent()->getDevice()->getHandle();
79  VkFence fence = VulkanContext::getCurrent()->getRenderFence()->getHandle();
80 
81  /* Wait for the submit fence */
82  vkWaitForFences(device, 1, &fence, VK_TRUE, std::numeric_limits<uint64_t>::max());
83  vkResetFences(device, 1, &fence);
84 
85  /* Initialize a command buffer begin info */
86  VkCommandBufferBeginInfo beginInfo = {};
87  beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
88  beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
89 
90  /* Begin recording */
91  if (vkBeginCommandBuffer(handle, &beginInfo) != VK_SUCCESS) {
92  throw runtime_error("Could not begin recording the command buffers!");
93  }
94  }
95 
96  void CommandBuffer::end() {
97  if (vkEndCommandBuffer(handle) != VK_SUCCESS) {
98  throw runtime_error("Could not record the command buffer!");
99  }
100  }
101 
102  void CommandBuffer::beginRenderPass(RenderPass* renderPass) {
103  VkFramebuffer framebuffer = VulkanContext::getCurrent()->getSwapchainFramebuffer()->getHandle();
104  SwapchainData swapchainData = VulkanContext::getCurrent()->getSwapchain()->getSwapchainData();
105 
106  /* Initialize the clear values */
107  vector<VkClearValue> clearValues(2);
108  clearValues[0].color = {0.0f, 0.0f, 0.0f, 1.0f};
109  clearValues[1].depthStencil = {1.0f, 0};
110 
111  /* Initialize a render pass begin info */
112  VkRenderPassBeginInfo renderPassBegin = {};
113  renderPassBegin.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
114  renderPassBegin.renderPass = renderPass->getHandle();
115  renderPassBegin.framebuffer = framebuffer;
116  renderPassBegin.renderArea.offset.x = 0;
117  renderPassBegin.renderArea.offset.y = 0;
118  renderPassBegin.renderArea.extent = swapchainData.extent;
119  renderPassBegin.clearValueCount = clearValues.size();
120  renderPassBegin.pClearValues = clearValues.data();
121 
122  /* Begin render pass */
123  vkCmdBeginRenderPass(handle, &renderPassBegin, VK_SUBPASS_CONTENTS_INLINE);
124  }
125 
126  void CommandBuffer::endRenderPass() {
127  vkCmdEndRenderPass(handle);
128  }
129 
130  void CommandBuffer::bindPipeline(GraphicsPipeline* pipeline) {
131  vkCmdBindPipeline(handle, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline->getHandle());
132  }
133 
134  void CommandBuffer::bindVertexBuffer(VertexBuffer* vertexBuffer, uint32_t binding) {
135  VkDeviceSize offset = 0;
136  VkBuffer vertexBufferHandle = vertexBuffer->getHandle();
137  vkCmdBindVertexBuffers(handle, binding, 1, &vertexBufferHandle, &offset);
138  }
139 
140  void CommandBuffer::bindDescriptorSet(DescriptorSet* descriptorSet, GraphicsPipeline* graphicsPipeline, uint32_t binding) {
141  VkPipelineLayout layout = graphicsPipeline->getPipelineLayout();
142  VkDescriptorSet descriptorSetHandle = descriptorSet->getHandle();
143  vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 0, 1, &descriptorSetHandle, 0, nullptr);
144  }
145 
146  void CommandBuffer::draw(uint32_t vertexCount) {
147  vkCmdDraw(handle, vertexCount, 1, 0, 0);
148  }
149 
150  void CommandBuffer::submit() {
151  VkQueue queue = VulkanContext::getCurrent()->getDevice()->getQueues().graphics;
152  VkFence fence = VulkanContext::getCurrent()->getRenderFence()->getHandle();
153 
154  /* Initialize a submit info */
155  VkSubmitInfo submitInfo = {};
156  submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
157  submitInfo.commandBufferCount = 1;
158  submitInfo.pCommandBuffers = &handle;
159 
160  /* Submit the command buffer */
161  if (vkQueueSubmit(queue, 1, &submitInfo, fence) != VK_SUCCESS) {
162  throw runtime_error("Could not submit the draw command buffer!");
163  }
164  }
165 }
VkRenderPass getHandle()
Returns the handle of the render pass.
This struct stores relevant queue family indices.
VkBuffer getHandle()
Returns the handle of the vertex buffer.
VkPipeline getHandle()
Returns the handle of the graphics pipeline.
Generic namespace for the SimpleGL framework.
Definition: application.hpp:18
VkExtent2D extent
The swapchain extent.
Definition: swapchain.hpp:40
This class wraps a Vulkan descriptor set.
This struct stores relevant swapchain data.
Definition: swapchain.hpp:28
This class wraps a Vulkan vertex buffer.
VkDescriptorSet getHandle()
Returns the handle of the descriptor set.
This class wraps a Vulkan graphics pipeline.
This class wraps a Vulkan render pass.
Definition: render_pass.hpp:22
VkPipelineLayout getPipelineLayout()
Returns the pipeline layout of the graphics pipeline.
int32_t graphics
The index of the graphics queue family.