GS: Prefix page/block size defines

This commit is contained in:
TheLastRar
2025-07-12 20:10:59 +02:00
committed by lightningterror
parent 77738f72b4
commit f747abcc3b
9 changed files with 85 additions and 91 deletions
+11 -11
View File
@@ -393,7 +393,7 @@ std::vector<GSVector2i>* GSLocalMemory::GetPage2TileMap(const GIFRegTEX0& TEX0)
{
for (; bn.blkX() < (tw >> off.blockShiftX()); bn.nextBlockX())
{
u32 page = (bn.value() >> 5) % MAX_PAGES;
u32 page = (bn.value() >> 5) % GS_MAX_PAGES;
tmp[page].insert((bn.blkY() << 7) + bn.blkX());
}
@@ -401,7 +401,7 @@ std::vector<GSVector2i>* GSLocalMemory::GetPage2TileMap(const GIFRegTEX0& TEX0)
// combine the lower 5 bits of the address into a 9:5 pointer:mask form, so the "valid bits" can be tested against an u32 array
auto p2t = new std::vector<GSVector2i>[MAX_PAGES];
auto p2t = new std::vector<GSVector2i>[GS_MAX_PAGES];
for (const auto& i : tmp)
{
@@ -495,12 +495,12 @@ u32 GSLocalMemory::GetEndBlockAddress(u32 bp, u32 bw, u32 psm, GSVector4i rect)
u32 GSLocalMemory::GetUnwrappedEndBlockAddress(u32 bp, u32 bw, u32 psm, GSVector4i rect)
{
const u32 result = GetEndBlockAddress(bp, bw, psm, rect);
return (result < bp) ? (result + MAX_BLOCKS) : result;
return (result < bp) ? (result + GS_MAX_BLOCKS) : result;
}
GSVector4i GSLocalMemory::GetRectForPageOffset(u32 base_bp, u32 offset_bp, u32 bw, u32 psm)
{
pxAssert((base_bp % BLOCKS_PER_PAGE) == 0 && (offset_bp % BLOCKS_PER_PAGE) == 0);
pxAssert((base_bp % GS_BLOCKS_PER_PAGE) == 0 && (offset_bp % GS_BLOCKS_PER_PAGE) == 0);
const u32 page_offset = (offset_bp - base_bp) >> 5;
const GSVector2i& pgs = m_psm[psm].pgs;
@@ -512,20 +512,20 @@ GSVector4i GSLocalMemory::GetRectForPageOffset(u32 base_bp, u32 offset_bp, u32 b
bool GSLocalMemory::HasOverlap(const u32 src_bp, const u32 src_bw, const u32 src_psm, const GSVector4i src_rect
, const u32 dst_bp, const u32 dst_bw, const u32 dst_psm, const GSVector4i dst_rect)
{
const u32 src_start_bp = GSLocalMemory::GetStartBlockAddress(src_bp, src_bw, src_psm, src_rect) & ~(BLOCKS_PER_PAGE - 1);
const u32 dst_start_bp = GSLocalMemory::GetStartBlockAddress(dst_bp, dst_bw, dst_psm, dst_rect) & ~(BLOCKS_PER_PAGE - 1);
const u32 src_start_bp = GSLocalMemory::GetStartBlockAddress(src_bp, src_bw, src_psm, src_rect) & ~(GS_BLOCKS_PER_PAGE - 1);
const u32 dst_start_bp = GSLocalMemory::GetStartBlockAddress(dst_bp, dst_bw, dst_psm, dst_rect) & ~(GS_BLOCKS_PER_PAGE - 1);
u32 src_end_bp = ((GSLocalMemory::GetEndBlockAddress(src_bp, src_bw, src_psm, src_rect) + 1) + (BLOCKS_PER_PAGE - 1)) & ~(BLOCKS_PER_PAGE - 1);
u32 dst_end_bp = ((GSLocalMemory::GetEndBlockAddress(dst_bp, dst_bw, dst_psm, dst_rect) + 1) + (BLOCKS_PER_PAGE - 1)) & ~(BLOCKS_PER_PAGE - 1);
u32 src_end_bp = ((GSLocalMemory::GetEndBlockAddress(src_bp, src_bw, src_psm, src_rect) + 1) + (GS_BLOCKS_PER_PAGE - 1)) & ~(GS_BLOCKS_PER_PAGE - 1);
u32 dst_end_bp = ((GSLocalMemory::GetEndBlockAddress(dst_bp, dst_bw, dst_psm, dst_rect) + 1) + (GS_BLOCKS_PER_PAGE - 1)) & ~(GS_BLOCKS_PER_PAGE - 1);
if (src_start_bp == src_end_bp)
{
src_end_bp = (src_end_bp + BLOCKS_PER_PAGE) & ~(MAX_BLOCKS - 1);
src_end_bp = (src_end_bp + GS_BLOCKS_PER_PAGE) & ~(GS_MAX_BLOCKS - 1);
}
if (dst_start_bp == dst_end_bp)
{
dst_end_bp = (dst_end_bp + BLOCKS_PER_PAGE) & ~(MAX_BLOCKS - 1);
dst_end_bp = (dst_end_bp + GS_BLOCKS_PER_PAGE) & ~(GS_MAX_BLOCKS - 1);
}
// Source has wrapped, 2 separate checks.
@@ -753,7 +753,7 @@ GSOffset::PageLooper GSOffset::pageLooperForRect(const GSVector4i& rect) const
out.yCnt = botPg - topPg;
out.firstRowPgXStart = out.midRowPgXStart = out.lastRowPgXStart = rect.left >> m_pageShiftX;
out.firstRowPgXEnd = out.midRowPgXEnd = out.lastRowPgXEnd = ((rect.right + m_pageMask.x) >> m_pageShiftX) + !aligned;
out.slowPath = static_cast<u32>(out.yCnt * out.yInc + out.midRowPgXEnd - out.midRowPgXStart) > MAX_PAGES;
out.slowPath = static_cast<u32>(out.yCnt * out.yInc + out.midRowPgXEnd - out.midRowPgXStart) > GS_MAX_PAGES;
// Page-aligned bp is easy, all tiles touch their lower page but not the upper
if (aligned)
+6 -6
View File
@@ -173,7 +173,7 @@ public:
/// Get the current block number
u32 value() const
{
return valueNoWrap() % MAX_BLOCKS;
return valueNoWrap() % GS_MAX_BLOCKS;
}
};
@@ -222,7 +222,7 @@ public:
int base = m_bp << (m_pageShiftX + m_pageShiftY - 5); // Offset from base pointer
base += ((y & ~m_pageMask.y) * m_bwPg) << m_pageShiftX; // Offset from pages in y direction
// TODO: Old GSOffset masked here but is that useful? Probably should mask at end or not at all...
base &= (MAX_PAGES << (m_pageShiftX + m_pageShiftY)) - 1; // Mask
base &= (GS_MAX_PAGES << (m_pageShiftX + m_pageShiftY)) - 1; // Mask
base += m_pixelSwizzleCol[y & m_pageMask.y]; // Add offset from y within page
return base;
}
@@ -307,7 +307,7 @@ public:
if (slowPath) [[unlikely]]
{
u32 touched[MAX_PAGES / 32] = {};
u32 touched[GS_MAX_PAGES / 32] = {};
for (int y = 0; y < yCnt; y++)
{
u32 start = lineBP + startOff;
@@ -315,7 +315,7 @@ public:
lineBP += yInc;
for (u32 pos = start; pos < end; pos++)
{
u32 page = pos % MAX_PAGES;
u32 page = pos % GS_MAX_PAGES;
u32 idx = page / 32;
u32 mask = 1 << (page % 32);
if (touched[idx] & mask)
@@ -349,7 +349,7 @@ public:
nextMin = end;
lineBP += yInc;
for (u32 pos = start; pos < end; pos++)
if (!fn(pos % MAX_PAGES))
if (!fn(pos % GS_MAX_PAGES))
return;
if (y < yCnt - 2)
@@ -579,7 +579,7 @@ public:
u8* BlockPtr(u32 bp) const
{
return &m_vm8[(bp % MAX_BLOCKS) << 8];
return &m_vm8[(bp % GS_MAX_BLOCKS) << 8];
}
u8* BlockPtr32(int x, int y, u32 bp, u32 bw) const
+7 -13
View File
@@ -5,22 +5,16 @@
// clang-format off
// MacOS headers define PAGE_SIZE to the size of an x86 page
#ifdef __APPLE__
#include <mach/vm_page_size.h>
#undef PAGE_SIZE
#endif
#define VM_SIZE 4194304u
#define HALF_VM_SIZE (VM_SIZE / 2u)
#define PAGE_SIZE 8192u
#define BLOCK_SIZE 256u
#define COLUMN_SIZE 64u
#define BLOCKS_PER_PAGE (PAGE_SIZE / BLOCK_SIZE)
#define GS_PAGE_SIZE 8192u
#define GS_BLOCK_SIZE 256u
#define GS_COLUMN_SIZE 64u
#define GS_BLOCKS_PER_PAGE (GS_PAGE_SIZE / GS_BLOCK_SIZE)
#define MAX_PAGES (VM_SIZE / PAGE_SIZE)
#define MAX_BLOCKS (VM_SIZE / BLOCK_SIZE)
#define MAX_COLUMNS (VM_SIZE / COLUMN_SIZE)
#define GS_MAX_PAGES (VM_SIZE / GS_PAGE_SIZE)
#define GS_MAX_BLOCKS (VM_SIZE / GS_BLOCK_SIZE)
#define GS_MAX_COLUMNS (VM_SIZE / GS_COLUMN_SIZE)
//if defined, will send much info in reply to the API title info queri from PCSX2
//default should be undefined
+1 -1
View File
@@ -1857,7 +1857,7 @@ void GSState::CheckWriteOverlap(bool req_write, bool req_read)
const GSDrawingContext& prev_ctx = m_prev_env.CTXT[m_prev_env.PRIM.CTXT];
const GSVector4i write_rect = GSVector4i(m_env.TRXPOS.DSAX, m_env.TRXPOS.DSAY, m_env.TRXPOS.DSAX + w, m_env.TRXPOS.DSAY + h);
const u32 write_start_bp = GSLocalMemory::GetStartBlockAddress(blit.DBP, blit.DBW, blit.DPSM, write_rect);
const u32 write_end_bp = ((GSLocalMemory::GetEndBlockAddress(blit.DBP, blit.DBW, blit.DPSM, write_rect) + 1) + (BLOCKS_PER_PAGE - 1)) & ~(BLOCKS_PER_PAGE - 1);
const u32 write_end_bp = ((GSLocalMemory::GetEndBlockAddress(blit.DBP, blit.DBW, blit.DPSM, write_rect) + 1) + (GS_BLOCKS_PER_PAGE - 1)) & ~(GS_BLOCKS_PER_PAGE - 1);
const GSVector4i tex_rect = m_prev_env.PRIM.TME ? GetTEX0Rect() : GSVector4i::zero();
if (m_index.tail > 0)
+1 -1
View File
@@ -633,7 +633,7 @@ bool GSHwHack::GSC_PolyphonyDigitalGames(GSRendererHW& r, int& skip)
// get away with just hardcoding it.
const GSVector2i resolution = r.PCRTCDisplays.GetResolution();
const GSVector2i size = GSVector2i(resolution.x, resolution.y / 2);
const u32 page_offset = ((size.y + 31) / 32) * src->m_TEX0.TBW * BLOCKS_PER_PAGE;
const u32 page_offset = ((size.y + 31) / 32) * src->m_TEX0.TBW * GS_BLOCKS_PER_PAGE;
constexpr u32 base = 0;
GL_PUSH("GSC_PolyphonyDigitalGames(): HLE Gran Turismo A channel shuffle");
+38 -38
View File
@@ -1292,10 +1292,10 @@ bool GSRendererHW::IsSplitTextureShuffle(GIFRegTEX0& rt_TEX0, GSVector4i& valid_
// "Potential" ones are for Jak3 which does a split shuffle on a 128x128 texture with a width of 256, writing to the lower half then offsetting 2 pages.
const u32 expected_next_FBP = (m_cached_ctx.FRAME.FBP + m_split_texture_shuffle_pages) + num_pages;
const u32 potential_expected_next_FBP = m_cached_ctx.FRAME.FBP + ((m_context->FRAME.FBW * 64) / aligned_rc.width());
const u32 expected_next_TBP0 = (m_cached_ctx.TEX0.TBP0 + (m_split_texture_shuffle_pages + num_pages) * BLOCKS_PER_PAGE);
const u32 potential_expected_next_TBP0 = m_cached_ctx.TEX0.TBP0 + (BLOCKS_PER_PAGE * ((m_context->TEX0.TBW * 64) / aligned_rc.width()));
const u32 expected_next_TBP0 = (m_cached_ctx.TEX0.TBP0 + (m_split_texture_shuffle_pages + num_pages) * GS_BLOCKS_PER_PAGE);
const u32 potential_expected_next_TBP0 = m_cached_ctx.TEX0.TBP0 + (GS_BLOCKS_PER_PAGE * ((m_context->TEX0.TBW * 64) / aligned_rc.width()));
GL_CACHE("HW: IsSplitTextureShuffle: Draw covers %ux%u pages, next FRAME %x TEX %x",
static_cast<u32>(aligned_rc.width()) / frame_psm.pgs.x, pages_high, expected_next_FBP * BLOCKS_PER_PAGE,
static_cast<u32>(aligned_rc.width()) / frame_psm.pgs.x, pages_high, expected_next_FBP * GS_BLOCKS_PER_PAGE,
expected_next_TBP0);
if (next_ctx.TEX0.TBP0 != expected_next_TBP0 && next_ctx.TEX0.TBP0 != potential_expected_next_TBP0 && next_ctx.TEX0.TBP0 != (rt_half << 5))
@@ -1307,8 +1307,8 @@ bool GSRendererHW::IsSplitTextureShuffle(GIFRegTEX0& rt_TEX0, GSVector4i& valid_
// Some games don't offset the FBP.
if (next_ctx.FRAME.FBP != expected_next_FBP && next_ctx.FRAME.FBP != m_cached_ctx.FRAME.FBP && next_ctx.FRAME.FBP != potential_expected_next_FBP && next_ctx.FRAME.FBP != rt_half)
{
GL_CACHE("HW: IsSplitTextureShuffle: Mismatch on FBP, expecting %x, got %x", expected_next_FBP * BLOCKS_PER_PAGE,
next_ctx.FRAME.FBP * BLOCKS_PER_PAGE);
GL_CACHE("HW: IsSplitTextureShuffle: Mismatch on FBP, expecting %x, got %x", expected_next_FBP * GS_BLOCKS_PER_PAGE,
next_ctx.FRAME.FBP * GS_BLOCKS_PER_PAGE);
return false;
}
@@ -1437,7 +1437,7 @@ bool GSRendererHW::TryToResolveSinglePageFramebuffer(GIFRegFRAME& FRAME, bool on
// Try with Z or FRAME (whichever we're not using).
tgt = g_texture_cache->GetTargetWithSharedBits(start_bp, new_psm ^ 0x30);
}
if (tgt && ((start_bp + (m_split_clear_pages * BLOCKS_PER_PAGE)) - 1) <= tgt->m_end_block)
if (tgt && ((start_bp + (m_split_clear_pages * GS_BLOCKS_PER_PAGE)) - 1) <= tgt->m_end_block)
{
GL_INS("HW: TryToResolveSinglePageWidth(): Using FBW of %u and PSM %s from existing target",
tgt->m_TEX0.PSM, GSUtil::GetPSMName(tgt->m_TEX0.PSM));
@@ -1542,9 +1542,9 @@ bool GSRendererHW::CheckNextDrawForSplitClear(const GSVector4i& r, u32* pages_co
if (pages_covered_by_this_draw)
{
if (end_block < m_cached_ctx.FRAME.Block())
*pages_covered_by_this_draw = (((MAX_BLOCKS - end_block) + m_cached_ctx.FRAME.Block()) + (BLOCKS_PER_PAGE)) / BLOCKS_PER_PAGE;
*pages_covered_by_this_draw = (((GS_MAX_BLOCKS - end_block) + m_cached_ctx.FRAME.Block()) + (GS_BLOCKS_PER_PAGE)) / GS_BLOCKS_PER_PAGE;
else
*pages_covered_by_this_draw = ((end_block - m_cached_ctx.FRAME.Block()) + (BLOCKS_PER_PAGE)) / BLOCKS_PER_PAGE;
*pages_covered_by_this_draw = ((end_block - m_cached_ctx.FRAME.Block()) + (GS_BLOCKS_PER_PAGE)) / GS_BLOCKS_PER_PAGE;
}
// must be changing FRAME
@@ -1557,7 +1557,7 @@ bool GSRendererHW::CheckNextDrawForSplitClear(const GSVector4i& r, u32* pages_co
// next FBP should point to the end of the rect
const GSDrawingContext& next_ctx = m_env.CTXT[m_backed_up_ctx];
if (next_ctx.FRAME.Block() != ((end_block + 1) % MAX_BLOCKS) ||
if (next_ctx.FRAME.Block() != ((end_block + 1) % GS_MAX_BLOCKS) ||
m_context->TEX0.U64 != next_ctx.TEX0.U64 ||
m_context->TEX1.U64 != next_ctx.TEX1.U64 || m_context->CLAMP.U64 != next_ctx.CLAMP.U64 ||
m_context->TEST.U64 != next_ctx.TEST.U64 || ((m_context->FRAME.U64 ^ next_ctx.FRAME.U64) & (~0x1FF)) != 0 ||
@@ -1571,7 +1571,7 @@ bool GSRendererHW::CheckNextDrawForSplitClear(const GSVector4i& r, u32* pages_co
{
const u32 end_z_block = GSLocalMemory::GetEndBlockAddress(
m_cached_ctx.ZBUF.Block(), m_cached_ctx.FRAME.FBW, m_cached_ctx.ZBUF.PSM, r);
if (next_ctx.ZBUF.Block() != ((end_z_block + 1) % MAX_BLOCKS))
if (next_ctx.ZBUF.Block() != ((end_z_block + 1) % GS_MAX_BLOCKS))
return false;
}
@@ -2594,7 +2594,7 @@ void GSRendererHW::Draw()
const GSVector4i new_r = GetSplitTextureShuffleDrawRect();
GL_CACHE(
"Split texture shuffle: FBP %x -> %x, TBP0 %x -> %x, draw %d,%d => %d,%d -> %d,%d => %d,%d",
m_cached_ctx.FRAME.Block(), m_split_texture_shuffle_start_FBP * BLOCKS_PER_PAGE,
m_cached_ctx.FRAME.Block(), m_split_texture_shuffle_start_FBP * GS_BLOCKS_PER_PAGE,
m_cached_ctx.TEX0.TBP0, m_split_texture_shuffle_start_TBP,
m_r.x, m_r.y, m_r.z, m_r.w,
new_r.x, new_r.y, new_r.z, new_r.w);
@@ -3793,7 +3793,7 @@ void GSRendererHW::Draw()
m_last_channel_shuffle_tbp = src->m_TEX0.TBP0;
// If it's a new target, we don't know where the end is as it's starting on a shuffle, so just do every shuffle following.
m_last_channel_shuffle_end_block = (rt->m_last_draw >= s_n) ? (MAX_BLOCKS - 1) : (rt->m_end_block < rt->m_TEX0.TBP0 ? (rt->m_end_block + MAX_BLOCKS) : rt->m_end_block);
m_last_channel_shuffle_end_block = (rt->m_last_draw >= s_n) ? (GS_MAX_BLOCKS - 1) : (rt->m_end_block < rt->m_TEX0.TBP0 ? (rt->m_end_block + GS_MAX_BLOCKS) : rt->m_end_block);
}
else
m_last_channel_shuffle_end_block = 0xFFFF;
@@ -3936,7 +3936,7 @@ void GSRendererHW::Draw()
m_last_channel_shuffle_end_block = (rt->m_TEX0.TBP0 + (src->m_from_target->m_end_block - src->m_from_target_TEX0.TBP0));
if (m_last_channel_shuffle_end_block < rt->m_TEX0.TBP0)
m_last_channel_shuffle_end_block += MAX_BLOCKS;
m_last_channel_shuffle_end_block += GS_MAX_BLOCKS;
// if the RT is bigger, then use that instead.
if (m_last_channel_shuffle_end_block < rt->m_end_block)
@@ -8454,17 +8454,17 @@ bool GSRendererHW::DetectDoubleHalfClear(bool& no_rt, bool& no_ds)
// path write out FRAME and Z separately, with their associated masks. Limit it to black to avoid false positives.
if (write_color == 0)
{
const GSTextureCache::Target* base_tgt = g_texture_cache->GetExactTarget(base * BLOCKS_PER_PAGE,
const GSTextureCache::Target* base_tgt = g_texture_cache->GetExactTarget(base * GS_BLOCKS_PER_PAGE,
m_cached_ctx.FRAME.FBW, clear_depth ? GSTextureCache::DepthStencil : GSTextureCache::RenderTarget,
GSLocalMemory::GetEndBlockAddress(half * BLOCKS_PER_PAGE, m_cached_ctx.FRAME.FBW, m_cached_ctx.FRAME.PSM, m_r));
GSLocalMemory::GetEndBlockAddress(half * GS_BLOCKS_PER_PAGE, m_cached_ctx.FRAME.FBW, m_cached_ctx.FRAME.PSM, m_r));
if (base_tgt)
{
GL_INS("HW: DetectDoubleHalfClear(): Invalidating targets at 0x%x/0x%x due to different formats, and clear to black.",
base * BLOCKS_PER_PAGE, half * BLOCKS_PER_PAGE);
g_texture_cache->InvalidateVideoMemType(GSTextureCache::RenderTarget, base * BLOCKS_PER_PAGE);
g_texture_cache->InvalidateVideoMemType(GSTextureCache::RenderTarget, half * BLOCKS_PER_PAGE);
g_texture_cache->InvalidateVideoMemType(GSTextureCache::DepthStencil, base * BLOCKS_PER_PAGE);
g_texture_cache->InvalidateVideoMemType(GSTextureCache::DepthStencil, half * BLOCKS_PER_PAGE);
base * GS_BLOCKS_PER_PAGE, half * GS_BLOCKS_PER_PAGE);
g_texture_cache->InvalidateVideoMemType(GSTextureCache::RenderTarget, base * GS_BLOCKS_PER_PAGE);
g_texture_cache->InvalidateVideoMemType(GSTextureCache::RenderTarget, half * GS_BLOCKS_PER_PAGE);
g_texture_cache->InvalidateVideoMemType(GSTextureCache::DepthStencil, base * GS_BLOCKS_PER_PAGE);
g_texture_cache->InvalidateVideoMemType(GSTextureCache::DepthStencil, half * GS_BLOCKS_PER_PAGE);
}
}
@@ -8501,16 +8501,16 @@ bool GSRendererHW::DetectDoubleHalfClear(bool& no_rt, bool& no_ds)
{
// Check for a target matching the starting point. It might be in Z or FRAME...
GSTextureCache::Target* tgt = g_texture_cache->GetTargetWithSharedBits(
base * BLOCKS_PER_PAGE, clear_depth ? m_cached_ctx.ZBUF.PSM : m_cached_ctx.FRAME.PSM);
base * GS_BLOCKS_PER_PAGE, clear_depth ? m_cached_ctx.ZBUF.PSM : m_cached_ctx.FRAME.PSM);
tgt = (tgt && tgt->m_valid_rgb && tgt->HasValidAlpha() == req_valid_alpha) ? tgt : nullptr;
if (!tgt)
{
tgt = g_texture_cache->GetTargetWithSharedBits(
base * BLOCKS_PER_PAGE, clear_depth ? m_cached_ctx.FRAME.PSM : m_cached_ctx.ZBUF.PSM);
base * GS_BLOCKS_PER_PAGE, clear_depth ? m_cached_ctx.FRAME.PSM : m_cached_ctx.ZBUF.PSM);
tgt = (tgt && tgt->m_valid_rgb && tgt->HasValidAlpha() == req_valid_alpha) ? tgt : nullptr;
}
u32 end_block = ((half + written_pages) * BLOCKS_PER_PAGE) - 1;
u32 end_block = ((half + written_pages) * GS_BLOCKS_PER_PAGE) - 1;
if (tgt && tgt->m_age <= 1)
{
@@ -8540,7 +8540,7 @@ bool GSRendererHW::DetectDoubleHalfClear(bool& no_rt, bool& no_ds)
}
// Are we clearing over the middle of this target?
if ((((half + written_pages) * BLOCKS_PER_PAGE) - 1) > end_block)
if ((((half + written_pages) * GS_BLOCKS_PER_PAGE) - 1) > end_block)
{
return false;
}
@@ -8548,7 +8548,7 @@ bool GSRendererHW::DetectDoubleHalfClear(bool& no_rt, bool& no_ds)
GL_INS("HW: DetectDoubleHalfClear(): Clearing %s %s, fbp=%x, zbp=%x, pages=%u, base=%x, half=%x, rect=(%d,%d=>%d,%d)",
clear_depth ? "depth" : "color", horizontal ? "horizontally" : "vertically", m_cached_ctx.FRAME.Block(),
m_cached_ctx.ZBUF.Block(), written_pages, base * BLOCKS_PER_PAGE, half * BLOCKS_PER_PAGE, m_r.x, m_r.y, m_r.z,
m_cached_ctx.ZBUF.Block(), written_pages, base * GS_BLOCKS_PER_PAGE, half * GS_BLOCKS_PER_PAGE, m_r.x, m_r.y, m_r.z,
m_r.w);
// Double the clear rect.
@@ -8584,22 +8584,22 @@ bool GSRendererHW::DetectDoubleHalfClear(bool& no_rt, bool& no_ds)
// Prevent wasting time looking up and creating the target which is getting blown away.
if (frame_psm.trbpp >= zbuf_psm.trbpp)
{
SetNewFRAME(base * BLOCKS_PER_PAGE, m_cached_ctx.FRAME.FBW, m_cached_ctx.FRAME.PSM);
SetNewFRAME(base * GS_BLOCKS_PER_PAGE, m_cached_ctx.FRAME.FBW, m_cached_ctx.FRAME.PSM);
m_cached_ctx.ZBUF.ZMSK = true;
no_rt = false;
no_ds = true;
}
else
{
SetNewZBUF(base * BLOCKS_PER_PAGE, m_cached_ctx.ZBUF.PSM);
SetNewZBUF(base * GS_BLOCKS_PER_PAGE, m_cached_ctx.ZBUF.PSM);
m_cached_ctx.FRAME.FBMSK = 0xFFFFFFFF;
no_rt = true;
no_ds = false;
}
// Remove any targets at the half-buffer point, they're getting overwritten.
g_texture_cache->InvalidateVideoMemType(GSTextureCache::RenderTarget, half * BLOCKS_PER_PAGE);
g_texture_cache->InvalidateVideoMemType(GSTextureCache::DepthStencil, half * BLOCKS_PER_PAGE);
g_texture_cache->InvalidateVideoMemType(GSTextureCache::RenderTarget, half * GS_BLOCKS_PER_PAGE);
g_texture_cache->InvalidateVideoMemType(GSTextureCache::DepthStencil, half * GS_BLOCKS_PER_PAGE);
return true;
}
@@ -8806,11 +8806,11 @@ void GSRendererHW::ClearGSLocalMemory(const GSOffset& off, const GSVector4i& r,
{
const GSVector4i vcolor = GSVector4i(vert_color);
const u32 iterations_per_page = (pages_wide * pixels_per_page) / 4;
pxAssert((off.bp() & (BLOCKS_PER_PAGE - 1)) == 0);
pxAssert((off.bp() & (GS_BLOCKS_PER_PAGE - 1)) == 0);
for (u32 current_page = off.bp() >> 5; top < page_aligned_bottom; top += pgs.y, current_page += fbw)
{
current_page &= (MAX_PAGES - 1);
GSVector4i* ptr = reinterpret_cast<GSVector4i*>(m_mem.vm8() + current_page * PAGE_SIZE);
current_page &= (GS_MAX_PAGES - 1);
GSVector4i* ptr = reinterpret_cast<GSVector4i*>(m_mem.vm8() + current_page * GS_PAGE_SIZE);
GSVector4i* const ptr_end = ptr + iterations_per_page;
while (ptr != ptr_end)
*(ptr++) = vcolor;
@@ -8821,11 +8821,11 @@ void GSRendererHW::ClearGSLocalMemory(const GSOffset& off, const GSVector4i& r,
const GSVector4i mask = GSVector4i::xff000000();
const GSVector4i vcolor = GSVector4i(vert_color & 0x00ffffffu);
const u32 iterations_per_page = (pages_wide * pixels_per_page) / 4;
pxAssert((off.bp() & (BLOCKS_PER_PAGE - 1)) == 0);
pxAssert((off.bp() & (GS_BLOCKS_PER_PAGE - 1)) == 0);
for (u32 current_page = off.bp() >> 5; top < page_aligned_bottom; top += pgs.y, current_page += fbw)
{
current_page &= (MAX_PAGES - 1);
GSVector4i* ptr = reinterpret_cast<GSVector4i*>(m_mem.vm8() + current_page * PAGE_SIZE);
current_page &= (GS_MAX_PAGES - 1);
GSVector4i* ptr = reinterpret_cast<GSVector4i*>(m_mem.vm8() + current_page * GS_PAGE_SIZE);
GSVector4i* const ptr_end = ptr + iterations_per_page;
while (ptr != ptr_end)
{
@@ -8840,11 +8840,11 @@ void GSRendererHW::ClearGSLocalMemory(const GSOffset& off, const GSVector4i& r,
((vert_color >> 6) & 0x7E0) | ((vert_color >> 3) & 0x1F);
const GSVector4i vcolor = GSVector4i::broadcast16(converted_color);
const u32 iterations_per_page = (pages_wide * pixels_per_page) / 8;
pxAssert((off.bp() & (BLOCKS_PER_PAGE - 1)) == 0);
pxAssert((off.bp() & (GS_BLOCKS_PER_PAGE - 1)) == 0);
for (u32 current_page = off.bp() >> 5; top < page_aligned_bottom; top += pgs.y, current_page += fbw)
{
current_page &= (MAX_PAGES - 1);
GSVector4i* ptr = reinterpret_cast<GSVector4i*>(m_mem.vm8() + current_page * PAGE_SIZE);
current_page &= (GS_MAX_PAGES - 1);
GSVector4i* ptr = reinterpret_cast<GSVector4i*>(m_mem.vm8() + current_page * GS_PAGE_SIZE);
GSVector4i* const ptr_end = ptr + iterations_per_page;
while (ptr != ptr_end)
*(ptr++) = vcolor;
+15 -15
View File
@@ -1329,7 +1329,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
// If the BP is offset in to a page and the format does not match, trying to match up the correct position is very difficult since we don't swizzle.
// Tomb Raider Legends does a block level BP in PSMT8 over a C16 target, which is just a nightmare to get right.
// Baldurs Gate used to have this too, but now we can translate HW moves inside targets when the format matches.
if (((bp & (BLOCKS_PER_PAGE - 1)) != (t->m_TEX0.TBP0 & (BLOCKS_PER_PAGE - 1))) && (bp & (BLOCKS_PER_PAGE - 1)))
if (((bp & (GS_BLOCKS_PER_PAGE - 1)) != (t->m_TEX0.TBP0 & (GS_BLOCKS_PER_PAGE))) && (bp & (GS_BLOCKS_PER_PAGE - 1)))
continue;
const bool width_match = (std::max(64U, bw * 64U) >> GSLocalMemory::m_psm[psm].info.pageShiftX()) ==
@@ -3405,7 +3405,7 @@ bool GSTextureCache::PreloadTarget(GIFRegTEX0 TEX0, const GSVector2i& size, cons
const GSVector4i dst_valid = dst->m_valid.rempty() ? GSVector4i::loadh(valid_size) : dst->m_valid;
u32 dst_end_block = GSLocalMemory::GetEndBlockAddress(dst->m_TEX0.TBP0, dst->m_TEX0.TBW, dst->m_TEX0.PSM, dst_valid);
if (dst_end_block < dst->m_TEX0.TBP0)
dst_end_block += MAX_BLOCKS;
dst_end_block += GS_MAX_BLOCKS;
// Can't do channel writes to depth targets, and DirectX can't partial copy depth targets.
if (psm_s.depth == 0)
@@ -4770,7 +4770,7 @@ void GSTextureCache::InvalidateLocalMem(const GSOffset& off, const GSVector4i& r
bool only_in_dirty_area = true;
off.pageLooperForRect(r).loopPagesWithBreak([t, &dirty_rect, &only_in_dirty_area](u32 page) {
const GSVector4i page_rect = GSLocalMemory::GetRectForPageOffset(t->m_TEX0.TBP0,
page * BLOCKS_PER_PAGE, t->m_TEX0.TBW, t->m_TEX0.PSM);
page * GS_BLOCKS_PER_PAGE, t->m_TEX0.TBW, t->m_TEX0.PSM);
if (!dirty_rect.rintersect(page_rect).eq(page_rect))
{
only_in_dirty_area = false;
@@ -5141,8 +5141,8 @@ bool GSTextureCache::Move(u32 SBP, u32 SBW, u32 SPSM, int sx, int sy, u32 DBP, u
// Page copy
if (w == GSLocalMemory::m_psm[src->m_TEX0.PSM].pgs.x && h == GSLocalMemory::m_psm[src->m_TEX0.PSM].pgs.y)
{
m_expected_src_bp = start_SBP + BLOCKS_PER_PAGE;
m_expected_dst_bp = start_DBP + BLOCKS_PER_PAGE;
m_expected_src_bp = start_SBP + GS_BLOCKS_PER_PAGE;
m_expected_dst_bp = start_DBP + GS_BLOCKS_PER_PAGE;
}
// Vertical Strips.
else if (w == GSLocalMemory::m_psm[src->m_TEX0.PSM].pgs.x)
@@ -5271,9 +5271,9 @@ bool GSTextureCache::PageMove(u32 SBP, u32 DBP, u32 BW, u32 PSM, int sx, int sy,
const GSVector2i& pgs = GSLocalMemory::m_psm[PSM].pgs;
const u32 num_pages = (h / pgs.y) * BW;
const u32 src_page_offset = ((sy / pgs.y) * BW) + (sx / pgs.x);
const u32 src_block_end = SBP + (((src_page_offset + num_pages) * BLOCKS_PER_PAGE) - 1);
const u32 src_block_end = SBP + (((src_page_offset + num_pages) * GS_BLOCKS_PER_PAGE) - 1);
const u32 dst_page_offset = ((dy / pgs.y) * BW) + (dx / pgs.x);
const u32 dst_block_end = DBP + (((dst_page_offset + num_pages) * BLOCKS_PER_PAGE) - 1);
const u32 dst_block_end = DBP + (((dst_page_offset + num_pages) * GS_BLOCKS_PER_PAGE) - 1);
pxAssert(num_pages > 0);
GL_PUSH("TC: GSTextureCache::PageMove(): %u pages, with offset of %u src %u dst", num_pages, src_page_offset,
dst_page_offset);
@@ -5310,15 +5310,15 @@ bool GSTextureCache::PageMove(u32 SBP, u32 DBP, u32 BW, u32 PSM, int sx, int sy,
}
// Double-check that we're not copying to a non-page-aligned target.
if (((SBP - stgt->m_TEX0.TBP0) % BLOCKS_PER_PAGE) != 0 || ((DBP - dtgt->m_TEX0.TBP0) % BLOCKS_PER_PAGE) != 0)
if (((SBP - stgt->m_TEX0.TBP0) % GS_BLOCKS_PER_PAGE) != 0 || ((DBP - dtgt->m_TEX0.TBP0) % GS_BLOCKS_PER_PAGE) != 0)
{
GL_INS("TC: Effective SBP of %x or DBP of %x is not page aligned.", SBP - stgt->m_TEX0.TBP0, DBP - dtgt->m_TEX0.TBP0);
return false;
}
// Need to offset based on the target's actual BP.
const u32 real_src_offset = ((SBP - stgt->m_TEX0.TBP0) / BLOCKS_PER_PAGE) + src_page_offset;
const u32 real_dst_offset = ((DBP - dtgt->m_TEX0.TBP0) / BLOCKS_PER_PAGE) + dst_page_offset;
const u32 real_src_offset = ((SBP - stgt->m_TEX0.TBP0) / GS_BLOCKS_PER_PAGE) + src_page_offset;
const u32 real_dst_offset = ((DBP - dtgt->m_TEX0.TBP0) / GS_BLOCKS_PER_PAGE) + dst_page_offset;
CopyPages(stgt, stgt->m_TEX0.TBW, real_src_offset, dtgt, dtgt->m_TEX0.TBW, real_dst_offset, num_pages);
return true;
}
@@ -7047,8 +7047,8 @@ bool GSTextureCache::Surface::Overlaps(u32 bp, u32 bw, u32 psm, const GSVector4i
}
// Wrapping around to the beginning of memory.
if (end_block > MAX_BLOCKS && bp < m_end_block && m_end_block < m_TEX0.TBP0)
bp += MAX_BLOCKS;
if (end_block > GS_MAX_BLOCKS && bp < m_end_block && m_end_block < m_TEX0.TBP0)
bp += GS_MAX_BLOCKS;
const bool overlap = GSTextureCache::CheckOverlap(m_TEX0.TBP0, UnwrappedEndBlock(), start_block, end_block);
return overlap;
@@ -7144,7 +7144,7 @@ void GSTextureCache::Source::Update(const GSVector4i& rect, int level)
u32 blocks = 0;
if (!m_valid)
m_valid = std::make_unique<u32[]>(MAX_PAGES);
m_valid = std::make_unique<u32[]>(GS_MAX_PAGES);
if (m_repeating)
{
@@ -7153,7 +7153,7 @@ void GSTextureCache::Source::Update(const GSVector4i& rect, int level)
for (int x = r.left; x < r.right; bn.nextBlockX(), x += bs.x)
{
const int i = (bn.blkY() << 7) + bn.blkX();
const u32 addr = i % MAX_BLOCKS;
const u32 addr = i % GS_MAX_BLOCKS;
const u32 row = addr >> 5u;
const u32 col = 1 << (addr & 31u);
@@ -8522,7 +8522,7 @@ __fi static void BlockHashReset(BlockHashState& st)
__fi static void BlockHashAccumulate(BlockHashState& st, const u8* bp)
{
GSXXH3_64bits_update(&st, bp, BLOCK_SIZE);
GSXXH3_64bits_update(&st, bp, GS_BLOCK_SIZE);
}
__fi static void BlockHashAccumulate(BlockHashState& st, const u8* bp, u32 size)
+3 -3
View File
@@ -155,7 +155,7 @@ public:
/// Returns the end block for the target, but doesn't wrap at 0x3FFF.
/// Can be used for overlap tests.
u32 UnwrappedEndBlock() const { return (m_end_block + (Wraps() ? MAX_BLOCKS : 0)); }
u32 UnwrappedEndBlock() const { return (m_end_block + (Wraps() ? GS_MAX_BLOCKS : 0)); }
bool Inside(u32 bp, u32 bw, u32 psm, const GSVector4i& rect);
bool Overlaps(u32 bp, u32 bw, u32 psm, const GSVector4i& rect);
@@ -312,7 +312,7 @@ public:
HashType m_layer_hash[7] = {};
// Keep a GSTextureCache::SourceMap::m_map iterator to allow fast erase
// Deliberately not initialized to save cycles.
std::array<u16, MAX_PAGES> m_erase_it;
std::array<u16, GS_MAX_PAGES> m_erase_it;
GSOffset::PageLooper m_pages;
public:
@@ -360,7 +360,7 @@ public:
{
public:
std::unordered_set<Source*> m_surfaces;
std::array<FastList<Source*>, MAX_PAGES> m_map;
std::array<FastList<Source*>, GS_MAX_PAGES> m_map;
void Add(Source* s, const GIFRegTEX0& TEX0);
void SwapTexture(GSTexture* old_tex, GSTexture* new_tex);
+3 -3
View File
@@ -23,8 +23,8 @@ public:
bool m_complete;
bool m_repeating;
std::vector<GSVector2i>* m_p2t;
u32 m_valid[MAX_PAGES];
std::array<u16, MAX_PAGES> m_erase_it;
u32 m_valid[GS_MAX_PAGES];
std::array<u16, GS_MAX_PAGES> m_erase_it;
const u32* RESTRICT m_sharedbits;
// m_valid
@@ -42,7 +42,7 @@ public:
protected:
std::unordered_set<Texture*> m_textures;
std::array<FastList<Texture*>, MAX_PAGES> m_map;
std::array<FastList<Texture*>, GS_MAX_PAGES> m_map;
public:
GSTextureCacheSW();