diff --git a/plugins/GSdx/GS.h b/plugins/GSdx/GS.h index ec414a3ac3..52611fff18 100644 --- a/plugins/GSdx/GS.h +++ b/plugins/GSdx/GS.h @@ -523,6 +523,7 @@ REG_END2 // opaque => output will be Cs/As __forceinline bool IsOpaque() const {return ((A == B || (C == 2 && FIX == 0)) && D == 0) || (A == 0 && B == D && C == 2 && FIX == 0x80);} __forceinline bool IsOpaque(int amin, int amax) const {return ((A == B || amax == 0) && D == 0) || (A == 0 && B == D && amin == 0x80 && amax == 0x80);} + __forceinline bool IsCd() { return (A == B) && (D == 1);} REG_END2 REG64_(GIFReg, BITBLTBUF) diff --git a/plugins/GSdx/GSDeviceOGL.cpp b/plugins/GSdx/GSDeviceOGL.cpp index 752ec9adec..eb8ada7304 100644 --- a/plugins/GSdx/GSDeviceOGL.cpp +++ b/plugins/GSdx/GSDeviceOGL.cpp @@ -996,7 +996,6 @@ void GSDeviceOGL::SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* ver { GL_PUSH("DATE First Pass"); - GSTexture* t = NULL; // sfex3 (after the capcom logo), vf4 (first menu fading in), ffxii shadows, rumble roses shadows, persona4 shadows BeginScene(); @@ -1016,7 +1015,7 @@ void GSDeviceOGL::SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* ver OMSetDepthStencilState(m_date.dss, 1); OMSetBlendState(m_date.bs, 0); // normally ok without any RT if GL_ARB_framebuffer_no_attachments is supported (minus driver bug) - OMSetRenderTargets(t, ds, &GLState::scissor); + OMSetRenderTargets(NULL, ds, &GLState::scissor); OMSetColorMaskState(); // TODO: likely useless // ia @@ -1035,9 +1034,7 @@ void GSDeviceOGL::SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* ver PSSetSamplerState(m_convert.pt); } - OMSetWriteBuffer(GL_NONE); DrawPrimitive(); - OMSetWriteBuffer(); EndScene(); @@ -1179,9 +1176,10 @@ void GSDeviceOGL::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVecto if (rt == NULL || !RT->IsBackbuffer()) { OMSetFBO(m_fbo); if (rt) { + OMSetWriteBuffer(); OMAttachRt(RT); } else { - // Note: NULL rt is only used in DATE so far. + OMSetWriteBuffer(GL_NONE); OMAttachRt(); } diff --git a/plugins/GSdx/GSRendererDX.cpp b/plugins/GSdx/GSRendererDX.cpp index 103fb50928..755606c919 100644 --- a/plugins/GSdx/GSRendererDX.cpp +++ b/plugins/GSdx/GSRendererDX.cpp @@ -47,8 +47,8 @@ void GSRendererDX::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sourc GSDrawingEnvironment& env = m_env; GSDrawingContext* context = m_context; - const GSVector2i& rtsize = rt->GetSize(); - const GSVector2& rtscale = rt->GetScale(); + const GSVector2i& rtsize = ds->GetSize(); + const GSVector2& rtscale = ds->GetScale(); bool DATE = m_context->TEST.DATE && context->FRAME.PSM != PSM_PSMCT24; @@ -199,7 +199,7 @@ void GSRendererDX::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sourc //The resulting shifted output aligns better with common blending / corona / blurring effects, //but introduces a few bad pixels on the edges. - if(rt->LikelyOffset) + if(rt && rt->LikelyOffset) { // DX9 has pixelcenter set to 0.0, so give it some value here diff --git a/plugins/GSdx/GSRendererDX9.cpp b/plugins/GSdx/GSRendererDX9.cpp index e8c16a1040..fa078e7646 100644 --- a/plugins/GSdx/GSRendererDX9.cpp +++ b/plugins/GSdx/GSRendererDX9.cpp @@ -231,6 +231,9 @@ void GSRendererDX9::SetupIA() void GSRendererDX9::UpdateFBA(GSTexture* rt) { + if (!rt) + return; + GSDevice9* dev = (GSDevice9*)m_dev; dev->BeginScene(); diff --git a/plugins/GSdx/GSRendererHW.cpp b/plugins/GSdx/GSRendererHW.cpp index 99f1cd0db8..2876b24baa 100644 --- a/plugins/GSdx/GSRendererHW.cpp +++ b/plugins/GSdx/GSRendererHW.cpp @@ -334,12 +334,17 @@ void GSRendererHW::Draw() GSDrawingEnvironment& env = m_env; GSDrawingContext* context = m_context; + // It is allowed to use the depth and rt at the same location. However at least 1 must + // be disabled. GoW uses a Cd blending on a 24 bits buffer (no alpha) + const bool no_rt = context->ALPHA.IsCd() && PRIM->ABE && (context->FRAME.PSM == 1); + GIFRegTEX0 TEX0; TEX0.TBP0 = context->FRAME.Block(); TEX0.TBW = context->FRAME.FBW; TEX0.PSM = context->FRAME.PSM; - GSTextureCache::Target* rt = m_tc->LookupTarget(TEX0, m_width, m_height, GSTextureCache::RenderTarget, true); + + GSTextureCache::Target* rt = no_rt ? NULL : m_tc->LookupTarget(TEX0, m_width, m_height, GSTextureCache::RenderTarget, true); TEX0.TBP0 = context->ZBUF.Block(); TEX0.TBW = context->FRAME.FBW; @@ -347,7 +352,7 @@ void GSRendererHW::Draw() GSTextureCache::Target* ds = m_tc->LookupTarget(TEX0, m_width, m_height, GSTextureCache::DepthStencil, context->DepthWrite()); - if(!rt || !ds) + if((!rt && !no_rt) || !ds) { GL_POP(); ASSERT(0); @@ -429,7 +434,8 @@ void GSRendererHW::Draw() { s = format("%05d_f%lld_rt0_%05x_%d.bmp", s_n, frame, context->FRAME.Block(), context->FRAME.PSM); - rt->m_texture->Save(root_hw+s); + if (rt) + rt->m_texture->Save(root_hw+s); } if(s_savez && s_n >= s_saven) @@ -447,7 +453,7 @@ void GSRendererHW::Draw() #endif } - if(m_hacks.m_oi && !(this->*m_hacks.m_oi)(rt->m_texture, ds->m_texture, tex)) + if(m_hacks.m_oi && !(this->*m_hacks.m_oi)(NULL, ds->m_texture, tex)) { s_n += 1; // keep counter sync GL_POP(); @@ -514,7 +520,7 @@ void GSRendererHW::Draw() // - DrawPrims(rt->m_texture, ds->m_texture, tex); + DrawPrims(rt ? rt->m_texture : NULL, ds->m_texture, tex); // @@ -526,7 +532,7 @@ void GSRendererHW::Draw() GSVector4i r = GSVector4i(m_vt.m_min.p.xyxy(m_vt.m_max.p)).rintersect(GSVector4i(context->scissor.in)); - if(fm != 0xffffffff) + if(fm != 0xffffffff && rt) { rt->m_valid = rt->m_valid.runion(r); @@ -557,7 +563,8 @@ void GSRendererHW::Draw() { s = format("%05d_f%lld_rt1_%05x_%d.bmp", s_n, frame, context->FRAME.Block(), context->FRAME.PSM); - rt->m_texture->Save(root_hw+s); + if (rt) + rt->m_texture->Save(root_hw+s); } if(s_savez && s_n >= s_saven) @@ -580,7 +587,8 @@ void GSRendererHW::Draw() #ifdef DISABLE_HW_TEXTURE_CACHE - m_tc->Read(rt, r); + if (rt) + m_tc->Read(rt, r); #endif diff --git a/plugins/GSdx/GSRendererOGL.cpp b/plugins/GSdx/GSRendererOGL.cpp index d1ea0a6e19..0489ac4065 100644 --- a/plugins/GSdx/GSRendererOGL.cpp +++ b/plugins/GSdx/GSRendererOGL.cpp @@ -217,13 +217,13 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour { GL_PUSH("GL Draw from %d in %d (Depth %d)", tex && tex->m_texture ? tex->m_texture->GetID() : 0, - rt->GetID(), ds->GetID()); + rt ? rt->GetID() : -1, ds->GetID()); GSDrawingEnvironment& env = m_env; GSDrawingContext* context = m_context; - const GSVector2i& rtsize = rt->GetSize(); - const GSVector2& rtscale = rt->GetScale(); + const GSVector2i& rtsize = ds->GetSize(); + const GSVector2& rtscale = ds->GetScale(); bool DATE = m_context->TEST.DATE && context->FRAME.PSM != PSM_PSMCT24; bool DATE_GL42 = false; @@ -425,7 +425,7 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour //The resulting shifted output aligns better with common blending / corona / blurring effects, //but introduces a few bad pixels on the edges. - if (rt->LikelyOffset) + if (rt && rt->LikelyOffset) { ox2 *= rt->OffsetHack_modx; oy2 *= rt->OffsetHack_mody; @@ -621,7 +621,7 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour bool all_sw = !( (ALPHA.A == ALPHA.B) || (ALPHA.C == 2 && afix <= 1.002f) ) && (m_accurate_blend > 1); bool sw_blending = (m_accurate_blend && (bogus_blend & A_MAX)) || acc_colclip_wrap || all_sw; - if (sw_blending && om_bsel.abe) { + if (sw_blending && om_bsel.abe && rt) { GL_INS("!!! SW blending effect used (0x%x from sel %d) !!!", bogus_blend, blend_sel); // select a shader that support blending