GS/HW: Force region match on fixed TEX0

Fixes lightmapping in Spinter Cell - Double Agent.
This commit is contained in:
Stenzek 2023-02-17 21:04:51 +10:00 committed by refractionpcsx2
parent 666de3a874
commit 2dd76c3f12
2 changed files with 10 additions and 6 deletions

View File

@ -3121,10 +3121,10 @@ void GSRendererHW::EmulateTextureSampler(const GSTextureCache::Source* tex)
const u8 wms = EffectiveClamp(m_context->CLAMP.WMS, tex->m_region.HasX() || redundant_wms); const u8 wms = EffectiveClamp(m_context->CLAMP.WMS, tex->m_region.HasX() || redundant_wms);
const u8 wmt = EffectiveClamp(m_context->CLAMP.WMT, tex->m_region.HasY() || redundant_wmt); const u8 wmt = EffectiveClamp(m_context->CLAMP.WMT, tex->m_region.HasY() || redundant_wmt);
const bool complex_wms_wmt = !!((wms | wmt) & 2); const bool complex_wms_wmt = !!((wms | wmt) & 2);
GL_CACHE("WMS: %s [%s%s] WMT: %s [%s%s] Complex: %d MINU: %d MINV: %d MINV: %d MAXV: %d", GL_CACHE("WMS: %s [%s%s] WMT: %s [%s%s] Complex: %d MINU: %d MAXU: %d MINV: %d MAXV: %d",
clamp_modes[m_context->CLAMP.WMS], redundant_wms ? "redundant," : "", clamp_modes[wms], clamp_modes[m_context->CLAMP.WMS], redundant_wms ? "redundant," : "", clamp_modes[wms],
clamp_modes[m_context->CLAMP.WMT], redundant_wmt ? "redundant," : "", clamp_modes[wmt], clamp_modes[m_context->CLAMP.WMT], redundant_wmt ? "redundant," : "", clamp_modes[wmt],
complex_wms_wmt, m_context->CLAMP.MINU, m_context->CLAMP.MINV, m_context->CLAMP.MAXU, m_context->CLAMP.MAXV); complex_wms_wmt, m_context->CLAMP.MINU, m_context->CLAMP.MAXU, m_context->CLAMP.MINV, m_context->CLAMP.MAXV);
const bool need_mipmap = IsMipMapDraw(); const bool need_mipmap = IsMipMapDraw();
const bool shader_emulated_sampler = tex->m_palette || cpsm.fmt != 0 || complex_wms_wmt || psm.depth; const bool shader_emulated_sampler = tex->m_palette || cpsm.fmt != 0 || complex_wms_wmt || psm.depth;

View File

@ -216,7 +216,7 @@ GSTextureCache::Source* GSTextureCache::LookupDepthSource(const GIFRegTEX0& TEX0
__ri static GSTextureCache::Source* FindSourceInMap(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA, __ri static GSTextureCache::Source* FindSourceInMap(const GIFRegTEX0& TEX0, const GIFRegTEXA& TEXA,
const GSLocalMemory::psm_t& psm_s, const u32* clut, const GSTexture* gpu_clut, const GSVector2i& compare_lod, const GSLocalMemory::psm_t& psm_s, const u32* clut, const GSTexture* gpu_clut, const GSVector2i& compare_lod,
const GSTextureCache::SourceRegion& region, FastList<GSTextureCache::Source*>& map) const GSTextureCache::SourceRegion& region, u32 fixed_tex0, FastList<GSTextureCache::Source*>& map)
{ {
for (auto i = map.begin(); i != map.end(); ++i) for (auto i = map.begin(); i != map.end(); ++i)
{ {
@ -248,7 +248,10 @@ __ri static GSTextureCache::Source* FindSourceInMap(const GIFRegTEX0& TEX0, cons
continue; continue;
} }
if (s->m_region.bits != 0 && s->m_region.bits != region.bits) // When fixed tex0 is used, we must find a matching region texture. The base likely
// doesn't contain to the correct region. Bit cheeky here, avoid a logical or by
// adding the invalid tex0 bit in.
if (((s->m_region.bits | fixed_tex0) != 0) && s->m_region.bits != region.bits)
continue; continue;
// Same base mip texture, but we need to check that MXL was the same as well. // Same base mip texture, but we need to check that MXL was the same as well.
@ -322,15 +325,16 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const GIFRegTEX0& TEX0, con
// Region textures might be placed in a different page, so check that first. // Region textures might be placed in a different page, so check that first.
const u32 lookup_page = TEX0.TBP0 >> 5; const u32 lookup_page = TEX0.TBP0 >> 5;
const bool is_fixed_tex0 = region.IsFixedTEX0(1 << TEX0.TW, 1 << TEX0.TH);
if (region.GetMinX() != 0 || region.GetMinY() != 0) if (region.GetMinX() != 0 || region.GetMinY() != 0)
{ {
const GSOffset offset(psm_s.info, TEX0.TBP0, TEX0.TBW, TEX0.PSM); const GSOffset offset(psm_s.info, TEX0.TBP0, TEX0.TBW, TEX0.PSM);
const u32 region_page = offset.bn(region.GetMinX(), region.GetMinY()) >> 5; const u32 region_page = offset.bn(region.GetMinX(), region.GetMinY()) >> 5;
if (lookup_page != region_page) if (lookup_page != region_page)
src = FindSourceInMap(TEX0, TEXA, psm_s, clut, gpu_clut, compare_lod, region, m_src.m_map[region_page]); src = FindSourceInMap(TEX0, TEXA, psm_s, clut, gpu_clut, compare_lod, region, is_fixed_tex0, m_src.m_map[region_page]);
} }
if (!src) if (!src)
src = FindSourceInMap(TEX0, TEXA, psm_s, clut, gpu_clut, compare_lod, region, m_src.m_map[lookup_page]); src = FindSourceInMap(TEX0, TEXA, psm_s, clut, gpu_clut, compare_lod, region, is_fixed_tex0, m_src.m_map[lookup_page]);
Target* dst = nullptr; Target* dst = nullptr;