summaryrefslogtreecommitdiffstats
path: root/src/video_core
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core')
-rw-r--r--src/video_core/CMakeLists.txt2
-rw-r--r--src/video_core/renderer_vulkan/vk_descriptor_pool.cpp89
-rw-r--r--src/video_core/renderer_vulkan/vk_descriptor_pool.h56
3 files changed, 147 insertions, 0 deletions
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt
index 65d7b9f93..abbf218f5 100644
--- a/src/video_core/CMakeLists.txt
+++ b/src/video_core/CMakeLists.txt
@@ -155,6 +155,8 @@ if (ENABLE_VULKAN)
renderer_vulkan/maxwell_to_vk.h
renderer_vulkan/vk_buffer_cache.cpp
renderer_vulkan/vk_buffer_cache.h
+ renderer_vulkan/vk_descriptor_pool.cpp
+ renderer_vulkan/vk_descriptor_pool.h
renderer_vulkan/vk_device.cpp
renderer_vulkan/vk_device.h
renderer_vulkan/vk_image.cpp
diff --git a/src/video_core/renderer_vulkan/vk_descriptor_pool.cpp b/src/video_core/renderer_vulkan/vk_descriptor_pool.cpp
new file mode 100644
index 000000000..cc7c281a0
--- /dev/null
+++ b/src/video_core/renderer_vulkan/vk_descriptor_pool.cpp
@@ -0,0 +1,89 @@
+// Copyright 2019 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <memory>
+#include <vector>
+
+#include "common/common_types.h"
+#include "video_core/renderer_vulkan/declarations.h"
+#include "video_core/renderer_vulkan/vk_descriptor_pool.h"
+#include "video_core/renderer_vulkan/vk_device.h"
+#include "video_core/renderer_vulkan/vk_resource_manager.h"
+
+namespace Vulkan {
+
+// Prefer small grow rates to avoid saturating the descriptor pool with barely used pipelines.
+constexpr std::size_t SETS_GROW_RATE = 0x20;
+
+DescriptorAllocator::DescriptorAllocator(VKDescriptorPool& descriptor_pool,
+ vk::DescriptorSetLayout layout)
+ : VKFencedPool{SETS_GROW_RATE}, descriptor_pool{descriptor_pool}, layout{layout} {}
+
+DescriptorAllocator::~DescriptorAllocator() = default;
+
+vk::DescriptorSet DescriptorAllocator::Commit(VKFence& fence) {
+ return *descriptors[CommitResource(fence)];
+}
+
+void DescriptorAllocator::Allocate(std::size_t begin, std::size_t end) {
+ auto new_sets = descriptor_pool.AllocateDescriptors(layout, end - begin);
+ descriptors.insert(descriptors.end(), std::make_move_iterator(new_sets.begin()),
+ std::make_move_iterator(new_sets.end()));
+}
+
+VKDescriptorPool::VKDescriptorPool(const VKDevice& device)
+ : device{device}, active_pool{AllocateNewPool()} {}
+
+VKDescriptorPool::~VKDescriptorPool() = default;
+
+vk::DescriptorPool VKDescriptorPool::AllocateNewPool() {
+ static constexpr u32 num_sets = 0x20000;
+ static constexpr vk::DescriptorPoolSize pool_sizes[] = {
+ {vk::DescriptorType::eUniformBuffer, num_sets * 90},
+ {vk::DescriptorType::eStorageBuffer, num_sets * 60},
+ {vk::DescriptorType::eUniformTexelBuffer, num_sets * 64},
+ {vk::DescriptorType::eCombinedImageSampler, num_sets * 64},
+ {vk::DescriptorType::eStorageImage, num_sets * 40}};
+
+ const vk::DescriptorPoolCreateInfo create_info(
+ vk::DescriptorPoolCreateFlagBits::eFreeDescriptorSet, num_sets,
+ static_cast<u32>(std::size(pool_sizes)), std::data(pool_sizes));
+ const auto dev = device.GetLogical();
+ return *pools.emplace_back(
+ dev.createDescriptorPoolUnique(create_info, nullptr, device.GetDispatchLoader()));
+}
+
+std::vector<UniqueDescriptorSet> VKDescriptorPool::AllocateDescriptors(
+ vk::DescriptorSetLayout layout, std::size_t count) {
+ std::vector layout_copies(count, layout);
+ vk::DescriptorSetAllocateInfo allocate_info(active_pool, static_cast<u32>(count),
+ layout_copies.data());
+
+ std::vector<vk::DescriptorSet> sets(count);
+ const auto dev = device.GetLogical();
+ const auto& dld = device.GetDispatchLoader();
+ switch (const auto result = dev.allocateDescriptorSets(&allocate_info, sets.data(), dld)) {
+ case vk::Result::eSuccess:
+ break;
+ case vk::Result::eErrorOutOfPoolMemory:
+ active_pool = AllocateNewPool();
+ allocate_info.descriptorPool = active_pool;
+ if (dev.allocateDescriptorSets(&allocate_info, sets.data(), dld) == vk::Result::eSuccess) {
+ break;
+ }
+ [[fallthrough]];
+ default:
+ vk::throwResultException(result, "vk::Device::allocateDescriptorSetsUnique");
+ }
+
+ vk::PoolFree deleter(dev, active_pool, dld);
+ std::vector<UniqueDescriptorSet> unique_sets;
+ unique_sets.reserve(count);
+ for (const auto set : sets) {
+ unique_sets.push_back(UniqueDescriptorSet{set, deleter});
+ }
+ return unique_sets;
+}
+
+} // namespace Vulkan
diff --git a/src/video_core/renderer_vulkan/vk_descriptor_pool.h b/src/video_core/renderer_vulkan/vk_descriptor_pool.h
new file mode 100644
index 000000000..a441dbc0f
--- /dev/null
+++ b/src/video_core/renderer_vulkan/vk_descriptor_pool.h
@@ -0,0 +1,56 @@
+// Copyright 2019 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <memory>
+#include <vector>
+
+#include "common/common_types.h"
+#include "video_core/renderer_vulkan/declarations.h"
+#include "video_core/renderer_vulkan/vk_resource_manager.h"
+
+namespace Vulkan {
+
+class VKDescriptorPool;
+
+class DescriptorAllocator final : public VKFencedPool {
+public:
+ explicit DescriptorAllocator(VKDescriptorPool& descriptor_pool, vk::DescriptorSetLayout layout);
+ ~DescriptorAllocator() override;
+
+ DescriptorAllocator(const DescriptorAllocator&) = delete;
+
+ vk::DescriptorSet Commit(VKFence& fence);
+
+protected:
+ void Allocate(std::size_t begin, std::size_t end) override;
+
+private:
+ VKDescriptorPool& descriptor_pool;
+ const vk::DescriptorSetLayout layout;
+
+ std::vector<UniqueDescriptorSet> descriptors;
+};
+
+class VKDescriptorPool final {
+ friend DescriptorAllocator;
+
+public:
+ explicit VKDescriptorPool(const VKDevice& device);
+ ~VKDescriptorPool();
+
+private:
+ vk::DescriptorPool AllocateNewPool();
+
+ std::vector<UniqueDescriptorSet> AllocateDescriptors(vk::DescriptorSetLayout layout,
+ std::size_t count);
+
+ const VKDevice& device;
+
+ std::vector<UniqueDescriptorPool> pools;
+ vk::DescriptorPool active_pool;
+};
+
+} // namespace Vulkan \ No newline at end of file