softjit: Optimize typical alpha/depth test.

Messed with SSE4 then realized there's no point, just use SHR.
This commit is contained in:
Unknown W. Brackets committed 2021-11-26 08:21:14 -08:00
1 parent 6644c4225c
commit 3f3e0ea8cf
3 files changed
+40 -24

No files matched your search

+6 -1
View File
@@ -1819,8 +1819,13 @@ void XEmitter::PCMPGTB(X64Reg dest, OpArg arg) {WriteSSEOp(0x66, 0x64, dest, ar
void XEmitter::PCMPGTW(X64Reg dest, OpArg arg) {WriteSSEOp(0x66, 0x65, dest, arg);}
void XEmitter::PCMPGTD(X64Reg dest, OpArg arg) {WriteSSEOp(0x66, 0x66, dest, arg);}
void XEmitter::PEXTRW(X64Reg dest, OpArg arg, u8 subreg) {WriteSSEOp(0x66, 0xC5, dest, arg, 1); Write8(subreg);}
void XEmitter::PEXTRW(X64Reg dest, X64Reg arg, u8 subreg) {WriteSSEOp(0x66, 0xC5, dest, R(arg), 1); Write8(subreg);}
void XEmitter::PINSRW(X64Reg dest, OpArg arg, u8 subreg) {WriteSSEOp(0x66, 0xC4, dest, arg, 1); Write8(subreg);}
void XEmitter::PEXTRB(OpArg dest, X64Reg arg, u8 subreg) {WriteSSE41Op(0x66, 0x3A14, arg, dest, 1); Write8(subreg);}
void XEmitter::PEXTRW(OpArg dest, X64Reg arg, u8 subreg) {WriteSSE41Op(0x66, 0x3A15, arg, dest, 1); Write8(subreg);}
void XEmitter::PEXTRD(OpArg dest, X64Reg arg, u8 subreg) {WriteSSE41Op(0x66, 0x3A16, arg, dest, 1); Write8(subreg);}
void XEmitter::PINSRB(X64Reg dest, OpArg arg, u8 subreg) {WriteSSE41Op(0x66, 0x3A20, dest, arg, 1); Write8(subreg);}
void XEmitter::PINSRD(X64Reg dest, OpArg arg, u8 subreg) {WriteSSE41Op(0x66, 0x3A22, dest, arg, 1); Write8(subreg);}
void XEmitter::PMADDWD(X64Reg dest, OpArg arg) {WriteSSEOp(0x66, 0xF5, dest, arg); }
void XEmitter::PSADBW(X64Reg dest, OpArg arg) {WriteSSEOp(0x66, 0xF6, dest, arg);}
+7 -1
View File
@@ -798,8 +798,14 @@ public:
void PCMPGTW(X64Reg dest, OpArg arg);
void PCMPGTD(X64Reg dest, OpArg arg);
void PEXTRW(X64Reg dest, OpArg arg, u8 subreg);
void PEXTRW(X64Reg dest, X64Reg arg, u8 subreg);
void PINSRW(X64Reg dest, OpArg arg, u8 subreg);
// SSE4 inserts and extracts.
void PEXTRB(OpArg dest, X64Reg arg, u8 subreg);
void PEXTRW(OpArg dest, X64Reg arg, u8 subreg);
void PEXTRD(OpArg dest, X64Reg arg, u8 subreg);
void PINSRB(X64Reg dest, OpArg arg, u8 subreg);
void PINSRD(X64Reg dest, OpArg arg, u8 subreg);
void PMADDWD(X64Reg dest, OpArg arg);
void PSADBW(X64Reg dest, OpArg arg);
+27 -22
View File
@@ -59,6 +59,13 @@ static bool Accessible(const T *t1, const T *t2) {
return diff > -0x7FFFFFE0 && diff < 0x7FFFFFE0;
}
template <typename T>
static OpArg MAccessibleDisp(X64Reg r, const T *tbase, const T *t) {
_assert_(Accessible(tbase, t));
ptrdiff_t diff = (const uint8_t *)t - (const uint8_t *)tbase;
return MDisp(r, (int)diff);
}
template <typename T>
static bool ConstAccessible(const T *t) {
return Accessible((const uint8_t *)&const255_16s[0], (const uint8_t *)t);
@@ -66,9 +73,7 @@ static bool ConstAccessible(const T *t) {
template <typename T>
static OpArg MConstDisp(X64Reg r, const T *t) {
_assert_(ConstAccessible(t));
ptrdiff_t diff = (const uint8_t *)t - (const uint8_t *)&const255_16s[0];
return MDisp(r, (int)diff);
return MAccessibleDisp(r, (const uint8_t *)&const255_16s[0], (const uint8_t *)t);
}
SingleFunc PixelJitCache::CompileSingle(const PixelFuncID &id) {
@@ -155,13 +160,23 @@ PixelRegCache::Reg PixelJitCache::GetConstBase() {
PixelRegCache::Reg PixelJitCache::GetColorOff(const PixelFuncID &id) {
if (!regCache_.Has(PixelRegCache::COLOR_OFF, PixelRegCache::T_GEN)) {
if (id.useStandardStride && !id.dithering) {
bool loadDepthOff = id.depthWrite || id.DepthTestFunc() != GE_COMP_ALWAYS;
X64Reg depthTemp = INVALID_REG;
// In this mode, we force argXReg to the off, and throw away argYReg.
SHL(32, R(argYReg), Imm8(9));
ADD(32, R(argXReg), R(argYReg));
// Now add the pointer for the color buffer.
MOV(PTRBITS, R(argYReg), ImmPtr(&fb.data));
MOV(PTRBITS, R(argYReg), MatR(argYReg));
if (loadDepthOff) {
_assert_(Accessible(&fb.data, &depthbuf.data));
depthTemp = regCache_.Alloc(PixelRegCache::DEPTH_OFF, PixelRegCache::T_GEN);
MOV(PTRBITS, R(depthTemp), ImmPtr(&fb.data));
MOV(PTRBITS, R(argYReg), MatR(depthTemp));
} else {
MOV(PTRBITS, R(argYReg), ImmPtr(&fb.data));
MOV(PTRBITS, R(argYReg), MatR(argYReg));
}
LEA(PTRBITS, argYReg, MComplex(argYReg, argXReg, id.FBFormat() == GE_FORMAT_8888 ? 4 : 2, 0));
// With that, argYOff is now COLOR_OFF.
regCache_.Release(argYReg, PixelRegCache::T_GEN, PixelRegCache::COLOR_OFF);
@@ -169,12 +184,10 @@ PixelRegCache::Reg PixelJitCache::GetColorOff(const PixelFuncID &id) {
regCache_.ForceLock(PixelRegCache::COLOR_OFF, PixelRegCache::T_GEN);
// Next, also calculate the depth offset, unless we won't need it at all.
if (id.depthWrite || id.DepthTestFunc() != GE_COMP_ALWAYS) {
X64Reg temp = regCache_.Alloc(PixelRegCache::DEPTH_OFF, PixelRegCache::T_GEN);
MOV(PTRBITS, R(temp), ImmPtr(&depthbuf.data));
MOV(PTRBITS, R(temp), MatR(temp));
LEA(PTRBITS, argXReg, MComplex(temp, argXReg, 2, 0));
regCache_.Release(temp, PixelRegCache::T_GEN);
if (loadDepthOff) {
MOV(PTRBITS, R(depthTemp), MAccessibleDisp(depthTemp, &fb.data, &depthbuf.data));
LEA(PTRBITS, argXReg, MComplex(depthTemp, argXReg, 2, 0));
regCache_.Release(depthTemp, PixelRegCache::T_GEN);
// Okay, same deal - release as DEPTH_OFF and force lock.
regCache_.Release(argXReg, PixelRegCache::T_GEN, PixelRegCache::DEPTH_OFF);
@@ -335,16 +348,8 @@ bool PixelJitCache::Jit_AlphaTest(const PixelFuncID &id) {
alphaReg = regCache_.Find(PixelRegCache::ALPHA, PixelRegCache::T_GEN);
} else {
alphaReg = regCache_.Alloc(PixelRegCache::ALPHA, PixelRegCache::T_GEN);
// TODO: Could do this a bit more cheaply on SSE4.1?
X64Reg zeroReg = regCache_.Alloc(PixelRegCache::TEMP0, PixelRegCache::T_VEC);
X64Reg colorCopyReg = regCache_.Alloc(PixelRegCache::TEMP1, PixelRegCache::T_VEC);
MOVDQA(colorCopyReg, R(argColorReg));
PXOR(zeroReg, R(zeroReg));
PUNPCKLBW(colorCopyReg, R(zeroReg));
PEXTRW(alphaReg, R(colorCopyReg), 3);
regCache_.Release(zeroReg, PixelRegCache::T_VEC);
regCache_.Release(colorCopyReg, PixelRegCache::T_VEC);
MOVD_xmm(R(alphaReg), argColorReg);
SHR(32, R(alphaReg), Imm8(24));
}
if (id.hasAlphaTestMask) {
@@ -487,7 +492,7 @@ bool PixelJitCache::Jit_ApplyFog(const PixelFuncID &id) {
alphaReg = regCache_.Find(PixelRegCache::ALPHA, PixelRegCache::T_GEN);
} else {
alphaReg = regCache_.Alloc(PixelRegCache::ALPHA, PixelRegCache::T_GEN);
PEXTRW(alphaReg, R(argColorReg), 3);
PEXTRW(alphaReg, argColorReg, 3);
}
// Okay, let's broadcast fog to an XMM.