PGXP: Allocate large storage dynamically
This causes performance issues on ARM otherwise.
This commit is contained in:
parent
1b47e6e8cd
commit
a2eaaf0e89
|
@ -61,6 +61,7 @@ void Initialize()
|
||||||
void Shutdown()
|
void Shutdown()
|
||||||
{
|
{
|
||||||
// GTE::Shutdown();
|
// GTE::Shutdown();
|
||||||
|
PGXP::Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reset()
|
void Reset()
|
||||||
|
@ -128,7 +129,8 @@ bool DoState(StateWrapper& sw)
|
||||||
if (sw.IsReading())
|
if (sw.IsReading())
|
||||||
{
|
{
|
||||||
ClearICache();
|
ClearICache();
|
||||||
PGXP::Initialize();
|
if (g_settings.gpu_pgxp_enable)
|
||||||
|
PGXP::Initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
return !sw.HasError();
|
return !sw.HasError();
|
||||||
|
|
|
@ -561,6 +561,9 @@ void HostInterface::CheckForSettingsChanges(const Settings& old_settings)
|
||||||
CPU::CodeCache::Flush();
|
CPU::CodeCache::Flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (old_settings.gpu_pgxp_enable)
|
||||||
|
PGXP::Shutdown();
|
||||||
|
|
||||||
if (g_settings.gpu_pgxp_enable)
|
if (g_settings.gpu_pgxp_enable)
|
||||||
PGXP::Initialize();
|
PGXP::Initialize();
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
|
|
||||||
#include "pgxp.h"
|
#include "pgxp.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include <cmath>
|
|
||||||
#include <climits>
|
#include <climits>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
namespace PGXP {
|
namespace PGXP {
|
||||||
// pgxp_types.h
|
// pgxp_types.h
|
||||||
|
@ -134,6 +134,26 @@ static void WriteMem(PGXP_value* value, u32 addr);
|
||||||
static void WriteMem16(PGXP_value* src, u32 addr);
|
static void WriteMem16(PGXP_value* src, u32 addr);
|
||||||
|
|
||||||
// pgxp_gpu.h
|
// pgxp_gpu.h
|
||||||
|
enum : u32
|
||||||
|
{
|
||||||
|
VERTEX_CACHE_WIDTH = 0x800 * 2,
|
||||||
|
VERTEX_CACHE_HEIGHT = 0x800 * 2,
|
||||||
|
VERTEX_CACHE_SIZE = VERTEX_CACHE_WIDTH * VERTEX_CACHE_HEIGHT,
|
||||||
|
PGXP_MEM_SIZE = 3 * 2048 * 1024 / 4 // mirror 2MB in 32-bit words * 3
|
||||||
|
};
|
||||||
|
|
||||||
|
static PGXP_value* Mem = nullptr;
|
||||||
|
|
||||||
|
const unsigned int mode_init = 0;
|
||||||
|
const unsigned int mode_write = 1;
|
||||||
|
const unsigned int mode_read = 2;
|
||||||
|
const unsigned int mode_fail = 3;
|
||||||
|
|
||||||
|
unsigned int baseID = 0;
|
||||||
|
unsigned int lastID = 0;
|
||||||
|
unsigned int cacheMode = 0;
|
||||||
|
static PGXP_value* vertexCache = nullptr;
|
||||||
|
|
||||||
void PGXP_CacheVertex(short sx, short sy, const PGXP_value* _pVertex);
|
void PGXP_CacheVertex(short sx, short sy, const PGXP_value* _pVertex);
|
||||||
|
|
||||||
// pgxp_gte.h
|
// pgxp_gte.h
|
||||||
|
@ -195,7 +215,6 @@ double f16Overflow(double in)
|
||||||
|
|
||||||
// pgxp_mem.c
|
// pgxp_mem.c
|
||||||
static void PGXP_InitMem();
|
static void PGXP_InitMem();
|
||||||
static PGXP_value Mem[3 * 2048 * 1024 / 4]; // mirror 2MB in 32-bit words * 3
|
|
||||||
static const u32 UserMemOffset = 0;
|
static const u32 UserMemOffset = 0;
|
||||||
static const u32 ScratchOffset = 2048 * 1024 / 4;
|
static const u32 ScratchOffset = 2048 * 1024 / 4;
|
||||||
static const u32 RegisterOffset = 2 * 2048 * 1024 / 4;
|
static const u32 RegisterOffset = 2 * 2048 * 1024 / 4;
|
||||||
|
@ -203,7 +222,19 @@ static const u32 InvalidAddress = 3 * 2048 * 1024 / 4;
|
||||||
|
|
||||||
void PGXP_InitMem()
|
void PGXP_InitMem()
|
||||||
{
|
{
|
||||||
memset(Mem, 0, sizeof(Mem));
|
if (!Mem)
|
||||||
|
{
|
||||||
|
Mem = static_cast<PGXP_value*>(std::calloc(PGXP_MEM_SIZE, sizeof(PGXP_value)));
|
||||||
|
if (!Mem)
|
||||||
|
{
|
||||||
|
std::fprintf(stderr, "Failed to allocate PGXP memory\n");
|
||||||
|
std::abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::memset(Mem, 0, sizeof(PGXP_value) * PGXP_MEM_SIZE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 PGXP_ConvertAddress(u32 addr)
|
u32 PGXP_ConvertAddress(u32 addr)
|
||||||
|
@ -366,8 +397,6 @@ void WriteMem16(PGXP_value* src, u32 addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// pgxp_main.c
|
// pgxp_main.c
|
||||||
u32 static gMode = 0;
|
|
||||||
|
|
||||||
void Initialize()
|
void Initialize()
|
||||||
{
|
{
|
||||||
PGXP_InitMem();
|
PGXP_InitMem();
|
||||||
|
@ -375,24 +404,19 @@ void Initialize()
|
||||||
PGXP_InitGTE();
|
PGXP_InitGTE();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PGXP_SetModes(u32 modes)
|
void Shutdown()
|
||||||
{
|
{
|
||||||
gMode = modes;
|
cacheMode = mode_init;
|
||||||
}
|
if (vertexCache)
|
||||||
|
{
|
||||||
u32 PGXP_GetModes()
|
std::free(vertexCache);
|
||||||
{
|
vertexCache = nullptr;
|
||||||
return gMode;
|
}
|
||||||
}
|
if (Mem)
|
||||||
|
{
|
||||||
void PGXP_EnableModes(u32 modes)
|
std::free(Mem);
|
||||||
{
|
Mem = nullptr;
|
||||||
gMode |= modes;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void PGXP_DisableModes(u32 modes)
|
|
||||||
{
|
|
||||||
gMode = gMode & ~modes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// pgxp_gte.c
|
// pgxp_gte.c
|
||||||
|
@ -584,17 +608,6 @@ void CPU_SWC2(u32 instr, u32 rtVal, u32 addr)
|
||||||
/////////////////////////////////
|
/////////////////////////////////
|
||||||
//// Blade_Arma's Vertex Cache (CatBlade?)
|
//// Blade_Arma's Vertex Cache (CatBlade?)
|
||||||
/////////////////////////////////
|
/////////////////////////////////
|
||||||
const unsigned int mode_init = 0;
|
|
||||||
const unsigned int mode_write = 1;
|
|
||||||
const unsigned int mode_read = 2;
|
|
||||||
const unsigned int mode_fail = 3;
|
|
||||||
|
|
||||||
PGXP_value vertexCache[0x800 * 2][0x800 * 2];
|
|
||||||
|
|
||||||
unsigned int baseID = 0;
|
|
||||||
unsigned int lastID = 0;
|
|
||||||
unsigned int cacheMode = 0;
|
|
||||||
|
|
||||||
unsigned int IsSessionID(unsigned int vertID)
|
unsigned int IsSessionID(unsigned int vertID)
|
||||||
{
|
{
|
||||||
// No wrapping
|
// No wrapping
|
||||||
|
@ -612,6 +625,23 @@ unsigned int IsSessionID(unsigned int vertID)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void InitPGXPVertexCache()
|
||||||
|
{
|
||||||
|
if (!vertexCache)
|
||||||
|
{
|
||||||
|
vertexCache = static_cast<PGXP_value*>(std::calloc(VERTEX_CACHE_SIZE, sizeof(PGXP_value)));
|
||||||
|
if (!vertexCache)
|
||||||
|
{
|
||||||
|
std::fprintf(stderr, "Failed to allocate PGXP vertex cache memory\n");
|
||||||
|
std::abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memset(vertexCache, 0x00, VERTEX_CACHE_SIZE * sizeof(PGXP_value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PGXP_CacheVertex(short sx, short sy, const PGXP_value* _pVertex)
|
void PGXP_CacheVertex(short sx, short sy, const PGXP_value* _pVertex)
|
||||||
{
|
{
|
||||||
const PGXP_value* pNewVertex = (const PGXP_value*)_pVertex;
|
const PGXP_value* pNewVertex = (const PGXP_value*)_pVertex;
|
||||||
|
@ -623,14 +653,14 @@ void PGXP_CacheVertex(short sx, short sy, const PGXP_value* _pVertex)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initialise cache on first use
|
||||||
|
if (!vertexCache)
|
||||||
|
InitPGXPVertexCache();
|
||||||
|
|
||||||
// if (bGteAccuracy)
|
// if (bGteAccuracy)
|
||||||
{
|
{
|
||||||
if (cacheMode != mode_write)
|
if (cacheMode != mode_write)
|
||||||
{
|
{
|
||||||
// Initialise cache on first use
|
|
||||||
if (cacheMode == mode_init)
|
|
||||||
memset(vertexCache, 0x00, sizeof(vertexCache));
|
|
||||||
|
|
||||||
// First vertex of write session (frame?)
|
// First vertex of write session (frame?)
|
||||||
cacheMode = mode_write;
|
cacheMode = mode_write;
|
||||||
baseID = pNewVertex->count;
|
baseID = pNewVertex->count;
|
||||||
|
@ -640,7 +670,7 @@ void PGXP_CacheVertex(short sx, short sy, const PGXP_value* _pVertex)
|
||||||
|
|
||||||
if (sx >= -0x800 && sx <= 0x7ff && sy >= -0x800 && sy <= 0x7ff)
|
if (sx >= -0x800 && sx <= 0x7ff && sy >= -0x800 && sy <= 0x7ff)
|
||||||
{
|
{
|
||||||
pOldVertex = &vertexCache[sy + 0x800][sx + 0x800];
|
pOldVertex = &vertexCache[(sy + 0x800) * VERTEX_CACHE_WIDTH + (sx + 0x800)];
|
||||||
|
|
||||||
// To avoid ambiguity there can only be one valid entry per-session
|
// To avoid ambiguity there can only be one valid entry per-session
|
||||||
if (0) //(IsSessionID(pOldVertex->count) && (pOldVertex->value == pNewVertex->value))
|
if (0) //(IsSessionID(pOldVertex->count) && (pOldVertex->value == pNewVertex->value))
|
||||||
|
@ -664,25 +694,25 @@ void PGXP_CacheVertex(short sx, short sy, const PGXP_value* _pVertex)
|
||||||
|
|
||||||
PGXP_value* PGXP_GetCachedVertex(short sx, short sy)
|
PGXP_value* PGXP_GetCachedVertex(short sx, short sy)
|
||||||
{
|
{
|
||||||
// if (bGteAccuracy)
|
if (g_settings.gpu_pgxp_vertex_cache)
|
||||||
{
|
{
|
||||||
if (cacheMode != mode_read)
|
if (cacheMode != mode_read)
|
||||||
{
|
{
|
||||||
if (cacheMode == mode_fail)
|
if (cacheMode == mode_fail)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
// Initialise cache on first use
|
|
||||||
if (cacheMode == mode_init)
|
|
||||||
memset(vertexCache, 0x00, sizeof(vertexCache));
|
|
||||||
|
|
||||||
// First vertex of read session (frame?)
|
// First vertex of read session (frame?)
|
||||||
cacheMode = mode_read;
|
cacheMode = mode_read;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initialise cache on first use
|
||||||
|
if (!vertexCache)
|
||||||
|
InitPGXPVertexCache();
|
||||||
|
|
||||||
if (sx >= -0x800 && sx <= 0x7ff && sy >= -0x800 && sy <= 0x7ff)
|
if (sx >= -0x800 && sx <= 0x7ff && sy >= -0x800 && sy <= 0x7ff)
|
||||||
{
|
{
|
||||||
// Return pointer to cache entry
|
// Return pointer to cache entry
|
||||||
return &vertexCache[sy + 0x800][sx + 0x800];
|
return &vertexCache[(sy + 0x800) * VERTEX_CACHE_WIDTH + (sx + 0x800)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
namespace PGXP {
|
namespace PGXP {
|
||||||
|
|
||||||
void Initialize();
|
void Initialize();
|
||||||
|
void Shutdown();
|
||||||
|
|
||||||
// -- GTE functions
|
// -- GTE functions
|
||||||
// Transforms
|
// Transforms
|
||||||
|
|
|
@ -1411,6 +1411,8 @@ void CommonHostInterface::RegisterGraphicsHotkeys()
|
||||||
|
|
||||||
if (g_settings.gpu_pgxp_enable)
|
if (g_settings.gpu_pgxp_enable)
|
||||||
PGXP::Initialize();
|
PGXP::Initialize();
|
||||||
|
else
|
||||||
|
PGXP::Shutdown();
|
||||||
|
|
||||||
// we need to recompile all blocks if pgxp is toggled on/off
|
// we need to recompile all blocks if pgxp is toggled on/off
|
||||||
if (g_settings.IsUsingCodeCache())
|
if (g_settings.IsUsingCodeCache())
|
||||||
|
|
Loading…
Reference in New Issue