Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Move alpha pretest to BPMemory.h and rename a bunch of alpha testing …
…related stuff
  • Loading branch information
neobrain committed Jan 8, 2013
1 parent c80f6e8 commit d26bcb0
Show file tree
Hide file tree
Showing 9 changed files with 68 additions and 72 deletions.
35 changes: 35 additions & 0 deletions Source/Core/VideoCommon/Src/BPMemory.cpp
Expand Up @@ -151,3 +151,38 @@ void GetBPRegInfo(const u8* data, char* name, size_t name_size, char* desc, size
#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;
}
13 changes: 11 additions & 2 deletions Source/Core/VideoCommon/Src/BPMemory.h
Expand Up @@ -857,7 +857,7 @@ union TevKSel
int getKA(int i) {return i?kasel1:kasel0;}
};

union AlphaFunc
union AlphaTest
{
struct
{
Expand All @@ -868,6 +868,15 @@ union AlphaFunc
u32 logic : 2;
};
u32 hex;

enum TEST_RESULT
{
UNDETERMINED = 0,
FAIL = 1,
PASS = 2,
};

TEST_RESULT TestResult();
};

union UPE_Copy
Expand Down Expand Up @@ -981,7 +990,7 @@ struct BPMemory
TevReg tevregs[4]; //0xE0
FogRangeParams fogRange;
FogParams fog; //0xEE,0xEF,0xF0,0xF1,0xF2
AlphaFunc alphaFunc; //0xF3
AlphaTest alpha_test; //0xF3
ZTex1 ztex1; //0xf4,0xf5
ZTex2 ztex2;
TevKSel tevksel[8];//0xf6,0xf7,f8,f9,fa,fb,fc,fd
Expand Down
6 changes: 3 additions & 3 deletions Source/Core/VideoCommon/Src/BPStructs.cpp
Expand Up @@ -357,9 +357,9 @@ void BPWritten(const BPCmd& bp)
PixelShaderManager::SetFogColorChanged();
break;
case BPMEM_ALPHACOMPARE: // Compare Alpha Values
PRIM_LOG("alphacmp: ref0=%d, ref1=%d, comp0=%d, comp1=%d, logic=%d", bpmem.alphaFunc.ref0,
bpmem.alphaFunc.ref1, bpmem.alphaFunc.comp0, bpmem.alphaFunc.comp1, bpmem.alphaFunc.logic);
PixelShaderManager::SetAlpha(bpmem.alphaFunc);
PRIM_LOG("alphacmp: ref0=%d, ref1=%d, comp0=%d, comp1=%d, logic=%d", bpmem.alpha_test.ref0,
bpmem.alpha_test.ref1, bpmem.alpha_test.comp0, bpmem.alpha_test.comp1, bpmem.alpha_test.logic);
PixelShaderManager::SetAlpha(bpmem.alpha_test);
break;
case BPMEM_BIAS: // BIAS
PRIM_LOG("ztex bias=0x%x", bpmem.ztex1.bias);
Expand Down
70 changes: 11 additions & 59 deletions Source/Core/VideoCommon/Src/PixelShaderGen.cpp
Expand Up @@ -28,12 +28,6 @@
#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)
{
out[0] |= bpmem.combiners[stage].colorC.hex & 0xFFFFFF; // 24
Expand Down Expand Up @@ -119,7 +113,7 @@ void GetPixelShaderId(PIXELSHADERUID *uid, DSTALPHA_MODE dstAlphaMode, u32 compo

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

// numtexgens should be <= 8
Expand Down Expand Up @@ -153,11 +147,11 @@ void GetPixelShaderId(PIXELSHADERUID *uid, DSTALPHA_MODE dstAlphaMode, u32 compo
ptr += 4; // max: ptr = &uid->values[66]
}

ptr[0] |= bpmem.alphaFunc.comp0; // 3
ptr[0] |= bpmem.alphaFunc.comp1 << 3; // 3
ptr[0] |= bpmem.alphaFunc.logic << 6; // 2
ptr[0] |= bpmem.alpha_test.comp0; // 3
ptr[0] |= bpmem.alpha_test.comp1 << 3; // 3
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.ztex2.op << 11; // 2
Expand Down Expand Up @@ -227,7 +221,7 @@ void GetSafePixelShaderId(PIXELSHADERUIDSAFE *uid, DSTALPHA_MODE dstAlphaMode, u

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.fogRange.Base.hex; // 114
Expand Down Expand Up @@ -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");

// TODO: ALPHATEST_FAIL should be handled by disabling color writes in the render state
int Pretest = AlphaPreTest();
if (Pretest == ALPHATEST_UNDETERMINED)
AlphaTest::TEST_RESULT Pretest = bpmem.alpha_test.TestResult();
if (Pretest == AlphaTest::UNDETERMINED)
WriteAlphaTest(p, ApiType, dstAlphaMode);

// the screen space depth value = far z + (clip z / clip w) * z range
Expand Down Expand Up @@ -1149,48 +1143,6 @@ static const char *tevAlphaFunclogicTable[] =
" == " // 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 const char *alphaRef[2] =
Expand All @@ -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
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, "%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, ")) {\n");

Expand Down
2 changes: 1 addition & 1 deletion Source/Core/VideoCommon/Src/PixelShaderManager.cpp
Expand Up @@ -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]);
}

void PixelShaderManager::SetAlpha(const AlphaFunc& alpha)
void PixelShaderManager::SetAlpha(const AlphaTest& alpha)
{
if ((alpha.hex & 0xffff) != lastAlpha)
{
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/VideoCommon/Src/PixelShaderManager.h
Expand Up @@ -38,7 +38,7 @@ class PixelShaderManager

// constant management, should be called after memory is committed
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 SetTexDims(int texmapid, u32 width, u32 height, u32 wraps, u32 wrapt);
static void SetZTextureBias(u32 bias);
Expand Down
2 changes: 1 addition & 1 deletion Source/Core/VideoCommon/Src/VertexManagerBase.cpp
Expand Up @@ -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,
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

u32 usedtextures = 0;
Expand Down
4 changes: 2 additions & 2 deletions Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp
Expand Up @@ -128,8 +128,8 @@ void VertexManager::vFlush()
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,
bpmem.genMode.numtexgens, (u32)bpmem.dstalpha.enable, (bpmem.alphaFunc.hex>>16)&0xff);
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.alpha_test.hex>>16)&0xff);
#endif

(void)GL_REPORT_ERROR();
Expand Down
6 changes: 3 additions & 3 deletions Source/Plugins/Plugin_VideoSoftware/Src/Tev.cpp
Expand Up @@ -433,10 +433,10 @@ static bool AlphaCompare(int alpha, int ref, int comp)

static bool AlphaTest(int alpha)
{
bool comp0 = AlphaCompare(alpha, bpmem.alphaFunc.ref0, bpmem.alphaFunc.comp0);
bool comp1 = AlphaCompare(alpha, bpmem.alphaFunc.ref1, bpmem.alphaFunc.comp1);
bool comp0 = AlphaCompare(alpha, bpmem.alpha_test.ref0, bpmem.alpha_test.comp0);
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 1: return comp0 || comp1; // or
case 2: return comp0 ^ comp1; // xor
Expand Down

0 comments on commit d26bcb0

Please sign in to comment.