Skip to content

Commit

Permalink
GS/HW: Temp changes which may break everything
Browse files Browse the repository at this point in the history
  • Loading branch information
refractionpcsx2 committed Dec 3, 2024
1 parent ba10782 commit 0959a98
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 72 deletions.
141 changes: 72 additions & 69 deletions pcsx2/GS/Renderers/HW/GSRendererHW.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2729,6 +2729,75 @@ void GSRendererHW::Draw()
m_in_target_draw = false;
m_target_offset = 0;

GSTextureCache::Target* ds = nullptr;
GIFRegTEX0 ZBUF_TEX0;
if (!no_ds)
{
ZBUF_TEX0.U64 = 0;
ZBUF_TEX0.TBP0 = m_cached_ctx.ZBUF.Block();
ZBUF_TEX0.TBW = m_cached_ctx.FRAME.FBW;
ZBUF_TEX0.PSM = m_cached_ctx.ZBUF.PSM;

ds = g_texture_cache->LookupTarget(ZBUF_TEX0, t_size, target_scale, GSTextureCache::DepthStencil,
m_cached_ctx.DepthWrite(), 0, false, force_preload, preserve_depth, preserve_depth, unclamped_draw_rect, IsPossibleChannelShuffle(), is_possible_mem_clear && ZBUF_TEX0.TBP0 != m_cached_ctx.FRAME.Block(), false,
src, -1);

ZBUF_TEX0.TBW = m_channel_shuffle ? src->m_from_target_TEX0.TBW : m_cached_ctx.FRAME.FBW;

if (!ds)
{
ds = g_texture_cache->CreateTarget(ZBUF_TEX0, t_size, GetValidSize(src), target_scale, GSTextureCache::DepthStencil,
true, 0, false, force_preload, preserve_depth, m_r, src);
if (!ds) [[unlikely]]
{
GL_INS("ERROR: Failed to create ZBUF target, skipping.");
CleanupDraw(true);
return;
}
}
else
{
// If it failed to check depth test earlier, we can now check the top bits from the alpha to get a bit more accurate picture.
if (((zm && m_cached_ctx.TEST.ZTST > ZTST_ALWAYS) || (m_vt.m_eq.z && m_cached_ctx.TEST.ZTST == ZTST_GEQUAL)) && GSLocalMemory::m_psm[m_cached_ctx.ZBUF.PSM].trbpp == 32)
{
if (ds->m_alpha_max != 0)
{
const u32 max_z = (static_cast<u64>(ds->m_alpha_max + 1) << 24) - 1;

switch (m_cached_ctx.TEST.ZTST)
{
case ZTST_GEQUAL:
// Every Z value will pass
if (max_z <= m_vt.m_min.p.z)
{
m_cached_ctx.TEST.ZTST = ZTST_ALWAYS;
if (zm)
{
ds = nullptr;
no_ds = true;
}
}
break;
case ZTST_GREATER:
// Every Z value will pass
if (max_z < m_vt.m_min.p.z)
{
m_cached_ctx.TEST.ZTST = ZTST_ALWAYS;
if (zm)
{
ds = nullptr;
no_ds = true;
}
}
break;
default:
break;
}
}
}
}
}

