File: Tev.h

package info (click to toggle)
dolphin-emu 2503%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 111,624 kB
  • sloc: cpp: 787,747; ansic: 217,914; xml: 31,400; python: 4,226; yacc: 3,985; javascript: 2,430; makefile: 777; asm: 726; sh: 281; pascal: 257; perl: 97; objc: 75
file content (234 lines) | stat: -rw-r--r-- 7,541 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
// 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();
};