vOOlkan
An object oriented approach to Vulkan
Buffer.h
Go to the documentation of this file.
1#ifndef VULKAN_BUFFER
2#define VULKAN_BUFFER
3
4#include <vulkan/vulkan.h>
5#include <glm/glm.hpp>
6
7#include "LogicalDevice.h"
8#include "PhysicalDevice.h"
9#include "VulkanException.h"
10
11
12namespace Vulkan::Buffers { class Buffer; }
13
15public:
16
17 template<std::same_as<VkMemoryPropertyFlagBits>... P>
18 Buffer(const LogicalDevice& virtualGpu, const PhysicalDevice& realGpu, size_t size, int usage, P... requiredMemoryProperties) : virtualGpu{ virtualGpu }, size{ size } {
19 //create the buffer
21
22 //find out the constraints about the real GPU memory to use for this buffer
23 VkMemoryRequirements memRequirements;
24 vkGetBufferMemoryRequirements(+virtualGpu, buffer, &memRequirements);
25
26 //find which GPU memory to use
27 auto memIndex = findSuitableMemoryIndex(realGpu, memRequirements.memoryTypeBits, requiredMemoryProperties...);
28
29 //allocate the choosen memory
30 allocateMemory(memIndex, memRequirements.size);
31
32 //associate the allocated memory with the created buffer
33 vkBindBufferMemory(+virtualGpu, buffer, bufferMemory, 0);
34 }
35
36
37 Buffer(const Buffer&) = delete;
38 Buffer& operator=(const Buffer&) = delete;
39 Buffer(Buffer&&) = default; //TODO
40 Buffer& operator=(Buffer&&) = default; //TODO
41
42
44 vkDestroyBuffer(+virtualGpu, buffer, nullptr);
45 vkFreeMemory(+virtualGpu, bufferMemory, nullptr);
46 }
47
48
49 const VkBuffer& operator+() const {
50 return buffer;
51 }
52
53
54 VkDeviceMemory& getBufferMemory() {
55 return bufferMemory;
56 }
57
58
59 //Return the first index of a memory type on the GPU which is suitable for the resource we want to load onto the GPU.
60 template<std::same_as< VkMemoryPropertyFlagBits>... P>
61 static uint32_t findSuitableMemoryIndex(const PhysicalDevice& realGpu, uint32_t suitableTypesBitmask, P... requiredMemoryProperties) {
62 //get the properties of the memory of the GPU
63 VkPhysicalDeviceMemoryProperties memProperties;
64 vkGetPhysicalDeviceMemoryProperties(+realGpu, &memProperties);
65 auto requiredMemoryPropertiesMask = (requiredMemoryProperties | ...);
66
67 //for each memory type, check if it is suitable for what we want to do (i.e. this type is 1 in the suitableTypesBitmask and the properties of this type are a superset of requiredMemoryProperties)
68 for (uint32_t i = 0; i < memProperties.memoryTypeCount; i++) {
69 if ((suitableTypesBitmask & (1 << i)) && (memProperties.memoryTypes[i].propertyFlags & requiredMemoryPropertiesMask) == requiredMemoryPropertiesMask) {
70 return i;
71 }
72 }
73
74 throw VulkanException{ "No suitable memory for the buffer" };
75 }
76
77
78protected:
79
80 //Create the buffer
81 void createBuffer(const LogicalDevice& virtualGpu, size_t size, int usage) {
82 //info about the buffer we want to create
83 VkBufferCreateInfo bufferInfo{};
84 bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
85 bufferInfo.size = size;
86 bufferInfo.usage = usage;
87 bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
88
89 //actually create the buffer
90 if (VkResult result = vkCreateBuffer(+virtualGpu, &bufferInfo, nullptr, &buffer); result != VK_SUCCESS) {
91 throw VulkanException("Failed to create buffer!", result);
92 }
93 }
94
95
96 //Allocate the required space on the GPU
97 void allocateMemory(uint32_t memoryIndex, VkDeviceSize sizeToAllocate) {
98 VkMemoryAllocateInfo allocInfo{};
99 allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
100 allocInfo.allocationSize = sizeToAllocate;
101 allocInfo.memoryTypeIndex = memoryIndex;
102
103 if (VkResult result = vkAllocateMemory(+virtualGpu, &allocInfo, nullptr, &bufferMemory); result != VK_SUCCESS) {
104 throw VulkanException{ "Failed to allocate buffer memory!", result };
105 }
106 }
107
108
109 VkBuffer buffer;
110 VkDeviceMemory bufferMemory;
112 const size_t size;
113};
114
115
116#endif
Definition: Buffer.h:14
const VkBuffer & operator+() const
Definition: Buffer.h:49
Buffer(Buffer &&)=default
Buffer(const LogicalDevice &virtualGpu, const PhysicalDevice &realGpu, size_t size, int usage, P... requiredMemoryProperties)
Definition: Buffer.h:18
VkDeviceMemory & getBufferMemory()
Definition: Buffer.h:54
Buffer & operator=(const Buffer &)=delete
~Buffer()
Definition: Buffer.h:43
const size_t size
Definition: Buffer.h:112
const LogicalDevice & virtualGpu
Definition: Buffer.h:111
static uint32_t findSuitableMemoryIndex(const PhysicalDevice &realGpu, uint32_t suitableTypesBitmask, P... requiredMemoryProperties)
Definition: Buffer.h:61
Buffer & operator=(Buffer &&)=default
Buffer(const Buffer &)=delete
VkDeviceMemory bufferMemory
Definition: Buffer.h:110
void createBuffer(const LogicalDevice &virtualGpu, size_t size, int usage)
Definition: Buffer.h:81
VkBuffer buffer
Definition: Buffer.h:109
void allocateMemory(uint32_t memoryIndex, VkDeviceSize sizeToAllocate)
Definition: Buffer.h:97
A logical device is an abstraction of the physical GPU which we can mainly use to send commands.
Definition: LogicalDevice.h:15
Represents the GPU (or any other device) that will be used with Vulkan to perform computer graphics.
Definition: PhysicalDevice.h:17
Generic runtime exception thrown by Vulkan-related functions.
Definition: VulkanException.h:13
Definition: Buffer.h:12