summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2020-01-01 16:44:06 -0300
committerGravatar ReinUsesLisp2020-01-01 16:44:06 -0300
commit1fe7df45177e805f14f0c9665fd23cac7172769a (patch)
treeea9b1a64b8d444e91124e353876f7f8802322874 /src
parentMerge pull request #3239 from ReinUsesLisp/p2r (diff)
downloadyuzu-1fe7df45177e805f14f0c9665fd23cac7172769a.tar.gz
yuzu-1fe7df45177e805f14f0c9665fd23cac7172769a.tar.xz
yuzu-1fe7df45177e805f14f0c9665fd23cac7172769a.zip
vk_descriptor_pool: Initial implementation
Create a large descriptor pool where we allocate all our descriptors from. It has to be wide enough to support any pipeline, hence its large numbers. If the descritor pool is filled, we allocate more memory at that moment. This way we can take advantage of permissive drivers like Nvidia's that allocate more descriptors than what the spec requires.
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 2594cd0bd..13f9848bc 100644
--- a/src/video_core/CMakeLists.txt
+++ b/src/video_core/CMakeLists.txt
@@ -157,6 +157,8 @@ if (ENABLE_VULKAN)
157 renderer_vulkan/maxwell_to_vk.h 157 renderer_vulkan/maxwell_to_vk.h
158 renderer_vulkan/vk_buffer_cache.cpp 158 renderer_vulkan/vk_buffer_cache.cpp
159 renderer_vulkan/vk_buffer_cache.h 159 renderer_vulkan/vk_buffer_cache.h
160 renderer_vulkan/vk_descriptor_pool.cpp
161 renderer_vulkan/vk_descriptor_pool.h
160 renderer_vulkan/vk_device.cpp 162 renderer_vulkan/vk_device.cpp
161 renderer_vulkan/vk_device.h 163 renderer_vulkan/vk_device.h
162 renderer_vulkan/vk_image.cpp 164 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..7e6e4ccb7
--- /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.
17static constexpr 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