diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index fc37fee9b8..40f319f68b 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -2143,6 +2143,21 @@ void GLGSRender::Flip() } +void GLGSRender::semaphorePGRAPHTextureReadRelease(u32 offset, u32 value) +{ + vm::write32(m_label_addr + offset, value); +} + +void GLGSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value) +{ + vm::write32(m_label_addr + offset, value); +} + +void GLGSRender::semaphorePFIFOAcquire(u32 offset, u32 value) +{ + +} + u32 LinearToSwizzleAddress(u32 x, u32 y, u32 z, u32 log2_width, u32 log2_height, u32 log2_depth) { u32 offset = 0; diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.h b/rpcs3/Emu/RSX/GL/GLGSRender.h index 495f940172..828a3bcf20 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.h +++ b/rpcs3/Emu/RSX/GL/GLGSRender.h @@ -197,4 +197,8 @@ protected: virtual void ExecCMD(u32 cmd); virtual void ExecCMD(); virtual void Flip(); + + virtual void semaphorePGRAPHTextureReadRelease(u32 offset, u32 value) override; + virtual void semaphorePGRAPHBackendRelease(u32 offset, u32 value) override; + virtual void semaphorePFIFOAcquire(u32 offset, u32 value) override; }; diff --git a/rpcs3/Emu/RSX/Null/NullGSRender.h b/rpcs3/Emu/RSX/Null/NullGSRender.h index 33875cbabe..4644856b73 100644 --- a/rpcs3/Emu/RSX/Null/NullGSRender.h +++ b/rpcs3/Emu/RSX/Null/NullGSRender.h @@ -46,4 +46,16 @@ private: virtual void Close() { } + + virtual void semaphorePGRAPHTextureReadRelease(u32 offset, u32 value) override + { + } + + virtual void semaphorePGRAPHBackendRelease(u32 offset, u32 value) override + { + } + + virtual void semaphorePFIFOAcquire(u32 offset, u32 value) override + { + } }; \ No newline at end of file diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index f204dfbd9c..754d50511e 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -201,43 +201,40 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, const u32 args_addr, const } case NV4097_SET_SEMAPHORE_OFFSET: + { + m_PGRAPH_semaphore_offset = ARGS(0); + break; + } + case NV406E_SEMAPHORE_OFFSET: { - m_set_semaphore_offset = true; - m_semaphore_offset = ARGS(0); + m_PFIFO_semaphore_offset = ARGS(0); break; } case NV406E_SEMAPHORE_ACQUIRE: { - if (ARGS(0)) - { - LOG_WARNING(RSX, "TODO: NV406E_SEMAPHORE_ACQUIRE: 0x%x", ARGS(0)); - } + semaphorePFIFOAcquire(m_PFIFO_semaphore_offset, ARGS(0)); break; } case NV406E_SEMAPHORE_RELEASE: + { + m_PFIFO_semaphore_release_value = ARGS(0); + break; + } + case NV4097_TEXTURE_READ_SEMAPHORE_RELEASE: { - if (m_set_semaphore_offset) - { - m_set_semaphore_offset = false; - vm::write32(m_label_addr + m_semaphore_offset, ARGS(0)); - } + semaphorePGRAPHTextureReadRelease(m_PGRAPH_semaphore_offset, ARGS(0)); break; } case NV4097_BACK_END_WRITE_SEMAPHORE_RELEASE: { - if (m_set_semaphore_offset) - { - m_set_semaphore_offset = false; - u32 value = ARGS(0); - value = (value & 0xff00ff00) | ((value & 0xff) << 16) | ((value >> 16) & 0xff); - - vm::write32(m_label_addr + m_semaphore_offset, value); - } + u32 value = ARGS(0); + value = (value & 0xff00ff00) | ((value & 0xff) << 16) | ((value >> 16) & 0xff); + semaphorePGRAPHBackendRelease(m_PGRAPH_semaphore_offset, value); break; } diff --git a/rpcs3/Emu/RSX/RSXThread.h b/rpcs3/Emu/RSX/RSXThread.h index 7556f40565..7e2990ea0e 100644 --- a/rpcs3/Emu/RSX/RSXThread.h +++ b/rpcs3/Emu/RSX/RSXThread.h @@ -343,8 +343,11 @@ public: s32 m_color_conv_dtdy; // Semaphore - bool m_set_semaphore_offset; - u32 m_semaphore_offset; + // PGRAPH + u32 m_PGRAPH_semaphore_offset; + //PFIFO + u32 m_PFIFO_semaphore_offset; + u32 m_PFIFO_semaphore_release_value; // Fog bool m_set_fog_mode; @@ -597,7 +600,6 @@ protected: m_set_line_width = false; m_set_line_smooth = false; m_set_shade_mode = false; - m_set_semaphore_offset = false; m_set_fog_mode = false; m_set_fog_params = false; m_set_clip_plane = false; @@ -648,6 +650,28 @@ protected: virtual void ExecCMD(u32 cmd) = 0; virtual void Flip() = 0; + /** + * This member is called when RSXThread parse a TEXTURE_READ_SEMAPHORE_RELEASE + * command. + * Backend is expected to write value at offset when current draw textures aren't + * needed anymore by the GPU and can be modified. + */ + virtual void semaphorePGRAPHTextureReadRelease(u32 offset, u32 value) = 0; + /** + * This member is called when RSXThread parse a BACK_END_WRITE_SEMAPHORE_RELEASE + * command. + * Backend is expected to write value at offset when current draw call has completed + * and render surface can be used. + */ + virtual void semaphorePGRAPHBackendRelease(u32 offset, u32 value) = 0; + /** + * This member is called when RSXThread parse a SEMAPHORE_ACQUIRE command. + * Backend and associated GPU is expected to wait that memory at offset is the same + * as value. In particular buffer/texture buffers value can change while backend is + * waiting. + */ + virtual void semaphorePFIFOAcquire(u32 offset, u32 value) = 0; + void LoadVertexData(u32 first, u32 count) { for (u32 i = 0; i < m_vertex_count; ++i)