mirror of https://github.com/PCSX2/pcsx2.git
microVU: changed VU1's cached program amount from 32 to 64, and vu0's from 32 to 8.
speeds up some games that use a lot of microprograms at once (like ffxii) git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1429 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
d9c40a7ccd
commit
d4132141d5
|
@ -37,7 +37,9 @@ declareAllVariables // Declares All Global Variables :D
|
||||||
// Only run this once per VU! ;)
|
// Only run this once per VU! ;)
|
||||||
microVUt(void) mVUinit(VURegs* vuRegsPtr, int vuIndex) {
|
microVUt(void) mVUinit(VURegs* vuRegsPtr, int vuIndex) {
|
||||||
|
|
||||||
microVU* mVU = mVUx;
|
microVU* mVU = mVUx;
|
||||||
|
memset(&mVU->prog, 0, sizeof(mVU->prog));
|
||||||
|
|
||||||
mVU->regs = vuRegsPtr;
|
mVU->regs = vuRegsPtr;
|
||||||
mVU->index = vuIndex;
|
mVU->index = vuIndex;
|
||||||
mVU->vuMemSize = (vuIndex ? 0x4000 : 0x1000);
|
mVU->vuMemSize = (vuIndex ? 0x4000 : 0x1000);
|
||||||
|
@ -45,7 +47,7 @@ microVUt(void) mVUinit(VURegs* vuRegsPtr, int vuIndex) {
|
||||||
mVU->progSize = (vuIndex ? 0x4000 : 0x1000) / 4;
|
mVU->progSize = (vuIndex ? 0x4000 : 0x1000) / 4;
|
||||||
mVU->cache = NULL;
|
mVU->cache = NULL;
|
||||||
mVU->cacheSize = mVUcacheSize;
|
mVU->cacheSize = mVUcacheSize;
|
||||||
memset(&mVU->prog, 0, sizeof(mVU->prog));
|
mVU->prog.max = mMaxProg - 1;
|
||||||
mVUprint((vuIndex) ? "microVU1: init" : "microVU0: init");
|
mVUprint((vuIndex) ? "microVU1: init" : "microVU0: init");
|
||||||
|
|
||||||
mVU->cache = SysMmapEx((vuIndex ? 0x5f240000 : 0x5e240000), mVU->cacheSize + 0x1000, 0, (vuIndex ? "Micro VU1" : "Micro VU0"));
|
mVU->cache = SysMmapEx((vuIndex ? 0x5f240000 : 0x5e240000), mVU->cacheSize + 0x1000, 0, (vuIndex ? "Micro VU1" : "Micro VU0"));
|
||||||
|
@ -59,13 +61,7 @@ microVUt(void) mVUinit(VURegs* vuRegsPtr, int vuIndex) {
|
||||||
microVUt(void) mVUreset(mV) {
|
microVUt(void) mVUreset(mV) {
|
||||||
|
|
||||||
mVUprint((mVU->index) ? "microVU1: reset" : "microVU0: reset");
|
mVUprint((mVU->index) ? "microVU1: reset" : "microVU0: reset");
|
||||||
|
mVUclose(mVU, 1);
|
||||||
// Delete Block Managers
|
|
||||||
for (int i = 0; i <= mVU->prog.max; i++) {
|
|
||||||
for (u32 j = 0; j < (mVU->progSize / 2); j++) {
|
|
||||||
microBlockManager::Delete( mVU->prog.prog[i].block[j] );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dynarec Cache
|
// Dynarec Cache
|
||||||
memset(mVU->cache, 0xcc, mVU->cacheSize + 0x1000);
|
memset(mVU->cache, 0xcc, mVU->cacheSize + 0x1000);
|
||||||
|
@ -77,14 +73,15 @@ microVUt(void) mVUreset(mV) {
|
||||||
|
|
||||||
// Clear All Program Data
|
// Clear All Program Data
|
||||||
memset(&mVU->prog, 0, sizeof(mVU->prog));
|
memset(&mVU->prog, 0, sizeof(mVU->prog));
|
||||||
|
memset(&mVU->prog.lpState, 0, sizeof(mVU->prog.lpState));
|
||||||
|
|
||||||
// Program Variables
|
// Program Variables
|
||||||
mVU->prog.isSame = -1;
|
mVU->prog.cleared = 1;
|
||||||
mVU->prog.cleared = 1;
|
mVU->prog.isSame = -1;
|
||||||
mVU->prog.cur = -1;
|
mVU->prog.cur = -1;
|
||||||
mVU->prog.total = -1;
|
mVU->prog.total = -1;
|
||||||
memset(&mVU->prog.lpState, 0, sizeof(mVU->prog.lpState));
|
mVU->prog.max = mMaxProg - 1;
|
||||||
//mVU->prog.lpState = &mVU->prog.prog[15].allocInfo.block.pState; // Blank Pipeline State (ToDo: finish implementation)
|
mVU->prog.prog = (microProgram*)_aligned_malloc(sizeof(microProgram)*(mVU->prog.max+1), 64);
|
||||||
|
|
||||||
// Setup Dynarec Cache Limits for Each Program
|
// Setup Dynarec Cache Limits for Each Program
|
||||||
u8* z = (mVU->cache + 0x1000); // Dispatcher Code is in first page of cache
|
u8* z = (mVU->cache + 0x1000); // Dispatcher Code is in first page of cache
|
||||||
|
@ -99,19 +96,20 @@ microVUt(void) mVUreset(mV) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Free Allocated Resources
|
// Free Allocated Resources
|
||||||
microVUt(void) mVUclose(mV) {
|
microVUt(void) mVUclose(mV, bool isReset) {
|
||||||
|
|
||||||
mVUprint((mVU->index) ? "microVU1: close" : "microVU0: close");
|
mVUprint((mVU->index) ? "microVU1: close" : "microVU0: close");
|
||||||
|
|
||||||
if (mVU->cache) { HostSys::Munmap(mVU->cache, mVU->cacheSize); mVU->cache = NULL; }
|
if (!isReset && mVU->cache) { HostSys::Munmap(mVU->cache, mVU->cacheSize); mVU->cache = NULL; }
|
||||||
|
|
||||||
// Delete Block Managers
|
// Delete Programs and Block Managers
|
||||||
for (int i = 0; i <= mVU->prog.max; i++) {
|
if (mVU->prog.prog) {
|
||||||
for (u32 j = 0; j < (mVU->progSize / 2); j++) {
|
for (int i = 0; i <= mVU->prog.max; i++) {
|
||||||
if (mVU->prog.prog[i].block[j]) {
|
for (u32 j = 0; j < (mVU->progSize / 2); j++) {
|
||||||
microBlockManager::Delete( mVU->prog.prog[i].block[j] );
|
microBlockManager::Delete(mVU->prog.prog[i].block[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!isReset) { _aligned_free(mVU->prog.prog); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,7 +250,7 @@ microVUf(int) mVUsearchProg() {
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
|
|
||||||
void initVUrec (VURegs* vuRegs, const int vuIndex) { mVUinit(vuRegs, vuIndex); }
|
void initVUrec (VURegs* vuRegs, const int vuIndex) { mVUinit(vuRegs, vuIndex); }
|
||||||
void closeVUrec(const int vuIndex) { mVUclose(mVUx); }
|
void closeVUrec(const int vuIndex) { mVUclose(mVUx, 0); }
|
||||||
void resetVUrec(const int vuIndex) { mVUreset(mVUx); }
|
void resetVUrec(const int vuIndex) { mVUreset(mVUx); }
|
||||||
void vsyncVUrec(const int vuIndex) { mVUvsyncUpdate(mVUx); }
|
void vsyncVUrec(const int vuIndex) { mVUvsyncUpdate(mVUx); }
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ public:
|
||||||
static void Delete(microBlockManager* dead) {
|
static void Delete(microBlockManager* dead) {
|
||||||
if (dead == NULL) return;
|
if (dead == NULL) return;
|
||||||
dead->~microBlockManager();
|
dead->~microBlockManager();
|
||||||
_aligned_free( dead );
|
_aligned_free(dead);
|
||||||
}
|
}
|
||||||
|
|
||||||
microBlockManager() { reset(); }
|
microBlockManager() { reset(); }
|
||||||
|
@ -84,11 +84,11 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<u32 progSize> // progSize = VU program memory size / 4
|
#define mProgSize 0x4000/4
|
||||||
struct microProgram {
|
struct microProgram {
|
||||||
PCSX2_ALIGNED16(u32 data[progSize]);
|
u32 data [mProgSize];
|
||||||
microBlockManager* block[progSize/2];
|
microBlockManager* block[mProgSize/2];
|
||||||
microIR<progSize> allocInfo;
|
microIR<mProgSize> allocInfo;
|
||||||
u32 used; // Number of times its been used
|
u32 used; // Number of times its been used
|
||||||
u32 last_used; // Counters # of frames since last use (starts at 3 and counts backwards to 0 for each 30fps vSync)
|
u32 last_used; // Counters # of frames since last use (starts at 3 and counts backwards to 0 for each 30fps vSync)
|
||||||
s32 range[2]; // The range of microMemory that has already been recompiled for the current program
|
s32 range[2]; // The range of microMemory that has already been recompiled for the current program
|
||||||
|
@ -97,16 +97,15 @@ struct microProgram {
|
||||||
u8* x86end; // Limit of program's rec-cache
|
u8* x86end; // Limit of program's rec-cache
|
||||||
};
|
};
|
||||||
|
|
||||||
#define mMaxProg 32 // The amount of Micro Programs Recs will 'remember' (For n = 1, 2, 4, 8, 16, etc...)
|
#define mMaxProg ((mVU->index)?64:8) // The amount of Micro Programs Recs will 'remember' (For n = 1, 2, 4, 8, 16, etc...)
|
||||||
template<u32 pSize> // pSize = VU program memory size / 4
|
|
||||||
struct microProgManager {
|
struct microProgManager {
|
||||||
microProgram<pSize> prog[mMaxProg]; // Store MicroPrograms in memory
|
microProgram* prog; // Store MicroPrograms in memory
|
||||||
static const int max = mMaxProg - 1;
|
int max; // Max Number of MicroPrograms minus 1
|
||||||
int cur; // Index to Current MicroProgram thats running (-1 = uncached)
|
int total; // Total Number of valid MicroPrograms minus 1
|
||||||
int total; // Total Number of valid MicroPrograms minus 1
|
int cur; // Index to Current MicroProgram thats running (-1 = uncached)
|
||||||
int isSame; // Current cached microProgram is Exact Same program as mVU->regs->Micro (-1 = unknown, 0 = No, 1 = Yes)
|
int isSame; // Current cached microProgram is Exact Same program as mVU->regs->Micro (-1 = unknown, 0 = No, 1 = Yes)
|
||||||
int cleared; // Micro Program is Indeterminate so must be searched for (and if no matches are found then recompile a new one)
|
int cleared; // Micro Program is Indeterminate so must be searched for (and if no matches are found then recompile a new one)
|
||||||
microRegInfo lpState; // Pipeline state from where program left off (useful for continuing execution)
|
microRegInfo lpState; // Pipeline state from where program left off (useful for continuing execution)
|
||||||
};
|
};
|
||||||
|
|
||||||
#define mVUcacheSize (0x2000000 / ((vuIndex) ? 1 : 4))
|
#define mVUcacheSize (0x2000000 / ((vuIndex) ? 1 : 4))
|
||||||
|
@ -123,7 +122,7 @@ struct microVU {
|
||||||
u32 progSize; // VU Micro Memory Size (in u32's)
|
u32 progSize; // VU Micro Memory Size (in u32's)
|
||||||
u32 cacheSize; // VU Cache Size
|
u32 cacheSize; // VU Cache Size
|
||||||
|
|
||||||
microProgManager<0x4000/4> prog; // Micro Program Data
|
microProgManager prog; // Micro Program Data
|
||||||
|
|
||||||
FILE* logFile; // Log File Pointer
|
FILE* logFile; // Log File Pointer
|
||||||
VURegs* regs; // VU Regs Struct
|
VURegs* regs; // VU Regs Struct
|
||||||
|
@ -145,17 +144,13 @@ struct microVU {
|
||||||
extern PCSX2_ALIGNED16(microVU microVU0);
|
extern PCSX2_ALIGNED16(microVU microVU0);
|
||||||
extern PCSX2_ALIGNED16(microVU microVU1);
|
extern PCSX2_ALIGNED16(microVU microVU1);
|
||||||
|
|
||||||
// Opcode Tables
|
|
||||||
extern void (*mVU_UPPER_OPCODE[64])( VURegs* VU, s32 info );
|
|
||||||
extern void (*mVU_LOWER_OPCODE[128])( VURegs* VU, s32 info );
|
|
||||||
|
|
||||||
// Debug Helper
|
// Debug Helper
|
||||||
extern int mVUdebugNow;
|
extern int mVUdebugNow;
|
||||||
|
|
||||||
// Main Functions
|
// Main Functions
|
||||||
microVUt(void) mVUinit(VURegs*, int);
|
microVUt(void) mVUinit(VURegs*, int);
|
||||||
microVUt(void) mVUreset(mV);
|
microVUt(void) mVUreset(mV);
|
||||||
microVUt(void) mVUclose(mV);
|
microVUt(void) mVUclose(mV, bool isReset);
|
||||||
microVUt(void) mVUclear(mV, u32, u32);
|
microVUt(void) mVUclear(mV, u32, u32);
|
||||||
microVUt(void*) mVUblockFetch(microVU* mVU, u32 startPC, uptr pState);
|
microVUt(void*) mVUblockFetch(microVU* mVU, u32 startPC, uptr pState);
|
||||||
microVUx(void*) __fastcall mVUcompileJIT(u32 startPC, uptr pState);
|
microVUx(void*) __fastcall mVUcompileJIT(u32 startPC, uptr pState);
|
||||||
|
|
|
@ -143,9 +143,9 @@ microVUt(int) mVUsetFlags(mV, int* xStatus, int* xMac, int* xClip) {
|
||||||
mFLAG.lastWrite = (xM-1) & 3;
|
mFLAG.lastWrite = (xM-1) & 3;
|
||||||
cFLAG.lastWrite = (xC-1) & 3;
|
cFLAG.lastWrite = (xC-1) & 3;
|
||||||
|
|
||||||
if (sFlagCond) { xStatus[xS] = cycles + 4; xS = (xS+1) & 3; }
|
if (sFlagCond) { xStatus[xS] = cycles + 4; xS = (xS+1) & 3; }
|
||||||
if (mFLAG.doFlag) { xMac [xM] = cycles + 4; xM = (xM+1) & 3; }
|
if (mFLAG.doFlag) { xMac [xM] = cycles + 4; xM = (xM+1) & 3; }
|
||||||
if (cFLAG.doFlag) { xClip [xC] = cycles + 4; xC = (xC+1) & 3; }
|
if (cFLAG.doFlag) { xClip [xC] = cycles + 4; xC = (xC+1) & 3; }
|
||||||
|
|
||||||
cycles++;
|
cycles++;
|
||||||
incPC2(2);
|
incPC2(2);
|
||||||
|
|
|
@ -52,12 +52,12 @@ microVUt(void) mVUupdateFlags(mV, int reg, int regT1, int regT2, int xyzw, bool
|
||||||
|
|
||||||
SSE_MOVMSKPS_XMM_to_R32(mReg, regT2); // Move the sign bits of the t1reg
|
SSE_MOVMSKPS_XMM_to_R32(mReg, regT2); // Move the sign bits of the t1reg
|
||||||
|
|
||||||
AND32ItoR(mReg, AND_XYZW); // Grab "Is Signed" bits from the previous calculation
|
AND32ItoR(mReg, AND_XYZW); // Grab "Is Signed" bits from the previous calculation
|
||||||
SHL32ItoR(mReg, 4 + ADD_XYZW);
|
SHL32ItoR(mReg, 4 + ADD_XYZW);
|
||||||
|
|
||||||
//-------------------------Check for Zero flags------------------------------
|
//-------------------------Check for Zero flags------------------------------
|
||||||
|
|
||||||
AND32ItoR(gprT2, AND_XYZW); // Grab "Is Zero" bits from the previous calculation
|
AND32ItoR(gprT2, AND_XYZW); // Grab "Is Zero" bits from the previous calculation
|
||||||
if (mFLAG.doFlag) { SHIFT_XYZW(gprT2); }
|
if (mFLAG.doFlag) { SHIFT_XYZW(gprT2); }
|
||||||
OR32RtoR(mReg, gprT2);
|
OR32RtoR(mReg, gprT2);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue