Merge pull request #10549 from Pokechu22/sw-tev-enum-map

Refactor various bits of graphics code for readability
This commit is contained in:
Pokechu22
2022-09-08 09:42:12 -07:00
committed by GitHub
13 changed files with 515 additions and 468 deletions

View File

@ -108,8 +108,6 @@ static std::vector<BPFunctions::ScissorRect> scissors;
void Init()
{
tev.Init();
// The other slopes are set each for each primitive drawn, but zfreeze means that the z slope
// needs to be set to an (untested) default value.
ZSlope = Slope();
@ -142,9 +140,9 @@ static inline int iround(float x)
return t;
}
void SetTevReg(int reg, int comp, s16 color)
void SetTevKonstColors()
{
tev.SetRegColor(reg, comp, color);
tev.SetKonstColors();
}
static void Draw(s32 x, s32 y, s32 xi, s32 yi)
@ -288,13 +286,10 @@ static void BuildBlock(s32 blockX, s32 blockY)
}
}
u32 indref = bpmem.tevindref.hex;
for (unsigned int i = 0; i < bpmem.genMode.numindstages; i++)
{
u32 texmap = indref & 7;
indref >>= 3;
u32 texcoord = indref & 7;
indref >>= 3;
u32 texmap = bpmem.tevindref.getTexMap(i);
u32 texcoord = bpmem.tevindref.getTexCoord(i);
CalculateLOD(&rasterBlock.IndirectLod[i], &rasterBlock.IndirectLinear[i], texmap, texcoord);
}

View File

