mirror of
https://github.com/ARMSX2/ARMSX2.git
synced 2026-08-24 16:50:16 -07:00
GS: Prefix page/block size defines
This commit is contained in:
committed by
lightningterror
parent
77738f72b4
commit
f747abcc3b
+11
-11
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user