summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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_shader_cache.cpp8
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.h3
4 files changed, 37 insertions, 7 deletions
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_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp
index 15812b678..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));
@@ -560,8 +560,8 @@ std::unique_ptr<ComputePipeline> ShaderCache::CreateComputePipeline(
560} 560}
561 561
562std::unique_ptr<ComputePipeline> ShaderCache::CreateComputePipeline( 562std::unique_ptr<ComputePipeline> ShaderCache::CreateComputePipeline(
563 ShaderContext::ShaderPools& pools, const ComputePipelineKey& key, 563 ShaderContext::ShaderPools& pools, const ComputePipelineKey& key, Shader::Environment& env,
564 Shader::Environment& env) try { 564 bool force_context_flush) try {
565 LOG_INFO(Render_OpenGL, "0x{:016x}", key.Hash()); 565 LOG_INFO(Render_OpenGL, "0x{:016x}", key.Hash());
566 566
567 Shader::Maxwell::Flow::CFG cfg{env, pools.flow_block, env.StartAddress()}; 567 Shader::Maxwell::Flow::CFG cfg{env, pools.flow_block, env.StartAddress()};
@@ -590,7 +590,7 @@ std::unique_ptr<ComputePipeline> ShaderCache::CreateComputePipeline(
590 } 590 }
591 591
592 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,
593 program.info, code, code_spirv); 593 program.info, code, code_spirv, force_context_flush);
594} catch (Shader::Exception& exception) { 594} catch (Shader::Exception& exception) {
595 LOG_ERROR(Render_OpenGL, "{}", exception.what()); 595 LOG_ERROR(Render_OpenGL, "{}", exception.what());
596 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 50f610cd0..6b9732fca 100644
--- a/src/video_core/renderer_opengl/gl_shader_cache.h
+++ b/src/video_core/renderer_opengl/gl_shader_cache.h
@@ -58,7 +58,8 @@ private:
58 58
59 std::unique_ptr<ComputePipeline> CreateComputePipeline(ShaderContext::ShaderPools& pools, 59 std::unique_ptr<ComputePipeline> CreateComputePipeline(ShaderContext::ShaderPools& pools,
60 const ComputePipelineKey& key, 60 const ComputePipelineKey& key,
61 Shader::Environment& env); 61 Shader::Environment& env,
62 bool force_context_flush = false);
62 63
63 std::unique_ptr<ShaderWorker> CreateWorkers() const; 64 std::unique_ptr<ShaderWorker> CreateWorkers() const;
64 65