@ -17,7 +17,7 @@ void UpdateZSlope(const OutputVertexData* v0, const OutputVertexData* v1,
void DrawTriangleFrontFace(const OutputVertexData* v0, const OutputVertexData* v1,
const OutputVertexData* v2);
void SetTevReg(int reg, int comp, s16 color);
void SetTevKonstColors();
struct RasterBlockPixel
{

View File

@ -67,15 +67,7 @@ void SWVertexLoader::DrawCurrentBatch(u32 base_index, u32 num_indices, u32 base_
g_renderer->BBoxFlush();
m_setup_unit.Init(primitive_type);
// set all states with are stored within video sw
for (int i = 0; i < 4; i++)
{
Rasterizer::SetTevReg(i, Tev::RED_C, PixelShaderManager::constants.kcolors[i][0]);
Rasterizer::SetTevReg(i, Tev::GRN_C, PixelShaderManager::constants.kcolors[i][1]);
Rasterizer::SetTevReg(i, Tev::BLU_C, PixelShaderManager::constants.kcolors[i][2]);
Rasterizer::SetTevReg(i, Tev::ALP_C, PixelShaderManager::constants.kcolors[i][3]);
}
Rasterizer::SetTevKonstColors();
for (u32 i = 0; i < m_index_generator.GetIndexLen(); i++)
{

View File

@ -27,190 +27,49 @@
#define ALLOW_TEV_DUMPS 0
#endif
void Tev::Init()
{
FixedConstants[0] = 0;
FixedConstants[1] = 32;
FixedConstants[2] = 64;
FixedConstants[3] = 96;
FixedConstants[4] = 128;
FixedConstants[5] = 159;
FixedConstants[6] = 191;
FixedConstants[7] = 223;
FixedConstants[8] = 255;
for (s16& comp : Zero16)
{
comp = 0;
}
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
m_AlphaInputLUT[1] = &Reg[1][ALP_C]; // c0
m_AlphaInputLUT[2] = &Reg[2][ALP_C]; // c1
m_AlphaInputLUT[3] = &Reg[3][ALP_C]; // c2
m_AlphaInputLUT[4] = &TexColor[ALP_C]; // tex
m_AlphaInputLUT[5] = &RasColor[ALP_C]; // ras
m_AlphaInputLUT[6] = &StageKonst[ALP_C]; // konst
m_AlphaInputLUT[7] = &Zero16[ALP_C]; // zero
for (int comp = 0; comp < 4; comp++)
{
m_KonstLUT[0][comp] = &FixedConstants[8];
m_KonstLUT[1][comp] = &FixedConstants[7];
m_KonstLUT[2][comp] = &FixedConstants[6];
m_KonstLUT[3][comp] = &FixedConstants[5];
m_KonstLUT[4][comp] = &FixedConstants[4];
m_KonstLUT[5][comp] = &FixedConstants[3];
m_KonstLUT[6][comp] = &FixedConstants[2];
m_KonstLUT[7][comp] = &FixedConstants[1];
// These are "invalid" values, not meant to be used. On hardware,
// they all output zero.
for (int i = 8; i < 16; ++i)
{
m_KonstLUT[i][comp] = &FixedConstants[0];
}
if (comp != ALP_C)
{
m_KonstLUT[12][comp] = &KonstantColors[0][comp];
m_KonstLUT[13][comp] = &KonstantColors[1][comp];
m_KonstLUT[14][comp] = &KonstantColors[2][comp];
m_KonstLUT[15][comp] = &KonstantColors[3][comp];
}
m_KonstLUT[16][comp] = &KonstantColors[0][RED_C];
m_KonstLUT[17][comp] = &KonstantColors[1][RED_C];
m_KonstLUT[18][comp] = &KonstantColors[2][RED_C];
m_KonstLUT[19][comp] = &KonstantColors[3][RED_C];
m_KonstLUT[20][comp] = &KonstantColors[0][GRN_C];
m_KonstLUT[21][comp] = &KonstantColors[1][GRN_C];
m_KonstLUT[22][comp] = &KonstantColors[2][GRN_C];
m_KonstLUT[23][comp] = &KonstantColors[3][GRN_C];
m_KonstLUT[24][comp] = &KonstantColors[0][BLU_C];
m_KonstLUT[25][comp] = &KonstantColors[1][BLU_C];
m_KonstLUT[26][comp] = &KonstantColors[2][BLU_C];
m_KonstLUT[27][comp] = &KonstantColors[3][BLU_C];
m_KonstLUT[28][comp] = &KonstantColors[0][ALP_C];
m_KonstLUT[29][comp] = &KonstantColors[1][ALP_C];
m_KonstLUT[30][comp] = &KonstantColors[2][ALP_C];
m_KonstLUT[31][comp] = &KonstantColors[3][ALP_C];
}
m_BiasLUT[0] = 0;
m_BiasLUT[1] = 128;
m_BiasLUT[2] = -128;
m_BiasLUT[3] = 0;
m_ScaleLShiftLUT[0] = 0;
m_ScaleLShiftLUT[1] = 1;
m_ScaleLShiftLUT[2] = 2;
m_ScaleLShiftLUT[3] = 0;
m_ScaleRShiftLUT[0] = 0;
m_ScaleRShiftLUT[1] = 0;
m_ScaleRShiftLUT[2] = 0;
m_ScaleRShiftLUT[3] = 1;
}
static inline s16 Clamp255(s16 in)
{
return in > 255 ? 255 : (in < 0 ? 0 : in);
return std::clamp<s16>(in, 0, 255);
}
static inline s16 Clamp1024(s16 in)
{
return in > 1023 ? 1023 : (in < -1024 ? -1024 : in);
return std::clamp<s16>(in, -1024, 1023);
}
void Tev::SetRasColor(RasColorChan colorChan, int swaptable)
void Tev::SetRasColor(RasColorChan colorChan, u32 swaptable)
{
switch (colorChan)
{
case RasColorChan::Color0:
{
const u8* color = Color[0];
RasColor[RED_C] = color[bpmem.tevksel[swaptable].swap1];
RasColor[GRN_C] = color[bpmem.tevksel[swaptable].swap2];
swaptable++;
RasColor[BLU_C] = color[bpmem.tevksel[swaptable].swap1];
RasColor[ALP_C] = color[bpmem.tevksel[swaptable].swap2];
const auto& swap = bpmem.tevksel.GetSwapTable(swaptable);
RasColor.r = color[u32(swap[ColorChannel::Red])];
RasColor.g = color[u32(swap[ColorChannel::Green])];
RasColor.b = color[u32(swap[ColorChannel::Blue])];
RasColor.a = color[u32(swap[ColorChannel::Alpha])];
}
break;
case RasColorChan::Color1:
{
const u8* color = Color[1];
RasColor[RED_C] = color[bpmem.tevksel[swaptable].swap1];
RasColor[GRN_C] = color[bpmem.tevksel[swaptable].swap2];
swaptable++;
RasColor[BLU_C] = color[bpmem.tevksel[swaptable].swap1];
RasColor[ALP_C] = color[bpmem.tevksel[swaptable].swap2];
const auto& swap = bpmem.tevksel.GetSwapTable(swaptable);
RasColor.r = color[u32(swap[ColorChannel::Red])];
RasColor.g = color[u32(swap[ColorChannel::Green])];
RasColor.b = color[u32(swap[ColorChannel::Blue])];
RasColor.a = color[u32(swap[ColorChannel::Alpha])];
}
break;
case RasColorChan::AlphaBump:
{
for (s16& comp : RasColor)
{
comp = AlphaBump;
}
RasColor = TevColor::All(AlphaBump);
}
break;
case RasColorChan::NormalizedAlphaBump:
{
const u8 normalized = AlphaBump | AlphaBump >> 5;
for (s16& comp : RasColor)
{
comp = normalized;
}
RasColor = TevColor::All(normalized);
}
break;
default:
@ -218,10 +77,7 @@ void Tev::SetRasColor(RasColorChan colorChan, int swaptable)
if (colorChan != RasColorChan::Zero)
PanicAlertFmt("Invalid ras color channel: {}", colorChan);
for (s16& comp : RasColor)
{
comp = 0;
}
RasColor = TevColor::All(0);
}
break;
}
@ -236,17 +92,15 @@ void Tev::DrawColorRegular(const TevStageCombiner::ColorCombiner& cc, const Inpu
const u16 c = InputReg.c + (InputReg.c >> 7);
s32 temp = InputReg.a * (256 - c) + (InputReg.b * c);
temp <<= m_ScaleLShiftLUT[u32(cc.scale.Value())];
temp <<= s_ScaleLShiftLUT[cc.scale];
temp += (cc.scale == TevScale::Divide2) ? 0 : (cc.op == TevOp::Sub) ? 127 : 128;
temp >>= 8;
temp = cc.op == TevOp::Sub ? -temp : temp;
s32 result = ((InputReg.d + m_BiasLUT[u32(cc.bias.Value())])
<< m_ScaleLShiftLUT[u32(cc.scale.Value())]) +
temp;
result = result >> m_ScaleRShiftLUT[u32(cc.scale.Value())];
s32 result = ((InputReg.d + s_BiasLUT[cc.bias]) << s_ScaleLShiftLUT[cc.scale]) + temp;
result = result >> s_ScaleRShiftLUT[cc.scale];
Reg[u32(cc.dest.Value())][i] = result;
Reg[cc.dest][i] = result;
}
}
@ -283,9 +137,9 @@ void Tev::DrawColorCompare(const TevStageCombiner::ColorCombiner& cc, const Inpu
}
if (cc.comparison == TevComparison::GT)
Reg[u32(cc.dest.Value())][i] = inputs[i].d + ((a > b) ? inputs[i].c : 0);
Reg[cc.dest][i] = inputs[i].d + ((a > b) ? inputs[i].c : 0);
else
Reg[u32(cc.dest.Value())][i] = inputs[i].d + ((a == b) ? inputs[i].c : 0);
Reg[cc.dest][i] = inputs[i].d + ((a == b) ? inputs[i].c : 0);
}
}
@ -296,16 +150,14 @@ void Tev::DrawAlphaRegular(const TevStageCombiner::AlphaCombiner& ac, const Inpu
const u16 c = InputReg.c + (InputReg.c >> 7);
s32 temp = InputReg.a * (256 - c) + (InputReg.b * c);
temp <<= m_ScaleLShiftLUT[u32(ac.scale.Value())];
temp <<= s_ScaleLShiftLUT[ac.scale];
temp += (ac.scale == TevScale::Divide2) ? 0 : (ac.op == TevOp::Sub) ? 127 : 128;
temp = ac.op == TevOp::Sub ? (-temp >> 8) : (temp >> 8);
s32 result =
((InputReg.d + m_BiasLUT[u32(ac.bias.Value())]) << m_ScaleLShiftLUT[u32(ac.scale.Value())]) +
temp;
result = result >> m_ScaleRShiftLUT[u32(ac.scale.Value())];
s32 result = ((InputReg.d + s_BiasLUT[ac.bias]) << s_ScaleLShiftLUT[ac.scale]) + temp;
result = result >> s_ScaleRShiftLUT[ac.scale];
Reg[u32(ac.dest.Value())][ALP_C] = result;
Reg[ac.dest].a = result;
}
void Tev::DrawAlphaCompare(const TevStageCombiner::AlphaCombiner& ac, const InputRegType inputs[4])
@ -339,9 +191,9 @@ void Tev::DrawAlphaCompare(const TevStageCombiner::AlphaCombiner& ac, const Inpu
}
if (ac.comparison == TevComparison::GT)
Reg[u32(ac.dest.Value())][ALP_C] = inputs[ALP_C].d + ((a > b) ? inputs[ALP_C].c : 0);
Reg[ac.dest].a = inputs[ALP_C].d + ((a > b) ? inputs[ALP_C].c : 0);
else
Reg[u32(ac.dest.Value())][ALP_C] = inputs[ALP_C].d + ((a == b) ? inputs[ALP_C].c : 0);
Reg[ac.dest].a = inputs[ALP_C].d + ((a == b) ? inputs[ALP_C].c : 0);
}
static bool AlphaCompare(int alpha, int ref, CompareMode comp)
@ -548,10 +400,10 @@ void Tev::Draw()
// initial color values
for (int i = 0; i < 4; i++)
{
Reg[i][RED_C] = PixelShaderManager::constants.colors[i][0];
Reg[i][GRN_C] = PixelShaderManager::constants.colors[i][1];
Reg[i][BLU_C] = PixelShaderManager::constants.colors[i][2];
Reg[i][ALP_C] = PixelShaderManager::constants.colors[i][3];
Reg[static_cast<TevOutput>(i)].r = PixelShaderManager::constants.colors[i][0];
Reg[static_cast<TevOutput>(i)].g = PixelShaderManager::constants.colors[i][1];
Reg[static_cast<TevOutput>(i)].b = PixelShaderManager::constants.colors[i][2];
Reg[static_cast<TevOutput>(i)].a = PixelShaderManager::constants.colors[i][3];
}
for (unsigned int stageNum = 0; stageNum < bpmem.genMode.numindstages; stageNum++)
@ -593,7 +445,6 @@ void Tev::Draw()
const int stageNum2 = stageNum >> 1;
const int stageOdd = stageNum & 1;
const TwoTevStageOrders& order = bpmem.tevorders[stageNum2];
const TevKSel& kSel = bpmem.tevksel[stageNum2];
// stage combiners
const TevStageCombiner::ColorCombiner& cc = bpmem.combiners[stageNum].colorC;
@ -632,39 +483,42 @@ void Tev::Draw()
DebugUtil::DrawTempBuffer(texel, DIRECT_TFETCH + stageNum);
#endif
int swaptable = ac.tswap * 2;
TexColor[RED_C] = texel[bpmem.tevksel[swaptable].swap1];
TexColor[GRN_C] = texel[bpmem.tevksel[swaptable].swap2];
swaptable++;
TexColor[BLU_C] = texel[bpmem.tevksel[swaptable].swap1];
TexColor[ALP_C] = texel[bpmem.tevksel[swaptable].swap2];
const auto& swap = bpmem.tevksel.GetSwapTable(ac.tswap);
TexColor.r = texel[u32(swap[ColorChannel::Red])];
TexColor.g = texel[u32(swap[ColorChannel::Green])];
TexColor.b = texel[u32(swap[ColorChannel::Blue])];
TexColor.a = texel[u32(swap[ColorChannel::Alpha])];
}
// set konst for this stage
const auto kc = u32(kSel.getKC(stageOdd));
const auto ka = u32(kSel.getKA(stageOdd));
StageKonst[RED_C] = *(m_KonstLUT[kc][RED_C]);
StageKonst[GRN_C] = *(m_KonstLUT[kc][GRN_C]);
StageKonst[BLU_C] = *(m_KonstLUT[kc][BLU_C]);
StageKonst[ALP_C] = *(m_KonstLUT[ka][ALP_C]);
const auto kc = bpmem.tevksel.GetKonstColor(stageNum);
const auto ka = bpmem.tevksel.GetKonstAlpha(stageNum);
StageKonst.r = m_KonstLUT[kc].r;
StageKonst.g = m_KonstLUT[kc].g;
StageKonst.b = m_KonstLUT[kc].b;
StageKonst.a = m_KonstLUT[ka].a;
// set color
SetRasColor(order.getColorChan(stageOdd), ac.rswap * 2);
SetRasColor(order.getColorChan(stageOdd), ac.rswap);
// combine inputs
InputRegType inputs[4];
for (int i = 0; i < 3; i++)
{
inputs[BLU_C + i].a = *m_ColorInputLUT[u32(cc.a.Value())][i];
inputs[BLU_C + i].b = *m_ColorInputLUT[u32(cc.b.Value())][i];
inputs[BLU_C + i].c = *m_ColorInputLUT[u32(cc.c.Value())][i];
inputs[BLU_C + i].d = *m_ColorInputLUT[u32(cc.d.Value())][i];
}
inputs[ALP_C].a = *m_AlphaInputLUT[u32(ac.a.Value())];
inputs[ALP_C].b = *m_AlphaInputLUT[u32(ac.b.Value())];
inputs[ALP_C].c = *m_AlphaInputLUT[u32(ac.c.Value())];
inputs[ALP_C].d = *m_AlphaInputLUT[u32(ac.d.Value())];
inputs[BLU_C].a = m_ColorInputLUT[cc.a].b;
inputs[BLU_C].b = m_ColorInputLUT[cc.b].b;
inputs[BLU_C].c = m_ColorInputLUT[cc.c].b;
inputs[BLU_C].d = m_ColorInputLUT[cc.d].b;
inputs[GRN_C].a = m_ColorInputLUT[cc.a].g;
inputs[GRN_C].b = m_ColorInputLUT[cc.b].g;
inputs[GRN_C].c = m_ColorInputLUT[cc.c].g;
inputs[GRN_C].d = m_ColorInputLUT[cc.d].g;
inputs[RED_C].a = m_ColorInputLUT[cc.a].r;
inputs[RED_C].b = m_ColorInputLUT[cc.b].r;
inputs[RED_C].c = m_ColorInputLUT[cc.c].r;
inputs[RED_C].d = m_ColorInputLUT[cc.d].r;
inputs[ALP_C].a = m_AlphaInputLUT[ac.a].a;
inputs[ALP_C].b = m_AlphaInputLUT[ac.b].a;
inputs[ALP_C].c = m_AlphaInputLUT[ac.c].a;
inputs[ALP_C].d = m_AlphaInputLUT[ac.d].a;
if (cc.bias != TevBias::Compare)
DrawColorRegular(cc, inputs);
@ -673,15 +527,15 @@ void Tev::Draw()
if (cc.clamp)
{
Reg[u32(cc.dest.Value())][RED_C] = Clamp255(Reg[u32(cc.dest.Value())][RED_C]);
Reg[u32(cc.dest.Value())][GRN_C] = Clamp255(Reg[u32(cc.dest.Value())][GRN_C]);
Reg[u32(cc.dest.Value())][BLU_C] = Clamp255(Reg[u32(cc.dest.Value())][BLU_C]);
Reg[cc.dest].r = Clamp255(Reg[cc.dest].r);
Reg[cc.dest].g = Clamp255(Reg[cc.dest].g);
Reg[cc.dest].b = Clamp255(Reg[cc.dest].b);
}
else
{
Reg[u32(cc.dest.Value())][RED_C] = Clamp1024(Reg[u32(cc.dest.Value())][RED_C]);
Reg[u32(cc.dest.Value())][GRN_C] = Clamp1024(Reg[u32(cc.dest.Value())][GRN_C]);
Reg[u32(cc.dest.Value())][BLU_C] = Clamp1024(Reg[u32(cc.dest.Value())][BLU_C]);
Reg[cc.dest].r = Clamp1024(Reg[cc.dest].r);
Reg[cc.dest].g = Clamp1024(Reg[cc.dest].g);
Reg[cc.dest].b = Clamp1024(Reg[cc.dest].b);
}
if (ac.bias != TevBias::Compare)
@ -690,14 +544,15 @@ void Tev::Draw()
DrawAlphaCompare(ac, inputs);
if (ac.clamp)
Reg[u32(ac.dest.Value())][ALP_C] = Clamp255(Reg[u32(ac.dest.Value())][ALP_C]);
Reg[ac.dest].a = Clamp255(Reg[ac.dest].a);
else
Reg[u32(ac.dest.Value())][ALP_C] = Clamp1024(Reg[u32(ac.dest.Value())][ALP_C]);
Reg[ac.dest].a = Clamp1024(Reg[ac.dest].a);
#if ALLOW_TEV_DUMPS
if (g_ActiveConfig.bDumpTevStages)
{
u8 stage[4] = {(u8)Reg[0][RED_C], (u8)Reg[0][GRN_C], (u8)Reg[0][BLU_C], (u8)Reg[0][ALP_C]};
u8 stage[4] = {(u8)Reg[cc.dest].r, (u8)Reg[cc.dest].g, (u8)Reg[cc.dest].b,
(u8)Reg[ac.dest].a};
DebugUtil::DrawTempBuffer(stage, DIRECT + stageNum);
}
#endif
@ -706,10 +561,10 @@ void Tev::Draw()
// convert to 8 bits per component
// the results of the last tev stage are put onto the screen,
// regardless of the used destination register - TODO: Verify!
const u32 color_index = u32(bpmem.combiners[bpmem.genMode.numtevstages].colorC.dest.Value());
const u32 alpha_index = u32(bpmem.combiners[bpmem.genMode.numtevstages].alphaC.dest.Value());
u8 output[4] = {(u8)Reg[alpha_index][ALP_C], (u8)Reg[color_index][BLU_C],
(u8)Reg[color_index][GRN_C], (u8)Reg[color_index][RED_C]};
const auto& color_index = bpmem.combiners[bpmem.genMode.numtevstages].colorC.dest;
const auto& alpha_index = bpmem.combiners[bpmem.genMode.numtevstages].alphaC.dest;
u8 output[4] = {(u8)Reg[alpha_index].a, (u8)Reg[color_index].b, (u8)Reg[color_index].g,
(u8)Reg[color_index].r};
if (!TevAlphaTest(output[ALP_C]))
return;
@ -882,7 +737,13 @@ void Tev::Draw()
EfbInterface::BlendTev(Position[0], Position[1], output);
}
void Tev::SetRegColor(int reg, int comp, s16 color)
void Tev::SetKonstColors()
{
KonstantColors[reg][comp] = color;
for (int i = 0; i < 4; i++)
{
KonstantColors[i].r = PixelShaderManager::constants.kcolors[i][0];
KonstantColors[i].g = PixelShaderManager::constants.kcolors[i][1];
KonstantColors[i].b = PixelShaderManager::constants.kcolors[i][2];
KonstantColors[i].a = PixelShaderManager::constants.kcolors[i][3];
}
}

