diff --git a/Source/Core/VideoCommon/Src/RenderBase.h b/Source/Core/VideoCommon/Src/RenderBase.h index e8d4c55a20..31ce6ce820 100644 --- a/Source/Core/VideoCommon/Src/RenderBase.h +++ b/Source/Core/VideoCommon/Src/RenderBase.h @@ -43,6 +43,11 @@ extern int OSDChoice, OSDTime; extern bool bLastFrameDumped; +#define RSM_None 0 +#define RSM_Multipass 1 +#define RSM_Zcomploc 2 +#define RSM_UseDstAlpha 4 + // Renderer really isn't a very good name for this class - it's more like "Misc". // The long term goal is to get rid of this class and replace it with others that make // more sense. @@ -63,7 +68,7 @@ public: virtual void SetSamplerState(int stage,int texindex) = 0; virtual void SetInterlacingMode() = 0; - virtual void ApplyState(bool bUseDstAlpha) = 0; + virtual void ApplyState(u32 mode) = 0; virtual void RestoreState() = 0; // Ideal internal resolution - determined by display resolution (automatic scaling) and/or a multiple of the native EFB resolution diff --git a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp index 941bcef4ba..0ad16bad08 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/Render.cpp @@ -1211,11 +1211,11 @@ void Renderer::RestoreAPIState() BPFunctions::SetScissor(); } -void Renderer::ApplyState(bool bUseDstAlpha) +void Renderer::ApplyState(u32 mode) { HRESULT hr; - if (bUseDstAlpha) + if (mode & RSM_UseDstAlpha) { // Colors should blend against SRC1_ALPHA if (gx_state.blenddc.RenderTarget[0].SrcBlend == D3D11_BLEND_SRC_ALPHA) @@ -1275,7 +1275,7 @@ void Renderer::ApplyState(bool bUseDstAlpha) D3D::stateman->Apply(); - if (bUseDstAlpha) + if (mode & RSM_UseDstAlpha) { // restore actual state SetBlendMode(false); diff --git a/Source/Plugins/Plugin_VideoDX11/Src/Render.h b/Source/Plugins/Plugin_VideoDX11/Src/Render.h index 8f6c78fae1..ad073e4b00 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/Render.h +++ b/Source/Plugins/Plugin_VideoDX11/Src/Render.h @@ -25,7 +25,7 @@ public: void SetInterlacingMode(); // TODO: Fix confusing names (see ResetAPIState and RestoreAPIState) - void ApplyState(bool bUseDstAlpha); + void ApplyState(u32 mode); void RestoreState(); void ApplyCullDisable(); diff --git a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp index d0f5a1c338..a81bcf311f 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/VertexManager.cpp @@ -264,7 +264,7 @@ void VertexManager::vFlush() unsigned int stride = g_nativeVertexFmt->GetVertexStride(); g_nativeVertexFmt->SetupVertexPointers(); - g_renderer->ApplyState(useDstAlpha); + g_renderer->ApplyState(useDstAlpha ? RSM_UseDstAlpha : RSM_None); LoadBuffers(); Draw(stride); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp index a5aaa6485b..2ce384d167 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp @@ -247,6 +247,7 @@ void TeardownDeviceObjects() // Init functions Renderer::Renderer() { + Renderer::LastMode = RSM_None; st = new char[32768]; int fullScreenRes, x, y, w_temp, h_temp; @@ -1204,20 +1205,49 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight,cons XFBWrited = false; } -void Renderer::ApplyState(bool bUseDstAlpha) +void Renderer::ApplyState(u32 mode) { - if (bUseDstAlpha) + if(mode & RSM_Zcomploc) + { + D3D::ChangeRenderState(D3DRS_COLORWRITEENABLE, 0); + } + + if(mode & RSM_Multipass) + { + D3D::ChangeRenderState(D3DRS_ZENABLE, TRUE); + D3D::ChangeRenderState(D3DRS_ZWRITEENABLE, false); + D3D::ChangeRenderState(D3DRS_ZFUNC, D3DCMP_EQUAL); + } + + if (mode & RSM_UseDstAlpha) { D3D::ChangeRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA); D3D::ChangeRenderState(D3DRS_ALPHABLENDENABLE, false); } + Renderer::LastMode |= mode; } void Renderer::RestoreState() { - D3D::RefreshRenderState(D3DRS_COLORWRITEENABLE); - D3D::RefreshRenderState(D3DRS_ALPHABLENDENABLE); - + if(Renderer::LastMode & RSM_Zcomploc) + { + D3D::RefreshRenderState(D3DRS_COLORWRITEENABLE); + } + + if(Renderer::LastMode & RSM_Multipass) + { + D3D::RefreshRenderState(D3DRS_ALPHABLENDENABLE); + D3D::RefreshRenderState(D3DRS_ZENABLE); + D3D::RefreshRenderState(D3DRS_ZWRITEENABLE); + D3D::RefreshRenderState(D3DRS_ZFUNC); + } + + if(Renderer::LastMode & RSM_UseDstAlpha) + { + D3D::RefreshRenderState(D3DRS_COLORWRITEENABLE); + D3D::RefreshRenderState(D3DRS_ALPHABLENDENABLE); + } + Renderer::LastMode = RSM_None; // TODO: Enable this code. Caused glitches for me however (neobrain) // for (unsigned int i = 0; i < 8; ++i) // D3D::dev->SetTexture(i, NULL); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Render.h b/Source/Plugins/Plugin_VideoDX9/Src/Render.h index 6e5198b3cd..147e6bcd76 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/Render.h +++ b/Source/Plugins/Plugin_VideoDX9/Src/Render.h @@ -9,6 +9,8 @@ namespace DX9 class Renderer : public ::Renderer { +private: + u32 LastMode; public: Renderer(); ~Renderer(); @@ -24,7 +26,7 @@ public: void SetSamplerState(int stage,int texindex); void SetInterlacingMode(); - void ApplyState(bool bUseDstAlpha); + void ApplyState(u32 mode); void RestoreState(); void RenderText(const char* pstr, int left, int top, u32 color); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp index c4e8225db1..393d49d9ef 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp @@ -182,7 +182,7 @@ void VertexManager::vFlush() goto shader_fail; } // update alpha only - g_renderer->ApplyState(true); + g_renderer->ApplyState(RSM_UseDstAlpha | (bpmem.zmode.updateenable ? RSM_Multipass : RSM_None)); Draw(stride); g_renderer->RestoreState(); } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp index 9883d35fbb..cbc0605060 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp @@ -245,6 +245,7 @@ int GetNumMSAACoverageSamples(int MSAAMode) // Init functions Renderer::Renderer() { + Renderer::LastMode = RSM_None; OSDInternalW = 0; OSDInternalH = 0; @@ -515,6 +516,49 @@ Renderer::~Renderer() delete g_framebuffer_manager; } +void Renderer::ApplyState(u32 mode) +{ + if(mode & RSM_Zcomploc) + { + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + } + + if(mode & RSM_Multipass) + { + glEnable(GL_DEPTH_TEST); + glDepthMask(GL_FALSE); + glDepthFunc(GL_EQUAL); + } + + if (mode & RSM_UseDstAlpha) + { + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); + glDisable(GL_BLEND); + } + Renderer::LastMode |= mode; +} + +void Renderer::RestoreState() +{ + if(Renderer::LastMode & RSM_Zcomploc) + { + SetColorMask(); + } + + if(Renderer::LastMode & RSM_Multipass) + { + SetDepthMode(); + } + + if (Renderer::LastMode & RSM_UseDstAlpha) + { + SetColorMask(); + if (bpmem.blendmode.blendenable || bpmem.blendmode.subtract) + glEnable(GL_BLEND); + } + Renderer::LastMode = RSM_None; +} + // Create On-Screen-Messages void Renderer::DrawDebugInfo() { diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.h b/Source/Plugins/Plugin_VideoOGL/Src/Render.h index 9cf1573b56..1abab18f2b 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Render.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.h @@ -11,6 +11,8 @@ void ClearEFBCache(); class Renderer : public ::Renderer { +private: + u32 LastMode; public: Renderer(); ~Renderer(); @@ -27,8 +29,8 @@ public: void SetInterlacingMode(); // TODO: Implement and use these - void ApplyState(bool bUseDstAlpha) {} - void RestoreState() {} + void ApplyState(u32 mode); + void RestoreState(); void RenderText(const char* pstr, int left, int top, u32 color); void DrawDebugInfo(); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp index dff7f8299e..ed9b442dee 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp @@ -224,17 +224,9 @@ void VertexManager::vFlush() ps = PixelShaderCache::SetShader(DSTALPHA_ALPHA_PASS,g_nativeVertexFmt->m_components); if (ps) PixelShaderCache::SetCurrentShader(ps->glprogid); - // only update alpha - glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); - - glDisable(GL_BLEND); - - Draw(); - // restore color mask - g_renderer->SetColorMask(); - - if (bpmem.blendmode.blendenable || bpmem.blendmode.subtract) - glEnable(GL_BLEND); + g_renderer->ApplyState(RSM_UseDstAlpha | (bpmem.zmode.updateenable ? RSM_Multipass : RSM_None)); + Draw(); + g_renderer->RestoreState(); } GFX_DEBUGGER_PAUSE_AT(NEXT_FLUSH, true);