summaryrefslogtreecommitdiffstats
path: root/src/video_core
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core')
-rw-r--r--src/video_core/renderer_vulkan/wrapper.h81
1 files changed, 81 insertions, 0 deletions
diff --git a/src/video_core/renderer_vulkan/wrapper.h b/src/video_core/renderer_vulkan/wrapper.h
index 5c6729dbc..b50e1f3c7 100644
--- a/src/video_core/renderer_vulkan/wrapper.h
+++ b/src/video_core/renderer_vulkan/wrapper.h
@@ -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