mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-03 22:20:53 +01:00
5ef8a7973e
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.
232 lines
7.3 KiB
C++
232 lines
7.3 KiB
C++
// 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;
|
|
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();
|
|
};
|