pvr: don't merge polys with != palette. 2nd pass sometimes ignored

polys with different palette index shouldn't be merged.
If a pass isn't using any opaque, it can't be found. Fall back to using
the transparent or punch-through list in this case.
This commit is contained in:
Flyinghead 2022-02-17 18:30:29 +01:00
parent d736dd027d
commit f2374982b8
3 changed files with 36 additions and 4 deletions

View File

@ -270,10 +270,25 @@ static u32 opbSize(int n)
static void markObjectListBlocks()
{
u32 addr = TA_OL_BASE;
// opaque
u32 opBlockSize = opbSize(TA_ALLOC_CTRL & 3);
if (opBlockSize == 0)
return;
u32 addr = TA_OL_BASE;
{
// skip modvols OPBs
addr += opbSize((TA_ALLOC_CTRL >> 4) & 3) * (TA_GLOB_TILE_CLIP.tile_y_num + 1) * (TA_GLOB_TILE_CLIP.tile_x_num + 1);
// transparent
opBlockSize = opbSize((TA_ALLOC_CTRL >> 8) & 3);
if (opBlockSize == 0)
{
// skip TR modvols OPBs
addr += opbSize((TA_ALLOC_CTRL >> 12) & 3) * (TA_GLOB_TILE_CLIP.tile_y_num + 1) * (TA_GLOB_TILE_CLIP.tile_x_num + 1);
// punch-through
opBlockSize = opbSize((TA_ALLOC_CTRL >> 16) & 3);
if (opBlockSize == 0)
return;
}
}
for (int y = 0; y <= TA_GLOB_TILE_CLIP.tile_y_num; y++)
for (int x = 0; x <= TA_GLOB_TILE_CLIP.tile_x_num; x++)
{

View File

@ -94,10 +94,10 @@ struct PolyParam
{
return ((pcw.full ^ other.pcw.full) & 0x300CE) == 0
&& ((isp.full ^ other.isp.full) & 0xF4000000) == 0
&& ((tcw.full ^ other.tcw.full) & 0xFE1FFFFF) == 0
&& tcw.full == other.tcw.full
&& tsp.full == other.tsp.full
&& tileclip == other.tileclip
&& ((tcw1.full ^ other.tcw1.full) & 0xFE1FFFFF) == 0
&& tcw1.full == other.tcw1.full
&& tsp1.full == other.tsp1.full
&& mvMatrix == other.mvMatrix
&& normalMatrix == other.normalMatrix

View File

@ -2122,7 +2122,24 @@ int getTAContextAddresses(u32 *addresses)
tile.full = pvr_read32p<u32>(addr);
if (tile.X != x || tile.Y != y)
break;
// Try the opaque pointer
u32 opbAddr = pvr_read32p<u32>(addr + 4);
if (opbAddr == 0xffffffff)
{
// Try the translucent pointer
opbAddr = pvr_read32p<u32>(addr + 12);
if (opbAddr == 0xffffffff)
{
// Try the punch-through pointer
if (tile_size >= 24)
opbAddr = pvr_read32p<u32>(addr + 20);
if (opbAddr == 0xffffffff)
{
INFO_LOG(PVR, "Can't find any non-null OPB for pass %d", count);
break;
}
}
}
addresses[count++] = pvr_read32p<u32>(opbAddr);
addr += tile_size;
} while (!tile.LastRegion && count < MAX_PASSES);