HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RV_VKBuffer.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: RV_Instance.h ( RV Library, C++)
7  *
8  * COMMENTS:
9  * Class to manage Vulkan Buffer object and allocated memory
10  */
11 
12 #ifndef RV_VKBuffer_h
13 #define RV_VKBuffer_h
14 
15 #include "RV_API.h"
16 
17 #include <UT/UT_UniquePtr.h>
18 #include <UT/UT_Span.h>
19 
20 #include <VE/VE_VK.h>
21 #include "RV_Instance.h"
22 #include "RV_Type.h"
23 #include "RV_TypePtrs.h"
24 
25 class RV_Render;
27 
28 // TODO: make into class ?
30 
31 /// RAII wrapper class for VkBufferView
33 {
34 public:
35  VkBufferView getVkView() { return myVkView; }
36  VkFormat getVkFormat() const { return myVkFormat; }
37 
38  // CAN have null state
40  : myInst(nullptr)
41  , myVkView(VK_NULL_HANDLE)
42  , myVkFormat(VK_FORMAT_UNDEFINED)
43  {}
44  RV_VKBufferView(RV_Instance* inst, VkBufferView vk_view, VkFormat vk_format)
45  : myInst(inst), myVkView(vk_view), myVkFormat(vk_format)
46  {}
47 
48  // disable copy semantics
49  RV_VKBufferView(const RV_VKBufferView&) = delete;
51 
52  // enable move semantics
53  RV_VKBufferView(RV_VKBufferView&& other) noexcept
54  : myInst(other.myInst)
55  , myVkView(other.myVkView)
56  , myVkFormat(other.myVkFormat)
57  {
58  other.myInst = nullptr;
59  other.myVkView = VK_NULL_HANDLE;
60  other.myVkFormat = VK_FORMAT_UNDEFINED;
61  }
62  RV_VKBufferView& operator=(RV_VKBufferView&& other) noexcept = delete;
63 
64  // Destroy Resource Handle on destruction
65  void destroy(RV_Instance* inst);
66  ~RV_VKBufferView();
67 
68 private:
69  RV_Instance* myInst = nullptr;
70  VkBufferView myVkView = VK_NULL_HANDLE;
71  VkFormat myVkFormat = VK_FORMAT_UNDEFINED;
72 };
73 
74 /// @brief A vulkan buffer object
76 {
77 public:
78 
79  /// @brief Allocate a new Buffer object
80  /// Allocate a vulkan buffer
81  /// `is_staging` - if true, buffer will be CPU visible
82  ///
83  /// `vk_format` - if provided, a BufferView is only created --
84  /// only needed for texel buffer usage
85  static RV_VKBufferPtr allocate( RV_Instance* inst,
86  exint size,
88  bool is_staging,
89  VkFormat vk_format = VK_FORMAT_UNDEFINED,
90  const char* name = nullptr,
91  exint alignment = 0);
92 
93  /// @brief Allocate a new Buffer object
94  /// Allocate a vulkan buffer
95  /// `mem_type` - Memory type to use
96  ///
97  /// `vk_format` - if provided, a BufferView is only created --
98  /// only needed for texel buffer usage
99  static RV_VKBufferPtr allocate( RV_Instance* inst,
100  exint size,
101  VkBufferUsageFlags usage,
102  RV_MemType mem_type,
103  VkFormat vk_format = VK_FORMAT_UNDEFINED,
104  const char* name = nullptr,
105  exint alignment = 0);
106 
107  /// check whether the format and usage can be used together
108  static bool queryIsUsable( RV_Instance* inst,
109  VkBufferUsageFlags vk_usage,
110  VkFormat vk_format);
111 
112  /// Get the raw vulkan buffer handle
113  VkBuffer getVkBuf() { return myVkBuf; }
114  /// Get the create info the buffer was created with
115  const RV_VKBufferCreateInfo& getInfo() { return *myCreateInfo; }
116  /// Get the memory the buffer is backed by
117  RV_VKMemory& getMemory() { return *myMemory; }
118  const RV_VKMemory& getMemory() const { return *myMemory; }
119  /// Return the memory size this buffer uses, in bytes
120  exint gpuMemoryUsage() const;
121  /// Return unique ID for buffer object
122  const RV_ResourceID &getID() const { return myId; }
123  /// Return label for buffer object
124  const UT_StringHolder &getName() const { return myName; }
125 
126  /// Allocate owned buffer view for use as texel Buffer. Does nothing
127  /// if it is already allocated
128  void generateVkView(RV_Instance* inst);
129 
130  /// Fetch the buffer view assigned to this buffer, if any
131  VkBufferView getVkView()
132  {
133  return myView ? myView->getVkView()
134  : VK_NULL_HANDLE;
135  }
136  /// Return the vulkan format of the buffer.
138  {
139  return myView ? myView->getVkFormat()
141  }
142  /// Return the size of the buffer, in bytes
143  exint getSize() const { return myCreateInfo->size; }
144  /// return the vulkan usage of the buffer when it was created
145  VkBufferUsageFlags getUsage() const { return myCreateInfo->usage; }
146  /// return the current usage of this buffer
147  VkBufferUsageFlags getLastUsage() const { return myLastUsage; }
148 
149  /// Number of elements in this buffer (eg. RGB 32b is 1 element)
150  exint entries() const;
151  /// Return the RV type of the buffer
152  RV_GPUType getGPUType() const;
153  /// Return the vector size of the buffer (1-4)
154  int getVectorSize() const;
155  /// Return the device address of the buffer
156  VkDeviceAddress getDeviceAddress() const;
157 
158  /// @brief Upload data to the buffer
159  /// Upload data to the buffer and add a barrier based on its usage.
160  /// Returns true if the size+offset doesn't exceed the allocated size.
161  bool uploadData(RV_Render* r,
162  VkBufferUsageFlags new_usage,
163  const void* data,
164  exint data_size,
165  exint data_offset = 0);
166  /// @brief Upload data to the buffer
167  /// Upload data to the buffer. Returns true if the size+offset doesn't
168  /// exceed the allocated size.
169  bool uploadData(RV_Render* r,
170  const void* data,
171  exint data_size,
172  exint data_offset = 0);
173 
174  /// Span version of buffer upload
176  bool uploadData(RV_Render* r, const T &data)
177  {
178  // `T` must be a `UT_Span` or convertable into a `UT_Span`
180  return uploadData(r, span.data(), span.size_bytes(), 0);
181  }
182 
184  bool uploadData(RV_Render* r, VkBufferUsageFlags new_usage, const T &data)
185  {
186  // `T` must be a `UT_Span` or convertable into a `UT_Span`
188  return uploadData(r, new_usage, span.data(), span.size_bytes(), 0);
189  }
190 
191  /// return whether buffer was declared as CPU visible, and mapped
192  bool isMappedMemory() const;
193 
194  /// Get a CPU mapped ptr to the raw memory. Will return nullptr
195  /// if buffer wasn't declared as CPU visible
196  void* getMappedMemory();
197 
198  /// Download data from the buffer into `buf`
199  bool copyData(RV_Render* r,
200  RV_VKBuffer* dst_buf,
201  exint src_offset = 0,
202  exint dst_offset = 0,
203  exint sublen = -1);
204 
205  /// Donwload data from the buffer to `data`. Returns false if the operation
206  /// would read data out-of-range or there was an error.
207  bool downloadData( RV_Render* r,
208  void* data,
209  exint data_size,
210  exint offset = 0,
211  exint sublen = -1);
212 
213  /// Clear the buffer with 0.
214  void clear(RV_Render *r);
215 
216  /// Add a barrier for using the buffer in the future
218  { addBarrier(r, myLastUsage, new_usage); }
219  /// Add a barrier for using the buffer in the future, changing its usage
220  void addBarrier(RV_Render* r, VkBufferUsageFlags old_usage,
221  VkBufferUsageFlags new_usage);
222 
223  void destroy(RV_Instance* inst);
224 
225  virtual ~RV_VKBuffer();
226 
227  /// Debug output of the buffer (but not its data).
228  void print() const;
229 
230 private:
231  struct PassKey {};
232 public:
233  RV_VKBuffer(RV_Instance* inst,
234  const RV_VKBufferCreateInfo* info,
235  VkBuffer vk_buf,
236  RV_VKMemoryPtr mem,
237  RV_VKBufferViewPtr view,
238  const PassKey&);
239 protected:
240  RV_Instance* myInst = nullptr;
241 
242  VkBuffer myVkBuf = VK_NULL_HANDLE;
246 
249 
250 public:
252  RV_StageGroup myWaitingBarrierStage = RV_STAGE_NONE;
253  exint myWaitingBarrierGroupID = -1;
254 };
255 
256 #endif
VkFormat getVkFormat() const
Definition: RV_VKBuffer.h:36
VkBuffer getVkBuf()
Get the raw vulkan buffer handle.
Definition: RV_VKBuffer.h:113
#define VK_NULL_HANDLE
Definition: vulkan_core.h:45
VkFlags VkBufferUsageFlags
Definition: vulkan_core.h:2515
constexpr span< ElementType, Extent > make_span(span< ElementType, Extent > s) noexcept
Definition: UT_Span.h:559
*get result *(waiting if necessary)*A common idiom is to fire a bunch of sub tasks at the and then *wait for them to all complete We provide a helper class
Definition: thread.h:632
UT_UniquePtr< RV_VKBuffer > RV_VKBufferPtr
Definition: RV_TypePtrs.h:63
const RV_VKBufferCreateInfo & getInfo()
Get the create info the buffer was created with.
Definition: RV_VKBuffer.h:115
GLsizei const GLfloat * value
Definition: glcorearb.h:824
Definition: span.h:74
int64 exint
Definition: SYS_Types.h:125
RV_StageGroup
Definition: RV_Type.h:442
VkBufferView getVkView()
Fetch the buffer view assigned to this buffer, if any.
Definition: RV_VKBuffer.h:131
UT_UniquePtr< RV_VKMemory > RV_VKMemoryPtr
Definition: RV_TypePtrs.h:50
bool uploadData(RV_Render *r, VkBufferUsageFlags new_usage, const T &data)
Definition: RV_VKBuffer.h:184
exint getSize() const
Return the size of the buffer, in bytes.
Definition: RV_VKBuffer.h:143
UT_UniquePtr< RV_VKMemory > myMemory
Definition: RV_VKBuffer.h:248
VkBufferView getVkView()
Definition: RV_VKBuffer.h:35
std::unique_ptr< T, Deleter > UT_UniquePtr
A smart pointer for unique ownership of dynamically allocated objects.
Definition: UT_UniquePtr.h:39
UT_StringHolder myName
Definition: RV_VKBuffer.h:244
VkBufferUsageFlags myLastUsage
Definition: RV_VKBuffer.h:251
UT_UniquePtr< RV_VKBufferView > myView
Definition: RV_VKBuffer.h:247
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:108
GLintptr offset
Definition: glcorearb.h:665
UT_UniquePtr< const RV_VKBufferCreateInfo > myCreateInfo
Definition: RV_VKBuffer.h:245
#define RV_API
Definition: RV_API.h:10
const UT_StringHolder & getName() const
Return label for buffer object.
Definition: RV_VKBuffer.h:124
bool uploadData(RV_Render *r, const T &data)
Span version of buffer upload.
Definition: RV_VKBuffer.h:176
RV_VKMemory & getMemory()
Get the memory the buffer is backed by.
Definition: RV_VKBuffer.h:117
const RV_ResourceID & getID() const
Return unique ID for buffer object.
Definition: RV_VKBuffer.h:122
GLuint const GLchar * name
Definition: glcorearb.h:786
Handle to the main interface of Vulkan.
Definition: RV_Instance.h:48
RV_VKBufferView(RV_VKBufferView &&other) noexcept
Definition: RV_VKBuffer.h:53
VkBufferUsageFlags getLastUsage() const
return the current usage of this buffer
Definition: RV_VKBuffer.h:147
VkFormat getVkFormat() const
Return the vulkan format of the buffer.
Definition: RV_VKBuffer.h:137
GLsizeiptr size
Definition: glcorearb.h:664
GLsizeiptr const void GLenum usage
Definition: glcorearb.h:664
RV_ResourceID myId
Definition: RV_VKBuffer.h:243
RV_GPUType
Definition: RV_Type.h:40
LeafData & operator=(const LeafData &)=delete
constexpr size_type size_bytes() const noexcept
Definition: span.h:187
VkFormat
Definition: vulkan_core.h:1386
VkBufferUsageFlags getUsage() const
return the vulkan usage of the buffer when it was created
Definition: RV_VKBuffer.h:145
RV_MemType
Definition: RV_Type.h:111
GLboolean r
Definition: glcorearb.h:1222
UT_UniquePtr< RV_VKBufferView > RV_VKBufferViewPtr
Definition: RV_TypePtrs.h:64
A vulkan buffer object.
Definition: RV_VKBuffer.h:75
RAII wrapper class for VkBufferView.
Definition: RV_VKBuffer.h:32
const RV_VKMemory & getMemory() const
Definition: RV_VKBuffer.h:118
VkBufferCreateInfo RV_VKBufferCreateInfo
Definition: RV_VKBuffer.h:26
FMT_INLINE void print(format_string< T...> fmt, T &&...args)
Definition: core.h:2903
uint64_t VkDeviceAddress
Definition: vulkan_core.h:94
constexpr pointer data() const noexcept
Definition: span.h:190
RV_VKBufferView(RV_Instance *inst, VkBufferView vk_view, VkFormat vk_format)
Definition: RV_VKBuffer.h:44
void addBarrier(RV_Render *r, VkBufferUsageFlags new_usage)
Add a barrier for using the buffer in the future.
Definition: RV_VKBuffer.h:217
Definition: format.h:1821