source: opengl-game/vulkan-buffer.hpp@ b7fc3c2

feature/imgui-sdl
Last change on this file since b7fc3c2 was b7fc3c2, checked in by Dmitry Portnoy <dportnoy@…>, 4 years ago

Modify the VulkanBuffer class to take a range and to align data based on that rather than the size of an individual data item. Also, reorganize the code in VulkanGae::updateScene() in a more logical fashion, and remove VulkanGame::updateObject() and inline its functionality.

  • Property mode set to 100644
File size: 4.8 KB
RevLine 
[a3cefaa]1#ifndef _VULKAN_BUFFER_H
2#define _VULKAN_BUFFER_H
3
4/*
5* This class is intended to be used with Storage Buffers and Uniform Buffers.
6*/
7
8template<class T>
9class VulkanBuffer {
10
11 public:
12
[8dcbf62]13 // TODO: Make these private (maybe make a getter for numObjects)
14 // Externally, they are only used in resizeBufferSet
[a3cefaa]15 size_t capacity;
[6bac215]16
17 // temp field to help with ubo+ssbo resizing until they are added to this class
18 // See if I need a separate field for this or if I can use other fields to check for this
19 // Maybe compare uniform or storage buffer size to the size of the memory allocated here
20 bool resized;
[a3cefaa]21
22 VulkanBuffer();
[b7fc3c2]23 VulkanBuffer(size_t capacity, size_t range, size_t minOffsetAlignment);
[6bac215]24
25 VulkanBuffer(const VulkanBuffer<T>&) = delete;
26 VulkanBuffer(VulkanBuffer<T>&& other);
27
[a3cefaa]28 ~VulkanBuffer();
29
[6bac215]30 VulkanBuffer<T>& operator=(const VulkanBuffer<T>&) = delete;
31 VulkanBuffer<T>& operator=(VulkanBuffer<T>&& other) noexcept;
32
33 void resize();
[a3cefaa]34
[8dcbf62]35 void add(T obj);
[a3cefaa]36
[b7fc3c2]37 size_t memorySize();
[1abebc1]38
[a3cefaa]39 private:
40
[8dcbf62]41 size_t alignment;
[b7fc3c2]42 size_t range;
[6bac215]43 size_t numObjects;
[8dcbf62]44
[a3cefaa]45 T* srcData; // TODO: Rename this to something else probably and rename rawData to data
46 vector<T>* vData;
47
48 // Remember that this is a pointer to the mapped video memory
49 // Maybe rename it to mappedData or something to make that clearer
50 void* rawData;
[b7fc3c2]51
52 size_t memRequirement(size_t capacity);
[a3cefaa]53};
54
55// Currently, for SSBOs, I store the per-object values (usually just the model matrix), on each object, so they
56// are not in their own array and therefore cannot be pushed to the GPU as one block. The updates must happen
57// separately per object.
58
59// Since Sascha WIllems' dynamic UBO example works the same way (iirc), I can implement dynamic UBOs like that as well
60// for now. Would be nice to plan for potentially storing the ubo data on the CPU in a contiguous block in the future,
61// assuming that would make updates easier. Keep in mind that this only makes sense if all or most of the objects
62// in the ubo get updated every frame.
63
64// ============================= TODO: Also, check when it makes sense to have a staging buffer for copying data to the GPU
65// and see if I actually need to use it everywhere I currently am. I think this is mentioned in Sascha WIllems dubo example
66// or some other Vulkan website I recently bookmarked
67
68template<class T>
69VulkanBuffer<T>::VulkanBuffer()
70 : alignment(0)
[b7fc3c2]71 , range(0)
[a3cefaa]72 , capacity(0)
73 , numObjects(0)
[6bac215]74 , resized(false)
[a3cefaa]75 , srcData(nullptr)
76 , rawData(nullptr)
77 , vData(nullptr) {
78}
79
80template<class T>
[b7fc3c2]81VulkanBuffer<T>::VulkanBuffer(size_t capacity, size_t range, size_t minOffsetAlignment)
82 : alignment(range)
83 , range(range / sizeof(T))
[a3cefaa]84 , capacity(capacity)
85 , numObjects(0)
[6bac215]86 , resized(false)
[a3cefaa]87 , srcData(nullptr)
88 , rawData(nullptr)
89 , vData(nullptr) {
90 if (minOffsetAlignment > 0) {
91 alignment = (alignment + minOffsetAlignment - 1) & ~(minOffsetAlignment - 1);
92 }
93
[b7fc3c2]94 srcData = (T*)malloc(memRequirement(capacity));
[a3cefaa]95}
96
[6bac215]97template<class T>
98VulkanBuffer<T>::VulkanBuffer(VulkanBuffer<T>&& other) {
99 // TODO: Implement
100}
101
[a3cefaa]102template<class T>
103VulkanBuffer<T>::~VulkanBuffer() {
104 if (srcData != nullptr) {
105 free(srcData);
106 }
107}
108
109template<class T>
[6bac215]110VulkanBuffer<T>& VulkanBuffer<T>::operator=(VulkanBuffer<T>&& other) noexcept {
111 if (this != &other) {
112 capacity = other.capacity;
113 numObjects = other.numObjects;
114 resized = other.resized;
[a3cefaa]115
[6bac215]116 alignment = other.alignment;
[b7fc3c2]117 range = other.range;
[a3cefaa]118
[6bac215]119 if (srcData != nullptr) {
120 free(srcData);
121 }
[a3cefaa]122
[6bac215]123 srcData = other.srcData;
[a3cefaa]124
[6bac215]125 other.capacity = 0;
126 other.numObjects = 0;
[b7fc3c2]127 other.range = 0;
[a3cefaa]128
[6bac215]129 other.srcData = nullptr;
130 }
[a3cefaa]131
132 return *this;
133}
134
[6bac215]135template<class T>
136void VulkanBuffer<T>::resize() {
137 resized = false;
138}
139
[a3cefaa]140template<class T>
[8dcbf62]141void VulkanBuffer<T>::add(T obj) {
[6bac215]142 if (numObjects == capacity) {
143 // Once I add Vulkan buffer objects in here, make sure this doesn't overlap with resizeBufferSet
144 resized = true;
145
146 capacity *= 2;
147 }
148
[8dcbf62]149 numObjects++;
[a3cefaa]150}
151
[b7fc3c2]152template<class T>
153size_t VulkanBuffer<T>::memorySize() {
154 return memRequirement(capacity);
155}
156
157template<class T>
158size_t VulkanBuffer<T>::memRequirement(size_t capacity) {
159 return (capacity / range) * alignment + (capacity % range) * sizeof(T);
160}
161
[a3cefaa]162#endif // _VULKAN_BUFFER_H
Note: See TracBrowser for help on using the repository browser.