From 27af8d80caf6b11474c8655af10c88ffb72104a0 Mon Sep 17 00:00:00 2001 From: "Jake.Stine" Date: Fri, 18 Sep 2009 19:54:56 +0000 Subject: [PATCH] GSopen2: Simplified the multithreaded and irq callback parameter passing scheme, and made them more "robust" so that they can be changed dynamically without the GS exploding (important with the new correct GSState preservation across open/close). git-svn-id: http://pcsx2.googlecode.com/svn/branches/GSopen2@1860 96395faa-99c1-11dd-bbfe-3dabce05a288 --- plugins/GSdx/GS.cpp | 36 ++++++++++++++++++++--------- plugins/GSdx/GSRenderer.cpp | 4 ++-- plugins/GSdx/GSRenderer.h | 6 ++--- plugins/GSdx/GSRendererDX.h | 4 ++-- plugins/GSdx/GSRendererDX10.cpp | 4 ++-- plugins/GSdx/GSRendererDX10.h | 2 +- plugins/GSdx/GSRendererDX11.cpp | 4 ++-- plugins/GSdx/GSRendererDX11.h | 2 +- plugins/GSdx/GSRendererDX9.cpp | 4 ++-- plugins/GSdx/GSRendererDX9.h | 2 +- plugins/GSdx/GSRendererHW.h | 4 ++-- plugins/GSdx/GSRendererNull.h | 4 ++-- plugins/GSdx/GSRendererOGL.cpp | 4 ++-- plugins/GSdx/GSRendererOGL.h | 2 +- plugins/GSdx/GSRendererSW.cpp | 4 ++-- plugins/GSdx/GSRendererSW.h | 2 +- plugins/GSdx/GSState.cpp | 41 +++++++++++++++++++++++++-------- plugins/GSdx/GSState.h | 4 +++- 18 files changed, 85 insertions(+), 48 deletions(-) diff --git a/plugins/GSdx/GS.cpp b/plugins/GSdx/GS.cpp index 20cb695473..06ea0b6356 100644 --- a/plugins/GSdx/GS.cpp +++ b/plugins/GSdx/GS.cpp @@ -126,7 +126,7 @@ EXPORT_C GSclose() s_gs->m_wnd.Detach(); } -static INT32 GSopen(void* dsp, char* title, int mt, int renderer) +static INT32 _GSopen(void* dsp, char* title, int renderer) { GSclose(); @@ -153,17 +153,17 @@ static INT32 GSopen(void* dsp, char* title, int mt, int renderer) switch(renderer) { default: - case 0: s_gs = new GSRendererDX9(!!mt, s_irq); break; - case 3: s_gs = new GSRendererDX10(!!mt, s_irq); break; - case 6: s_gs = new GSRendererDX11(!!mt, s_irq); break; + case 0: s_gs = new GSRendererDX9(); break; + case 3: s_gs = new GSRendererDX10(); break; + case 6: s_gs = new GSRendererDX11(); break; #if 0 - case 9: s_gs = new GSRendererOGL(!!mt, s_irq); break; + case 9: s_gs = new GSRendererOGL(); break; #endif case 2: case 5: case 8: case 11: case 13: - s_gs = new GSRendererNull(!!mt, s_irq); break; + s_gs = new GSRendererNull(); break; case 1: case 4: case 7: case 10: case 12: - s_gs = new GSRendererSW(!!mt, s_irq); break; + s_gs = new GSRendererSW(); break; } } } @@ -176,7 +176,8 @@ static INT32 GSopen(void* dsp, char* title, int mt, int renderer) return -1; } - s_gs->SetRegsMem( s_basemem ); + s_gs->SetRegsMem(s_basemem); + s_gs->SetIrqCallback(s_irq); if( *(HWND*)dsp == NULL ) { @@ -196,6 +197,7 @@ static INT32 GSopen(void* dsp, char* title, int mt, int renderer) } else { + s_gs->SetMultithreaded( true ); s_gs->m_wnd.Attach( *(HWND*)dsp, false ); } @@ -221,7 +223,7 @@ EXPORT_C_(INT32) GSopen2( void* dsp, INT32 flags ) renderer = 1; } - return GSopen( dsp, NULL, true, renderer ); + return _GSopen( dsp, NULL, renderer ); } EXPORT_C_(INT32) GSopen(void* dsp, char* title, int mt) @@ -241,7 +243,15 @@ EXPORT_C_(INT32) GSopen(void* dsp, char* title, int mt) } *(HWND*)dsp = NULL; - return GSopen(dsp, title, mt, renderer); + + int retval = _GSopen(dsp, title, renderer); + + if( retval == 0 && s_gs ) + { + s_gs->SetMultithreaded( false ); + } + + return retval; } EXPORT_C GSreset() @@ -348,6 +358,10 @@ EXPORT_C GSabout() EXPORT_C GSirqCallback(void (*irq)()) { s_irq = irq; + if( s_gs ) + { + s_gs->SetIrqCallback(s_irq); + } } EXPORT_C_(int) GSsetupRecording(int start, void* data) @@ -409,7 +423,7 @@ EXPORT_C GSReplay(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) GSsetBaseMem(regs); HWND hWnd = NULL; - GSopen(&hWnd, "", true, renderer); + GSopen(&hWnd, "", renderer); uint32 crc; fread(&crc, 4, 1, fp); diff --git a/plugins/GSdx/GSRenderer.cpp b/plugins/GSdx/GSRenderer.cpp index b6b6c3e53f..f2c484ea3d 100644 --- a/plugins/GSdx/GSRenderer.cpp +++ b/plugins/GSdx/GSRenderer.cpp @@ -22,8 +22,8 @@ #include "StdAfx.h" #include "GSRenderer.h" -GSRenderer::GSRenderer(bool mt, void (*irq)()) - : GSState(mt, irq) +GSRenderer::GSRenderer() + : GSState() , m_dev(NULL) , m_shader(0) , m_vt(this) diff --git a/plugins/GSdx/GSRenderer.h b/plugins/GSdx/GSRenderer.h index 420e46c7f0..6b441368d9 100644 --- a/plugins/GSdx/GSRenderer.h +++ b/plugins/GSdx/GSRenderer.h @@ -69,7 +69,7 @@ public: int s_saven; public: - GSRenderer(bool mt, void (*irq)()); + GSRenderer(); virtual ~GSRenderer(); virtual bool CreateWnd(const string& title, int w, int h); @@ -217,8 +217,8 @@ protected: virtual void Draw() = 0; public: - GSRendererT(bool mt, void (*irq)()) - : GSRenderer(mt, irq) + GSRendererT() + : GSRenderer() , m_vertices(NULL) , m_count(0) , m_maxcount(0) diff --git a/plugins/GSdx/GSRendererDX.h b/plugins/GSdx/GSRendererDX.h index ef67661cc2..2034d8282f 100644 --- a/plugins/GSdx/GSRendererDX.h +++ b/plugins/GSdx/GSRendererDX.h @@ -40,8 +40,8 @@ protected: virtual void UpdateFBA(GSTexture* rt) {} public: - GSRendererDX(bool mt, void (*irq)(), GSTextureCache* tc, const GSVector2& pixelcenter = GSVector2(0, 0)) - : GSRendererHW(mt, irq, tc) + GSRendererDX(GSTextureCache* tc, const GSVector2& pixelcenter = GSVector2(0, 0)) + : GSRendererHW(tc) , m_pixelcenter(pixelcenter) , m_topology(-1) { diff --git a/plugins/GSdx/GSRendererDX10.cpp b/plugins/GSdx/GSRendererDX10.cpp index 61f471d2eb..32bebe2cca 100644 --- a/plugins/GSdx/GSRendererDX10.cpp +++ b/plugins/GSdx/GSRendererDX10.cpp @@ -24,8 +24,8 @@ #include "GSCrc.h" #include "resource.h" -GSRendererDX10::GSRendererDX10(bool mt, void (*irq)()) - : GSRendererDX(mt, irq, new GSTextureCache10(this), GSVector2(-0.5f, -0.5f)) +GSRendererDX10::GSRendererDX10() + : GSRendererDX(new GSTextureCache10(this), GSVector2(-0.5f, -0.5f)) { InitVertexKick(); } diff --git a/plugins/GSdx/GSRendererDX10.h b/plugins/GSdx/GSRendererDX10.h index eca99b27c6..17b51589b2 100644 --- a/plugins/GSdx/GSRendererDX10.h +++ b/plugins/GSdx/GSRendererDX10.h @@ -38,7 +38,7 @@ protected: void SetupDATE(GSTexture* rt, GSTexture* ds); public: - GSRendererDX10(bool mt, void (*irq)()); + GSRendererDX10(); bool CreateDevice(GSDevice* dev); diff --git a/plugins/GSdx/GSRendererDX11.cpp b/plugins/GSdx/GSRendererDX11.cpp index 53912dfce3..d7eeb0a46c 100644 --- a/plugins/GSdx/GSRendererDX11.cpp +++ b/plugins/GSdx/GSRendererDX11.cpp @@ -24,8 +24,8 @@ #include "GSCrc.h" #include "resource.h" -GSRendererDX11::GSRendererDX11(bool mt, void (*irq)()) - : GSRendererDX(mt, irq, new GSTextureCache11(this), GSVector2(-0.5f, -0.5f)) +GSRendererDX11::GSRendererDX11() + : GSRendererDX(new GSTextureCache11(this), GSVector2(-0.5f, -0.5f)) { InitVertexKick(); } diff --git a/plugins/GSdx/GSRendererDX11.h b/plugins/GSdx/GSRendererDX11.h index a389de7012..35411f90b8 100644 --- a/plugins/GSdx/GSRendererDX11.h +++ b/plugins/GSdx/GSRendererDX11.h @@ -39,7 +39,7 @@ protected: void SetupDATE(GSTexture* rt, GSTexture* ds); public: - GSRendererDX11(bool mt, void (*irq)()); + GSRendererDX11(); bool CreateDevice(GSDevice* dev); diff --git a/plugins/GSdx/GSRendererDX9.cpp b/plugins/GSdx/GSRendererDX9.cpp index 9bc79a3849..78135c2742 100644 --- a/plugins/GSdx/GSRendererDX9.cpp +++ b/plugins/GSdx/GSRendererDX9.cpp @@ -24,8 +24,8 @@ #include "GSCrc.h" #include "resource.h" -GSRendererDX9::GSRendererDX9(bool mt, void (*irq)()) - : GSRendererDX(mt, irq, new GSTextureCache9(this)) +GSRendererDX9::GSRendererDX9() + : GSRendererDX(new GSTextureCache9(this)) { InitVertexKick(); } diff --git a/plugins/GSdx/GSRendererDX9.h b/plugins/GSdx/GSRendererDX9.h index 26884ae89d..1772830694 100644 --- a/plugins/GSdx/GSRendererDX9.h +++ b/plugins/GSdx/GSRendererDX9.h @@ -45,7 +45,7 @@ protected: void UpdateFBA(GSTexture* rt); public: - GSRendererDX9(bool mt, void (*irq)()); + GSRendererDX9(); bool CreateDevice(GSDevice* dev); diff --git a/plugins/GSdx/GSRendererHW.h b/plugins/GSdx/GSRendererHW.h index 597392f858..985b447089 100644 --- a/plugins/GSdx/GSRendererHW.h +++ b/plugins/GSdx/GSRendererHW.h @@ -704,8 +704,8 @@ protected: } public: - GSRendererHW(bool mt, void (*irq)(), GSTextureCache* tc) - : GSRendererT(mt, irq) + GSRendererHW(GSTextureCache* tc) + : GSRendererT() , m_tc(tc) , m_width(1024) , m_height(1024) diff --git a/plugins/GSdx/GSRendererNull.h b/plugins/GSdx/GSRendererNull.h index 2fbb488a12..b1c5b60b14 100644 --- a/plugins/GSdx/GSRendererNull.h +++ b/plugins/GSdx/GSRendererNull.h @@ -37,8 +37,8 @@ protected: } public: - GSRendererNull(bool mt, void (*irq)()) - : GSRendererT(mt, irq) + GSRendererNull() + : GSRendererT() { InitVertexKick(); } diff --git a/plugins/GSdx/GSRendererOGL.cpp b/plugins/GSdx/GSRendererOGL.cpp index dba86b4b15..cbbe87f381 100644 --- a/plugins/GSdx/GSRendererOGL.cpp +++ b/plugins/GSdx/GSRendererOGL.cpp @@ -24,8 +24,8 @@ #include "GSCrc.h" #include "resource.h" -GSRendererOGL::GSRendererOGL(bool mt, void (*irq)()) - : GSRendererHW(mt, irq, new GSTextureCacheOGL(this)) +GSRendererOGL::GSRendererOGL() + : GSRendererHW(new GSTextureCacheOGL(this)) { InitVertexKick(); } diff --git a/plugins/GSdx/GSRendererOGL.h b/plugins/GSdx/GSRendererOGL.h index a769898c44..e9accf1a87 100644 --- a/plugins/GSdx/GSRendererOGL.h +++ b/plugins/GSdx/GSRendererOGL.h @@ -31,7 +31,7 @@ protected: void Draw(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex); public: - GSRendererOGL(bool mt, void (*irq)()); + GSRendererOGL(); bool CreateDevice(GSDevice* dev); diff --git a/plugins/GSdx/GSRendererSW.cpp b/plugins/GSdx/GSRendererSW.cpp index 00171e2e33..10cc08b782 100644 --- a/plugins/GSdx/GSRendererSW.cpp +++ b/plugins/GSdx/GSRendererSW.cpp @@ -24,8 +24,8 @@ const GSVector4 g_pos_scale(1.0f / 16, 1.0f / 16, 1.0f, 128.0f); -GSRendererSW::GSRendererSW(bool mt, void (*irq)()) - : GSRendererT(mt, irq) +GSRendererSW::GSRendererSW() + : GSRendererT() { m_tc = new GSTextureCacheSW(this); diff --git a/plugins/GSdx/GSRendererSW.h b/plugins/GSdx/GSRendererSW.h index b14462f004..0aac07b450 100644 --- a/plugins/GSdx/GSRendererSW.h +++ b/plugins/GSdx/GSRendererSW.h @@ -44,7 +44,7 @@ protected: void GetScanlineParam(GSScanlineParam& p, GS_PRIM_CLASS primclass); public: - GSRendererSW(bool mt, void (*irq)()); + GSRendererSW(); virtual ~GSRendererSW(); template diff --git a/plugins/GSdx/GSState.cpp b/plugins/GSdx/GSState.cpp index d41a92c5c2..ef01439854 100644 --- a/plugins/GSdx/GSState.cpp +++ b/plugins/GSdx/GSState.cpp @@ -22,9 +22,10 @@ #include "stdafx.h" #include "GSState.h" -GSState::GSState(bool mt, void (*irq)()) - : m_mt(mt) - , m_irq(irq) +GSState::GSState() + : m_mt(false) + , m_irq(NULL) + , m_regs(NULL) , m_crc(0) , m_options(0) , m_path3hack(0) @@ -97,12 +98,38 @@ GSState::~GSState() { } -void GSState::SetRegsMem( uint8* basemem ) +void GSState::SetRegsMem(uint8* basemem) { ASSERT(basemem); m_regs = (GSPrivRegSet*)basemem; } +void GSState::SetIrqCallback(void (*irq)()) +{ + m_irq = irq; +} + +void GSState::SetMultithreaded( bool isMT ) +{ + // Some older versions of PCSX2 didn't properly set the irq callback to NULL + // in multithreaded mode (possibly because ZeroGS itself would assert in such + // cases), and didn't bind them to a dummy callback either. PCSX2 handles all + // IRQs internally when multithreaded anyway -- so let's ignore them here: + + m_mt = isMT; + if( isMT ) + { + m_fpGIFRegHandlers[GIF_A_D_REG_SIGNAL] = &GSState::GIFRegHandlerNull; + m_fpGIFRegHandlers[GIF_A_D_REG_FINISH] = &GSState::GIFRegHandlerNull; + m_fpGIFRegHandlers[GIF_A_D_REG_LABEL] = &GSState::GIFRegHandlerNull; + } + else + { + m_fpGIFRegHandlers[GIF_A_D_REG_SIGNAL] = &GSState::GIFRegHandlerSIGNAL; + m_fpGIFRegHandlers[GIF_A_D_REG_FINISH] = &GSState::GIFRegHandlerFINISH; + m_fpGIFRegHandlers[GIF_A_D_REG_LABEL] = &GSState::GIFRegHandlerLABEL; + } +} void GSState::Reset() { @@ -915,8 +942,6 @@ void GSState::GIFRegHandlerHWREG(GIFReg* r) void GSState::GIFRegHandlerSIGNAL(GIFReg* r) { - if(m_mt) return; - m_regs->SIGLBLID.SIGID = (m_regs->SIGLBLID.SIGID & ~r->SIGNAL.IDMSK) | (r->SIGNAL.ID & r->SIGNAL.IDMSK); if(m_regs->CSR.wSIGNAL) m_regs->CSR.rSIGNAL = 1; @@ -925,16 +950,12 @@ void GSState::GIFRegHandlerSIGNAL(GIFReg* r) void GSState::GIFRegHandlerFINISH(GIFReg* r) { - if(m_mt) return; - if(m_regs->CSR.wFINISH) m_regs->CSR.rFINISH = 1; if(!m_regs->IMR.FINISHMSK && m_irq) m_irq(); } void GSState::GIFRegHandlerLABEL(GIFReg* r) { - if(m_mt) return; - m_regs->SIGLBLID.LBLID = (m_regs->SIGLBLID.LBLID & ~r->LABEL.IDMSK) | (r->LABEL.ID & r->LABEL.IDMSK); } diff --git a/plugins/GSdx/GSState.h b/plugins/GSdx/GSState.h index 01ca087d8e..b752b752c6 100644 --- a/plugins/GSdx/GSState.h +++ b/plugins/GSdx/GSState.h @@ -215,7 +215,7 @@ public: GSDump m_dump; public: - GSState(bool mt, void (*irq)()); + GSState(); virtual ~GSState(); void ResetHandlers(); @@ -251,5 +251,7 @@ public: void SetFrameSkip(int skip); void SetFrameLimit(bool limit); void SetRegsMem( uint8* basemem ); + void SetIrqCallback(void (*irq)()); + void SetMultithreaded( bool isMT=true ); };