Skip to content

Commit 90c1d92

Browse files
authored
Fix three errors in BufferPool<bindingType>. (#1127)
* Fix buffer offset in BufferBlock<bindingType>::allocate for the C-binding-path. * Restore to how BufferPool::reset worked before.
1 parent 7619314 commit 90c1d92

File tree

1 file changed

+59
-26
lines changed

1 file changed

+59
-26
lines changed

framework/buffer_pool.h

Lines changed: 59 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -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

6363
using BufferAllocationC = BufferAllocation<vkb::BindingType::C>;
6464
using 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

7480
template <vkb::BindingType bindingType>
7581
bool BufferAllocation<bindingType>::empty() const
@@ -81,19 +87,40 @@ template <vkb::BindingType bindingType>
8187
typename 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

87100
template <vkb::BindingType bindingType>
88101
typename 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

93113
template <vkb::BindingType bindingType>
94114
typename 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

99126
template <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

303330
using 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

343370
template <vkb::BindingType bindingType>
344371
void 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

Comments
 (0)