From e5f629da3769caf71011312e7be95c640d2073c1 Mon Sep 17 00:00:00 2001 From: pierre Date: Wed, 4 Aug 2010 21:02:32 +0000 Subject: [PATCH] Fix saving states on mesa3d and clean up the handling of asynchronous requests (those originating from a thread other than the gpu thread) glxMakeCurrent is supposed to error out when the context is still current in another thread. NVIDIA handles that, but mesa3d errors. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6054 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/VideoCommon/Src/Fifo.cpp | 6 +- Source/Core/VideoCommon/Src/Fifo.h | 4 +- .../Plugin_VideoDX11/Src/VertexManager.cpp | 1 + Source/Plugins/Plugin_VideoDX11/Src/main.cpp | 4 + Source/Plugins/Plugin_VideoDX11/Src/main.h | 2 + .../Plugin_VideoDX9/Src/VertexManager.cpp | 1 + Source/Plugins/Plugin_VideoDX9/Src/main.cpp | 4 + Source/Plugins/Plugin_VideoDX9/Src/main.h | 2 + .../Plugin_VideoOGL/Src/VertexManager.cpp | 2 + Source/Plugins/Plugin_VideoOGL/Src/main.cpp | 73 +++++++++++++++---- Source/Plugins/Plugin_VideoOGL/Src/main.h | 2 + 11 files changed, 78 insertions(+), 23 deletions(-) diff --git a/Source/Core/VideoCommon/Src/Fifo.cpp b/Source/Core/VideoCommon/Src/Fifo.cpp index e833a5cf52..5169129c2e 100644 --- a/Source/Core/VideoCommon/Src/Fifo.cpp +++ b/Source/Core/VideoCommon/Src/Fifo.cpp @@ -142,8 +142,7 @@ void Fifo_EnterLoop(const SVideoInitialize &video_initialize) { video_initialize.pPeekMessages(); - VideoFifo_CheckEFBAccess(); - VideoFifo_CheckSwapRequest(); + VideoFifo_CheckAsyncRequest(); // check if we are able to run this buffer @@ -209,8 +208,7 @@ void Fifo_EnterLoop(const SVideoInitialize &video_initialize) // If we don't, s_swapRequested (OGL only) or s_efbAccessRequested won't be set to false // leading the CPU thread to wait in Video_BeginField or Video_AccessEFB thus slowing things down. - VideoFifo_CheckEFBAccess(); - VideoFifo_CheckSwapRequest(); + VideoFifo_CheckAsyncRequest(); CommandProcessor::isFifoBusy = false; } diff --git a/Source/Core/VideoCommon/Src/Fifo.h b/Source/Core/VideoCommon/Src/Fifo.h index 124a019f7d..95c7630a5d 100644 --- a/Source/Core/VideoCommon/Src/Fifo.h +++ b/Source/Core/VideoCommon/Src/Fifo.h @@ -43,8 +43,6 @@ void Fifo_DoState(PointerWrap &f); void Fifo_SetRendering(bool bEnabled); // Implemented by the Video Plugin -void VideoFifo_CheckSwapRequest(); -void VideoFifo_CheckSwapRequestAt(u32 xfbAddr, u32 fbWidth, u32 fbHeight); -void VideoFifo_CheckEFBAccess(); +void VideoFifo_CheckAsyncRequest(); #endif // _FIFO_H diff --git a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp index 38a5116919..0286289fa7 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp @@ -35,6 +35,7 @@ #include "NativeVertexFormat.h" #include "NativeVertexWriter.h" #include "TextureCache.h" +#include "main.h" #include "BPStructs.h" #include "XFStructs.h" diff --git a/Source/Plugins/Plugin_VideoDX11/Src/main.cpp b/Source/Plugins/Plugin_VideoDX11/Src/main.cpp index f76dcdf85b..c6585b3909 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/main.cpp @@ -409,6 +409,10 @@ u32 Video_AccessEFB(EFBAccessType type, u32 x, u32 y, u32 InputData) return 0; } +void VideoFifo_CheckAsyncRequest() { + VideoFifo_CheckSwapRequest(); + VideoFifo_CheckEFBAccess(); +} void Video_CommandProcessorRead16(u16& _rReturnValue, const u32 _Address) { diff --git a/Source/Plugins/Plugin_VideoDX11/Src/main.h b/Source/Plugins/Plugin_VideoDX11/Src/main.h index fb3775ab7e..05ea0677fd 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/main.h +++ b/Source/Plugins/Plugin_VideoDX11/Src/main.h @@ -23,5 +23,7 @@ extern SVideoInitialize g_VideoInitialize; extern volatile u32 s_swapRequested; +void VideoFifo_CheckEFBAccess(); +void VideoFifo_CheckSwapRequestAt(u32 xfbAddr, u32 fbWidth, u32 fbHeight); #endif diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp index cf4de8c8ca..5719e94f9e 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp @@ -32,6 +32,7 @@ #include "NativeVertexFormat.h" #include "NativeVertexWriter.h" #include "TextureCache.h" +#include "main.h" #include "BPStructs.h" #include "XFStructs.h" diff --git a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp index 94d01611c4..e745bd4e56 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/main.cpp @@ -435,6 +435,10 @@ u32 Video_AccessEFB(EFBAccessType type, u32 x, u32 y,u32 InputData) return 0; } +void VideoFifo_CheckAsyncRequest() { + VideoFifo_CheckSwapRequest(); + VideoFifo_CheckEFBAccess(); +} void Video_CommandProcessorRead16(u16& _rReturnValue, const u32 _Address) { diff --git a/Source/Plugins/Plugin_VideoDX9/Src/main.h b/Source/Plugins/Plugin_VideoDX9/Src/main.h index fb3775ab7e..05ea0677fd 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/main.h +++ b/Source/Plugins/Plugin_VideoDX9/Src/main.h @@ -23,5 +23,7 @@ extern SVideoInitialize g_VideoInitialize; extern volatile u32 s_swapRequested; +void VideoFifo_CheckEFBAccess(); +void VideoFifo_CheckSwapRequestAt(u32 xfbAddr, u32 fbWidth, u32 fbHeight); #endif diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp index 746d7cfc1d..22695d7657 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp @@ -41,6 +41,8 @@ #include "OpcodeDecoding.h" #include "FileUtil.h" +#include "main.h" + // internal state for loading vertices extern NativeVertexFormat *g_nativeVertexFmt; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp index a657ac38e7..10cc1a283b 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp @@ -103,6 +103,9 @@ int GLScissorX, GLScissorY, GLScissorW, GLScissorH; static bool s_PluginInitialized = false; volatile u32 s_swapRequested = FALSE; +#if defined(HAVE_X11) && HAVE_X11 +static volatile u32 s_doStateRequested = FALSE; +#endif static u32 s_efbAccessRequested = FALSE; static volatile u32 s_FifoShuttingDown = FALSE; @@ -191,24 +194,53 @@ void Initialize(void *init) OSD::AddMessage("Dolphin OpenGL Video Plugin", 5000); } -void DoState(unsigned char **ptr, int mode) +static volatile struct { + unsigned char **ptr; + int mode; +} s_doStateArgs; + +// Run from the GPU thread on X11, CPU thread on the rest +static void check_DoState() { #if defined(HAVE_X11) && HAVE_X11 - OpenGL_MakeCurrent(); -#endif - // Clear all caches that touch RAM - TextureMngr::Invalidate(false); - VertexLoaderManager::MarkAllDirty(); - - PointerWrap p(ptr, mode); - VideoCommon_DoState(p); - - // Refresh state. - if (mode == PointerWrap::MODE_READ) + if (Common::AtomicLoadAcquire(s_doStateRequested)) { - BPReload(); - RecomputeCachedArraybases(); +#endif + // Clear all caches that touch RAM + TextureMngr::Invalidate(false); + VertexLoaderManager::MarkAllDirty(); + + PointerWrap p(s_doStateArgs.ptr, s_doStateArgs.mode); + VideoCommon_DoState(p); + + // Refresh state. + if (s_doStateArgs.mode == PointerWrap::MODE_READ) + { + BPReload(); + RecomputeCachedArraybases(); + } + +#if defined(HAVE_X11) && HAVE_X11 + Common::AtomicStoreRelease(s_doStateRequested, FALSE); } +#endif +} + +// Run from the CPU thread +void DoState(unsigned char **ptr, int mode) { + s_doStateArgs.ptr = ptr; + s_doStateArgs.mode = mode; +#if defined(HAVE_X11) && HAVE_X11 + Common::AtomicStoreRelease(s_doStateRequested, TRUE); + if (g_VideoInitialize.bOnThread) + { + while (Common::AtomicLoadAcquire(s_doStateRequested) && !s_FifoShuttingDown) + //Common::SleepCurrentThread(1); + Common::YieldCPU(); + } + else +#endif + check_DoState(); } void EmuStateChange(PLUGIN_EMUSTATE newState) @@ -216,7 +248,8 @@ void EmuStateChange(PLUGIN_EMUSTATE newState) Fifo_RunLoop((newState == PLUGIN_EMUSTATE_PLAY) ? true : false); } -// This is called after Video_Initialize() from the Core +// This is called after Initialize() from the Core +// Run from the graphics thread void Video_Prepare(void) { OpenGL_MakeCurrent(); @@ -335,7 +368,7 @@ void VideoFifo_CheckSwapRequest() } } -inline bool addrRangesOverlap(u32 aLower, u32 aUpper, u32 bLower, u32 bUpper) +static inline bool addrRangesOverlap(u32 aLower, u32 aUpper, u32 bLower, u32 bUpper) { return !((aLower >= bUpper) || (bLower >= aUpper)); } @@ -430,6 +463,14 @@ u32 Video_AccessEFB(EFBAccessType type, u32 x, u32 y, u32 InputData) return 0; } +void VideoFifo_CheckAsyncRequest() { + VideoFifo_CheckSwapRequest(); + VideoFifo_CheckEFBAccess(); +#if defined(HAVE_X11) && HAVE_X11 + check_DoState(); +#endif +} + void Video_CommandProcessorRead16(u16& _rReturnValue, const u32 _Address) { CommandProcessor::Read16(_rReturnValue, _Address); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/main.h b/Source/Plugins/Plugin_VideoOGL/Src/main.h index 8deae603e3..1715657d18 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/main.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/main.h @@ -22,5 +22,7 @@ extern SVideoInitialize g_VideoInitialize; extern volatile u32 s_swapRequested; +void VideoFifo_CheckEFBAccess(); +void VideoFifo_CheckSwapRequestAt(u32 xfbAddr, u32 fbWidth, u32 fbHeight); #endif // _MAIN_H_