summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2021-04-25 00:15:32 -0300
committerGravatar ameerj2021-07-22 21:51:29 -0400
commit2f3c3dfc10a318f63862c4976f0608ea50c19387 (patch)
tree243109289cc347fe1e8d3ea8adee8e32c791af3b /src
parentvk_graphics_pipeline: Generate specialized pipeline config functions and impr... (diff)
downloadyuzu-2f3c3dfc10a318f63862c4976f0608ea50c19387.tar.gz
yuzu-2f3c3dfc10a318f63862c4976f0608ea50c19387.tar.xz
yuzu-2f3c3dfc10a318f63862c4976f0608ea50c19387.zip
vulkan: Rework descriptor allocation algorithm
Create multiple descriptor pools on demand. There are some degrees of freedom what is considered a compatible pool to avoid wasting large pools on small descriptors.
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_vulkan/blit_image.cpp19
-rw-r--r--src/video_core/renderer_vulkan/blit_image.h2
-rw-r--r--src/video_core/renderer_vulkan/vk_buffer_cache.cpp2
-rw-r--r--src/video_core/renderer_vulkan/vk_buffer_cache.h4
-rw-r--r--src/video_core/renderer_vulkan/vk_compute_pass.cpp200
-rw-r--r--src/video_core/renderer_vulkan/vk_compute_pass.h28
-rw-r--r--src/video_core/renderer_vulkan/vk_compute_pipeline.cpp4
-rw-r--r--src/video_core/renderer_vulkan/vk_compute_pipeline.h2
-rw-r--r--src/video_core/renderer_vulkan/vk_descriptor_pool.cpp172
-rw-r--r--src/video_core/renderer_vulkan/vk_descriptor_pool.h62
-rw-r--r--src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp4
-rw-r--r--src/video_core/renderer_vulkan/vk_graphics_pipeline.h2
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.cpp2
-rw-r--r--src/video_core/renderer_vulkan/vk_pipeline_cache.h6
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.h2
15 files changed, 314 insertions, 197 deletions
diff --git a/src/video_core/renderer_vulkan/blit_image.cpp b/src/video_core/renderer_vulkan/blit_image.cpp
index 39fe9289b..4058f62cd 100644
--- a/src/video_core/renderer_vulkan/blit_image.cpp
+++ b/src/video_core/renderer_vulkan/blit_image.cpp
@@ -49,6 +49,16 @@ constexpr VkDescriptorSetLayoutCreateInfo ONE_TEXTURE_DESCRIPTOR_SET_LAYOUT_CREA
49 .bindingCount = 1, 49 .bindingCount = 1,
50 .pBindings = &TEXTURE_DESCRIPTOR_SET_LAYOUT_BINDING<0>, 50 .pBindings = &TEXTURE_DESCRIPTOR_SET_LAYOUT_BINDING<0>,
51}; 51};
52template <u32 num_textures>
53inline constexpr DescriptorBankInfo TEXTURE_DESCRIPTOR_BANK_INFO{
54 .uniform_buffers = 0,
55 .storage_buffers = 0,
56 .texture_buffers = 0,
57 .image_buffers = 0,
58 .textures = num_textures,
59 .images = 0,
60 .score = 2,
61};
52constexpr VkDescriptorSetLayoutCreateInfo TWO_TEXTURES_DESCRIPTOR_SET_LAYOUT_CREATE_INFO{ 62constexpr VkDescriptorSetLayoutCreateInfo TWO_TEXTURES_DESCRIPTOR_SET_LAYOUT_CREATE_INFO{
53 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, 63 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
54 .pNext = nullptr, 64 .pNext = nullptr,
@@ -326,14 +336,16 @@ void BindBlitState(vk::CommandBuffer cmdbuf, VkPipelineLayout layout, const Regi
326} // Anonymous namespace 336} // Anonymous namespace
327 337
328BlitImageHelper::BlitImageHelper(const Device& device_, VKScheduler& scheduler_, 338BlitImageHelper::BlitImageHelper(const Device& device_, VKScheduler& scheduler_,
329 StateTracker& state_tracker_, VKDescriptorPool& descriptor_pool) 339 StateTracker& state_tracker_, DescriptorPool& descriptor_pool)
330 : device{device_}, scheduler{scheduler_}, state_tracker{state_tracker_}, 340 : device{device_}, scheduler{scheduler_}, state_tracker{state_tracker_},
331 one_texture_set_layout(device.GetLogical().CreateDescriptorSetLayout( 341 one_texture_set_layout(device.GetLogical().CreateDescriptorSetLayout(
332 ONE_TEXTURE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO)), 342 ONE_TEXTURE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO)),
333 two_textures_set_layout(device.GetLogical().CreateDescriptorSetLayout( 343 two_textures_set_layout(device.GetLogical().CreateDescriptorSetLayout(
334 TWO_TEXTURES_DESCRIPTOR_SET_LAYOUT_CREATE_INFO)), 344 TWO_TEXTURES_DESCRIPTOR_SET_LAYOUT_CREATE_INFO)),
335 one_texture_descriptor_allocator(descriptor_pool, *one_texture_set_layout), 345 one_texture_descriptor_allocator{
336 two_textures_descriptor_allocator(descriptor_pool, *two_textures_set_layout), 346 descriptor_pool.Allocator(*one_texture_set_layout, TEXTURE_DESCRIPTOR_BANK_INFO<1>)},
347 two_textures_descriptor_allocator{
348 descriptor_pool.Allocator(*two_textures_set_layout, TEXTURE_DESCRIPTOR_BANK_INFO<2>)},
337 one_texture_pipeline_layout(device.GetLogical().CreatePipelineLayout( 349 one_texture_pipeline_layout(device.GetLogical().CreatePipelineLayout(
338 PipelineLayoutCreateInfo(one_texture_set_layout.address()))), 350 PipelineLayoutCreateInfo(one_texture_set_layout.address()))),
339 two_textures_pipeline_layout(device.GetLogical().CreatePipelineLayout( 351 two_textures_pipeline_layout(device.GetLogical().CreatePipelineLayout(
@@ -415,7 +427,6 @@ void BlitImageHelper::ConvertD32ToR32(const Framebuffer* dst_framebuffer,
415 427
416void BlitImageHelper::ConvertR32ToD32(const Framebuffer* dst_framebuffer, 428void BlitImageHelper::ConvertR32ToD32(const Framebuffer* dst_framebuffer,
417 const ImageView& src_image_view) { 429 const ImageView& src_image_view) {
418
419 ConvertColorToDepthPipeline(convert_r32_to_d32_pipeline, dst_framebuffer->RenderPass()); 430 ConvertColorToDepthPipeline(convert_r32_to_d32_pipeline, dst_framebuffer->RenderPass());
420 Convert(*convert_r32_to_d32_pipeline, dst_framebuffer, src_image_view); 431 Convert(*convert_r32_to_d32_pipeline, dst_framebuffer, src_image_view);
421} 432}
diff --git a/src/video_core/renderer_vulkan/blit_image.h b/src/video_core/renderer_vulkan/blit_image.h
index 0d81a06ed..33ee095c1 100644
--- a/src/video_core/renderer_vulkan/blit_image.h
+++ b/src/video_core/renderer_vulkan/blit_image.h
@@ -31,7 +31,7 @@ struct BlitImagePipelineKey {
31class BlitImageHelper { 31class BlitImageHelper {
32public: 32public:
33 explicit BlitImageHelper(const Device& device, VKScheduler& scheduler, 33 explicit BlitImageHelper(const Device& device, VKScheduler& scheduler,
34 StateTracker& state_tracker, VKDescriptorPool& descriptor_pool); 34 StateTracker& state_tracker, DescriptorPool& descriptor_pool);
35 ~BlitImageHelper(); 35 ~BlitImageHelper();
36 36
37 void BlitColor(const Framebuffer* dst_framebuffer, const ImageView& src_image_view, 37 void BlitColor(const Framebuffer* dst_framebuffer, const ImageView& src_image_view,
diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp
index cdda56ab1..568993c58 100644
--- a/src/video_core/renderer_vulkan/vk_buffer_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_buffer_cache.cpp
@@ -116,7 +116,7 @@ VkBufferView Buffer::View(u32 offset, u32 size, VideoCore::Surface::PixelFormat
116BufferCacheRuntime::BufferCacheRuntime(const Device& device_, MemoryAllocator& memory_allocator_, 116BufferCacheRuntime::BufferCacheRuntime(const Device& device_, MemoryAllocator& memory_allocator_,
117 VKScheduler& scheduler_, StagingBufferPool& staging_pool_, 117 VKScheduler& scheduler_, StagingBufferPool& staging_pool_,
118 VKUpdateDescriptorQueue& update_descriptor_queue_, 118 VKUpdateDescriptorQueue& update_descriptor_queue_,
119 VKDescriptorPool& descriptor_pool) 119 DescriptorPool& descriptor_pool)
120 : device{device_}, memory_allocator{memory_allocator_}, scheduler{scheduler_}, 120 : device{device_}, memory_allocator{memory_allocator_}, scheduler{scheduler_},
121 staging_pool{staging_pool_}, update_descriptor_queue{update_descriptor_queue_}, 121 staging_pool{staging_pool_}, update_descriptor_queue{update_descriptor_queue_},
122 uint8_pass(device, scheduler, descriptor_pool, staging_pool, update_descriptor_queue), 122 uint8_pass(device, scheduler, descriptor_pool, staging_pool, update_descriptor_queue),
diff --git a/src/video_core/renderer_vulkan/vk_buffer_cache.h b/src/video_core/renderer_vulkan/vk_buffer_cache.h
index ea17406dc..c52001b5a 100644
--- a/src/video_core/renderer_vulkan/vk_buffer_cache.h
+++ b/src/video_core/renderer_vulkan/vk_buffer_cache.h
@@ -16,7 +16,7 @@
16namespace Vulkan { 16namespace Vulkan {
17 17
18class Device; 18class Device;
19class VKDescriptorPool; 19class DescriptorPool;
20class VKScheduler; 20class VKScheduler;
21 21
22class BufferCacheRuntime; 22class BufferCacheRuntime;
@@ -61,7 +61,7 @@ public:
61 explicit BufferCacheRuntime(const Device& device_, MemoryAllocator& memory_manager_, 61 explicit BufferCacheRuntime(const Device& device_, MemoryAllocator& memory_manager_,
62 VKScheduler& scheduler_, StagingBufferPool& staging_pool_, 62 VKScheduler& scheduler_, StagingBufferPool& staging_pool_,
63 VKUpdateDescriptorQueue& update_descriptor_queue_, 63 VKUpdateDescriptorQueue& update_descriptor_queue_,
64 VKDescriptorPool& descriptor_pool); 64 DescriptorPool& descriptor_pool);
65 65
66 void Finish(); 66 void Finish();
67 67
diff --git a/src/video_core/renderer_vulkan/vk_compute_pass.cpp b/src/video_core/renderer_vulkan/vk_compute_pass.cpp
index ec9866605..e2f3d16bf 100644
--- a/src/video_core/renderer_vulkan/vk_compute_pass.cpp
+++ b/src/video_core/renderer_vulkan/vk_compute_pass.cpp
@@ -41,80 +41,92 @@ constexpr u32 ASTC_BINDING_SWIZZLE_BUFFER = 2;
41constexpr u32 ASTC_BINDING_OUTPUT_IMAGE = 3; 41constexpr u32 ASTC_BINDING_OUTPUT_IMAGE = 3;
42constexpr size_t ASTC_NUM_BINDINGS = 4; 42constexpr size_t ASTC_NUM_BINDINGS = 4;
43 43
44VkPushConstantRange BuildComputePushConstantRange(std::size_t size) { 44template <size_t size>
45 return { 45inline constexpr VkPushConstantRange COMPUTE_PUSH_CONSTANT_RANGE{
46 .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT, 46 .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
47 .offset = 0, 47 .offset = 0,
48 .size = static_cast<u32>(size), 48 .size = static_cast<u32>(size),
49 }; 49};
50}
51
52std::array<VkDescriptorSetLayoutBinding, 2> BuildInputOutputDescriptorSetBindings() {
53 return {{
54 {
55 .binding = 0,
56 .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
57 .descriptorCount = 1,
58 .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
59 .pImmutableSamplers = nullptr,
60 },
61 {
62 .binding = 1,
63 .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
64 .descriptorCount = 1,
65 .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
66 .pImmutableSamplers = nullptr,
67 },
68 }};
69}
70 50
71std::array<VkDescriptorSetLayoutBinding, ASTC_NUM_BINDINGS> BuildASTCDescriptorSetBindings() { 51constexpr std::array<VkDescriptorSetLayoutBinding, 2> INPUT_OUTPUT_DESCRIPTOR_SET_BINDINGS{{
72 return {{ 52 {
73 { 53 .binding = 0,
74 .binding = ASTC_BINDING_INPUT_BUFFER, 54 .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
75 .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 55 .descriptorCount = 1,
76 .descriptorCount = 1, 56 .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
77 .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT, 57 .pImmutableSamplers = nullptr,
78 .pImmutableSamplers = nullptr, 58 },
79 }, 59 {
80 { 60 .binding = 1,
81 .binding = ASTC_BINDING_ENC_BUFFER, 61 .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
82 .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 62 .descriptorCount = 1,
83 .descriptorCount = 1, 63 .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
84 .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT, 64 .pImmutableSamplers = nullptr,
85 .pImmutableSamplers = nullptr, 65 },
86 }, 66}};
87 { 67
88 .binding = ASTC_BINDING_SWIZZLE_BUFFER, 68constexpr DescriptorBankInfo INPUT_OUTPUT_BANK_INFO{
89 .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 69 .uniform_buffers = 0,
90 .descriptorCount = 1, 70 .storage_buffers = 2,
91 .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT, 71 .texture_buffers = 0,
92 .pImmutableSamplers = nullptr, 72 .image_buffers = 0,
93 }, 73 .textures = 0,
94 { 74 .images = 0,
95 .binding = ASTC_BINDING_OUTPUT_IMAGE, 75 .score = 2,
96 .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 76};
97 .descriptorCount = 1,
98 .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
99 .pImmutableSamplers = nullptr,
100 },
101 }};
102}
103 77
104VkDescriptorUpdateTemplateEntryKHR BuildInputOutputDescriptorUpdateTemplate() { 78constexpr std::array<VkDescriptorSetLayoutBinding, 4> ASTC_DESCRIPTOR_SET_BINDINGS{{
105 return { 79 {
106 .dstBinding = 0, 80 .binding = ASTC_BINDING_INPUT_BUFFER,
107 .dstArrayElement = 0,
108 .descriptorCount = 2,
109 .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 81 .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
110 .offset = 0, 82 .descriptorCount = 1,
111 .stride = sizeof(DescriptorUpdateEntry), 83 .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
112 }; 84 .pImmutableSamplers = nullptr,
113} 85 },
86 {
87 .binding = ASTC_BINDING_ENC_BUFFER,
88 .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
89 .descriptorCount = 1,
90 .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
91 .pImmutableSamplers = nullptr,
92 },
93 {
94 .binding = ASTC_BINDING_SWIZZLE_BUFFER,
95 .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
96 .descriptorCount = 1,
97 .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
98 .pImmutableSamplers = nullptr,
99 },
100 {
101 .binding = ASTC_BINDING_OUTPUT_IMAGE,
102 .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
103 .descriptorCount = 1,
104 .stageFlags = VK_SHADER_STAGE_COMPUTE_BIT,
105 .pImmutableSamplers = nullptr,
106 },
107}};
108
109constexpr DescriptorBankInfo ASTC_BANK_INFO{
110 .uniform_buffers = 0,
111 .storage_buffers = 3,
112 .texture_buffers = 0,
113 .image_buffers = 0,
114 .textures = 0,
115 .images = 1,
116 .score = 4,
117};
118
119constexpr VkDescriptorUpdateTemplateEntryKHR INPUT_OUTPUT_DESCRIPTOR_UPDATE_TEMPLATE{
120 .dstBinding = 0,
121 .dstArrayElement = 0,
122 .descriptorCount = 2,
123 .descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,
124 .offset = 0,
125 .stride = sizeof(DescriptorUpdateEntry),
126};
114 127
115std::array<VkDescriptorUpdateTemplateEntryKHR, ASTC_NUM_BINDINGS> 128constexpr std::array<VkDescriptorUpdateTemplateEntryKHR, ASTC_NUM_BINDINGS>
116BuildASTCPassDescriptorUpdateTemplateEntry() { 129 ASTC_PASS_DESCRIPTOR_UPDATE_TEMPLATE_ENTRY{{
117 return {{
118 { 130 {
119 .dstBinding = ASTC_BINDING_INPUT_BUFFER, 131 .dstBinding = ASTC_BINDING_INPUT_BUFFER,
120 .dstArrayElement = 0, 132 .dstArrayElement = 0,
@@ -148,7 +160,6 @@ BuildASTCPassDescriptorUpdateTemplateEntry() {
148 .stride = sizeof(DescriptorUpdateEntry), 160 .stride = sizeof(DescriptorUpdateEntry),
149 }, 161 },
150 }}; 162 }};
151}
152 163
153struct AstcPushConstants { 164struct AstcPushConstants {
154 std::array<u32, 2> blocks_dims; 165 std::array<u32, 2> blocks_dims;
@@ -159,14 +170,13 @@ struct AstcPushConstants {
159 u32 block_height; 170 u32 block_height;
160 u32 block_height_mask; 171 u32 block_height_mask;
161}; 172};
162
163} // Anonymous namespace 173} // Anonymous namespace
164 174
165VKComputePass::VKComputePass(const Device& device, VKDescriptorPool& descriptor_pool, 175ComputePass::ComputePass(const Device& device, DescriptorPool& descriptor_pool,
166 vk::Span<VkDescriptorSetLayoutBinding> bindings, 176 vk::Span<VkDescriptorSetLayoutBinding> bindings,
167 vk::Span<VkDescriptorUpdateTemplateEntryKHR> templates, 177 vk::Span<VkDescriptorUpdateTemplateEntryKHR> templates,
168 vk::Span<VkPushConstantRange> push_constants, 178 const DescriptorBankInfo& bank_info,
169 std::span<const u32> code) { 179 vk::Span<VkPushConstantRange> push_constants, std::span<const u32> code) {
170 descriptor_set_layout = device.GetLogical().CreateDescriptorSetLayout({ 180 descriptor_set_layout = device.GetLogical().CreateDescriptorSetLayout({
171 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, 181 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
172 .pNext = nullptr, 182 .pNext = nullptr,
@@ -196,8 +206,7 @@ VKComputePass::VKComputePass(const Device& device, VKDescriptorPool& descriptor_
196 .pipelineLayout = *layout, 206 .pipelineLayout = *layout,
197 .set = 0, 207 .set = 0,
198 }); 208 });
199 209 descriptor_allocator = descriptor_pool.Allocator(*descriptor_set_layout, bank_info);
200 descriptor_allocator.emplace(descriptor_pool, *descriptor_set_layout);
201 } 210 }
202 module = device.GetLogical().CreateShaderModule({ 211 module = device.GetLogical().CreateShaderModule({
203 .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO, 212 .sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO,
@@ -226,23 +235,23 @@ VKComputePass::VKComputePass(const Device& device, VKDescriptorPool& descriptor_
226 }); 235 });
227} 236}
228 237
229VKComputePass::~VKComputePass() = default; 238ComputePass::~ComputePass() = default;
230 239
231VkDescriptorSet VKComputePass::CommitDescriptorSet( 240VkDescriptorSet ComputePass::CommitDescriptorSet(VKUpdateDescriptorQueue& update_descriptor_queue) {
232 VKUpdateDescriptorQueue& update_descriptor_queue) {
233 if (!descriptor_template) { 241 if (!descriptor_template) {
234 return nullptr; 242 return nullptr;
235 } 243 }
236 const VkDescriptorSet set = descriptor_allocator->Commit(); 244 const VkDescriptorSet set = descriptor_allocator.Commit();
237 update_descriptor_queue.Send(descriptor_template.address(), set); 245 update_descriptor_queue.Send(descriptor_template.address(), set);
238 return set; 246 return set;
239} 247}
240 248
241Uint8Pass::Uint8Pass(const Device& device, VKScheduler& scheduler_, 249Uint8Pass::Uint8Pass(const Device& device, VKScheduler& scheduler_, DescriptorPool& descriptor_pool,
242 VKDescriptorPool& descriptor_pool, StagingBufferPool& staging_buffer_pool_, 250 StagingBufferPool& staging_buffer_pool_,
243 VKUpdateDescriptorQueue& update_descriptor_queue_) 251 VKUpdateDescriptorQueue& update_descriptor_queue_)
244 : VKComputePass(device, descriptor_pool, BuildInputOutputDescriptorSetBindings(), 252 : ComputePass(device, descriptor_pool, INPUT_OUTPUT_DESCRIPTOR_SET_BINDINGS,
245 BuildInputOutputDescriptorUpdateTemplate(), {}, VULKAN_UINT8_COMP_SPV), 253 INPUT_OUTPUT_DESCRIPTOR_UPDATE_TEMPLATE, INPUT_OUTPUT_BANK_INFO, {},
254 VULKAN_UINT8_COMP_SPV),
246 scheduler{scheduler_}, staging_buffer_pool{staging_buffer_pool_}, 255 scheduler{scheduler_}, staging_buffer_pool{staging_buffer_pool_},
247 update_descriptor_queue{update_descriptor_queue_} {} 256 update_descriptor_queue{update_descriptor_queue_} {}
248 257
@@ -277,12 +286,12 @@ std::pair<VkBuffer, VkDeviceSize> Uint8Pass::Assemble(u32 num_vertices, VkBuffer
277} 286}
278 287
279QuadIndexedPass::QuadIndexedPass(const Device& device_, VKScheduler& scheduler_, 288QuadIndexedPass::QuadIndexedPass(const Device& device_, VKScheduler& scheduler_,
280 VKDescriptorPool& descriptor_pool_, 289 DescriptorPool& descriptor_pool_,
281 StagingBufferPool& staging_buffer_pool_, 290 StagingBufferPool& staging_buffer_pool_,
282 VKUpdateDescriptorQueue& update_descriptor_queue_) 291 VKUpdateDescriptorQueue& update_descriptor_queue_)
283 : VKComputePass(device_, descriptor_pool_, BuildInputOutputDescriptorSetBindings(), 292 : ComputePass(device_, descriptor_pool_, INPUT_OUTPUT_DESCRIPTOR_SET_BINDINGS,
284 BuildInputOutputDescriptorUpdateTemplate(), 293 INPUT_OUTPUT_DESCRIPTOR_UPDATE_TEMPLATE, INPUT_OUTPUT_BANK_INFO,
285 BuildComputePushConstantRange(sizeof(u32) * 2), VULKAN_QUAD_INDEXED_COMP_SPV), 294 COMPUTE_PUSH_CONSTANT_RANGE<sizeof(u32) * 2>, VULKAN_QUAD_INDEXED_COMP_SPV),
286 scheduler{scheduler_}, staging_buffer_pool{staging_buffer_pool_}, 295 scheduler{scheduler_}, staging_buffer_pool{staging_buffer_pool_},
287 update_descriptor_queue{update_descriptor_queue_} {} 296 update_descriptor_queue{update_descriptor_queue_} {}
288 297
@@ -337,14 +346,13 @@ std::pair<VkBuffer, VkDeviceSize> QuadIndexedPass::Assemble(
337} 346}
338 347
339ASTCDecoderPass::ASTCDecoderPass(const Device& device_, VKScheduler& scheduler_, 348ASTCDecoderPass::ASTCDecoderPass(const Device& device_, VKScheduler& scheduler_,
340 VKDescriptorPool& descriptor_pool_, 349 DescriptorPool& descriptor_pool_,
341 StagingBufferPool& staging_buffer_pool_, 350 StagingBufferPool& staging_buffer_pool_,
342 VKUpdateDescriptorQueue& update_descriptor_queue_, 351 VKUpdateDescriptorQueue& update_descriptor_queue_,
343 MemoryAllocator& memory_allocator_) 352 MemoryAllocator& memory_allocator_)
344 : VKComputePass(device_, descriptor_pool_, BuildASTCDescriptorSetBindings(), 353 : ComputePass(device_, descriptor_pool_, ASTC_DESCRIPTOR_SET_BINDINGS,
345 BuildASTCPassDescriptorUpdateTemplateEntry(), 354 ASTC_PASS_DESCRIPTOR_UPDATE_TEMPLATE_ENTRY, ASTC_BANK_INFO,
346 BuildComputePushConstantRange(sizeof(AstcPushConstants)), 355 COMPUTE_PUSH_CONSTANT_RANGE<sizeof(AstcPushConstants)>, ASTC_DECODER_COMP_SPV),
347 ASTC_DECODER_COMP_SPV),
348 device{device_}, scheduler{scheduler_}, staging_buffer_pool{staging_buffer_pool_}, 356 device{device_}, scheduler{scheduler_}, staging_buffer_pool{staging_buffer_pool_},
349 update_descriptor_queue{update_descriptor_queue_}, memory_allocator{memory_allocator_} {} 357 update_descriptor_queue{update_descriptor_queue_}, memory_allocator{memory_allocator_} {}
350 358
diff --git a/src/video_core/renderer_vulkan/vk_compute_pass.h b/src/video_core/renderer_vulkan/vk_compute_pass.h
index 5ea187c30..54c1ac4cb 100644
--- a/src/video_core/renderer_vulkan/vk_compute_pass.h
+++ b/src/video_core/renderer_vulkan/vk_compute_pass.h
@@ -4,7 +4,6 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <optional>
8#include <span> 7#include <span>
9#include <utility> 8#include <utility>
10 9
@@ -27,13 +26,14 @@ class VKUpdateDescriptorQueue;
27class Image; 26class Image;
28struct StagingBufferRef; 27struct StagingBufferRef;
29 28
30class VKComputePass { 29class ComputePass {
31public: 30public:
32 explicit VKComputePass(const Device& device, VKDescriptorPool& descriptor_pool, 31 explicit ComputePass(const Device& device, DescriptorPool& descriptor_pool,
33 vk::Span<VkDescriptorSetLayoutBinding> bindings, 32 vk::Span<VkDescriptorSetLayoutBinding> bindings,
34 vk::Span<VkDescriptorUpdateTemplateEntryKHR> templates, 33 vk::Span<VkDescriptorUpdateTemplateEntryKHR> templates,
35 vk::Span<VkPushConstantRange> push_constants, std::span<const u32> code); 34 const DescriptorBankInfo& bank_info,
36 ~VKComputePass(); 35 vk::Span<VkPushConstantRange> push_constants, std::span<const u32> code);
36 ~ComputePass();
37 37
38protected: 38protected:
39 VkDescriptorSet CommitDescriptorSet(VKUpdateDescriptorQueue& update_descriptor_queue); 39 VkDescriptorSet CommitDescriptorSet(VKUpdateDescriptorQueue& update_descriptor_queue);
@@ -44,14 +44,14 @@ protected:
44 44
45private: 45private:
46 vk::DescriptorSetLayout descriptor_set_layout; 46 vk::DescriptorSetLayout descriptor_set_layout;
47 std::optional<DescriptorAllocator> descriptor_allocator; 47 DescriptorAllocator descriptor_allocator;
48 vk::ShaderModule module; 48 vk::ShaderModule module;
49}; 49};
50 50
51class Uint8Pass final : public VKComputePass { 51class Uint8Pass final : public ComputePass {
52public: 52public:
53 explicit Uint8Pass(const Device& device_, VKScheduler& scheduler_, 53 explicit Uint8Pass(const Device& device_, VKScheduler& scheduler_,
54 VKDescriptorPool& descriptor_pool_, StagingBufferPool& staging_buffer_pool_, 54 DescriptorPool& descriptor_pool_, StagingBufferPool& staging_buffer_pool_,
55 VKUpdateDescriptorQueue& update_descriptor_queue_); 55 VKUpdateDescriptorQueue& update_descriptor_queue_);
56 ~Uint8Pass(); 56 ~Uint8Pass();
57 57
@@ -66,10 +66,10 @@ private:
66 VKUpdateDescriptorQueue& update_descriptor_queue; 66 VKUpdateDescriptorQueue& update_descriptor_queue;
67}; 67};
68 68
69class QuadIndexedPass final : public VKComputePass { 69class QuadIndexedPass final : public ComputePass {
70public: 70public:
71 explicit QuadIndexedPass(const Device& device_, VKScheduler& scheduler_, 71 explicit QuadIndexedPass(const Device& device_, VKScheduler& scheduler_,
72 VKDescriptorPool& descriptor_pool_, 72 DescriptorPool& descriptor_pool_,
73 StagingBufferPool& staging_buffer_pool_, 73 StagingBufferPool& staging_buffer_pool_,
74 VKUpdateDescriptorQueue& update_descriptor_queue_); 74 VKUpdateDescriptorQueue& update_descriptor_queue_);
75 ~QuadIndexedPass(); 75 ~QuadIndexedPass();
@@ -84,10 +84,10 @@ private:
84 VKUpdateDescriptorQueue& update_descriptor_queue; 84 VKUpdateDescriptorQueue& update_descriptor_queue;
85}; 85};
86 86
87class ASTCDecoderPass final : public VKComputePass { 87class ASTCDecoderPass final : public ComputePass {
88public: 88public:
89 explicit ASTCDecoderPass(const Device& device_, VKScheduler& scheduler_, 89 explicit ASTCDecoderPass(const Device& device_, VKScheduler& scheduler_,
90 VKDescriptorPool& descriptor_pool_, 90 DescriptorPool& descriptor_pool_,
91 StagingBufferPool& staging_buffer_pool_, 91 StagingBufferPool& staging_buffer_pool_,
92 VKUpdateDescriptorQueue& update_descriptor_queue_, 92 VKUpdateDescriptorQueue& update_descriptor_queue_,
93 MemoryAllocator& memory_allocator_); 93 MemoryAllocator& memory_allocator_);
diff --git a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp
index 990ead575..54a57c358 100644
--- a/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp
+++ b/src/video_core/renderer_vulkan/vk_compute_pipeline.cpp
@@ -18,7 +18,7 @@
18 18
19namespace Vulkan { 19namespace Vulkan {
20 20
21ComputePipeline::ComputePipeline(const Device& device, VKDescriptorPool& descriptor_pool, 21ComputePipeline::ComputePipeline(const Device& device, DescriptorPool& descriptor_pool,
22 VKUpdateDescriptorQueue& update_descriptor_queue_, 22 VKUpdateDescriptorQueue& update_descriptor_queue_,
23 Common::ThreadWorker* thread_worker, const Shader::Info& info_, 23 Common::ThreadWorker* thread_worker, const Shader::Info& info_,
24 vk::ShaderModule spv_module_) 24 vk::ShaderModule spv_module_)
@@ -30,7 +30,7 @@ ComputePipeline::ComputePipeline(const Device& device, VKDescriptorPool& descrip
30 descriptor_set_layout = builder.CreateDescriptorSetLayout(); 30 descriptor_set_layout = builder.CreateDescriptorSetLayout();
31 pipeline_layout = builder.CreatePipelineLayout(*descriptor_set_layout); 31 pipeline_layout = builder.CreatePipelineLayout(*descriptor_set_layout);
32 descriptor_update_template = builder.CreateTemplate(*descriptor_set_layout, *pipeline_layout); 32 descriptor_update_template = builder.CreateTemplate(*descriptor_set_layout, *pipeline_layout);
33 descriptor_allocator = DescriptorAllocator(descriptor_pool, *descriptor_set_layout); 33 descriptor_allocator = descriptor_pool.Allocator(*descriptor_set_layout, info);
34 34
35 auto func{[this, &device] { 35 auto func{[this, &device] {
36 const VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT subgroup_size_ci{ 36 const VkPipelineShaderStageRequiredSubgroupSizeCreateInfoEXT subgroup_size_ci{
diff --git a/src/video_core/renderer_vulkan/vk_compute_pipeline.h b/src/video_core/renderer_vulkan/vk_compute_pipeline.h
index 8efdc2926..0d4cd37be 100644
--- a/src/video_core/renderer_vulkan/vk_compute_pipeline.h
+++ b/src/video_core/renderer_vulkan/vk_compute_pipeline.h
@@ -25,7 +25,7 @@ class VKScheduler;
25 25
26class ComputePipeline { 26class ComputePipeline {
27public: 27public:
28 explicit ComputePipeline(const Device& device, VKDescriptorPool& descriptor_pool, 28 explicit ComputePipeline(const Device& device, DescriptorPool& descriptor_pool,
29 VKUpdateDescriptorQueue& update_descriptor_queue, 29 VKUpdateDescriptorQueue& update_descriptor_queue,
30 Common::ThreadWorker* thread_worker, const Shader::Info& info, 30 Common::ThreadWorker* thread_worker, const Shader::Info& info,
31 vk::ShaderModule spv_module); 31 vk::ShaderModule spv_module);
diff --git a/src/video_core/renderer_vulkan/vk_descriptor_pool.cpp b/src/video_core/renderer_vulkan/vk_descriptor_pool.cpp
index 3bea1ff44..8e77e4796 100644
--- a/src/video_core/renderer_vulkan/vk_descriptor_pool.cpp
+++ b/src/video_core/renderer_vulkan/vk_descriptor_pool.cpp
@@ -2,6 +2,8 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <mutex>
6#include <span>
5#include <vector> 7#include <vector>
6 8
7#include "common/common_types.h" 9#include "common/common_types.h"
@@ -13,77 +15,149 @@
13 15
14namespace Vulkan { 16namespace Vulkan {
15 17
16// Prefer small grow rates to avoid saturating the descriptor pool with barely used pipelines. 18// Prefer small grow rates to avoid saturating the descriptor pool with barely used pipelines
17constexpr std::size_t SETS_GROW_RATE = 0x20; 19constexpr size_t SETS_GROW_RATE = 16;
20constexpr s32 SCORE_THRESHOLD = 3;
21constexpr u32 SETS_PER_POOL = 64;
18 22
19DescriptorAllocator::DescriptorAllocator(VKDescriptorPool& descriptor_pool_, 23struct DescriptorBank {
20 VkDescriptorSetLayout layout_) 24 DescriptorBankInfo info;
21 : ResourcePool(descriptor_pool_.master_semaphore, SETS_GROW_RATE), 25 std::vector<vk::DescriptorPool> pools;
22 descriptor_pool{&descriptor_pool_}, layout{layout_} {} 26};
23 27
24VkDescriptorSet DescriptorAllocator::Commit() { 28bool DescriptorBankInfo::IsSuperset(const DescriptorBankInfo& subset) const noexcept {
25 const std::size_t index = CommitResource(); 29 return uniform_buffers >= subset.uniform_buffers && storage_buffers >= subset.storage_buffers &&
26 return descriptors_allocations[index / SETS_GROW_RATE][index % SETS_GROW_RATE]; 30 texture_buffers >= subset.texture_buffers && image_buffers >= subset.image_buffers &&
31 textures >= subset.textures && images >= subset.image_buffers;
27} 32}
28 33
29void DescriptorAllocator::Allocate(std::size_t begin, std::size_t end) { 34template <typename Descriptors>
30 descriptors_allocations.push_back(descriptor_pool->AllocateDescriptors(layout, end - begin)); 35static u32 Accumulate(const Descriptors& descriptors) {
36 u32 count = 0;
37 for (const auto& descriptor : descriptors) {
38 count += descriptor.count;
39 }
40 return count;
31} 41}
32 42
33VKDescriptorPool::VKDescriptorPool(const Device& device_, VKScheduler& scheduler) 43static DescriptorBankInfo MakeBankInfo(std::span<const Shader::Info> infos) {
34 : device{device_}, master_semaphore{scheduler.GetMasterSemaphore()}, active_pool{ 44 DescriptorBankInfo bank;
35 AllocateNewPool()} {} 45 for (const Shader::Info& info : infos) {
36 46 bank.uniform_buffers += Accumulate(info.constant_buffer_descriptors);
37VKDescriptorPool::~VKDescriptorPool() = default; 47 bank.storage_buffers += Accumulate(info.storage_buffers_descriptors);
38 48 bank.texture_buffers += Accumulate(info.texture_buffer_descriptors);
39vk::DescriptorPool* VKDescriptorPool::AllocateNewPool() { 49 bank.image_buffers += Accumulate(info.image_buffer_descriptors);
40 static constexpr u32 num_sets = 0x20000; 50 bank.textures += Accumulate(info.texture_descriptors);
41 static constexpr VkDescriptorPoolSize pool_sizes[] = { 51 bank.images += Accumulate(info.image_descriptors);
42 {VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, num_sets * 90}, 52 }
43 {VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, num_sets * 60}, 53 bank.score = bank.uniform_buffers + bank.storage_buffers + bank.texture_buffers +
44 {VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, num_sets * 64}, 54 bank.image_buffers + bank.textures + bank.images;
45 {VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, num_sets * 64}, 55 return bank;
46 {VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, num_sets * 64}, 56}
47 {VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, num_sets * 40},
48 };
49 57
50 const VkDescriptorPoolCreateInfo ci{ 58static void AllocatePool(const Device& device, DescriptorBank& bank) {
59 std::array<VkDescriptorPoolSize, 6> pool_sizes;
60 size_t pool_cursor{};
61 const auto add = [&](VkDescriptorType type, u32 count) {
62 if (count > 0) {
63 pool_sizes[pool_cursor++] = {
64 .type = type,
65 .descriptorCount = count * SETS_PER_POOL,
66 };
67 }
68 };
69 const auto& info{bank.info};
70 add(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, info.uniform_buffers);
71 add(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, info.storage_buffers);
72 add(VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, info.texture_buffers);
73 add(VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, info.image_buffers);
74 add(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, info.textures);
75 add(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, info.images);
76 bank.pools.push_back(device.GetLogical().CreateDescriptorPool({
51 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, 77 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
52 .pNext = nullptr, 78 .pNext = nullptr,
53 .flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 79 .flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
54 .maxSets = num_sets, 80 .maxSets = SETS_PER_POOL,
55 .poolSizeCount = static_cast<u32>(std::size(pool_sizes)), 81 .poolSizeCount = static_cast<u32>(pool_cursor),
56 .pPoolSizes = std::data(pool_sizes), 82 .pPoolSizes = std::data(pool_sizes),
57 }; 83 }));
58 return &pools.emplace_back(device.GetLogical().CreateDescriptorPool(ci));
59} 84}
60 85
61vk::DescriptorSets VKDescriptorPool::AllocateDescriptors(VkDescriptorSetLayout layout, 86DescriptorAllocator::DescriptorAllocator(const Device& device_, MasterSemaphore& master_semaphore_,
62 std::size_t count) { 87 DescriptorBank& bank_, VkDescriptorSetLayout layout_)
63 const std::vector layout_copies(count, layout); 88 : ResourcePool(master_semaphore_, SETS_GROW_RATE), device{&device_}, bank{&bank_},
64 VkDescriptorSetAllocateInfo ai{ 89 layout{layout_} {}
90
91VkDescriptorSet DescriptorAllocator::Commit() {
92 const size_t index = CommitResource();
93 return sets[index / SETS_GROW_RATE][index % SETS_GROW_RATE];
94}
95
96void DescriptorAllocator::Allocate(size_t begin, size_t end) {
97 sets.push_back(AllocateDescriptors(end - begin));
98}
99
100vk::DescriptorSets DescriptorAllocator::AllocateDescriptors(size_t count) {
101 const std::vector<VkDescriptorSetLayout> layouts(count, layout);
102 VkDescriptorSetAllocateInfo allocate_info{
65 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, 103 .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
66 .pNext = nullptr, 104 .pNext = nullptr,
67 .descriptorPool = **active_pool, 105 .descriptorPool = *bank->pools.back(),
68 .descriptorSetCount = static_cast<u32>(count), 106 .descriptorSetCount = static_cast<u32>(count),
69 .pSetLayouts = layout_copies.data(), 107 .pSetLayouts = layouts.data(),
70 }; 108 };
71 109 vk::DescriptorSets new_sets = bank->pools.back().Allocate(allocate_info);
72 vk::DescriptorSets sets = active_pool->Allocate(ai); 110 if (!new_sets.IsOutOfPoolMemory()) {
73 if (!sets.IsOutOfPoolMemory()) { 111 return new_sets;
74 return sets;
75 } 112 }
76
77 // Our current pool is out of memory. Allocate a new one and retry 113 // Our current pool is out of memory. Allocate a new one and retry
78 active_pool = AllocateNewPool(); 114 AllocatePool(*device, *bank);
79 ai.descriptorPool = **active_pool; 115 allocate_info.descriptorPool = *bank->pools.back();
80 sets = active_pool->Allocate(ai); 116 new_sets = bank->pools.back().Allocate(allocate_info);
81 if (!sets.IsOutOfPoolMemory()) { 117 if (!new_sets.IsOutOfPoolMemory()) {
82 return sets; 118 return new_sets;
83 } 119 }
84
85 // After allocating a new pool, we are out of memory again. We can't handle this from here. 120 // After allocating a new pool, we are out of memory again. We can't handle this from here.
86 throw vk::Exception(VK_ERROR_OUT_OF_POOL_MEMORY); 121 throw vk::Exception(VK_ERROR_OUT_OF_POOL_MEMORY);
87} 122}
88 123
124DescriptorPool::DescriptorPool(const Device& device_, VKScheduler& scheduler)
125 : device{device_}, master_semaphore{scheduler.GetMasterSemaphore()} {}
126
127DescriptorPool::~DescriptorPool() = default;
128
129DescriptorAllocator DescriptorPool::Allocator(VkDescriptorSetLayout layout,
130 std::span<const Shader::Info> infos) {
131 return Allocator(layout, MakeBankInfo(infos));
132}
133
134DescriptorAllocator DescriptorPool::Allocator(VkDescriptorSetLayout layout,
135 const Shader::Info& info) {
136 return Allocator(layout, MakeBankInfo(std::array{info}));
137}
138
139DescriptorAllocator DescriptorPool::Allocator(VkDescriptorSetLayout layout,
140 const DescriptorBankInfo& info) {
141 return DescriptorAllocator(device, master_semaphore, Bank(info), layout);
142}
143
144DescriptorBank& DescriptorPool::Bank(const DescriptorBankInfo& reqs) {
145 std::shared_lock read_lock{banks_mutex};
146 const auto it = std::ranges::find_if(bank_infos, [&reqs](const DescriptorBankInfo& bank) {
147 return std::abs(bank.score - reqs.score) < SCORE_THRESHOLD && bank.IsSuperset(reqs);
148 });
149 if (it != bank_infos.end()) {
150 return *banks[std::distance(bank_infos.begin(), it)].get();
151 }
152 read_lock.unlock();
153
154 std::unique_lock write_lock{banks_mutex};
155 bank_infos.push_back(reqs);
156
157 auto& bank = *banks.emplace_back(std::make_unique<DescriptorBank>());
158 bank.info = reqs;
159 AllocatePool(device, bank);
160 return bank;
161}
162
89} // namespace Vulkan 163} // namespace Vulkan
diff --git a/src/video_core/renderer_vulkan/vk_descriptor_pool.h b/src/video_core/renderer_vulkan/vk_descriptor_pool.h
index 2501f9967..59466aac5 100644
--- a/src/video_core/renderer_vulkan/vk_descriptor_pool.h
+++ b/src/video_core/renderer_vulkan/vk_descriptor_pool.h
@@ -4,21 +4,38 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <shared_mutex>
8#include <span>
7#include <vector> 9#include <vector>
8 10
11#include "shader_recompiler/shader_info.h"
9#include "video_core/renderer_vulkan/vk_resource_pool.h" 12#include "video_core/renderer_vulkan/vk_resource_pool.h"
10#include "video_core/vulkan_common/vulkan_wrapper.h" 13#include "video_core/vulkan_common/vulkan_wrapper.h"
11 14
12namespace Vulkan { 15namespace Vulkan {
13 16
14class Device; 17class Device;
15class VKDescriptorPool;
16class VKScheduler; 18class VKScheduler;
17 19
20struct DescriptorBank;
21
22struct DescriptorBankInfo {
23 [[nodiscard]] bool IsSuperset(const DescriptorBankInfo& subset) const noexcept;
24
25 u32 uniform_buffers{}; ///< Number of uniform buffer descriptors
26 u32 storage_buffers{}; ///< Number of storage buffer descriptors
27 u32 texture_buffers{}; ///< Number of texture buffer descriptors
28 u32 image_buffers{}; ///< Number of image buffer descriptors
29 u32 textures{}; ///< Number of texture descriptors
30 u32 images{}; ///< Number of image descriptors
31 s32 score{}; ///< Number of descriptors in total
32};
33
18class DescriptorAllocator final : public ResourcePool { 34class DescriptorAllocator final : public ResourcePool {
35 friend class DescriptorPool;
36
19public: 37public:
20 explicit DescriptorAllocator() = default; 38 explicit DescriptorAllocator() = default;
21 explicit DescriptorAllocator(VKDescriptorPool& descriptor_pool, VkDescriptorSetLayout layout);
22 ~DescriptorAllocator() override = default; 39 ~DescriptorAllocator() override = default;
23 40
24 DescriptorAllocator& operator=(DescriptorAllocator&&) noexcept = default; 41 DescriptorAllocator& operator=(DescriptorAllocator&&) noexcept = default;
@@ -29,36 +46,43 @@ public:
29 46
30 VkDescriptorSet Commit(); 47 VkDescriptorSet Commit();
31 48
32protected:
33 void Allocate(std::size_t begin, std::size_t end) override;
34
35private: 49private:
36 VKDescriptorPool* descriptor_pool{}; 50 explicit DescriptorAllocator(const Device& device_, MasterSemaphore& master_semaphore_,
51 DescriptorBank& bank_, VkDescriptorSetLayout layout_);
52
53 void Allocate(size_t begin, size_t end) override;
54
55 vk::DescriptorSets AllocateDescriptors(size_t count);
56
57 const Device* device{};
58 DescriptorBank* bank{};
37 VkDescriptorSetLayout layout{}; 59 VkDescriptorSetLayout layout{};
38 60
39 std::vector<vk::DescriptorSets> descriptors_allocations; 61 std::vector<vk::DescriptorSets> sets;
40}; 62};
41 63
42class VKDescriptorPool final { 64class DescriptorPool {
43 friend DescriptorAllocator;
44
45public: 65public:
46 explicit VKDescriptorPool(const Device& device, VKScheduler& scheduler); 66 explicit DescriptorPool(const Device& device, VKScheduler& scheduler);
47 ~VKDescriptorPool(); 67 ~DescriptorPool();
48 68
49 VKDescriptorPool(const VKDescriptorPool&) = delete; 69 DescriptorPool& operator=(const DescriptorPool&) = delete;
50 VKDescriptorPool& operator=(const VKDescriptorPool&) = delete; 70 DescriptorPool(const DescriptorPool&) = delete;
51 71
52private: 72 DescriptorAllocator Allocator(VkDescriptorSetLayout layout,
53 vk::DescriptorPool* AllocateNewPool(); 73 std::span<const Shader::Info> infos);
74 DescriptorAllocator Allocator(VkDescriptorSetLayout layout, const Shader::Info& info);
75 DescriptorAllocator Allocator(VkDescriptorSetLayout layout, const DescriptorBankInfo& info);
54 76
55 vk::DescriptorSets AllocateDescriptors(VkDescriptorSetLayout layout, std::size_t count); 77private:
78 DescriptorBank& Bank(const DescriptorBankInfo& reqs);
56 79
57 const Device& device; 80 const Device& device;
58 MasterSemaphore& master_semaphore; 81 MasterSemaphore& master_semaphore;
59 82
60 std::vector<vk::DescriptorPool> pools; 83 std::shared_mutex banks_mutex;
61 vk::DescriptorPool* active_pool; 84 std::vector<DescriptorBankInfo> bank_infos;
85 std::vector<std::unique_ptr<DescriptorBank>> banks;
62}; 86};
63 87
64} // namespace Vulkan \ No newline at end of file 88} // namespace Vulkan \ No newline at end of file
diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
index 674226cb7..0526c197a 100644
--- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
+++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp
@@ -205,7 +205,7 @@ ConfigureFuncPtr ConfigureFunc(const std::array<vk::ShaderModule, NUM_STAGES>& m
205GraphicsPipeline::GraphicsPipeline(Tegra::Engines::Maxwell3D& maxwell3d_, 205GraphicsPipeline::GraphicsPipeline(Tegra::Engines::Maxwell3D& maxwell3d_,
206 Tegra::MemoryManager& gpu_memory_, VKScheduler& scheduler_, 206 Tegra::MemoryManager& gpu_memory_, VKScheduler& scheduler_,
207 BufferCache& buffer_cache_, TextureCache& texture_cache_, 207 BufferCache& buffer_cache_, TextureCache& texture_cache_,
208 const Device& device, VKDescriptorPool& descriptor_pool, 208 const Device& device, DescriptorPool& descriptor_pool,
209 VKUpdateDescriptorQueue& update_descriptor_queue_, 209 VKUpdateDescriptorQueue& update_descriptor_queue_,
210 Common::ThreadWorker* worker_thread, 210 Common::ThreadWorker* worker_thread,
211 RenderPassCache& render_pass_cache, 211 RenderPassCache& render_pass_cache,
@@ -220,7 +220,7 @@ GraphicsPipeline::GraphicsPipeline(Tegra::Engines::Maxwell3D& maxwell3d_,
220 220
221 DescriptorLayoutBuilder builder{MakeBuilder(device, stage_infos)}; 221 DescriptorLayoutBuilder builder{MakeBuilder(device, stage_infos)};
222 descriptor_set_layout = builder.CreateDescriptorSetLayout(); 222 descriptor_set_layout = builder.CreateDescriptorSetLayout();
223 descriptor_allocator = DescriptorAllocator(descriptor_pool, *descriptor_set_layout); 223 descriptor_allocator = descriptor_pool.Allocator(*descriptor_set_layout, stage_infos);
224 224
225 auto func{[this, &device, &render_pass_cache, builder] { 225 auto func{[this, &device, &render_pass_cache, builder] {
226 const VkDescriptorSetLayout set_layout{*descriptor_set_layout}; 226 const VkDescriptorSetLayout set_layout{*descriptor_set_layout};
diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.h b/src/video_core/renderer_vulkan/vk_graphics_pipeline.h
index edab5703f..454fc049e 100644
--- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.h
+++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.h
@@ -67,7 +67,7 @@ public:
67 explicit GraphicsPipeline(Tegra::Engines::Maxwell3D& maxwell3d, 67 explicit GraphicsPipeline(Tegra::Engines::Maxwell3D& maxwell3d,
68 Tegra::MemoryManager& gpu_memory, VKScheduler& scheduler, 68 Tegra::MemoryManager& gpu_memory, VKScheduler& scheduler,
69 BufferCache& buffer_cache, TextureCache& texture_cache, 69 BufferCache& buffer_cache, TextureCache& texture_cache,
70 const Device& device, VKDescriptorPool& descriptor_pool, 70 const Device& device, DescriptorPool& descriptor_pool,
71 VKUpdateDescriptorQueue& update_descriptor_queue, 71 VKUpdateDescriptorQueue& update_descriptor_queue,
72 Common::ThreadWorker* worker_thread, 72 Common::ThreadWorker* worker_thread,
73 RenderPassCache& render_pass_cache, 73 RenderPassCache& render_pass_cache,
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
index 2bd870060..9d9729022 100644
--- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
+++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp
@@ -647,7 +647,7 @@ PipelineCache::PipelineCache(RasterizerVulkan& rasterizer_, Tegra::GPU& gpu_,
647 Tegra::Engines::Maxwell3D& maxwell3d_, 647 Tegra::Engines::Maxwell3D& maxwell3d_,
648 Tegra::Engines::KeplerCompute& kepler_compute_, 648 Tegra::Engines::KeplerCompute& kepler_compute_,
649 Tegra::MemoryManager& gpu_memory_, const Device& device_, 649 Tegra::MemoryManager& gpu_memory_, const Device& device_,
650 VKScheduler& scheduler_, VKDescriptorPool& descriptor_pool_, 650 VKScheduler& scheduler_, DescriptorPool& descriptor_pool_,
651 VKUpdateDescriptorQueue& update_descriptor_queue_, 651 VKUpdateDescriptorQueue& update_descriptor_queue_,
652 RenderPassCache& render_pass_cache_, BufferCache& buffer_cache_, 652 RenderPassCache& render_pass_cache_, BufferCache& buffer_cache_,
653 TextureCache& texture_cache_) 653 TextureCache& texture_cache_)
diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.h b/src/video_core/renderer_vulkan/vk_pipeline_cache.h
index ad569acc4..eec17d3fd 100644
--- a/src/video_core/renderer_vulkan/vk_pipeline_cache.h
+++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.h
@@ -75,10 +75,10 @@ namespace Vulkan {
75 75
76class ComputePipeline; 76class ComputePipeline;
77class Device; 77class Device;
78class DescriptorPool;
78class GenericEnvironment; 79class GenericEnvironment;
79class RasterizerVulkan; 80class RasterizerVulkan;
80class RenderPassCache; 81class RenderPassCache;
81class VKDescriptorPool;
82class VKScheduler; 82class VKScheduler;
83class VKUpdateDescriptorQueue; 83class VKUpdateDescriptorQueue;
84 84
@@ -105,7 +105,7 @@ public:
105 Tegra::Engines::Maxwell3D& maxwell3d, 105 Tegra::Engines::Maxwell3D& maxwell3d,
106 Tegra::Engines::KeplerCompute& kepler_compute, 106 Tegra::Engines::KeplerCompute& kepler_compute,
107 Tegra::MemoryManager& gpu_memory, const Device& device, 107 Tegra::MemoryManager& gpu_memory, const Device& device,
108 VKScheduler& scheduler, VKDescriptorPool& descriptor_pool, 108 VKScheduler& scheduler, DescriptorPool& descriptor_pool,
109 VKUpdateDescriptorQueue& update_descriptor_queue, 109 VKUpdateDescriptorQueue& update_descriptor_queue,
110 RenderPassCache& render_pass_cache, BufferCache& buffer_cache, 110 RenderPassCache& render_pass_cache, BufferCache& buffer_cache,
111 TextureCache& texture_cache); 111 TextureCache& texture_cache);
@@ -147,7 +147,7 @@ private:
147 147
148 const Device& device; 148 const Device& device;
149 VKScheduler& scheduler; 149 VKScheduler& scheduler;
150 VKDescriptorPool& descriptor_pool; 150 DescriptorPool& descriptor_pool;
151 VKUpdateDescriptorQueue& update_descriptor_queue; 151 VKUpdateDescriptorQueue& update_descriptor_queue;
152 RenderPassCache& render_pass_cache; 152 RenderPassCache& render_pass_cache;
153 BufferCache& buffer_cache; 153 BufferCache& buffer_cache;
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h
index 2f1551e65..1302bed02 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.h
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.h
@@ -147,7 +147,7 @@ private:
147 VKScheduler& scheduler; 147 VKScheduler& scheduler;
148 148
149 StagingBufferPool staging_pool; 149 StagingBufferPool staging_pool;
150 VKDescriptorPool descriptor_pool; 150 DescriptorPool descriptor_pool;
151 VKUpdateDescriptorQueue update_descriptor_queue; 151 VKUpdateDescriptorQueue update_descriptor_queue;
152 BlitImageHelper blit_image; 152 BlitImageHelper blit_image;
153 ASTCDecoderPass astc_decoder_pass; 153 ASTCDecoderPass astc_decoder_pass;