diff --git a/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp b/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp index 6412e9a42479..d923913d9608 100644 --- a/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp +++ b/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp @@ -906,7 +906,7 @@ bool FragmentProgramDecompiler::handle_sct_scb(u32 opcode) // SCB-only ops case RSX_FP_OPCODE_COS: SetDst("cos($0.xxxx)"); return true; - case RSX_FP_OPCODE_DST: SetDst("distance($0, $1).xxxx", OPFLAGS::src_cast_f32); return true; + case RSX_FP_OPCODE_DST: SetDst("$Ty(1.0, $0.y * $1.y, $0.z, $1.w)", OPFLAGS::op_extern); return true; case RSX_FP_OPCODE_REFL: SetDst(getFunction(FUNCTION::FUNCTION_REFL), OPFLAGS::op_extern); return true; case RSX_FP_OPCODE_EX2: SetDst("exp2($0.xxxx)"); return true; case RSX_FP_OPCODE_FLR: SetDst("floor($0)"); return true; diff --git a/rpcs3/Emu/RSX/Common/VertexProgramDecompiler.cpp b/rpcs3/Emu/RSX/Common/VertexProgramDecompiler.cpp index c4d54775ec23..4c3c3ce51fbc 100644 --- a/rpcs3/Emu/RSX/Common/VertexProgramDecompiler.cpp +++ b/rpcs3/Emu/RSX/Common/VertexProgramDecompiler.cpp @@ -574,7 +574,7 @@ std::string VertexProgramDecompiler::Decompile() case RSX_VEC_OPCODE_DP3: SetDSTVec(getFunction(FUNCTION::FUNCTION_DP3)); break; case RSX_VEC_OPCODE_DPH: SetDSTVec(getFunction(FUNCTION::FUNCTION_DPH)); break; case RSX_VEC_OPCODE_DP4: SetDSTVec(getFunction(FUNCTION::FUNCTION_DP4)); break; - case RSX_VEC_OPCODE_DST: SetDSTVec("vec4(distance($0, $1))"); break; + case RSX_VEC_OPCODE_DST: SetDSTVec("vec4(1.0, $0.y * $1.y, $0.z, $1.w)"); break; case RSX_VEC_OPCODE_MIN: SetDSTVec("min($0, $1)"); break; case RSX_VEC_OPCODE_MAX: SetDSTVec("max($0, $1)"); break; case RSX_VEC_OPCODE_SLT: SetDSTVec(getFloatTypeName(4) + "(" + compareFunction(COMPARE::FUNCTION_SLT, "$0", "$1") + ")"); break; diff --git a/rpcs3/Emu/RSX/GL/GLCompute.h b/rpcs3/Emu/RSX/GL/GLCompute.h index 779d43c74565..850656c8f742 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 389ca79437f4..998125fdd581 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 012a9fe3455f..9fb537e0bd76 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 3364ecdcf5d2..16f4aceb6449 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 @@ namespace gl class program { GLuint m_id = 0; + fence m_fence; public: class uniform_t @@ -2717,6 +2727,15 @@ namespace gl rsx_log.fatal("Linkage failed: %s", error_msg); } + else + { + m_fence.create(); + + if (!is_primary_context_thread()) + { + glFlush(); + } + } } void validate() @@ -2743,11 +2762,6 @@ namespace gl } } - void make() - { - link(); - } - uint id() const { return m_id; @@ -2764,6 +2778,14 @@ namespace gl 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 8145cf342411..3dc134ad0a09 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 9cbdb66e4258..4916521aecf6 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 42c358b94de5..7a72dd3b3ebd 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 ee20d323ab98..59fd25a15abf 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)