renderer_vulkan/wrapper: Add pool allocations owning templated class
This commit is contained in:
parent
d8d392b39a
commit
7413b30923
1 changed files with 81 additions and 0 deletions
|
@ -422,4 +422,85 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
/// Array of a pool allocation.
|
||||
/// Analogue to std::vector
|
||||
template <typename AllocationType, typename PoolType>
|
||||
class PoolAllocations {
|
||||
public:
|
||||
/// Construct an empty allocation.
|
||||
PoolAllocations() = default;
|
||||
|
||||
/// Construct an allocation. Errors are reported through IsOutOfPoolMemory().
|
||||
explicit PoolAllocations(std::unique_ptr<AllocationType[]> allocations, std::size_t num,
|
||||
VkDevice device, PoolType pool, const DeviceDispatch& dld) noexcept
|
||||
: allocations{std::move(allocations)}, num{num}, device{device}, pool{pool}, dld{&dld} {}
|
||||
|
||||
/// Copying Vulkan allocations is not supported and will never be.
|
||||
PoolAllocations(const PoolAllocations&) = delete;
|
||||
PoolAllocations& operator=(const PoolAllocations&) = delete;
|
||||
|
||||
/// Construct an allocation transfering ownership from another allocation.
|
||||
PoolAllocations(PoolAllocations&& rhs) noexcept
|
||||
: allocations{std::move(rhs.allocations)}, num{rhs.num}, device{rhs.device}, pool{rhs.pool},
|
||||
dld{rhs.dld} {}
|
||||
|
||||
/// Assign an allocation transfering ownership from another allocation.
|
||||
/// Releases any previously held allocation.
|
||||
PoolAllocations& operator=(PoolAllocations&& rhs) noexcept {
|
||||
Release();
|
||||
allocations = std::move(rhs.allocations);
|
||||
num = rhs.num;
|
||||
device = rhs.device;
|
||||
pool = rhs.pool;
|
||||
dld = rhs.dld;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Destroys any held allocation.
|
||||
~PoolAllocations() {
|
||||
Release();
|
||||
}
|
||||
|
||||
/// Returns the number of allocations.
|
||||
std::size_t size() const noexcept {
|
||||
return num;
|
||||
}
|
||||
|
||||
/// Returns a pointer to the array of allocations.
|
||||
AllocationType const* data() const noexcept {
|
||||
return allocations.get();
|
||||
}
|
||||
|
||||
/// Returns the allocation in the specified index.
|
||||
/// @pre index < size()
|
||||
AllocationType operator[](std::size_t index) const noexcept {
|
||||
return allocations[index];
|
||||
}
|
||||
|
||||
/// True when a pool fails to construct.
|
||||
bool IsOutOfPoolMemory() const noexcept {
|
||||
return !device;
|
||||
}
|
||||
|
||||
private:
|
||||
/// Destroys the held allocations if they exist.
|
||||
void Release() noexcept {
|
||||
if (!allocations) {
|
||||
return;
|
||||
}
|
||||
const Span<AllocationType> span(allocations.get(), num);
|
||||
const VkResult result = Free(device, pool, span, *dld);
|
||||
// There's no way to report errors from a destructor.
|
||||
if (result != VK_SUCCESS) {
|
||||
std::terminate();
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<AllocationType[]> allocations;
|
||||
std::size_t num = 0;
|
||||
VkDevice device = nullptr;
|
||||
PoolType pool = nullptr;
|
||||
const DeviceDispatch* dld = nullptr;
|
||||
};
|
||||
|
||||
} // namespace Vulkan::vk
|
||||
|
|
Loading…
Reference in a new issue