summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-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
6 files changed, 49 insertions, 16 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_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