Move alpha pretest to BPMemory.h and rename a bunch of alpha testing related stuff

This commit is contained in:
NeoBrainX 2013-01-08 17:18:45 +01:00
parent c80f6e8b84
commit d26bcb0847
9 changed files with 68 additions and 72 deletions

View File

@ -151,3 +151,38 @@ void GetBPRegInfo(const u8* data, char* name, size_t name_size, char* desc, size
#undef SET_REG_NAME #undef SET_REG_NAME
} }
} }
AlphaTest::TEST_RESULT AlphaTest::TestResult()
{
switch(logic)
{
case 0: // AND
if (comp0 == ALPHACMP_ALWAYS && comp1 == ALPHACMP_ALWAYS)
return PASS;
if (comp0 == ALPHACMP_NEVER || comp1 == ALPHACMP_NEVER)
return FAIL;
break;
case 1: // OR
if (comp0 == ALPHACMP_ALWAYS || comp1 == ALPHACMP_ALWAYS)
return PASS;
if (comp0 == ALPHACMP_NEVER && comp1 == ALPHACMP_NEVER)
return FAIL;
break;
case 2: // XOR
if ((comp0 == ALPHACMP_ALWAYS && comp1 == ALPHACMP_NEVER) || (comp0 == ALPHACMP_NEVER && comp1 == ALPHACMP_ALWAYS))
return PASS;
if ((comp0 == ALPHACMP_ALWAYS && comp1 == ALPHACMP_ALWAYS) || (comp0 == ALPHACMP_NEVER && comp1 == ALPHACMP_NEVER))
return FAIL;
break;
case 3: // XNOR
if ((comp0 == ALPHACMP_ALWAYS && comp1 == ALPHACMP_NEVER) || (comp0 == ALPHACMP_NEVER && comp1 == ALPHACMP_ALWAYS))
return FAIL;
if ((comp0 == ALPHACMP_ALWAYS && comp1 == ALPHACMP_ALWAYS) || (comp0 == ALPHACMP_NEVER && comp1 == ALPHACMP_NEVER))
return PASS;
break;
}
return UNDETERMINED;
}

View File

@ -857,7 +857,7 @@ union TevKSel
int getKA(int i) {return i?kasel1:kasel0;} int getKA(int i) {return i?kasel1:kasel0;}
}; };
union AlphaFunc union AlphaTest
{ {
struct struct
{ {
@ -868,6 +868,15 @@ union AlphaFunc
u32 logic : 2; u32 logic : 2;
}; };
u32 hex; u32 hex;
enum TEST_RESULT
{
UNDETERMINED = 0,
FAIL = 1,
PASS = 2,
};
TEST_RESULT TestResult();
}; };
union UPE_Copy union UPE_Copy
@ -981,7 +990,7 @@ struct BPMemory
TevReg tevregs[4]; //0xE0 TevReg tevregs[4]; //0xE0
FogRangeParams fogRange; FogRangeParams fogRange;
FogParams fog; //0xEE,0xEF,0xF0,0xF1,0xF2 FogParams fog; //0xEE,0xEF,0xF0,0xF1,0xF2
AlphaFunc alphaFunc; //0xF3 AlphaTest alpha_test; //0xF3
ZTex1 ztex1; //0xf4,0xf5 ZTex1 ztex1; //0xf4,0xf5
ZTex2 ztex2; ZTex2 ztex2;
TevKSel tevksel[8];//0xf6,0xf7,f8,f9,fa,fb,fc,fd TevKSel tevksel[8];//0xf6,0xf7,f8,f9,fa,fb,fc,fd

View File

