mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
softjit: Optimize common case bloom blending.
Bloom often uses fixed ONE + ONE, which is a lot less work for us. And bloom often runs over and over again on pixels, so saving work is good.
This commit is contained in:
parent
6fb5d82fe0
commit
355bad666c
6 changed files with 189 additions and 86 deletions
|
@ -591,47 +591,73 @@ void ComputePixelBlendState(PixelBlendState &state, const PixelFuncID &id) {
|
|||
|
||||
if (state.usesFactors) {
|
||||
switch (id.AlphaBlendSrc()) {
|
||||
case GE_SRCBLEND_DSTALPHA:
|
||||
case GE_SRCBLEND_INVDSTALPHA:
|
||||
case GE_SRCBLEND_DOUBLEDSTALPHA:
|
||||
case GE_SRCBLEND_DOUBLEINVDSTALPHA:
|
||||
case PixelBlendFactor::DSTALPHA:
|
||||
case PixelBlendFactor::INVDSTALPHA:
|
||||
case PixelBlendFactor::DOUBLEDSTALPHA:
|
||||
case PixelBlendFactor::DOUBLEINVDSTALPHA:
|
||||
state.usesDstAlpha = true;
|
||||
break;
|
||||
|
||||
case PixelBlendFactor::OTHERCOLOR:
|
||||
case PixelBlendFactor::INVOTHERCOLOR:
|
||||
state.dstColorAsFactor = true;
|
||||
break;
|
||||
|
||||
case PixelBlendFactor::SRCALPHA:
|
||||
case PixelBlendFactor::INVSRCALPHA:
|
||||
case PixelBlendFactor::DOUBLESRCALPHA:
|
||||
case PixelBlendFactor::DOUBLEINVSRCALPHA:
|
||||
state.srcColorAsFactor = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (id.AlphaBlendDst()) {
|
||||
case GE_DSTBLEND_INVSRCALPHA:
|
||||
state.dstFactorIsInverse = id.AlphaBlendSrc() == GE_SRCBLEND_SRCALPHA;
|
||||
case PixelBlendFactor::INVSRCALPHA:
|
||||
state.dstFactorIsInverse = id.AlphaBlendSrc() == PixelBlendFactor::SRCALPHA;
|
||||
state.srcColorAsFactor = true;
|
||||
break;
|
||||
|
||||
case GE_DSTBLEND_DOUBLEINVSRCALPHA:
|
||||
state.dstFactorIsInverse = id.AlphaBlendSrc() == GE_SRCBLEND_DOUBLESRCALPHA;
|
||||
case PixelBlendFactor::DOUBLEINVSRCALPHA:
|
||||
state.dstFactorIsInverse = id.AlphaBlendSrc() == PixelBlendFactor::DOUBLESRCALPHA;
|
||||
state.srcColorAsFactor = true;
|
||||
break;
|
||||
|
||||
case GE_DSTBLEND_DSTALPHA:
|
||||
case PixelBlendFactor::DSTALPHA:
|
||||
state.usesDstAlpha = true;
|
||||
break;
|
||||
|
||||
case GE_DSTBLEND_INVDSTALPHA:
|
||||
state.dstFactorIsInverse = id.AlphaBlendSrc() == GE_SRCBLEND_DSTALPHA;
|
||||
case PixelBlendFactor::INVDSTALPHA:
|
||||
state.dstFactorIsInverse = id.AlphaBlendSrc() == PixelBlendFactor::DSTALPHA;
|
||||
state.usesDstAlpha = true;
|
||||
break;
|
||||
|
||||
case GE_DSTBLEND_DOUBLEDSTALPHA:
|
||||
case PixelBlendFactor::DOUBLEDSTALPHA:
|
||||
state.usesDstAlpha = true;
|
||||
break;
|
||||
|
||||
case GE_DSTBLEND_DOUBLEINVDSTALPHA:
|
||||
state.dstFactorIsInverse = id.AlphaBlendSrc() == GE_SRCBLEND_DOUBLEDSTALPHA;
|
||||
case PixelBlendFactor::DOUBLEINVDSTALPHA:
|
||||
state.dstFactorIsInverse = id.AlphaBlendSrc() == PixelBlendFactor::DOUBLEDSTALPHA;
|
||||
state.usesDstAlpha = true;
|
||||
break;
|
||||
|
||||
case PixelBlendFactor::OTHERCOLOR:
|
||||
case PixelBlendFactor::INVOTHERCOLOR:
|
||||
state.dstColorAsFactor = true;
|
||||
break;
|
||||
|
||||
case PixelBlendFactor::SRCALPHA:
|
||||
case PixelBlendFactor::DOUBLESRCALPHA:
|
||||
state.srcColorAsFactor = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
state.dstColorAsFactor = state.dstColorAsFactor || state.usesDstAlpha;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -47,6 +47,8 @@ struct PixelBlendState {
|
|||
bool usesFactors = false;
|
||||
bool usesDstAlpha = false;
|
||||
bool dstFactorIsInverse = false;
|
||||
bool srcColorAsFactor = false;
|
||||
bool dstColorAsFactor = false;
|
||||
};
|
||||
void ComputePixelBlendState(PixelBlendState &state, const PixelFuncID &id);
|
||||
|
||||
|
@ -88,7 +90,7 @@ private:
|
|||
bool Jit_DepthTest(const PixelFuncID &id);
|
||||
bool Jit_WriteDepth(const PixelFuncID &id);
|
||||
bool Jit_AlphaBlend(const PixelFuncID &id);
|
||||
bool Jit_BlendFactor(const PixelFuncID &id, RegCache::Reg factorReg, RegCache::Reg dstReg, GEBlendSrcFactor factor);
|
||||
bool Jit_BlendFactor(const PixelFuncID &id, RegCache::Reg factorReg, RegCache::Reg dstReg, PixelBlendFactor factor);
|
||||
bool Jit_DstBlendFactor(const PixelFuncID &id, RegCache::Reg srcFactorReg, RegCache::Reg dstFactorReg, RegCache::Reg dstReg);
|
||||
bool Jit_Dither(const PixelFuncID &id);
|
||||
bool Jit_WriteColor(const PixelFuncID &id);
|
||||
|
|
|
@ -1081,34 +1081,59 @@ bool PixelJitCache::Jit_AlphaBlend(const PixelFuncID &id) {
|
|||
}
|
||||
colorIs16Bit_ = true;
|
||||
|
||||
// Skip multiplying by factors if we can.
|
||||
bool multiplySrc = id.AlphaBlendSrc() != PixelBlendFactor::ZERO && id.AlphaBlendSrc() != PixelBlendFactor::ONE;
|
||||
bool multiplyDst = id.AlphaBlendDst() != PixelBlendFactor::ZERO && id.AlphaBlendDst() != PixelBlendFactor::ONE;
|
||||
// We also shift left by 4, so mulhi gives us a free shift
|
||||
// We also need to add a half bit later, so this gives us space.
|
||||
PSLLW(argColorReg, 4);
|
||||
PSLLW(dstReg, 4);
|
||||
if (multiplySrc || blendState.srcColorAsFactor)
|
||||
PSLLW(argColorReg, 4);
|
||||
if (multiplyDst || blendState.dstColorAsFactor)
|
||||
PSLLW(dstReg, 4);
|
||||
|
||||
// Okay, now grab our factors.
|
||||
success = success && Jit_BlendFactor(id, srcFactorReg, dstReg, id.AlphaBlendSrc());
|
||||
success = success && Jit_DstBlendFactor(id, srcFactorReg, dstFactorReg, dstReg);
|
||||
// Okay, now grab our factors. Don't bother if they're known values.
|
||||
if (id.AlphaBlendSrc() < PixelBlendFactor::ZERO)
|
||||
success = success && Jit_BlendFactor(id, srcFactorReg, dstReg, id.AlphaBlendSrc());
|
||||
if (id.AlphaBlendDst() < PixelBlendFactor::ZERO)
|
||||
success = success && Jit_DstBlendFactor(id, srcFactorReg, dstFactorReg, dstReg);
|
||||
|
||||
X64Reg constReg = GetConstBase();
|
||||
X64Reg halfReg = regCache_.Alloc(RegCache::VEC_TEMP3);
|
||||
// We'll use this several times, so load into a reg.
|
||||
MOVDQA(halfReg, MConstDisp(constReg, &blendHalf_11_4s[0]));
|
||||
regCache_.Unlock(constReg, RegCache::GEN_CONST_BASE);
|
||||
X64Reg halfReg = INVALID_REG;
|
||||
if (multiplySrc || multiplyDst) {
|
||||
X64Reg constReg = GetConstBase();
|
||||
halfReg = regCache_.Alloc(RegCache::VEC_TEMP3);
|
||||
// We'll use this several times, so load into a reg.
|
||||
MOVDQA(halfReg, MConstDisp(constReg, &blendHalf_11_4s[0]));
|
||||
regCache_.Unlock(constReg, RegCache::GEN_CONST_BASE);
|
||||
}
|
||||
|
||||
// Add in the half bit to the factors and color values, then multiply.
|
||||
// We take the high 16 bits to get a free right shift by 16.
|
||||
POR(srcFactorReg, R(halfReg));
|
||||
POR(argColorReg, R(halfReg));
|
||||
PMULHUW(argColorReg, R(srcFactorReg));
|
||||
if (multiplySrc) {
|
||||
POR(srcFactorReg, R(halfReg));
|
||||
POR(argColorReg, R(halfReg));
|
||||
PMULHUW(argColorReg, R(srcFactorReg));
|
||||
} else if (id.AlphaBlendSrc() == PixelBlendFactor::ZERO) {
|
||||
PXOR(argColorReg, R(argColorReg));
|
||||
} else if (id.AlphaBlendSrc() == PixelBlendFactor::ONE) {
|
||||
if (blendState.srcColorAsFactor)
|
||||
PSRLW(argColorReg, 4);
|
||||
}
|
||||
|
||||
POR(dstFactorReg, R(halfReg));
|
||||
POR(dstReg, R(halfReg));
|
||||
PMULHUW(dstReg, R(dstFactorReg));
|
||||
if (multiplyDst) {
|
||||
POR(dstFactorReg, R(halfReg));
|
||||
POR(dstReg, R(halfReg));
|
||||
PMULHUW(dstReg, R(dstFactorReg));
|
||||
} else if (id.AlphaBlendDst() == PixelBlendFactor::ZERO) {
|
||||
PXOR(dstReg, R(dstReg));
|
||||
} else if (id.AlphaBlendDst() == PixelBlendFactor::ONE) {
|
||||
if (blendState.dstColorAsFactor)
|
||||
PSRLW(dstReg, 4);
|
||||
}
|
||||
|
||||
regCache_.Release(srcFactorReg, RegCache::VEC_TEMP1);
|
||||
regCache_.Release(dstFactorReg, RegCache::VEC_TEMP2);
|
||||
regCache_.Release(halfReg, RegCache::VEC_TEMP3);
|
||||
if (halfReg != INVALID_REG)
|
||||
regCache_.Release(halfReg, RegCache::VEC_TEMP3);
|
||||
} else if (colorIs16Bit_) {
|
||||
// If it's expanded, shrink and clamp for our min/max/absdiff handling.
|
||||
PACKUSWB(argColorReg, R(argColorReg));
|
||||
|
@ -1165,7 +1190,7 @@ bool PixelJitCache::Jit_AlphaBlend(const PixelFuncID &id) {
|
|||
}
|
||||
|
||||
|
||||
bool PixelJitCache::Jit_BlendFactor(const PixelFuncID &id, RegCache::Reg factorReg, RegCache::Reg dstReg, GEBlendSrcFactor factor) {
|
||||
bool PixelJitCache::Jit_BlendFactor(const PixelFuncID &id, RegCache::Reg factorReg, RegCache::Reg dstReg, PixelBlendFactor factor) {
|
||||
X64Reg constReg = INVALID_REG;
|
||||
X64Reg gstateReg = INVALID_REG;
|
||||
X64Reg tempReg = INVALID_REG;
|
||||
|
@ -1178,21 +1203,21 @@ bool PixelJitCache::Jit_BlendFactor(const PixelFuncID &id, RegCache::Reg factorR
|
|||
// In those cases, it uses SRCCOLOR, INVSRCCOLOR, and FIXB respectively.
|
||||
|
||||
switch (factor) {
|
||||
case GE_SRCBLEND_DSTCOLOR:
|
||||
case PixelBlendFactor::OTHERCOLOR:
|
||||
MOVDQA(factorReg, R(dstReg));
|
||||
break;
|
||||
|
||||
case GE_SRCBLEND_INVDSTCOLOR:
|
||||
case PixelBlendFactor::INVOTHERCOLOR:
|
||||
constReg = GetConstBase();
|
||||
MOVDQA(factorReg, MConstDisp(constReg, &blendInvert_11_4s[0]));
|
||||
PSUBUSW(factorReg, R(dstReg));
|
||||
break;
|
||||
|
||||
case GE_SRCBLEND_SRCALPHA:
|
||||
case PixelBlendFactor::SRCALPHA:
|
||||
PSHUFLW(factorReg, R(argColorReg), _MM_SHUFFLE(3, 3, 3, 3));
|
||||
break;
|
||||
|
||||
case GE_SRCBLEND_INVSRCALPHA:
|
||||
case PixelBlendFactor::INVSRCALPHA:
|
||||
constReg = GetConstBase();
|
||||
tempReg = regCache_.Alloc(RegCache::VEC_TEMP3);
|
||||
|
||||
|
@ -1201,11 +1226,11 @@ bool PixelJitCache::Jit_BlendFactor(const PixelFuncID &id, RegCache::Reg factorR
|
|||
PSUBUSW(factorReg, R(tempReg));
|
||||
break;
|
||||
|
||||
case GE_SRCBLEND_DSTALPHA:
|
||||
case PixelBlendFactor::DSTALPHA:
|
||||
PSHUFLW(factorReg, R(dstReg), _MM_SHUFFLE(3, 3, 3, 3));
|
||||
break;
|
||||
|
||||
case GE_SRCBLEND_INVDSTALPHA:
|
||||
case PixelBlendFactor::INVDSTALPHA:
|
||||
constReg = GetConstBase();
|
||||
tempReg = regCache_.Alloc(RegCache::VEC_TEMP3);
|
||||
|
||||
|
@ -1214,12 +1239,12 @@ bool PixelJitCache::Jit_BlendFactor(const PixelFuncID &id, RegCache::Reg factorR
|
|||
PSUBUSW(factorReg, R(tempReg));
|
||||
break;
|
||||
|
||||
case GE_SRCBLEND_DOUBLESRCALPHA:
|
||||
case PixelBlendFactor::DOUBLESRCALPHA:
|
||||
PSHUFLW(factorReg, R(argColorReg), _MM_SHUFFLE(3, 3, 3, 3));
|
||||
PSLLW(factorReg, 1);
|
||||
break;
|
||||
|
||||
case GE_SRCBLEND_DOUBLEINVSRCALPHA:
|
||||
case PixelBlendFactor::DOUBLEINVSRCALPHA:
|
||||
constReg = GetConstBase();
|
||||
tempReg = regCache_.Alloc(RegCache::VEC_TEMP3);
|
||||
|
||||
|
@ -1229,12 +1254,12 @@ bool PixelJitCache::Jit_BlendFactor(const PixelFuncID &id, RegCache::Reg factorR
|
|||
PSUBUSW(factorReg, R(tempReg));
|
||||
break;
|
||||
|
||||
case GE_SRCBLEND_DOUBLEDSTALPHA:
|
||||
case PixelBlendFactor::DOUBLEDSTALPHA:
|
||||
PSHUFLW(factorReg, R(dstReg), _MM_SHUFFLE(3, 3, 3, 3));
|
||||
PSLLW(factorReg, 1);
|
||||
break;
|
||||
|
||||
case GE_SRCBLEND_DOUBLEINVDSTALPHA:
|
||||
case PixelBlendFactor::DOUBLEINVDSTALPHA:
|
||||
constReg = GetConstBase();
|
||||
tempReg = regCache_.Alloc(RegCache::VEC_TEMP3);
|
||||
|
||||
|
@ -1244,7 +1269,19 @@ bool PixelJitCache::Jit_BlendFactor(const PixelFuncID &id, RegCache::Reg factorR
|
|||
PSUBUSW(factorReg, R(tempReg));
|
||||
break;
|
||||
|
||||
case GE_SRCBLEND_FIXA:
|
||||
case PixelBlendFactor::ZERO:
|
||||
// Special value meaning zero.
|
||||
PXOR(factorReg, R(factorReg));
|
||||
break;
|
||||
|
||||
case PixelBlendFactor::ONE:
|
||||
// Special value meaning all 255s.
|
||||
PCMPEQD(factorReg, R(factorReg));
|
||||
PSLLW(factorReg, 8);
|
||||
PSRLW(factorReg, 4);
|
||||
break;
|
||||
|
||||
case PixelBlendFactor::FIX:
|
||||
default:
|
||||
gstateReg = GetGState();
|
||||
if (cpu_info.bSSE4_1) {
|
||||
|
@ -1285,37 +1322,39 @@ bool PixelJitCache::Jit_DstBlendFactor(const PixelFuncID &id, RegCache::Reg srcF
|
|||
|
||||
// We might be able to reuse srcFactorReg for dst, in some cases.
|
||||
switch (id.AlphaBlendDst()) {
|
||||
case GE_DSTBLEND_SRCCOLOR:
|
||||
case PixelBlendFactor::OTHERCOLOR:
|
||||
MOVDQA(dstFactorReg, R(argColorReg));
|
||||
break;
|
||||
|
||||
case GE_DSTBLEND_INVSRCCOLOR:
|
||||
case PixelBlendFactor::INVOTHERCOLOR:
|
||||
constReg = GetConstBase();
|
||||
MOVDQA(dstFactorReg, MConstDisp(constReg, &blendInvert_11_4s[0]));
|
||||
PSUBUSW(dstFactorReg, R(argColorReg));
|
||||
break;
|
||||
|
||||
case GE_DSTBLEND_SRCALPHA:
|
||||
case GE_DSTBLEND_INVSRCALPHA:
|
||||
case GE_DSTBLEND_DSTALPHA:
|
||||
case GE_DSTBLEND_INVDSTALPHA:
|
||||
case GE_DSTBLEND_DOUBLESRCALPHA:
|
||||
case GE_DSTBLEND_DOUBLEINVSRCALPHA:
|
||||
case GE_DSTBLEND_DOUBLEDSTALPHA:
|
||||
case GE_DSTBLEND_DOUBLEINVDSTALPHA:
|
||||
case PixelBlendFactor::SRCALPHA:
|
||||
case PixelBlendFactor::INVSRCALPHA:
|
||||
case PixelBlendFactor::DSTALPHA:
|
||||
case PixelBlendFactor::INVDSTALPHA:
|
||||
case PixelBlendFactor::DOUBLESRCALPHA:
|
||||
case PixelBlendFactor::DOUBLEINVSRCALPHA:
|
||||
case PixelBlendFactor::DOUBLEDSTALPHA:
|
||||
case PixelBlendFactor::DOUBLEINVDSTALPHA:
|
||||
case PixelBlendFactor::ZERO:
|
||||
case PixelBlendFactor::ONE:
|
||||
// These are all equivalent for src factor, so reuse that logic.
|
||||
if (id.AlphaBlendSrc() == GEBlendSrcFactor(id.AlphaBlendDst())) {
|
||||
if (id.AlphaBlendSrc() == id.AlphaBlendDst()) {
|
||||
MOVDQA(dstFactorReg, R(srcFactorReg));
|
||||
} else if (blendState.dstFactorIsInverse) {
|
||||
constReg = GetConstBase();
|
||||
MOVDQA(dstFactorReg, MConstDisp(constReg, &blendInvert_11_4s[0]));
|
||||
PSUBUSW(dstFactorReg, R(srcFactorReg));
|
||||
} else {
|
||||
success = success && Jit_BlendFactor(id, dstFactorReg, dstReg, GEBlendSrcFactor(id.AlphaBlendDst()));
|
||||
success = success && Jit_BlendFactor(id, dstFactorReg, dstReg, id.AlphaBlendDst());
|
||||
}
|
||||
break;
|
||||
|
||||
case GE_DSTBLEND_FIXB:
|
||||
case PixelBlendFactor::FIX:
|
||||
default:
|
||||
gstateReg = GetGState();
|
||||
if (cpu_info.bSSE4_1) {
|
||||
|
|
|
@ -42,6 +42,14 @@ static inline GEComparison OptimizeRefByteCompare(GEComparison func, u8 ref) {
|
|||
return func;
|
||||
}
|
||||
|
||||
static inline PixelBlendFactor OptimizeAlphaFactor(uint32_t color) {
|
||||
if (color == 0x00000000)
|
||||
return PixelBlendFactor::ZERO;
|
||||
if (color == 0x00FFFFFF)
|
||||
return PixelBlendFactor::ONE;
|
||||
return PixelBlendFactor::FIX;
|
||||
}
|
||||
|
||||
void ComputePixelFuncID(PixelFuncID *id) {
|
||||
id->fullKey = 0;
|
||||
|
||||
|
@ -143,10 +151,16 @@ void ComputePixelFuncID(PixelFuncID *id) {
|
|||
if (srcFixedOne && dstFixedZero)
|
||||
id->alphaBlend = false;
|
||||
}
|
||||
if (id->alphaBlend) {
|
||||
if (id->alphaBlend)
|
||||
id->alphaBlendEq = gstate.getBlendEq();
|
||||
if (id->alphaBlend && id->alphaBlendEq <= GE_BLENDMODE_MUL_AND_SUBTRACT_REVERSE) {
|
||||
id->alphaBlendSrc = gstate.getBlendFuncA();
|
||||
id->alphaBlendDst = gstate.getBlendFuncB();
|
||||
// Special values.
|
||||
if (id->alphaBlendSrc == GE_SRCBLEND_FIXA)
|
||||
id->alphaBlendSrc = (uint8_t)OptimizeAlphaFactor(gstate.getFixA());
|
||||
if (id->alphaBlendDst == GE_DSTBLEND_FIXB)
|
||||
id->alphaBlendDst = (uint8_t)OptimizeAlphaFactor(gstate.getFixB());
|
||||
}
|
||||
|
||||
id->applyLogicOp = gstate.isLogicOpEnabled() && gstate.getLogicOp() != GE_LOGIC_COPY;
|
||||
|
@ -301,30 +315,34 @@ std::string DescribePixelFuncID(const PixelFuncID &id) {
|
|||
case GE_BLENDMODE_ABSDIFF: desc += "BlendDiff<"; break;
|
||||
}
|
||||
switch (id.AlphaBlendSrc()) {
|
||||
case GE_SRCBLEND_DSTCOLOR: desc += "DstRGB,"; break;
|
||||
case GE_SRCBLEND_INVDSTCOLOR: desc += "1-DstRGB,"; break;
|
||||
case GE_SRCBLEND_SRCALPHA: desc += "SrcA,"; break;
|
||||
case GE_SRCBLEND_INVSRCALPHA: desc += "1-SrcA,"; break;
|
||||
case GE_SRCBLEND_DSTALPHA: desc += "DstA,"; break;
|
||||
case GE_SRCBLEND_INVDSTALPHA: desc += "1-DstA,"; break;
|
||||
case GE_SRCBLEND_DOUBLESRCALPHA: desc += "2*SrcA,"; break;
|
||||
case GE_SRCBLEND_DOUBLEINVSRCALPHA: desc += "1-2*SrcA,"; break;
|
||||
case GE_SRCBLEND_DOUBLEDSTALPHA: desc += "2*DstA,"; break;
|
||||
case GE_SRCBLEND_DOUBLEINVDSTALPHA: desc += "1-2*DstA,"; break;
|
||||
case GE_SRCBLEND_FIXA: desc += "Fix,"; break;
|
||||
case PixelBlendFactor::OTHERCOLOR: desc += "DstRGB,"; break;
|
||||
case PixelBlendFactor::INVOTHERCOLOR: desc += "1-DstRGB,"; break;
|
||||
case PixelBlendFactor::SRCALPHA: desc += "SrcA,"; break;
|
||||
case PixelBlendFactor::INVSRCALPHA: desc += "1-SrcA,"; break;
|
||||
case PixelBlendFactor::DSTALPHA: desc += "DstA,"; break;
|
||||
case PixelBlendFactor::INVDSTALPHA: desc += "1-DstA,"; break;
|
||||
case PixelBlendFactor::DOUBLESRCALPHA: desc += "2*SrcA,"; break;
|
||||
case PixelBlendFactor::DOUBLEINVSRCALPHA: desc += "1-2*SrcA,"; break;
|
||||
case PixelBlendFactor::DOUBLEDSTALPHA: desc += "2*DstA,"; break;
|
||||
case PixelBlendFactor::DOUBLEINVDSTALPHA: desc += "1-2*DstA,"; break;
|
||||
case PixelBlendFactor::FIX: desc += "Fix,"; break;
|
||||
case PixelBlendFactor::ZERO: desc += "0,"; break;
|
||||
case PixelBlendFactor::ONE: desc += "1,"; break;
|
||||
}
|
||||
switch (id.AlphaBlendDst()) {
|
||||
case GE_DSTBLEND_SRCCOLOR: desc += "SrcRGB>:"; break;
|
||||
case GE_DSTBLEND_INVSRCCOLOR: desc += "1-SrcRGB>:"; break;
|
||||
case GE_DSTBLEND_SRCALPHA: desc += "SrcA>:"; break;
|
||||
case GE_DSTBLEND_INVSRCALPHA: desc += "1-SrcA>:"; break;
|
||||
case GE_DSTBLEND_DSTALPHA: desc += "DstA>:"; break;
|
||||
case GE_DSTBLEND_INVDSTALPHA: desc += "1-DstA>:"; break;
|
||||
case GE_DSTBLEND_DOUBLESRCALPHA: desc += "2*SrcA>:"; break;
|
||||
case GE_DSTBLEND_DOUBLEINVSRCALPHA: desc += "1-2*SrcA>:"; break;
|
||||
case GE_DSTBLEND_DOUBLEDSTALPHA: desc += "2*DstA>:"; break;
|
||||
case GE_DSTBLEND_DOUBLEINVDSTALPHA: desc += "1-2*DstA>:"; break;
|
||||
case GE_DSTBLEND_FIXB: desc += "Fix>:"; break;
|
||||
case PixelBlendFactor::OTHERCOLOR: desc += "SrcRGB>:"; break;
|
||||
case PixelBlendFactor::INVOTHERCOLOR: desc += "1-SrcRGB>:"; break;
|
||||
case PixelBlendFactor::SRCALPHA: desc += "SrcA>:"; break;
|
||||
case PixelBlendFactor::INVSRCALPHA: desc += "1-SrcA>:"; break;
|
||||
case PixelBlendFactor::DSTALPHA: desc += "DstA>:"; break;
|
||||
case PixelBlendFactor::INVDSTALPHA: desc += "1-DstA>:"; break;
|
||||
case PixelBlendFactor::DOUBLESRCALPHA: desc += "2*SrcA>:"; break;
|
||||
case PixelBlendFactor::DOUBLEINVSRCALPHA: desc += "1-2*SrcA>:"; break;
|
||||
case PixelBlendFactor::DOUBLEDSTALPHA: desc += "2*DstA>:"; break;
|
||||
case PixelBlendFactor::DOUBLEINVDSTALPHA: desc += "1-2*DstA>:"; break;
|
||||
case PixelBlendFactor::FIX: desc += "Fix>:"; break;
|
||||
case PixelBlendFactor::ZERO: desc += "0>:"; break;
|
||||
case PixelBlendFactor::ONE: desc += "1>:"; break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,24 @@
|
|||
|
||||
#define SOFTPIXEL_USE_CACHE 1
|
||||
|
||||
// 0-10 match GEBlendSrcFactor/GEBlendDstFactor.
|
||||
enum class PixelBlendFactor {
|
||||
OTHERCOLOR,
|
||||
INVOTHERCOLOR,
|
||||
SRCALPHA,
|
||||
INVSRCALPHA,
|
||||
DSTALPHA,
|
||||
INVDSTALPHA,
|
||||
DOUBLESRCALPHA,
|
||||
DOUBLEINVSRCALPHA,
|
||||
DOUBLEDSTALPHA,
|
||||
DOUBLEINVDSTALPHA,
|
||||
FIX,
|
||||
// These are invented, but common FIX values.
|
||||
ZERO,
|
||||
ONE,
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
struct PixelFuncID {
|
||||
|
@ -110,11 +128,11 @@ struct PixelFuncID {
|
|||
GEBlendMode AlphaBlendEq() const {
|
||||
return GEBlendMode(alphaBlendEq);
|
||||
}
|
||||
GEBlendSrcFactor AlphaBlendSrc() const {
|
||||
return GEBlendSrcFactor(alphaBlendSrc);
|
||||
PixelBlendFactor AlphaBlendSrc() const {
|
||||
return PixelBlendFactor(alphaBlendSrc);
|
||||
}
|
||||
GEBlendDstFactor AlphaBlendDst() const {
|
||||
return GEBlendDstFactor(alphaBlendDst);
|
||||
PixelBlendFactor AlphaBlendDst() const {
|
||||
return PixelBlendFactor(alphaBlendDst);
|
||||
}
|
||||
|
||||
GEStencilOp SFail() const {
|
||||
|
|
|
@ -379,8 +379,8 @@ static inline Vec3<int> GetDestFactor(GEBlendDstFactor factor, const Vec4<int> &
|
|||
Vec3<int> AlphaBlendingResult(const PixelFuncID &pixelID, const Vec4<int> &source, const Vec4<int> &dst)
|
||||
{
|
||||
// Note: These factors cannot go below 0, but they can go above 255 when doubling.
|
||||
Vec3<int> srcfactor = GetSourceFactor(pixelID.AlphaBlendSrc(), source, dst);
|
||||
Vec3<int> dstfactor = GetDestFactor(pixelID.AlphaBlendDst(), source, dst);
|
||||
Vec3<int> srcfactor = GetSourceFactor(GEBlendSrcFactor(pixelID.AlphaBlendSrc()), source, dst);
|
||||
Vec3<int> dstfactor = GetDestFactor(GEBlendDstFactor(pixelID.AlphaBlendDst()), source, dst);
|
||||
|
||||
switch (pixelID.AlphaBlendEq()) {
|
||||
case GE_BLENDMODE_MUL_AND_ADD:
|
||||
|
|
Loading…
Add table
Reference in a new issue