Video software:

Changed the EFB color order from RGBA to ABGR to emulate it correctly on little-endian platforms. Added some enumerations to clear up what components are which colors. Fixed the TEV alpha input LUT which would have caused problems if anything was doing alpha comparisons.
Changed box filter for EFB copies from 3x3 to 2x2 because that is probably correct. Also makes the math nicer.


git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6696 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
donkopunchstania
2010-12-31 06:45:18 +00:00
parent bc3b43d1bd
commit 8a711eadac
11 changed files with 280 additions and 266 deletions
@@ -23,6 +23,7 @@
#include "EfbCopy.h"
#include "Rasterizer.h"
#include "PixelEngine.h"
#include "Tev.h"
#include "../../../Core/VideoCommon/Src/TextureDecoder.h"
@@ -55,7 +56,7 @@ void LoadBPReg(u32 value)
void BPWritten(int address, int newvalue)
{
switch (address)
{
{
case BPMEM_SCISSORTL:
case BPMEM_SCISSORBR:
case BPMEM_SCISSOROFFSET:
@@ -124,8 +125,8 @@ void BPWritten(int address, int newvalue)
ColReg& reg = bpmem.tevregs[regNum].low;
bool konst = reg.type;
Rasterizer::SetTevReg(regNum, 3, konst, reg.b); // A
Rasterizer::SetTevReg(regNum, 0, konst, reg.a); // R
Rasterizer::SetTevReg(regNum, Tev::ALP_C, konst, reg.b); // A
Rasterizer::SetTevReg(regNum, Tev::RED_C, konst, reg.a); // R
break;
}
@@ -139,8 +140,8 @@ void BPWritten(int address, int newvalue)
ColReg& reg = bpmem.tevregs[regNum].high;
bool konst = reg.type;
Rasterizer::SetTevReg(regNum, 1, konst, reg.b); // G
Rasterizer::SetTevReg(regNum, 2, konst, reg.a); // B
Rasterizer::SetTevReg(regNum, Tev::GRN_C, konst, reg.b); // G
Rasterizer::SetTevReg(regNum, Tev::BLU_C, konst, reg.a); // B
break;
}
@@ -143,11 +143,11 @@ void DumpEfb(const char* filename)
for (int y = 0; y < EFB_HEIGHT; y++)
for (int x = 0; x < EFB_WIDTH; x++) {
EfbInterface::GetColor(x, y, sample);
// rgba to bgra
*(writePtr++) = sample[2];
// ABGR to BGRA
*(writePtr++) = sample[1];
*(writePtr++) = sample[0];
*(writePtr++) = sample[2];
*(writePtr++) = sample[3];
*(writePtr++) = sample[0];
}
(void)SaveTGA(filename, EFB_WIDTH, EFB_HEIGHT, data);
@@ -58,7 +58,7 @@ namespace EfbCopy
void ClearEfb()
{
u32 clearColor = (bpmem.clearcolorAR & 0xff) | Common::swap16(bpmem.clearcolorGB) << 8 | (bpmem.clearcolorAR & 0xff00) << 16;
u32 clearColor = (bpmem.clearcolorAR & 0xff) << 24 | bpmem.clearcolorGB << 8 | (bpmem.clearcolorAR & 0xff00) >> 8;
int left = bpmem.copyTexSrcXY.x;
int top = bpmem.copyTexSrcXY.y;
@@ -53,8 +53,8 @@ namespace EfbInterface
{
u32 a32 = a;
u32 *dst = (u32*)&efb[offset];
u32 val = *dst & 0xff03ffff;
val |= (a32 << 16) & 0xfc0000;
u32 val = *dst & 0xffffffc0;
val |= (a32 >> 2) & 0x0000003f;
*dst = val;
}
break;
@@ -73,7 +73,7 @@ namespace EfbInterface
u32 src = *(u32*)rgb;
u32 *dst = (u32*)&efb[offset];
u32 val = *dst & 0xff000000;
val |= src & 0x00ffffff;
val |= src >> 8;
*dst = val;
}
break;
@@ -81,10 +81,10 @@ namespace EfbInterface
{
u32 src = *(u32*)rgb;
u32 *dst = (u32*)&efb[offset];
u32 val = *dst & 0xfffc0000;
val |= (src >> 2) & 0x3f;
val |= (src >> 4) & 0xfc0;
val |= (src >> 6) & 0x3f000;
u32 val = *dst & 0xff00003f;
val |= (src >> 4) & 0x00000fc0; // blue
val |= (src >> 6) & 0x0003f000; // green
val |= (src >> 8) & 0x00fc0000; // red
*dst = val;
}
break;
@@ -94,7 +94,7 @@ namespace EfbInterface
u32 src = *(u32*)rgb;
u32 *dst = (u32*)&efb[offset];
u32 val = *dst & 0xff000000;
val |= src & 0x00ffffff;
val |= src >> 8;
*dst = val;
}
break;
@@ -113,7 +113,7 @@ namespace EfbInterface
u32 src = *(u32*)color;
u32 *dst = (u32*)&efb[offset];
u32 val = *dst & 0xff000000;
val |= src & 0x00ffffff;
val |= src >> 8;
*dst = val;
}
break;
@@ -122,10 +122,10 @@ namespace EfbInterface
u32 src = *(u32*)color;
u32 *dst = (u32*)&efb[offset];
u32 val = *dst & 0xff000000;
val |= (src >> 2) & 0x3f;
val |= (src >> 4) & 0xfc0;
val |= (src >> 6) & 0x3f000;
val |= (src >> 8) & 0xfc0000;
val |= (src >> 2) & 0x0000003f; // alpha
val |= (src >> 4) & 0x00000fc0; // blue
val |= (src >> 6) & 0x0003f000; // green
val |= (src >> 8) & 0x00fc0000; // red
*dst = val;
}
break;
@@ -135,7 +135,7 @@ namespace EfbInterface
u32 src = *(u32*)color;
u32 *dst = (u32*)&efb[offset];
u32 val = *dst & 0xff000000;
val |= src & 0x00ffffff;
val |= src >> 8;
*dst = val;
}
break;
@@ -153,17 +153,17 @@ namespace EfbInterface
{
u32 src = *(u32*)&efb[offset];
u32 *dst = (u32*)color;
u32 val = 0xff000000 | (src & 0x00ffffff);
u32 val = 0xff | ((src & 0x00ffffff) << 8);
*dst = val;
}
break;
case PIXELFMT_RGBA6_Z24:
{
u32 src = *(u32*)&efb[offset];
color[0] = Convert6To8(src & 0x3f);
color[1] = Convert6To8((src >> 6) & 0x3f);
color[2] = Convert6To8((src >> 12) & 0x3f);
color[3] = Convert6To8((src >> 18) & 0x3f);
color[ALP_C] = Convert6To8(src & 0x3f);
color[BLU_C] = Convert6To8((src >> 6) & 0x3f);
color[GRN_C] = Convert6To8((src >> 12) & 0x3f);
color[RED_C] = Convert6To8((src >> 18) & 0x3f);
}
break;
case PIXELFMT_RGB565_Z16:
@@ -171,7 +171,7 @@ namespace EfbInterface
INFO_LOG(VIDEO, "PIXELFMT_RGB565_Z16 is not supported correctly yet");
u32 src = *(u32*)&efb[offset];
u32 *dst = (u32*)color;
u32 val = 0xff000000 | (src & 0x00ffffff);
u32 val = 0xff | ((src & 0x00ffffff) << 8);
*dst = val;
}
break;
@@ -247,25 +247,25 @@ namespace EfbInterface
return 0xffffffff - *(u32*)dstClr;
case 4: // srcalpha
{
u8 alpha = srcClr[3];
u8 alpha = srcClr[ALP_C];
u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
return factor;
}
case 5: // invsrcalpha
{
u8 alpha = 0xff - srcClr[3];
u8 alpha = 0xff - srcClr[ALP_C];
u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
return factor;
}
case 6: // dstalpha
{
u8 alpha = dstClr[3];
u8 alpha = dstClr[ALP_C];
u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
return factor;
}
case 7: // invdstalpha
{
u8 alpha = 0xff - dstClr[3];
u8 alpha = 0xff - dstClr[ALP_C];
u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
return factor;
}
@@ -287,25 +287,25 @@ namespace EfbInterface
return 0xffffffff - *(u32*)srcClr;
case 4: // srcalpha
{
u8 alpha = srcClr[3];
u8 alpha = srcClr[ALP_C];
u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
return factor;
}
case 5: // invsrcalpha
{
u8 alpha = 0xff - srcClr[3];
u8 alpha = 0xff - srcClr[ALP_C];
u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
return factor;
}
case 6: // dstalpha
{
u8 alpha = dstClr[3] & 0xff;
u8 alpha = dstClr[ALP_C] & 0xff;
u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
return factor;
}
case 7: // invdstalpha
{
u8 alpha = 0xff - dstClr[3];
u8 alpha = 0xff - dstClr[ALP_C];
u32 factor = alpha << 24 | alpha << 16 | alpha << 8 | alpha;
return factor;
}
@@ -421,7 +421,7 @@ namespace EfbInterface
dstClrPtr = color;
if (bpmem.dstalpha.enable)
dstClrPtr[3] = bpmem.dstalpha.alpha;
dstClrPtr[ALP_C] = bpmem.dstalpha.alpha;
if (bpmem.blendmode.colorupdate)
{
@@ -431,7 +431,7 @@ namespace EfbInterface
SetPixelColorOnly(offset, dstClrPtr);
}
else if (bpmem.blendmode.alphaupdate)
SetPixelAlphaOnly(offset, dstClrPtr[3]);
SetPixelAlphaOnly(offset, dstClrPtr[ALP_C]);
// branchless bounding box update
PixelEngine::pereg.boxLeft = PixelEngine::pereg.boxLeft>x?x:PixelEngine::pereg.boxLeft;
@@ -451,7 +451,7 @@ namespace EfbInterface
SetPixelColorOnly(offset, color);
}
else if (bpmem.blendmode.alphaupdate)
SetPixelAlphaOnly(offset, color[3]);
SetPixelAlphaOnly(offset, color[ALP_C]);
}
void SetDepth(u16 x, u16 y, u32 depth)
@@ -486,13 +486,13 @@ namespace EfbInterface
u32 textureAddress = 0;
u32 efbOffset = 0;
for (u16 y = 0; y < EFB_HEIGHT; y++)
for (u16 y = 0; y < EFB_HEIGHT; y++)
{
for (u16 x = 0; x < EFB_WIDTH; x++)
{
GetPixelColor(efbOffset, colorPtr);
efbOffset += 3;
texturePtr[textureAddress++] = color;
efbOffset += 3;
texturePtr[textureAddress++] = Common::swap32(color); // ABGR->RGBA
}
}
}
@@ -24,7 +24,9 @@ namespace EfbInterface
{
const int DEPTH_BUFFER_START = EFB_WIDTH * EFB_HEIGHT * 3;
// color order is RGBA
enum { ALP_C, BLU_C, GRN_C, RED_C };
// color order is ABGR in order to emulate RGBA on little-endian hardware
// does full blending of an incoming pixel
void BlendTev(u16 x, u16 y, u8 *color);
@@ -44,7 +46,7 @@ namespace EfbInterface
u8* GetPixelPointer(u16 x, u16 y, bool depth);
void UpdateColorTexture();
extern u8 efbColorTexture[EFB_WIDTH*EFB_HEIGHT*4]; // rgba format
extern u8 efbColorTexture[EFB_WIDTH*EFB_HEIGHT*4]; // RGBA format
}
#endif
@@ -79,7 +79,7 @@ namespace HwRasterizer
void DrawColorVertex(OutputVertexData *v)
{
glColor3ub(v->color[0][0], v->color[0][1], v->color[0][2]);
glColor3ub(v->color[0][OutputVertexData::RED_C], v->color[0][OutputVertexData::GRN_C], v->color[0][OutputVertexData::BLU_C]);
glVertex3f(v->screenPosition.x / efbHalfWidth - 1.0f, 1.0f - v->screenPosition.y / efbHalfHeight, v->screenPosition.z);
}
@@ -49,7 +49,10 @@ struct InputVertexData
struct OutputVertexData
{
Vec3 mvPosition;
// components in color channels
enum { RED_C, GRN_C, BLU_C, ALP_C };
Vec3 mvPosition;
Vec4 projectedPosition;
Vec3 screenPosition;
Vec3 normal[3];
+84 -80
View File
@@ -47,31 +47,31 @@ void Tev::Init()
for (int i = 0; i < 4; i++)
Zero16[i] = 0;
m_ColorInputLUT[0][0] = &Reg[0][RED_C]; m_ColorInputLUT[0][1] = &Reg[0][GRN_C]; m_ColorInputLUT[0][2] = &Reg[0][BLU_C]; // prev.rgb
m_ColorInputLUT[1][0] = &Reg[0][ALP_C]; m_ColorInputLUT[1][1] = &Reg[0][ALP_C]; m_ColorInputLUT[1][2] = &Reg[0][ALP_C]; // prev.aaa
m_ColorInputLUT[2][0] = &Reg[1][RED_C]; m_ColorInputLUT[2][1] = &Reg[1][GRN_C]; m_ColorInputLUT[2][2] = &Reg[1][BLU_C]; // c0.rgb
m_ColorInputLUT[3][0] = &Reg[1][ALP_C]; m_ColorInputLUT[3][1] = &Reg[1][ALP_C]; m_ColorInputLUT[3][2] = &Reg[1][ALP_C]; // c0.aaa
m_ColorInputLUT[4][0] = &Reg[2][RED_C]; m_ColorInputLUT[4][1] = &Reg[2][GRN_C]; m_ColorInputLUT[4][2] = &Reg[2][BLU_C]; // c1.rgb
m_ColorInputLUT[5][0] = &Reg[2][ALP_C]; m_ColorInputLUT[5][1] = &Reg[2][ALP_C]; m_ColorInputLUT[5][2] = &Reg[2][ALP_C]; // c1.aaa
m_ColorInputLUT[6][0] = &Reg[3][RED_C]; m_ColorInputLUT[6][1] = &Reg[3][GRN_C]; m_ColorInputLUT[6][2] = &Reg[3][BLU_C]; // c2.rgb
m_ColorInputLUT[7][0] = &Reg[3][ALP_C]; m_ColorInputLUT[7][1] = &Reg[3][ALP_C]; m_ColorInputLUT[7][2] = &Reg[3][ALP_C]; // c2.aaa
m_ColorInputLUT[8][0] = &TexColor[RED_C]; m_ColorInputLUT[8][1] = &TexColor[GRN_C]; m_ColorInputLUT[8][2] = &TexColor[BLU_C]; // tex.rgb
m_ColorInputLUT[9][0] = &TexColor[ALP_C]; m_ColorInputLUT[9][1] = &TexColor[ALP_C]; m_ColorInputLUT[9][2] = &TexColor[ALP_C]; // tex.aaa
m_ColorInputLUT[10][0] = &RasColor[RED_C]; m_ColorInputLUT[10][1] = &RasColor[GRN_C]; m_ColorInputLUT[10][2] = &RasColor[BLU_C]; // ras.rgb
m_ColorInputLUT[11][0] = &RasColor[ALP_C]; m_ColorInputLUT[11][1] = &RasColor[ALP_C]; m_ColorInputLUT[11][2] = &RasColor[ALP_C]; // ras.rgb
m_ColorInputLUT[12][0] = &FixedConstants[8]; m_ColorInputLUT[12][1] = &FixedConstants[8]; m_ColorInputLUT[12][2] = &FixedConstants[8]; // one
m_ColorInputLUT[13][0] = &FixedConstants[4]; m_ColorInputLUT[13][1] = &FixedConstants[4]; m_ColorInputLUT[13][2] = &FixedConstants[4]; // half
m_ColorInputLUT[14][0] = &StageKonst[0]; m_ColorInputLUT[14][1] = &StageKonst[1]; m_ColorInputLUT[14][2] = &StageKonst[2]; // konst
m_ColorInputLUT[15][0] = &FixedConstants[0]; m_ColorInputLUT[15][1] = &FixedConstants[0]; m_ColorInputLUT[15][2] = &FixedConstants[0]; // zero
m_ColorInputLUT[0][RED_INP] = &Reg[0][RED_C]; m_ColorInputLUT[0][GRN_INP] = &Reg[0][GRN_C]; m_ColorInputLUT[0][BLU_INP] = &Reg[0][BLU_C]; // prev.rgb
m_ColorInputLUT[1][RED_INP] = &Reg[0][ALP_C]; m_ColorInputLUT[1][GRN_INP] = &Reg[0][ALP_C]; m_ColorInputLUT[1][BLU_INP] = &Reg[0][ALP_C]; // prev.aaa
m_ColorInputLUT[2][RED_INP] = &Reg[1][RED_C]; m_ColorInputLUT[2][GRN_INP] = &Reg[1][GRN_C]; m_ColorInputLUT[2][BLU_INP] = &Reg[1][BLU_C]; // c0.rgb
m_ColorInputLUT[3][RED_INP] = &Reg[1][ALP_C]; m_ColorInputLUT[3][GRN_INP] = &Reg[1][ALP_C]; m_ColorInputLUT[3][BLU_INP] = &Reg[1][ALP_C]; // c0.aaa
m_ColorInputLUT[4][RED_INP] = &Reg[2][RED_C]; m_ColorInputLUT[4][GRN_INP] = &Reg[2][GRN_C]; m_ColorInputLUT[4][BLU_INP] = &Reg[2][BLU_C]; // c1.rgb
m_ColorInputLUT[5][RED_INP] = &Reg[2][ALP_C]; m_ColorInputLUT[5][GRN_INP] = &Reg[2][ALP_C]; m_ColorInputLUT[5][BLU_INP] = &Reg[2][ALP_C]; // c1.aaa
m_ColorInputLUT[6][RED_INP] = &Reg[3][RED_C]; m_ColorInputLUT[6][GRN_INP] = &Reg[3][GRN_C]; m_ColorInputLUT[6][BLU_INP] = &Reg[3][BLU_C]; // c2.rgb
m_ColorInputLUT[7][RED_INP] = &Reg[3][ALP_C]; m_ColorInputLUT[7][GRN_INP] = &Reg[3][ALP_C]; m_ColorInputLUT[7][BLU_INP] = &Reg[3][ALP_C]; // c2.aaa
m_ColorInputLUT[8][RED_INP] = &TexColor[RED_C]; m_ColorInputLUT[8][GRN_INP] = &TexColor[GRN_C]; m_ColorInputLUT[8][BLU_INP] = &TexColor[BLU_C]; // tex.rgb
m_ColorInputLUT[9][RED_INP] = &TexColor[ALP_C]; m_ColorInputLUT[9][GRN_INP] = &TexColor[ALP_C]; m_ColorInputLUT[9][BLU_INP] = &TexColor[ALP_C]; // tex.aaa
m_ColorInputLUT[10][RED_INP] = &RasColor[RED_C]; m_ColorInputLUT[10][GRN_INP] = &RasColor[GRN_C]; m_ColorInputLUT[10][BLU_INP] = &RasColor[BLU_C]; // ras.rgb
m_ColorInputLUT[11][RED_INP] = &RasColor[ALP_C]; m_ColorInputLUT[11][GRN_INP] = &RasColor[ALP_C]; m_ColorInputLUT[11][BLU_INP] = &RasColor[ALP_C]; // ras.rgb
m_ColorInputLUT[12][RED_INP] = &FixedConstants[8]; m_ColorInputLUT[12][GRN_INP] = &FixedConstants[8]; m_ColorInputLUT[12][BLU_INP] = &FixedConstants[8]; // one
m_ColorInputLUT[13][RED_INP] = &FixedConstants[4]; m_ColorInputLUT[13][GRN_INP] = &FixedConstants[4]; m_ColorInputLUT[13][BLU_INP] = &FixedConstants[4]; // half
m_ColorInputLUT[14][RED_INP] = &StageKonst[RED_C]; m_ColorInputLUT[14][GRN_INP] = &StageKonst[GRN_C]; m_ColorInputLUT[14][BLU_INP] = &StageKonst[BLU_C]; // konst
m_ColorInputLUT[15][RED_INP] = &FixedConstants[0]; m_ColorInputLUT[15][GRN_INP] = &FixedConstants[0]; m_ColorInputLUT[15][BLU_INP] = &FixedConstants[0]; // zero
m_AlphaInputLUT[0] = &Reg[0][ALP_C]; // prev.a
m_AlphaInputLUT[1] = &Reg[1][ALP_C]; // c0.a
m_AlphaInputLUT[2] = &Reg[2][ALP_C]; // c1.a
m_AlphaInputLUT[3] = &Reg[3][ALP_C]; // c2.a
m_AlphaInputLUT[4] = &TexColor[ALP_C]; // tex.a
m_AlphaInputLUT[5] = &RasColor[ALP_C]; // ras.a
m_AlphaInputLUT[6] = &StageKonst[ALP_C]; // konst.a
m_AlphaInputLUT[7] = &Zero16[ALP_C]; // zero
m_AlphaInputLUT[0] = Reg[0]; // prev
m_AlphaInputLUT[1] = Reg[1]; // c0
m_AlphaInputLUT[2] = Reg[2]; // c1
m_AlphaInputLUT[3] = Reg[3]; // c2
m_AlphaInputLUT[4] = TexColor; // tex
m_AlphaInputLUT[5] = RasColor; // ras
m_AlphaInputLUT[6] = StageKonst; // konst
m_AlphaInputLUT[7] = Zero16; // zero
for (int comp = 0; comp < 4; comp++)
{
@@ -140,21 +140,21 @@ inline void Tev::SetRasColor(int colorChan, int swaptable)
case 0: // Color0
{
u8 *color = Color[0];
RasColor[0] = color[bpmem.tevksel[swaptable].swap1];
RasColor[1] = color[bpmem.tevksel[swaptable].swap2];
RasColor[RED_C] = color[bpmem.tevksel[swaptable].swap1];
RasColor[GRN_C] = color[bpmem.tevksel[swaptable].swap2];
swaptable++;
RasColor[2] = color[bpmem.tevksel[swaptable].swap1];
RasColor[3] = color[bpmem.tevksel[swaptable].swap2];
RasColor[BLU_C] = color[bpmem.tevksel[swaptable].swap1];
RasColor[ALP_C] = color[bpmem.tevksel[swaptable].swap2];
}
break;
case 1: // Color1
{
u8 *color = Color[1];
RasColor[0] = color[bpmem.tevksel[swaptable].swap1];
RasColor[1] = color[bpmem.tevksel[swaptable].swap2];
RasColor[RED_C] = color[bpmem.tevksel[swaptable].swap1];
RasColor[GRN_C] = color[bpmem.tevksel[swaptable].swap2];
swaptable++;
RasColor[2] = color[bpmem.tevksel[swaptable].swap1];
RasColor[3] = color[bpmem.tevksel[swaptable].swap2];
RasColor[BLU_C] = color[bpmem.tevksel[swaptable].swap1];
RasColor[ALP_C] = color[bpmem.tevksel[swaptable].swap2];
}
break;
case 5: // alpha bump
@@ -199,7 +199,7 @@ void Tev::DrawColorRegular(TevStageCombiner::ColorCombiner &cc)
result = result << m_ScaleLShiftLUT[cc.shift];
result = result >> m_ScaleRShiftLUT[cc.shift];
Reg[cc.dest][RED_C + i] = result;
Reg[cc.dest][BLU_C + i] = result;
}
}
@@ -215,74 +215,74 @@ void Tev::DrawColorCompare(TevStageCombiner::ColorCombiner &cc)
switch(cmp) {
case TEVCMP_R8_GT:
{
a = *m_ColorInputLUT[cc.a][RED_C] & 0xff;
b = *m_ColorInputLUT[cc.b][RED_C] & 0xff;
a = *m_ColorInputLUT[cc.a][RED_INP] & 0xff;
b = *m_ColorInputLUT[cc.b][RED_INP] & 0xff;
for (int i = 0; i < 3; i++)
{
InputReg.c = *m_ColorInputLUT[cc.c][i];
InputReg.d = *m_ColorInputLUT[cc.d][i];
Reg[cc.dest][RED_C + i] = InputReg.d + ((a > b) ? InputReg.c : 0);
Reg[cc.dest][BLU_C + i] = InputReg.d + ((a > b) ? InputReg.c : 0);
}
}
break;
case TEVCMP_R8_EQ:
{
a = *m_ColorInputLUT[cc.a][RED_C] & 0xff;
b = *m_ColorInputLUT[cc.b][RED_C] & 0xff;
a = *m_ColorInputLUT[cc.a][RED_INP] & 0xff;
b = *m_ColorInputLUT[cc.b][RED_INP] & 0xff;
for (int i = 0; i < 3; i++)
{
InputReg.c = *m_ColorInputLUT[cc.c][i];
InputReg.d = *m_ColorInputLUT[cc.d][i];
Reg[cc.dest][RED_C + i] = InputReg.d + ((a == b) ? InputReg.c : 0);
Reg[cc.dest][BLU_C + i] = InputReg.d + ((a == b) ? InputReg.c : 0);
}
}
break;
case TEVCMP_GR16_GT:
{
a = ((*m_ColorInputLUT[cc.a][GRN_C] & 0xff) << 8) | (*m_ColorInputLUT[cc.a][RED_C] & 0xff);
b = ((*m_ColorInputLUT[cc.b][GRN_C] & 0xff) << 8) | (*m_ColorInputLUT[cc.b][RED_C] & 0xff);
a = ((*m_ColorInputLUT[cc.a][GRN_INP] & 0xff) << 8) | (*m_ColorInputLUT[cc.a][RED_INP] & 0xff);
b = ((*m_ColorInputLUT[cc.b][GRN_INP] & 0xff) << 8) | (*m_ColorInputLUT[cc.b][RED_INP] & 0xff);
for (int i = 0; i < 3; i++)
{
InputReg.c = *m_ColorInputLUT[cc.c][i];
InputReg.d = *m_ColorInputLUT[cc.d][i];
Reg[cc.dest][RED_C + i] = InputReg.d + ((a > b) ? InputReg.c : 0);
Reg[cc.dest][BLU_C + i] = InputReg.d + ((a > b) ? InputReg.c : 0);
}
}
break;
case TEVCMP_GR16_EQ:
{
a = ((*m_ColorInputLUT[cc.a][GRN_C] & 0xff) << 8) | (*m_ColorInputLUT[cc.a][RED_C] & 0xff);
b = ((*m_ColorInputLUT[cc.b][GRN_C] & 0xff) << 8) | (*m_ColorInputLUT[cc.b][RED_C] & 0xff);
a = ((*m_ColorInputLUT[cc.a][GRN_C] & 0xff) << 8) | (*m_ColorInputLUT[cc.a][RED_INP] & 0xff);
b = ((*m_ColorInputLUT[cc.b][GRN_C] & 0xff) << 8) | (*m_ColorInputLUT[cc.b][RED_INP] & 0xff);
for (int i = 0; i < 3; i++)
{
InputReg.c = *m_ColorInputLUT[cc.c][i];
InputReg.d = *m_ColorInputLUT[cc.d][i];
Reg[cc.dest][RED_C + i] = InputReg.d + ((a == b) ? InputReg.c : 0);
Reg[cc.dest][BLU_C + i] = InputReg.d + ((a == b) ? InputReg.c : 0);
}
}
break;
case TEVCMP_BGR24_GT:
{
a = ((*m_ColorInputLUT[cc.a][BLU_C] & 0xff) << 16) | ((*m_ColorInputLUT[cc.a][GRN_C] & 0xff) << 8) | (*m_ColorInputLUT[cc.a][RED_C] & 0xff);
b = ((*m_ColorInputLUT[cc.b][BLU_C] & 0xff) << 16) | ((*m_ColorInputLUT[cc.b][GRN_C] & 0xff) << 8) | (*m_ColorInputLUT[cc.b][RED_C] & 0xff);
a = ((*m_ColorInputLUT[cc.a][BLU_C] & 0xff) << 16) | ((*m_ColorInputLUT[cc.a][GRN_C] & 0xff) << 8) | (*m_ColorInputLUT[cc.a][RED_INP] & 0xff);
b = ((*m_ColorInputLUT[cc.b][BLU_C] & 0xff) << 16) | ((*m_ColorInputLUT[cc.b][GRN_C] & 0xff) << 8) | (*m_ColorInputLUT[cc.b][RED_INP] & 0xff);
for (int i = 0; i < 3; i++)
{
InputReg.c = *m_ColorInputLUT[cc.c][i];
InputReg.d = *m_ColorInputLUT[cc.d][i];
Reg[cc.dest][RED_C + i] = InputReg.d + ((a > b) ? InputReg.c : 0);
Reg[cc.dest][BLU_C + i] = InputReg.d + ((a > b) ? InputReg.c : 0);
}
}
break;
case TEVCMP_BGR24_EQ:
{
a = ((*m_ColorInputLUT[cc.a][BLU_C] & 0xff) << 16) | ((*m_ColorInputLUT[cc.a][GRN_C] & 0xff) << 8) | (*m_ColorInputLUT[cc.a][RED_C] & 0xff);
b = ((*m_ColorInputLUT[cc.b][BLU_C] & 0xff) << 16) | ((*m_ColorInputLUT[cc.b][GRN_C] & 0xff) << 8) | (*m_ColorInputLUT[cc.b][RED_C] & 0xff);
a = ((*m_ColorInputLUT[cc.a][BLU_C] & 0xff) << 16) | ((*m_ColorInputLUT[cc.a][GRN_C] & 0xff) << 8) | (*m_ColorInputLUT[cc.a][RED_INP] & 0xff);
b = ((*m_ColorInputLUT[cc.b][BLU_C] & 0xff) << 16) | ((*m_ColorInputLUT[cc.b][GRN_C] & 0xff) << 8) | (*m_ColorInputLUT[cc.b][RED_INP] & 0xff);
for (int i = 0; i < 3; i++)
{
InputReg.c = *m_ColorInputLUT[cc.c][i];
InputReg.d = *m_ColorInputLUT[cc.d][i];
Reg[cc.dest][RED_C + i] = InputReg.d + ((a == b) ? InputReg.c : 0);
Reg[cc.dest][BLU_C + i] = InputReg.d + ((a == b) ? InputReg.c : 0);
}
}
break;
@@ -293,7 +293,7 @@ void Tev::DrawColorCompare(TevStageCombiner::ColorCombiner &cc)
InputReg.b = *m_ColorInputLUT[cc.b][i];
InputReg.c = *m_ColorInputLUT[cc.c][i];
InputReg.d = *m_ColorInputLUT[cc.d][i];
Reg[cc.dest][RED_C + i] = InputReg.d + ((InputReg.a > InputReg.b) ? InputReg.c : 0);
Reg[cc.dest][BLU_C + i] = InputReg.d + ((InputReg.a > InputReg.b) ? InputReg.c : 0);
}
break;
case TEVCMP_RGB8_EQ:
@@ -303,7 +303,7 @@ void Tev::DrawColorCompare(TevStageCombiner::ColorCombiner &cc)
InputReg.b = *m_ColorInputLUT[cc.b][i];
InputReg.c = *m_ColorInputLUT[cc.c][i];
InputReg.d = *m_ColorInputLUT[cc.d][i];
Reg[cc.dest][RED_C + i] = InputReg.d + ((InputReg.a == InputReg.b) ? InputReg.c : 0);
Reg[cc.dest][BLU_C + i] = InputReg.d + ((InputReg.a == InputReg.b) ? InputReg.c : 0);
}
break;
}
@@ -313,10 +313,10 @@ void Tev::DrawAlphaRegular(TevStageCombiner::AlphaCombiner &ac)
{
InputRegType InputReg;
InputReg.a = *m_AlphaInputLUT[ac.a];
InputReg.b = *m_AlphaInputLUT[ac.b];
InputReg.c = *m_AlphaInputLUT[ac.c];
InputReg.d = *m_AlphaInputLUT[ac.d];
InputReg.a = m_AlphaInputLUT[ac.a][ALP_C];
InputReg.b = m_AlphaInputLUT[ac.b][ALP_C];
InputReg.c = m_AlphaInputLUT[ac.c][ALP_C];
InputReg.d = m_AlphaInputLUT[ac.d][ALP_C];
u16 c = InputReg.c + (InputReg.c >> 7);
@@ -479,13 +479,13 @@ void Tev::Indirect(unsigned int stageNum, s32 s, s32 t)
AlphaBump = 0;
break;
case ITBA_S:
AlphaBump = indmap[ALP_C];
AlphaBump = indmap[TextureSampler::ALP_SMP];
break;
case ITBA_T:
AlphaBump = indmap[BLU_C];
AlphaBump = indmap[TextureSampler::BLU_SMP];
break;
case ITBA_U:
AlphaBump = indmap[GRN_C];
AlphaBump = indmap[TextureSampler::GRN_SMP];
break;
}
@@ -499,27 +499,27 @@ void Tev::Indirect(unsigned int stageNum, s32 s, s32 t)
// format
switch(indirect.fmt) {
case ITF_8:
indcoord[0] = indmap[ALP_C] + bias[0];
indcoord[1] = indmap[BLU_C] + bias[1];
indcoord[2] = indmap[GRN_C] + bias[2];
indcoord[0] = indmap[TextureSampler::ALP_SMP] + bias[0];
indcoord[1] = indmap[TextureSampler::BLU_SMP] + bias[1];
indcoord[2] = indmap[TextureSampler::GRN_SMP] + bias[2];
AlphaBump = AlphaBump & 0xf8;
break;
case ITF_5:
indcoord[0] = (indmap[ALP_C] & 0x1f) + bias[0];
indcoord[1] = (indmap[BLU_C] & 0x1f) + bias[1];
indcoord[2] = (indmap[GRN_C] & 0x1f) + bias[2];
indcoord[0] = (indmap[TextureSampler::ALP_SMP] & 0x1f) + bias[0];
indcoord[1] = (indmap[TextureSampler::BLU_SMP] & 0x1f) + bias[1];
indcoord[2] = (indmap[TextureSampler::GRN_SMP] & 0x1f) + bias[2];
AlphaBump = AlphaBump & 0xe0;
break;
case ITF_4:
indcoord[0] = (indmap[ALP_C] & 0x0f) + bias[0];
indcoord[1] = (indmap[BLU_C] & 0x0f) + bias[1];
indcoord[2] = (indmap[GRN_C] & 0x0f) + bias[2];
indcoord[0] = (indmap[TextureSampler::ALP_SMP] & 0x0f) + bias[0];
indcoord[1] = (indmap[TextureSampler::BLU_SMP] & 0x0f) + bias[1];
indcoord[2] = (indmap[TextureSampler::GRN_SMP] & 0x0f) + bias[2];
AlphaBump = AlphaBump & 0xf0;
break;
case ITF_3:
indcoord[0] = (indmap[ALP_C] & 0x07) + bias[0];
indcoord[1] = (indmap[BLU_C] & 0x07) + bias[1];
indcoord[2] = (indmap[GRN_C] & 0x07) + bias[2];
indcoord[0] = (indmap[TextureSampler::ALP_SMP] & 0x07) + bias[0];
indcoord[1] = (indmap[TextureSampler::BLU_SMP] & 0x07) + bias[1];
indcoord[2] = (indmap[TextureSampler::GRN_SMP] & 0x07) + bias[2];
AlphaBump = AlphaBump & 0xf8;
break;
default:
@@ -601,7 +601,10 @@ void Tev::Draw()
#if ALLOW_TEV_DUMPS
if (g_Config.bDumpTevStages)
{
u8 stage[4] = {(u8)IndirectTex[stageNum][3], (u8)IndirectTex[stageNum][2], (u8)IndirectTex[stageNum][1], 255};
u8 stage[4] = { IndirectTex[stageNum][TextureSampler::ALP_SMP],
IndirectTex[stageNum][TextureSampler::BLU_SMP],
IndirectTex[stageNum][TextureSampler::GRN_SMP],
255};
DebugUtil::DrawTempBuffer(stage, INDIRECT + stageNum);
}
#endif
@@ -626,7 +629,8 @@ void Tev::Draw()
// sample texture
if (order.getEnable(stageOdd))
{
u8 texel[4];
// RGBA
u8 texel[4];
TextureSampler::Sample(TexCoord.s, TexCoord.t, TextureLod[stageNum], TextureLinear[stageNum], texmap, texel);
@@ -637,11 +641,11 @@ void Tev::Draw()
int swaptable = ac.tswap * 2;
TexColor[0] = texel[bpmem.tevksel[swaptable].swap1];
TexColor[1] = texel[bpmem.tevksel[swaptable].swap2];
TexColor[RED_C] = texel[bpmem.tevksel[swaptable].swap1];
TexColor[GRN_C] = texel[bpmem.tevksel[swaptable].swap2];
swaptable++;
TexColor[2] = texel[bpmem.tevksel[swaptable].swap1];
TexColor[3] = texel[bpmem.tevksel[swaptable].swap2];
TexColor[BLU_C] = texel[bpmem.tevksel[swaptable].swap1];
TexColor[ALP_C] = texel[bpmem.tevksel[swaptable].swap2];
}
// set konst for this stage
@@ -687,14 +691,14 @@ void Tev::Draw()
#if ALLOW_TEV_DUMPS
if (g_Config.bDumpTevStages)
{
u8 stage[4] = {(u8)Reg[0][0], (u8)Reg[0][1], (u8)Reg[0][2], (u8)Reg[0][3]};
u8 stage[4] = {(u8)Reg[0][RED_C], (u8)Reg[0][GRN_C], (u8)Reg[0][BLU_C], (u8)Reg[0][ALP_C]};
DebugUtil::DrawTempBuffer(stage, DIRECT + stageNum);
}
#endif
}
// convert to 8 bits per component
u8 output[4] = {(u8)Reg[0][0], (u8)Reg[0][1], (u8)Reg[0][2], (u8)Reg[0][3]};
u8 output[4] = {(u8)Reg[0][ALP_C], (u8)Reg[0][BLU_C], (u8)Reg[0][GRN_C], (u8)Reg[0][RED_C]};
if (!AlphaTest(output[ALP_C]))
return;
+16 -7
View File
@@ -35,26 +35,35 @@ class Tev
signed t : 24;
};
// color order: RGBA
s16 Reg[4][4];
// color order: ABGR
s16 Reg[4][4];
s16 KonstantColors[4][4];
s16 FixedConstants[9];
s16 TexColor[4];
s16 RasColor[4];
s16 StageKonst[4];
s16 Zero16[4];
u8 AlphaBump;
s16 FixedConstants[9];
u8 AlphaBump;
u8 IndirectTex[4][4];
TextureCoordinateType TexCoord;
s16 *m_ColorInputLUT[16][3];
s16 *m_AlphaInputLUT[8]; // values must point to RGBA color
s16 *m_AlphaInputLUT[8]; // values must point to ABGR color
s16 *m_KonstLUT[32][4];
u8 *m_RasColorLUT[8];
s16 m_BiasLUT[4];
u8 m_ScaleLShiftLUT[4];
u8 m_ScaleRShiftLUT[4];
// enumeration for color input LUT
enum
{
BLU_INP,
GRN_INP,
RED_INP
};
enum BufferBase
{
DIRECT = 0,
@@ -73,7 +82,7 @@ class Tev
public:
s32 Position[3];
u8 Color[2][4];
u8 Color[2][4]; // must be RGBA for correct swap table ordering
TextureCoordinateType Uv[8];
s32 IndirectLod[4];
bool IndirectLinear[4];
@@ -86,7 +95,7 @@ public:
void SetRegColor(int reg, int comp, bool konst, s16 color);
enum { RED_C, GRN_C, BLU_C, ALP_C };
enum { ALP_C, BLU_C, GRN_C, RED_C };
};
#endif
File diff suppressed because it is too large Load Diff
@@ -26,6 +26,8 @@ namespace TextureSampler
void Sample(s32 s, s32 t, s32 lod, bool linear, u8 texmap, u8 *sample);
void SampleMip(s32 s, s32 t, s32 mip, bool linear, u8 texmap, u8 *sample);
enum { RED_SMP, GRN_SMP, BLU_SMP, ALP_SMP };
}