@ -357,9 +357,9 @@ void BPWritten(const BPCmd& bp)
PixelShaderManager::SetFogColorChanged(); PixelShaderManager::SetFogColorChanged();
break; break;
case BPMEM_ALPHACOMPARE: // Compare Alpha Values case BPMEM_ALPHACOMPARE: // Compare Alpha Values
PRIM_LOG("alphacmp: ref0=%d, ref1=%d, comp0=%d, comp1=%d, logic=%d", bpmem.alphaFunc.ref0, PRIM_LOG("alphacmp: ref0=%d, ref1=%d, comp0=%d, comp1=%d, logic=%d", bpmem.alpha_test.ref0,
bpmem.alphaFunc.ref1, bpmem.alphaFunc.comp0, bpmem.alphaFunc.comp1, bpmem.alphaFunc.logic); bpmem.alpha_test.ref1, bpmem.alpha_test.comp0, bpmem.alpha_test.comp1, bpmem.alpha_test.logic);
PixelShaderManager::SetAlpha(bpmem.alphaFunc); PixelShaderManager::SetAlpha(bpmem.alpha_test);
break; break;
case BPMEM_BIAS: // BIAS case BPMEM_BIAS: // BIAS
PRIM_LOG("ztex bias=0x%x", bpmem.ztex1.bias); PRIM_LOG("ztex bias=0x%x", bpmem.ztex1.bias);

View File

