summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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)
155 renderer_vulkan/maxwell_to_vk.h 155 renderer_vulkan/maxwell_to_vk.h
156 renderer_vulkan/vk_buffer_cache.cpp 156 renderer_vulkan/vk_buffer_cache.cpp
157 renderer_vulkan/vk_buffer_cache.h 157 renderer_vulkan/vk_buffer_cache.h
158 renderer_vulkan/vk_descriptor_pool.cpp
159 renderer_vulkan/vk_descriptor_pool.h
158 renderer_vulkan/vk_device.cpp 160 renderer_vulkan/vk_device.cpp
159 renderer_vulkan/vk_device.h 161 renderer_vulkan/vk_device.h
160 renderer_vulkan/vk_image.cpp 162 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 @@
1// Copyright 2019 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <memory>
6#include <vector>
7
8#include "common/common_types.h"
9#include "video_core/renderer_vulkan/declarations.h"
10#include "video_core/renderer_vulkan/vk_descriptor_pool.h"
11#include "video_core/renderer_vulkan/vk_device.h"
12#include "video_core/renderer_vulkan/vk_resource_manager.h"
13
14namespace Vulkan {
15
16// Prefer small grow rates to avoid saturating the descriptor pool with barely used pipelines.
17constexpr std::size_t SETS_GROW_RATE = 0x20;
18
19DescriptorAllocator::DescriptorAllocator(VKDescriptorPool& descriptor_pool,
20 vk::DescriptorSetLayout layout)
21 : VKFencedPool{SETS_GROW_RATE}, descriptor_pool{descriptor_pool}, layout{layout} {}
22
23DescriptorAllocator::~DescriptorAllocator() = default;
24
25vk::DescriptorSet DescriptorAllocator::Commit(VKFence& fence) {
26 return *descriptors[CommitResource(fence)];
27}
28
29void DescriptorAllocator::Allocate(std::size_t begin, std::size_t end) {
30 auto new_sets = descriptor_pool.AllocateDescriptors(layout, end - begin);
31 descriptors.insert(descriptors.end(), std::make_move_iterator(new_sets.begin()),
32 std::make_move_iterator(new_sets.end()));
33}
34
35VKDescriptorPool::VKDescriptorPool(const VKDevice& device)
36 : device{device}, active_pool{AllocateNewPool()} {}
37
38VKDescriptorPool::~VKDescriptorPool() = default;
39
40vk::DescriptorPool VKDescriptorPool::AllocateNewPool() {
41 static constexpr u32 num_sets = 0x20000;
42 static constexpr vk::DescriptorPoolSize pool_sizes[] = {
43 {vk::DescriptorType::eUniformBuffer, num_sets * 90},
44 {vk::DescriptorType::eStorageBuffer, num_sets * 60},
45 {vk::DescriptorType::eUniformTexelBuffer, num_sets * 64},
46 {vk::DescriptorType::eCombinedImageSampler, num_sets * 64},
47 {vk::DescriptorType::eStorageImage, num_sets * 40}};
48
49 const vk::DescriptorPoolCreateInfo create_info(
50 vk::DescriptorPoolCreateFlagBits::eFreeDescriptorSet, num_sets,
51 static_cast<u32>(std::size(pool_sizes)), std::data(pool_sizes));
52 const auto dev = device.GetLogical();
53 return *pools.emplace_back(
54 dev.createDescriptorPoolUnique(create_info, nullptr, device.GetDispatchLoader()));
55}
56
57std::vector<UniqueDescriptorSet> VKDescriptorPool::AllocateDescriptors(
58 vk::DescriptorSetLayout layout, std::size_t count) {
59 std::vector layout_copies(count, layout);
60 vk::DescriptorSetAllocateInfo allocate_info(active_pool, static_cast<u32>(count),
61 layout_copies.data());
62
63 std::vector<vk::DescriptorSet> sets(count);
64 const auto dev = device.GetLogical();
65 const auto& dld = device.GetDispatchLoader();
66 switch (const auto result = dev.allocateDescriptorSets(&allocate_info, sets.data(), dld)) {
67 case vk::Result::eSuccess:
68 break;
69 case vk::Result::eErrorOutOfPoolMemory:
70 active_pool = AllocateNewPool();
71 allocate_info.descriptorPool = active_pool;
72 if (dev.allocateDescriptorSets(&allocate_info, sets.data(), dld) == vk::Result::eSuccess) {
73 break;
74 }
75 [[fallthrough]];
76 default:
77 vk::throwResultException(result, "vk::Device::allocateDescriptorSetsUnique");
78 }
79
80 vk::PoolFree deleter(dev, active_pool, dld);
81 std::vector<UniqueDescriptorSet> unique_sets;
82 unique_sets.reserve(count);
83 for (const auto set : sets) {
84 unique_sets.push_back(UniqueDescriptorSet{set, deleter});
85 }
86 return unique_sets;
87}
88
89} // 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 @@
1// Copyright 2019 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <memory>
8#include <vector>
9
10#include "common/common_types.h"
11#include "video_core/renderer_vulkan/declarations.h"
12#include "video_core/renderer_vulkan/vk_resource_manager.h"
13
14namespace Vulkan {
15
16class VKDescriptorPool;
17
18class DescriptorAllocator final : public VKFencedPool {
19public:
20 explicit DescriptorAllocator(VKDescriptorPool& descriptor_pool, vk::DescriptorSetLayout layout);
21 ~DescriptorAllocator() override;
22
23 DescriptorAllocator(const DescriptorAllocator&) = delete;
24
25 vk::DescriptorSet Commit(VKFence& fence);
26
27protected:
28 void Allocate(std::size_t begin, std::size_t end) override;
29
30private:
31 VKDescriptorPool& descriptor_pool;
32 const vk::DescriptorSetLayout layout;
33
34 std::vector<UniqueDescriptorSet> descriptors;
35};
36
37class VKDescriptorPool final {
38 friend DescriptorAllocator;
39
40public:
41 explicit VKDescriptorPool(const VKDevice& device);
42 ~VKDescriptorPool();
43
44private:
45 vk::DescriptorPool AllocateNewPool();
46
47 std::vector<UniqueDescriptorSet> AllocateDescriptors(vk::DescriptorSetLayout layout,
48 std::size_t count);
49
50 const VKDevice& device;
51
52 std::vector<UniqueDescriptorPool> pools;
53 vk::DescriptorPool active_pool;
54};
55
56} // namespace Vulkan \ No newline at end of file