123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472 |
- // Copyright 2008 Dolphin Emulator Project
- // SPDX-License-Identifier: GPL-2.0-or-later
- #pragma once
- // X.h defines None to be 0, which causes problems with some of the enums
- #undef None
- #include <array>
- #include "Common/BitField.h"
- #include "Common/CommonTypes.h"
- #include "Common/EnumFormatter.h"
- #include "VideoCommon/CPMemory.h"
- constexpr size_t NUM_XF_COLOR_CHANNELS = 2;
- // Lighting
- // Projection
- enum class TexSize : u32
- {
- ST = 0,
- STQ = 1
- };
- template <>
- struct fmt::formatter<TexSize> : EnumFormatter<TexSize::STQ>
- {
- constexpr formatter() : EnumFormatter({"ST (2x4 matrix)", "STQ (3x4 matrix)"}) {}
- };
- // Input form
- enum class TexInputForm : u32
- {
- AB11 = 0,
- ABC1 = 1
- };
- template <>
- struct fmt::formatter<TexInputForm> : EnumFormatter<TexInputForm::ABC1>
- {
- constexpr formatter() : EnumFormatter({"AB11", "ABC1"}) {}
- };
- enum class NormalCount : u32
- {
- None = 0,
- Normal = 1,
- NormalTangentBinormal = 2,
- // Hardware testing indicates that this beahves the same as NormalTangentBinormal.
- // Call of Duty: Black Ops uses this in some cases; see https://bugs.dolphin-emu.org/issues/13070
- Invalid = 3,
- };
- template <>
- struct fmt::formatter<NormalCount> : EnumFormatter<NormalCount::Invalid>
- {
- static constexpr array_type names = {
- "None",
- "Normal only",
- "Normal, tangent, and binormal",
- "Invalid (Normal, tangent, and binormal)",
- };
- constexpr formatter() : EnumFormatter(names) {}
- };
- // Texture generation type
- enum class TexGenType : u32
- {
- Regular = 0,
- EmbossMap = 1, // Used when bump mapping
- Color0 = 2,
- Color1 = 3
- };
- template <>
- struct fmt::formatter<TexGenType> : EnumFormatter<TexGenType::Color1>
- {
- static constexpr array_type names = {
- "Regular",
- "Emboss map (used when bump mapping)",
- "Color channel 0",
- "Color channel 1",
- };
- constexpr formatter() : EnumFormatter(names) {}
- };
- // Source row
- enum class SourceRow : u32
- {
- Geom = 0, // Input is abc
- Normal = 1, // Input is abc
- Colors = 2,
- BinormalT = 3, // Input is abc
- BinormalB = 4, // Input is abc
- Tex0 = 5,
- Tex1 = 6,
- Tex2 = 7,
- Tex3 = 8,
- Tex4 = 9,
- Tex5 = 10,
- Tex6 = 11,
- Tex7 = 12
- };
- template <>
- struct fmt::formatter<SourceRow> : EnumFormatter<SourceRow::Tex7>
- {
- static constexpr array_type names = {
- "Geometry (input is ABC1)",
- "Normal (input is ABC1)",
- "Colors",
- "Binormal T (input is ABC1)",
- "Binormal B (input is ABC1)",
- "Tex 0",
- "Tex 1",
- "Tex 2",
- "Tex 3",
- "Tex 4",
- "Tex 5",
- "Tex 6",
- "Tex 7",
- };
- constexpr formatter() : EnumFormatter(names) {}
- };
- enum class MatSource : u32
- {
- MatColorRegister = 0,
- Vertex = 1,
- };
- template <>
- struct fmt::formatter<MatSource> : EnumFormatter<MatSource::Vertex>
- {
- constexpr formatter() : EnumFormatter({"Material color register", "Vertex color"}) {}
- };
- enum class AmbSource : u32
- {
- AmbColorRegister = 0,
- Vertex = 1,
- };
- template <>
- struct fmt::formatter<AmbSource> : EnumFormatter<AmbSource::Vertex>
- {
- constexpr formatter() : EnumFormatter({"Ambient color register", "Vertex color"}) {}
- };
- // Light diffuse attenuation function
- enum class DiffuseFunc : u32
- {
- None = 0,
- Sign = 1,
- Clamp = 2
- };
- template <>
- struct fmt::formatter<DiffuseFunc> : EnumFormatter<DiffuseFunc::Clamp>
- {
- constexpr formatter() : EnumFormatter({"None", "Sign", "Clamp"}) {}
- };
- // Light attenuation function
- enum class AttenuationFunc : u32
- {
- None = 0, // No attenuation
- Spec = 1, // Point light attenuation
- Dir = 2, // Directional light attenuation
- Spot = 3 // Spot light attenuation
- };
- template <>
- struct fmt::formatter<AttenuationFunc> : EnumFormatter<AttenuationFunc::Spot>
- {
- static constexpr array_type names = {
- "No attenuation",
- "Point light attenuation",
- "Directional light attenuation",
- "Spot light attenuation",
- };
- constexpr formatter() : EnumFormatter(names) {}
- };
- // Projection type
- enum class ProjectionType : u32
- {
- Perspective = 0,
- Orthographic = 1
- };
- template <>
- struct fmt::formatter<ProjectionType> : EnumFormatter<ProjectionType::Orthographic>
- {
- constexpr formatter() : EnumFormatter({"Perspective", "Orthographic"}) {}
- };
- // Registers and register ranges
- enum
- {
- XFMEM_POSMATRICES = 0x000,
- XFMEM_POSMATRICES_END = 0x100,
- XFMEM_NORMALMATRICES = 0x400,
- XFMEM_NORMALMATRICES_END = 0x460,
- XFMEM_POSTMATRICES = 0x500,
- XFMEM_POSTMATRICES_END = 0x600,
- XFMEM_LIGHTS = 0x600,
- XFMEM_LIGHTS_END = 0x680,
- XFMEM_REGISTERS_START = 0x1000,
- XFMEM_ERROR = 0x1000,
- XFMEM_DIAG = 0x1001,
- XFMEM_STATE0 = 0x1002,
- XFMEM_STATE1 = 0x1003,
- XFMEM_CLOCK = 0x1004,
- XFMEM_CLIPDISABLE = 0x1005,
- XFMEM_SETGPMETRIC = 0x1006, // Perf0 according to YAGCD
- XFMEM_UNKNOWN_1007 = 0x1007, // Perf1 according to YAGCD
- XFMEM_VTXSPECS = 0x1008,
- XFMEM_SETNUMCHAN = 0x1009,
- XFMEM_SETCHAN0_AMBCOLOR = 0x100a,
- XFMEM_SETCHAN1_AMBCOLOR = 0x100b,
- XFMEM_SETCHAN0_MATCOLOR = 0x100c,
- XFMEM_SETCHAN1_MATCOLOR = 0x100d,
- XFMEM_SETCHAN0_COLOR = 0x100e,
- XFMEM_SETCHAN1_COLOR = 0x100f,
- XFMEM_SETCHAN0_ALPHA = 0x1010,
- XFMEM_SETCHAN1_ALPHA = 0x1011,
- XFMEM_DUALTEX = 0x1012,
- XFMEM_UNKNOWN_GROUP_1_START = 0x1013,
- XFMEM_UNKNOWN_GROUP_1_END = 0x1017,
- XFMEM_SETMATRIXINDA = 0x1018,
- XFMEM_SETMATRIXINDB = 0x1019,
- XFMEM_SETVIEWPORT = 0x101a,
- XFMEM_SETZSCALE = 0x101c,
- XFMEM_SETZOFFSET = 0x101f,
- XFMEM_SETPROJECTION = 0x1020,
- // XFMEM_SETPROJECTIONB = 0x1021,
- // XFMEM_SETPROJECTIONC = 0x1022,
- // XFMEM_SETPROJECTIOND = 0x1023,
- // XFMEM_SETPROJECTIONE = 0x1024,
- // XFMEM_SETPROJECTIONF = 0x1025,
- // XFMEM_SETPROJECTIONORTHO = 0x1026,
- XFMEM_UNKNOWN_GROUP_2_START = 0x1027,
- XFMEM_UNKNOWN_GROUP_2_END = 0x103e,
- XFMEM_SETNUMTEXGENS = 0x103f,
- XFMEM_SETTEXMTXINFO = 0x1040,
- XFMEM_UNKNOWN_GROUP_3_START = 0x1048,
- XFMEM_UNKNOWN_GROUP_3_END = 0x104f,
- XFMEM_SETPOSTMTXINFO = 0x1050,
- XFMEM_REGISTERS_END = 0x1058,
- };
- union LitChannel
- {
- BitField<0, 1, MatSource> matsource;
- BitField<1, 1, bool, u32> enablelighting;
- BitField<2, 4, u32> lightMask0_3;
- BitField<6, 1, AmbSource> ambsource;
- BitField<7, 2, DiffuseFunc> diffusefunc;
- BitField<9, 2, AttenuationFunc> attnfunc;
- BitField<11, 4, u32> lightMask4_7;
- u32 hex;
- unsigned int GetFullLightMask() const
- {
- return enablelighting ? (lightMask0_3 | (lightMask4_7 << 4)) : 0;
- }
- };
- template <>
- struct fmt::formatter<LitChannel>
- {
- constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
- template <typename FormatContext>
- auto format(const LitChannel& chan, FormatContext& ctx) const
- {
- return fmt::format_to(
- ctx.out(),
- "Material source: {0}\nEnable lighting: {1}\nLight mask: {2:x} ({2:08b})\n"
- "Ambient source: {3}\nDiffuse function: {4}\nAttenuation function: {5}",
- chan.matsource, chan.enablelighting ? "Yes" : "No", chan.GetFullLightMask(), chan.ambsource,
- chan.diffusefunc, chan.attnfunc);
- }
- };
- union ClipDisable
- {
- BitField<0, 1, bool, u32> disable_clipping_detection;
- BitField<1, 1, bool, u32> disable_trivial_rejection;
- BitField<2, 1, bool, u32> disable_cpoly_clipping_acceleration;
- u32 hex;
- };
- template <>
- struct fmt::formatter<ClipDisable>
- {
- constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
- template <typename FormatContext>
- auto format(const ClipDisable& cd, FormatContext& ctx) const
- {
- return fmt::format_to(ctx.out(),
- "Disable clipping detection: {}\n"
- "Disable trivial rejection: {}\n"
- "Disable cpoly clipping acceleration: {}",
- cd.disable_clipping_detection ? "Yes" : "No",
- cd.disable_trivial_rejection ? "Yes" : "No",
- cd.disable_cpoly_clipping_acceleration ? "Yes" : "No");
- }
- };
- union INVTXSPEC
- {
- BitField<0, 2, u32> numcolors;
- BitField<2, 2, NormalCount> numnormals;
- BitField<4, 4, u32> numtextures;
- u32 hex;
- };
- template <>
- struct fmt::formatter<INVTXSPEC>
- {
- constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
- template <typename FormatContext>
- auto format(const INVTXSPEC& spec, FormatContext& ctx) const
- {
- return fmt::format_to(ctx.out(), "Num colors: {}\nNum normals: {}\nNum textures: {}",
- spec.numcolors, spec.numnormals, spec.numtextures);
- }
- };
- union TexMtxInfo
- {
- BitField<0, 1, u32> unknown;
- BitField<1, 1, TexSize> projection;
- BitField<2, 1, TexInputForm> inputform;
- BitField<3, 1, u32> unknown2;
- BitField<4, 3, TexGenType> texgentype;
- BitField<7, 5, SourceRow> sourcerow;
- BitField<12, 3, u32> embosssourceshift; // what generated texcoord to use
- BitField<15, 3, u32> embosslightshift; // light index that is used
- u32 hex;
- };
- template <>
- struct fmt::formatter<TexMtxInfo>
- {
- constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
- template <typename FormatContext>
- auto format(const TexMtxInfo& i, FormatContext& ctx) const
- {
- return fmt::format_to(ctx.out(),
- "Projection: {}\nInput form: {}\nTex gen type: {}\n"
- "Source row: {}\nEmboss source shift: {}\nEmboss light shift: {}",
- i.projection, i.inputform, i.texgentype, i.sourcerow, i.embosssourceshift,
- i.embosslightshift);
- }
- };
- union PostMtxInfo
- {
- BitField<0, 6, u32> index; // base row of dual transform matrix
- BitField<6, 2, u32> unused; //
- BitField<8, 1, bool, u32> normalize; // normalize before send operation
- u32 hex;
- };
- template <>
- struct fmt::formatter<PostMtxInfo>
- {
- constexpr auto parse(format_parse_context& ctx) { return ctx.begin(); }
- template <typename FormatContext>
- auto format(const PostMtxInfo& i, FormatContext& ctx) const
- {
- return fmt::format_to(ctx.out(), "Index: {}\nNormalize before send operation: {}", i.index,
- i.normalize ? "Yes" : "No");
- }
- };
- union NumColorChannel
- {
- BitField<0, 2, u32> numColorChans;
- u32 hex;
- };
- union NumTexGen
- {
- BitField<0, 4, u32> numTexGens;
- u32 hex;
- };
- union DualTexInfo
- {
- BitField<0, 1, bool, u32> enabled;
- u32 hex;
- };
- struct Light
- {
- u32 useless[3];
- u8 color[4];
- float cosatt[3]; // cos attenuation
- float distatt[3]; // dist attenuation
- union
- {
- struct
- {
- float dpos[3];
- float ddir[3]; // specular lights only
- };
- struct
- {
- float sdir[3];
- float shalfangle[3]; // specular lights only
- };
- };
- };
- struct Viewport
- {
- float wd;
- float ht;
- float zRange;
- float xOrig;
- float yOrig;
- float farZ;
- };
- struct Projection
- {
- using Raw = std::array<float, 6>;
- Raw rawProjection;
- ProjectionType type;
- };
- struct alignas(16) XFMemory
- {
- float posMatrices[256]; // 0x0000 - 0x00ff
- u32 unk0[768]; // 0x0100 - 0x03ff
- float normalMatrices[96]; // 0x0400 - 0x045f
- u32 unk1[160]; // 0x0460 - 0x04ff
- float postMatrices[256]; // 0x0500 - 0x05ff
- Light lights[8]; // 0x0600 - 0x067f
- u32 unk2[2432]; // 0x0680 - 0x0fff
- u32 error; // 0x1000
- u32 diag; // 0x1001
- u32 state0; // 0x1002
- u32 state1; // 0x1003
- u32 xfClock; // 0x1004
- ClipDisable clipDisable; // 0x1005
- u32 perf0; // 0x1006
- u32 perf1; // 0x1007
- INVTXSPEC invtxspec; // 0x1008
- NumColorChannel numChan; // 0x1009
- u32 ambColor[NUM_XF_COLOR_CHANNELS]; // 0x100a, 0x100b
- u32 matColor[NUM_XF_COLOR_CHANNELS]; // 0x100c, 0x100d
- LitChannel color[NUM_XF_COLOR_CHANNELS]; // 0x100e, 0x100f
- LitChannel alpha[NUM_XF_COLOR_CHANNELS]; // 0x1010, 0x1011
- DualTexInfo dualTexTrans; // 0x1012
- u32 unk3; // 0x1013
- u32 unk4; // 0x1014
- u32 unk5; // 0x1015
- u32 unk6; // 0x1016
- u32 unk7; // 0x1017
- TMatrixIndexA MatrixIndexA; // 0x1018
- TMatrixIndexB MatrixIndexB; // 0x1019
- Viewport viewport; // 0x101a - 0x101f
- Projection projection; // 0x1020 - 0x1026
- u32 unk8[24]; // 0x1027 - 0x103e
- NumTexGen numTexGen; // 0x103f
- TexMtxInfo texMtxInfo[8]; // 0x1040 - 0x1047
- u32 unk9[8]; // 0x1048 - 0x104f
- PostMtxInfo postMtxInfo[8]; // 0x1050 - 0x1057
- };
- static_assert(sizeof(XFMemory) == sizeof(u32) * XFMEM_REGISTERS_END);
- extern XFMemory xfmem;
- void LoadXFReg(u16 base_address, u8 transfer_size, const u8* data);
- void LoadIndexedXF(CPArray array, u32 index, u16 address, u8 size);
- void PreprocessIndexedXF(CPArray array, u32 index, u16 address, u8 size);
|