diff --git a/plugins/GSdx/GSRendererHW.cpp b/plugins/GSdx/GSRendererHW.cpp index 2876b24baa..1f4b78b6a8 100644 --- a/plugins/GSdx/GSRendererHW.cpp +++ b/plugins/GSdx/GSRendererHW.cpp @@ -537,6 +537,8 @@ void GSRendererHW::Draw() rt->m_valid = rt->m_valid.runion(r); m_tc->InvalidateVideoMem(context->offset.fb, r, false); + + m_tc->InvalidateVideoMemType(GSTextureCache::DepthStencil, context->FRAME.Block()); } if(zm != 0xffffffff) @@ -544,6 +546,8 @@ void GSRendererHW::Draw() ds->m_valid = ds->m_valid.runion(r); m_tc->InvalidateVideoMem(context->offset.zb, r, false); + + m_tc->InvalidateVideoMemType(GSTextureCache::RenderTarget, context->ZBUF.Block()); } // diff --git a/plugins/GSdx/GSTextureCache.cpp b/plugins/GSdx/GSTextureCache.cpp index 2a0fc01e68..06549004c2 100644 --- a/plugins/GSdx/GSTextureCache.cpp +++ b/plugins/GSdx/GSTextureCache.cpp @@ -152,7 +152,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const GIFRegTEX0& TEX0, con { #ifdef ENABLE_OGL_DEBUG if (dst) { - GL_CACHE("TC: dst hit (%s): %d (0x%x)", half_right ? "half" : "full", + GL_CACHE("TC: dst %s hit (%s): %d (0x%x)", dst->m_type ? "Depth" : "Color", half_right ? "half" : "full", dst->m_texture ? dst->m_texture->GetID() : 0, TEX0.TBP0); } else { @@ -165,6 +165,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const GIFRegTEX0& TEX0, con { return NULL; } + #ifdef ENABLE_OGL_DEBUG } else { GL_CACHE("TC: src hit: %d (0x%x)", @@ -258,6 +259,10 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(const GIFRegTEX0& TEX0, int hh *= 2; } + // Gregory: I'm sure this sillyness is related to the usage of a 32bits + // buffer as a 16 bits format. In this case the height of the buffer is + // multiplyed by 2 (Hence a scissor bigger than the RT) + // This vp2 fix doesn't work most of the time if(hh < 512 && m_renderer->m_context->SCISSOR.SCAY1 == 511) // vp2 @@ -334,6 +339,30 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(const GIFRegTEX0& TEX0, int return dst; } +// Goal: Depth And Target at the same address is not possible. On GS it is +// the same memory but not on the Dx/GL. Therefore a write to the Depth/Target +// must invalidate the Target/Depth respectively +void GSTextureCache::InvalidateVideoMemType(int type, uint32 bp) +{ + for(list::iterator i = m_dst[type].begin(); i != m_dst[type].end(); i++) + { + Target* t = *i; + + if(bp == t->m_TEX0.TBP0) + { + GL_CACHE("TC: InvalidateVideoMemType: Remove Target(T%d) %d (0x%x)", type, + t->m_texture ? t->m_texture->GetID() : 0, + t->m_TEX0.TBP0); + + m_dst[type].erase(i); + delete t; + + break; + } + } + +} + // Goal: invalidate data sent to the GPU when the source (GS memory) is modified // Called each time you want to write to the GS memory void GSTextureCache::InvalidateVideoMem(GSOffset* off, const GSVector4i& rect, bool target) @@ -465,7 +494,7 @@ void GSTextureCache::InvalidateVideoMem(GSOffset* off, const GSVector4i& rect, b else { m_dst[type].erase(j); - GL_CACHE("TC: Remove Target(%d) %d (0x%x)", type, + GL_CACHE("TC: Remove Target(T%d) %d (0x%x)", type, t->m_texture ? t->m_texture->GetID() : 0, t->m_TEX0.TBP0); delete t; @@ -776,6 +805,9 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con GSVector4 dRect(0, 0, w, h); + // Try to extract a texture bigger than the RT. Current solution is to rescale the size + // of the texture to fit in the RT. In my opinion, it would be better to increase the size of + // the RT if(w > dstsize.x) { scale.x = (float)dstsize.x / tw; @@ -825,6 +857,7 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con } else { + // Different size or not the same format sRect.z /= sTex->GetWidth(); sRect.w /= sTex->GetHeight(); diff --git a/plugins/GSdx/GSTextureCache.h b/plugins/GSdx/GSTextureCache.h index 04f71b4aaa..0879c63a64 100644 --- a/plugins/GSdx/GSTextureCache.h +++ b/plugins/GSdx/GSTextureCache.h @@ -135,6 +135,7 @@ public: Target* LookupTarget(const GIFRegTEX0& TEX0, int w, int h, int type, bool used); Target* LookupTarget(const GIFRegTEX0& TEX0, int w, int h); + void InvalidateVideoMemType(int type, uint32 bp); void InvalidateVideoMem(GSOffset* off, const GSVector4i& r, bool target = true); void InvalidateLocalMem(GSOffset* off, const GSVector4i& r);