Engine
Frameworkcreatedbymeusableforthecreationofsimplegames.CurrentlysupportsOpenGL(Verysimple)andVulkan.
VulkanBuffer.cpp
Go to the documentation of this file.
2 #ifdef USING_VULKAN
3 
4 namespace Engine {
5 
6  VulkanBuffer::VulkanBuffer(VulkanLogicalDevice * device, VmaAllocator allocator, uint32_t size, VkBufferUsageFlags usage, bool gpu, VkCommandPool pool)
7  {
8  this->device = device;
9  this->allocator = allocator;
10  this->size = size;
11  this->usage = usage;
12  this->gpu = gpu;
13  this->pool = pool;
14 
15  VkBufferCreateInfo createInfo = {};
16  createInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
17  createInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
18  createInfo.size = size;
19  createInfo.usage = usage;
20  createInfo.usage |= VK_BUFFER_USAGE_TRANSFER_DST_BIT;
21 
22  VmaAllocationCreateInfo allocInfo = {};
23  if (gpu)
24  allocInfo.usage = VMA_MEMORY_USAGE_GPU_ONLY;
25  else
26  allocInfo.usage = VMA_MEMORY_USAGE_CPU_ONLY;
27 
28  vmaCreateBuffer(allocator, &createInfo, &allocInfo, &buffer, &allocation, &allocationInfo);
29 
30  }
31 
32  VulkanBuffer::VulkanBuffer(VulkanLogicalDevice * device, VmaAllocator allocator, uint32_t size, VkBufferUsageFlags usage, VmaMemoryUsage memoryType, VkCommandPool pool)
33  {
34  this->device = device;
35  this->allocator = allocator;
36  this->size = size;
37  this->usage = usage;
38  this->gpu = gpu;
39  this->pool = pool;
40 
41  VkBufferCreateInfo createInfo = {};
42  createInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
43  createInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
44  createInfo.size = size;
45  createInfo.usage = usage;
46  createInfo.usage |= VK_BUFFER_USAGE_TRANSFER_DST_BIT;
47 
48  VmaAllocationCreateInfo allocInfo = {};
49  allocInfo.usage = memoryType;
50 
51  if (memoryType == VMA_MEMORY_USAGE_GPU_ONLY)
52  gpu = true;
53  else
54  gpu = false;
55 
56  vmaCreateBuffer(allocator, &createInfo, &allocInfo, &buffer, &allocation, &allocationInfo);
57  }
58 
59  VulkanBuffer::~VulkanBuffer()
60  {
61  vkQueueWaitIdle(device->GetGraphicsQueue());
62  vmaDestroyBuffer(allocator, buffer, allocation);
63  }
64 
65  void VulkanBuffer::CreateBufferView(uint32_t range, uint32_t offset, VkFormat format)
66  {
67  VkBufferViewCreateInfo viewInfo = {};
68  viewInfo.sType = VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO;
69  viewInfo.buffer = buffer;
70  viewInfo.range = range;
71  viewInfo.offset = offset;
72  viewInfo.format = format;
73  viewInfo.flags = 0;
74 
75  vkCreateBufferView(device->GetDevice(), &viewInfo, nullptr, &view);
76 
77  }
78 
79  VkBuffer VulkanBuffer::GetBuffer() const
80  {
81  return buffer;
82  }
83 
84  VkBufferView VulkanBuffer::GetBufferView() const
85  {
86  return view;
87  }
88 
89  VmaAllocationInfo VulkanBuffer::getAllocationInfo()
90  {
91  return allocationInfo;
92  }
93 
94  void VulkanBuffer::UpdateBuffer(void * data, uint32_t offset, uint32_t size)
95  {
96  if (gpu) {
97  VkBufferCreateInfo createInfo = {};
98  createInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
99  createInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
100  createInfo.size = size;
101  createInfo.usage = (usage | VK_BUFFER_USAGE_TRANSFER_SRC_BIT) & (~VK_BUFFER_USAGE_TRANSFER_DST_BIT);
102 
103  VmaAllocationCreateInfo allocInfo = {};
104  allocInfo.usage = VMA_MEMORY_USAGE_CPU_ONLY;
105 
106  VkBuffer stagingBuffer;
107  VmaAllocation stagingAllocation;
108 
109  vmaCreateBuffer(allocator, &createInfo, &allocInfo, &stagingBuffer, &stagingAllocation, nullptr);
110 
111  void* dst;
112  vmaMapMemory(allocator, stagingAllocation, &dst);
113  memcpy((static_cast<char*>(dst) + offset), data, size);
114  vmaUnmapMemory(allocator, stagingAllocation);
115 
116  VkCommandBufferAllocateInfo cmdAllocInfo = {};
117  cmdAllocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
118  cmdAllocInfo.commandBufferCount = 1;
119  cmdAllocInfo.commandPool = pool;
120  cmdAllocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
121 
122  VkCommandBuffer cmdBuffer;
123 
124  vkAllocateCommandBuffers(device->GetDevice(), &cmdAllocInfo, &cmdBuffer);
125 
126  VkCommandBufferBeginInfo cmdBeginInfo = {};
127  cmdBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
128  cmdBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
129 
130  vkBeginCommandBuffer(cmdBuffer, &cmdBeginInfo);
131 
132  VkBufferCopy copyRegion = {};
133  copyRegion.srcOffset = offset;
134  copyRegion.dstOffset = offset;
135  copyRegion.size = size;
136  vkCmdCopyBuffer(cmdBuffer, stagingBuffer, buffer, 1, &copyRegion);
137 
138  vkEndCommandBuffer(cmdBuffer);
139 
140  VkSubmitInfo submitInfo = {};
141  submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
142  submitInfo.commandBufferCount = 1;
143  submitInfo.pCommandBuffers = &cmdBuffer;
144 
145  vkQueueSubmit(device->GetGraphicsQueue(), 1, &submitInfo, VK_NULL_HANDLE);
146  vkQueueWaitIdle(device->GetGraphicsQueue());
147 
148  vkFreeCommandBuffers(device->GetDevice(), pool, 1, &cmdBuffer);
149 
150  vmaDestroyBuffer(allocator, stagingBuffer, stagingAllocation);
151 
152  }
153  else {
154  void* dst;
155  vmaMapMemory(allocator, allocation, &dst);
156  memcpy((static_cast<char*>(dst) + offset), data, size);
157  vmaUnmapMemory(allocator, allocation);
158  }
159  }
160 
161  void VulkanBuffer::MapBuffer(void * location)
162  {
163  vmaMapMemory(allocator, allocation, &location);
164  }
165 
166  void VulkanBuffer::UnmapBuffer()
167  {
168  vmaUnmapMemory(allocator, allocation);
169  }
170 
171  void VulkanBuffer::ClearBuffer() const
172  {
173  vkQueueWaitIdle(device->GetGraphicsQueue());
174 
175  VkCommandBufferAllocateInfo cmdAllocInfo = {};
176  cmdAllocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
177  cmdAllocInfo.commandBufferCount = 1;
178  cmdAllocInfo.commandPool = pool;
179  cmdAllocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
180 
181  VkCommandBuffer cmdBuffer;
182 
183  vkAllocateCommandBuffers(device->GetDevice(), &cmdAllocInfo, &cmdBuffer);
184 
185  VkCommandBufferBeginInfo cmdBeginInfo = {};
186  cmdBeginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
187  cmdBeginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
188 
189  vkBeginCommandBuffer(cmdBuffer, &cmdBeginInfo);
190 
191  vkCmdFillBuffer(cmdBuffer, buffer, 0, VK_WHOLE_SIZE, 0);
192 
193  vkEndCommandBuffer(cmdBuffer);
194 
195  VkSubmitInfo submitInfo = {};
196  submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO;
197  submitInfo.commandBufferCount = 1;
198  submitInfo.pCommandBuffers = &cmdBuffer;
199 
200  vkQueueSubmit(device->GetGraphicsQueue(), 1, &submitInfo, VK_NULL_HANDLE);
201  vkQueueWaitIdle(device->GetGraphicsQueue());
202 
203  vkFreeCommandBuffers(device->GetDevice(), pool, 1, &cmdBuffer);
204  }
205 }
206 
207 #endif // USING_VULKAN