if (!no_rt)
{
const bool possible_shuffle = draw_sprite_tex && (((src && src->m_target && src->m_from_target && src->m_from_target->m_32_bits_fmt) &&
Expand Down Expand Up @@ -2758,7 +2827,7 @@ void GSRendererHW::Draw()

rt = g_texture_cache->LookupTarget(FRAME_TEX0, t_size, ((src && src->m_scale != 1) && GSConfig.UserHacks_NativeScaling == GSNativeScaling::Normal && !possible_shuffle) ? GetTextureScaleFactor() : target_scale, GSTextureCache::RenderTarget, true,
fm, false, force_preload, preserve_rt_rgb, preserve_rt_alpha, unclamped_draw_rect, possible_shuffle, is_possible_mem_clear && FRAME_TEX0.TBP0 != m_cached_ctx.ZBUF.Block(),
GSConfig.UserHacks_NativeScaling != GSNativeScaling::Off && preserve_downscale_draw && is_possible_mem_clear != ClearType::NormalClear, src);
GSConfig.UserHacks_NativeScaling != GSNativeScaling::Off && preserve_downscale_draw && is_possible_mem_clear != ClearType::NormalClear, src, no_ds ? -1 : (ds->m_TEX0.TBP0 - m_cached_ctx.ZBUF.Block()));

// Draw skipped because it was a clear and there was no target.
if (!rt)
Expand Down Expand Up @@ -2828,6 +2897,8 @@ void GSRendererHW::Draw()
{
u32 new_height = m_r.w;

if (possible_shuffle && std::abs(static_cast<s16>(GSLocalMemory::m_psm[rt->m_TEX0.PSM].bpp - GSLocalMemory::m_psm[TEX0.PSM].bpp)) == 16)
new_height /= 2;
//DevCon.Warning("Resizing texture %d x %d draw %d", rt->m_unscaled_size.x, new_height, s_n);
rt->ResizeTexture(rt->m_unscaled_size.x, new_height);
rt->UpdateValidity(m_r, true);
Expand Down Expand Up @@ -2859,74 +2930,6 @@ void GSRendererHW::Draw()
m_last_channel_shuffle_end_block = 0xFFFF;
}

GSTextureCache::Target* ds = nullptr;
GIFRegTEX0 ZBUF_TEX0;
if (!no_ds)
{
ZBUF_TEX0.U64 = 0;
ZBUF_TEX0.TBP0 = m_cached_ctx.ZBUF.Block();
ZBUF_TEX0.TBW = m_cached_ctx.FRAME.FBW;
ZBUF_TEX0.PSM = m_cached_ctx.ZBUF.PSM;

ds = g_texture_cache->LookupTarget(ZBUF_TEX0, t_size, target_scale, GSTextureCache::DepthStencil,
m_cached_ctx.DepthWrite(), 0, false, force_preload, preserve_depth, preserve_depth, unclamped_draw_rect, IsPossibleChannelShuffle(), is_possible_mem_clear && ZBUF_TEX0.TBP0 != m_cached_ctx.FRAME.Block());

ZBUF_TEX0.TBW = m_channel_shuffle ? src->m_from_target_TEX0.TBW : m_cached_ctx.FRAME.FBW;

if (!ds)
{
ds = g_texture_cache->CreateTarget(ZBUF_TEX0, t_size, GetValidSize(src), target_scale, GSTextureCache::DepthStencil,
true, 0, false, force_preload, preserve_depth, m_r, src);
if (!ds) [[unlikely]]
{
GL_INS("ERROR: Failed to create ZBUF target, skipping.");
CleanupDraw(true);
return;
}
}
else
{
// If it failed to check depth test earlier, we can now check the top bits from the alpha to get a bit more accurate picture.
if (((zm && m_cached_ctx.TEST.ZTST > ZTST_ALWAYS) || (m_vt.m_eq.z && m_cached_ctx.TEST.ZTST == ZTST_GEQUAL)) && GSLocalMemory::m_psm[m_cached_ctx.ZBUF.PSM].trbpp == 32)
{
if (ds->m_alpha_max != 0)
{
const u32 max_z = (static_cast<u64>(ds->m_alpha_max + 1) << 24) - 1;

switch (m_cached_ctx.TEST.ZTST)
{
case ZTST_GEQUAL:
// Every Z value will pass
if (max_z <= m_vt.m_min.p.z)
{
m_cached_ctx.TEST.ZTST = ZTST_ALWAYS;
if (zm)
{
ds = nullptr;
no_ds = true;
}
}
break;
case ZTST_GREATER:
// Every Z value will pass
if (max_z < m_vt.m_min.p.z)
{
m_cached_ctx.TEST.ZTST = ZTST_ALWAYS;
if (zm)
{
ds = nullptr;
no_ds = true;
}
}
break;
default:
break;
}
}
}
}
}

if (m_process_texture)
{
GIFRegCLAMP MIP_CLAMP = m_cached_ctx.CLAMP;
Expand Down
23 changes: 21 additions & 2 deletions pcsx2/GS/Renderers/HW/GSTextureCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1797,7 +1797,8 @@ GSVector2i GSTextureCache::ScaleRenderTargetSize(const GSVector2i& sz, float sca
}

GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVector2i& size, float scale, int type,
bool used, u32 fbmask, bool is_frame, bool preload, bool preserve_rgb, bool preserve_alpha, const GSVector4i draw_rect, bool is_shuffle, bool possible_clear, bool preserve_scale, GSTextureCache::Source* src)
bool used, u32 fbmask, bool is_frame, bool preload, bool preserve_rgb, bool preserve_alpha, const GSVector4i draw_rect,
bool is_shuffle, bool possible_clear, bool preserve_scale, GSTextureCache::Source* src, int offset)
{
const GSLocalMemory::psm_t& psm_s = GSLocalMemory::m_psm[TEX0.PSM];
const u32 bp = TEX0.TBP0;
Expand Down Expand Up @@ -1895,8 +1896,11 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
}
}
// Probably pointing to half way through the target
else if(GSConfig.UserHacks_TextureInsideRt >= GSTextureInRtMode::InsideTargets)
else if (GSConfig.UserHacks_TextureInsideRt >= GSTextureInRtMode::InsideTargets)
{
if (offset != -1 && (bp - t->m_TEX0.TBP0) != offset)
continue;

const u32 widthpage_offset = (std::abs(static_cast<int>(bp - t->m_TEX0.TBP0)) >> 5) % std::max(t->m_TEX0.TBW, 1U);
const bool is_aligned_ok = widthpage_offset == 0 || ((widthpage_offset + TEX0.TBW) <= t->m_TEX0.TBW) || min_rect.width() <= 64 || (widthpage_offset == (t->m_TEX0.TBW >> 1) && (static_cast<u32>(min_rect.width()) <= (widthpage_offset * 64)));
if ((!dst || ((GSState::s_n - dst->m_last_draw) < (GSState::s_n - t->m_last_draw))) && is_aligned_ok && (t->m_TEX0.TBW == TEX0.TBW || (TEX0.TBW == 1 && t->m_TEX0.TBW > 1)) && t->Inside(bp, TEX0.TBW, TEX0.PSM, min_rect))
Expand Down Expand Up @@ -2080,6 +2084,8 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
}
else if (!is_shuffle && std::abs(static_cast<s16>(GSLocalMemory::m_psm[dst->m_TEX0.PSM].bpp - GSLocalMemory::m_psm[TEX0.PSM].bpp)) == 16)
{
dst->Update(false);

const bool scale_down = GSLocalMemory::m_psm[dst->m_TEX0.PSM].bpp > GSLocalMemory::m_psm[TEX0.PSM].bpp;
new_size = dst->m_unscaled_size;
new_scaled_size = ScaleRenderTargetSize(dst->m_unscaled_size, scale);
Expand Down Expand Up @@ -2337,6 +2343,8 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
dst->m_valid_alpha_high = dst_match->m_valid_alpha_high; //&& psm_s.trbpp != 24;
dst->m_valid_rgb = dst_match->m_valid_rgb;
dst->m_was_dst_matched = true;
dst_match->m_was_dst_matched = true;
dst_match->m_valid_rgb = false;

if (GSLocalMemory::m_psm[dst->m_TEX0.PSM].bpp == 16 && GSLocalMemory::m_psm[dst_match->m_TEX0.PSM].bpp > 16)
dst->m_TEX0.TBW = dst_match->m_TEX0.TBW; // Be careful of shuffles of the depth as C16, but using a buffer width of 16 (Mercenaries).
Expand Down Expand Up @@ -3164,6 +3172,17 @@ void GSTextureCache::InvalidateContainedTargets(u32 start_bp, u32 end_bp, u32 wr
continue;
}

// Not covering the whole target, and a different format, so just dirty it.
if (start_bp == t->m_TEX0.TBP0 && (t->UnwrappedEndBlock() > end_bp) && write_psm != t->m_TEX0.PSM)
{
const GSLocalMemory::psm_t& target_psm = GSLocalMemory::m_psm[write_psm];
u32 total_pages = (end_bp - t->m_TEX0.TBP0) >> 5;
GSVector4i dirty_area = GSVector4i(0, 0, t->m_valid.z, (total_pages / t->m_TEX0.TBW) * target_psm.pgs.y);
InvalidateVideoMem(g_gs_renderer->m_mem.GetOffset(t->m_TEX0.TBP0, t->m_TEX0.TBW, write_psm), dirty_area, true);
++i;
continue;
}

InvalidateSourcesFromTarget(t);

t->m_valid_alpha_low &= preserve_alpha;
Expand Down
2 changes: 1 addition & 1 deletion pcsx2/GS/Renderers/HW/GSTextureCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,7 @@ class GSTextureCache
Target* FindTargetOverlap(Target* target, int type, int psm);
Target* LookupTarget(GIFRegTEX0 TEX0, const GSVector2i& size, float scale, int type, bool used = true, u32 fbmask = 0,
bool is_frame = false, bool preload = GSConfig.PreloadFrameWithGSData, bool preserve_rgb = true, bool preserve_alpha = true,
const GSVector4i draw_rc = GSVector4i::zero(), bool is_shuffle = false, bool possible_clear = false, bool preserve_scale = false, GSTextureCache::Source* src = nullptr);
const GSVector4i draw_rc = GSVector4i::zero(), bool is_shuffle = false, bool possible_clear = false, bool preserve_scale = false, GSTextureCache::Source* src = nullptr, int offset = -1);
Target* CreateTarget(GIFRegTEX0 TEX0, const GSVector2i& size, const GSVector2i& valid_size,float scale, int type, bool used = true, u32 fbmask = 0,
bool is_frame = false, bool preload = GSConfig.PreloadFrameWithGSData, bool preserve_target = true,
const GSVector4i draw_rc = GSVector4i::zero(), GSTextureCache::Source* src = nullptr);
Expand Down

0 comments on commit 0959a98

Please sign in to comment.