@@ -55,21 +55,27 @@ class BufferAllocation
5555 void update (const T &value, uint32_t offset = 0 );
5656
5757 private:
58- BufferType *buffer = nullptr ;
59- DeviceSizeType base_offset = 0 ;
60- DeviceSizeType size = 0 ;
58+ vkb::core::HPPBuffer *buffer = nullptr ;
59+ vk::DeviceSize offset = 0 ;
60+ vk::DeviceSize size = 0 ;
6161};
6262
6363using BufferAllocationC = BufferAllocation<vkb::BindingType::C>;
6464using BufferAllocationCpp = BufferAllocation<vkb::BindingType::Cpp>;
6565
66- template <vkb::BindingType bindingType>
67- BufferAllocation<bindingType>::BufferAllocation(BufferType &buffer, DeviceSizeType size, DeviceSizeType offset) :
68- buffer{&buffer},
69- size{size},
70- base_offset{offset}
71- {
72- }
66+ template <>
67+ inline BufferAllocation<vkb::BindingType::Cpp>::BufferAllocation(vkb::core::HPPBuffer &buffer, vk::DeviceSize size, vk::DeviceSize offset) :
68+ buffer (&buffer),
69+ offset(offset),
70+ size(size)
71+ {}
72+
73+ template <>
74+ inline BufferAllocation<vkb::BindingType::C>::BufferAllocation(vkb::core::Buffer &buffer, VkDeviceSize size, VkDeviceSize offset) :
75+ buffer (reinterpret_cast <vkb::core::HPPBuffer *>(&buffer)),
76+ offset(static_cast <vk::DeviceSize>(offset)),
77+ size(static_cast <vk::DeviceSize>(size))
78+ {}
7379
7480template <vkb::BindingType bindingType>
7581bool BufferAllocation<bindingType>::empty() const
@@ -81,19 +87,40 @@ template <vkb::BindingType bindingType>
8187typename BufferAllocation<bindingType>::BufferType &BufferAllocation<bindingType>::get_buffer()
8288{
8389 assert (buffer && " Invalid buffer pointer" );
84- return *buffer;
90+ if constexpr (bindingType == vkb::BindingType::Cpp)
91+ {
92+ return *buffer;
93+ }
94+ else
95+ {
96+ return reinterpret_cast <vkb::core::Buffer &>(*buffer);
97+ }
8598}
8699
87100template <vkb::BindingType bindingType>
88101typename BufferAllocation<bindingType>::DeviceSizeType BufferAllocation<bindingType>::get_offset() const
89102{
90- return base_offset;
103+ if constexpr (bindingType == vkb::BindingType::Cpp)
104+ {
105+ return offset;
106+ }
107+ else
108+ {
109+ return static_cast <VkDeviceSize>(offset);
110+ }
91111}
92112
93113template <vkb::BindingType bindingType>
94114typename BufferAllocation<bindingType>::DeviceSizeType BufferAllocation<bindingType>::get_size() const
95115{
96- return size;
116+ if constexpr (bindingType == vkb::BindingType::Cpp)
117+ {
118+ return size;
119+ }
120+ else
121+ {
122+ return static_cast <VkDeviceSize>(size);
123+ }
97124}
98125
99126template <vkb::BindingType bindingType>
@@ -103,7 +130,7 @@ void BufferAllocation<bindingType>::update(const std::vector<uint8_t> &data, uin
103130
104131 if (offset + data.size () <= size)
105132 {
106- buffer->update (data, to_u32 (base_offset ) + offset);
133+ buffer->update (data, to_u32 (this -> offset ) + offset);
107134 }
108135 else
109136 {
@@ -200,7 +227,7 @@ BufferAllocation<bindingType> BufferBlock<bindingType>::allocate(DeviceSizeType
200227 }
201228 else
202229 {
203- return BufferAllocationC{reinterpret_cast <vkb::core::Buffer &>(buffer), static_cast <VkDeviceSize>(size), static_cast <VkDeviceSize>(offset )};
230+ return BufferAllocationC{reinterpret_cast <vkb::core::Buffer &>(buffer), static_cast <VkDeviceSize>(size), static_cast <VkDeviceSize>(aligned )};
204231 }
205232 }
206233
@@ -293,11 +320,11 @@ class BufferPool
293320 void reset ();
294321
295322 private:
296- vkb::core::HPPDevice &device;
297- std::vector<BufferBlockCpp> buffer_blocks; // / List of blocks requested
298- vk::DeviceSize block_size = 0 ; // / Minimum size of the blocks
299- vk::BufferUsageFlags usage;
300- VmaMemoryUsage memory_usage{};
323+ vkb::core::HPPDevice &device;
324+ std::vector<std::unique_ptr< BufferBlockCpp>> buffer_blocks; // / List of blocks requested (need to be pointers in order to keep their address constant on vector resizing)
325+ vk::DeviceSize block_size = 0 ; // / Minimum size of the blocks
326+ vk::BufferUsageFlags usage;
327+ VmaMemoryUsage memory_usage{};
301328};
302329
303330using BufferPoolC = BufferPool<vkb::BindingType::C>;
@@ -315,10 +342,10 @@ BufferBlock<bindingType> &BufferPool<bindingType>::request_buffer_block(DeviceSi
315342 // Find a block in the range of the blocks which can fit the minimum size
316343 auto it = minimal ? std::find_if (buffer_blocks.begin (),
317344 buffer_blocks.end (),
318- [&minimum_size](const BufferBlockCpp &buffer_block) { return (buffer_block. get_size () == minimum_size) && buffer_block. can_allocate (minimum_size); }) :
345+ [&minimum_size](auto const &buffer_block) { return (buffer_block-> get_size () == minimum_size) && buffer_block-> can_allocate (minimum_size); }) :
319346 std::find_if (buffer_blocks.begin (),
320347 buffer_blocks.end (),
321- [&minimum_size](const BufferBlockCpp &buffer_block) { return buffer_block. can_allocate (minimum_size); });
348+ [&minimum_size](auto const &buffer_block) { return buffer_block-> can_allocate (minimum_size); });
322349
323350 if (it == buffer_blocks.end ())
324351 {
@@ -327,23 +354,29 @@ BufferBlock<bindingType> &BufferPool<bindingType>::request_buffer_block(DeviceSi
327354 vk::DeviceSize new_block_size = minimal ? minimum_size : std::max (block_size, minimum_size);
328355
329356 // Create a new block and get the iterator on it
330- it = buffer_blocks.emplace (buffer_blocks.end (), BufferBlockCpp (device, new_block_size, usage, memory_usage));
357+ it = buffer_blocks.emplace (buffer_blocks.end (), std::make_unique< BufferBlockCpp> (device, new_block_size, usage, memory_usage));
331358 }
332359
333360 if constexpr (bindingType == vkb::BindingType::Cpp)
334361 {
335- return *it;
362+ return *it-> get () ;
336363 }
337364 else
338365 {
339- return reinterpret_cast <BufferBlockC &>(*it);
366+ return reinterpret_cast <BufferBlockC &>(*it-> get () );
340367 }
341368}
342369
343370template <vkb::BindingType bindingType>
344371void BufferPool<bindingType>::reset()
345372{
346- buffer_blocks.clear ();
373+ // Attention: Resetting the BufferPool is not supposed to clear the BufferBlocks, but just reset them!
374+ // The actual VkBuffers are used to hash the DescriptorSet in RenderFrame::request_descriptor_set.
375+ // Don't know (for now) how that works with resetted buffers!
376+ for (auto &buffer_block : buffer_blocks)
377+ {
378+ buffer_block->reset ();
379+ }
347380}
348381
349382} // namespace vkb
0 commit comments