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; } 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/VideoBackends/Software/Rasterizer.cpp b/Source/Core/VideoBackends/Software/Rasterizer.cpp index 2a341d8093..b27dc14c89 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(); @@ -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); } 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 c2039df3ea..e788d55d92 100644 --- a/Source/Core/VideoBackends/Software/Tev.cpp +++ b/Source/Core/VideoBackends/Software/Tev.cpp @@ -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(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) +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(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++) @@ -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]; + } } diff --git a/Source/Core/VideoBackends/Software/Tev.h b/Source/Core/VideoBackends/Software/Tev.h index 9c18afbd23..c4e5e1f45f 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,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 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]; - 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 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 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 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 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 { @@ -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); }; diff --git a/Source/Core/VideoCommon/BPMemory.h b/Source/Core/VideoCommon/BPMemory.h index 641118417a..974e00dfa3 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 @@ -683,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); @@ -777,69 +778,82 @@ 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 +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.texmap0, stages.texcoord0, stages.enable0 ? "Yes" : "No", - stages.colorchan0, stages.texmap1, stages.texcoord1, - stages.enable1 ? "Yes" : "No", stages.colorchan1); + "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); } }; 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; @@ -858,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); } @@ -1743,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; } }; @@ -1834,6 +1853,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, @@ -1908,29 +1940,65 @@ 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 +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.swap1, ksel.swap2, ksel.kcsel0, ksel.kasel0, ksel.kcsel1, - ksel.kasel1); + "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); + } +}; + +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}; } }; @@ -2350,70 +2418,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 + AllTevKSels tevksel; // 0xf6-0xfd + u32 bpMask; // 0xfe + u32 unknown18; // 0xff EmulatedZ GetEmulatedZ() const { 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), 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 22708f3d66..5bbd9f39af 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"); @@ -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,13 +1217,13 @@ 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", 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" @@ -1239,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; 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