Skip to content

Commit 0c9037f

Browse files
renderer_vulkan: Rewrite descriptor management
* Switch to batched vkUpdateDescriptorSets from cached descriptor sets with templates
1 parent 4a63fc2 commit 0c9037f

36 files changed

+786
-740
lines changed

src/video_core/CMakeLists.txt

+2-2
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,8 @@ if (ENABLE_VULKAN)
160160
renderer_vulkan/vk_blit_helper.h
161161
renderer_vulkan/vk_common.cpp
162162
renderer_vulkan/vk_common.h
163-
renderer_vulkan/vk_descriptor_pool.cpp
164-
renderer_vulkan/vk_descriptor_pool.h
163+
renderer_vulkan/vk_descriptor_update_queue.cpp
164+
renderer_vulkan/vk_descriptor_update_queue.h
165165
renderer_vulkan/vk_graphics_pipeline.cpp
166166
renderer_vulkan/vk_graphics_pipeline.h
167167
renderer_vulkan/vk_master_semaphore.cpp

src/video_core/custom_textures/custom_tex_manager.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ std::vector<FileUtil::FSTEntry> CustomTexManager::GetTextures(u64 title_id) {
385385
}
386386

387387
void CustomTexManager::CreateWorkers() {
388-
const std::size_t num_workers = std::max(std::thread::hardware_concurrency(), 2U) - 1;
388+
const std::size_t num_workers = std::max(std::thread::hardware_concurrency(), 2U) >> 1;
389389
workers = std::make_unique<Common::ThreadWorker>(num_workers, "Custom textures");
390390
}
391391