@ -28,12 +28,6 @@
#include "NativeVertexFormat.h" #include "NativeVertexFormat.h"
#define ALPHATEST_PASS 2
#define ALPHATEST_FAIL 1
#define ALPHATEST_UNDETERMINED 0
static unsigned int AlphaPreTest();
static void StageHash(int stage, u32* out) static void StageHash(int stage, u32* out)
{ {
out[0] |= bpmem.combiners[stage].colorC.hex & 0xFFFFFF; // 24 out[0] |= bpmem.combiners[stage].colorC.hex & 0xFFFFFF; // 24
@ -119,7 +113,7 @@ void GetPixelShaderId(PIXELSHADERUID *uid, DSTALPHA_MODE dstAlphaMode, u32 compo
if (!enablePL) uid->values[0] |= xfregs.numTexGen.numTexGens << 11; // 4 if (!enablePL) uid->values[0] |= xfregs.numTexGen.numTexGens << 11; // 4
u32 alphaPreTest = AlphaPreTest(); AlphaTest::TEST_RESULT alphaPreTest = bpmem.alpha_test.TestResult();
uid->values[0] |= alphaPreTest << 15; // 2 uid->values[0] |= alphaPreTest << 15; // 2
// numtexgens should be <= 8 // numtexgens should be <= 8
@ -153,11 +147,11 @@ void GetPixelShaderId(PIXELSHADERUID *uid, DSTALPHA_MODE dstAlphaMode, u32 compo
ptr += 4; // max: ptr = &uid->values[66] ptr += 4; // max: ptr = &uid->values[66]
} }
ptr[0] |= bpmem.alphaFunc.comp0; // 3 ptr[0] |= bpmem.alpha_test.comp0; // 3
ptr[0] |= bpmem.alphaFunc.comp1 << 3; // 3 ptr[0] |= bpmem.alpha_test.comp1 << 3; // 3
ptr[0] |= bpmem.alphaFunc.logic << 6; // 2 ptr[0] |= bpmem.alpha_test.logic << 6; // 2
if (alphaPreTest != ALPHATEST_FAIL) if (alphaPreTest != AlphaTest::FAIL)
{ {
ptr[0] |= bpmem.fog.c_proj_fsel.fsel << 8; // 3 ptr[0] |= bpmem.fog.c_proj_fsel.fsel << 8; // 3
ptr[0] |= bpmem.ztex2.op << 11; // 2 ptr[0] |= bpmem.ztex2.op << 11; // 2
@ -227,7 +221,7 @@ void GetSafePixelShaderId(PIXELSHADERUIDSAFE *uid, DSTALPHA_MODE dstAlphaMode, u
ptr = &uid->values[112]; ptr = &uid->values[112];
*ptr++ = bpmem.alphaFunc.hex; // 112 *ptr++ = bpmem.alpha_test.hex; // 112
*ptr++ = bpmem.fog.c_proj_fsel.hex; // 113 *ptr++ = bpmem.fog.c_proj_fsel.hex; // 113
*ptr++ = bpmem.fogRange.Base.hex; // 114 *ptr++ = bpmem.fogRange.Base.hex; // 114
@ -719,8 +713,8 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType
WRITE(p, "prev = frac(prev * (255.0f/256.0f)) * (256.0f/255.0f);\n"); WRITE(p, "prev = frac(prev * (255.0f/256.0f)) * (256.0f/255.0f);\n");
// TODO: ALPHATEST_FAIL should be handled by disabling color writes in the render state // TODO: ALPHATEST_FAIL should be handled by disabling color writes in the render state
int Pretest = AlphaPreTest(); AlphaTest::TEST_RESULT Pretest = bpmem.alpha_test.TestResult();
if (Pretest == ALPHATEST_UNDETERMINED) if (Pretest == AlphaTest::UNDETERMINED)
WriteAlphaTest(p, ApiType, dstAlphaMode); WriteAlphaTest(p, ApiType, dstAlphaMode);
// the screen space depth value = far z + (clip z / clip w) * z range // the screen space depth value = far z + (clip z / clip w) * z range
@ -1149,48 +1143,6 @@ static const char *tevAlphaFunclogicTable[] =
" == " // xnor " == " // xnor
}; };
static unsigned int AlphaPreTest()
{
u32 op = bpmem.alphaFunc.logic;
u32 comp[2] = { bpmem.alphaFunc.comp0, bpmem.alphaFunc.comp1 };
// First kill all the simple cases
switch(op)
{
case 0: // AND
if (comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_ALWAYS)
return ALPHATEST_PASS;
if (comp[0] == ALPHACMP_NEVER || comp[1] == ALPHACMP_NEVER)
return ALPHATEST_FAIL;
break;
case 1: // OR
if (comp[0] == ALPHACMP_ALWAYS || comp[1] == ALPHACMP_ALWAYS)
return ALPHATEST_PASS;
if (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_NEVER)
return ALPHATEST_FAIL;
break;
case 2: // XOR
if ((comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_NEVER) || (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_ALWAYS))
return ALPHATEST_PASS;
if ((comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_ALWAYS) || (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_NEVER))
return ALPHATEST_FAIL;
break;
case 3: // XNOR
if ((comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_NEVER) || (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_ALWAYS))
return ALPHATEST_FAIL;
if ((comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_ALWAYS) || (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_NEVER))
return ALPHATEST_PASS;
break;
default: PanicAlert("bad logic for alpha test? %08x", op);
}
return ALPHATEST_UNDETERMINED;
}
static void WriteAlphaTest(char *&p, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode) static void WriteAlphaTest(char *&p, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode)
{ {
static const char *alphaRef[2] = static const char *alphaRef[2] =
@ -1202,12 +1154,12 @@ static void WriteAlphaTest(char *&p, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode
// using discard then return works the same in cg and dx9 but not in dx11 // using discard then return works the same in cg and dx9 but not in dx11
WRITE(p, "if(!( "); WRITE(p, "if(!( ");
int compindex = bpmem.alphaFunc.comp0 % 8; int compindex = bpmem.alpha_test.comp0;
WRITE(p, tevAlphaFuncsTable[compindex],alphaRef[0]);//lookup the first component from the alpha function table WRITE(p, tevAlphaFuncsTable[compindex],alphaRef[0]);//lookup the first component from the alpha function table
WRITE(p, "%s", tevAlphaFunclogicTable[bpmem.alphaFunc.logic % 4]);//lookup the logic op WRITE(p, "%s", tevAlphaFunclogicTable[bpmem.alpha_test.logic]);//lookup the logic op
compindex = bpmem.alphaFunc.comp1 % 8; compindex = bpmem.alpha_test.comp1;
WRITE(p, tevAlphaFuncsTable[compindex],alphaRef[1]);//lookup the second component from the alpha function table WRITE(p, tevAlphaFuncsTable[compindex],alphaRef[1]);//lookup the second component from the alpha function table
WRITE(p, ")) {\n"); WRITE(p, ")) {\n");

View File

@ -373,7 +373,7 @@ void PixelShaderManager::SetColorChanged(int type, int num, bool high)
PRIM_LOG("pixel %scolor%d: %f %f %f %f\n", type?"k":"", num, pf[0], pf[1], pf[2], pf[3]); PRIM_LOG("pixel %scolor%d: %f %f %f %f\n", type?"k":"", num, pf[0], pf[1], pf[2], pf[3]);
} }
void PixelShaderManager::SetAlpha(const AlphaFunc& alpha) void PixelShaderManager::SetAlpha(const AlphaTest& alpha)
{ {
if ((alpha.hex & 0xffff) != lastAlpha) if ((alpha.hex & 0xffff) != lastAlpha)
{ {

View File

@ -38,7 +38,7 @@ public:
// constant management, should be called after memory is committed // constant management, should be called after memory is committed
static void SetColorChanged(int type, int index, bool high); static void SetColorChanged(int type, int index, bool high);
static void SetAlpha(const AlphaFunc& alpha); static void SetAlpha(const AlphaTest& alpha);
static void SetDestAlpha(const ConstantAlpha& alpha); static void SetDestAlpha(const ConstantAlpha& alpha);
static void SetTexDims(int texmapid, u32 width, u32 height, u32 wraps, u32 wrapt); static void SetTexDims(int texmapid, u32 width, u32 height, u32 wraps, u32 wrapt);
static void SetZTextureBias(u32 bias); static void SetZTextureBias(u32 bias);

View File

@ -202,7 +202,7 @@ void VertexManager::Flush()
} }
PRIM_LOG("pixel: tev=%d, ind=%d, texgen=%d, dstalpha=%d, alphafunc=0x%x", bpmem.genMode.numtevstages+1, bpmem.genMode.numindstages, PRIM_LOG("pixel: tev=%d, ind=%d, texgen=%d, dstalpha=%d, alphafunc=0x%x", bpmem.genMode.numtevstages+1, bpmem.genMode.numindstages,
bpmem.genMode.numtexgens, (u32)bpmem.dstalpha.enable, (bpmem.alphaFunc.hex>>16)&0xff); bpmem.genMode.numtexgens, (u32)bpmem.dstalpha.enable, (bpmem.alpha_test.hex>>16)&0xff);
#endif #endif
u32 usedtextures = 0; u32 usedtextures = 0;

View File

@ -128,8 +128,8 @@ void VertexManager::vFlush()
xfregs.postMtxInfo[i].index, xfregs.postMtxInfo[i].normalize); xfregs.postMtxInfo[i].index, xfregs.postMtxInfo[i].normalize);
} }
PRIM_LOG("pixel: tev=%d, ind=%d, texgen=%d, dstalpha=%d, alphafunc=0x%x", bpmem.genMode.numtevstages+1, bpmem.genMode.numindstages, PRIM_LOG("pixel: tev=%d, ind=%d, texgen=%d, dstalpha=%d, alphatest=0x%x", bpmem.genMode.numtevstages+1, bpmem.genMode.numindstages,
bpmem.genMode.numtexgens, (u32)bpmem.dstalpha.enable, (bpmem.alphaFunc.hex>>16)&0xff); bpmem.genMode.numtexgens, (u32)bpmem.dstalpha.enable, (bpmem.alpha_test.hex>>16)&0xff);
#endif #endif
(void)GL_REPORT_ERROR(); (void)GL_REPORT_ERROR();

View File

@ -433,10 +433,10 @@ static bool AlphaCompare(int alpha, int ref, int comp)
static bool AlphaTest(int alpha) static bool AlphaTest(int alpha)
{ {
bool comp0 = AlphaCompare(alpha, bpmem.alphaFunc.ref0, bpmem.alphaFunc.comp0); bool comp0 = AlphaCompare(alpha, bpmem.alpha_test.ref0, bpmem.alpha_test.comp0);
bool comp1 = AlphaCompare(alpha, bpmem.alphaFunc.ref1, bpmem.alphaFunc.comp1); bool comp1 = AlphaCompare(alpha, bpmem.alpha_test.ref1, bpmem.alpha_test.comp1);
switch (bpmem.alphaFunc.logic) { switch (bpmem.alpha_test.logic) {
case 0: return comp0 && comp1; // and case 0: return comp0 && comp1; // and
case 1: return comp0 || comp1; // or case 1: return comp0 || comp1; // or
case 2: return comp0 ^ comp1; // xor case 2: return comp0 ^ comp1; // xor