mirror of https://github.com/PCSX2/pcsx2.git
GS-HW: Limit BP overlap check to stop FMV flicker.
Games changing the double buffer addresses get screwed up, make sure we don't misdetect
This commit is contained in:
parent
4ef879d1f2
commit
878e06cd36
|
@ -254,7 +254,7 @@ GSTexture* GSRendererHW::GetOutput(int i, int& y_offset)
|
|||
GSTexture* t = nullptr;
|
||||
GSVector2i size = GetOutputSize(fb_height);
|
||||
|
||||
if (GSTextureCache::Target* rt = m_tc->LookupDisplayTarget(TEX0, GetOutputSize(fb_height), fb_height, fb_width))
|
||||
if (GSTextureCache::Target* rt = m_tc->LookupDisplayTarget(TEX0, GetOutputSize(fb_height), fb_width, fb_height))
|
||||
{
|
||||
t = rt->m_texture;
|
||||
|
||||
|
|
|
@ -414,7 +414,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const GIFRegTEX0& TEX0, con
|
|||
return src;
|
||||
}
|
||||
|
||||
GSTextureCache::Target* GSTextureCache::LookupTarget(const GIFRegTEX0& TEX0, const GSVector2i& size, int type, bool used, u32 fbmask, const bool is_frame, const int real_h, const int real_w)
|
||||
GSTextureCache::Target* GSTextureCache::LookupTarget(const GIFRegTEX0& TEX0, const GSVector2i& size, int type, bool used, u32 fbmask, const bool is_frame, const int real_w, const int real_h)
|
||||
{
|
||||
const GSLocalMemory::psm_t& psm_s = GSLocalMemory::m_psm[TEX0.PSM];
|
||||
const GSVector2& new_s = static_cast<GSRendererHW*>(g_gs_renderer.get())->GetTextureScaleFactor();
|
||||
|
@ -470,7 +470,7 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(const GIFRegTEX0& TEX0, con
|
|||
dst = t;
|
||||
GL_CACHE("TC: Lookup Frame %dx%d, perfect hit: %d (0x%x -> 0x%x %s)", size.x, size.y, dst->m_texture->GetID(), bp, t->m_end_block, psm_str(TEX0.PSM));
|
||||
if (real_h > 0 || real_w > 0)
|
||||
ScaleTargetForDisplay(dst, TEX0, real_h, real_w);
|
||||
ScaleTargetForDisplay(dst, TEX0, real_w, real_h);
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -479,14 +479,21 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(const GIFRegTEX0& TEX0, con
|
|||
// 2nd try ! Try to find a frame that include the bp
|
||||
if (!dst)
|
||||
{
|
||||
const int page_width = std::max(1, (real_w / psm_s.pgs.x));
|
||||
const int page_height = std::max(1, (real_h / psm_s.pgs.y));
|
||||
const int pitch = (std::max(1U, TEX0.TBW) * 64) / psm_s.pgs.x;
|
||||
const u32 end_bp = bp + ((page_width << 5) + ((page_height * pitch) << 5));
|
||||
|
||||
for (auto t : list)
|
||||
{
|
||||
if (t->m_TEX0.TBP0 < bp && bp <= t->m_end_block)
|
||||
// Make sure the target is inside the texture
|
||||
if (t->m_TEX0.TBP0 < bp && bp <= t->m_end_block && end_bp > t->m_TEX0.TBP0 && end_bp <= t->m_end_block)
|
||||
{
|
||||
dst = t;
|
||||
GL_CACHE("TC: Lookup Frame %dx%d, inclusive hit: %d (0x%x, took 0x%x -> 0x%x %s)", size.x, size.y, t->m_texture->GetID(), bp, t->m_TEX0.TBP0, t->m_end_block, psm_str(TEX0.PSM));
|
||||
GL_CACHE("TC: Lookup Frame %dx%d, inclusive hit: %d (0x%x, took 0x%x -> 0x%x %s endbp 0x%x)", size.x, size.y, t->m_texture->GetID(), bp, t->m_TEX0.TBP0, t->m_end_block, psm_str(TEX0.PSM), end_bp);
|
||||
|
||||
if (real_h > 0 || real_w > 0)
|
||||
ScaleTargetForDisplay(dst, TEX0, real_h, real_w);
|
||||
ScaleTargetForDisplay(dst, TEX0, real_w, real_h);
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -623,12 +630,12 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(const GIFRegTEX0& TEX0, con
|
|||
return dst;
|
||||
}
|
||||
|
||||
GSTextureCache::Target* GSTextureCache::LookupDisplayTarget(const GIFRegTEX0& TEX0, const GSVector2i& size, const int real_h, const int real_w)
|
||||
GSTextureCache::Target* GSTextureCache::LookupDisplayTarget(const GIFRegTEX0& TEX0, const GSVector2i& size, const int real_w, const int real_h)
|
||||
{
|
||||
return LookupTarget(TEX0, size, RenderTarget, true, 0, true, real_h, real_w);
|
||||
return LookupTarget(TEX0, size, RenderTarget, true, 0, true, real_w, real_h);
|
||||
}
|
||||
|
||||
void GSTextureCache::ScaleTargetForDisplay(Target* t, const GIFRegTEX0& dispfb, int real_h, int real_w)
|
||||
void GSTextureCache::ScaleTargetForDisplay(Target* t, const GIFRegTEX0& dispfb, int real_w, int real_h)
|
||||
{
|
||||
// This handles a case where you have two images stacked on top of one another (usually FMVs), and
|
||||
// the size of the top framebuffer is larger than the height of the image. Usually happens when
|
||||
|
@ -655,12 +662,11 @@ void GSTextureCache::ScaleTargetForDisplay(Target* t, const GIFRegTEX0& dispfb,
|
|||
// Take that into consideration to find the extent of the target which will be sampled.
|
||||
GSTexture* old_texture = t->m_texture;
|
||||
const int needed_height = std::min(real_h + y_offset, GSRendererHW::MAX_FRAMEBUFFER_HEIGHT);
|
||||
const int scaled_needed_height = static_cast<int>(static_cast<float>(needed_height) * old_texture->GetScale().y);
|
||||
const int scaled_needed_height = std::max(static_cast<int>(static_cast<float>(needed_height) * old_texture->GetScale().y), old_texture->GetHeight());
|
||||
const int needed_width = std::min(real_w, static_cast<int>(dispfb.TBW * 64));
|
||||
const int scaled_needed_width = static_cast<int>(static_cast<float>(needed_width) * old_texture->GetScale().x);
|
||||
const int scaled_needed_width = std::max(static_cast<int>(static_cast<float>(needed_width) * old_texture->GetScale().x), old_texture->GetWidth());
|
||||
if (scaled_needed_height <= old_texture->GetHeight() && scaled_needed_width <= old_texture->GetWidth())
|
||||
return;
|
||||
|
||||
// We're expanding, so create a new texture.
|
||||
GSTexture* new_texture = g_gs_device->CreateRenderTarget(scaled_needed_width, scaled_needed_height, GSTexture::Format::Color, false);
|
||||
if (!new_texture)
|
||||
|
|
|
@ -311,7 +311,7 @@ protected:
|
|||
|
||||
/// Expands a target when the block pointer for a display framebuffer is within another target, but the read offset
|
||||
/// plus the height is larger than the current size of the target.
|
||||
void ScaleTargetForDisplay(Target* t, const GIFRegTEX0& dispfb, int real_h, int real_w);
|
||||
void ScaleTargetForDisplay(Target* t, const GIFRegTEX0& dispfb, int real_w, int real_h);
|
||||
|
||||
HashCacheEntry* LookupHashCache(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, bool& paltex, const u32* clut, const GSVector2i* lod);
|
||||
|
||||
|
@ -335,8 +335,8 @@ public:
|
|||
Source* LookupSource(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GSVector4i& r, const GSVector2i* lod);
|
||||
Source* LookupDepthSource(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, const GSVector4i& r, bool palette = false);
|
||||
|
||||
Target* LookupTarget(const GIFRegTEX0& TEX0, const GSVector2i& size, int type, bool used, u32 fbmask = 0, const bool is_frame = false, const int real_h = 0, const int real_w = 0);
|
||||
Target* LookupDisplayTarget(const GIFRegTEX0& TEX0, const GSVector2i& size, const int real_h, const int real_w);
|
||||
Target* LookupTarget(const GIFRegTEX0& TEX0, const GSVector2i& size, int type, bool used, u32 fbmask = 0, const bool is_frame = false, const int real_w = 0, const int real_h = 0);
|
||||
Target* LookupDisplayTarget(const GIFRegTEX0& TEX0, const GSVector2i& size, const int real_w, const int real_h);
|
||||
|
||||
/// Looks up a target in the cache, and only returns it if the BP/BW/PSM match exactly.
|
||||
Target* GetExactTarget(u32 BP, u32 BW, u32 PSM) const;
|
||||
|
|
Loading…
Reference in New Issue