summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/shader_recompiler/backend/glasm/emit_glasm_image.cpp10
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl_image.cpp32
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_image.cpp25
-rw-r--r--src/shader_recompiler/backend/spirv/spirv_emit_context.cpp1
-rw-r--r--src/shader_recompiler/backend/spirv/spirv_emit_context.h1
-rw-r--r--src/video_core/renderer_opengl/gl_compute_pipeline.cpp23
-rw-r--r--src/video_core/renderer_opengl/gl_compute_pipeline.h10
-rw-r--r--src/video_core/renderer_opengl/gl_graphics_pipeline.cpp7
-rw-r--r--src/video_core/renderer_opengl/gl_graphics_pipeline.h2
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.cpp17
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.h6
11 files changed, 100 insertions, 34 deletions
diff --git a/src/shader_recompiler/backend/glasm/emit_glasm_image.cpp b/src/shader_recompiler/backend/glasm/emit_glasm_image.cpp
index b7bc11416..85ee27333 100644
--- a/src/shader_recompiler/backend/glasm/emit_glasm_image.cpp
+++ b/src/shader_recompiler/backend/glasm/emit_glasm_image.cpp
@@ -59,6 +59,13 @@ std::string Image(EmitContext& ctx, IR::TextureInstInfo info,
59 } 59 }
60} 60}
61 61
62bool IsTextureMsaa(EmitContext& ctx, const IR::TextureInstInfo& info) {
63 if (info.type == TextureType::Buffer) {
64 return false;
65 }
66 return ctx.info.texture_descriptors.at(info.descriptor_index).is_multisample;
67}
68
62std::string_view TextureType(IR::TextureInstInfo info, bool is_ms = false) { 69std::string_view TextureType(IR::TextureInstInfo info, bool is_ms = false) {
63 if (info.is_depth) { 70 if (info.is_depth) {
64 switch (info.type) { 71 switch (info.type) {
@@ -535,7 +542,8 @@ void EmitImageQueryDimensions(EmitContext& ctx, IR::Inst& inst, const IR::Value&
535 ScalarS32 lod, [[maybe_unused]] const IR::Value& skip_mips) { 542 ScalarS32 lod, [[maybe_unused]] const IR::Value& skip_mips) {
536 const auto info{inst.Flags<IR::TextureInstInfo>()}; 543 const auto info{inst.Flags<IR::TextureInstInfo>()};
537 const std::string texture{Texture(ctx, info, index)}; 544 const std::string texture{Texture(ctx, info, index)};
538 const std::string_view type{TextureType(info)}; 545 const bool is_msaa{IsTextureMsaa(ctx, info)};
546 const std::string_view type{TextureType(info, is_msaa)};
539 ctx.Add("TXQ {},{},{},{};", inst, lod, texture, type); 547 ctx.Add("TXQ {},{},{},{};", inst, lod, texture, type);
540} 548}
541 549
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp
index 4be2c25ec..f335c8af0 100644
--- a/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp
+++ b/src/shader_recompiler/backend/glsl/emit_glsl_image.cpp
@@ -25,6 +25,13 @@ std::string Image(EmitContext& ctx, const IR::TextureInstInfo& info, const IR::V
25 return fmt::format("img{}{}", def.binding, index_offset); 25 return fmt::format("img{}{}", def.binding, index_offset);
26} 26}
27 27
28bool IsTextureMsaa(EmitContext& ctx, const IR::TextureInstInfo& info) {
29 if (info.type == TextureType::Buffer) {
30 return false;
31 }
32 return ctx.info.texture_descriptors.at(info.descriptor_index).is_multisample;
33}
34
28std::string CastToIntVec(std::string_view value, const IR::TextureInstInfo& info) { 35std::string CastToIntVec(std::string_view value, const IR::TextureInstInfo& info) {
29 switch (info.type) { 36 switch (info.type) {
30 case TextureType::Color1D: 37 case TextureType::Color1D:
@@ -463,26 +470,33 @@ void EmitImageQueryDimensions(EmitContext& ctx, IR::Inst& inst, const IR::Value&
463 std::string_view lod, const IR::Value& skip_mips_val) { 470 std::string_view lod, const IR::Value& skip_mips_val) {
464 const auto info{inst.Flags<IR::TextureInstInfo>()}; 471 const auto info{inst.Flags<IR::TextureInstInfo>()};
465 const auto texture{Texture(ctx, info, index)}; 472 const auto texture{Texture(ctx, info, index)};
473 const bool is_msaa{IsTextureMsaa(ctx, info)};
466 const bool skip_mips{skip_mips_val.U1()}; 474 const bool skip_mips{skip_mips_val.U1()};
467 const auto mips{ 475 const auto mips{skip_mips ? "0u" : fmt::format("uint(textureQueryLevels({}))", texture)};
468 [&] { return skip_mips ? "0u" : fmt::format("uint(textureQueryLevels({}))", texture); }}; 476 if (is_msaa && !skip_mips) {
477 throw NotImplementedException("EmitImageQueryDimensions MSAA QueryLevels");
478 }
479 if (info.type == TextureType::Buffer && !skip_mips) {
480 throw NotImplementedException("EmitImageQueryDimensions TextureType::Buffer QueryLevels");
481 }
482 const bool uses_lod{!is_msaa && info.type != TextureType::Buffer};
483 const auto lod_str{uses_lod ? fmt::format(",int({})", lod) : ""};
469 switch (info.type) { 484 switch (info.type) {
470 case TextureType::Color1D: 485 case TextureType::Color1D:
471 return ctx.AddU32x4("{}=uvec4(uint(textureSize({},int({}))),0u,0u,{});", inst, texture, lod, 486 return ctx.AddU32x4("{}=uvec4(uint(textureSize({}{})),0u,0u,{});", inst, texture, lod_str,
472 mips()); 487 mips);
473 case TextureType::ColorArray1D: 488 case TextureType::ColorArray1D:
474 case TextureType::Color2D: 489 case TextureType::Color2D:
475 case TextureType::ColorCube: 490 case TextureType::ColorCube:
476 case TextureType::Color2DRect: 491 case TextureType::Color2DRect:
477 return ctx.AddU32x4("{}=uvec4(uvec2(textureSize({},int({}))),0u,{});", inst, texture, lod, 492 return ctx.AddU32x4("{}=uvec4(uvec2(textureSize({}{})),0u,{});", inst, texture, lod_str,
478 mips()); 493 mips);
479 case TextureType::ColorArray2D: 494 case TextureType::ColorArray2D:
480 case TextureType::Color3D: 495 case TextureType::Color3D:
481 case TextureType::ColorArrayCube: 496 case TextureType::ColorArrayCube:
482 return ctx.AddU32x4("{}=uvec4(uvec3(textureSize({},int({}))),{});", inst, texture, lod, 497 return ctx.AddU32x4("{}=uvec4(uvec3(textureSize({}{})),{});", inst, texture, lod_str, mips);
483 mips());
484 case TextureType::Buffer: 498 case TextureType::Buffer:
485 throw NotImplementedException("EmitImageQueryDimensions Texture buffers"); 499 return ctx.AddU32x4("{}=uvec4(uint(textureSize({})),0u,0u,{});", inst, texture, mips);
486 } 500 }
487 throw LogicError("Unspecified image type {}", info.type.Value()); 501 throw LogicError("Unspecified image type {}", info.type.Value());
488} 502}
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp
index 3b969d915..02073c420 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp
@@ -201,6 +201,13 @@ Id Image(EmitContext& ctx, const IR::Value& index, IR::TextureInstInfo info) {
201 } 201 }
202} 202}
203 203
204bool IsTextureMsaa(EmitContext& ctx, const IR::TextureInstInfo& info) {
205 if (info.type == TextureType::Buffer) {
206 return false;
207 }
208 return ctx.textures.at(info.descriptor_index).is_multisample;
209}
210
204Id Decorate(EmitContext& ctx, IR::Inst* inst, Id sample) { 211Id Decorate(EmitContext& ctx, IR::Inst* inst, Id sample) {
205 const auto info{inst->Flags<IR::TextureInstInfo>()}; 212 const auto info{inst->Flags<IR::TextureInstInfo>()};
206 if (info.relaxed_precision != 0) { 213 if (info.relaxed_precision != 0) {
@@ -452,24 +459,26 @@ Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, const IR::Value& i
452 const Id zero{ctx.u32_zero_value}; 459 const Id zero{ctx.u32_zero_value};
453 const bool skip_mips{skip_mips_val.U1()}; 460 const bool skip_mips{skip_mips_val.U1()};
454 const auto mips{[&] { return skip_mips ? zero : ctx.OpImageQueryLevels(ctx.U32[1], image); }}; 461 const auto mips{[&] { return skip_mips ? zero : ctx.OpImageQueryLevels(ctx.U32[1], image); }};
462 const bool is_msaa{IsTextureMsaa(ctx, info)};
463 const bool uses_lod{!is_msaa && info.type != TextureType::Buffer};
464 const auto query{[&](Id type) {
465 return uses_lod ? ctx.OpImageQuerySizeLod(type, image, lod)
466 : ctx.OpImageQuerySize(type, image);
467 }};
455 switch (info.type) { 468 switch (info.type) {
456 case TextureType::Color1D: 469 case TextureType::Color1D:
457 return ctx.OpCompositeConstruct(ctx.U32[4], ctx.OpImageQuerySizeLod(ctx.U32[1], image, lod), 470 return ctx.OpCompositeConstruct(ctx.U32[4], query(ctx.U32[1]), zero, zero, mips());
458 zero, zero, mips());
459 case TextureType::ColorArray1D: 471 case TextureType::ColorArray1D:
460 case TextureType::Color2D: 472 case TextureType::Color2D:
461 case TextureType::ColorCube: 473 case TextureType::ColorCube:
462 case TextureType::Color2DRect: 474 case TextureType::Color2DRect:
463 return ctx.OpCompositeConstruct(ctx.U32[4], ctx.OpImageQuerySizeLod(ctx.U32[2], image, lod), 475 return ctx.OpCompositeConstruct(ctx.U32[4], query(ctx.U32[2]), zero, mips());
464 zero, mips());
465 case TextureType::ColorArray2D: 476 case TextureType::ColorArray2D:
466 case TextureType::Color3D: 477 case TextureType::Color3D:
467 case TextureType::ColorArrayCube: 478 case TextureType::ColorArrayCube:
468 return ctx.OpCompositeConstruct(ctx.U32[4], ctx.OpImageQuerySizeLod(ctx.U32[3], image, lod), 479 return ctx.OpCompositeConstruct(ctx.U32[4], query(ctx.U32[3]), mips());
469 mips());
470 case TextureType::Buffer: 480 case TextureType::Buffer:
471 return ctx.OpCompositeConstruct(ctx.U32[4], ctx.OpImageQuerySize(ctx.U32[1], image), zero, 481 return ctx.OpCompositeConstruct(ctx.U32[4], query(ctx.U32[1]), zero, zero, mips());
472 zero, mips());
473 } 482 }
474 throw LogicError("Unspecified image type {}", info.type.Value()); 483 throw LogicError("Unspecified image type {}", info.type.Value());
475} 484}
diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp
index 3b97721e1..d48d4860e 100644
--- a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp
+++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp
@@ -1288,6 +1288,7 @@ void EmitContext::DefineTextures(const Info& info, u32& binding, u32& scaling_in
1288 .pointer_type = pointer_type, 1288 .pointer_type = pointer_type,
1289 .image_type = image_type, 1289 .image_type = image_type,
1290 .count = desc.count, 1290 .count = desc.count,
1291 .is_multisample = desc.is_multisample,
1291 }); 1292 });
1292 if (profile.supported_spirv >= 0x00010400) { 1293 if (profile.supported_spirv >= 0x00010400) {
1293 interfaces.push_back(id); 1294 interfaces.push_back(id);
diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.h b/src/shader_recompiler/backend/spirv/spirv_emit_context.h
index dbc5c55b9..768a4fbb5 100644
--- a/src/shader_recompiler/backend/spirv/spirv_emit_context.h
+++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.h
@@ -35,6 +35,7 @@ struct TextureDefinition {
35 Id pointer_type; 35 Id pointer_type;
36 Id image_type; 36 Id image_type;
37 u32 count; 37 u32 count;
38 bool is_multisample;
38}; 39};
39 40
40struct TextureBufferDefinition { 41struct TextureBufferDefinition {
diff --git a/src/video_core/renderer_opengl/gl_compute_pipeline.cpp b/src/video_core/renderer_opengl/gl_compute_pipeline.cpp
index 26d066004..1a0cea9b7 100644
--- a/src/video_core/renderer_opengl/gl_compute_pipeline.cpp
+++ b/src/video_core/renderer_opengl/gl_compute_pipeline.cpp
@@ -30,7 +30,7 @@ bool ComputePipelineKey::operator==(const ComputePipelineKey& rhs) const noexcep
30ComputePipeline::ComputePipeline(const Device& device, TextureCache& texture_cache_, 30ComputePipeline::ComputePipeline(const Device& device, TextureCache& texture_cache_,
31 BufferCache& buffer_cache_, ProgramManager& program_manager_, 31 BufferCache& buffer_cache_, ProgramManager& program_manager_,
32 const Shader::Info& info_, std::string code, 32 const Shader::Info& info_, std::string code,
33 std::vector<u32> code_v) 33 std::vector<u32> code_v, bool force_context_flush)
34 : texture_cache{texture_cache_}, buffer_cache{buffer_cache_}, 34 : texture_cache{texture_cache_}, buffer_cache{buffer_cache_},
35 program_manager{program_manager_}, info{info_} { 35 program_manager{program_manager_}, info{info_} {
36 switch (device.GetShaderBackend()) { 36 switch (device.GetShaderBackend()) {
@@ -63,6 +63,15 @@ ComputePipeline::ComputePipeline(const Device& device, TextureCache& texture_cac
63 writes_global_memory = !use_storage_buffers && 63 writes_global_memory = !use_storage_buffers &&
64 std::ranges::any_of(info.storage_buffers_descriptors, 64 std::ranges::any_of(info.storage_buffers_descriptors,
65 [](const auto& desc) { return desc.is_written; }); 65 [](const auto& desc) { return desc.is_written; });
66 if (force_context_flush) {
67 std::scoped_lock lock{built_mutex};
68 built_fence.Create();
69 // Flush this context to ensure compilation commands and fence are in the GPU pipe.
70 glFlush();
71 built_condvar.notify_one();
72 } else {
73 is_built = true;
74 }
66} 75}
67 76
68void ComputePipeline::Configure() { 77void ComputePipeline::Configure() {
@@ -142,6 +151,9 @@ void ComputePipeline::Configure() {
142 } 151 }
143 texture_cache.FillComputeImageViews(std::span(views.data(), views.size())); 152 texture_cache.FillComputeImageViews(std::span(views.data(), views.size()));
144 153
154 if (!is_built) {
155 WaitForBuild();
156 }
145 if (assembly_program.handle != 0) { 157 if (assembly_program.handle != 0) {
146 program_manager.BindComputeAssemblyProgram(assembly_program.handle); 158 program_manager.BindComputeAssemblyProgram(assembly_program.handle);
147 } else { 159 } else {
@@ -223,4 +235,13 @@ void ComputePipeline::Configure() {
223 } 235 }
224} 236}
225 237
238void ComputePipeline::WaitForBuild() {
239 if (built_fence.handle == 0) {
240 std::unique_lock lock{built_mutex};
241 built_condvar.wait(lock, [this] { return built_fence.handle != 0; });
242 }
243 ASSERT(glClientWaitSync(built_fence.handle, 0, GL_TIMEOUT_IGNORED) != GL_WAIT_FAILED);
244 is_built = true;
245}
246
226} // namespace OpenGL 247} // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/gl_compute_pipeline.h b/src/video_core/renderer_opengl/gl_compute_pipeline.h
index 6534dec32..9bcc72b59 100644
--- a/src/video_core/renderer_opengl/gl_compute_pipeline.h
+++ b/src/video_core/renderer_opengl/gl_compute_pipeline.h
@@ -50,7 +50,8 @@ class ComputePipeline {
50public: 50public:
51 explicit ComputePipeline(const Device& device, TextureCache& texture_cache_, 51 explicit ComputePipeline(const Device& device, TextureCache& texture_cache_,
52 BufferCache& buffer_cache_, ProgramManager& program_manager_, 52 BufferCache& buffer_cache_, ProgramManager& program_manager_,
53 const Shader::Info& info_, std::string code, std::vector<u32> code_v); 53 const Shader::Info& info_, std::string code, std::vector<u32> code_v,
54 bool force_context_flush = false);
54 55
55 void Configure(); 56 void Configure();
56 57
@@ -65,6 +66,8 @@ public:
65 } 66 }
66 67
67private: 68private:
69 void WaitForBuild();
70
68 TextureCache& texture_cache; 71 TextureCache& texture_cache;
69 BufferCache& buffer_cache; 72 BufferCache& buffer_cache;
70 Tegra::MemoryManager* gpu_memory; 73 Tegra::MemoryManager* gpu_memory;
@@ -81,6 +84,11 @@ private:
81 84
82 bool use_storage_buffers{}; 85 bool use_storage_buffers{};
83 bool writes_global_memory{}; 86 bool writes_global_memory{};
87
88 std::mutex built_mutex;
89 std::condition_variable built_condvar;
90 OGLSync built_fence{};
91 bool is_built{false};
84}; 92};
85 93
86} // namespace OpenGL 94} // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp
index c115dabe1..29491e762 100644
--- a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp
+++ b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp
@@ -176,7 +176,7 @@ GraphicsPipeline::GraphicsPipeline(const Device& device, TextureCache& texture_c
176 std::array<std::string, 5> sources, 176 std::array<std::string, 5> sources,
177 std::array<std::vector<u32>, 5> sources_spirv, 177 std::array<std::vector<u32>, 5> sources_spirv,
178 const std::array<const Shader::Info*, 5>& infos, 178 const std::array<const Shader::Info*, 5>& infos,
179 const GraphicsPipelineKey& key_) 179 const GraphicsPipelineKey& key_, bool force_context_flush)
180 : texture_cache{texture_cache_}, buffer_cache{buffer_cache_}, program_manager{program_manager_}, 180 : texture_cache{texture_cache_}, buffer_cache{buffer_cache_}, program_manager{program_manager_},
181 state_tracker{state_tracker_}, key{key_} { 181 state_tracker{state_tracker_}, key{key_} {
182 if (shader_notify) { 182 if (shader_notify) {
@@ -231,7 +231,8 @@ GraphicsPipeline::GraphicsPipeline(const Device& device, TextureCache& texture_c
231 const bool in_parallel = thread_worker != nullptr; 231 const bool in_parallel = thread_worker != nullptr;
232 const auto backend = device.GetShaderBackend(); 232 const auto backend = device.GetShaderBackend();
233 auto func{[this, sources = std::move(sources), sources_spirv = std::move(sources_spirv), 233 auto func{[this, sources = std::move(sources), sources_spirv = std::move(sources_spirv),
234 shader_notify, backend, in_parallel](ShaderContext::Context*) mutable { 234 shader_notify, backend, in_parallel,
235 force_context_flush](ShaderContext::Context*) mutable {
235 for (size_t stage = 0; stage < 5; ++stage) { 236 for (size_t stage = 0; stage < 5; ++stage) {
236 switch (backend) { 237 switch (backend) {
237 case Settings::ShaderBackend::GLSL: 238 case Settings::ShaderBackend::GLSL:
@@ -251,7 +252,7 @@ GraphicsPipeline::GraphicsPipeline(const Device& device, TextureCache& texture_c
251 break; 252 break;
252 } 253 }
253 } 254 }
254 if (in_parallel) { 255 if (force_context_flush || in_parallel) {
255 std::scoped_lock lock{built_mutex}; 256 std::scoped_lock lock{built_mutex};
256 built_fence.Create(); 257 built_fence.Create();
257 // Flush this context to ensure compilation commands and fence are in the GPU pipe. 258 // Flush this context to ensure compilation commands and fence are in the GPU pipe.
diff --git a/src/video_core/renderer_opengl/gl_graphics_pipeline.h b/src/video_core/renderer_opengl/gl_graphics_pipeline.h
index 1c06b3655..7bab3be0a 100644
--- a/src/video_core/renderer_opengl/gl_graphics_pipeline.h
+++ b/src/video_core/renderer_opengl/gl_graphics_pipeline.h
@@ -78,7 +78,7 @@ public:
78 std::array<std::string, 5> sources, 78 std::array<std::string, 5> sources,
79 std::array<std::vector<u32>, 5> sources_spirv, 79 std::array<std::vector<u32>, 5> sources_spirv,
80 const std::array<const Shader::Info*, 5>& infos, 80 const std::array<const Shader::Info*, 5>& infos,
81 const GraphicsPipelineKey& key_); 81 const GraphicsPipelineKey& key_, bool force_context_flush = false);
82 82
83 void Configure(bool is_indexed) { 83 void Configure(bool is_indexed) {
84 configure_func(this, is_indexed); 84 configure_func(this, is_indexed);
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp
index 7dd854e0f..626ea7dcb 100644
--- a/src/video_core/renderer_opengl/gl_shader_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp
@@ -286,7 +286,7 @@ void ShaderCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading,
286 file.read(reinterpret_cast<char*>(&key), sizeof(key)); 286 file.read(reinterpret_cast<char*>(&key), sizeof(key));
287 queue_work([this, key, env = std::move(env), &state, &callback](Context* ctx) mutable { 287 queue_work([this, key, env = std::move(env), &state, &callback](Context* ctx) mutable {
288 ctx->pools.ReleaseContents(); 288 ctx->pools.ReleaseContents();
289 auto pipeline{CreateComputePipeline(ctx->pools, key, env)}; 289 auto pipeline{CreateComputePipeline(ctx->pools, key, env, true)};
290 std::scoped_lock lock{state.mutex}; 290 std::scoped_lock lock{state.mutex};
291 if (pipeline) { 291 if (pipeline) {
292 compute_cache.emplace(key, std::move(pipeline)); 292 compute_cache.emplace(key, std::move(pipeline));
@@ -307,7 +307,7 @@ void ShaderCache::LoadDiskResources(u64 title_id, std::stop_token stop_loading,
307 env_ptrs.push_back(&env); 307 env_ptrs.push_back(&env);
308 } 308 }
309 ctx->pools.ReleaseContents(); 309 ctx->pools.ReleaseContents();
310 auto pipeline{CreateGraphicsPipeline(ctx->pools, key, MakeSpan(env_ptrs), false)}; 310 auto pipeline{CreateGraphicsPipeline(ctx->pools, key, MakeSpan(env_ptrs), false, true)};
311 std::scoped_lock lock{state.mutex}; 311 std::scoped_lock lock{state.mutex};
312 if (pipeline) { 312 if (pipeline) {
313 graphics_cache.emplace(key, std::move(pipeline)); 313 graphics_cache.emplace(key, std::move(pipeline));
@@ -439,7 +439,8 @@ std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline() {
439 439
440std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline( 440std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline(
441 ShaderContext::ShaderPools& pools, const GraphicsPipelineKey& key, 441 ShaderContext::ShaderPools& pools, const GraphicsPipelineKey& key,
442 std::span<Shader::Environment* const> envs, bool build_in_parallel) try { 442 std::span<Shader::Environment* const> envs, bool use_shader_workers,
443 bool force_context_flush) try {
443 LOG_INFO(Render_OpenGL, "0x{:016x}", key.Hash()); 444 LOG_INFO(Render_OpenGL, "0x{:016x}", key.Hash());
444 size_t env_index{}; 445 size_t env_index{};
445 u32 total_storage_buffers{}; 446 u32 total_storage_buffers{};
@@ -531,10 +532,10 @@ std::unique_ptr<GraphicsPipeline> ShaderCache::CreateGraphicsPipeline(
531 } 532 }
532 previous_program = &program; 533 previous_program = &program;
533 } 534 }
534 auto* const thread_worker{build_in_parallel ? workers.get() : nullptr}; 535 auto* const thread_worker{use_shader_workers ? workers.get() : nullptr};
535 return std::make_unique<GraphicsPipeline>(device, texture_cache, buffer_cache, program_manager, 536 return std::make_unique<GraphicsPipeline>(device, texture_cache, buffer_cache, program_manager,
536 state_tracker, thread_worker, &shader_notify, sources, 537 state_tracker, thread_worker, &shader_notify, sources,
537 sources_spirv, infos, key); 538 sources_spirv, infos, key, force_context_flush);
538 539
539} catch (Shader::Exception& exception) { 540} catch (Shader::Exception& exception) {
540 LOG_ERROR(Render_OpenGL, "{}", exception.what()); 541 LOG_ERROR(Render_OpenGL, "{}", exception.what());
@@ -559,8 +560,8 @@ std::unique_ptr<ComputePipeline> ShaderCache::CreateComputePipeline(
559} 560}
560 561
561std::unique_ptr<ComputePipeline> ShaderCache::CreateComputePipeline( 562std::unique_ptr<ComputePipeline> ShaderCache::CreateComputePipeline(
562 ShaderContext::ShaderPools& pools, const ComputePipelineKey& key, 563 ShaderContext::ShaderPools& pools, const ComputePipelineKey& key, Shader::Environment& env,
563 Shader::Environment& env) try { 564 bool force_context_flush) try {
564 LOG_INFO(Render_OpenGL, "0x{:016x}", key.Hash()); 565 LOG_INFO(Render_OpenGL, "0x{:016x}", key.Hash());
565 566
566 Shader::Maxwell::Flow::CFG cfg{env, pools.flow_block, env.StartAddress()}; 567 Shader::Maxwell::Flow::CFG cfg{env, pools.flow_block, env.StartAddress()};
@@ -589,7 +590,7 @@ std::unique_ptr<ComputePipeline> ShaderCache::CreateComputePipeline(
589 } 590 }
590 591
591 return std::make_unique<ComputePipeline>(device, texture_cache, buffer_cache, program_manager, 592 return std::make_unique<ComputePipeline>(device, texture_cache, buffer_cache, program_manager,
592 program.info, code, code_spirv); 593 program.info, code, code_spirv, force_context_flush);
593} catch (Shader::Exception& exception) { 594} catch (Shader::Exception& exception) {
594 LOG_ERROR(Render_OpenGL, "{}", exception.what()); 595 LOG_ERROR(Render_OpenGL, "{}", exception.what());
595 return nullptr; 596 return nullptr;
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.h b/src/video_core/renderer_opengl/gl_shader_cache.h
index f82420592..6b9732fca 100644
--- a/src/video_core/renderer_opengl/gl_shader_cache.h
+++ b/src/video_core/renderer_opengl/gl_shader_cache.h
@@ -50,14 +50,16 @@ private:
50 50
51 std::unique_ptr<GraphicsPipeline> CreateGraphicsPipeline( 51 std::unique_ptr<GraphicsPipeline> CreateGraphicsPipeline(
52 ShaderContext::ShaderPools& pools, const GraphicsPipelineKey& key, 52 ShaderContext::ShaderPools& pools, const GraphicsPipelineKey& key,
53 std::span<Shader::Environment* const> envs, bool build_in_parallel); 53 std::span<Shader::Environment* const> envs, bool use_shader_workers,
54 bool force_context_flush = false);
54 55
55 std::unique_ptr<ComputePipeline> CreateComputePipeline(const ComputePipelineKey& key, 56 std::unique_ptr<ComputePipeline> CreateComputePipeline(const ComputePipelineKey& key,
56 const VideoCommon::ShaderInfo* shader); 57 const VideoCommon::ShaderInfo* shader);
57 58
58 std::unique_ptr<ComputePipeline> CreateComputePipeline(ShaderContext::ShaderPools& pools, 59 std::unique_ptr<ComputePipeline> CreateComputePipeline(ShaderContext::ShaderPools& pools,
59 const ComputePipelineKey& key, 60 const ComputePipelineKey& key,
60 Shader::Environment& env); 61 Shader::Environment& env,
62 bool force_context_flush = false);
61 63
62 std::unique_ptr<ShaderWorker> CreateWorkers() const; 64 std::unique_ptr<ShaderWorker> CreateWorkers() const;
63 65