Просмотр исходного кода

renderer_vulkan/wrapper: Add pool allocations owning templated class

ReinUsesLisp 6 лет назад
Родитель
Сommit
7413b30923
1 измененных файлов с 81 добавлено и 0 удалено
  1. 81 0
      src/video_core/renderer_vulkan/wrapper.h

+ 81 - 0
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