|
|
|
@ -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 |