diff --git a/Source/Core/VideoCommon/Src/Fifo.cpp b/Source/Core/VideoCommon/Src/Fifo.cpp index 1325408294..c8d8d79b83 100644 --- a/Source/Core/VideoCommon/Src/Fifo.cpp +++ b/Source/Core/VideoCommon/Src/Fifo.cpp @@ -32,6 +32,8 @@ volatile u32 g_XFBUpdateRequested = FALSE; extern u8* g_pVideoData; +volatile bool g_EFBAccessRequested = false; + namespace { static volatile bool fifoStateRun = false; @@ -139,6 +141,12 @@ void Fifo_EnterLoop(const SVideoInitialize &video_initialize) video_initialize.pPeekMessages(); #endif + if (g_EFBAccessRequested) + { + Video_OnThreadAccessEFB(); + g_EFBAccessRequested = false; + } + // Draw XFB if CP/GPfifo isn't used if (g_XFBUpdateRequested) { diff --git a/Source/Core/VideoCommon/Src/VideoCommon.h b/Source/Core/VideoCommon/Src/VideoCommon.h index be393a60f2..78006e8693 100644 --- a/Source/Core/VideoCommon/Src/VideoCommon.h +++ b/Source/Core/VideoCommon/Src/VideoCommon.h @@ -57,6 +57,8 @@ extern SVideoInitialize g_VideoInitialize; // (mb2) for XFB update hack. TODO: find a static better place extern volatile u32 g_XFBUpdateRequested; +extern volatile bool g_EFBAccessRequested; + ////////////////////////////////////////////////////////////////////////// inline u8 *Memory_GetPtr(u32 _uAddress) { diff --git a/Source/PluginSpecs/pluginspecs_video.h b/Source/PluginSpecs/pluginspecs_video.h index 4cbdba0579..780d4e7915 100644 --- a/Source/PluginSpecs/pluginspecs_video.h +++ b/Source/PluginSpecs/pluginspecs_video.h @@ -126,6 +126,7 @@ EXPORT void CALL Video_UpdateXFB(u32 _dwXFBAddr, u32 _dwWidth, u32 _dwHeight, s3 // output: response to the access request (ex: peek z data at specified coord) // EXPORT u32 CALL Video_AccessEFB(EFBAccessType type, u32 x, u32 y); +void Video_OnThreadAccessEFB(); // TODO: Find a more sympathetic place to place this // __________________________________________________________________________________________________ // Function: Video_Screenshot diff --git a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda_Synth.cpp b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda_Synth.cpp index 2501b29159..80ee9fff15 100644 --- a/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda_Synth.cpp +++ b/Source/Plugins/Plugin_DSP_HLE/Src/UCodes/UCode_Zelda_Synth.cpp @@ -87,8 +87,7 @@ _lRestart: else PB.RemLength -= pos[1]; - PB.CurAddr += pos[1] << 1; - // There should be a position fraction as well. + //PB.CurSampleFrac = TrueSamplePosition & 0xFFFF; } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp index 8ba23d64b8..4ca2d6be6c 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp @@ -907,7 +907,6 @@ void Renderer::Swap(u32 xfbAddr, u32 srcWidth, u32 srcHeight, s32 yOffset) s_bLastFrameDumped = false; } #endif - // --------------------------------------------------------------------- // Place messages on the picture, then copy it to the screen SwapBuffers(); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp index 874fe05507..eb9a4e7299 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp @@ -96,6 +96,11 @@ int GLScissorX, GLScissorY, GLScissorW, GLScissorH; static bool s_PluginInitialized = false; +static volatile u32 s_AccessEFBResult = 0, s_EFBx, s_EFBy; +static volatile EFBAccessType s_AccessEFBType; +static Common::Event s_AccessEFBDone; +static Common::CriticalSection s_criticalEFB; + #if defined(HAVE_WX) && HAVE_WX void DllDebugger(HWND _hParent, bool Show) { @@ -458,36 +463,36 @@ void Video_UpdateXFB(u32 _dwXFBAddr, u32 _dwWidth, u32 _dwHeight, s32 _dwYOffset } } -u32 Video_AccessEFB(EFBAccessType type, u32 x, u32 y) +void Video_OnThreadAccessEFB() { - switch (type) + s_criticalEFB.Enter(); + s_AccessEFBResult = 0; + + switch (s_AccessEFBType) { case PEEK_Z: { - if (!g_VideoInitialize.bUseDualCore) + u32 z = 0; + float xScale = Renderer::GetTargetScaleX(); + float yScale = Renderer::GetTargetScaleY(); + + if (g_Config.iMultisampleMode != MULTISAMPLE_OFF) { - u32 z = 0; - float xScale = Renderer::GetTargetScaleX(); - float yScale = Renderer::GetTargetScaleY(); - - if (g_Config.iMultisampleMode != MULTISAMPLE_OFF) - { - // Find the proper dimensions - TRectangle source, scaledTargetSource; - ComputeBackbufferRectangle(&source); - source.Scale(xScale, yScale, &scaledTargetSource); - // This will resolve and bind to the depth buffer - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, Renderer::ResolveAndGetDepthTarget(scaledTargetSource)); - } - - // Read the z value! Also adjust the pixel to read to the upscaled EFB resolution - // Plus we need to flip the y value as the OGL image is upside down - glReadPixels(x*xScale, Renderer::GetTargetHeight() - y*yScale, xScale, yScale, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, &z); - GL_REPORT_ERRORD(); - - // Clamp the 32bits value returned by glReadPixels to a 24bits value (GC uses a 24bits Z-Buffer) - return z / 0x100; + // Find the proper dimensions + TRectangle source, scaledTargetSource; + ComputeBackbufferRectangle(&source); + source.Scale(xScale, yScale, &scaledTargetSource); + // This will resolve and bind to the depth buffer + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, Renderer::ResolveAndGetDepthTarget(scaledTargetSource)); } + + // Read the z value! Also adjust the pixel to read to the upscaled EFB resolution + // Plus we need to flip the y value as the OGL image is upside down + glReadPixels(s_EFBx*xScale, Renderer::GetTargetHeight() - s_EFBy*yScale, xScale, yScale, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, &z); + GL_REPORT_ERRORD(); + + // Clamp the 32bits value returned by glReadPixels to a 24bits value (GC uses a 24bits Z-Buffer) + s_AccessEFBResult = z / 0x100; } break; @@ -503,6 +508,42 @@ u32 Video_AccessEFB(EFBAccessType type, u32 x, u32 y) default: break; } - return 0; + + s_AccessEFBDone.Set(); + + s_criticalEFB.Leave(); +} + +u32 Video_AccessEFB(EFBAccessType type, u32 x, u32 y) +{ + u32 result; + + s_criticalEFB.Enter(); + + s_AccessEFBType = type; + s_EFBx = x; + s_EFBy = y; + + if (g_VideoInitialize.bUseDualCore) + { + g_EFBAccessRequested = true; + s_AccessEFBDone.Init(); + } + + s_criticalEFB.Leave(); + + if (g_VideoInitialize.bUseDualCore) + s_AccessEFBDone.Wait(); + else + Video_OnThreadAccessEFB(); + + s_criticalEFB.Enter(); + if (g_VideoInitialize.bUseDualCore) + s_AccessEFBDone.Shutdown(); + + result = s_AccessEFBResult; + s_criticalEFB.Leave(); + + return result; }