directly set VRAMDirty for VRAM BG/OAM writes

This commit is contained in:
RSDuck 2021-02-23 02:09:14 +01:00
parent 97643586fa
commit 58dd1ec580
2 changed files with 86 additions and 69 deletions

View File

@ -93,8 +93,7 @@ std::unique_ptr<GPU2D> GPU2D_B = {};
we don't want to completely invalidate them every time they're unmapped and remapped
For this reason we don't track the dirtyness per mapping region, but instead per VRAM bank
with VRAMDirty. Writes to LCDC go directly into VRAMDirty, while writes via other mapping regions
like BG or OBJ are first tracked in VRAMWritten_* and need to be flushed using SyncDirtyFlags.
with VRAMDirty.
This is more or less a description of VRAMTrackingSet::DeriveState
Each time before the memory is read two things could have happened
@ -120,13 +119,6 @@ VRAMTrackingSet<8*1024, 8*1024> VRAMDirty_BOBJExtPal;
VRAMTrackingSet<512*1024, 128*1024> VRAMDirty_Texture;
VRAMTrackingSet<128*1024, 16*1024> VRAMDirty_TexPal;
NonStupidBitField<512*1024/VRAMDirtyGranularity> VRAMWritten_ABG;
NonStupidBitField<256*1024/VRAMDirtyGranularity> VRAMWritten_AOBJ;
NonStupidBitField<128*1024/VRAMDirtyGranularity> VRAMWritten_BBG;
NonStupidBitField<128*1024/VRAMDirtyGranularity> VRAMWritten_BOBJ;
NonStupidBitField<256*1024/VRAMDirtyGranularity> VRAMWritten_ARM7;
NonStupidBitField<128*1024/VRAMDirtyGranularity> VRAMDirty[9];
u8 VRAMFlat_ABG[512*1024];
@ -1028,8 +1020,6 @@ void StartHBlank(u32 line)
DispStat[0] |= (1<<1);
DispStat[1] |= (1<<1);
SyncDirtyFlags();
if (VCount < 192)
{
// draw
@ -1266,34 +1256,6 @@ template NonStupidBitField<128*1024/VRAMDirtyGranularity> VRAMTrackingSet<128*10
template NonStupidBitField<256*1024/VRAMDirtyGranularity> VRAMTrackingSet<256*1024, 16*1024>::DeriveState(u32*);
template NonStupidBitField<512*1024/VRAMDirtyGranularity> VRAMTrackingSet<512*1024, 16*1024>::DeriveState(u32*);
template <u32 Size>
void SyncDirtyFlags(u32* mappings, NonStupidBitField<Size>& writtenFlags)
{
const u32 VRAMWrittenBitsPer16KB = 16*1024/VRAMDirtyGranularity;
for (typename NonStupidBitField<Size>::Iterator it = writtenFlags.Begin(); it != writtenFlags.End(); it++)
{
u32 mapping = mappings[*it / VRAMWrittenBitsPer16KB];
while (mapping != 0)
{
u32 num = __builtin_ctz(mapping);
VRAMDirty[num][*it & (VRAMMask[num] / VRAMDirtyGranularity)] = true;
mapping &= ~(1 << num);
}
}
writtenFlags.Clear();
}
void SyncDirtyFlags()
{
SyncDirtyFlags(VRAMMap_ABG, VRAMWritten_ABG);
SyncDirtyFlags(VRAMMap_AOBJ, VRAMWritten_AOBJ);
SyncDirtyFlags(VRAMMap_BBG, VRAMWritten_BBG);
SyncDirtyFlags(VRAMMap_BOBJ, VRAMWritten_BOBJ);
}
template <u32 MappingGranularity, u32 Size>
inline bool CopyLinearVRAM(u8* flat, u32* mappings, NonStupidBitField<Size>& dirty, u64 (*slowAccess)(u32 addr))
{

115
src/GPU.h
View File

@ -82,11 +82,6 @@ extern int Renderer;
const u32 VRAMDirtyGranularity = 512;
extern NonStupidBitField<512*1024/VRAMDirtyGranularity> VRAMWritten_ABG;
extern NonStupidBitField<256*1024/VRAMDirtyGranularity> VRAMWritten_AOBJ;
extern NonStupidBitField<128*1024/VRAMDirtyGranularity> VRAMWritten_BBG;
extern NonStupidBitField<128*1024/VRAMDirtyGranularity> VRAMWritten_BOBJ;
extern NonStupidBitField<128*1024/VRAMDirtyGranularity> VRAMDirty[9];
template <u32 Size, u32 MappingGranularity>
@ -350,15 +345,41 @@ void WriteVRAM_ABG(u32 addr, T val)
{
u32 mask = VRAMMap_ABG[(addr >> 14) & 0x1F];
VRAMWritten_ABG[(addr & 0x7FFFF) / VRAMDirtyGranularity] = true;
if (mask & (1<<0)) *(T*)&VRAM_A[addr & 0x1FFFF] = val;
if (mask & (1<<1)) *(T*)&VRAM_B[addr & 0x1FFFF] = val;
if (mask & (1<<2)) *(T*)&VRAM_C[addr & 0x1FFFF] = val;
if (mask & (1<<3)) *(T*)&VRAM_D[addr & 0x1FFFF] = val;
if (mask & (1<<4)) *(T*)&VRAM_E[addr & 0xFFFF] = val;
if (mask & (1<<5)) *(T*)&VRAM_F[addr & 0x3FFF] = val;
if (mask & (1<<6)) *(T*)&VRAM_G[addr & 0x3FFF] = val;
if (mask & (1<<0))
{
VRAMDirty[0][(addr & 0x1FFFF) / VRAMDirtyGranularity] = true;
*(T*)&VRAM_A[addr & 0x1FFFF] = val;
}
if (mask & (1<<1))
{
VRAMDirty[1][(addr & 0x1FFFF) / VRAMDirtyGranularity] = true;
*(T*)&VRAM_B[addr & 0x1FFFF] = val;
}
if (mask & (1<<2))
{
VRAMDirty[2][(addr & 0x1FFFF) / VRAMDirtyGranularity] = true;
*(T*)&VRAM_C[addr & 0x1FFFF] = val;
}
if (mask & (1<<3))
{
VRAMDirty[3][(addr & 0x1FFFF) / VRAMDirtyGranularity] = true;
*(T*)&VRAM_D[addr & 0x1FFFF] = val;
}
if (mask & (1<<4))
{
VRAMDirty[4][(addr & 0xFFFF) / VRAMDirtyGranularity] = true;
*(T*)&VRAM_E[addr & 0xFFFF] = val;
}
if (mask & (1<<5))
{
VRAMDirty[5][(addr & 0x3FFF) / VRAMDirtyGranularity] = true;
*(T*)&VRAM_F[addr & 0x3FFF] = val;
}
if (mask & (1<<6))
{
VRAMDirty[6][(addr & 0x3FFF) / VRAMDirtyGranularity] = true;
*(T*)&VRAM_G[addr & 0x3FFF] = val;
}
}
@ -385,13 +406,31 @@ void WriteVRAM_AOBJ(u32 addr, T val)
{
u32 mask = VRAMMap_AOBJ[(addr >> 14) & 0xF];
VRAMWritten_AOBJ[(addr & 0x3FFFF) / VRAMDirtyGranularity] = true;
if (mask & (1<<0)) *(T*)&VRAM_A[addr & 0x1FFFF] = val;
if (mask & (1<<1)) *(T*)&VRAM_B[addr & 0x1FFFF] = val;
if (mask & (1<<4)) *(T*)&VRAM_E[addr & 0xFFFF] = val;
if (mask & (1<<5)) *(T*)&VRAM_F[addr & 0x3FFF] = val;
if (mask & (1<<6)) *(T*)&VRAM_G[addr & 0x3FFF] = val;
if (mask & (1<<0))
{
VRAMDirty[0][(addr & 0x1FFFF) / VRAMDirtyGranularity] = true;
*(T*)&VRAM_A[addr & 0x1FFFF] = val;
}
if (mask & (1<<1))
{
VRAMDirty[1][(addr & 0x1FFFF) / VRAMDirtyGranularity] = true;
*(T*)&VRAM_B[addr & 0x1FFFF] = val;
}
if (mask & (1<<4))
{
VRAMDirty[4][(addr & 0xFFFF) / VRAMDirtyGranularity] = true;
*(T*)&VRAM_E[addr & 0xFFFF] = val;
}
if (mask & (1<<5))
{
VRAMDirty[5][(addr & 0x3FFF) / VRAMDirtyGranularity] = true;
*(T*)&VRAM_F[addr & 0x3FFF] = val;
}
if (mask & (1<<6))
{
VRAMDirty[6][(addr & 0x3FFF) / VRAMDirtyGranularity] = true;
*(T*)&VRAM_G[addr & 0x3FFF] = val;
}
}
@ -416,11 +455,21 @@ void WriteVRAM_BBG(u32 addr, T val)
{
u32 mask = VRAMMap_BBG[(addr >> 14) & 0x7];
VRAMWritten_BBG[(addr & 0x1FFFF) / VRAMDirtyGranularity] = true;
if (mask & (1<<2)) *(T*)&VRAM_C[addr & 0x1FFFF] = val;
if (mask & (1<<7)) *(T*)&VRAM_H[addr & 0x7FFF] = val;
if (mask & (1<<8)) *(T*)&VRAM_I[addr & 0x3FFF] = val;
if (mask & (1<<2))
{
VRAMDirty[2][(addr & 0x1FFFF) / VRAMDirtyGranularity] = true;
*(T*)&VRAM_C[addr & 0x1FFFF] = val;
}
if (mask & (1<<7))
{
VRAMDirty[7][(addr & 0x7FFF) / VRAMDirtyGranularity] = true;
*(T*)&VRAM_H[addr & 0x7FFF] = val;
}
if (mask & (1<<8))
{
VRAMDirty[8][(addr & 0x3FFF) / VRAMDirtyGranularity] = true;
*(T*)&VRAM_I[addr & 0x3FFF] = val;
}
}
@ -444,10 +493,16 @@ void WriteVRAM_BOBJ(u32 addr, T val)
{
u32 mask = VRAMMap_BOBJ[(addr >> 14) & 0x7];
VRAMWritten_BOBJ[(addr & 0x1FFFF) / VRAMDirtyGranularity] = true;
if (mask & (1<<3)) *(T*)&VRAM_D[addr & 0x1FFFF] = val;
if (mask & (1<<8)) *(T*)&VRAM_I[addr & 0x3FFF] = val;
if (mask & (1<<3))
{
VRAMDirty[3][(addr & 0x1FFFF) / VRAMDirtyGranularity] = true;
*(T*)&VRAM_D[addr & 0x1FFFF] = val;
}
if (mask & (1<<8))
{
VRAMDirty[8][(addr & 0x3FFF) / VRAMDirtyGranularity] = true;
*(T*)&VRAM_I[addr & 0x3FFF] = val;
}
}
template<typename T>