From b301fecfd85b81a4ec95dde631b5c440dbcc9f4e Mon Sep 17 00:00:00 2001 From: kd-11 Date: Sun, 5 Apr 2020 14:16:57 +0300 Subject: [PATCH] gl: Fix async shader compiler - Removes glFinish hack. - Adds proper server-side synchronization. - Adds primary context detection to allow worker threads to be identified. --- rpcs3/Emu/RSX/GL/GLCompute.h | 2 +- rpcs3/Emu/RSX/GL/GLGSRender.cpp | 16 +++++++-------- rpcs3/Emu/RSX/GL/GLHelpers.cpp | 12 +++++++++++ rpcs3/Emu/RSX/GL/GLHelpers.h | 32 +++++++++++++++++++++++++----- rpcs3/Emu/RSX/GL/GLOverlays.h | 2 +- rpcs3/Emu/RSX/GL/GLProcTable.h | 1 + rpcs3/Emu/RSX/GL/GLProgramBuffer.h | 2 +- rpcs3/Emu/RSX/GL/GLTextOut.h | 4 ++-- 8 files changed, 52 insertions(+), 19 deletions(-) diff --git a/rpcs3/Emu/RSX/GL/GLCompute.h b/rpcs3/Emu/RSX/GL/GLCompute.h index 779d43c745..850656c8f7 100644 --- a/rpcs3/Emu/RSX/GL/GLCompute.h +++ b/rpcs3/Emu/RSX/GL/GLCompute.h @@ -50,7 +50,7 @@ namespace gl m_program.create(); m_program.attach(m_shader); - m_program.make(); + m_program.link(); compiled = true; } diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index 389ca79437..998125fdd5 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -76,6 +76,7 @@ void GLGSRender::on_init_thread() // Bind primary context to main RSX thread m_frame->set_current(m_context); + gl::set_primary_context_thread(); zcull_ctrl.reset(static_cast<::rsx::reports::ZCULL_control*>(this)); @@ -625,6 +626,11 @@ bool GLGSRender::load_program() } } } + else + { + verify(HERE), m_program; + m_program->sync(); + } return m_program != nullptr; } @@ -946,13 +952,5 @@ void GLGSRender::on_decompiler_exit() bool GLGSRender::on_decompiler_task() { - const auto result = m_prog_buffer.async_update(8); - if (result.second) - { - // TODO: Proper synchronization with renderer - // Finish works well enough for now but it is not a proper soulution - glFinish(); - } - - return result.first; + return m_prog_buffer.async_update(8).first; } diff --git a/rpcs3/Emu/RSX/GL/GLHelpers.cpp b/rpcs3/Emu/RSX/GL/GLHelpers.cpp index 012a9fe345..9fb537e0bd 100644 --- a/rpcs3/Emu/RSX/GL/GLHelpers.cpp +++ b/rpcs3/Emu/RSX/GL/GLHelpers.cpp @@ -11,6 +11,18 @@ namespace gl capabilities g_driver_caps; const fbo screen{}; + thread_local bool tls_primary_context_thread = false; + + void set_primary_context_thread() + { + tls_primary_context_thread = true; + } + + bool is_primary_context_thread() + { + return tls_primary_context_thread; + } + GLenum draw_mode(rsx::primitive_type in) { switch (in) diff --git a/rpcs3/Emu/RSX/GL/GLHelpers.h b/rpcs3/Emu/RSX/GL/GLHelpers.h index 3364ecdcf5..16f4aceb64 100644 --- a/rpcs3/Emu/RSX/GL/GLHelpers.h +++ b/rpcs3/Emu/RSX/GL/GLHelpers.h @@ -86,6 +86,9 @@ namespace gl bool is_primitive_native(rsx::primitive_type in); GLenum draw_mode(rsx::primitive_type in); + void set_primary_context_thread(); + bool is_primary_context_thread(); + // Texture helpers std::array apply_swizzle_remap(const std::array& swizzle_remap, const std::pair, std::array>& decoded_remap); @@ -391,6 +394,12 @@ namespace gl return signaled; } + + void server_wait_sync() const + { + verify(HERE), m_value != nullptr; + glWaitSync(m_value, 0, GL_TIMEOUT_IGNORED); + } }; template @@ -2533,6 +2542,7 @@ public: class program { GLuint m_id = 0; + fence m_fence; public: class uniform_t @@ -2717,6 +2727,15 @@ public: rsx_log.fatal("Linkage failed: %s", error_msg); } + else + { + m_fence.create(); + + if (!is_primary_context_thread()) + { + glFlush(); + } + } } void validate() @@ -2743,11 +2762,6 @@ public: } } - void make() - { - link(); - } - uint id() const { return m_id; @@ -2764,6 +2778,14 @@ public: return m_id != 0; } + void sync() + { + if (!m_fence.check_signaled()) + { + m_fence.server_wait_sync(); + } + } + explicit operator bool() const { return created(); diff --git a/rpcs3/Emu/RSX/GL/GLOverlays.h b/rpcs3/Emu/RSX/GL/GLOverlays.h index 8145cf3424..3dc134ad0a 100644 --- a/rpcs3/Emu/RSX/GL/GLOverlays.h +++ b/rpcs3/Emu/RSX/GL/GLOverlays.h @@ -66,7 +66,7 @@ namespace gl program_handle.create(); program_handle.attach(vs); program_handle.attach(fs); - program_handle.make(); + program_handle.link(); fbo.create(); diff --git a/rpcs3/Emu/RSX/GL/GLProcTable.h b/rpcs3/Emu/RSX/GL/GLProcTable.h index 9cbdb66e42..4916521aec 100644 --- a/rpcs3/Emu/RSX/GL/GLProcTable.h +++ b/rpcs3/Emu/RSX/GL/GLProcTable.h @@ -217,6 +217,7 @@ OPENGL_PROC(PFNGLBUFFERSTORAGEPROC, BufferStorage); // ARB_sync OPENGL_PROC(PFNGLFENCESYNCPROC, FenceSync); OPENGL_PROC(PFNGLCLIENTWAITSYNCPROC, ClientWaitSync); +OPENGL_PROC(PFNGLWAITSYNCPROC, WaitSync); OPENGL_PROC(PFNGLGETSYNCIVPROC, GetSynciv); OPENGL_PROC(PFNGLDELETESYNCPROC, DeleteSync); diff --git a/rpcs3/Emu/RSX/GL/GLProgramBuffer.h b/rpcs3/Emu/RSX/GL/GLProgramBuffer.h index 42c358b94d..7a72dd3b3e 100644 --- a/rpcs3/Emu/RSX/GL/GLProgramBuffer.h +++ b/rpcs3/Emu/RSX/GL/GLProgramBuffer.h @@ -42,7 +42,7 @@ struct GLTraits .bind_fragment_data_location("ocol1", 1) .bind_fragment_data_location("ocol2", 2) .bind_fragment_data_location("ocol3", 3) - .make(); + .link(); // Progam locations are guaranteed to not change after linking // Texture locations are simply bound to the TIUs so this can be done once diff --git a/rpcs3/Emu/RSX/GL/GLTextOut.h b/rpcs3/Emu/RSX/GL/GLTextOut.h index ee20d323ab..59fd25a15a 100644 --- a/rpcs3/Emu/RSX/GL/GLTextOut.h +++ b/rpcs3/Emu/RSX/GL/GLTextOut.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include "stdafx.h" #include "GLHelpers.h" @@ -63,7 +63,7 @@ namespace gl m_program.create(); m_program.attach(m_vs); m_program.attach(m_fs); - m_program.make(); + m_program.link(); } void load_program(float scale_x, float scale_y, float *offsets, size_t nb_offsets, color4f color)