Skip to content

Commit e62de23

Browse files
committed
CPU/PGXP: Allocate storage based on active RAM size
Roughly a 3x performance improvement when using PGXP with runahead, copying those extra 32MB or so worth of values really hurts. Also saves that memory from being pointlessly allocated in the non-runahead case.
1 parent a10d7f6 commit e62de23

File tree

3 files changed

+20
-11
lines changed

3 files changed

+20
-11
lines changed

src/core/cpu_pgxp.cpp

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ enum : u32
3636
VERTEX_CACHE_WIDTH = 2048,
3737
VERTEX_CACHE_HEIGHT = 2048,
3838
VERTEX_CACHE_SIZE = VERTEX_CACHE_WIDTH * VERTEX_CACHE_HEIGHT,
39-
PGXP_MEM_SIZE = (static_cast<u32>(Bus::RAM_8MB_SIZE) + static_cast<u32>(CPU::SCRATCHPAD_SIZE)) / 4,
40-
PGXP_MEM_SCRATCH_OFFSET = Bus::RAM_8MB_SIZE / 4,
39+
PGXP_SCRATCH_VALUE_COUNT = (CPU::SCRATCHPAD_SIZE / 4u),
40+
PGXP_MEM_RAM_OFFSET = PGXP_SCRATCH_VALUE_COUNT,
4141
};
4242

4343
enum : u32
@@ -63,6 +63,8 @@ enum : u32
6363

6464
#define PGXP_GTE_REGISTER(field) g_state.pgxp_gte[offsetof(GTE::Regs, field) / sizeof(u32)]
6565

66+
static size_t GetMemoryValueCount();
67+
6668
static double f16Sign(double val);
6769
static double f16Unsign(double val);
6870
static double f16Overflow(double val);
@@ -128,6 +130,11 @@ static std::FILE* s_log;
128130
#endif
129131
} // namespace CPU::PGXP
130132

133+
size_t CPU::PGXP::GetMemoryValueCount()
134+
{
135+
return (PGXP_SCRATCH_VALUE_COUNT + (Bus::g_ram_size / 4u));
136+
}
137+
131138
void CPU::PGXP::Initialize()
132139
{
133140
// Just in case due to memory layout...
@@ -142,7 +149,7 @@ void CPU::PGXP::Initialize()
142149

143150
if (!s_mem)
144151
{
145-
s_mem = static_cast<PGXPValue*>(std::calloc(PGXP_MEM_SIZE, sizeof(PGXPValue)));
152+
s_mem = static_cast<PGXPValue*>(std::calloc(GetMemoryValueCount(), sizeof(PGXPValue)));
146153
if (!s_mem)
147154
Panic("Failed to allocate PGXP memory");
148155
}
@@ -168,7 +175,7 @@ void CPU::PGXP::Reset()
168175
std::memset(g_state.pgxp_gte, 0, sizeof(g_state.pgxp_gte));
169176

170177
if (s_mem)
171-
std::memset(s_mem, 0, sizeof(PGXPValue) * PGXP_MEM_SIZE);
178+
std::memset(s_mem, 0, sizeof(PGXPValue) * GetMemoryValueCount());
172179

173180
if (g_settings.gpu_pgxp_vertex_cache && s_vertex_cache)
174181
std::memset(s_vertex_cache, 0, sizeof(PGXPValue) * VERTEX_CACHE_SIZE);
@@ -199,10 +206,12 @@ bool CPU::PGXP::ShouldSavePGXPState()
199206
return (g_settings.gpu_pgxp_enable && g_settings.IsRunaheadEnabled());
200207
}
201208

202-
size_t CPU::PGXP::GetStateSize()
209+
size_t CPU::PGXP::GetStateSize(bool enable_8mb_memory)
203210
{
211+
static constexpr u32 value_count_2mb = (PGXP_SCRATCH_VALUE_COUNT + (Bus::RAM_2MB_SIZE / 4u));
212+
static constexpr u32 value_count_8mb = (PGXP_SCRATCH_VALUE_COUNT + (Bus::RAM_8MB_SIZE / 4u));
204213
const size_t base_size = sizeof(g_state.pgxp_gpr) + sizeof(g_state.pgxp_cop0) + sizeof(g_state.pgxp_gte) +
205-
(sizeof(PGXPValue) * PGXP_MEM_SIZE);
214+
(sizeof(PGXPValue) * (enable_8mb_memory ? value_count_8mb : value_count_2mb));
206215
const size_t vertex_cache_size = sizeof(PGXPValue) * VERTEX_CACHE_SIZE;
207216
return base_size + (g_settings.gpu_pgxp_vertex_cache ? vertex_cache_size : 0);
208217
}
@@ -219,7 +228,7 @@ void CPU::PGXP::DoState(StateWrapper& sw)
219228
sw.DoBytes(g_state.pgxp_cop0, sizeof(g_state.pgxp_cop0));
220229
sw.DoBytes(g_state.pgxp_gte, sizeof(g_state.pgxp_gte));
221230

222-
sw.DoBytes(s_mem, sizeof(PGXPValue) * PGXP_MEM_SIZE);
231+
sw.DoBytes(s_mem, sizeof(PGXPValue) * GetMemoryValueCount());
223232

224233
if (s_vertex_cache)
225234
sw.DoBytes(s_vertex_cache, sizeof(PGXPValue) * VERTEX_CACHE_SIZE);
@@ -293,12 +302,12 @@ ALWAYS_INLINE_RELEASE CPU::PGXPValue* CPU::PGXP::GetPtr(u32 addr)
293302
#endif
294303

295304
if ((addr & SCRATCHPAD_ADDR_MASK) == SCRATCHPAD_ADDR)
296-
return &s_mem[PGXP_MEM_SCRATCH_OFFSET + ((addr & SCRATCHPAD_OFFSET_MASK) >> 2)];
305+
return &s_mem[((addr & SCRATCHPAD_OFFSET_MASK) >> 2)];
297306

298307
// Don't worry about >512MB here for performance reasons.
299308
const u32 paddr = (addr & KSEG_MASK);
300309
if (paddr < Bus::RAM_MIRROR_END)
301-
return &s_mem[(paddr & Bus::g_ram_mask) >> 2];
310+
return &s_mem[PGXP_MEM_RAM_OFFSET + ((paddr & Bus::g_ram_mask) >> 2)];
302311
else
303312
return nullptr;
304313
}

src/core/cpu_pgxp.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ void Shutdown();
1515
bool ShouldSavePGXPState();
1616

1717
/// Returns memory usage to serialize additional PGXP state.
18-
size_t GetStateSize();
18+
size_t GetStateSize(bool enable_8mb_memory);
1919

2020
/// Save/load additional PGXP state.
2121
void DoState(StateWrapper& sw);

src/core/system.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3022,7 +3022,7 @@ size_t System::GetMaxSaveStateSize(bool enable_8mb_ram)
30223022

30233023
size_t System::GetMaxMemorySaveStateSize(bool enable_8mb_ram, bool pgxp)
30243024
{
3025-
return GetMaxSaveStateSize(enable_8mb_ram) + (pgxp ? CPU::PGXP::GetStateSize() : 0);
3025+
return GetMaxSaveStateSize(enable_8mb_ram) + (pgxp ? CPU::PGXP::GetStateSize(enable_8mb_ram) : 0);
30263026
}
30273027

30283028
std::string System::GetMediaPathFromSaveState(const char* path)

0 commit comments

Comments
 (0)