View File

@ -3,10 +3,90 @@
#pragma once
#include <array>
#include "Common/EnumMap.h"
#include "VideoCommon/BPMemory.h"
class Tev
{
struct TevColor
{
constexpr TevColor() = default;
constexpr explicit TevColor(s16 a, s16 b, s16 g, s16 r) : a(a), b(b), g(g), r(r) {}
s16 a = 0;
s16 b = 0;
s16 g = 0;
s16 r = 0;
constexpr static TevColor All(s16 value) { return TevColor(value, value, value, value); }
constexpr s16& operator[](int index)
{
switch (index)
{
case ALP_C:
return a;
case BLU_C:
return b;
case GRN_C:
return g;
case RED_C:
return r;
default:
// invalid
return a;
}
}
};
struct TevColorRef
{
constexpr explicit TevColorRef(const s16& r, const s16& g, const s16& b) : r(r), g(g), b(b) {}
const s16& r;
const s16& g;
const s16& b;
constexpr static TevColorRef Color(const TevColor& color)
{
return TevColorRef(color.r, color.g, color.b);
}
constexpr static TevColorRef All(const s16& value) { return TevColorRef(value, value, value); }
constexpr static TevColorRef Alpha(const TevColor& color) { return All(color.a); }
};
struct TevAlphaRef
{
constexpr explicit TevAlphaRef(const TevColor& color) : a(color.a) {}
constexpr explicit TevAlphaRef(const s16& a) : a(a) {}
const s16& a;
};
struct TevKonstRef
{
constexpr explicit TevKonstRef(const s16& a, const s16& r, const s16& g, const s16& b)
: a(a), r(r), g(g), b(b)
{
}
const s16& a;
const s16& r;
const s16& g;
const s16& b;
constexpr static TevKonstRef Value(const s16& value)
{
return TevKonstRef(value, value, value, value);
}
constexpr static TevKonstRef Konst(const s16& alpha, const TevColor& color)
{
return TevKonstRef(alpha, color.r, color.g, color.b);
}
};
struct InputRegType
{
unsigned a : 8;
@ -22,32 +102,96 @@ class Tev
};
// color order: ABGR
s16 Reg[4][4];
s16 KonstantColors[4][4];
s16 TexColor[4];
s16 RasColor[4];
s16 StageKonst[4];
s16 Zero16[4];
Common::EnumMap<TevColor, TevOutput::Color2> Reg;
std::array<TevColor, 4> KonstantColors;
TevColor TexColor;
TevColor RasColor;
TevColor StageKonst;
// Fixed constants, corresponding to KonstSel
static constexpr s16 V0 = 0;
static constexpr s16 V1_8 = 32;
static constexpr s16 V1_4 = 64;
static constexpr s16 V3_8 = 96;
static constexpr s16 V1_2 = 128;
static constexpr s16 V5_8 = 159;
static constexpr s16 V3_4 = 191;
static constexpr s16 V7_8 = 223;
static constexpr s16 V1 = 255;
s16 FixedConstants[9];
u8 AlphaBump;
u8 IndirectTex[4][4];
TextureCoordinateType TexCoord;
s16* m_ColorInputLUT[16][3];
s16* m_AlphaInputLUT[8]; // values must point to ABGR color
s16* m_KonstLUT[32][4];
s16 m_BiasLUT[4];
u8 m_ScaleLShiftLUT[4];
u8 m_ScaleRShiftLUT[4];
// enumeration for color input LUT
enum
{
BLU_INP,
GRN_INP,
RED_INP
const Common::EnumMap<TevColorRef, TevColorArg::Zero> m_ColorInputLUT{
TevColorRef::Color(Reg[TevOutput::Prev]), // prev.rgb
TevColorRef::Alpha(Reg[TevOutput::Prev]), // prev.aaa
TevColorRef::Color(Reg[TevOutput::Color0]), // c0.rgb
TevColorRef::Alpha(Reg[TevOutput::Color0]), // c0.aaa
TevColorRef::Color(Reg[TevOutput::Color1]), // c1.rgb
TevColorRef::Alpha(Reg[TevOutput::Color1]), // c1.aaa
TevColorRef::Color(Reg[TevOutput::Color2]), // c2.rgb
TevColorRef::Alpha(Reg[TevOutput::Color2]), // c2.aaa
TevColorRef::Color(TexColor), // tex.rgb
TevColorRef::Alpha(TexColor), // tex.aaa
TevColorRef::Color(RasColor), // ras.rgb
TevColorRef::Alpha(RasColor), // ras.aaa
TevColorRef::All(V1), // one
TevColorRef::All(V1_2), // half
TevColorRef::Color(StageKonst), // konst
TevColorRef::All(V0), // zero
};
const Common::EnumMap<TevAlphaRef, TevAlphaArg::Zero> m_AlphaInputLUT{
TevAlphaRef(Reg[TevOutput::Prev]), // prev
TevAlphaRef(Reg[TevOutput::Color0]), // c0
TevAlphaRef(Reg[TevOutput::Color1]), // c1
TevAlphaRef(Reg[TevOutput::Color2]), // c2
TevAlphaRef(TexColor), // tex
TevAlphaRef(RasColor), // ras
TevAlphaRef(StageKonst), // konst
TevAlphaRef(V0), // zero
};
const Common::EnumMap<TevKonstRef, KonstSel::K3_A> m_KonstLUT{
TevKonstRef::Value(V1), // 1
TevKonstRef::Value(V7_8), // 7/8
TevKonstRef::Value(V3_4), // 3/4
TevKonstRef::Value(V5_8), // 5/8
TevKonstRef::Value(V1_2), // 1/2
TevKonstRef::Value(V3_8), // 3/8
TevKonstRef::Value(V1_4), // 1/4
TevKonstRef::Value(V1_8), // 1/8
// These are "invalid" values, not meant to be used. On hardware,
// they all output zero.
TevKonstRef::Value(V0), TevKonstRef::Value(V0), TevKonstRef::Value(V0),
TevKonstRef::Value(V0),
// These values are valid for RGB only; they're invalid for alpha
TevKonstRef::Konst(V0, KonstantColors[0]), // Konst 0 RGB
TevKonstRef::Konst(V0, KonstantColors[1]), // Konst 1 RGB
TevKonstRef::Konst(V0, KonstantColors[2]), // Konst 2 RGB
TevKonstRef::Konst(V0, KonstantColors[3]), // Konst 3 RGB
TevKonstRef::Value(KonstantColors[0].r), // Konst 0 Red
TevKonstRef::Value(KonstantColors[1].r), // Konst 1 Red
TevKonstRef::Value(KonstantColors[2].r), // Konst 2 Red
TevKonstRef::Value(KonstantColors[3].r), // Konst 3 Red
TevKonstRef::Value(KonstantColors[0].g), // Konst 0 Green
TevKonstRef::Value(KonstantColors[1].g), // Konst 1 Green
TevKonstRef::Value(KonstantColors[2].g), // Konst 2 Green
TevKonstRef::Value(KonstantColors[3].g), // Konst 3 Green
TevKonstRef::Value(KonstantColors[0].b), // Konst 0 Blue
TevKonstRef::Value(KonstantColors[1].b), // Konst 1 Blue
TevKonstRef::Value(KonstantColors[2].b), // Konst 2 Blue
TevKonstRef::Value(KonstantColors[3].b), // Konst 3 Blue
TevKonstRef::Value(KonstantColors[0].a), // Konst 0 Alpha
TevKonstRef::Value(KonstantColors[1].a), // Konst 1 Alpha
TevKonstRef::Value(KonstantColors[2].a), // Konst 2 Alpha
TevKonstRef::Value(KonstantColors[3].a), // Konst 3 Alpha
};
static constexpr Common::EnumMap<s16, TevBias::Compare> s_BiasLUT{0, 128, -128, 0};
static constexpr Common::EnumMap<u8, TevScale::Divide2> s_ScaleLShiftLUT{0, 1, 2, 0};
static constexpr Common::EnumMap<u8, TevScale::Divide2> s_ScaleRShiftLUT{0, 0, 0, 1};
enum BufferBase
{
@ -56,7 +200,7 @@ class Tev
INDIRECT = 32
};
void SetRasColor(RasColorChan colorChan, int swaptable);
void SetRasColor(RasColorChan colorChan, u32 swaptable);
void DrawColorRegular(const TevStageCombiner::ColorCombiner& cc, const InputRegType inputs[4]);
void DrawColorCompare(const TevStageCombiner::ColorCombiner& cc, const InputRegType inputs[4]);
@ -82,9 +226,6 @@ public:
RED_C
};
void Init();
void SetKonstColors();
void Draw();
void SetRegColor(int reg, int comp, s16 color);
};