mirror of https://github.com/PCSX2/pcsx2.git
newVif: fixed some bugs with mask/mode modes. i had forgotten that mVUmergeRegs() modifies the source reg's vectors, so data was being corrupted and breaking some games (sse4.1 users didn't have this problem).
This revision correctly fixes .hack GU Rebirth. At this point we don't know any games newVif breaks compared to the old vif code. If you know any please leave a comment. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2447 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
c6b79a4915
commit
fbb95f85e4
|
@ -26,6 +26,18 @@
|
|||
|
||||
static __pagealigned u8 nVifUpkExec[__pagesize*4];
|
||||
|
||||
// Merges xmm vectors without modifying source reg
|
||||
void mergeVectors(int dest, int src, int temp, int xyzw) {
|
||||
if (x86caps.hasStreamingSIMD4Extensions || (xyzw==15)
|
||||
|| (xyzw==12) || (xyzw==11) || (xyzw==8) || (xyzw==3)) {
|
||||
mVUmergeRegs(dest, src, xyzw);
|
||||
}
|
||||
else {
|
||||
SSE_MOVAPS_XMM_to_XMM(temp, src);
|
||||
mVUmergeRegs(dest, temp, xyzw);
|
||||
}
|
||||
}
|
||||
|
||||
// =====================================================================================================
|
||||
// VifUnpackSSE_Base Section
|
||||
// =====================================================================================================
|
||||
|
|
|
@ -26,6 +26,8 @@ using namespace x86Emitter;
|
|||
|
||||
#if newVif
|
||||
|
||||
extern void mergeVectors(int dest, int src, int temp, int xyzw);
|
||||
|
||||
// --------------------------------------------------------------------------------------
|
||||
// VifUnpackSSE_Base
|
||||
// --------------------------------------------------------------------------------------
|
||||
|
|
|
@ -111,28 +111,29 @@ _f void VifUnpackSSE_Dynarec::SetMasks(int cS) const {
|
|||
|
||||
void VifUnpackSSE_Dynarec::doMaskWrite(const xRegisterSSE& regX) const {
|
||||
pxAssumeDev(regX.Id <= 1, "Reg Overflow! XMM2 thru XMM6 are reserved for masking.");
|
||||
int t = regX.Id ? 0 : 1; // Get Temp Reg
|
||||
int cc = aMin(vCL, 3);
|
||||
u32 m0 = (vB.mask >> (cc * 8)) & 0xff;
|
||||
u32 m1 = m0 & 0xaaaa;
|
||||
u32 m1 = m0 & 0xaa;
|
||||
u32 m2 =(~m1>>1) & m0;
|
||||
u32 m3 = (m1>>1) & ~m0;
|
||||
u32 m4 = (m1>>1) & m0;
|
||||
makeMergeMask(m2);
|
||||
makeMergeMask(m3);
|
||||
makeMergeMask(m4);
|
||||
if (doMask&&m4) { xMOVAPS(xmmTemp, ptr[dstIndirect]); } // Load Write Protect
|
||||
if (doMask&&m2) { mVUmergeRegs(regX.Id, xmmRow.Id, m2); } // Merge Row
|
||||
if (doMask&&m3) { mVUmergeRegs(regX.Id, xmmCol0.Id+cc, m3); } // Merge Col
|
||||
if (doMask&&m4) { mVUmergeRegs(regX.Id, xmmTemp.Id, m4); } // Merge Write Protect
|
||||
if (doMask&&m4) { xMOVAPS(xmmTemp, ptr[dstIndirect]); } // Load Write Protect
|
||||
if (doMask&&m2) { mergeVectors(regX.Id, xmmRow.Id, t, m2); } // Merge Row
|
||||
if (doMask&&m3) { mergeVectors(regX.Id, xmmCol0.Id+cc, t, m3); } // Merge Col
|
||||
if (doMask&&m4) { mergeVectors(regX.Id, xmmTemp.Id, t, m4); } // Merge Write Protect
|
||||
if (doMode) {
|
||||
u32 m5 = (~m1>>1) & ~m0;
|
||||
if (!doMask) m5 = 0xf;
|
||||
else makeMergeMask(m5);
|
||||
if (m5 < 0xf) {
|
||||
xPXOR(xmmTemp, xmmTemp);
|
||||
mVUmergeRegs(xmmTemp.Id, xmmRow.Id, m5);
|
||||
mergeVectors(xmmTemp.Id, xmmRow.Id, t, m5);
|
||||
xPADD.D(regX, xmmTemp);
|
||||
if (doMode==2) mVUmergeRegs(xmmRow.Id, regX.Id, m5);
|
||||
if (doMode==2) mergeVectors(xmmRow.Id, regX.Id, t, m5);
|
||||
}
|
||||
else if (m5 == 0xf) {
|
||||
xPADD.D(regX, xmmRow);
|
||||
|
|
|
@ -141,7 +141,8 @@ int nVifUnpack(int idx, u8* data) {
|
|||
}
|
||||
|
||||
if (ret == v.vif->tag.size) { // Full Transfer
|
||||
dVifUnpack(idx, data, size, isFill);
|
||||
if (newVifDynaRec) dVifUnpack(idx, data, size, isFill);
|
||||
else _nVifUnpack(idx, data, size, isFill);
|
||||
vif->tag.size = 0;
|
||||
vif->cmd = 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue