GS/HW: Improve target lookup handling + fix alpha requirements

This commit is contained in:
refractionpcsx2 2023-12-27 18:29:54 +00:00
parent fe2ed74020
commit fb393c22b6
3 changed files with 17 additions and 10 deletions

View File

@ -2252,7 +2252,7 @@ void GSRendererHW::Draw()
tgt = nullptr; tgt = nullptr;
} }
const bool possible_shuffle = ((shuffle_target && GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM].bpp == 16) || m_cached_ctx.FRAME.Block() == m_cached_ctx.TEX0.TBP0) || IsPossibleChannelShuffle(); const bool possible_shuffle = ((shuffle_target && GSLocalMemory::m_psm[m_cached_ctx.FRAME.PSM].bpp == 16) || (m_cached_ctx.FRAME.Block() == m_cached_ctx.TEX0.TBP0 && ((m_cached_ctx.TEX0.PSM & 0x6) || m_cached_ctx.FRAME.PSM != m_cached_ctx.TEX0.PSM))) || IsPossibleChannelShuffle();
const bool need_aem_color = GSLocalMemory::m_psm[m_cached_ctx.TEX0.PSM].trbpp <= 24 && GSLocalMemory::m_psm[m_cached_ctx.TEX0.PSM].pal == 0 && m_context->ALPHA.C == 0 && m_env.TEXA.AEM; const bool need_aem_color = GSLocalMemory::m_psm[m_cached_ctx.TEX0.PSM].trbpp <= 24 && GSLocalMemory::m_psm[m_cached_ctx.TEX0.PSM].pal == 0 && m_context->ALPHA.C == 0 && m_env.TEXA.AEM;
const bool req_color = (!PRIM->ABE || (PRIM->ABE && (m_context->ALPHA.IsUsingCs() || need_aem_color))) && (possible_shuffle || (m_cached_ctx.FRAME.FBMSK & (fm_mask & 0x00FFFFFF)) != (fm_mask & 0x00FFFFFF)); const bool req_color = (!PRIM->ABE || (PRIM->ABE && (m_context->ALPHA.IsUsingCs() || need_aem_color))) && (possible_shuffle || (m_cached_ctx.FRAME.FBMSK & (fm_mask & 0x00FFFFFF)) != (fm_mask & 0x00FFFFFF));
const bool alpha_used = m_context->TEX0.TCC && ((PRIM->ABE && m_context->ALPHA.IsUsingAs()) || (m_cached_ctx.TEST.ATE && m_cached_ctx.TEST.ATST > ATST_ALWAYS) || (possible_shuffle || (m_cached_ctx.FRAME.FBMSK & (fm_mask & 0xFF000000)) != (fm_mask & 0xFF000000))); const bool alpha_used = m_context->TEX0.TCC && ((PRIM->ABE && m_context->ALPHA.IsUsingAs()) || (m_cached_ctx.TEST.ATE && m_cached_ctx.TEST.ATST > ATST_ALWAYS) || (possible_shuffle || (m_cached_ctx.FRAME.FBMSK & (fm_mask & 0xFF000000)) != (fm_mask & 0xFF000000)));

View File

