video_core: Move shader and pipeline compilation into separate workers (#1802)

This commit is contained in:
PabloMK7 2026-03-01 23:09:13 +01:00 committed by GitHub
parent cb09d1e064
commit 0f9d5f29f3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 12 additions and 9 deletions

View file

@ -84,8 +84,9 @@ PipelineCache::PipelineCache(const Instance& instance_, Scheduler& scheduler_,
RenderManager& renderpass_cache_, DescriptorUpdateQueue& update_queue_) RenderManager& renderpass_cache_, DescriptorUpdateQueue& update_queue_)
: instance{instance_}, scheduler{scheduler_}, renderpass_cache{renderpass_cache_}, : instance{instance_}, scheduler{scheduler_}, renderpass_cache{renderpass_cache_},
update_queue{update_queue_}, update_queue{update_queue_},
num_worker_threads{std::max(std::thread::hardware_concurrency(), 2U) >> 1}, num_worker_threads{std::max(std::thread::hardware_concurrency(), 2U) / 2},
workers{num_worker_threads, "Pipeline workers"}, pipeline_workers{num_worker_threads, "Pipeline workers"},
shader_workers{num_worker_threads, "Shader workers"},
descriptor_heaps{ descriptor_heaps{
DescriptorHeap{instance, scheduler.GetMasterSemaphore(), BUFFER_BINDINGS, 32}, DescriptorHeap{instance, scheduler.GetMasterSemaphore(), BUFFER_BINDINGS, 32},
DescriptorHeap{instance, scheduler.GetMasterSemaphore(), TEXTURE_BINDINGS<1>}, DescriptorHeap{instance, scheduler.GetMasterSemaphore(), TEXTURE_BINDINGS<1>},
@ -144,7 +145,8 @@ void PipelineCache::BuildLayout() {
} }
PipelineCache::~PipelineCache() { PipelineCache::~PipelineCache() {
workers.WaitForRequests(); pipeline_workers.WaitForRequests();
shader_workers.WaitForRequests();
SaveDriverPipelineDiskCache(); SaveDriverPipelineDiskCache();
} }

View file

@ -147,7 +147,8 @@ private:
vk::UniquePipelineCache driver_pipeline_cache; vk::UniquePipelineCache driver_pipeline_cache;
vk::UniquePipelineLayout pipeline_layout; vk::UniquePipelineLayout pipeline_layout;
std::size_t num_worker_threads; std::size_t num_worker_threads;
Common::ThreadWorker workers; Common::ThreadWorker pipeline_workers;
Common::ThreadWorker shader_workers;
PipelineInfo current_info{}; PipelineInfo current_info{};
GraphicsPipeline* current_pipeline{}; GraphicsPipeline* current_pipeline{};
std::array<DescriptorHeap, NumDescriptorHeaps> descriptor_heaps; std::array<DescriptorHeap, NumDescriptorHeaps> descriptor_heaps;

View file

@ -123,7 +123,7 @@ std::optional<std::pair<u64, Shader* const>> ShaderDiskCache::UseProgrammableVer
shader.program = std::move(program); shader.program = std::move(program);
const vk::Device device = parent.instance.GetDevice(); const vk::Device device = parent.instance.GetDevice();
parent.workers.QueueWork([device, &shader, this, spirv_id] { parent.shader_workers.QueueWork([device, &shader, this, spirv_id] {
auto spirv = CompileGLSL(shader.program, vk::ShaderStageFlagBits::eVertex); auto spirv = CompileGLSL(shader.program, vk::ShaderStageFlagBits::eVertex);
AppendVSSPIRV(vs_cache, spirv, spirv_id); AppendVSSPIRV(vs_cache, spirv, spirv_id);
shader.program.clear(); shader.program.clear();
@ -157,7 +157,7 @@ std::optional<std::pair<u64, Shader* const>> ShaderDiskCache::UseFragmentShader(
if (new_shader) { if (new_shader) {
LOG_NEW_OBJECT(Render_Vulkan, "New FS config {:016X}", fs_config_hash); LOG_NEW_OBJECT(Render_Vulkan, "New FS config {:016X}", fs_config_hash);
parent.workers.QueueWork([fs_config, user, this, &shader, fs_config_hash]() { parent.shader_workers.QueueWork([fs_config, user, this, &shader, fs_config_hash]() {
std::vector<u32> spirv; std::vector<u32> spirv;
const bool use_spirv = parent.profile.vk_use_spirv_generator; const bool use_spirv = parent.profile.vk_use_spirv_generator;
if (use_spirv && !fs_config.UsesSpirvIncompatibleConfig()) { if (use_spirv && !fs_config.UsesSpirvIncompatibleConfig()) {
@ -212,7 +212,7 @@ std::optional<std::pair<u64, Shader* const>> ShaderDiskCache::UseFixedGeometrySh
if (new_shader) { if (new_shader) {
LOG_NEW_OBJECT(Render_Vulkan, "New GS config {:016X}", gs_config_hash); LOG_NEW_OBJECT(Render_Vulkan, "New GS config {:016X}", gs_config_hash);
parent.workers.QueueWork([gs_config, this, &shader, gs_config_hash]() { parent.shader_workers.QueueWork([gs_config, this, &shader, gs_config_hash]() {
ExtraFixedGSConfig extra; ExtraFixedGSConfig extra;
extra.use_clip_planes = parent.profile.has_clip_planes; extra.use_clip_planes = parent.profile.has_clip_planes;
extra.separable_shader = true; extra.separable_shader = true;
@ -252,7 +252,7 @@ GraphicsPipeline* ShaderDiskCache::GetPipeline(const PipelineInfo& info) {
} }
it.value() = std::make_unique<GraphicsPipeline>( it.value() = std::make_unique<GraphicsPipeline>(
parent.instance, parent.renderpass_cache, info, *parent.driver_pipeline_cache, parent.instance, parent.renderpass_cache, info, *parent.driver_pipeline_cache,
*parent.pipeline_layout, parent.current_shaders, &parent.workers); *parent.pipeline_layout, parent.current_shaders, &parent.pipeline_workers);
} }
if (known_graphic_pipelines.emplace(hash).second) { if (known_graphic_pipelines.emplace(hash).second) {
@ -1454,7 +1454,7 @@ bool ShaderDiskCache::InitPLCache(const std::atomic_bool& stop_loading,
auto [it_pl, _] = graphics_pipelines.try_emplace(pl_hash_opt); auto [it_pl, _] = graphics_pipelines.try_emplace(pl_hash_opt);
it_pl.value() = std::make_unique<GraphicsPipeline>( it_pl.value() = std::make_unique<GraphicsPipeline>(
parent.instance, parent.renderpass_cache, info, *parent.driver_pipeline_cache, parent.instance, parent.renderpass_cache, info, *parent.driver_pipeline_cache,
*parent.pipeline_layout, shaders, &parent.workers); *parent.pipeline_layout, shaders, &parent.pipeline_workers);
it_pl.value()->TryBuild(false); it_pl.value()->TryBuild(false);