gsdx: GS kinds of support draw without framebuffer

Gow uses 24 bits buffer, so only color is updated but blending is configured as Cd
so it is a NOP

In this case, we don't lookup the target in the texture cache. It reduces the complexity
to handle depth which can be located at same address as RT

Note: please test DX renderer
This commit is contained in:
Gregory Hainaut 2015-06-05 22:37:34 +02:00
parent e3adf823b3
commit 35081f922a
6 changed files with 31 additions and 21 deletions

View File

@ -523,6 +523,7 @@ REG_END2
// opaque => output will be Cs/As // 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() 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 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 REG_END2
REG64_(GIFReg, BITBLTBUF) REG64_(GIFReg, BITBLTBUF)

View File

@ -996,7 +996,6 @@ void GSDeviceOGL::SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* ver
{ {
GL_PUSH("DATE First Pass"); 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 // sfex3 (after the capcom logo), vf4 (first menu fading in), ffxii shadows, rumble roses shadows, persona4 shadows
BeginScene(); BeginScene();
@ -1016,7 +1015,7 @@ void GSDeviceOGL::SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* ver
OMSetDepthStencilState(m_date.dss, 1); OMSetDepthStencilState(m_date.dss, 1);
OMSetBlendState(m_date.bs, 0); OMSetBlendState(m_date.bs, 0);
// normally ok without any RT if GL_ARB_framebuffer_no_attachments is supported (minus driver bug) // 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 OMSetColorMaskState(); // TODO: likely useless
// ia // ia
@ -1035,9 +1034,7 @@ void GSDeviceOGL::SetupDATE(GSTexture* rt, GSTexture* ds, const GSVertexPT1* ver
PSSetSamplerState(m_convert.pt); PSSetSamplerState(m_convert.pt);
} }
OMSetWriteBuffer(GL_NONE);
DrawPrimitive(); DrawPrimitive();
OMSetWriteBuffer();
EndScene(); EndScene();
@ -1179,9 +1176,10 @@ void GSDeviceOGL::OMSetRenderTargets(GSTexture* rt, GSTexture* ds, const GSVecto
if (rt == NULL || !RT->IsBackbuffer()) { if (rt == NULL || !RT->IsBackbuffer()) {
OMSetFBO(m_fbo); OMSetFBO(m_fbo);
if (rt) { if (rt) {
OMSetWriteBuffer();
OMAttachRt(RT); OMAttachRt(RT);
} else { } else {
// Note: NULL rt is only used in DATE so far. OMSetWriteBuffer(GL_NONE);
OMAttachRt(); OMAttachRt();
} }

View File

@ -47,8 +47,8 @@ void GSRendererDX::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sourc
GSDrawingEnvironment& env = m_env; GSDrawingEnvironment& env = m_env;
GSDrawingContext* context = m_context; GSDrawingContext* context = m_context;
const GSVector2i& rtsize = rt->GetSize(); const GSVector2i& rtsize = ds->GetSize();
const GSVector2& rtscale = rt->GetScale(); const GSVector2& rtscale = ds->GetScale();
bool DATE = m_context->TEST.DATE && context->FRAME.PSM != PSM_PSMCT24; 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, //The resulting shifted output aligns better with common blending / corona / blurring effects,
//but introduces a few bad pixels on the edges. //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 // DX9 has pixelcenter set to 0.0, so give it some value here

View File

@ -231,6 +231,9 @@ void GSRendererDX9::SetupIA()
void GSRendererDX9::UpdateFBA(GSTexture* rt) void GSRendererDX9::UpdateFBA(GSTexture* rt)
{ {
if (!rt)
return;
GSDevice9* dev = (GSDevice9*)m_dev; GSDevice9* dev = (GSDevice9*)m_dev;
dev->BeginScene(); dev->BeginScene();

View File

@ -334,12 +334,17 @@ void GSRendererHW::Draw()
GSDrawingEnvironment& env = m_env; GSDrawingEnvironment& env = m_env;
GSDrawingContext* context = m_context; 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; GIFRegTEX0 TEX0;
TEX0.TBP0 = context->FRAME.Block(); TEX0.TBP0 = context->FRAME.Block();
TEX0.TBW = context->FRAME.FBW; TEX0.TBW = context->FRAME.FBW;
TEX0.PSM = context->FRAME.PSM; 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.TBP0 = context->ZBUF.Block();
TEX0.TBW = context->FRAME.FBW; 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()); 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(); GL_POP();
ASSERT(0); ASSERT(0);
@ -429,6 +434,7 @@ void GSRendererHW::Draw()
{ {
s = format("%05d_f%lld_rt0_%05x_%d.bmp", s_n, frame, context->FRAME.Block(), context->FRAME.PSM); s = format("%05d_f%lld_rt0_%05x_%d.bmp", s_n, frame, context->FRAME.Block(), context->FRAME.PSM);
if (rt)
rt->m_texture->Save(root_hw+s); rt->m_texture->Save(root_hw+s);
} }
@ -447,7 +453,7 @@ void GSRendererHW::Draw()
#endif #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 s_n += 1; // keep counter sync
GL_POP(); 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)); 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); rt->m_valid = rt->m_valid.runion(r);
@ -557,6 +563,7 @@ void GSRendererHW::Draw()
{ {
s = format("%05d_f%lld_rt1_%05x_%d.bmp", s_n, frame, context->FRAME.Block(), context->FRAME.PSM); s = format("%05d_f%lld_rt1_%05x_%d.bmp", s_n, frame, context->FRAME.Block(), context->FRAME.PSM);
if (rt)
rt->m_texture->Save(root_hw+s); rt->m_texture->Save(root_hw+s);
} }
@ -580,6 +587,7 @@ void GSRendererHW::Draw()
#ifdef DISABLE_HW_TEXTURE_CACHE #ifdef DISABLE_HW_TEXTURE_CACHE
if (rt)
m_tc->Read(rt, r); m_tc->Read(rt, r);
#endif #endif

View File

@ -217,13 +217,13 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
{ {
GL_PUSH("GL Draw from %d in %d (Depth %d)", GL_PUSH("GL Draw from %d in %d (Depth %d)",
tex && tex->m_texture ? tex->m_texture->GetID() : 0, tex && tex->m_texture ? tex->m_texture->GetID() : 0,
rt->GetID(), ds->GetID()); rt ? rt->GetID() : -1, ds->GetID());
GSDrawingEnvironment& env = m_env; GSDrawingEnvironment& env = m_env;
GSDrawingContext* context = m_context; GSDrawingContext* context = m_context;
const GSVector2i& rtsize = rt->GetSize(); const GSVector2i& rtsize = ds->GetSize();
const GSVector2& rtscale = rt->GetScale(); const GSVector2& rtscale = ds->GetScale();
bool DATE = m_context->TEST.DATE && context->FRAME.PSM != PSM_PSMCT24; bool DATE = m_context->TEST.DATE && context->FRAME.PSM != PSM_PSMCT24;
bool DATE_GL42 = false; 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, //The resulting shifted output aligns better with common blending / corona / blurring effects,
//but introduces a few bad pixels on the edges. //but introduces a few bad pixels on the edges.
if (rt->LikelyOffset) if (rt && rt->LikelyOffset)
{ {
ox2 *= rt->OffsetHack_modx; ox2 *= rt->OffsetHack_modx;
oy2 *= rt->OffsetHack_mody; 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 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; 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); GL_INS("!!! SW blending effect used (0x%x from sel %d) !!!", bogus_blend, blend_sel);
// select a shader that support blending // select a shader that support blending