summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_graphics_pipeline.cpp46
-rw-r--r--src/video_core/renderer_opengl/gl_graphics_pipeline.h7
2 files changed, 32 insertions, 21 deletions
diff --git a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp
index f8495896c..9e6732abd 100644
--- a/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp
+++ b/src/video_core/renderer_opengl/gl_graphics_pipeline.cpp
@@ -243,10 +243,6 @@ GraphicsPipeline::GraphicsPipeline(
243 case Settings::ShaderBackend::GLASM: 243 case Settings::ShaderBackend::GLASM:
244 if (!sources[stage].empty()) { 244 if (!sources[stage].empty()) {
245 assembly_programs[stage] = CompileProgram(sources[stage], AssemblyStage(stage)); 245 assembly_programs[stage] = CompileProgram(sources[stage], AssemblyStage(stage));
246 if (in_parallel) {
247 // Make sure program is built before continuing when building in parallel
248 glGetString(GL_PROGRAM_ERROR_STRING_NV);
249 }
250 } 246 }
251 break; 247 break;
252 case Settings::ShaderBackend::SPIRV: 248 case Settings::ShaderBackend::SPIRV:
@@ -256,20 +252,18 @@ GraphicsPipeline::GraphicsPipeline(
256 break; 252 break;
257 } 253 }
258 } 254 }
259 if (in_parallel && backend != Settings::ShaderBackend::GLASM) { 255 if (in_parallel) {
260 // Make sure programs have built if we are building shaders in parallel 256 std::lock_guard lock{built_mutex};
261 for (OGLProgram& program : source_programs) { 257 built_fence.Create();
262 if (program.handle != 0) { 258 // Flush this context to ensure compilation commands and fence are in the GPU pipe.
263 GLint status{}; 259 glFlush();
264 glGetProgramiv(program.handle, GL_LINK_STATUS, &status); 260 built_condvar.notify_one();
265 } 261 } else {
266 } 262 is_built = true;
267 } 263 }
268 if (shader_notify) { 264 if (shader_notify) {
269 shader_notify->MarkShaderComplete(); 265 shader_notify->MarkShaderComplete();
270 } 266 }
271 is_built = true;
272 built_condvar.notify_one();
273 }}; 267 }};
274 if (thread_worker) { 268 if (thread_worker) {
275 thread_worker->QueueWork(std::move(func)); 269 thread_worker->QueueWork(std::move(func));
@@ -440,7 +434,7 @@ void GraphicsPipeline::ConfigureImpl(bool is_indexed) {
440 buffer_cache.UpdateGraphicsBuffers(is_indexed); 434 buffer_cache.UpdateGraphicsBuffers(is_indexed);
441 buffer_cache.BindHostGeometryBuffers(is_indexed); 435 buffer_cache.BindHostGeometryBuffers(is_indexed);
442 436
443 if (!is_built.load(std::memory_order::relaxed)) { 437 if (!IsBuilt()) {
444 WaitForBuild(); 438 WaitForBuild();
445 } 439 }
446 const bool use_assembly{assembly_programs[0].handle != 0}; 440 const bool use_assembly{assembly_programs[0].handle != 0};
@@ -585,8 +579,26 @@ void GraphicsPipeline::GenerateTransformFeedbackState() {
585} 579}
586 580
587void GraphicsPipeline::WaitForBuild() { 581void GraphicsPipeline::WaitForBuild() {
588 std::unique_lock lock{built_mutex}; 582 if (built_fence.handle == 0) {
589 built_condvar.wait(lock, [this] { return is_built.load(std::memory_order::relaxed); }); 583 std::unique_lock lock{built_mutex};
584 built_condvar.wait(lock, [this] { return built_fence.handle != 0; });
585 }
586 ASSERT(glClientWaitSync(built_fence.handle, 0, GL_TIMEOUT_IGNORED) != GL_WAIT_FAILED);
587 is_built = true;
588}
589
590bool GraphicsPipeline::IsBuilt() noexcept {
591 if (is_built) {
592 return true;
593 }
594 if (built_fence.handle == 0) {
595 return false;
596 }
597 // Timeout of zero means this is non-blocking
598 const auto sync_status = glClientWaitSync(built_fence.handle, 0, 0);
599 ASSERT(sync_status != GL_WAIT_FAILED);
600 is_built = sync_status != GL_TIMEOUT_EXPIRED;
601 return is_built;
590} 602}
591 603
592} // namespace OpenGL 604} // namespace OpenGL
diff --git a/src/video_core/renderer_opengl/gl_graphics_pipeline.h b/src/video_core/renderer_opengl/gl_graphics_pipeline.h
index 4e28d9a42..311d49f3f 100644
--- a/src/video_core/renderer_opengl/gl_graphics_pipeline.h
+++ b/src/video_core/renderer_opengl/gl_graphics_pipeline.h
@@ -100,9 +100,7 @@ public:
100 return writes_global_memory; 100 return writes_global_memory;
101 } 101 }
102 102
103 [[nodiscard]] bool IsBuilt() const noexcept { 103 [[nodiscard]] bool IsBuilt() noexcept;
104 return is_built.load(std::memory_order::relaxed);
105 }
106 104
107 template <typename Spec> 105 template <typename Spec>
108 static auto MakeConfigureSpecFunc() { 106 static auto MakeConfigureSpecFunc() {
@@ -154,7 +152,8 @@ private:
154 152
155 std::mutex built_mutex; 153 std::mutex built_mutex;
156 std::condition_variable built_condvar; 154 std::condition_variable built_condvar;
157 std::atomic_bool is_built{false}; 155 OGLSync built_fence{};
156 bool is_built{false};
158}; 157};
159 158
160} // namespace OpenGL 159} // namespace OpenGL