src/video_core/pica/regs_texturing.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -176,15 +176,15 @@ struct TexturingRegs {
176176
INSERT_PADDING_WORDS(0x9);
177177

178178
struct FullTextureConfig {
179-
const bool enabled;
179+
const u32 enabled;
180180
const TextureConfig config;
181181
const TextureFormat format;
182182
};
183183
const std::array<FullTextureConfig, 3> GetTextures() const {
184184
return {{
185-
{static_cast<bool>(main_config.texture0_enable), texture0, texture0_format},
186-
{static_cast<bool>(main_config.texture1_enable), texture1, texture1_format},
187-
{static_cast<bool>(main_config.texture2_enable), texture2, texture2_format},
185+
{main_config.texture0_enable, texture0, texture0_format},
186+
{main_config.texture1_enable, texture1, texture1_format},
187+
{main_config.texture2_enable, texture2, texture2_format},
188188
}};
189189
}
190190

src/video_core/rasterizer_cache/rasterizer_cache.h

+37-26
Original file line numberDiff line numberDiff line change
@@ -600,14 +600,43 @@ typename T::Surface& RasterizerCache<T>::GetTextureCube(const TextureCubeConfig&
600600
auto [it, new_surface] = texture_cube_cache.try_emplace(config);
601601
TextureCube& cube = it->second;
602602

603+
const std::array addresses = {config.px, config.nx, config.py, config.ny, config.pz, config.nz};
604+
603605
if (new_surface) {
606+
Pica::Texture::TextureInfo info = {
607+
.width = config.width,
608+
.height = config.width,
609+
.format = config.format,
610+
};
611+
info.SetDefaultStride();
612+
613+
u32 res_scale = 1;
614+
for (u32 i = 0; i < addresses.size(); i++) {
615+
if (!addresses[i]) {
616+
continue;
617+
}
618+
619+
SurfaceId& face_id = cube.face_ids[i];
620+
if (!face_id) {
621+
info.physical_address = addresses[i];
622+
face_id = GetTextureSurface(info, config.levels - 1);
623+
Surface& surface = slot_surfaces[face_id];
624+
ASSERT_MSG(
625+
surface.levels >= config.levels,
626+
"Texture cube face levels are not enough to validate the levels requested");
627+
surface.flags |= SurfaceFlagBits::Tracked;
628+
}
629+
Surface& surface = slot_surfaces[face_id];
630+
res_scale = std::max(surface.res_scale, res_scale);
631+
}
632+
604633
SurfaceParams cube_params = {
605634
.addr = config.px,
606635
.width = config.width,
607636
.height = config.width,
608637
.stride = config.width,
609638
.levels = config.levels,
610-
.res_scale = filter != Settings::TextureFilter::None ? resolution_scale_factor : 1,
639+
.res_scale = res_scale,
611640
.texture_type = TextureType::CubeMap,
612641
.pixel_format = PixelFormatFromTextureFormat(config.format),
613642
.type = SurfaceType::Texture,
@@ -616,48 +645,30 @@ typename T::Surface& RasterizerCache<T>::GetTextureCube(const TextureCubeConfig&
616645
cube.surface_id = CreateSurface(cube_params);
617646
}
618647

619-
const u32 scaled_size = slot_surfaces[cube.surface_id].GetScaledWidth();
620-
const std::array addresses = {config.px, config.nx, config.py, config.ny, config.pz, config.nz};
621-
622-
Pica::Texture::TextureInfo info = {
623-
.width = config.width,
624-
.height = config.width,
625-
.format = config.format,
626-
};
627-
info.SetDefaultStride();
628-
648+
Surface& cube_surface = slot_surfaces[cube.surface_id];
629649
for (u32 i = 0; i < addresses.size(); i++) {
630650
if (!addresses[i]) {
631651
continue;
632652
}
633-
634-
SurfaceId& face_id = cube.face_ids[i];
635-
if (!face_id) {
636-
info.physical_address = addresses[i];
637-
face_id = GetTextureSurface(info, config.levels - 1);
638-
ASSERT_MSG(slot_surfaces[face_id].levels >= config.levels,
639-
"Texture cube face levels are not enough to validate the levels requested");
640-
}
641-
Surface& surface = slot_surfaces[face_id];
642-
surface.flags |= SurfaceFlagBits::Tracked;
653+
Surface& surface = slot_surfaces[cube.face_ids[i]];
643654
if (cube.ticks[i] == surface.modification_tick) {
644655
continue;
645656
}
646657
cube.ticks[i] = surface.modification_tick;
647-
Surface& cube_surface = slot_surfaces[cube.surface_id];
658+
boost::container::small_vector<TextureCopy, 8> upload_copies;
648659
for (u32 level = 0; level < config.levels; level++) {
649-
const u32 width_lod = scaled_size >> level;
650-
const TextureCopy texture_copy = {
660+
const u32 width_lod = surface.GetScaledWidth() >> level;
661+
upload_copies.push_back({
651662
.src_level = level,
652663
.dst_level = level,
653664
.src_layer = 0,
654665
.dst_layer = i,
655666
.src_offset = {0, 0},
656667
.dst_offset = {0, 0},
657668
.extent = {width_lod, width_lod},
658-
};
659-
runtime.CopyTextures(surface, cube_surface, texture_copy);
669+
});
660670
}
671+
runtime.CopyTextures(surface, cube_surface, upload_copies);
661672
}
662673

663674
return slot_surfaces[cube.surface_id];

src/video_core/renderer_opengl/gl_texture_runtime.cpp

+8-5
Original file line numberDiff line numberDiff line change
@@ -260,16 +260,19 @@ void TextureRuntime::ClearTexture(Surface& surface, const VideoCore::TextureClea
260260
}
261261

262262
bool TextureRuntime::CopyTextures(Surface& source, Surface& dest,
263-
const VideoCore::TextureCopy& copy) {
263+
std::span<const VideoCore::TextureCopy> copies) {
264264
const GLenum src_textarget = source.texture_type == VideoCore::TextureType::CubeMap
265265
? GL_TEXTURE_CUBE_MAP
266266
: GL_TEXTURE_2D;
267267
const GLenum dest_textarget =
268268
dest.texture_type == VideoCore::TextureType::CubeMap ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
269-
glCopyImageSubData(source.Handle(), src_textarget, copy.src_level, copy.src_offset.x,
270-
copy.src_offset.y, copy.src_layer, dest.Handle(), dest_textarget,
271-
copy.dst_level, copy.dst_offset.x, copy.dst_offset.y, copy.dst_layer,
272-
copy.extent.width, copy.extent.height, 1);
269+
270+
for (const auto& copy : copies) {
271+
glCopyImageSubData(source.Handle(), src_textarget, copy.src_level, copy.src_offset.x,
272+
copy.src_offset.y, copy.src_layer, dest.Handle(), dest_textarget,
273+
copy.dst_level, copy.dst_offset.x, copy.dst_offset.y, copy.dst_layer,
274+
copy.extent.width, copy.extent.height, 1);
275+
}
273276
return true;
274277
}
275278

src/video_core/renderer_opengl/gl_texture_runtime.h

+6-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,12 @@ class TextureRuntime {
6565
void ClearTexture(Surface& surface, const VideoCore::TextureClear& clear);
6666

6767
/// Copies a rectangle of source to another rectange of dest
68-
bool CopyTextures(Surface& source, Surface& dest, const VideoCore::TextureCopy& copy);
68+
bool CopyTextures(Surface& source, Surface& dest,
69+
std::span<const VideoCore::TextureCopy> copies);
70+
71+
bool CopyTextures(Surface& source, Surface& dest, const VideoCore::TextureCopy& copy) {
72+
return CopyTextures(source, dest, std::array{copy});
73+
}
6974

7075
/// Blits a rectangle of source to another rectange of dest
7176
bool BlitTextures(Surface& source, Surface& dest, const VideoCore::TextureBlit& blit);

src/video_core/renderer_vulkan/renderer_vulkan.cpp

+21-23
Original file line numberDiff line numberDiff line change
@@ -54,21 +54,21 @@ RendererVulkan::RendererVulkan(Core::System& system, Pica::PicaCore& pica_,
5454
Frontend::EmuWindow& window, Frontend::EmuWindow* secondary_window)
5555
: RendererBase{system, window, secondary_window}, memory{system.Memory()}, pica{pica_},
5656
instance{system.TelemetrySession(), window, Settings::values.physical_device.GetValue()},
57-
scheduler{instance}, render_manager{instance, scheduler}, pool{instance},
58-
main_window{window, instance, scheduler},
57+
scheduler{instance}, render_manager{instance, scheduler}, main_window{window, instance,
58+
scheduler},
5959
vertex_buffer{instance, scheduler, vk::BufferUsageFlagBits::eVertexBuffer,
6060
VERTEX_BUFFER_SIZE},
61-
rasterizer{memory,
62-
pica,
63-
system.CustomTexManager(),
64-
*this,
65-
render_window,
66-
instance,
67-
scheduler,
68-
pool,
69-
render_manager,
70-
main_window.ImageCount()},
71-
present_set_provider{instance, pool, PRESENT_BINDINGS} {
61+
update_queue{instance}, rasterizer{memory,
62+
pica,
63+
system.CustomTexManager(),
64+
*this,
65+
render_window,
66+
instance,
67+
scheduler,
68+
render_manager,
69+
update_queue,
70+
main_window.ImageCount()},
71+
present_heap{instance, scheduler.GetMasterSemaphore(), PRESENT_BINDINGS, 32} {
7272
CompileShaders();
7373
BuildLayouts();
7474
BuildPipelines();
@@ -127,16 +127,14 @@ void RendererVulkan::PrepareRendertarget() {
127127

128128
void RendererVulkan::PrepareDraw(Frame* frame, const Layout::FramebufferLayout& layout) {
129129
const auto sampler = present_samplers[!Settings::values.filter_mode.GetValue()];
130-
std::transform(screen_infos.begin(), screen_infos.end(), present_textures.begin(),
131-
[&](auto& info) {
132-
return DescriptorData{vk::DescriptorImageInfo{sampler, info.image_view,
133-
vk::ImageLayout::eGeneral}};
134-
});
135-
136-
const auto descriptor_set = present_set_provider.Acquire(present_textures);
130+
const auto present_set = present_heap.Commit();
131+
for (u32 index = 0; index < screen_infos.size(); index++) {
132+
update_queue.AddImageSampler(present_set, 0, index, screen_infos[index].image_view,
133+
sampler);
134+
}
137135

138136
render_manager.EndRendering();
139-
scheduler.Record([this, layout, frame, descriptor_set, renderpass = main_window.Renderpass(),
137+
scheduler.Record([this, layout, frame, present_set, renderpass = main_window.Renderpass(),
140138
index = current_pipeline](vk::CommandBuffer cmdbuf) {
141139
const vk::Viewport viewport = {
142140
.x = 0.0f,
@@ -171,7 +169,7 @@ void RendererVulkan::PrepareDraw(Frame* frame, const Layout::FramebufferLayout&
171169

172170
cmdbuf.beginRenderPass(renderpass_begin_info, vk::SubpassContents::eInline);
173171
cmdbuf.bindPipeline(vk::PipelineBindPoint::eGraphics, present_pipelines[index]);
174-
cmdbuf.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, layout, 0, descriptor_set, {});
172+
cmdbuf.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, layout, 0, present_set, {});
175173
});
176174
}
177175

@@ -258,7 +256,7 @@ void RendererVulkan::BuildLayouts() {
258256
.size = sizeof(PresentUniformData),
259257
};
260258

261-
const auto descriptor_set_layout = present_set_provider.Layout();
259+
const auto descriptor_set_layout = present_heap.Layout();
262260
const vk::PipelineLayoutCreateInfo layout_info = {
263261
.setLayoutCount = 1,
264262
.pSetLayouts = &descriptor_set_layout,

src/video_core/renderer_vulkan/renderer_vulkan.h

+2-4
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
#include "common/common_types.h"
88
#include "common/math_util.h"
99
#include "video_core/renderer_base.h"
10-
#include "video_core/renderer_vulkan/vk_descriptor_pool.h"
1110
#include "video_core/renderer_vulkan/vk_instance.h"
1211
#include "video_core/renderer_vulkan/vk_present_window.h"
1312
#include "video_core/renderer_vulkan/vk_rasterizer.h"
@@ -119,22 +118,21 @@ class RendererVulkan : public VideoCore::RendererBase {
119118
Instance instance;
120119
Scheduler scheduler;
121120
RenderManager render_manager;
122-
DescriptorPool pool;
123121
PresentWindow main_window;
124122
StreamBuffer vertex_buffer;
123+
DescriptorUpdateQueue update_queue;
125124
RasterizerVulkan rasterizer;
126125
std::unique_ptr<PresentWindow> second_window;
127126

127+
DescriptorHeap present_heap;
128128
vk::UniquePipelineLayout present_pipeline_layout;
129-
DescriptorSetProvider present_set_provider;
130129
std::array<vk::Pipeline, PRESENT_PIPELINES> present_pipelines;
131130
std::array<vk::ShaderModule, PRESENT_PIPELINES> present_shaders;
132131
std::array<vk::Sampler, 2> present_samplers;
133132
vk::ShaderModule present_vertex_shader;
134133
u32 current_pipeline = 0;
135134

136135
std::array<ScreenInfo, 3> screen_infos{};
137-
std::array<DescriptorData, 3> present_textures{};
138136
PresentUniformData draw_info{};
139137
vk::ClearColorValue clear_color{};
140138
};

0 commit comments

Comments
 (0)