From ec1ed64832a0e626a2d20c25e5cdcb7aea7ed25c Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Tue, 21 Dec 2021 18:03:18 -0800 Subject: [PATCH 01/14] EnumMap: Fix typo --- Source/Core/Common/EnumMap.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Core/Common/EnumMap.h b/Source/Core/Common/EnumMap.h index 478ff42ec7..1418c1f01e 100644 --- a/Source/Core/Common/EnumMap.h +++ b/Source/Core/Common/EnumMap.h @@ -58,7 +58,7 @@ public: constexpr V& operator[](BitField key) { static_assert(1 << bits == s_size, "Unsafe indexing into EnumMap (may go out of bounds)"); - return m_array[static_cast(key.value())]; + return m_array[static_cast(key.Value())]; } constexpr bool InBounds(T key) const { return static_cast(key) < s_size; } From 2db756946341e796747bd522f4d240406f363766 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Tue, 21 Dec 2021 16:43:38 -0800 Subject: [PATCH 02/14] SW/Tev: Use TevColorRef/TevAlphaRef instead of raw s16 pointers --- Source/Core/VideoBackends/Software/Tev.cpp | 231 +++++---------------- Source/Core/VideoBackends/Software/Tev.h | 180 ++++++++++++++-- 2 files changed, 217 insertions(+), 194 deletions(-) diff --git a/Source/Core/VideoBackends/Software/Tev.cpp b/Source/Core/VideoBackends/Software/Tev.cpp index c2039df3ea..f5aa1450c8 100644 --- a/Source/Core/VideoBackends/Software/Tev.cpp +++ b/Source/Core/VideoBackends/Software/Tev.cpp @@ -29,123 +29,6 @@ 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; @@ -179,38 +62,32 @@ void Tev::SetRasColor(RasColorChan colorChan, int swaptable) case RasColorChan::Color0: { const u8* color = Color[0]; - RasColor[RED_C] = color[bpmem.tevksel[swaptable].swap1]; - RasColor[GRN_C] = color[bpmem.tevksel[swaptable].swap2]; + RasColor.r = color[bpmem.tevksel[swaptable].swap1]; + RasColor.g = color[bpmem.tevksel[swaptable].swap2]; swaptable++; - RasColor[BLU_C] = color[bpmem.tevksel[swaptable].swap1]; - RasColor[ALP_C] = color[bpmem.tevksel[swaptable].swap2]; + RasColor.b = color[bpmem.tevksel[swaptable].swap1]; + RasColor.a = color[bpmem.tevksel[swaptable].swap2]; } 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]; + RasColor.r = color[bpmem.tevksel[swaptable].swap1]; + RasColor.g = color[bpmem.tevksel[swaptable].swap2]; swaptable++; - RasColor[BLU_C] = color[bpmem.tevksel[swaptable].swap1]; - RasColor[ALP_C] = color[bpmem.tevksel[swaptable].swap2]; + RasColor.b = color[bpmem.tevksel[swaptable].swap1]; + RasColor.a = color[bpmem.tevksel[swaptable].swap2]; } 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 +95,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; } @@ -305,7 +179,7 @@ void Tev::DrawAlphaRegular(const TevStageCombiner::AlphaCombiner& ac, const Inpu temp; result = result >> m_ScaleRShiftLUT[u32(ac.scale.Value())]; - Reg[u32(ac.dest.Value())][ALP_C] = result; + Reg[u32(ac.dest.Value())].a = result; } void Tev::DrawAlphaCompare(const TevStageCombiner::AlphaCombiner& ac, const InputRegType inputs[4]) @@ -339,9 +213,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[u32(ac.dest.Value())].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[u32(ac.dest.Value())].a = inputs[ALP_C].d + ((a == b) ? inputs[ALP_C].c : 0); } static bool AlphaCompare(int alpha, int ref, CompareMode comp) @@ -548,10 +422,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[i].r = PixelShaderManager::constants.colors[i][0]; + Reg[i].g = PixelShaderManager::constants.colors[i][1]; + Reg[i].b = PixelShaderManager::constants.colors[i][2]; + Reg[i].a = PixelShaderManager::constants.colors[i][3]; } for (unsigned int stageNum = 0; stageNum < bpmem.genMode.numindstages; stageNum++) @@ -634,37 +508,42 @@ void Tev::Draw() int swaptable = ac.tswap * 2; - TexColor[RED_C] = texel[bpmem.tevksel[swaptable].swap1]; - TexColor[GRN_C] = texel[bpmem.tevksel[swaptable].swap2]; + TexColor.r = texel[bpmem.tevksel[swaptable].swap1]; + TexColor.g = texel[bpmem.tevksel[swaptable].swap2]; swaptable++; - TexColor[BLU_C] = texel[bpmem.tevksel[swaptable].swap1]; - TexColor[ALP_C] = texel[bpmem.tevksel[swaptable].swap2]; + TexColor.b = texel[bpmem.tevksel[swaptable].swap1]; + TexColor.a = texel[bpmem.tevksel[swaptable].swap2]; } // 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 = kSel.getKC(stageOdd); + const auto ka = kSel.getKA(stageOdd); + 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); // 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 +552,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[u32(cc.dest.Value())].r = Clamp255(Reg[u32(cc.dest.Value())].r); + Reg[u32(cc.dest.Value())].g = Clamp255(Reg[u32(cc.dest.Value())].g); + Reg[u32(cc.dest.Value())].b = Clamp255(Reg[u32(cc.dest.Value())].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[u32(cc.dest.Value())].r = Clamp1024(Reg[u32(cc.dest.Value())].r); + Reg[u32(cc.dest.Value())].g = Clamp1024(Reg[u32(cc.dest.Value())].g); + Reg[u32(cc.dest.Value())].b = Clamp1024(Reg[u32(cc.dest.Value())].b); } if (ac.bias != TevBias::Compare) @@ -690,14 +569,14 @@ 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[u32(ac.dest.Value())].a = Clamp255(Reg[u32(ac.dest.Value())].a); else - Reg[u32(ac.dest.Value())][ALP_C] = Clamp1024(Reg[u32(ac.dest.Value())][ALP_C]); + Reg[u32(ac.dest.Value())].a = Clamp1024(Reg[u32(ac.dest.Value())].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[0].r, (u8)Reg[0].g, (u8)Reg[0].b, (u8)Reg[0].a}; DebugUtil::DrawTempBuffer(stage, DIRECT + stageNum); } #endif @@ -708,8 +587,8 @@ void Tev::Draw() // 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]}; + u8 output[4] = {(u8)Reg[alpha_index].a, (u8)Reg[color_index].r, (u8)Reg[color_index].g, + (u8)Reg[color_index].b}; if (!TevAlphaTest(output[ALP_C])) return; diff --git a/Source/Core/VideoBackends/Software/Tev.h b/Source/Core/VideoBackends/Software/Tev.h index 9c18afbd23..79e03a0ab0 100644 --- a/Source/Core/VideoBackends/Software/Tev.h +++ b/Source/Core/VideoBackends/Software/Tev.h @@ -3,10 +3,90 @@ #pragma once +#include + +#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,33 +102,97 @@ 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]; + std::array Reg; + std::array 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]; + const Common::EnumMap m_ColorInputLUT{ + TevColorRef::Color(Reg[0]), // prev.rgb + TevColorRef::Alpha(Reg[0]), // prev.aaa + TevColorRef::Color(Reg[1]), // c0.rgb + TevColorRef::Alpha(Reg[1]), // c0.aaa + TevColorRef::Color(Reg[2]), // c1.rgb + TevColorRef::Alpha(Reg[2]), // c1.aaa + TevColorRef::Color(Reg[3]), // c2.rgb + TevColorRef::Alpha(Reg[3]), // 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 m_AlphaInputLUT{ + TevAlphaRef(Reg[0]), // prev + TevAlphaRef(Reg[1]), // c0 + TevAlphaRef(Reg[2]), // c1 + TevAlphaRef(Reg[3]), // c2 + TevAlphaRef(TexColor), // tex + TevAlphaRef(RasColor), // ras + TevAlphaRef(StageKonst), // konst + TevAlphaRef(V0), // zero + }; + const Common::EnumMap 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 + }; 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, From b02992548e2582a5ce5f23991614f471da70e1a2 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Tue, 21 Dec 2021 18:03:47 -0800 Subject: [PATCH 03/14] SW/Tev: Use EnumMap for Reg --- Source/Core/VideoBackends/Software/Tev.cpp | 47 ++++++++++---------- Source/Core/VideoBackends/Software/Tev.h | 50 +++++++++++----------- 2 files changed, 49 insertions(+), 48 deletions(-) diff --git a/Source/Core/VideoBackends/Software/Tev.cpp b/Source/Core/VideoBackends/Software/Tev.cpp index f5aa1450c8..4bd54b5a8e 100644 --- a/Source/Core/VideoBackends/Software/Tev.cpp +++ b/Source/Core/VideoBackends/Software/Tev.cpp @@ -120,7 +120,7 @@ void Tev::DrawColorRegular(const TevStageCombiner::ColorCombiner& cc, const Inpu temp; result = result >> m_ScaleRShiftLUT[u32(cc.scale.Value())]; - Reg[u32(cc.dest.Value())][i] = result; + Reg[cc.dest][i] = result; } } @@ -157,9 +157,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); } } @@ -179,7 +179,7 @@ void Tev::DrawAlphaRegular(const TevStageCombiner::AlphaCombiner& ac, const Inpu temp; result = result >> m_ScaleRShiftLUT[u32(ac.scale.Value())]; - Reg[u32(ac.dest.Value())].a = result; + Reg[ac.dest].a = result; } void Tev::DrawAlphaCompare(const TevStageCombiner::AlphaCombiner& ac, const InputRegType inputs[4]) @@ -213,9 +213,9 @@ void Tev::DrawAlphaCompare(const TevStageCombiner::AlphaCombiner& ac, const Inpu } if (ac.comparison == TevComparison::GT) - Reg[u32(ac.dest.Value())].a = 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())].a = 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) @@ -422,10 +422,10 @@ void Tev::Draw() // initial color values for (int i = 0; i < 4; i++) { - Reg[i].r = PixelShaderManager::constants.colors[i][0]; - Reg[i].g = PixelShaderManager::constants.colors[i][1]; - Reg[i].b = PixelShaderManager::constants.colors[i][2]; - Reg[i].a = PixelShaderManager::constants.colors[i][3]; + Reg[static_cast(i)].r = PixelShaderManager::constants.colors[i][0]; + Reg[static_cast(i)].g = PixelShaderManager::constants.colors[i][1]; + Reg[static_cast(i)].b = PixelShaderManager::constants.colors[i][2]; + Reg[static_cast(i)].a = PixelShaderManager::constants.colors[i][3]; } for (unsigned int stageNum = 0; stageNum < bpmem.genMode.numindstages; stageNum++) @@ -552,15 +552,15 @@ void Tev::Draw() if (cc.clamp) { - Reg[u32(cc.dest.Value())].r = Clamp255(Reg[u32(cc.dest.Value())].r); - Reg[u32(cc.dest.Value())].g = Clamp255(Reg[u32(cc.dest.Value())].g); - Reg[u32(cc.dest.Value())].b = Clamp255(Reg[u32(cc.dest.Value())].b); + 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())].r = Clamp1024(Reg[u32(cc.dest.Value())].r); - Reg[u32(cc.dest.Value())].g = Clamp1024(Reg[u32(cc.dest.Value())].g); - Reg[u32(cc.dest.Value())].b = Clamp1024(Reg[u32(cc.dest.Value())].b); + 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) @@ -569,14 +569,15 @@ void Tev::Draw() DrawAlphaCompare(ac, inputs); if (ac.clamp) - Reg[u32(ac.dest.Value())].a = Clamp255(Reg[u32(ac.dest.Value())].a); + Reg[ac.dest].a = Clamp255(Reg[ac.dest].a); else - Reg[u32(ac.dest.Value())].a = Clamp1024(Reg[u32(ac.dest.Value())].a); + Reg[ac.dest].a = Clamp1024(Reg[ac.dest].a); #if ALLOW_TEV_DUMPS if (g_ActiveConfig.bDumpTevStages) { - u8 stage[4] = {(u8)Reg[0].r, (u8)Reg[0].g, (u8)Reg[0].b, (u8)Reg[0].a}; + 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 @@ -585,10 +586,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].a, (u8)Reg[color_index].r, (u8)Reg[color_index].g, - (u8)Reg[color_index].b}; + 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; diff --git a/Source/Core/VideoBackends/Software/Tev.h b/Source/Core/VideoBackends/Software/Tev.h index 79e03a0ab0..da94f05172 100644 --- a/Source/Core/VideoBackends/Software/Tev.h +++ b/Source/Core/VideoBackends/Software/Tev.h @@ -102,7 +102,7 @@ class Tev }; // color order: ABGR - std::array Reg; + Common::EnumMap Reg; std::array KonstantColors; TevColor TexColor; TevColor RasColor; @@ -124,32 +124,32 @@ class Tev TextureCoordinateType TexCoord; const Common::EnumMap m_ColorInputLUT{ - TevColorRef::Color(Reg[0]), // prev.rgb - TevColorRef::Alpha(Reg[0]), // prev.aaa - TevColorRef::Color(Reg[1]), // c0.rgb - TevColorRef::Alpha(Reg[1]), // c0.aaa - TevColorRef::Color(Reg[2]), // c1.rgb - TevColorRef::Alpha(Reg[2]), // c1.aaa - TevColorRef::Color(Reg[3]), // c2.rgb - TevColorRef::Alpha(Reg[3]), // 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 + 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 m_AlphaInputLUT{ - TevAlphaRef(Reg[0]), // prev - TevAlphaRef(Reg[1]), // c0 - TevAlphaRef(Reg[2]), // c1 - TevAlphaRef(Reg[3]), // c2 - TevAlphaRef(TexColor), // tex - TevAlphaRef(RasColor), // ras - TevAlphaRef(StageKonst), // konst - TevAlphaRef(V0), // zero + 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 m_KonstLUT{ TevKonstRef::Value(V1), // 1 From c9936f8c1cd061c6b045c2223d4bb83c5eb9b6e0 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Tue, 21 Dec 2021 18:15:25 -0800 Subject: [PATCH 04/14] SW/Tev: Use EnumMap for scale/bias tables --- Source/Core/VideoBackends/Software/Tev.cpp | 30 +++++----------------- Source/Core/VideoBackends/Software/Tev.h | 6 ++--- 2 files changed, 9 insertions(+), 27 deletions(-) diff --git a/Source/Core/VideoBackends/Software/Tev.cpp b/Source/Core/VideoBackends/Software/Tev.cpp index 4bd54b5a8e..52a2ecebd0 100644 --- a/Source/Core/VideoBackends/Software/Tev.cpp +++ b/Source/Core/VideoBackends/Software/Tev.cpp @@ -29,20 +29,6 @@ void Tev::Init() { - 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) @@ -110,15 +96,13 @@ 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[cc.dest][i] = result; } @@ -170,14 +154,12 @@ 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[ac.dest].a = result; } diff --git a/Source/Core/VideoBackends/Software/Tev.h b/Source/Core/VideoBackends/Software/Tev.h index da94f05172..a9c54e8dd4 100644 --- a/Source/Core/VideoBackends/Software/Tev.h +++ b/Source/Core/VideoBackends/Software/Tev.h @@ -189,9 +189,9 @@ class Tev TevKonstRef::Value(KonstantColors[2].a), // Konst 2 Alpha TevKonstRef::Value(KonstantColors[3].a), // Konst 3 Alpha }; - s16 m_BiasLUT[4]; - u8 m_ScaleLShiftLUT[4]; - u8 m_ScaleRShiftLUT[4]; + static constexpr Common::EnumMap s_BiasLUT{0, 128, -128, 0}; + static constexpr Common::EnumMap s_ScaleLShiftLUT{0, 1, 2, 0}; + static constexpr Common::EnumMap s_ScaleRShiftLUT{0, 0, 0, 1}; enum BufferBase { From bae0f21f74b1c63beb95adb80b180f835963f066 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Tue, 21 Dec 2021 18:22:47 -0800 Subject: [PATCH 05/14] SW/Tev: Remove Tev::Init --- Source/Core/VideoBackends/Software/Rasterizer.cpp | 2 -- Source/Core/VideoBackends/Software/Tev.cpp | 4 ---- Source/Core/VideoBackends/Software/Tev.h | 2 -- 3 files changed, 8 deletions(-) diff --git a/Source/Core/VideoBackends/Software/Rasterizer.cpp b/Source/Core/VideoBackends/Software/Rasterizer.cpp index 2a341d8093..e27d1a49b0 100644 --- a/Source/Core/VideoBackends/Software/Rasterizer.cpp +++ b/Source/Core/VideoBackends/Software/Rasterizer.cpp @@ -108,8 +108,6 @@ static std::vector 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(); diff --git a/Source/Core/VideoBackends/Software/Tev.cpp b/Source/Core/VideoBackends/Software/Tev.cpp index 52a2ecebd0..6dd3a2aa56 100644 --- a/Source/Core/VideoBackends/Software/Tev.cpp +++ b/Source/Core/VideoBackends/Software/Tev.cpp @@ -27,10 +27,6 @@ #define ALLOW_TEV_DUMPS 0 #endif -void Tev::Init() -{ -} - static inline s16 Clamp255(s16 in) { return in > 255 ? 255 : (in < 0 ? 0 : in); diff --git a/Source/Core/VideoBackends/Software/Tev.h b/Source/Core/VideoBackends/Software/Tev.h index a9c54e8dd4..422bbb9fff 100644 --- a/Source/Core/VideoBackends/Software/Tev.h +++ b/Source/Core/VideoBackends/Software/Tev.h @@ -226,8 +226,6 @@ public: RED_C }; - void Init(); - void Draw(); void SetRegColor(int reg, int comp, s16 color); From 3b9a048291bd9edeb69cb8c074ac3cbba3744531 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Tue, 21 Dec 2021 18:23:39 -0800 Subject: [PATCH 06/14] SW/Tev: Use std::clamp for Clamp255 and Clamp1024 --- Source/Core/VideoBackends/Software/Tev.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Core/VideoBackends/Software/Tev.cpp b/Source/Core/VideoBackends/Software/Tev.cpp index 6dd3a2aa56..f1fecdab40 100644 --- a/Source/Core/VideoBackends/Software/Tev.cpp +++ b/Source/Core/VideoBackends/Software/Tev.cpp @@ -29,12 +29,12 @@ static inline s16 Clamp255(s16 in) { - return in > 255 ? 255 : (in < 0 ? 0 : in); + return std::clamp(in, 0, 255); } static inline s16 Clamp1024(s16 in) { - return in > 1023 ? 1023 : (in < -1024 ? -1024 : in); + return std::clamp(in, -1024, 1023); } void Tev::SetRasColor(RasColorChan colorChan, int swaptable) From ae0fcd9a9f495bb11820545ae46dbe0827328b6b Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Sun, 26 Dec 2021 13:24:47 -0800 Subject: [PATCH 07/14] SW/Tev: Replace Tev::SetRegColor with Tev::SetKonstColors --- Source/Core/VideoBackends/Software/Rasterizer.cpp | 4 ++-- Source/Core/VideoBackends/Software/Rasterizer.h | 2 +- Source/Core/VideoBackends/Software/SWVertexLoader.cpp | 10 +--------- Source/Core/VideoBackends/Software/Tev.cpp | 10 ++++++++-- Source/Core/VideoBackends/Software/Tev.h | 3 +-- 5 files changed, 13 insertions(+), 16 deletions(-) diff --git a/Source/Core/VideoBackends/Software/Rasterizer.cpp b/Source/Core/VideoBackends/Software/Rasterizer.cpp index e27d1a49b0..c302203015 100644 --- a/Source/Core/VideoBackends/Software/Rasterizer.cpp +++ b/Source/Core/VideoBackends/Software/Rasterizer.cpp @@ -140,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) diff --git a/Source/Core/VideoBackends/Software/Rasterizer.h b/Source/Core/VideoBackends/Software/Rasterizer.h index 5edd8f76af..d9cd4a6b11 100644 --- a/Source/Core/VideoBackends/Software/Rasterizer.h +++ b/Source/Core/VideoBackends/Software/Rasterizer.h @@ -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 { diff --git a/Source/Core/VideoBackends/Software/SWVertexLoader.cpp b/Source/Core/VideoBackends/Software/SWVertexLoader.cpp index aaf91d9891..00357b12d7 100644 --- a/Source/Core/VideoBackends/Software/SWVertexLoader.cpp +++ b/Source/Core/VideoBackends/Software/SWVertexLoader.cpp @@ -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++) { diff --git a/Source/Core/VideoBackends/Software/Tev.cpp b/Source/Core/VideoBackends/Software/Tev.cpp index f1fecdab40..b85fdc0c3b 100644 --- a/Source/Core/VideoBackends/Software/Tev.cpp +++ b/Source/Core/VideoBackends/Software/Tev.cpp @@ -740,7 +740,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]; + } } diff --git a/Source/Core/VideoBackends/Software/Tev.h b/Source/Core/VideoBackends/Software/Tev.h index 422bbb9fff..efbeed0c69 100644 --- a/Source/Core/VideoBackends/Software/Tev.h +++ b/Source/Core/VideoBackends/Software/Tev.h @@ -226,7 +226,6 @@ public: RED_C }; + void SetKonstColors(); void Draw(); - - void SetRegColor(int reg, int comp, s16 color); }; From 4206ac243b1381bc02481ce7a4a69b02663a60ba Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Sun, 26 Dec 2021 16:16:13 -0800 Subject: [PATCH 08/14] SW/Rasterizer: Use RAS1_IREF::getTexCoord and getTexMap --- Source/Core/VideoBackends/Software/Rasterizer.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Source/Core/VideoBackends/Software/Rasterizer.cpp b/Source/Core/VideoBackends/Software/Rasterizer.cpp index c302203015..b27dc14c89 100644 --- a/Source/Core/VideoBackends/Software/Rasterizer.cpp +++ b/Source/Core/VideoBackends/Software/Rasterizer.cpp @@ -286,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); } From e43f02c7524be8d534389d10d349d4f8361ef4f2 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Sun, 26 Dec 2021 15:20:20 -0800 Subject: [PATCH 09/14] BPMemory: Improve consistency of hex offset comments I search for these somewhat often with control+f, but tend to default to adding a 0x prefix, which means I don't find them until I remove it. --- Source/Core/VideoCommon/BPMemory.h | 118 ++++++++++++++--------------- 1 file changed, 59 insertions(+), 59 deletions(-) diff --git a/Source/Core/VideoCommon/BPMemory.h b/Source/Core/VideoCommon/BPMemory.h index 641118417a..da8a2d9c4e 100644 --- a/Source/Core/VideoCommon/BPMemory.h +++ b/Source/Core/VideoCommon/BPMemory.h @@ -2350,70 +2350,70 @@ enum class EmulatedZ : u32 struct BPMemory { - GenMode genMode; - u32 display_copy_filter[4]; // 01-04 - u32 unknown; // 05 + GenMode genMode; // 0x00 + u32 display_copy_filter[4]; // 0x01-0x04 + u32 unknown; // 0x05 // indirect matrices (set by GXSetIndTexMtx, selected by TevStageIndirect::matrix_index) // abc form a 2x3 offset matrix, there's 3 such matrices // the 3 offset matrices can either be indirect type, S-type, or T-type // 6bit scale factor s is distributed across IND_MTXA/B/C. // before using matrices scale by 2^-(s-17) - IND_MTX indmtx[3]; // 06-0e GXSetIndTexMtx, 2x3 matrices - IND_IMASK imask; // 0f - TevStageIndirect tevind[16]; // 10 GXSetTevIndirect - ScissorPos scissorTL; // 20 - ScissorPos scissorBR; // 21 - LPSize lineptwidth; // 22 line and point width - u32 sucounter; // 23 - u32 rascounter; // 24 - TEXSCALE texscale[2]; // 25-26 GXSetIndTexCoordScale - RAS1_IREF tevindref; // 27 GXSetIndTexOrder - TwoTevStageOrders tevorders[8]; // 28-2F - TCoordInfo texcoords[8]; // 0x30 s,t,s,t,s,t,s,t... - ZMode zmode; // 40 - BlendMode blendmode; // 41 - ConstantAlpha dstalpha; // 42 - PEControl zcontrol; // 43 GXSetZCompLoc, GXPixModeSync - FieldMask fieldmask; // 44 - u32 drawdone; // 45, bit1=1 if end of list - u32 unknown5; // 46 clock? - u32 petoken; // 47 - u32 petokenint; // 48 - X10Y10 copyTexSrcXY; // 49 - X10Y10 copyTexSrcWH; // 4a - u32 copyTexDest; // 4b// 4b == CopyAddress (GXDispCopy and GXTexCopy use it) - u32 unknown6; // 4c - u32 copyMipMapStrideChannels; // 4d usually set to 4 when dest is single channel, 8 when dest is - // 2 channel, 16 when dest is RGBA - // also, doubles whenever mipmap box filter option is set (excent on RGBA). Probably to do with - // number of bytes to look at when smoothing - u32 dispcopyyscale; // 4e - u32 clearcolorAR; // 4f - u32 clearcolorGB; // 50 - u32 clearZValue; // 51 - UPE_Copy triggerEFBCopy; // 52 - CopyFilterCoefficients copyfilter; // 53,54 - u32 boundbox0; // 55 - u32 boundbox1; // 56 - u32 unknown7[2]; // 57,58 - ScissorOffset scissorOffset; // 59 - u32 unknown8[6]; // 5a,5b,5c,5d, 5e,5f - BPS_TmemConfig tmem_config; // 60-66 - u32 metric; // 67 - FieldMode fieldmode; // 68 - u32 unknown10[7]; // 69-6F - u32 unknown11[16]; // 70-7F - AllTexUnits tex; // 80-bf - TevStageCombiner combiners[16]; // 0xC0-0xDF - TevReg tevregs[4]; // 0xE0 - FogRangeParams fogRange; // 0xE8 - FogParams fog; // 0xEE,0xEF,0xF0,0xF1,0xF2 - AlphaTest alpha_test; // 0xF3 - ZTex1 ztex1; // 0xf4,0xf5 - ZTex2 ztex2; - TevKSel tevksel[8]; // 0xf6,0xf7,f8,f9,fa,fb,fc,fd - u32 bpMask; // 0xFE - u32 unknown18; // ff + IND_MTX indmtx[3]; // 0x06-0x0e: GXSetIndTexMtx, 2x3 matrices + IND_IMASK imask; // 0x0f + TevStageIndirect tevind[16]; // 0x10-0x1f: GXSetTevIndirect + ScissorPos scissorTL; // 0x20 + ScissorPos scissorBR; // 0x21 + LPSize lineptwidth; // 0x22 + u32 sucounter; // 0x23 + u32 rascounter; // 0x24 + TEXSCALE texscale[2]; // 0x25,0x26: GXSetIndTexCoordScale + RAS1_IREF tevindref; // 0x27: GXSetIndTexOrder + TwoTevStageOrders tevorders[8]; // 0x28-0x2f + TCoordInfo texcoords[8]; // 0x30-0x4f: s,t,s,t,s,t,s,t... + ZMode zmode; // 0x40 + BlendMode blendmode; // 0x41 + ConstantAlpha dstalpha; // 0x42 + PEControl zcontrol; // 0x43: GXSetZCompLoc, GXPixModeSync + FieldMask fieldmask; // 0x44 + u32 drawdone; // 0x45: bit1=1 if end of list + u32 unknown5; // 0x46: clock? + u32 petoken; // 0x47 + u32 petokenint; // 0x48 + X10Y10 copyTexSrcXY; // 0x49 + X10Y10 copyTexSrcWH; // 0x4a + u32 copyTexDest; // 0x4b: CopyAddress (GXDispCopy and GXTexCopy use it) + u32 unknown6; // 0x4c + // usually set to 4 when dest is single channel, 8 when dest is 2 channel, 16 when dest is RGBA + // also, doubles whenever mipmap box filter option is set (excent on RGBA). Probably to do + // with number of bytes to look at when smoothing + u32 copyMipMapStrideChannels; // 0x4d + u32 dispcopyyscale; // 0x4e + u32 clearcolorAR; // 0x4f + u32 clearcolorGB; // 0x50 + u32 clearZValue; // 0x51 + UPE_Copy triggerEFBCopy; // 0x52 + CopyFilterCoefficients copyfilter; // 0x53,0x54 + u32 boundbox0; // 0x55 + u32 boundbox1; // 0x56 + u32 unknown7[2]; // 0x57,0x58 + ScissorOffset scissorOffset; // 0x59 + u32 unknown8[6]; // 0x5a-0x5f + BPS_TmemConfig tmem_config; // 0x60-0x66 + u32 metric; // 0x67 + FieldMode fieldmode; // 0x68 + u32 unknown10[7]; // 0x69-0x6f + u32 unknown11[16]; // 0x70-0x7f + AllTexUnits tex; // 0x80-0xbf + TevStageCombiner combiners[16]; // 0xc0-0xdf + TevReg tevregs[4]; // 0xe0-0xe7 + FogRangeParams fogRange; // 0xe8-0xed + FogParams fog; // 0xee-0xf2 + AlphaTest alpha_test; // 0xf3 + ZTex1 ztex1; // 0xf4 + ZTex2 ztex2; // 0xf5 + TevKSel tevksel[8]; // 0xf6-0xfd + u32 bpMask; // 0xfe + u32 unknown18; // 0xff EmulatedZ GetEmulatedZ() const { From f21798b9b6680aa79e0a2eec322cba93dde497b2 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Sun, 26 Dec 2021 16:25:56 -0800 Subject: [PATCH 10/14] BPMemory: Use even/odd in TwoTevStageOrders instead of 0/1 --- Source/Core/VideoCommon/BPMemory.h | 34 ++++++++++++--------- Source/Core/VideoCommon/UberShaderPixel.cpp | 11 ++++--- 2 files changed, 25 insertions(+), 20 deletions(-) diff --git a/Source/Core/VideoCommon/BPMemory.h b/Source/Core/VideoCommon/BPMemory.h index da8a2d9c4e..89c47d9dfe 100644 --- a/Source/Core/VideoCommon/BPMemory.h +++ b/Source/Core/VideoCommon/BPMemory.h @@ -777,21 +777,24 @@ struct fmt::formatter : EnumFormatter union TwoTevStageOrders { - BitField<0, 3, u32> texmap0; // Indirect tex stage texmap - BitField<3, 3, u32> texcoord0; - BitField<6, 1, bool, u32> enable0; // true if should read from texture - BitField<7, 3, RasColorChan> colorchan0; + BitField<0, 3, u32> texmap_even; + BitField<3, 3, u32> texcoord_even; + BitField<6, 1, bool, u32> enable_tex_even; // true if should read from texture + BitField<7, 3, RasColorChan> colorchan_even; - BitField<12, 3, u32> texmap1; - BitField<15, 3, u32> texcoord1; - BitField<18, 1, bool, u32> enable1; // true if should read from texture - BitField<19, 3, RasColorChan> colorchan1; + BitField<12, 3, u32> texmap_odd; + BitField<15, 3, u32> texcoord_odd; + BitField<18, 1, bool, u32> enable_tex_odd; // true if should read from texture + BitField<19, 3, RasColorChan> colorchan_odd; u32 hex; - u32 getTexMap(int i) const { return i ? texmap1.Value() : texmap0.Value(); } - u32 getTexCoord(int i) const { return i ? texcoord1.Value() : texcoord0.Value(); } - u32 getEnable(int i) const { return i ? enable1.Value() : enable0.Value(); } - RasColorChan getColorChan(int i) const { return i ? colorchan1.Value() : colorchan0.Value(); } + u32 getTexMap(int i) const { return i ? texmap_odd.Value() : texmap_even.Value(); } + u32 getTexCoord(int i) const { return i ? texcoord_odd.Value() : texcoord_even.Value(); } + u32 getEnable(int i) const { return i ? enable_tex_odd.Value() : enable_tex_even.Value(); } + RasColorChan getColorChan(int i) const + { + return i ? colorchan_odd.Value() : colorchan_even.Value(); + } }; template <> struct fmt::formatter @@ -805,9 +808,10 @@ struct fmt::formatter "Stage 0 enable texmap: {}\nStage 0 color channel: {}\n" "Stage 1 texmap: {}\nStage 1 tex coord: {}\n" "Stage 1 enable texmap: {}\nStage 1 color channel: {}\n", - stages.texmap0, stages.texcoord0, stages.enable0 ? "Yes" : "No", - stages.colorchan0, stages.texmap1, stages.texcoord1, - stages.enable1 ? "Yes" : "No", stages.colorchan1); + stages.texmap_even, stages.texcoord_even, + stages.enable_tex_even ? "Yes" : "No", stages.colorchan_even, + stages.texmap_odd, stages.texcoord_odd, + stages.enable_tex_odd ? "Yes" : "No", stages.colorchan_odd); } }; diff --git a/Source/Core/VideoCommon/UberShaderPixel.cpp b/Source/Core/VideoCommon/UberShaderPixel.cpp index 22708f3d66..2561e801bc 100644 --- a/Source/Core/VideoCommon/UberShaderPixel.cpp +++ b/Source/Core/VideoCommon/UberShaderPixel.cpp @@ -581,7 +581,8 @@ ShaderCode GenPixelShader(APIType api_type, const ShaderHostConfig& host_config, " ss.order = bpmem_tevorder(stage>>1);\n" " if ((stage & 1u) == 1u)\n" " ss.order = ss.order >> {};\n\n", - int(TwoTevStageOrders().enable1.StartBit() - TwoTevStageOrders().enable0.StartBit())); + int(TwoTevStageOrders().enable_tex_odd.StartBit() - + TwoTevStageOrders().enable_tex_even.StartBit())); // Disable texturing when there are no texgens (for now) if (numTexgen != 0) @@ -596,11 +597,11 @@ ShaderCode GenPixelShader(APIType api_type, const ShaderHostConfig& host_config, out.Write("\n" " uint tex_coord = {};\n", - BitfieldExtract<&TwoTevStageOrders::texcoord0>("ss.order")); + BitfieldExtract<&TwoTevStageOrders::texcoord_even>("ss.order")); out.Write(" int2 fixedPoint_uv = getTexCoord(tex_coord);\n" "\n" " bool texture_enabled = (ss.order & {}u) != 0u;\n", - 1 << TwoTevStageOrders().enable0.StartBit()); + 1 << TwoTevStageOrders().enable_tex_even.StartBit()); out.Write("\n" " // Indirect textures\n" " uint tevind = bpmem_tevind(stage);\n" @@ -712,7 +713,7 @@ ShaderCode GenPixelShader(APIType api_type, const ShaderHostConfig& host_config, " // Sample texture for stage\n" " if (texture_enabled) {{\n" " uint sampler_num = {};\n", - BitfieldExtract<&TwoTevStageOrders::texmap0>("ss.order")); + BitfieldExtract<&TwoTevStageOrders::texmap_even>("ss.order")); out.Write("\n" " int4 color = sampleTextureWrapper(sampler_num, tevcoord.xy, layer);\n" " uint swap = {};\n", @@ -1216,7 +1217,7 @@ ShaderCode GenPixelShader(APIType api_type, const ShaderHostConfig& host_config, "int4 getRasColor(State s, StageState ss, float4 colors_0, float4 colors_1) {{\n" " // Select Ras for stage\n" " uint ras = {};\n", - BitfieldExtract<&TwoTevStageOrders::colorchan0>("ss.order")); + BitfieldExtract<&TwoTevStageOrders::colorchan_even>("ss.order")); out.Write(" if (ras < 2u) {{ // Lighting Channel 0 or 1\n" " int4 color = iround(((ras == 0u) ? colors_0 : colors_1) * 255.0);\n" " uint swap = {};\n", From 5ef8a7973e7b229de77c63d1d7ec4d8eb97a9041 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Sun, 26 Dec 2021 19:21:15 -0800 Subject: [PATCH 11/14] BPMemory: Make TevKSel more clear It stores both the konst selection value for alpha and color channels (for two tev stages per ksel), and half of a swap table row (there are 4 total swap tables, which can be used for swizzling the rasterized color and the texture color, and indices selecting which tables to use are stored per tev stage in the alpha combiner). Since these are indexed very differently, the old code was hard to follow. --- Source/Core/VideoBackends/Software/Tev.cpp | 41 +++++++------- Source/Core/VideoBackends/Software/Tev.h | 2 +- Source/Core/VideoCommon/BPMemory.h | 63 +++++++++++++++++---- Source/Core/VideoCommon/PixelShaderGen.cpp | 52 +++++++---------- Source/Core/VideoCommon/PixelShaderGen.h | 21 +++---- Source/Core/VideoCommon/UberShaderPixel.cpp | 16 +++--- 6 files changed, 111 insertions(+), 84 deletions(-) diff --git a/Source/Core/VideoBackends/Software/Tev.cpp b/Source/Core/VideoBackends/Software/Tev.cpp index b85fdc0c3b..e788d55d92 100644 --- a/Source/Core/VideoBackends/Software/Tev.cpp +++ b/Source/Core/VideoBackends/Software/Tev.cpp @@ -37,28 +37,28 @@ static inline s16 Clamp1024(s16 in) return std::clamp(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.r = color[bpmem.tevksel[swaptable].swap1]; - RasColor.g = color[bpmem.tevksel[swaptable].swap2]; - swaptable++; - RasColor.b = color[bpmem.tevksel[swaptable].swap1]; - RasColor.a = 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.r = color[bpmem.tevksel[swaptable].swap1]; - RasColor.g = color[bpmem.tevksel[swaptable].swap2]; - swaptable++; - RasColor.b = color[bpmem.tevksel[swaptable].swap1]; - RasColor.a = 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: @@ -445,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; @@ -484,25 +483,23 @@ void Tev::Draw() DebugUtil::DrawTempBuffer(texel, DIRECT_TFETCH + stageNum); #endif - int swaptable = ac.tswap * 2; - - TexColor.r = texel[bpmem.tevksel[swaptable].swap1]; - TexColor.g = texel[bpmem.tevksel[swaptable].swap2]; - swaptable++; - TexColor.b = texel[bpmem.tevksel[swaptable].swap1]; - TexColor.a = 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 = kSel.getKC(stageOdd); - const auto ka = kSel.getKA(stageOdd); + 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]; diff --git a/Source/Core/VideoBackends/Software/Tev.h b/Source/Core/VideoBackends/Software/Tev.h index efbeed0c69..c4e5e1f45f 100644 --- a/Source/Core/VideoBackends/Software/Tev.h +++ b/Source/Core/VideoBackends/Software/Tev.h @@ -200,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]); diff --git a/Source/Core/VideoCommon/BPMemory.h b/Source/Core/VideoCommon/BPMemory.h index 89c47d9dfe..285c45f95e 100644 --- a/Source/Core/VideoCommon/BPMemory.h +++ b/Source/Core/VideoCommon/BPMemory.h @@ -11,6 +11,7 @@ #include "Common/BitUtils.h" #include "Common/CommonTypes.h" #include "Common/EnumFormatter.h" +#include "Common/EnumMap.h" #include "Common/Inline.h" // X.h defines None to be 0 and Always to be 2, which causes problems with some of the enums @@ -1838,6 +1839,19 @@ struct fmt::formatter } }; +enum class ColorChannel : u32 +{ + Red = 0, + Green = 1, + Blue = 2, + Alpha = 3, +}; +template <> +struct fmt::formatter : EnumFormatter +{ + formatter() : EnumFormatter({"Red", "Green", "Blue", "Alpha"}) {} +}; + enum class KonstSel : u32 { V1 = 0, @@ -1912,16 +1926,13 @@ struct fmt::formatter : EnumFormatter union TevKSel { - BitField<0, 2, u32> swap1; - BitField<2, 2, u32> swap2; - BitField<4, 5, KonstSel> kcsel0; - BitField<9, 5, KonstSel> kasel0; - BitField<14, 5, KonstSel> kcsel1; - BitField<19, 5, KonstSel> kasel1; + BitField<0, 2, ColorChannel> swap_rb; // Odd ksel number: red; even: blue + BitField<2, 2, ColorChannel> swap_ga; // Odd ksel number: green; even: alpha + BitField<4, 5, KonstSel> kcsel_even; + BitField<9, 5, KonstSel> kasel_even; + BitField<14, 5, KonstSel> kcsel_odd; + BitField<19, 5, KonstSel> kasel_odd; u32 hex; - - KonstSel getKC(int i) const { return i ? kcsel1.Value() : kcsel0.Value(); } - KonstSel getKA(int i) const { return i ? kasel1.Value() : kasel0.Value(); } }; template <> struct fmt::formatter @@ -1933,8 +1944,36 @@ struct fmt::formatter return fmt::format_to(ctx.out(), "Swap 1: {}\nSwap 2: {}\nColor sel 0: {}\nAlpha sel 0: {}\n" "Color sel 1: {}\nAlpha sel 1: {}", - ksel.swap1, ksel.swap2, ksel.kcsel0, ksel.kasel0, ksel.kcsel1, - ksel.kasel1); + ksel.swap_rb, ksel.swap_ga, ksel.kcsel_even, ksel.kasel_even, + ksel.kcsel_odd, ksel.kasel_odd); + } +}; + +struct AllTevKSels +{ + std::array ksel; + + KonstSel GetKonstColor(u32 tev_stage) const + { + const u32 ksel_num = tev_stage >> 1; + const bool odd = tev_stage & 1; + const auto& cur_ksel = ksel[ksel_num]; + return odd ? cur_ksel.kcsel_odd.Value() : cur_ksel.kcsel_even.Value(); + } + KonstSel GetKonstAlpha(u32 tev_stage) const + { + const u32 ksel_num = tev_stage >> 1; + const bool odd = tev_stage & 1; + const auto& cur_ksel = ksel[ksel_num]; + return odd ? cur_ksel.kasel_odd.Value() : cur_ksel.kasel_even.Value(); + } + Common::EnumMap GetSwapTable(u32 swap_table_id) const + { + const u32 rg_ksel_num = swap_table_id << 1; + const u32 ba_ksel_num = rg_ksel_num + 1; + const auto& rg_ksel = ksel[rg_ksel_num]; + const auto& ba_ksel = ksel[ba_ksel_num]; + return {rg_ksel.swap_rb, rg_ksel.swap_ga, ba_ksel.swap_rb, ba_ksel.swap_ga}; } }; @@ -2415,7 +2454,7 @@ struct BPMemory AlphaTest alpha_test; // 0xf3 ZTex1 ztex1; // 0xf4 ZTex2 ztex2; // 0xf5 - TevKSel tevksel[8]; // 0xf6-0xfd + AllTevKSels tevksel; // 0xf6-0xfd u32 bpMask; // 0xfe u32 unknown18; // 0xff diff --git a/Source/Core/VideoCommon/PixelShaderGen.cpp b/Source/Core/VideoCommon/PixelShaderGen.cpp index 79d2bd1d52..9eda40c8e5 100644 --- a/Source/Core/VideoCommon/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/PixelShaderGen.cpp @@ -167,6 +167,8 @@ constexpr Common::EnumMap tev_a_output_table{ "c2.a", }; +constexpr Common::EnumMap rgba_swizzle{'r', 'g', 'b', 'a'}; + PixelShaderUid GetPixelShaderUid() { PixelShaderUid out; @@ -254,22 +256,22 @@ PixelShaderUid GetPixelShaderUid() ac.a == TevAlphaArg::RasAlpha || ac.b == TevAlphaArg::RasAlpha || ac.c == TevAlphaArg::RasAlpha || ac.d == TevAlphaArg::RasAlpha) { - const int i = bpmem.combiners[n].alphaC.rswap; - uid_data->stagehash[n].tevksel_swap1a = bpmem.tevksel[i * 2].swap1; - uid_data->stagehash[n].tevksel_swap2a = bpmem.tevksel[i * 2].swap2; - uid_data->stagehash[n].tevksel_swap1b = bpmem.tevksel[i * 2 + 1].swap1; - uid_data->stagehash[n].tevksel_swap2b = bpmem.tevksel[i * 2 + 1].swap2; + const auto ras_swap_table = bpmem.tevksel.GetSwapTable(bpmem.combiners[n].alphaC.rswap); + uid_data->stagehash[n].ras_swap_r = ras_swap_table[ColorChannel::Red]; + uid_data->stagehash[n].ras_swap_g = ras_swap_table[ColorChannel::Green]; + uid_data->stagehash[n].ras_swap_b = ras_swap_table[ColorChannel::Blue]; + uid_data->stagehash[n].ras_swap_a = ras_swap_table[ColorChannel::Alpha]; uid_data->stagehash[n].tevorders_colorchan = bpmem.tevorders[n / 2].getColorChan(n & 1); } uid_data->stagehash[n].tevorders_enable = bpmem.tevorders[n / 2].getEnable(n & 1); if (uid_data->stagehash[n].tevorders_enable) { - const int i = bpmem.combiners[n].alphaC.tswap; - uid_data->stagehash[n].tevksel_swap1c = bpmem.tevksel[i * 2].swap1; - uid_data->stagehash[n].tevksel_swap2c = bpmem.tevksel[i * 2].swap2; - uid_data->stagehash[n].tevksel_swap1d = bpmem.tevksel[i * 2 + 1].swap1; - uid_data->stagehash[n].tevksel_swap2d = bpmem.tevksel[i * 2 + 1].swap2; + const auto tex_swap_table = bpmem.tevksel.GetSwapTable(bpmem.combiners[n].alphaC.tswap); + uid_data->stagehash[n].tex_swap_r = tex_swap_table[ColorChannel::Red]; + uid_data->stagehash[n].tex_swap_g = tex_swap_table[ColorChannel::Green]; + uid_data->stagehash[n].tex_swap_b = tex_swap_table[ColorChannel::Blue]; + uid_data->stagehash[n].tex_swap_a = tex_swap_table[ColorChannel::Alpha]; uid_data->stagehash[n].tevorders_texmap = bpmem.tevorders[n / 2].getTexMap(n & 1); } @@ -277,8 +279,8 @@ PixelShaderUid GetPixelShaderUid() cc.d == TevColorArg::Konst || ac.a == TevAlphaArg::Konst || ac.b == TevAlphaArg::Konst || ac.c == TevAlphaArg::Konst || ac.d == TevAlphaArg::Konst) { - uid_data->stagehash[n].tevksel_kc = bpmem.tevksel[n / 2].getKC(n & 1); - uid_data->stagehash[n].tevksel_ka = bpmem.tevksel[n / 2].getKA(n & 1); + uid_data->stagehash[n].tevksel_kc = bpmem.tevksel.GetKonstColor(n); + uid_data->stagehash[n].tevksel_ka = bpmem.tevksel.GetKonstAlpha(n); } } @@ -1412,30 +1414,18 @@ static void WriteStage(ShaderCode& out, const pixel_shader_uid_data* uid_data, i ac.c == TevAlphaArg::RasAlpha || ac.d == TevAlphaArg::RasAlpha) { // Generate swizzle string to represent the Ras color channel swapping - const char rasswap[5] = { - "rgba"[stage.tevksel_swap1a], - "rgba"[stage.tevksel_swap2a], - "rgba"[stage.tevksel_swap1b], - "rgba"[stage.tevksel_swap2b], - '\0', - }; - - out.Write("\trastemp = {}.{};\n", tev_ras_table[stage.tevorders_colorchan], rasswap); + out.Write("\trastemp = {}.{}{}{}{};\n", tev_ras_table[stage.tevorders_colorchan], + rgba_swizzle[stage.ras_swap_r], rgba_swizzle[stage.ras_swap_g], + rgba_swizzle[stage.ras_swap_b], rgba_swizzle[stage.ras_swap_a]); } if (stage.tevorders_enable && uid_data->genMode_numtexgens > 0) { // Generate swizzle string to represent the texture color channel swapping - const char texswap[5] = { - "rgba"[stage.tevksel_swap1c], - "rgba"[stage.tevksel_swap2c], - "rgba"[stage.tevksel_swap1d], - "rgba"[stage.tevksel_swap2d], - '\0', - }; - - out.Write("\ttextemp = sampleTextureWrapper({0}u, tevcoord.xy, layer).{1};\n", - stage.tevorders_texmap, texswap); + out.Write("\ttextemp = sampleTextureWrapper({}u, tevcoord.xy, layer).{}{}{}{};\n", + stage.tevorders_texmap, rgba_swizzle[stage.tex_swap_r], + rgba_swizzle[stage.tex_swap_g], rgba_swizzle[stage.tex_swap_b], + rgba_swizzle[stage.tex_swap_a]); } else if (uid_data->genMode_numtexgens == 0) { diff --git a/Source/Core/VideoCommon/PixelShaderGen.h b/Source/Core/VideoCommon/PixelShaderGen.h index 34e0239ddc..1cfe5a0ebc 100644 --- a/Source/Core/VideoCommon/PixelShaderGen.h +++ b/Source/Core/VideoCommon/PixelShaderGen.h @@ -125,7 +125,7 @@ struct pixel_shader_uid_data { // TODO: Can save a lot space by removing the padding bits u32 cc : 24; - u32 ac : 24; // tswap and rswap are left blank (encoded into the tevksel fields below) + u32 ac : 24; // tswap and rswap are left blank (decoded into the swap fields below) u32 tevorders_texmap : 3; u32 tevorders_texcoord : 3; @@ -133,18 +133,19 @@ struct pixel_shader_uid_data RasColorChan tevorders_colorchan : 3; u32 pad1 : 7; - // TODO: Clean up the swapXY mess + // TODO: We could save space by storing the 4 swap tables elsewhere and only storing references + // to which table is used (the tswap and rswap fields), instead of duplicating them here u32 tevind : 21; - u32 tevksel_swap1a : 2; - u32 tevksel_swap2a : 2; - u32 tevksel_swap1b : 2; - u32 tevksel_swap2b : 2; + ColorChannel ras_swap_r : 2; + ColorChannel ras_swap_g : 2; + ColorChannel ras_swap_b : 2; + ColorChannel ras_swap_a : 2; u32 pad2 : 2; - u32 tevksel_swap1c : 2; - u32 tevksel_swap2c : 2; - u32 tevksel_swap1d : 2; - u32 tevksel_swap2d : 2; + ColorChannel tex_swap_r : 2; + ColorChannel tex_swap_g : 2; + ColorChannel tex_swap_b : 2; + ColorChannel tex_swap_a : 2; KonstSel tevksel_kc : 5; KonstSel tevksel_ka : 5; u32 pad3 : 14; diff --git a/Source/Core/VideoCommon/UberShaderPixel.cpp b/Source/Core/VideoCommon/UberShaderPixel.cpp index 2561e801bc..4db8f40ea4 100644 --- a/Source/Core/VideoCommon/UberShaderPixel.cpp +++ b/Source/Core/VideoCommon/UberShaderPixel.cpp @@ -271,12 +271,12 @@ ShaderCode GenPixelShader(APIType api_type, const ShaderHostConfig& host_config, " // AKA: Color Channel Swapping\n" "\n" " int4 ret;\n"); - out.Write(" ret.r = color[{}];\n", BitfieldExtract<&TevKSel::swap1>("bpmem_tevksel(s * 2u)")); - out.Write(" ret.g = color[{}];\n", BitfieldExtract<&TevKSel::swap2>("bpmem_tevksel(s * 2u)")); + out.Write(" ret.r = color[{}];\n", BitfieldExtract<&TevKSel::swap_rb>("bpmem_tevksel(s * 2u)")); + out.Write(" ret.g = color[{}];\n", BitfieldExtract<&TevKSel::swap_ga>("bpmem_tevksel(s * 2u)")); out.Write(" ret.b = color[{}];\n", - BitfieldExtract<&TevKSel::swap1>("bpmem_tevksel(s * 2u + 1u)")); + BitfieldExtract<&TevKSel::swap_rb>("bpmem_tevksel(s * 2u + 1u)")); out.Write(" ret.a = color[{}];\n", - BitfieldExtract<&TevKSel::swap2>("bpmem_tevksel(s * 2u + 1u)")); + BitfieldExtract<&TevKSel::swap_ga>("bpmem_tevksel(s * 2u + 1u)")); out.Write(" return ret;\n" "}}\n\n"); @@ -1240,12 +1240,12 @@ ShaderCode GenPixelShader(APIType api_type, const ShaderHostConfig& host_config, " uint tevksel = bpmem_tevksel(ss.stage>>1);\n" " if ((ss.stage & 1u) == 0u)\n" " return int4(konstLookup[{}].rgb, konstLookup[{}].a);\n", - BitfieldExtract<&TevKSel::kcsel0>("tevksel"), - BitfieldExtract<&TevKSel::kasel0>("tevksel")); + BitfieldExtract<&TevKSel::kcsel_even>("tevksel"), + BitfieldExtract<&TevKSel::kasel_even>("tevksel")); out.Write(" else\n" " return int4(konstLookup[{}].rgb, konstLookup[{}].a);\n", - BitfieldExtract<&TevKSel::kcsel1>("tevksel"), - BitfieldExtract<&TevKSel::kasel1>("tevksel")); + BitfieldExtract<&TevKSel::kcsel_odd>("tevksel"), + BitfieldExtract<&TevKSel::kasel_odd>("tevksel")); out.Write("}}\n"); return out; From 546f9952a2875360c04368456742b2783634ec0d Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Sun, 26 Dec 2021 19:31:13 -0800 Subject: [PATCH 12/14] UberShaderPixel: Fix typo --- Source/Core/VideoCommon/UberShaderPixel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Core/VideoCommon/UberShaderPixel.cpp b/Source/Core/VideoCommon/UberShaderPixel.cpp index 4db8f40ea4..5bbd9f39af 100644 --- a/Source/Core/VideoCommon/UberShaderPixel.cpp +++ b/Source/Core/VideoCommon/UberShaderPixel.cpp @@ -1223,7 +1223,7 @@ ShaderCode GenPixelShader(APIType api_type, const ShaderHostConfig& host_config, " uint swap = {};\n", BitfieldExtract<&TevStageCombiner::AlphaCombiner::rswap>("ss.ac")); out.Write(" return Swizzle(swap, color);\n"); - out.Write(" }} else if (ras == 5u) {{ // Alpha Bumb\n" + out.Write(" }} else if (ras == 5u) {{ // Alpha Bump\n" " return int4(s.AlphaBump, s.AlphaBump, s.AlphaBump, s.AlphaBump);\n" " }} else if (ras == 6u) {{ // Normalzied Alpha Bump\n" " int normalized = s.AlphaBump | s.AlphaBump >> 5;\n" From 3fb09e32973884a86c61d88ab5b4ec9f09f1c0b8 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Sun, 26 Dec 2021 20:52:07 -0800 Subject: [PATCH 13/14] Fifo analyzer: Improve some BP descriptions Mainly, the improvements are passing in the current command ID so that e.g. stage numbers can be directly included, instead of saying 0/1 or even/odd. --- Source/Core/VideoCommon/BPMemory.h | 117 ++++++++++++++++---------- Source/Core/VideoCommon/BPStructs.cpp | 20 ++--- 2 files changed, 80 insertions(+), 57 deletions(-) diff --git a/Source/Core/VideoCommon/BPMemory.h b/Source/Core/VideoCommon/BPMemory.h index 285c45f95e..974e00dfa3 100644 --- a/Source/Core/VideoCommon/BPMemory.h +++ b/Source/Core/VideoCommon/BPMemory.h @@ -684,8 +684,8 @@ struct fmt::formatter "Clamp: {}\n" "Scale factor: {} / Compare mode: {}\n" "Dest: {}\n" - "Ras sel: {}\n" - "Tex sel: {}", + "Rasterized color swaptable: {}\n" + "Texture color swaptable: {}", ac.a, ac.b, ac.c, ac.d, ac.bias, ac.op, ac.comparison, ac.clamp ? "Yes" : "No", ac.scale, ac.compare_mode, ac.dest, ac.rswap, ac.tswap); @@ -798,19 +798,23 @@ union TwoTevStageOrders } }; template <> -struct fmt::formatter +struct fmt::formatter> { constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); } template - auto format(const TwoTevStageOrders& stages, FormatContext& ctx) const + auto format(const std::pair& p, FormatContext& ctx) const { + const auto& [cmd, stages] = p; + const u8 stage_even = (cmd - BPMEM_TREF) * 2; + const u8 stage_odd = stage_even + 1; + return fmt::format_to(ctx.out(), - "Stage 0 texmap: {}\nStage 0 tex coord: {}\n" - "Stage 0 enable texmap: {}\nStage 0 color channel: {}\n" - "Stage 1 texmap: {}\nStage 1 tex coord: {}\n" - "Stage 1 enable texmap: {}\nStage 1 color channel: {}\n", - stages.texmap_even, stages.texcoord_even, - stages.enable_tex_even ? "Yes" : "No", stages.colorchan_even, + "Stage {0} texmap: {1}\nStage {0} tex coord: {2}\n" + "Stage {0} enable texmap: {3}\nStage {0} rasterized color channel: {4}\n" + "Stage {5} texmap: {6}\nStage {5} tex coord: {7}\n" + "Stage {5} enable texmap: {8}\nStage {5} rasterized color channel: {9}\n", + stage_even, stages.texmap_even, stages.texcoord_even, + stages.enable_tex_even ? "Yes" : "No", stages.colorchan_even, stage_odd, stages.texmap_odd, stages.texcoord_odd, stages.enable_tex_odd ? "Yes" : "No", stages.colorchan_odd); } @@ -818,33 +822,38 @@ struct fmt::formatter union TEXSCALE { - BitField<0, 4, u32> ss0; // Indirect tex stage 0, 2^(-ss0) - BitField<4, 4, u32> ts0; // Indirect tex stage 0 - BitField<8, 4, u32> ss1; // Indirect tex stage 1 - BitField<12, 4, u32> ts1; // Indirect tex stage 1 + BitField<0, 4, u32> ss0; // Indirect tex stage 0 or 2, 2^(-ss0) + BitField<4, 4, u32> ts0; // Indirect tex stage 0 or 2 + BitField<8, 4, u32> ss1; // Indirect tex stage 1 or 3 + BitField<12, 4, u32> ts1; // Indirect tex stage 1 or 3 u32 hex; }; template <> -struct fmt::formatter +struct fmt::formatter> { constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); } template - auto format(const TEXSCALE& scale, FormatContext& ctx) const + auto format(const std::pair& p, FormatContext& ctx) const { + const auto& [cmd, scale] = p; + const u8 even = (cmd - BPMEM_RAS1_SS0) * 2; + const u8 odd_ = even + 1; + return fmt::format_to(ctx.out(), - "Even stage S scale: {} ({})\n" - "Even stage T scale: {} ({})\n" - "Odd stage S scale: {} ({})\n" - "Odd stage T scale: {} ({})", - scale.ss0, 1.f / (1 << scale.ss0), scale.ts0, 1.f / (1 << scale.ts0), - scale.ss1, 1.f / (1 << scale.ss1), scale.ts1, 1.f / (1 << scale.ts1)); + "Indirect stage {0} S coord scale: {1} ({2})\n" + "Indirect stage {0} T coord scale: {3} ({4})\n" + "Indirect stage {5} S coord scale: {6} ({7})\n" + "Indirect stage {5} T coord scale: {8} ({9})", + even, 1.f / (1 << scale.ss0), scale.ss0, 1.f / (1 << scale.ts0), + scale.ts0, odd_, 1.f / (1 << scale.ss1), scale.ss1, + 1.f / (1 << scale.ts1), scale.ts1); } }; union RAS1_IREF { - BitField<0, 3, u32> bi0; // Indirect tex stage 0 ntexmap - BitField<3, 3, u32> bc0; // Indirect tex stage 0 ntexcoord + BitField<0, 3, u32> bi0; // Indirect tex stage 0 texmap + BitField<3, 3, u32> bc0; // Indirect tex stage 0 tex coord BitField<6, 3, u32> bi1; BitField<9, 3, u32> bc1; BitField<12, 3, u32> bi2; @@ -863,12 +872,11 @@ struct fmt::formatter template auto format(const RAS1_IREF& indref, FormatContext& ctx) const { - // The field names here are suspicious, since there is no bi3 or bc2 return fmt::format_to(ctx.out(), - "Stage 0 ntexmap: {}\nStage 0 ntexcoord: {}\n" - "Stage 1 ntexmap: {}\nStage 1 ntexcoord: {}\n" - "Stage 2 ntexmap: {}\nStage 2 ntexcoord: {}\n" - "Stage 3 ntexmap: {}\nStage 3 ntexcoord: {}", + "Indirect stage 0 texmap: {}\nIndirect stage 0 tex coord: {}\n" + "Indirect stage 1 texmap: {}\nIndirect stage 1 tex coord: {}\n" + "Indirect stage 2 texmap: {}\nIndirect stage 2 tex coord: {}\n" + "Indirect stage 3 texmap: {}\nIndirect stage 3 tex coord: {}", indref.bi0, indref.bc0, indref.bi1, indref.bc1, indref.bi2, indref.bc2, indref.bi3, indref.bc3); } @@ -1748,21 +1756,27 @@ union TCInfo u32 hex; }; template <> -struct fmt::formatter +struct fmt::formatter> { constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); } template - auto format(const TCInfo& info, FormatContext& ctx) const + auto format(const std::pair& p, FormatContext& ctx) const { - return fmt::format_to(ctx.out(), - "Scale: {}\n" - "Range bias: {}\n" - "Cylindric wrap: {}\n" - "Use line offset: {} (s only)\n" - "Use point offset: {} (s only)", - info.scale_minus_1 + 1, info.range_bias ? "Yes" : "No", - info.cylindric_wrap ? "Yes" : "No", info.line_offset ? "Yes" : "No", - info.point_offset ? "Yes" : "No"); + const auto& [is_s, info] = p; + auto out = fmt::format_to(ctx.out(), + "{0} coord scale: {1}\n" + "{0} coord range bias: {2}\n" + "{0} coord cylindric wrap: {3}", + is_s ? 'S' : 'T', info.scale_minus_1 + 1, + info.range_bias ? "Yes" : "No", info.cylindric_wrap ? "Yes" : "No"); + if (is_s) + { + out = fmt::format_to(out, + "\nUse line offset: {}" + "\nUse point offset: {}", + info.line_offset ? "Yes" : "No", info.point_offset ? "Yes" : "No"); + } + return out; } }; @@ -1935,17 +1949,28 @@ union TevKSel u32 hex; }; template <> -struct fmt::formatter +struct fmt::formatter> { constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); } template - auto format(const TevKSel& ksel, FormatContext& ctx) const + auto format(const std::pair& p, FormatContext& ctx) const { + const auto& [cmd, ksel] = p; + const u8 swap_number = (cmd - BPMEM_TEV_KSEL) / 2; + const bool swap_ba = (cmd - BPMEM_TEV_KSEL) & 1; + const u8 even_stage = (cmd - BPMEM_TEV_KSEL) * 2; + const u8 odd_stage = even_stage + 1; + return fmt::format_to(ctx.out(), - "Swap 1: {}\nSwap 2: {}\nColor sel 0: {}\nAlpha sel 0: {}\n" - "Color sel 1: {}\nAlpha sel 1: {}", - ksel.swap_rb, ksel.swap_ga, ksel.kcsel_even, ksel.kasel_even, - ksel.kcsel_odd, ksel.kasel_odd); + "Swap table {0}: {1} channel comes from input's {2} channel\n" + "Swap table {0}: {3} channel comes from input's {4} channel\n" + "TEV stage {5} konst color: {6}\n" + "TEV stage {5} konst alpha: {7}\n" + "TEV stage {8} konst color: {9}\n" + "TEV stage {8} konst alpha: {10}", + swap_number, swap_ba ? "Blue" : "Red", ksel.swap_rb, + swap_ba ? "Alpha" : "Green", ksel.swap_ga, even_stage, ksel.kcsel_even, + ksel.kasel_even, odd_stage, ksel.kcsel_odd, ksel.kasel_odd); } }; diff --git a/Source/Core/VideoCommon/BPStructs.cpp b/Source/Core/VideoCommon/BPStructs.cpp index 010dbf6abe..b806bf654d 100644 --- a/Source/Core/VideoCommon/BPStructs.cpp +++ b/Source/Core/VideoCommon/BPStructs.cpp @@ -811,7 +811,7 @@ std::pair GetBPRegInfo(u8 cmd, u32 cmddata) case BPMEM_IND_CMD + 13: case BPMEM_IND_CMD + 14: case BPMEM_IND_CMD + 15: - return std::make_pair(fmt::format("BPMEM_IND_CMD command {}", cmd - BPMEM_IND_CMD), + return std::make_pair(fmt::format("BPMEM_IND_CMD number {}", cmd - BPMEM_IND_CMD), fmt::to_string(TevStageIndirect{.fullhex = cmddata})); case BPMEM_SCISSORTL: // 0x20 @@ -832,14 +832,12 @@ std::pair GetBPRegInfo(u8 cmd, u32 cmddata) // TODO: Description case BPMEM_RAS1_SS0: // 0x25 - return std::make_pair( - RegName(BPMEM_RAS1_SS0), - fmt::format("Indirect texture stages 0 and 1:\n{}", TEXSCALE{.hex = cmddata})); + return std::make_pair(RegName(BPMEM_RAS1_SS0), + fmt::to_string(std::make_pair(cmd, TEXSCALE{.hex = cmddata}))); case BPMEM_RAS1_SS1: // 0x26 - return std::make_pair( - RegName(BPMEM_RAS1_SS1), - fmt::format("Indirect texture stages 2 and 3:\n{}", TEXSCALE{.hex = cmddata})); + return std::make_pair(RegName(BPMEM_RAS1_SS1), + fmt::to_string(std::make_pair(cmd, TEXSCALE{.hex = cmddata}))); case BPMEM_IREF: // 0x27 return std::make_pair(RegName(BPMEM_IREF), fmt::to_string(RAS1_IREF{.hex = cmddata})); @@ -853,7 +851,7 @@ std::pair GetBPRegInfo(u8 cmd, u32 cmddata) case BPMEM_TREF + 6: case BPMEM_TREF + 7: return std::make_pair(fmt::format("BPMEM_TREF number {}", cmd - BPMEM_TREF), - fmt::to_string(TwoTevStageOrders{.hex = cmddata})); + fmt::to_string(std::make_pair(cmd, TwoTevStageOrders{.hex = cmddata}))); case BPMEM_SU_SSIZE: // 0x30 case BPMEM_SU_SSIZE + 2: @@ -864,7 +862,7 @@ std::pair GetBPRegInfo(u8 cmd, u32 cmddata) case BPMEM_SU_SSIZE + 12: case BPMEM_SU_SSIZE + 14: return std::make_pair(fmt::format("BPMEM_SU_SSIZE number {}", (cmd - BPMEM_SU_SSIZE) / 2), - fmt::format("S size info:\n{}", TCInfo{.hex = cmddata})); + fmt::to_string(std::make_pair(true, TCInfo{.hex = cmddata}))); case BPMEM_SU_TSIZE: // 0x31 case BPMEM_SU_TSIZE + 2: @@ -875,7 +873,7 @@ std::pair GetBPRegInfo(u8 cmd, u32 cmddata) case BPMEM_SU_TSIZE + 12: case BPMEM_SU_TSIZE + 14: return std::make_pair(fmt::format("BPMEM_SU_TSIZE number {}", (cmd - BPMEM_SU_TSIZE) / 2), - fmt::format("T size info:\n{}", TCInfo{.hex = cmddata})); + fmt::to_string(std::make_pair(false, TCInfo{.hex = cmddata}))); case BPMEM_ZMODE: // 0x40 return std::make_pair(RegName(BPMEM_ZMODE), fmt::format("Z mode: {}", ZMode{.hex = cmddata})); @@ -1249,7 +1247,7 @@ std::pair GetBPRegInfo(u8 cmd, u32 cmddata) case BPMEM_TEV_KSEL + 6: case BPMEM_TEV_KSEL + 7: return std::make_pair(fmt::format("BPMEM_TEV_KSEL number {}", cmd - BPMEM_TEV_KSEL), - fmt::to_string(TevKSel{.hex = cmddata})); + fmt::to_string(std::make_pair(cmd, TevKSel{.hex = cmddata}))); case BPMEM_BP_MASK: // 0xFE return std::make_pair(RegName(BPMEM_BP_MASK), From 698def66ff36fc0155d84b3777501e71a2ad22a1 Mon Sep 17 00:00:00 2001 From: Pokechu22 Date: Tue, 8 Feb 2022 21:10:31 -0800 Subject: [PATCH 14/14] Fifo analyzer: Fix various XF mistakes * 'hangle' was a typo * Light colors include an alpha value, so they should be 8 characters, not 6 * The XF command format adds 1 to the count internally (so 0 is one word), but we need to subtract that back to produce a valid command * XFMEM_POSTMATRICES was calculating the row by subtracting XFMEM_POSMATRICES (POS vs POST), resulting in incorrect row numbering --- Source/Core/DolphinQt/FIFO/FIFOAnalyzer.cpp | 2 +- Source/Core/VideoCommon/XFStructs.cpp | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Source/Core/DolphinQt/FIFO/FIFOAnalyzer.cpp b/Source/Core/DolphinQt/FIFO/FIFOAnalyzer.cpp index 586982e0e4..d593a7419d 100644 --- a/Source/Core/DolphinQt/FIFO/FIFOAnalyzer.cpp +++ b/Source/Core/DolphinQt/FIFO/FIFOAnalyzer.cpp @@ -224,7 +224,7 @@ public: const auto [name, desc] = GetXFTransferInfo(address, count, data); ASSERT(!name.empty()); - const u32 command = address | (count << 16); + const u32 command = address | ((count - 1) << 16); text = QStringLiteral("XF %1 ").arg(command, 8, 16, QLatin1Char('0')); diff --git a/Source/Core/VideoCommon/XFStructs.cpp b/Source/Core/VideoCommon/XFStructs.cpp index 33e148d043..1d6811f92a 100644 --- a/Source/Core/VideoCommon/XFStructs.cpp +++ b/Source/Core/VideoCommon/XFStructs.cpp @@ -321,17 +321,17 @@ std::pair GetXFRegInfo(u32 address, u32 value) case XFMEM_SETCHAN0_AMBCOLOR: return std::make_pair(RegName(XFMEM_SETCHAN0_AMBCOLOR), - fmt::format("Channel 0 Ambient Color: {:06x}", value)); + fmt::format("Channel 0 Ambient Color: {:08x}", value)); case XFMEM_SETCHAN1_AMBCOLOR: return std::make_pair(RegName(XFMEM_SETCHAN1_AMBCOLOR), - fmt::format("Channel 1 Ambient Color: {:06x}", value)); + fmt::format("Channel 1 Ambient Color: {:08x}", value)); case XFMEM_SETCHAN0_MATCOLOR: return std::make_pair(RegName(XFMEM_SETCHAN0_MATCOLOR), - fmt::format("Channel 0 Material Color: {:06x}", value)); + fmt::format("Channel 0 Material Color: {:08x}", value)); case XFMEM_SETCHAN1_MATCOLOR: return std::make_pair(RegName(XFMEM_SETCHAN1_MATCOLOR), - fmt::format("Channel 1 Material Color: {:06x}", value)); + fmt::format("Channel 1 Material Color: {:08x}", value)); case XFMEM_SETCHAN0_COLOR: // Channel Color return std::make_pair(RegName(XFMEM_SETCHAN0_COLOR), @@ -474,8 +474,8 @@ std::string GetXFMemName(u32 address) } else if (address >= XFMEM_POSTMATRICES && address < XFMEM_POSTMATRICES_END) { - const u32 row = (address - XFMEM_POSMATRICES) / 4; - const u32 col = (address - XFMEM_POSMATRICES) % 4; + const u32 row = (address - XFMEM_POSTMATRICES) / 4; + const u32 col = (address - XFMEM_POSTMATRICES) % 4; return fmt::format("Post matrix row {:2d} col {:2d}", row, col); } else if (address >= XFMEM_LIGHTS && address < XFMEM_LIGHTS_END) @@ -508,9 +508,9 @@ std::string GetXFMemName(u32 address) case 15: // Yagcd says light dir or "1/2 angle", dolphin has union for ddir or shalfangle. // It would make sense if d stood for direction and s for specular, but it's ddir and - // shalfhangle that have the comment "specular lights only", both at the same offset, + // shalfangle that have the comment "specular lights only", both at the same offset, // while dpos and sdir have none... - return fmt::format("Light {0} {1} direction or half hangle {1}", light, "xyz"[offset - 13]); + return fmt::format("Light {0} {1} direction or half angle {1}", light, "xyz"[offset - 13]); } } else