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
__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)

View File

@ -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();
}

View File

@ -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

View File

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

View File

@ -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,6 +434,7 @@ void GSRendererHW::Draw()
{
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);
}
@ -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,6 +563,7 @@ void GSRendererHW::Draw()
{
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);
}
@ -580,6 +587,7 @@ void GSRendererHW::Draw()
#ifdef DISABLE_HW_TEXTURE_CACHE
if (rt)
m_tc->Read(rt, r);
#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)",
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