@ -1032,12 +1032,10 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
const u32 bw = TEX0.TBW; const u32 bw = TEX0.TBW;
GSVector4i req_rect = r; GSVector4i req_rect = r;
// The read area might be offset but the start of the texture is at the beginning of the space.
req_rect.x = 0;
req_rect.y = 0;
if (region.HasX() || region.HasY()) // The read area might be offset but the start of the texture is at the beginning of the space.
req_rect = req_rect + region.GetOffset(req_rect.z, req_rect.w); req_rect.x = region.HasX() ? region.GetMinX() : 0;
req_rect.y = region.HasY() ? region.GetMinY() : 0;
// Arc the Lad finds the wrong surface here when looking for a depth stencil. // Arc the Lad finds the wrong surface here when looking for a depth stencil.
// Since we're currently not caching depth stencils (check ToDo in CreateSource) we should not look for it here. // Since we're currently not caching depth stencils (check ToDo in CreateSource) we should not look for it here.
@ -1219,7 +1217,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
else else
{ {
rect_clean = t->m_dirty.empty(); rect_clean = t->m_dirty.empty();
if (!possible_shuffle && rect_clean && bp == t->m_TEX0.TBP0 && t && GSUtil::HasCompatibleBits(psm, t->m_TEX0.PSM) && width_match && real_fmt_match) if (!possible_shuffle && frame_fbp != t->m_TEX0.TBP0 && rect_clean && bp == t->m_TEX0.TBP0 && t && GSUtil::HasCompatibleBits(psm, t->m_TEX0.PSM) && width_match && real_fmt_match)
{ {
if (!tex_merge_rt && t->Overlaps(bp, bw, psm, req_rect)) if (!tex_merge_rt && t->Overlaps(bp, bw, psm, req_rect))
ResizeTarget(t, req_rect, bp, psm, bw); ResizeTarget(t, req_rect, bp, psm, bw);
@ -1291,7 +1289,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
// 1/ it just works :) // 1/ it just works :)
// 2/ even with upscaling // 2/ even with upscaling
// 3/ for both Direct3D and OpenGL // 3/ for both Direct3D and OpenGL
if (GSConfig.UserHacks_CPUFBConversion && (psm == PSMT4 || psm == PSMT8)) if (psm == PSMT4 || (GSConfig.UserHacks_CPUFBConversion && psm == PSMT8))
{ {
// Forces 4-bit and 8-bit frame buffer conversion to be done on the CPU instead of the GPU, but performance will be slower. // Forces 4-bit and 8-bit frame buffer conversion to be done on the CPU instead of the GPU, but performance will be slower.
// There is no dedicated shader to handle 4-bit conversion (Stuntman has been confirmed to use 4-bit). // There is no dedicated shader to handle 4-bit conversion (Stuntman has been confirmed to use 4-bit).
@ -5780,10 +5778,19 @@ bool GSTextureCache::Target::HasValidBitsForFormat(u32 psm, bool req_color, bool
default: default:
alpha_valid = ((m_TEX0.PSM & 0xF) == 0x1) ? true : (m_valid_alpha_low || m_valid_alpha_high); alpha_valid = ((m_TEX0.PSM & 0xF) == 0x1) ? true : (m_valid_alpha_low || m_valid_alpha_high);
color_valid = m_valid_rgb; color_valid = m_valid_rgb;
if (req_alpha && !alpha_valid && color_valid)
{
RGBAMask mask;
mask._u32 = 0x8;
AddDirtyRectTarget(this, this->m_valid, m_TEX0.PSM, m_TEX0.TBW, mask, false);
alpha_valid = true; // This is going to get resolved going forward.
m_valid_alpha_low = true;
m_valid_alpha_high = true;
}
break; break;
} }
return (color_valid && req_color) || (!req_color && ((alpha_valid && req_alpha) || !req_alpha)); return (!req_color || color_valid) && (!req_alpha || alpha_valid);
} }
void GSTextureCache::Target::ResizeDrawn(const GSVector4i& rect) void GSTextureCache::Target::ResizeDrawn(const GSVector4i& rect)

View File

@ -451,7 +451,7 @@ public:
void Read(Source* t, const GSVector4i& r); void Read(Source* t, const GSVector4i& r);
void RemoveAll(bool sources, bool targets, bool hash_cache); void RemoveAll(bool sources, bool targets, bool hash_cache);
void ReadbackAll(); void ReadbackAll();
void AddDirtyRectTarget(Target* target, GSVector4i rect, u32 psm, u32 bw, RGBAMask rgba, bool req_linear = false); static void AddDirtyRectTarget(Target* target, GSVector4i rect, u32 psm, u32 bw, RGBAMask rgba, bool req_linear = false);
void ResizeTarget(Target* t, GSVector4i rect, u32 tbp, u32 psm, u32 tbw); void ResizeTarget(Target* t, GSVector4i rect, u32 tbp, u32 psm, u32 tbw);
static bool FullRectDirty(Target* target, u32 rgba_mask); static bool FullRectDirty(Target* target, u32 rgba_mask);
static bool FullRectDirty(Target* target); static bool FullRectDirty(Target* target);