123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235 |
- // Copyright 2009 Dolphin Emulator Project
- // SPDX-License-Identifier: GPL-2.0-or-later
- #pragma once
- #include <array>
- #include "Common/EnumMap.h"
- #include "VideoCommon/BPMemory.h"
- class Tev
- {
- struct TevColor
- {
- constexpr TevColor() = default;
- constexpr explicit TevColor(s16 a_, s16 b_, s16 g_, s16 r_) : a(a_), b(b_), g(g_), r(r_) {}
- s16 a = 0;
- s16 b = 0;
- s16 g = 0;
- s16 r = 0;
- constexpr static TevColor All(s16 value) { return TevColor(value, value, value, value); }
- constexpr s16& operator[](int index)
- {
- switch (index)
- {
- case ALP_C:
- return a;
- case BLU_C:
- return b;
- case GRN_C:
- return g;
- case RED_C:
- return r;
- default:
- // invalid
- return a;
- }
- }
- };
- struct TevColorRef
- {
- constexpr explicit TevColorRef(const s16& r_, const s16& g_, const s16& b_)
- : r(r_), g(g_), b(b_)
- {
- }
- const s16& r;
- const s16& g;
- const s16& b;
- constexpr static TevColorRef Color(const TevColor& color)
- {
- return TevColorRef(color.r, color.g, color.b);
- }
- constexpr static TevColorRef All(const s16& value) { return TevColorRef(value, value, value); }
- constexpr static TevColorRef Alpha(const TevColor& color) { return All(color.a); }
- };
- struct TevAlphaRef
- {
- constexpr explicit TevAlphaRef(const TevColor& color) : a(color.a) {}
- constexpr explicit TevAlphaRef(const s16& a_) : a(a_) {}
- const s16& a;
- };
- struct TevKonstRef
- {
- constexpr explicit TevKonstRef(const s16& a_, const s16& r_, const s16& g_, const s16& b_)
- : a(a_), r(r_), g(g_), b(b_)
- {
- }
- const s16& a;
- const s16& r;
- const s16& g;
- const s16& b;
- constexpr static TevKonstRef Value(const s16& value)
- {
- return TevKonstRef(value, value, value, value);
- }
- constexpr static TevKonstRef Konst(const s16& alpha, const TevColor& color)
- {
- return TevKonstRef(alpha, color.r, color.g, color.b);
- }
- };
- struct InputRegType
- {
- unsigned a : 8;
- unsigned b : 8;
- unsigned c : 8;
- signed d : 11;
- };
- struct TextureCoordinateType
- {
- signed s : 24;
- signed t : 24;
- };
- // color order: ABGR
- Common::EnumMap<TevColor, TevOutput::Color2> Reg;
- std::array<TevColor, 4> KonstantColors;
- TevColor TexColor;
- TevColor RasColor;
- TevColor StageKonst;
- // Fixed constants, corresponding to KonstSel
- static constexpr s16 V0 = 0;
- static constexpr s16 V1_8 = 32;
- static constexpr s16 V1_4 = 64;
- static constexpr s16 V3_8 = 96;
- static constexpr s16 V1_2 = 128;
- static constexpr s16 V5_8 = 159;
- static constexpr s16 V3_4 = 191;
- static constexpr s16 V7_8 = 223;
- static constexpr s16 V1 = 255;
- u8 AlphaBump = 0;
- u8 IndirectTex[4][4]{};
- TextureCoordinateType TexCoord{};
- const Common::EnumMap<TevColorRef, TevColorArg::Zero> m_ColorInputLUT{
- TevColorRef::Color(Reg[TevOutput::Prev]), // prev.rgb
- TevColorRef::Alpha(Reg[TevOutput::Prev]), // prev.aaa
- TevColorRef::Color(Reg[TevOutput::Color0]), // c0.rgb
- TevColorRef::Alpha(Reg[TevOutput::Color0]), // c0.aaa
- TevColorRef::Color(Reg[TevOutput::Color1]), // c1.rgb
- TevColorRef::Alpha(Reg[TevOutput::Color1]), // c1.aaa
- TevColorRef::Color(Reg[TevOutput::Color2]), // c2.rgb
- TevColorRef::Alpha(Reg[TevOutput::Color2]), // c2.aaa
- TevColorRef::Color(TexColor), // tex.rgb
- TevColorRef::Alpha(TexColor), // tex.aaa
- TevColorRef::Color(RasColor), // ras.rgb
- TevColorRef::Alpha(RasColor), // ras.aaa
- TevColorRef::All(V1), // one
- TevColorRef::All(V1_2), // half
- TevColorRef::Color(StageKonst), // konst
- TevColorRef::All(V0), // zero
- };
- const Common::EnumMap<TevAlphaRef, TevAlphaArg::Zero> m_AlphaInputLUT{
- TevAlphaRef(Reg[TevOutput::Prev]), // prev
- TevAlphaRef(Reg[TevOutput::Color0]), // c0
- TevAlphaRef(Reg[TevOutput::Color1]), // c1
- TevAlphaRef(Reg[TevOutput::Color2]), // c2
- TevAlphaRef(TexColor), // tex
- TevAlphaRef(RasColor), // ras
- TevAlphaRef(StageKonst), // konst
- TevAlphaRef(V0), // zero
- };
- const Common::EnumMap<TevKonstRef, KonstSel::K3_A> m_KonstLUT{
- TevKonstRef::Value(V1), // 1
- TevKonstRef::Value(V7_8), // 7/8
- TevKonstRef::Value(V3_4), // 3/4
- TevKonstRef::Value(V5_8), // 5/8
- TevKonstRef::Value(V1_2), // 1/2
- TevKonstRef::Value(V3_8), // 3/8
- TevKonstRef::Value(V1_4), // 1/4
- TevKonstRef::Value(V1_8), // 1/8
- // These are "invalid" values, not meant to be used. On hardware,
- // they all output zero.
- TevKonstRef::Value(V0), TevKonstRef::Value(V0), TevKonstRef::Value(V0),
- TevKonstRef::Value(V0),
- // These values are valid for RGB only; they're invalid for alpha
- TevKonstRef::Konst(V0, KonstantColors[0]), // Konst 0 RGB
- TevKonstRef::Konst(V0, KonstantColors[1]), // Konst 1 RGB
- TevKonstRef::Konst(V0, KonstantColors[2]), // Konst 2 RGB
- TevKonstRef::Konst(V0, KonstantColors[3]), // Konst 3 RGB
- TevKonstRef::Value(KonstantColors[0].r), // Konst 0 Red
- TevKonstRef::Value(KonstantColors[1].r), // Konst 1 Red
- TevKonstRef::Value(KonstantColors[2].r), // Konst 2 Red
- TevKonstRef::Value(KonstantColors[3].r), // Konst 3 Red
- TevKonstRef::Value(KonstantColors[0].g), // Konst 0 Green
- TevKonstRef::Value(KonstantColors[1].g), // Konst 1 Green
- TevKonstRef::Value(KonstantColors[2].g), // Konst 2 Green
- TevKonstRef::Value(KonstantColors[3].g), // Konst 3 Green
- TevKonstRef::Value(KonstantColors[0].b), // Konst 0 Blue
- TevKonstRef::Value(KonstantColors[1].b), // Konst 1 Blue
- TevKonstRef::Value(KonstantColors[2].b), // Konst 2 Blue
- TevKonstRef::Value(KonstantColors[3].b), // Konst 3 Blue
- TevKonstRef::Value(KonstantColors[0].a), // Konst 0 Alpha
- TevKonstRef::Value(KonstantColors[1].a), // Konst 1 Alpha
- TevKonstRef::Value(KonstantColors[2].a), // Konst 2 Alpha
- TevKonstRef::Value(KonstantColors[3].a), // Konst 3 Alpha
- };
- static constexpr Common::EnumMap<s16, TevBias::Compare> s_BiasLUT{0, 128, -128, 0};
- static constexpr Common::EnumMap<u8, TevScale::Divide2> s_ScaleLShiftLUT{0, 1, 2, 0};
- static constexpr Common::EnumMap<u8, TevScale::Divide2> s_ScaleRShiftLUT{0, 0, 0, 1};
- enum BufferBase
- {
- DIRECT = 0,
- DIRECT_TFETCH = 16,
- INDIRECT = 32
- };
- 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]);
- void DrawAlphaRegular(const TevStageCombiner::AlphaCombiner& ac, const InputRegType inputs[4]);
- void DrawAlphaCompare(const TevStageCombiner::AlphaCombiner& ac, const InputRegType inputs[4]);
- void Indirect(unsigned int stageNum, s32 s, s32 t);
- public:
- s32 Position[3]{};
- u8 Color[2][4]{}; // must be RGBA for correct swap table ordering
- TextureCoordinateType Uv[8]{};
- s32 IndirectLod[4]{};
- bool IndirectLinear[4]{};
- s32 TextureLod[16]{};
- bool TextureLinear[16]{};
- enum
- {
- ALP_C,
- BLU_C,
- GRN_C,
- RED_C
- };
- void SetKonstColors();
- void Draw();
- };
|