mirror of
https://github.com/cemu-project/Cemu.git
synced 2025-07-03 05:21:18 +12:00
1685 lines
51 KiB
C++
1685 lines
51 KiB
C++
#pragma once
|
|
|
|
namespace Latte
|
|
{
|
|
// common enums
|
|
enum class E_DIM : uint32 // shared between Latte backend and GX2 code
|
|
{
|
|
DIM_1D = 0,
|
|
DIM_2D = 1,
|
|
DIM_3D = 2,
|
|
DIM_CUBEMAP = 3,
|
|
DIM_1D_ARRAY = 4,
|
|
DIM_2D_ARRAY = 5,
|
|
DIM_2D_MSAA = 6,
|
|
DIM_2D_ARRAY_MSAA = 7
|
|
};
|
|
|
|
enum class E_AAMODE : uint32 // shared between Latte backend and GX2 code
|
|
{
|
|
AA_1X = 0,
|
|
AA_2X = 1,
|
|
AA_4X = 2,
|
|
AA_8X = 3,
|
|
};
|
|
|
|
enum class E_HWTILEMODE
|
|
{
|
|
TM_LINEAR_GENERAL = 0, // linear (pitch must be aligned to 8?)
|
|
TM_LINEAR_ALIGNED = 1, // pitch must be multiple of 64 pixels?
|
|
|
|
TM_1D_TILED_THIN1 = 2, // no macro tiling, 8x8 micro tiles
|
|
TM_1D_TILED_THICK = 3, // no macro tiling, 8x8x4 micro tiles
|
|
|
|
TM_2D_TILED_THIN1 = 4, // 4x2
|
|
TM_2D_TILED_THIN2 = 5, // 2x4
|
|
TM_2D_TILED_THIN4 = 6, // 1x8
|
|
TM_2D_TILED_THICK = 7, // 4x2x1
|
|
|
|
TM_2B_TILED_THIN1 = 8, // 4x2
|
|
TM_2B_TILED_THIN2 = 9, // 2x4
|
|
TM_2B_TILED_THIN4 = 10, // 1x8
|
|
TM_2B_TILED_THICK = 11, // 4x2x1
|
|
|
|
TM_3D_TILED_THIN1 = 12, // 4x2
|
|
TM_3D_TILED_THICK = 13, // 4x2x1
|
|
|
|
TM_3B_TILED_THIN1 = 14, // 4x2
|
|
TM_3B_TILED_THICK = 15, // 4x2x1
|
|
};
|
|
|
|
enum class E_GX2TILEMODE : uint32
|
|
{
|
|
// same as E_TILEMODE but contains additional options with special meaning
|
|
TM_LINEAR_GENERAL = 0,
|
|
TM_LINEAR_ALIGNED = 1,
|
|
|
|
// micro-tiled
|
|
TM_1D_TILED_THIN1 = 2,
|
|
TM_1D_TILED_THICK = 3,
|
|
|
|
// macro-tiled
|
|
TM_2D_TILED_THIN1 = 4,
|
|
TM_2D_TILED_THIN2 = 5,
|
|
TM_2D_TILED_THIN4 = 6,
|
|
TM_2D_TILED_THICK = 7,
|
|
|
|
TM_2B_TILED_THIN1 = 8,
|
|
TM_2B_TILED_THIN2 = 9,
|
|
TM_2B_TILED_THIN4 = 10,
|
|
TM_2B_TILED_THICK = 11,
|
|
|
|
TM_3D_TILED_THIN1 = 12,
|
|
TM_3D_TILED_THICK = 13,
|
|
|
|
TM_3B_TILED_THIN1 = 14,
|
|
TM_3B_TILED_THICK = 15,
|
|
|
|
// special
|
|
TM_LINEAR_SPECIAL = 16,
|
|
TM_32_SPECIAL = 32,
|
|
};
|
|
|
|
inline E_HWTILEMODE MakeHWTileMode(const E_GX2TILEMODE gx2Tilemode)
|
|
{
|
|
return (E_HWTILEMODE)((uint32)gx2Tilemode & 0xF);
|
|
}
|
|
|
|
inline E_GX2TILEMODE MakeGX2TileMode(const E_HWTILEMODE hwTilemode)
|
|
{
|
|
return (E_GX2TILEMODE)hwTilemode;
|
|
}
|
|
|
|
inline bool TM_IsMacroTiled(const E_HWTILEMODE tm)
|
|
{
|
|
return (uint32)tm >= 4;
|
|
}
|
|
|
|
inline bool TM_IsMacroTiled(const E_GX2TILEMODE tm)
|
|
{
|
|
return (uint32)tm >= 4 && (uint32)tm != 16;
|
|
}
|
|
|
|
inline bool TM_IsBankSwapped(const E_HWTILEMODE tileMode)
|
|
{
|
|
return
|
|
tileMode == E_HWTILEMODE::TM_2B_TILED_THIN1 ||
|
|
tileMode == E_HWTILEMODE::TM_2B_TILED_THIN2 ||
|
|
tileMode == E_HWTILEMODE::TM_2B_TILED_THIN4 ||
|
|
tileMode == E_HWTILEMODE::TM_2B_TILED_THICK ||
|
|
tileMode == E_HWTILEMODE::TM_3B_TILED_THIN1 ||
|
|
tileMode == E_HWTILEMODE::TM_3B_TILED_THICK;
|
|
}
|
|
|
|
enum class E_HWSURFFMT
|
|
{
|
|
INVALID_FORMAT = 0,
|
|
// hardware formats only
|
|
HWFMT_8 = 0x1,
|
|
HWFMT_4_4 = 0x2,
|
|
HWFMT_3_3_2 = 0x3,
|
|
HWFMT_16 = 0x5,
|
|
HWFMT_16_FLOAT = 0x6,
|
|
HWFMT_8_8 = 0x7,
|
|
HWFMT_5_6_5 = 0x8,
|
|
HWFMT_6_5_5 = 0x9,
|
|
HWFMT_1_5_5_5 = 0xA,
|
|
HWFMT_4_4_4_4 = 0xB,
|
|
HWFMT_5_5_5_1 = 0xC,
|
|
HWFMT_32 = 0xD,
|
|
HWFMT_32_FLOAT = 0xE,
|
|
HWFMT_16_16 = 0xF,
|
|
HWFMT_16_16_FLOAT = 0x10,
|
|
HWFMT_8_24 = 0x11,
|
|
HWFMT_8_24_FLOAT = 0x12,
|
|
HWFMT_24_8 = 0x13,
|
|
HWFMT_24_8_FLOAT = 0x14,
|
|
HWFMT_10_11_11 = 0x15,
|
|
HWFMT_10_11_11_FLOAT = 0x16,
|
|
HWFMT_11_11_10 = 0x17,
|
|
HWFMT_11_11_10_FLOAT = 0x18,
|
|
HWFMT_2_10_10_10 = 0x19,
|
|
HWFMT_8_8_8_8 = 0x1A,
|
|
HWFMT_10_10_10_2 = 0x1B,
|
|
HWFMT_X24_8_32_FLOAT = 0x1C,
|
|
HWFMT_32_32 = 0x1D,
|
|
HWFMT_32_32_FLOAT = 0x1E,
|
|
HWFMT_16_16_16_16 = 0x1F,
|
|
HWFMT_16_16_16_16_FLOAT = 0x20,
|
|
HWFMT_32_32_32_32 = 0x22,
|
|
HWFMT_32_32_32_32_FLOAT = 0x23,
|
|
HWFMT_BC1 = 0x31,
|
|
HWFMT_BC2 = 0x32,
|
|
HWFMT_BC3 = 0x33,
|
|
HWFMT_BC4 = 0x34,
|
|
HWFMT_BC5 = 0x35,
|
|
|
|
// these formats exist in R600/R700 documentation, but GX2 doesn't seem to handle them. Are they supported?
|
|
U_HWFMT_BC6 = 0x36,
|
|
U_HWFMT_BC7 = 0x37,
|
|
U_HWFMT_32_32_32 = 0x2F,
|
|
U_HWFMT_32_32_32_FLOAT = 0x30,
|
|
|
|
|
|
};
|
|
|
|
enum class E_GX2SURFFMT // GX2 surface format
|
|
{
|
|
INVALID_FORMAT = 0,
|
|
// base hardware formats (shared with E_HWSURFFMT)
|
|
HWFMT_8 = 0x1,
|
|
HWFMT_4_4 = 0x2,
|
|
HWFMT_3_3_2 = 0x3,
|
|
HWFMT_16 = 0x5,
|
|
HWFMT_16_FLOAT = 0x6,
|
|
HWFMT_8_8 = 0x7,
|
|
HWFMT_5_6_5 = 0x8,
|
|
HWFMT_6_5_5 = 0x9,
|
|
HWFMT_1_5_5_5 = 0xA,
|
|
HWFMT_4_4_4_4 = 0xB,
|
|
HWFMT_5_5_5_1 = 0xC,
|
|
HWFMT_32 = 0xD,
|
|
HWFMT_32_FLOAT = 0xE,
|
|
HWFMT_16_16 = 0xF,
|
|
HWFMT_16_16_FLOAT = 0x10,
|
|
HWFMT_8_24 = 0x11,
|
|
HWFMT_8_24_FLOAT = 0x12,
|
|
HWFMT_24_8 = 0x13,
|
|
HWFMT_24_8_FLOAT = 0x14,
|
|
HWFMT_10_11_11 = 0x15,
|
|
HWFMT_10_11_11_FLOAT = 0x16,
|
|
HWFMT_11_11_10 = 0x17,
|
|
HWFMT_11_11_10_FLOAT = 0x18,
|
|
HWFMT_2_10_10_10 = 0x19,
|
|
HWFMT_8_8_8_8 = 0x1A,
|
|
HWFMT_10_10_10_2 = 0x1B,
|
|
HWFMT_X24_8_32_FLOAT = 0x1C,
|
|
HWFMT_32_32 = 0x1D,
|
|
HWFMT_32_32_FLOAT = 0x1E,
|
|
HWFMT_16_16_16_16 = 0x1F,
|
|
HWFMT_16_16_16_16_FLOAT = 0x20,
|
|
HWFMT_32_32_32_32 = 0x22,
|
|
HWFMT_32_32_32_32_FLOAT = 0x23,
|
|
HWFMT_BC1 = 0x31,
|
|
HWFMT_BC2 = 0x32,
|
|
HWFMT_BC3 = 0x33,
|
|
HWFMT_BC4 = 0x34,
|
|
HWFMT_BC5 = 0x35,
|
|
|
|
// GX2 extra format bits
|
|
FMT_BIT_INT = 0x100,
|
|
FMT_BIT_SIGNED = 0x200,
|
|
FMT_BIT_SRGB = 0x400,
|
|
FMT_BIT_FLOAT = 0x800,
|
|
|
|
// GX2 formats
|
|
R4_G4_UNORM = HWFMT_4_4,
|
|
|
|
R5_G6_B5_UNORM = HWFMT_5_6_5,
|
|
R5_G5_B5_A1_UNORM = HWFMT_1_5_5_5,
|
|
R4_G4_B4_A4_UNORM = HWFMT_4_4_4_4,
|
|
A1_B5_G5_R5_UNORM = HWFMT_5_5_5_1,
|
|
|
|
R8_UNORM = HWFMT_8,
|
|
R8_SNORM = (HWFMT_8 | FMT_BIT_SIGNED),
|
|
R8_UINT = (HWFMT_8 | FMT_BIT_INT),
|
|
R8_SINT = (HWFMT_8 | FMT_BIT_INT | FMT_BIT_SIGNED),
|
|
|
|
R8_G8_UNORM = HWFMT_8_8,
|
|
R8_G8_SNORM = (HWFMT_8_8 | FMT_BIT_SIGNED),
|
|
R8_G8_UINT = (HWFMT_8_8 | FMT_BIT_INT),
|
|
R8_G8_SINT = (HWFMT_8_8 | FMT_BIT_INT | FMT_BIT_SIGNED),
|
|
|
|
R8_G8_B8_A8_UNORM = HWFMT_8_8_8_8,
|
|
R8_G8_B8_A8_SNORM = (HWFMT_8_8_8_8 | FMT_BIT_SIGNED),
|
|
R8_G8_B8_A8_UINT = (HWFMT_8_8_8_8 | FMT_BIT_INT),
|
|
R8_G8_B8_A8_SINT = (HWFMT_8_8_8_8 | FMT_BIT_INT | FMT_BIT_SIGNED),
|
|
R8_G8_B8_A8_SRGB = (HWFMT_8_8_8_8 | FMT_BIT_SRGB),
|
|
|
|
R10_G10_B10_A2_UNORM = HWFMT_2_10_10_10,
|
|
R10_G10_B10_A2_SNORM = (HWFMT_2_10_10_10 | FMT_BIT_SIGNED),
|
|
R10_G10_B10_A2_UINT = (HWFMT_2_10_10_10 | FMT_BIT_INT),
|
|
R10_G10_B10_A2_SINT = (HWFMT_2_10_10_10 | FMT_BIT_INT | FMT_BIT_SIGNED),
|
|
R10_G10_B10_A2_SRGB = (HWFMT_2_10_10_10 | FMT_BIT_SRGB),
|
|
|
|
A2_B10_G10_R10_UNORM = HWFMT_10_10_10_2,
|
|
A2_B10_G10_R10_UINT = (HWFMT_10_10_10_2 | FMT_BIT_INT),
|
|
|
|
R16_UNORM = HWFMT_16,
|
|
R16_SNORM = (HWFMT_16 | FMT_BIT_SIGNED),
|
|
R16_UINT = (HWFMT_16 | FMT_BIT_INT),
|
|
R16_SINT = (HWFMT_16 | FMT_BIT_INT | FMT_BIT_SIGNED),
|
|
R16_FLOAT = (HWFMT_16_FLOAT | FMT_BIT_FLOAT),
|
|
|
|
R16_G16_UNORM = HWFMT_16_16,
|
|
R16_G16_SNORM = (HWFMT_16_16 | FMT_BIT_SIGNED),
|
|
R16_G16_UINT = (HWFMT_16_16 | FMT_BIT_INT),
|
|
R16_G16_SINT = (HWFMT_16_16 | FMT_BIT_INT | FMT_BIT_SIGNED),
|
|
R16_G16_FLOAT = (HWFMT_16_16_FLOAT | FMT_BIT_FLOAT),
|
|
|
|
R16_G16_B16_A16_UNORM = HWFMT_16_16_16_16,
|
|
R16_G16_B16_A16_SNORM = (HWFMT_16_16_16_16 | FMT_BIT_SIGNED),
|
|
R16_G16_B16_A16_UINT = (HWFMT_16_16_16_16 | FMT_BIT_INT),
|
|
R16_G16_B16_A16_SINT = (HWFMT_16_16_16_16 | FMT_BIT_INT | FMT_BIT_SIGNED),
|
|
R16_G16_B16_A16_FLOAT = (HWFMT_16_16_16_16_FLOAT | FMT_BIT_FLOAT),
|
|
|
|
|
|
R24_X8_UNORM = (HWFMT_8_24),
|
|
R24_X8_FLOAT = (HWFMT_8_24 | FMT_BIT_FLOAT),
|
|
X24_G8_UINT = (HWFMT_8_24 | FMT_BIT_INT),
|
|
R32_X8_FLOAT = (HWFMT_X24_8_32_FLOAT | FMT_BIT_FLOAT), // R32_X8_FLOAT
|
|
X32_G8_UINT_X24 = (HWFMT_X24_8_32_FLOAT | FMT_BIT_INT), // X32_G8_UINT
|
|
|
|
R11_G11_B10_FLOAT = (HWFMT_10_11_11_FLOAT | FMT_BIT_FLOAT),
|
|
|
|
// 32bit component formats do not support SNORM/UNORM (at least GX2 doesnt expose it)
|
|
R32_UINT = (HWFMT_32 | FMT_BIT_INT),
|
|
R32_SINT = (HWFMT_32 | FMT_BIT_INT | FMT_BIT_SIGNED),
|
|
R32_FLOAT = (HWFMT_32_FLOAT | FMT_BIT_FLOAT),
|
|
|
|
R32_G32_UINT = (HWFMT_32_32 | FMT_BIT_INT),
|
|
R32_G32_SINT = (HWFMT_32_32 | FMT_BIT_INT | FMT_BIT_SIGNED),
|
|
R32_G32_FLOAT = (HWFMT_32_32_FLOAT | FMT_BIT_FLOAT),
|
|
|
|
R32_G32_B32_A32_UINT = (HWFMT_32_32_32_32 | FMT_BIT_INT),
|
|
R32_G32_B32_A32_SINT = (HWFMT_32_32_32_32 | FMT_BIT_INT | FMT_BIT_SIGNED),
|
|
R32_G32_B32_A32_FLOAT = (HWFMT_32_32_32_32_FLOAT | FMT_BIT_FLOAT),
|
|
|
|
// depth
|
|
D24_S8_UNORM = (HWFMT_8_24),
|
|
D24_S8_FLOAT = (HWFMT_8_24 | FMT_BIT_FLOAT),
|
|
D32_S8_FLOAT = (HWFMT_X24_8_32_FLOAT | FMT_BIT_FLOAT),
|
|
D16_UNORM = HWFMT_16,
|
|
D32_FLOAT = (HWFMT_32_FLOAT | FMT_BIT_FLOAT),
|
|
|
|
// compressed formats
|
|
BC1_UNORM = (HWFMT_BC1),
|
|
BC1_SRGB = (HWFMT_BC1 | FMT_BIT_SRGB),
|
|
BC2_UNORM = (HWFMT_BC2),
|
|
BC2_SRGB = (HWFMT_BC2 | FMT_BIT_SRGB),
|
|
BC3_UNORM = (HWFMT_BC3),
|
|
BC3_SRGB = (HWFMT_BC3 | FMT_BIT_SRGB),
|
|
BC4_UNORM = (HWFMT_BC4),
|
|
BC4_SNORM = (HWFMT_BC4 | FMT_BIT_SIGNED),
|
|
BC5_UNORM = (HWFMT_BC5),
|
|
BC5_SNORM = (HWFMT_BC5 | FMT_BIT_SIGNED),
|
|
|
|
// special
|
|
NV12_UNORM = 0x81,
|
|
};
|
|
DEFINE_ENUM_FLAG_OPERATORS(E_GX2SURFFMT);
|
|
|
|
inline uint32 GetFormatBits(const Latte::E_HWSURFFMT hwFmt)
|
|
{
|
|
const uint8 sBitsTable[0x40] = {
|
|
0x00,0x08,0x08,0x00,0x00,0x10,0x10,0x10,
|
|
0x10,0x10,0x10,0x10,0x10,0x20,0x20,0x20,
|
|
0x20,0x20,0x00,0x20,0x00,0x00,0x20,0x00,
|
|
0x00,0x20,0x20,0x20,0x40,0x40,0x40,0x40,
|
|
0x40,0x00,0x80,0x80,0x00,0x00,0x00,0x10,
|
|
0x10,0x20,0x20,0x20,0x00,0x00,0x00,0x60,
|
|
0x60,0x40,0x80,0x80,0x40,0x80,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
};
|
|
cemu_assert((uint32)hwFmt < 0x40);
|
|
return sBitsTable[(uint32)hwFmt];
|
|
}
|
|
|
|
inline uint32 GetFormatBits(const Latte::E_GX2SURFFMT gx2Fmt)
|
|
{
|
|
return GetFormatBits((Latte::E_HWSURFFMT)((uint32)gx2Fmt & 0x3F));
|
|
}
|
|
|
|
inline E_HWSURFFMT GetHWFormat(E_GX2SURFFMT format)
|
|
{
|
|
return (E_HWSURFFMT)((uint32)format & 0x3F);
|
|
}
|
|
|
|
inline bool IsCompressedFormat(Latte::E_HWSURFFMT format)
|
|
{
|
|
return (uint32)format >= 0x31 && (uint32)format <= 0x35;
|
|
}
|
|
|
|
inline bool IsCompressedFormat(Latte::E_GX2SURFFMT format)
|
|
{
|
|
return IsCompressedFormat((Latte::E_HWSURFFMT)((uint32)format & 0x3F));
|
|
}
|
|
|
|
inline bool IsMSAA(Latte::E_DIM dim)
|
|
{
|
|
return dim == E_DIM::DIM_2D_MSAA || dim == E_DIM::DIM_2D_ARRAY_MSAA;
|
|
}
|
|
|
|
enum GPU_LIMITS
|
|
{
|
|
NUM_VERTEX_BUFFERS = 16,
|
|
NUM_TEXTURES_PER_STAGE = 18,
|
|
NUM_SAMPLERS_PER_STAGE = 18, // is this 16 or 18?
|
|
NUM_COLOR_ATTACHMENTS = 8,
|
|
};
|
|
|
|
enum REGADDR
|
|
{
|
|
VGT_PRIMITIVE_TYPE = 0x2256,
|
|
|
|
// each stage has 12 sets of 4 border color registers
|
|
TD_PS_SAMPLER0_BORDER_RED = 0x2900,
|
|
TD_PS_SAMPLER0_BORDER_GREEN = 0x2901,
|
|
TD_PS_SAMPLER0_BORDER_BLUE = 0x2902,
|
|
TD_PS_SAMPLER0_BORDER_ALPHA = 0x2903,
|
|
|
|
TD_VS_SAMPLER0_BORDER_RED = 0x2980,
|
|
TD_VS_SAMPLER0_BORDER_GREEN = 0x2981,
|
|
TD_VS_SAMPLER0_BORDER_BLUE = 0x2982,
|
|
TD_VS_SAMPLER0_BORDER_ALPHA = 0x2983,
|
|
|
|
TD_GS_SAMPLER0_BORDER_RED = 0x2A00,
|
|
TD_GS_SAMPLER0_BORDER_GREEN = 0x2A01,
|
|
TD_GS_SAMPLER0_BORDER_BLUE = 0x2A02,
|
|
TD_GS_SAMPLER0_BORDER_ALPHA = 0x2A03,
|
|
|
|
DB_STENCIL_CLEAR = 0xA00A,
|
|
DB_DEPTH_CLEAR = 0xA00B,
|
|
|
|
CB_TARGET_MASK = 0xA08E,
|
|
|
|
PA_SC_GENERIC_SCISSOR_TL = 0xA090,
|
|
PA_SC_GENERIC_SCISSOR_BR = 0xA091,
|
|
|
|
SQ_VTX_SEMANTIC_0 = 0xA0E0,
|
|
SQ_VTX_SEMANTIC_31 = 0xA0FF,
|
|
|
|
VGT_MULTI_PRIM_IB_RESET_INDX = 0xA103,
|
|
SX_ALPHA_TEST_CONTROL = 0xA104,
|
|
CB_BLEND_RED = 0xA105,
|
|
CB_BLEND_GREEN = 0xA106,
|
|
CB_BLEND_BLUE = 0xA107,
|
|
CB_BLEND_ALPHA = 0xA108,
|
|
|
|
DB_STENCILREFMASK = 0xA10C,
|
|
DB_STENCILREFMASK_BF = 0xA10D,
|
|
SX_ALPHA_REF = 0xA10E,
|
|
PA_CL_VPORT_XSCALE = 0xA10F,
|
|
PA_CL_VPORT_XOFFSET = 0xA110,
|
|
PA_CL_VPORT_YSCALE = 0xA111,
|
|
PA_CL_VPORT_YOFFSET = 0xA112,
|
|
PA_CL_VPORT_ZSCALE = 0xA113,
|
|
PA_CL_VPORT_ZOFFSET = 0xA114,
|
|
|
|
SPI_VS_OUT_ID_0 = 0xA185,
|
|
|
|
SPI_VS_OUT_CONFIG = 0xA1B1,
|
|
|
|
CB_BLEND0_CONTROL = 0xA1E0, // first
|
|
CB_BLEND7_CONTROL = 0xA1E7, // last
|
|
|
|
DB_DEPTH_CONTROL = 0xA200,
|
|
|
|
CB_COLOR_CONTROL = 0xA202,
|
|
|
|
PA_CL_CLIP_CNTL = 0xA204,
|
|
PA_SU_SC_MODE_CNTL = 0xA205,
|
|
PA_CL_VTE_CNTL = 0xA206,
|
|
PA_CL_VS_OUT_CNTL = 0xA207,
|
|
|
|
// shader program descriptors:
|
|
SQ_PGM_START_PS = 0xA210,
|
|
SQ_PGM_RESOURCES_PS = 0xA214,
|
|
SQ_PGM_EXPORTS_PS = 0xA215,
|
|
SQ_PGM_START_VS = 0xA216,
|
|
SQ_PGM_RESOURCES_VS = 0xA21A,
|
|
SQ_PGM_START_GS = 0xA21B,
|
|
SQ_PGM_RESOURCES_GS = 0xA21F,
|
|
SQ_PGM_START_ES = 0xA220,
|
|
SQ_PGM_RESOURCES_ES = 0xA224,
|
|
SQ_PGM_START_FS = 0xA225,
|
|
SQ_PGM_RESOURCES_FS = 0xA229,
|
|
|
|
SQ_VTX_SEMANTIC_CLEAR = 0xA238,
|
|
|
|
PA_SU_POINT_SIZE = 0xA280,
|
|
PA_SU_POINT_MINMAX = 0xA281,
|
|
|
|
VGT_GS_MODE = 0xA290,
|
|
|
|
VGT_DMA_INDEX_TYPE = 0xA29F, // todo - verify offset
|
|
|
|
VGT_PRIMITIVEID_EN = 0xA2A1,
|
|
|
|
VGT_MULTI_PRIM_IB_RESET_EN = 0xA2A5,
|
|
|
|
VGT_INSTANCE_STEP_RATE_0 = 0xA2A8,
|
|
VGT_INSTANCE_STEP_RATE_1 = 0xA2A9,
|
|
|
|
VGT_STRMOUT_BUFFER_SIZE_0 = 0xA2B4,
|
|
VGT_STRMOUT_VTX_STRIDE_0 = 0xA2B5,
|
|
VGT_STRMOUT_BUFFER_BASE_0 = 0xA2B6,
|
|
VGT_STRMOUT_BUFFER_OFFSET_0 = 0xA2B7,
|
|
VGT_STRMOUT_BUFFER_SIZE_1 = 0xA2B8,
|
|
VGT_STRMOUT_VTX_STRIDE_1 = 0xA2B9,
|
|
VGT_STRMOUT_BUFFER_BASE_1 = 0xA2BA,
|
|
VGT_STRMOUT_BUFFER_OFFSET_1 = 0xA2BB,
|
|
VGT_STRMOUT_BUFFER_SIZE_2 = 0xA2BC,
|
|
VGT_STRMOUT_VTX_STRIDE_2 = 0xA2BD,
|
|
VGT_STRMOUT_BUFFER_BASE_2 = 0xA2BE,
|
|
VGT_STRMOUT_BUFFER_OFFSET_2 = 0xA2BF,
|
|
VGT_STRMOUT_BUFFER_SIZE_3 = 0xA2C0,
|
|
VGT_STRMOUT_VTX_STRIDE_3 = 0xA2C1,
|
|
VGT_STRMOUT_BUFFER_BASE_3 = 0xA2C2,
|
|
VGT_STRMOUT_BUFFER_OFFSET_3 = 0xA2C3,
|
|
VGT_STRMOUT_BASE_OFFSET_0 = 0xA2C4,
|
|
VGT_STRMOUT_BASE_OFFSET_1 = 0xA2C5,
|
|
VGT_STRMOUT_BASE_OFFSET_2 = 0xA2C6,
|
|
VGT_STRMOUT_BASE_OFFSET_3 = 0xA2C7,
|
|
VGT_STRMOUT_BUFFER_EN = 0xA2C8,
|
|
|
|
// HiZ early stencil test?
|
|
DB_SRESULTS_COMPARE_STATE0 = 0xA34A,
|
|
DB_SRESULTS_COMPARE_STATE1 = 0xA34B,
|
|
|
|
PA_SU_POLY_OFFSET_CLAMP = 0xA37F,
|
|
PA_SU_POLY_OFFSET_FRONT_SCALE = 0xA380,
|
|
PA_SU_POLY_OFFSET_FRONT_OFFSET = 0xA381,
|
|
PA_SU_POLY_OFFSET_BACK_SCALE = 0xA382,
|
|
PA_SU_POLY_OFFSET_BACK_OFFSET = 0xA383,
|
|
|
|
// texture units
|
|
SQ_TEX_RESOURCE_WORD0_N_PS = 0xE000,
|
|
SQ_TEX_RESOURCE_WORD0_N_VS = 0xE460,
|
|
SQ_TEX_RESOURCE_WORD0_N_GS = 0xE930,
|
|
SQ_TEX_RESOURCE_WORD_FIRST = SQ_TEX_RESOURCE_WORD0_N_PS,
|
|
SQ_TEX_RESOURCE_WORD_LAST = (SQ_TEX_RESOURCE_WORD0_N_GS + GPU_LIMITS::NUM_TEXTURES_PER_STAGE * 7 - 1),
|
|
// there are 54 samplers with 3 registers each. 18 (actually only 16?) per stage. For stage indices see SAMPLER_BASE_INDEX_*
|
|
SQ_TEX_SAMPLER_WORD0_0 = 0xF000,
|
|
SQ_TEX_SAMPLER_WORD1_0 = 0xF001,
|
|
SQ_TEX_SAMPLER_WORD2_0 = 0xF002,
|
|
|
|
|
|
};
|
|
|
|
inline constexpr int SAMPLER_BASE_INDEX_PIXEL = 0;
|
|
inline constexpr int SAMPLER_BASE_INDEX_VERTEX = 18;
|
|
inline constexpr int SAMPLER_BASE_INDEX_GEOMETRY = 36;
|
|
|
|
#define LATTE_BITFIELD(__regname, __bitIndex, __bitWidth) \
|
|
auto& set_##__regname(uint32 newValue) \
|
|
{ \
|
|
cemu_assert_debug(newValue < (1u << (__bitWidth))); \
|
|
v &= ~((((1u << (__bitWidth)) - 1u) << (__bitIndex))); \
|
|
v |= (newValue << (__bitIndex)); \
|
|
return *this; \
|
|
} \
|
|
uint32 get_##__regname() const \
|
|
{ \
|
|
return (v >> (__bitIndex))&((1u << (__bitWidth)) - 1u); \
|
|
}
|
|
|
|
#define LATTE_BITFIELD_SIGNED(__regname, __bitIndex, __bitWidth) \
|
|
auto& set_##__regname(sint32 newValue) \
|
|
{ \
|
|
cemu_assert_debug(newValue < (1 << ((__bitWidth)-1))); \
|
|
cemu_assert_debug(newValue >= -(1 << ((__bitWidth)-1))); \
|
|
v &= ~((((1u << (__bitWidth)) - 1u) << (__bitIndex))); \
|
|
v |= (((uint32)newValue & ((1u << (__bitWidth)) - 1u)) << (__bitIndex)); \
|
|
return *this; \
|
|
} \
|
|
sint32 get_##__regname() const \
|
|
{ \
|
|
sint32 r = (v >> (__bitIndex))&((1u << (__bitWidth)) - 1u); \
|
|
r = (r << (32 - (__bitWidth))); \
|
|
r = (r >> (32 - (__bitWidth))); \
|
|
return r; \
|
|
}
|
|
|
|
#define LATTE_BITFIELD_BOOL(__regname, __bitIndex) \
|
|
auto& set_##__regname(bool newValue) \
|
|
{ \
|
|
if(newValue) \
|
|
v |= (1u << (__bitIndex)); \
|
|
else \
|
|
v &= ~(1u << (__bitIndex)); \
|
|
return *this; \
|
|
} \
|
|
bool get_##__regname() const \
|
|
{ \
|
|
return (v&(1u << (__bitIndex))) != 0; \
|
|
}
|
|
|
|
#define LATTE_BITFIELD_TYPED(__regname, __bitIndex, __bitWidth, __typename) \
|
|
auto& set_##__regname(__typename newValue) \
|
|
{ \
|
|
cemu_assert_debug(static_cast<uint32>(newValue) < (1u << (__bitWidth))); \
|
|
v &= ~((((1u << (__bitWidth)) - 1u) << (__bitIndex))); \
|
|
v |= (static_cast<uint32>(newValue) << (__bitIndex)); \
|
|
return *this; \
|
|
} \
|
|
__typename get_##__regname() const \
|
|
{ \
|
|
return static_cast<__typename>((v >> (__bitIndex))&((1u << (__bitWidth)) - 1u)); \
|
|
}
|
|
|
|
#define LATTE_BITFIELD_FULL_TYPED(__regname, __typename) \
|
|
auto& set_##__regname(__typename newValue) \
|
|
{ \
|
|
v = (static_cast<uint32>(newValue)); \
|
|
return *this; \
|
|
} \
|
|
__typename get_##__regname() const \
|
|
{ \
|
|
return static_cast<__typename>(v); \
|
|
}
|
|
|
|
#define LATTE_BITFIELD_FLOAT(__regname) \
|
|
auto& set_##__regname(float newValue) \
|
|
{ \
|
|
*(float*)&v = newValue; \
|
|
return *this; \
|
|
} \
|
|
float get_##__regname() const \
|
|
{ \
|
|
return *(float*)&v; \
|
|
}
|
|
|
|
class LATTEREG
|
|
{
|
|
public:
|
|
uint32 getRawValue() const
|
|
{
|
|
return v;
|
|
}
|
|
|
|
uint32 getRawValueBE() const
|
|
{
|
|
return _swapEndianU32(v);
|
|
}
|
|
|
|
protected:
|
|
uint32 v{};
|
|
};
|
|
|
|
// shared enums
|
|
enum class E_COMPAREFUNC // used by depth test func and alpha test func
|
|
{
|
|
NEVER,
|
|
LESS,
|
|
EQUAL,
|
|
LEQUAL,
|
|
GREATER,
|
|
NOTEQUAL,
|
|
GEQUAL,
|
|
ALWAYS
|
|
};
|
|
|
|
enum class E_ENDIAN_SWAP
|
|
{
|
|
SWAP_NONE = 0,
|
|
};
|
|
|
|
struct LATTE_VGT_PRIMITIVE_TYPE : LATTEREG // 0x2256
|
|
{
|
|
enum class E_PRIMITIVE_TYPE
|
|
{
|
|
NONE = 0x0,
|
|
POINTS = 0x1,
|
|
LINES = 0x2,
|
|
LINE_STRIP = 0x3,
|
|
TRIANGLES = 0x4,
|
|
TRIANGLE_FAN = 0x5,
|
|
TRIANGLE_STRIP = 0x6,
|
|
|
|
LINES_ADJACENT = 0xA,
|
|
LINE_STRIP_ADJACENT = 0xB,
|
|
TRIANGLES_ADJACENT = 0xC,
|
|
TRIANGLE_STRIP_ADJACENT = 0xD,
|
|
|
|
RECTS = 0x11,
|
|
LINE_LOOP = 0x12,
|
|
QUADS = 0x13,
|
|
QUAD_STRIP = 0x14,
|
|
};
|
|
|
|
LATTE_BITFIELD_FULL_TYPED(PRIMITIVE_MODE, E_PRIMITIVE_TYPE);
|
|
};
|
|
|
|
struct LATTE_TD_BORDER_COLOR : LATTEREG // 0x2900 - 0x2A47
|
|
{
|
|
LATTE_BITFIELD_FLOAT(channelValue);
|
|
};
|
|
|
|
struct LATTE_DB_STENCIL_CLEAR : LATTEREG // 0xA00A
|
|
{
|
|
LATTE_BITFIELD(clearValue, 0, 8);
|
|
};
|
|
|
|
struct LATTE_DB_DEPTH_CLEAR : LATTEREG // 0xA00B
|
|
{
|
|
LATTE_BITFIELD_FLOAT(clearValue);
|
|
};
|
|
|
|
struct LATTE_CB_TARGET_MASK : LATTEREG // 0xA08E
|
|
{
|
|
LATTE_BITFIELD_FULL_TYPED(MASK, uint32);
|
|
};
|
|
|
|
struct LATTE_PA_SC_GENERIC_SCISSOR_TL : LATTEREG // 0xA090
|
|
{
|
|
LATTE_BITFIELD(TL_X, 0, 15);
|
|
LATTE_BITFIELD(TL_Y, 16, 15);
|
|
LATTE_BITFIELD_BOOL(WINDOW_OFFSET_DISABLE, 31);
|
|
};
|
|
|
|
struct LATTE_PA_SC_GENERIC_SCISSOR_BR : LATTEREG // 0xA091
|
|
{
|
|
LATTE_BITFIELD(BR_X, 0, 15);
|
|
LATTE_BITFIELD(BR_Y, 16, 15);
|
|
};
|
|
|
|
struct LATTE_VGT_MULTI_PRIM_IB_RESET_INDX : LATTEREG // 0xA103
|
|
{
|
|
LATTE_BITFIELD_FULL_TYPED(RESTART_INDEX, uint32);
|
|
};
|
|
|
|
struct LATTE_SX_ALPHA_TEST_CONTROL : LATTEREG // 0xA104
|
|
{
|
|
using E_ALPHA_FUNC = E_COMPAREFUNC;
|
|
|
|
LATTE_BITFIELD_TYPED(ALPHA_FUNC, 0, 3, E_ALPHA_FUNC);
|
|
LATTE_BITFIELD_BOOL(ALPHA_TEST_ENABLE, 3);
|
|
LATTE_BITFIELD_BOOL(ALPHA_TEST_BYPASS, 8);
|
|
};
|
|
|
|
struct LATTE_CB_BLEND_RED : LATTEREG // 0xA105
|
|
{
|
|
LATTE_BITFIELD_FLOAT(RED);
|
|
};
|
|
|
|
struct LATTE_CB_BLEND_GREEN : LATTEREG // 0xA106
|
|
{
|
|
LATTE_BITFIELD_FLOAT(GREEN);
|
|
};
|
|
|
|
struct LATTE_CB_BLEND_BLUE : LATTEREG // 0xA107
|
|
{
|
|
LATTE_BITFIELD_FLOAT(BLUE);
|
|
};
|
|
|
|
struct LATTE_CB_BLEND_ALPHA : LATTEREG // 0xA108
|
|
{
|
|
LATTE_BITFIELD_FLOAT(ALPHA);
|
|
};
|
|
|
|
struct LATTE_DB_STENCILREFMASK : LATTEREG // 0xA10C
|
|
{
|
|
LATTE_BITFIELD(STENCILREF_F, 0, 8);
|
|
LATTE_BITFIELD(STENCILMASK_F, 8, 8);
|
|
LATTE_BITFIELD(STENCILWRITEMASK_F, 16, 8);
|
|
};
|
|
|
|
struct LATTE_DB_STENCILREFMASK_BF : LATTEREG // 0xA10D
|
|
{
|
|
LATTE_BITFIELD(STENCILREF_B, 0, 8);
|
|
LATTE_BITFIELD(STENCILMASK_B, 8, 8);
|
|
LATTE_BITFIELD(STENCILWRITEMASK_B, 16, 8);
|
|
};
|
|
|
|
struct LATTE_SX_ALPHA_REF : LATTEREG // 0xA10E
|
|
{
|
|
LATTE_BITFIELD_FLOAT(ALPHA_TEST_REF);
|
|
};
|
|
|
|
struct LATTE_PA_CL_VPORT_XSCALE : LATTEREG // 0xA10F
|
|
{
|
|
LATTE_BITFIELD_FLOAT(SCALE);
|
|
};
|
|
|
|
struct LATTE_PA_CL_VPORT_XOFFSET : LATTEREG // 0xA110
|
|
{
|
|
LATTE_BITFIELD_FLOAT(OFFSET);
|
|
};
|
|
|
|
struct LATTE_PA_CL_VPORT_YSCALE : LATTEREG // 0xA111
|
|
{
|
|
LATTE_BITFIELD_FLOAT(SCALE);
|
|
};
|
|
|
|
struct LATTE_PA_CL_VPORT_YOFFSET : LATTEREG // 0xA112
|
|
{
|
|
LATTE_BITFIELD_FLOAT(OFFSET);
|
|
};
|
|
|
|
struct LATTE_PA_CL_VPORT_ZSCALE : LATTEREG // 0xA113
|
|
{
|
|
LATTE_BITFIELD_FLOAT(SCALE);
|
|
};
|
|
|
|
struct LATTE_PA_CL_VPORT_ZOFFSET : LATTEREG // 0xA114
|
|
{
|
|
LATTE_BITFIELD_FLOAT(OFFSET);
|
|
};
|
|
|
|
struct LATTE_CB_BLENDN_CONTROL : LATTEREG // 0xA1E0 - 0xA1E7
|
|
{
|
|
enum class E_BLENDFACTOR
|
|
{
|
|
BLEND_ZERO = 0x00,
|
|
BLEND_ONE = 0x01,
|
|
BLEND_SRC_COLOR = 0x02,
|
|
BLEND_ONE_MINUS_SRC_COLOR = 0x03,
|
|
BLEND_SRC_ALPHA = 0x04,
|
|
BLEND_ONE_MINUS_SRC_ALPHA = 0x05,
|
|
BLEND_DST_ALPHA = 0x06,
|
|
BLEND_ONE_MINUS_DST_ALPHA = 0x07,
|
|
BLEND_DST_COLOR = 0x08,
|
|
BLEND_ONE_MINUS_DST_COLOR = 0x09,
|
|
BLEND_SRC_ALPHA_SATURATE = 0x0A,
|
|
BLEND_BOTH_SRC_ALPHA = 0x0B,
|
|
BLEND_BOTH_INV_SRC_ALPHA = 0x0C,
|
|
BLEND_CONST_COLOR = 0x0D,
|
|
BLEND_ONE_MINUS_CONST_COLOR = 0x0E,
|
|
BLEND_SRC1_COLOR = 0x0F,
|
|
BLEND_INV_SRC1_COLOR = 0x10,
|
|
BLEND_SRC1_ALPHA = 0x11,
|
|
BLEND_INV_SRC1_ALPHA = 0x12,
|
|
BLEND_CONST_ALPHA = 0x13,
|
|
BLEND_ONE_MINUS_CONST_ALPHA = 0x14
|
|
};
|
|
|
|
enum class E_COMBINEFUNC
|
|
{
|
|
DST_PLUS_SRC = 0,
|
|
SRC_MINUS_DST = 1,
|
|
MIN_DST_SRC = 2,
|
|
MAX_DST_SRC = 3,
|
|
DST_MINUS_SRC = 4
|
|
};
|
|
|
|
LATTE_BITFIELD_TYPED(COLOR_SRCBLEND, 0, 5, E_BLENDFACTOR);
|
|
LATTE_BITFIELD_TYPED(COLOR_COMB_FCN, 5, 3, E_COMBINEFUNC);
|
|
LATTE_BITFIELD_TYPED(COLOR_DSTBLEND, 8, 5, E_BLENDFACTOR);
|
|
LATTE_BITFIELD_BOOL(OPACITY_WEIGHT, 13);
|
|
LATTE_BITFIELD_TYPED(ALPHA_SRCBLEND, 16, 5, E_BLENDFACTOR);
|
|
LATTE_BITFIELD_TYPED(ALPHA_COMB_FCN, 21, 3, E_COMBINEFUNC);
|
|
LATTE_BITFIELD_TYPED(ALPHA_DSTBLEND, 24, 5, E_BLENDFACTOR);
|
|
LATTE_BITFIELD_BOOL(SEPARATE_ALPHA_BLEND, 29);
|
|
};
|
|
|
|
struct LATTE_DB_DEPTH_CONTROL : LATTEREG // 0xA200
|
|
{
|
|
using E_ZFUNC = E_COMPAREFUNC;
|
|
using E_STENCILFUNC = E_COMPAREFUNC;
|
|
|
|
enum class E_STENCILACTION
|
|
{
|
|
KEEP,
|
|
ZERO,
|
|
REPLACE,
|
|
INCR,
|
|
DECR,
|
|
INVERT,
|
|
INCR_WRAP,
|
|
DECR_WRAP,
|
|
};
|
|
|
|
LATTE_BITFIELD_BOOL(STENCIL_ENABLE, 0);
|
|
LATTE_BITFIELD_BOOL(Z_ENABLE, 1);
|
|
LATTE_BITFIELD_BOOL(Z_WRITE_ENABLE, 2);
|
|
// bit 3 is unused?
|
|
LATTE_BITFIELD_TYPED(Z_FUNC, 4, 3, E_ZFUNC);
|
|
LATTE_BITFIELD_BOOL(BACK_STENCIL_ENABLE, 7);
|
|
|
|
LATTE_BITFIELD_TYPED(STENCIL_FUNC_F, 8, 3, E_STENCILFUNC);
|
|
LATTE_BITFIELD_TYPED(STENCIL_FAIL_F, 11, 3, E_STENCILACTION);
|
|
LATTE_BITFIELD_TYPED(STENCIL_ZPASS_F, 14, 3, E_STENCILACTION);
|
|
LATTE_BITFIELD_TYPED(STENCIL_ZFAIL_F, 17, 3, E_STENCILACTION);
|
|
|
|
LATTE_BITFIELD_TYPED(STENCIL_FUNC_B, 20, 3, E_STENCILFUNC);
|
|
LATTE_BITFIELD_TYPED(STENCIL_FAIL_B, 23, 3, E_STENCILACTION);
|
|
LATTE_BITFIELD_TYPED(STENCIL_ZPASS_B, 26, 3, E_STENCILACTION);
|
|
LATTE_BITFIELD_TYPED(STENCIL_ZFAIL_B, 29, 3, E_STENCILACTION);
|
|
};
|
|
|
|
struct LATTE_CB_COLOR_CONTROL : LATTEREG // 0xA202
|
|
{
|
|
enum class E_SPECIALOP
|
|
{
|
|
NORMAL = 0, // use state to render
|
|
DISABLE = 1, // dont write color results
|
|
};
|
|
|
|
enum class E_LOGICOP
|
|
{
|
|
CLEAR = 0x00,
|
|
COPY = 0xCC,
|
|
OR = 0xEE,
|
|
SET = 0xFF,
|
|
};
|
|
|
|
LATTE_BITFIELD_BOOL(FOG_ENABLE, 0);
|
|
LATTE_BITFIELD_BOOL(MULTIWRITE_ENABLE, 1);
|
|
LATTE_BITFIELD_BOOL(DITHER_ENABLE, 2);
|
|
LATTE_BITFIELD_BOOL(DEGAMMA_ENABLE, 3);
|
|
LATTE_BITFIELD_TYPED(SPECIAL_OP, 4, 3, E_SPECIALOP);
|
|
LATTE_BITFIELD_BOOL(PER_MRT_BLEND, 7);
|
|
LATTE_BITFIELD(BLEND_MASK, 8, 8);
|
|
LATTE_BITFIELD_TYPED(ROP, 16, 8, E_LOGICOP); // aka logic op
|
|
};
|
|
|
|
struct LATTE_PA_CL_CLIP_CNTL : LATTEREG // 0xA204
|
|
{
|
|
// todo - other fields
|
|
// see R6xx_3D_Registers.pdf
|
|
|
|
LATTE_BITFIELD_BOOL(CLIP_DISABLE, 16);
|
|
|
|
LATTE_BITFIELD_BOOL(DX_CLIP_SPACE_DEF, 19); // GX2 calls this flag HalfZ
|
|
|
|
|
|
LATTE_BITFIELD_BOOL(DX_RASTERIZATION_KILL, 22);
|
|
|
|
LATTE_BITFIELD_BOOL(DX_LINEAR_ATTR_CLIP_ENA, 24); // what does this do?
|
|
|
|
LATTE_BITFIELD_BOOL(ZCLIP_NEAR_DISABLE, 26);
|
|
LATTE_BITFIELD_BOOL(ZCLIP_FAR_DISABLE, 27);
|
|
|
|
};
|
|
|
|
struct LATTE_PA_CL_VTE_CNTL : LATTEREG // 0xA206
|
|
{
|
|
LATTE_BITFIELD_BOOL(VPORT_X_SCALE_ENA, 0);
|
|
LATTE_BITFIELD_BOOL(VPORT_X_OFFSET_ENA, 1);
|
|
|
|
LATTE_BITFIELD_BOOL(VPORT_Y_SCALE_ENA, 2);
|
|
LATTE_BITFIELD_BOOL(VPORT_Y_OFFSET_ENA, 3);
|
|
|
|
LATTE_BITFIELD_BOOL(VPORT_Z_SCALE_ENA, 4);
|
|
LATTE_BITFIELD_BOOL(VPORT_Z_OFFSET_ENA, 5);
|
|
|
|
LATTE_BITFIELD_BOOL(VTX_XY_FMT, 8);
|
|
LATTE_BITFIELD_BOOL(VTX_Z_FMT, 9);
|
|
LATTE_BITFIELD_BOOL(VTX_W0_FMT, 10);
|
|
};
|
|
|
|
struct LATTE_PA_CL_VS_OUT_CNTL : LATTEREG // 0xA207
|
|
{
|
|
LATTE_BITFIELD(CLIP_DIST_ENA_MASK, 0, 8);
|
|
LATTE_BITFIELD(CULL_DIST_ENA_MASK, 8, 8);
|
|
};
|
|
|
|
struct LATTE_PA_SU_POINT_SIZE : LATTEREG // 0xA280
|
|
{
|
|
LATTE_BITFIELD(HEIGHT, 0, 16);
|
|
LATTE_BITFIELD(WIDTH, 16, 16);
|
|
};
|
|
|
|
struct LATTE_PA_SU_POINT_MINMAX : LATTEREG // 0xA281
|
|
{
|
|
LATTE_BITFIELD(MIN_SIZE, 0, 16);
|
|
LATTE_BITFIELD(MAX_SIZE, 16, 16);
|
|
};
|
|
|
|
struct LATTE_VGT_GS_MODE : LATTEREG // 0xA290
|
|
{
|
|
enum class E_MODE
|
|
{
|
|
OFF = 0,
|
|
SCENARIO_A = 1,
|
|
SCENARIO_B = 2,
|
|
SCENARIO_G = 3
|
|
};
|
|
|
|
enum class E_CUT_MODE
|
|
{
|
|
CUT_1024 = 0,
|
|
CUT_512 = 1,
|
|
CUT_256 = 2,
|
|
CUT_128 = 3,
|
|
};
|
|
|
|
enum class E_COMPUTE_MODE
|
|
{
|
|
OFF = 0,
|
|
UKN_1 = 1,
|
|
UKN_2 = 2,
|
|
ON = 3,
|
|
};
|
|
|
|
LATTE_BITFIELD_TYPED(MODE, 0, 2, E_MODE);
|
|
LATTE_BITFIELD_BOOL(ES_PASSTHRU, 2);
|
|
LATTE_BITFIELD_TYPED(CUT_MODE, 3, 2, E_CUT_MODE);
|
|
LATTE_BITFIELD_TYPED(COMPUTE_MODE, 14, 2, E_COMPUTE_MODE);
|
|
LATTE_BITFIELD_BOOL(PARTIAL_THD_AT_EOI, 17);
|
|
};
|
|
|
|
struct LATTE_VGT_DMA_INDEX_TYPE : LATTEREG // 0xA29F
|
|
{
|
|
enum class E_INDEX_TYPE
|
|
{
|
|
U16_LE = 0, // U16
|
|
U32_LE = 1, // U32
|
|
|
|
U16_BE = 4, // U16 + SwapU16
|
|
U32_BE = 9, // U32 + SwapU32
|
|
|
|
// index 0 -> U16
|
|
// index 1 -> U32
|
|
// bit 0x2 -> swap U16
|
|
// bit 0x4 -> swap U32
|
|
// bit 0x8 -> swap U32 (machine word?)
|
|
|
|
AUTO = 0xFFFF, // helper value for tracking auto-generated indices. Not part of the actual enum
|
|
};
|
|
|
|
LATTE_BITFIELD_FULL_TYPED(INDEX_TYPE, E_INDEX_TYPE);
|
|
};
|
|
|
|
struct LATTE_VGT_PRIMITIVEID_EN : LATTEREG // 0xA2A1
|
|
{
|
|
LATTE_BITFIELD_BOOL(PRIMITIVEID_EN, 0);
|
|
};
|
|
|
|
struct LATTE_VGT_MULTI_PRIM_IB_RESET_EN : LATTEREG // 0xA2A5
|
|
{
|
|
LATTE_BITFIELD_BOOL(RESET_EN, 0);
|
|
};
|
|
|
|
struct LATTE_VGT_INSTANCE_STEP_RATE_X : LATTEREG // 0xA2A8-0xA2A9
|
|
{
|
|
LATTE_BITFIELD_FULL_TYPED(STEP_RATE, uint32);
|
|
};
|
|
|
|
struct LATTE_VGT_STRMOUT_BUFFER_SIZE_X : LATTEREG // 0xA2B4 + index * 4
|
|
{
|
|
LATTE_BITFIELD_FULL_TYPED(SIZE, uint32);
|
|
};
|
|
|
|
struct LATTE_VGT_STRMOUT_STRIDE_X : LATTEREG // 0xA2B5 + index * 4
|
|
{
|
|
LATTE_BITFIELD_FULL_TYPED(STRIDE, uint32);
|
|
};
|
|
|
|
struct LATTE_VGT_STRMOUT_BUFFER_BASE_X : LATTEREG // 0xA2B6 + index * 4
|
|
{
|
|
LATTE_BITFIELD_FULL_TYPED(BASE, uint32);
|
|
};
|
|
|
|
struct LATTE_VGT_STRMOUT_BUFFER_OFFSET_X : LATTEREG // 0xA2B7 + index * 4
|
|
{
|
|
LATTE_BITFIELD_FULL_TYPED(BUFFER_OFFSET, uint32);
|
|
};
|
|
|
|
struct LATTE_VGT_STRMOUT_BASE_OFFSET_X : LATTEREG // 0xA2C4-0xA2C7
|
|
{
|
|
LATTE_BITFIELD_FULL_TYPED(BASE_OFFSET, uint32);
|
|
};
|
|
|
|
struct LATTE_VGT_STRMOUT_BUFFER_EN : LATTEREG // 0xA2C8
|
|
{
|
|
LATTE_BITFIELD_BOOL(BUFFER_ENABLE_0, 0);
|
|
LATTE_BITFIELD_BOOL(BUFFER_ENABLE_1, 1);
|
|
LATTE_BITFIELD_BOOL(BUFFER_ENABLE_2, 2);
|
|
LATTE_BITFIELD_BOOL(BUFFER_ENABLE_3, 3);
|
|
};
|
|
|
|
struct LATTE_PA_SU_POLY_OFFSET_CLAMP : LATTEREG // 0xA37F
|
|
{
|
|
LATTE_BITFIELD_FLOAT(CLAMP);
|
|
};
|
|
|
|
struct LATTE_PA_SU_POLY_OFFSET_FRONT_SCALE : LATTEREG // 0xA380
|
|
{
|
|
LATTE_BITFIELD_FLOAT(SCALE);
|
|
};
|
|
|
|
struct LATTE_PA_SU_POLY_OFFSET_FRONT_OFFSET : LATTEREG // 0xA381
|
|
{
|
|
LATTE_BITFIELD_FLOAT(OFFSET);
|
|
};
|
|
|
|
struct LATTE_PA_SU_POLY_OFFSET_BACK_SCALE : LATTEREG // 0xA382
|
|
{
|
|
LATTE_BITFIELD_FLOAT(SCALE);
|
|
};
|
|
|
|
struct LATTE_PA_SU_POLY_OFFSET_BACK_OFFSET : LATTEREG // 0xA383
|
|
{
|
|
LATTE_BITFIELD_FLOAT(OFFSET);
|
|
};
|
|
|
|
struct LATTE_SQ_VTX_SEMANTIC_CLEAR : LATTEREG // 0xA238
|
|
{
|
|
LATTE_BITFIELD_FULL_TYPED(CLEAR_MASK, uint32); // probably a bitmask
|
|
};
|
|
|
|
struct LATTE_SQ_VTX_SEMANTIC_X : LATTEREG // 0xA0E0 - 0xA0FF
|
|
{
|
|
LATTE_BITFIELD(SEMANTIC_ID, 0, 8);
|
|
};
|
|
|
|
struct LATTE_SQ_TEX_RESOURCE_WORD0_N : LATTEREG // 0xE000 + index * 7
|
|
{
|
|
LATTE_BITFIELD_TYPED(DIM, 0, 3, E_DIM);
|
|
LATTE_BITFIELD_TYPED(TILE_MODE, 3, 4, E_HWTILEMODE);
|
|
|
|
LATTE_BITFIELD_BOOL(TILE_TYPE, 7);
|
|
|
|
LATTE_BITFIELD(PITCH, 8, 11);
|
|
LATTE_BITFIELD(WIDTH, 19, 13);
|
|
};
|
|
|
|
struct LATTE_SQ_TEX_RESOURCE_WORD1_N : LATTEREG // 0xE001 + index * 7
|
|
{
|
|
LATTE_BITFIELD(HEIGHT, 0, 13);
|
|
LATTE_BITFIELD(DEPTH, 13, 13);
|
|
LATTE_BITFIELD_TYPED(DATA_FORMAT, 26, 6, E_HWSURFFMT);
|
|
};
|
|
|
|
struct LATTE_SQ_TEX_RESOURCE_WORD2_N : LATTEREG // 0xE002 + index * 7
|
|
{
|
|
LATTE_BITFIELD_FULL_TYPED(BASE_ADDRESS, uint32);
|
|
};
|
|
|
|
struct LATTE_SQ_TEX_RESOURCE_WORD3_N : LATTEREG // 0xE003 + index * 7
|
|
{
|
|
LATTE_BITFIELD_FULL_TYPED(MIP_ADDRESS, uint32);
|
|
};
|
|
|
|
struct LATTE_SQ_TEX_RESOURCE_WORD4_N : LATTEREG // 0xE004 + index * 7
|
|
{
|
|
enum class E_FORMAT_COMP
|
|
{
|
|
COMP_UNSIGNED = 0,
|
|
COMP_SIGNED = 1,
|
|
COMP_UNSIGNED_BIASED = 2,
|
|
};
|
|
|
|
enum class E_NUM_FORMAT_ALL
|
|
{
|
|
NUM_FORMAT_NORM = 0,
|
|
NUM_FORMAT_INT = 1,
|
|
NUM_FORMAT_SCALED = 2,
|
|
};
|
|
|
|
enum class E_SRF_MODE_ALL
|
|
{
|
|
SRF_MODE_ZERO_CLAMP_MINUS_ONE = 0,
|
|
SRF_MODE_NO_ZERO = 1,
|
|
};
|
|
|
|
// using E_ENDIAN_SWAP = E_ENDIAN_SWAP;
|
|
|
|
enum class E_SEL
|
|
{
|
|
SEL_X = 0,
|
|
SEL_Y = 1,
|
|
SEL_Z = 2,
|
|
SEL_W = 3,
|
|
SEL_0 = 4,
|
|
SEL_1 = 5
|
|
};
|
|
|
|
LATTE_BITFIELD_TYPED(FORMAT_COMP_X, 0, 2, E_FORMAT_COMP);
|
|
LATTE_BITFIELD_TYPED(FORMAT_COMP_Y, 2, 2, E_FORMAT_COMP);
|
|
LATTE_BITFIELD_TYPED(FORMAT_COMP_Z, 4, 2, E_FORMAT_COMP);
|
|
LATTE_BITFIELD_TYPED(FORMAT_COMP_W, 6, 2, E_FORMAT_COMP);
|
|
LATTE_BITFIELD_TYPED(NUM_FORM_ALL, 8, 2, E_NUM_FORMAT_ALL);
|
|
LATTE_BITFIELD_TYPED(SRF_MODE_ALL, 10, 1, E_SRF_MODE_ALL);
|
|
LATTE_BITFIELD_BOOL(FORCE_DEGAMMA, 11);
|
|
LATTE_BITFIELD_TYPED(ENDIAN_SWAP, 12, 2, E_ENDIAN_SWAP);
|
|
LATTE_BITFIELD(REQUEST_SIZE, 14, 2);
|
|
LATTE_BITFIELD_TYPED(DST_SEL_X, 16, 3, E_SEL);
|
|
LATTE_BITFIELD_TYPED(DST_SEL_Y, 19, 3, E_SEL);
|
|
LATTE_BITFIELD_TYPED(DST_SEL_Z, 22, 3, E_SEL);
|
|
LATTE_BITFIELD_TYPED(DST_SEL_W, 25, 3, E_SEL);
|
|
LATTE_BITFIELD(BASE_LEVEL, 28, 4);
|
|
};
|
|
|
|
struct LATTE_SQ_TEX_RESOURCE_WORD5_N : LATTEREG // 0xE005 + index * 7
|
|
{
|
|
LATTE_BITFIELD(LAST_LEVEL, 0, 4); // for MSAA textures, this stores the AA level
|
|
LATTE_BITFIELD(BASE_ARRAY, 4, 13);
|
|
LATTE_BITFIELD(LAST_ARRAY, 17, 13);
|
|
LATTE_BITFIELD_BOOL(UKN_BIT_30, 30); // may be a 2 bit value?
|
|
};
|
|
|
|
struct LATTE_SQ_TEX_RESOURCE_WORD6_N : LATTEREG // 0xE006 + index * 7
|
|
{
|
|
enum class E_MPEG_CLAMP
|
|
{
|
|
UKN = 0,
|
|
};
|
|
|
|
enum class E_TYPE
|
|
{
|
|
VTX_INVALID_TEXTURE = 0,
|
|
VTX_INVALID_BUFFER = 1,
|
|
VTX_VALID_TEXTURE = 2,
|
|
VTX_VALID_BUFFER = 3,
|
|
};
|
|
|
|
// unsure if these are correct
|
|
|
|
LATTE_BITFIELD_TYPED(MPEG_CLAMP, 0, 2, E_MPEG_CLAMP);
|
|
LATTE_BITFIELD(MAX_ANISO, 2, 3);
|
|
LATTE_BITFIELD(PERF_MODULATION, 5, 3);
|
|
LATTE_BITFIELD_BOOL(INTERLACED, 8);
|
|
LATTE_BITFIELD_TYPED(TYPE, 30, 2, E_TYPE);
|
|
};
|
|
|
|
struct LATTE_SQ_TEX_SAMPLER_WORD0_0 : LATTEREG // 0xF000+n*3 - 0xF???
|
|
{
|
|
enum class E_CLAMP
|
|
{
|
|
WRAP = 0,
|
|
MIRROR = 1,
|
|
CLAMP_LAST_TEXEL = 2,
|
|
MIRROR_ONCE_LAST_TEXEL = 3,
|
|
CLAMP_HALF_BORDER = 4,
|
|
MIRROR_ONCE_HALF_BORDER = 5,
|
|
CLAMP_BORDER = 6,
|
|
MIRROR_ONCE_BORDER = 7,
|
|
};
|
|
|
|
enum class E_XY_FILTER
|
|
{
|
|
POINT = 0,
|
|
BILINEAR = 1,
|
|
BICUBIC = 2,
|
|
// 3 unused ?
|
|
ANISO_POINT = 4,
|
|
ANISO_BILINEAR = 5,
|
|
// 6, 7 unused ?
|
|
};
|
|
|
|
enum class E_Z_FILTER
|
|
{
|
|
NONE = 0,
|
|
POINT = 1,
|
|
LINEAR = 2,
|
|
// 3 is unused ?
|
|
};
|
|
|
|
enum class E_BORDER_COLOR_TYPE
|
|
{
|
|
TRANSPARENT_BLACK = 0,
|
|
OPAQUE_BLACK = 1,
|
|
OPAQUE_WHITE = 2,
|
|
REGISTER = 3,
|
|
};
|
|
|
|
enum class E_DEPTH_COMPARE
|
|
{
|
|
NEVER = 0,
|
|
LESS = 1,
|
|
EQUAL = 2,
|
|
LEQUAL = 3,
|
|
GREATER = 4,
|
|
NOTEQUAL = 5,
|
|
GEQUAL = 6,
|
|
ALWAYS = 7
|
|
};
|
|
|
|
|
|
enum class E_CHROMA_KEY
|
|
{
|
|
DISABLE = 0,
|
|
KILL = 1,
|
|
BLEND = 2,
|
|
// 3 is unused
|
|
};
|
|
|
|
LATTE_BITFIELD_TYPED(CLAMP_X, 0, 3, E_CLAMP);
|
|
LATTE_BITFIELD_TYPED(CLAMP_Y, 3, 3, E_CLAMP);
|
|
LATTE_BITFIELD_TYPED(CLAMP_Z, 6, 3, E_CLAMP);
|
|
LATTE_BITFIELD_TYPED(XY_MAG_FILTER, 9, 3, E_XY_FILTER);
|
|
LATTE_BITFIELD_TYPED(XY_MIN_FILTER, 12, 3, E_XY_FILTER);
|
|
LATTE_BITFIELD_TYPED(Z_FILTER, 15, 2, E_Z_FILTER);
|
|
LATTE_BITFIELD_TYPED(MIP_FILTER, 17, 2, E_Z_FILTER);
|
|
LATTE_BITFIELD(MAX_ANISO_RATIO, 19, 3);
|
|
LATTE_BITFIELD_TYPED(BORDER_COLOR_TYPE, 22, 2, E_BORDER_COLOR_TYPE);
|
|
LATTE_BITFIELD_BOOL(POINT_SAMPLING_CLAMP, 24);
|
|
LATTE_BITFIELD_BOOL(TEX_ARRAY_OVERRIDE, 25);
|
|
LATTE_BITFIELD_TYPED(DEPTH_COMPARE_FUNCTION, 26, 3, E_DEPTH_COMPARE);
|
|
LATTE_BITFIELD_TYPED(CHROMA_KEY, 28, 2, E_CHROMA_KEY);
|
|
LATTE_BITFIELD_BOOL(LOD_USES_MINOR_AXIS, 25);
|
|
};
|
|
|
|
struct LATTE_SQ_TEX_SAMPLER_WORD1_0 : LATTEREG // 0xF001+n*3 - 0xF???
|
|
{
|
|
LATTE_BITFIELD(MIN_LOD, 0, 10);
|
|
LATTE_BITFIELD(MAX_LOD, 10, 10);
|
|
LATTE_BITFIELD_SIGNED(LOD_BIAS, 20, 12);
|
|
};
|
|
|
|
struct LATTE_SQ_TEX_SAMPLER_WORD2_0 : LATTEREG // 0xF002+n*3 - 0xF???
|
|
{
|
|
enum E_SAMPLER_TYPE
|
|
{
|
|
UKN0 = 0,
|
|
UKN1 = 1,
|
|
};
|
|
|
|
LATTE_BITFIELD(LOD_BIAS_SECONDARY, 0, 12);
|
|
LATTE_BITFIELD_BOOL(MC_COORD_TRUNCATE, 12);
|
|
LATTE_BITFIELD_BOOL(FORCE_DEGAMMA, 13);
|
|
LATTE_BITFIELD_BOOL(HIGH_PRECISION_FILTER, 14);
|
|
|
|
// PERF_MIP at 15, 3 bits
|
|
// PERF_Z at 18, 3 bits
|
|
// bit 21 is unused?
|
|
|
|
LATTE_BITFIELD(ANISO_BIAS, 22, 6); // is size correct?
|
|
|
|
//LATTE_BITFIELD_BOOL(FETCH_4, 26); overlaps with ANISO_BIAS
|
|
//LATTE_BITFIELD_BOOL(SAMPLE_IS_PCF, 27); overlaps with ANISO_BIAS
|
|
|
|
LATTE_BITFIELD_TYPED(TYPE, 31, 1, E_SAMPLER_TYPE);
|
|
};
|
|
|
|
struct LATTE_SQ_PGM_START_X : LATTEREG // 0xA210 / 0xA216 / 0xA21B / 0xA220 / 0xA225
|
|
{
|
|
LATTE_BITFIELD_FULL_TYPED(PGM_START, uint32);
|
|
};
|
|
|
|
struct LATTE_SQ_PGM_RESOURCES_PS : LATTEREG // 0xA214
|
|
{
|
|
LATTE_BITFIELD(NUM_GPRS, 0, 8);
|
|
LATTE_BITFIELD(NUM_STACK_ENTRIES, 8, 8);
|
|
LATTE_BITFIELD_BOOL(DX10_CLAMP, 21); // if true, CLAMP modifier in shaders will return 0 for NaN
|
|
LATTE_BITFIELD(FETCH_CACHE_LINES, 24, 3);
|
|
LATTE_BITFIELD_BOOL(UNCACHED_FIRST_INST, 28);
|
|
LATTE_BITFIELD_BOOL(CLAMP_CONSTS, 31);
|
|
};
|
|
|
|
struct LATTE_SQ_PGM_RESOURCES_VS : LATTEREG // 0xA21A
|
|
{
|
|
LATTE_BITFIELD(NUM_GPRS, 0, 8);
|
|
LATTE_BITFIELD(NUM_STACK_ENTRIES, 8, 8);
|
|
LATTE_BITFIELD_BOOL(DX10_CLAMP, 21); // if true, CLAMP modifier in shaders will return 0 for NaN
|
|
LATTE_BITFIELD(FETCH_CACHE_LINES, 24, 3);
|
|
LATTE_BITFIELD_BOOL(UNCACHED_FIRST_INST, 28);
|
|
};
|
|
|
|
struct LATTE_SQ_PGM_RESOURCES_GS : LATTEREG // 0xA21F
|
|
{
|
|
LATTE_BITFIELD(NUM_GPRS, 0, 8);
|
|
LATTE_BITFIELD(NUM_STACK_ENTRIES, 8, 8);
|
|
LATTE_BITFIELD_BOOL(DX10_CLAMP, 21); // if true, CLAMP modifier in shaders will return 0 for NaN
|
|
};
|
|
|
|
struct LATTE_SQ_PGM_RESOURCES_ES : LATTEREG // 0xA224
|
|
{
|
|
LATTE_BITFIELD(NUM_GPRS, 0, 8);
|
|
LATTE_BITFIELD(NUM_STACK_ENTRIES, 8, 8);
|
|
LATTE_BITFIELD_BOOL(DX10_CLAMP, 21); // if true, CLAMP modifier in shaders will return 0 for NaN
|
|
};
|
|
|
|
struct LATTE_SQ_PGM_RESOURCES_FS : LATTEREG // 0xA229
|
|
{
|
|
LATTE_BITFIELD(NUM_GPRS, 0, 8);
|
|
LATTE_BITFIELD(NUM_STACK_ENTRIES, 8, 8);
|
|
LATTE_BITFIELD_BOOL(DX10_CLAMP, 21); // if true, CLAMP modifier in shaders will return 0 for NaN
|
|
};
|
|
|
|
struct LATTE_SQ_XX_ITEMSIZE : LATTEREG // 0xA227 - 0xA2XX
|
|
{
|
|
// used by:
|
|
// SQ_ESGS_RING_ITEMSIZE
|
|
// SQ_GSVS_RING_ITEMSIZE
|
|
// SQ_ESTMP_RING_ITEMSIZE
|
|
// SQ_GSTMP_RING_ITEMSIZE
|
|
// SQ_VSTMP_RING_ITEMSIZE
|
|
// SQ_PSTMP_RING_ITEMSIZE
|
|
// SQ_FBUF_RING_ITEMSIZE
|
|
// SQ_REDUC_RING_ITEMSIZE
|
|
LATTE_BITFIELD(ITEMSIZE, 0, 15);
|
|
};
|
|
|
|
struct LATTE_PA_SU_SC_MODE_CNTL : LATTEREG // 0xA205
|
|
{
|
|
enum class E_FRONTFACE
|
|
{
|
|
CCW = 0,
|
|
CW = 1
|
|
};
|
|
|
|
enum class E_POLYGONMODE
|
|
{
|
|
UKN0 = 0, // default - render triangles
|
|
};
|
|
|
|
enum class E_PTYPE
|
|
{
|
|
POINTS = 0,
|
|
LINES = 1,
|
|
TRIANGLES = 2,
|
|
};
|
|
|
|
LATTE_BITFIELD_BOOL(CULL_FRONT, 0);
|
|
LATTE_BITFIELD_BOOL(CULL_BACK, 1);
|
|
LATTE_BITFIELD_TYPED(FRONT_FACE, 2, 1, E_FRONTFACE);
|
|
LATTE_BITFIELD_TYPED(POLYGON_MODE, 3, 2, E_POLYGONMODE);
|
|
LATTE_BITFIELD_TYPED(FRONT_POLY_MODE, 5, 3, E_PTYPE);
|
|
LATTE_BITFIELD_TYPED(BACK_POLY_MODE, 8, 3, E_PTYPE);
|
|
LATTE_BITFIELD_BOOL(OFFSET_FRONT_ENABLED, 11);
|
|
LATTE_BITFIELD_BOOL(OFFSET_BACK_ENABLED, 12);
|
|
LATTE_BITFIELD_BOOL(OFFSET_PARA_ENABLED, 13); // offset enable for lines and points?
|
|
// additional fields?
|
|
};
|
|
|
|
struct LATTE_SPI_VS_OUT_CONFIG : LATTEREG // 0xA1B1
|
|
{
|
|
LATTE_BITFIELD_BOOL(VS_PER_COMPONENT, 0);
|
|
LATTE_BITFIELD(VS_EXPORT_COUNT, 1, 5);
|
|
LATTE_BITFIELD_BOOL(EXPORTS_FOG, 8);
|
|
LATTE_BITFIELD(VS_OUT_FOG_VEC_ADDR, 9, 5);
|
|
};
|
|
|
|
struct LATTE_SPI_VS_OUT_ID_N : LATTEREG // 0xA185 - 0xA18E(?) - 0xA1B2 - 0xA1B3
|
|
{
|
|
uint8 get_SEMANTIC(sint32 index)
|
|
{
|
|
cemu_assert_debug(index < 4);
|
|
return (uint8)((v >> (index * 8)) & 0xFF);
|
|
}
|
|
|
|
void set_SEMANTIC(sint32 index, uint8 value)
|
|
{
|
|
cemu_assert_debug(index < 4);
|
|
v &= ~(0xFF << (index * 8));
|
|
v |= (value & 0xFF) << (index * 8);
|
|
}
|
|
};
|
|
|
|
};
|
|
|
|
struct _LatteRegisterSetTextureUnit
|
|
{
|
|
Latte::LATTE_SQ_TEX_RESOURCE_WORD0_N word0;
|
|
Latte::LATTE_SQ_TEX_RESOURCE_WORD1_N word1;
|
|
Latte::LATTE_SQ_TEX_RESOURCE_WORD2_N word2;
|
|
Latte::LATTE_SQ_TEX_RESOURCE_WORD3_N word3;
|
|
Latte::LATTE_SQ_TEX_RESOURCE_WORD4_N word4;
|
|
Latte::LATTE_SQ_TEX_RESOURCE_WORD5_N word5;
|
|
Latte::LATTE_SQ_TEX_RESOURCE_WORD6_N word6;
|
|
};
|
|
|
|
static_assert(sizeof(_LatteRegisterSetTextureUnit) == 28);
|
|
|
|
struct _LatteRegisterSetSampler
|
|
{
|
|
Latte::LATTE_SQ_TEX_SAMPLER_WORD0_0 WORD0;
|
|
Latte::LATTE_SQ_TEX_SAMPLER_WORD1_0 WORD1;
|
|
Latte::LATTE_SQ_TEX_SAMPLER_WORD2_0 WORD2;
|
|
};
|
|
|
|
static_assert(sizeof(_LatteRegisterSetSampler) == 12);
|
|
|
|
struct _LatteRegisterSetSamplerBorderColor
|
|
{
|
|
Latte::LATTE_TD_BORDER_COLOR red;
|
|
Latte::LATTE_TD_BORDER_COLOR green;
|
|
Latte::LATTE_TD_BORDER_COLOR blue;
|
|
Latte::LATTE_TD_BORDER_COLOR alpha;
|
|
};
|
|
|
|
static_assert(sizeof(_LatteRegisterSetSamplerBorderColor) == 16);
|
|
|
|
struct _LatteRegisterSetStreamoutBuffer
|
|
{
|
|
Latte::LATTE_VGT_STRMOUT_BUFFER_SIZE_X SIZE;
|
|
Latte::LATTE_VGT_STRMOUT_STRIDE_X STRIDE;
|
|
Latte::LATTE_VGT_STRMOUT_BUFFER_BASE_X BASE;
|
|
Latte::LATTE_VGT_STRMOUT_BUFFER_OFFSET_X BUFFER_OFFSET;
|
|
};
|
|
|
|
static_assert(sizeof(_LatteRegisterSetStreamoutBuffer) == 16);
|
|
|
|
struct LatteContextRegister
|
|
{
|
|
uint8 padding0[0x08958];
|
|
|
|
/* +0x08958 */ Latte::LATTE_VGT_PRIMITIVE_TYPE VGT_PRIMITIVE_TYPE;
|
|
uint8 padding5[0x0A400 - 0x0895C];
|
|
/* +0x0A400 */ _LatteRegisterSetSamplerBorderColor TD_PS_SAMPLER_BORDER_COLOR[Latte::GPU_LIMITS::NUM_SAMPLERS_PER_STAGE];
|
|
uint8 padding6[0x0A600 - 0x0A520];
|
|
/* +0x0A600 */ _LatteRegisterSetSamplerBorderColor TD_VS_SAMPLER_BORDER_COLOR[Latte::GPU_LIMITS::NUM_SAMPLERS_PER_STAGE];
|
|
uint8 padding7[0x0A800 - 0x0A720];
|
|
/* +0x0A800 */ _LatteRegisterSetSamplerBorderColor TD_GS_SAMPLER_BORDER_COLOR[Latte::GPU_LIMITS::NUM_SAMPLERS_PER_STAGE];
|
|
uint8 padding8[0x28238 - 0x0A920];
|
|
/* +0x28238 */ Latte::LATTE_CB_TARGET_MASK CB_TARGET_MASK;
|
|
uint8 padding_2823C[4];
|
|
/* +0x28240 */ Latte::LATTE_PA_SC_GENERIC_SCISSOR_TL PA_SC_GENERIC_SCISSOR_TL;
|
|
/* +0x28244 */ Latte::LATTE_PA_SC_GENERIC_SCISSOR_BR PA_SC_GENERIC_SCISSOR_BR;
|
|
uint8 padding_28248[0x28380 - 0x28248];
|
|
/* +0x28380 */ Latte::LATTE_SQ_VTX_SEMANTIC_X SQ_VTX_SEMANTIC_X[32];
|
|
/* +0x28400 */ uint8 padding_28400[0x2840C - 0x28400];
|
|
/* +0x2840C */ Latte::LATTE_VGT_MULTI_PRIM_IB_RESET_INDX VGT_MULTI_PRIM_IB_RESET_INDX;
|
|
/* +0x28410 */ Latte::LATTE_SX_ALPHA_TEST_CONTROL SX_ALPHA_TEST_CONTROL;
|
|
/* +0x28414 */ Latte::LATTE_CB_BLEND_RED CB_BLEND_RED;
|
|
/* +0x28418 */ Latte::LATTE_CB_BLEND_GREEN CB_BLEND_GREEN;
|
|
/* +0x2841C */ Latte::LATTE_CB_BLEND_BLUE CB_BLEND_BLUE;
|
|
/* +0x28420 */ Latte::LATTE_CB_BLEND_ALPHA CB_BLEND_ALPHA;
|
|
uint8 padding_28424[0x28430 - 0x28424];
|
|
/* +0x28430 */ Latte::LATTE_DB_STENCILREFMASK DB_STENCILREFMASK;
|
|
/* +0x28434 */ Latte::LATTE_DB_STENCILREFMASK_BF DB_STENCILREFMASK_BF;
|
|
/* +0x28438 */ Latte::LATTE_SX_ALPHA_REF SX_ALPHA_REF;
|
|
/* +0x2843C */ Latte::LATTE_PA_CL_VPORT_XSCALE PA_CL_VPORT_XSCALE;
|
|
/* +0x28440 */ Latte::LATTE_PA_CL_VPORT_XOFFSET PA_CL_VPORT_XOFFSET;
|
|
/* +0x28444 */ Latte::LATTE_PA_CL_VPORT_YSCALE PA_CL_VPORT_YSCALE;
|
|
/* +0x28448 */ Latte::LATTE_PA_CL_VPORT_YOFFSET PA_CL_VPORT_YOFFSET;
|
|
/* +0x2844C */ Latte::LATTE_PA_CL_VPORT_ZSCALE PA_CL_VPORT_ZSCALE;
|
|
/* +0x28450 */ Latte::LATTE_PA_CL_VPORT_ZOFFSET PA_CL_VPORT_ZOFFSET;
|
|
|
|
uint8 padding_28450[0x28614 - 0x28454];
|
|
|
|
/* +0x28614 */ Latte::LATTE_SPI_VS_OUT_ID_N LATTE_SPI_VS_OUT_ID_N[10];
|
|
|
|
uint8 padding_2863C[0x286C4 - 0x2863C];
|
|
|
|
/* +0x286C4 */ Latte::LATTE_SPI_VS_OUT_CONFIG SPI_VS_OUT_CONFIG;
|
|
|
|
uint8 padding_286C8[0x28780 - 0x286C8];
|
|
|
|
/* +0x28780 */ Latte::LATTE_CB_BLENDN_CONTROL CB_BLENDN_CONTROL[8];
|
|
|
|
uint8 padding_287A0[0x28800 - 0x287A0];
|
|
|
|
/* +0x28800 */ Latte::LATTE_DB_DEPTH_CONTROL DB_DEPTH_CONTROL;
|
|
uint8 padding_28804[4];
|
|
/* +0x28808 */ Latte::LATTE_CB_COLOR_CONTROL CB_COLOR_CONTROL;
|
|
uint8 padding_2880C[4];
|
|
/* +0x28810 */ Latte::LATTE_PA_CL_CLIP_CNTL PA_CL_CLIP_CNTL;
|
|
/* +0x28814 */ Latte::LATTE_PA_SU_SC_MODE_CNTL PA_SU_SC_MODE_CNTL;
|
|
/* +0x28818 */ Latte::LATTE_PA_CL_VTE_CNTL PA_CL_VTE_CNTL;
|
|
/* +0x2881C */ Latte::LATTE_PA_CL_VS_OUT_CNTL PA_CL_VS_OUT_CNTL;
|
|
|
|
uint8 padding_2881C[0x28840 - 0x28820];
|
|
|
|
/* +0x28840 */ Latte::LATTE_SQ_PGM_START_X SQ_PGM_START_PS;
|
|
/* +0x28844 */ uint32 ukn28844; // PS size
|
|
/* +0x28848 */ uint32 ukn28848;
|
|
/* +0x2884C */ uint32 ukn2884C;
|
|
/* +0x28850 */ Latte::LATTE_SQ_PGM_RESOURCES_PS SQ_PGM_RESOURCES_PS;
|
|
/* +0x28854 */ uint32 ukn28854; // SQ_PGM_EXPORTS_PS
|
|
/* +0x28858 */ Latte::LATTE_SQ_PGM_START_X SQ_PGM_START_VS;
|
|
/* +0x2885C */ uint32 ukn2885C; // VS size
|
|
/* +0x28860 */ uint32 ukn28860;
|
|
/* +0x28864 */ uint32 ukn28864;
|
|
/* +0x28868 */ Latte::LATTE_SQ_PGM_RESOURCES_VS SQ_PGM_RESOURCES_VS;
|
|
/* +0x2886C */ Latte::LATTE_SQ_PGM_START_X SQ_PGM_START_GS;
|
|
/* +0x28870 */ uint32 ukn28870; // GS size
|
|
/* +0x28874 */ uint32 ukn28874;
|
|
/* +0x28878 */ uint32 ukn28878;
|
|
/* +0x2887C */ Latte::LATTE_SQ_PGM_RESOURCES_GS SQ_PGM_RESOURCES_GS;
|
|
/* +0x28880 */ Latte::LATTE_SQ_PGM_START_X SQ_PGM_START_ES;
|
|
/* +0x28884 */ uint32 ukn28884; // ES size
|
|
/* +0x28888 */ uint32 ukn28888;
|
|
/* +0x2888C */ uint32 ukn2888C;
|
|
/* +0x28890 */ Latte::LATTE_SQ_PGM_RESOURCES_ES SQ_PGM_RESOURCES_ES;
|
|
/* +0x28894 */ Latte::LATTE_SQ_PGM_START_X SQ_PGM_START_FS;
|
|
/* +0x28898 */ uint32 ukn28898; // FS size
|
|
/* +0x2889C */ uint32 ukn2889C;
|
|
/* +0x288A0 */ uint32 ukn288A0;
|
|
/* +0x288A4 */ Latte::LATTE_SQ_PGM_RESOURCES_FS SQ_PGM_RESOURCES_FS;
|
|
/* +0x288A8 */ Latte::LATTE_SQ_XX_ITEMSIZE SQ_ESGS_RING_ITEMSIZE;
|
|
/* +0x288AC */ Latte::LATTE_SQ_XX_ITEMSIZE SQ_GSVS_RING_ITEMSIZE;
|
|
/* +0x288B0 */ Latte::LATTE_SQ_XX_ITEMSIZE SQ_ESTMP_RING_ITEMSIZE;
|
|
/* +0x288B4 */ Latte::LATTE_SQ_XX_ITEMSIZE SQ_GSTMP_RING_ITEMSIZE;
|
|
/* +0x288B8 */ Latte::LATTE_SQ_XX_ITEMSIZE SQ_VSTMP_RING_ITEMSIZE;
|
|
uint8 padding_288BC[0x288E0 - 0x288BC];
|
|
/* +0x288E0 */ Latte::LATTE_SQ_VTX_SEMANTIC_CLEAR SQ_VTX_SEMANTIC_CLEAR;
|
|
uint8 padding_288E4[0x28A00 - 0x288E4];
|
|
/* +0x28A00 */ Latte::LATTE_PA_SU_POINT_SIZE PA_SU_POINT_SIZE;
|
|
/* +0x28A04 */ Latte::LATTE_PA_SU_POINT_MINMAX PA_SU_POINT_MINMAX;
|
|
|
|
uint8 padding_28A08[0x28A40 - 0x28A08];
|
|
|
|
/* +0x28A40 */ Latte::LATTE_VGT_GS_MODE VGT_GS_MODE;
|
|
|
|
uint8 padding_28A44[0x28A7C - 0x28A44];
|
|
|
|
/* +0x28A7C */ Latte::LATTE_VGT_DMA_INDEX_TYPE VGT_DMA_INDEX_TYPE;
|
|
/* +0x28A80 */ uint32 ukn28A80;
|
|
/* +0x28A84 */ Latte::LATTE_VGT_PRIMITIVEID_EN VGT_PRIMITIVEID_EN;
|
|
/* +0x28A88 */ uint32 ukn28A88;
|
|
/* +0x28A8C */ uint32 ukn28A8C;
|
|
/* +0x28A90 */ uint32 ukn28A90;
|
|
/* +0x28A94 */ Latte::LATTE_VGT_MULTI_PRIM_IB_RESET_EN VGT_MULTI_PRIM_IB_RESET_EN;
|
|
/* +0x28A98 */ uint32 ukn28A98;
|
|
/* +0x28A9C */ uint32 ukn28A9C;
|
|
/* +0x28AA0 */ Latte::LATTE_VGT_INSTANCE_STEP_RATE_X VGT_INSTANCE_STEP_RATE_0;
|
|
/* +0x28AA4 */ Latte::LATTE_VGT_INSTANCE_STEP_RATE_X VGT_INSTANCE_STEP_RATE_1;
|
|
|
|
uint8 padding_28AA8[0x28AD0 - 0x28AA8];
|
|
|
|
/* +0x28AD0 */ _LatteRegisterSetStreamoutBuffer VGT_STRMOUT_BUFFER_X[4];
|
|
/* +0x28B10 */ Latte::LATTE_VGT_STRMOUT_BASE_OFFSET_X VGT_STRMOUT_BASE_OFFSET_X[4];
|
|
/* +0x28B20 */ Latte::LATTE_VGT_STRMOUT_BUFFER_EN VGT_STRMOUT_BUFFER_EN;
|
|
|
|
uint8 padding_28B24[0x28DFC - 0x28B24];
|
|
|
|
/* +0x28DFC */ Latte::LATTE_PA_SU_POLY_OFFSET_CLAMP PA_SU_POLY_OFFSET_CLAMP;
|
|
/* +0x28E00 */ Latte::LATTE_PA_SU_POLY_OFFSET_FRONT_SCALE PA_SU_POLY_OFFSET_FRONT_SCALE;
|
|
/* +0x28E04 */ Latte::LATTE_PA_SU_POLY_OFFSET_FRONT_OFFSET PA_SU_POLY_OFFSET_FRONT_OFFSET;
|
|
/* +0x28E08 */ Latte::LATTE_PA_SU_POLY_OFFSET_BACK_SCALE PA_SU_POLY_OFFSET_BACK_SCALE;
|
|
/* +0x28E0C */ Latte::LATTE_PA_SU_POLY_OFFSET_BACK_OFFSET PA_SU_POLY_OFFSET_BACK_OFFSET;
|
|
|
|
uint8 padding_28E10[0x38000 - 0x28E10];
|
|
|
|
// texture units are mapped as following (18 sets each):
|
|
// 0xE000 0x38000 -> pixel shader
|
|
// 0xE460 0x39180 -> vertex shader / compute shader
|
|
// 0xE930 0x3A4C0 -> geometry shader
|
|
// there is register space for exactly 160 ps tex units and 176 vs tex units. It's unknown how many GS units there are.
|
|
|
|
/* +0x38000 */ _LatteRegisterSetTextureUnit SQ_TEX_START_PS[Latte::GPU_LIMITS::NUM_TEXTURES_PER_STAGE];
|
|
_LatteRegisterSetTextureUnit _DUMMY_TEX_UNITS_PS[160 - Latte::GPU_LIMITS::NUM_TEXTURES_PER_STAGE];
|
|
/* +0x39180 */ _LatteRegisterSetTextureUnit SQ_TEX_START_VS[Latte::GPU_LIMITS::NUM_TEXTURES_PER_STAGE];
|
|
_LatteRegisterSetTextureUnit _DUMMY_TEX_UNITS_VS[176 - Latte::GPU_LIMITS::NUM_TEXTURES_PER_STAGE];
|
|
/* +0x3A4C0 */ _LatteRegisterSetTextureUnit SQ_TEX_START_GS[Latte::GPU_LIMITS::NUM_TEXTURES_PER_STAGE];
|
|
|
|
uint8 padding_3A6B8[0x3C000 - 0x3A6B8];
|
|
|
|
/* +0x3C000 */ _LatteRegisterSetSampler SQ_TEX_SAMPLER[18 * 3];
|
|
|
|
/* +0x3C288 */
|
|
uint8 padding_3C288[0x40000 - 0x3C288];
|
|
|
|
/* +0x40000 */
|
|
// special state registers
|
|
uint32 hleSpecialState[9]; // deprecated
|
|
|
|
uint32* GetRawView() const
|
|
{
|
|
return (uint32*)padding0;
|
|
}
|
|
|
|
uint32* GetSpecialStateValues() const
|
|
{
|
|
return (uint32*)hleSpecialState;
|
|
}
|
|
|
|
bool IsRasterizationEnabled() const
|
|
{
|
|
bool rasterizationEnabled = !PA_CL_CLIP_CNTL.get_DX_RASTERIZATION_KILL();
|
|
|
|
// GX2SetSpecialState(0, true) enables DX_RASTERIZATION_KILL, but still expects depth writes to happen? -> Research which stages are disabled by DX_RASTERIZATION_KILL exactly
|
|
// for now we use a workaround:
|
|
if (!PA_CL_VTE_CNTL.get_VPORT_X_OFFSET_ENA())
|
|
rasterizationEnabled = true;
|
|
|
|
// Culling both front and back faces effectively disables rasterization
|
|
uint32 cullFront = PA_SU_SC_MODE_CNTL.get_CULL_FRONT();
|
|
uint32 cullBack = PA_SU_SC_MODE_CNTL.get_CULL_BACK();
|
|
if (cullFront && cullBack)
|
|
rasterizationEnabled = false;
|
|
|
|
return rasterizationEnabled;
|
|
}
|
|
};
|
|
|
|
static_assert(sizeof(LatteContextRegister) == 0x10000 * 4 + 9 * 4);
|
|
|
|
static_assert(offsetof(LatteContextRegister, VGT_PRIMITIVE_TYPE) == Latte::REGADDR::VGT_PRIMITIVE_TYPE * 4);
|
|
static_assert(offsetof(LatteContextRegister, TD_PS_SAMPLER_BORDER_COLOR) == Latte::REGADDR::TD_PS_SAMPLER0_BORDER_RED * 4);
|
|
static_assert(offsetof(LatteContextRegister, TD_VS_SAMPLER_BORDER_COLOR) == Latte::REGADDR::TD_VS_SAMPLER0_BORDER_RED * 4);
|
|
static_assert(offsetof(LatteContextRegister, TD_GS_SAMPLER_BORDER_COLOR) == Latte::REGADDR::TD_GS_SAMPLER0_BORDER_RED * 4);
|
|
static_assert(offsetof(LatteContextRegister, CB_TARGET_MASK) == Latte::REGADDR::CB_TARGET_MASK * 4);
|
|
static_assert(offsetof(LatteContextRegister, PA_SC_GENERIC_SCISSOR_TL) == Latte::REGADDR::PA_SC_GENERIC_SCISSOR_TL * 4);
|
|
static_assert(offsetof(LatteContextRegister, PA_SC_GENERIC_SCISSOR_BR) == Latte::REGADDR::PA_SC_GENERIC_SCISSOR_BR * 4);
|
|
static_assert(offsetof(LatteContextRegister, VGT_MULTI_PRIM_IB_RESET_INDX) == Latte::REGADDR::VGT_MULTI_PRIM_IB_RESET_INDX * 4);
|
|
static_assert(offsetof(LatteContextRegister, VGT_PRIMITIVEID_EN) == Latte::REGADDR::VGT_PRIMITIVEID_EN * 4);
|
|
static_assert(offsetof(LatteContextRegister, VGT_MULTI_PRIM_IB_RESET_EN) == Latte::REGADDR::VGT_MULTI_PRIM_IB_RESET_EN * 4);
|
|
static_assert(offsetof(LatteContextRegister, VGT_INSTANCE_STEP_RATE_0) == Latte::REGADDR::VGT_INSTANCE_STEP_RATE_0 * 4);
|
|
static_assert(offsetof(LatteContextRegister, VGT_INSTANCE_STEP_RATE_1) == Latte::REGADDR::VGT_INSTANCE_STEP_RATE_1 * 4);
|
|
static_assert(offsetof(LatteContextRegister, VGT_STRMOUT_BUFFER_X) == Latte::REGADDR::VGT_STRMOUT_BUFFER_SIZE_0 * 4);
|
|
static_assert(offsetof(LatteContextRegister, VGT_STRMOUT_BASE_OFFSET_X) == Latte::REGADDR::VGT_STRMOUT_BASE_OFFSET_0 * 4);
|
|
static_assert(offsetof(LatteContextRegister, VGT_STRMOUT_BUFFER_EN) == Latte::REGADDR::VGT_STRMOUT_BUFFER_EN * 4);
|
|
static_assert(offsetof(LatteContextRegister, SX_ALPHA_TEST_CONTROL) == Latte::REGADDR::SX_ALPHA_TEST_CONTROL * 4);
|
|
static_assert(offsetof(LatteContextRegister, DB_STENCILREFMASK) == Latte::REGADDR::DB_STENCILREFMASK * 4);
|
|
static_assert(offsetof(LatteContextRegister, DB_STENCILREFMASK_BF) == Latte::REGADDR::DB_STENCILREFMASK_BF * 4);
|
|
static_assert(offsetof(LatteContextRegister, SX_ALPHA_REF) == Latte::REGADDR::SX_ALPHA_REF * 4);
|
|
static_assert(offsetof(LatteContextRegister, CB_BLEND_RED) == Latte::REGADDR::CB_BLEND_RED * 4);
|
|
static_assert(offsetof(LatteContextRegister, CB_BLEND_GREEN) == Latte::REGADDR::CB_BLEND_GREEN * 4);
|
|
static_assert(offsetof(LatteContextRegister, CB_BLEND_BLUE) == Latte::REGADDR::CB_BLEND_BLUE * 4);
|
|
static_assert(offsetof(LatteContextRegister, CB_BLEND_ALPHA) == Latte::REGADDR::CB_BLEND_ALPHA * 4);
|
|
static_assert(offsetof(LatteContextRegister, PA_CL_VPORT_XSCALE) == Latte::REGADDR::PA_CL_VPORT_XSCALE * 4);
|
|
static_assert(offsetof(LatteContextRegister, PA_CL_VPORT_XOFFSET) == Latte::REGADDR::PA_CL_VPORT_XOFFSET * 4);
|
|
static_assert(offsetof(LatteContextRegister, PA_CL_VPORT_YSCALE) == Latte::REGADDR::PA_CL_VPORT_YSCALE * 4);
|
|
static_assert(offsetof(LatteContextRegister, PA_CL_VPORT_YOFFSET) == Latte::REGADDR::PA_CL_VPORT_YOFFSET * 4);
|
|
static_assert(offsetof(LatteContextRegister, PA_CL_VPORT_ZSCALE) == Latte::REGADDR::PA_CL_VPORT_ZSCALE * 4);
|
|
static_assert(offsetof(LatteContextRegister, PA_CL_VPORT_ZOFFSET) == Latte::REGADDR::PA_CL_VPORT_ZOFFSET * 4);
|
|
static_assert(offsetof(LatteContextRegister, PA_CL_CLIP_CNTL) == Latte::REGADDR::PA_CL_CLIP_CNTL * 4);
|
|
static_assert(offsetof(LatteContextRegister, PA_SU_SC_MODE_CNTL) == Latte::REGADDR::PA_SU_SC_MODE_CNTL * 4);
|
|
static_assert(offsetof(LatteContextRegister, PA_CL_VTE_CNTL) == Latte::REGADDR::PA_CL_VTE_CNTL * 4);
|
|
static_assert(offsetof(LatteContextRegister, PA_CL_VS_OUT_CNTL) == Latte::REGADDR::PA_CL_VS_OUT_CNTL * 4);
|
|
static_assert(offsetof(LatteContextRegister, PA_SU_POINT_SIZE) == Latte::REGADDR::PA_SU_POINT_SIZE * 4);
|
|
static_assert(offsetof(LatteContextRegister, PA_SU_POINT_MINMAX) == Latte::REGADDR::PA_SU_POINT_MINMAX * 4);
|
|
static_assert(offsetof(LatteContextRegister, CB_BLENDN_CONTROL) == Latte::REGADDR::CB_BLEND0_CONTROL * 4);
|
|
static_assert(offsetof(LatteContextRegister, DB_DEPTH_CONTROL) == Latte::REGADDR::DB_DEPTH_CONTROL * 4);
|
|
static_assert(offsetof(LatteContextRegister, CB_COLOR_CONTROL) == Latte::REGADDR::CB_COLOR_CONTROL * 4);
|
|
static_assert(offsetof(LatteContextRegister, VGT_GS_MODE) == Latte::REGADDR::VGT_GS_MODE * 4);
|
|
static_assert(offsetof(LatteContextRegister, VGT_DMA_INDEX_TYPE) == Latte::REGADDR::VGT_DMA_INDEX_TYPE * 4);
|
|
static_assert(offsetof(LatteContextRegister, PA_SU_POLY_OFFSET_CLAMP) == Latte::REGADDR::PA_SU_POLY_OFFSET_CLAMP * 4);
|
|
static_assert(offsetof(LatteContextRegister, PA_SU_POLY_OFFSET_FRONT_SCALE) == Latte::REGADDR::PA_SU_POLY_OFFSET_FRONT_SCALE * 4);
|
|
static_assert(offsetof(LatteContextRegister, PA_SU_POLY_OFFSET_FRONT_OFFSET) == Latte::REGADDR::PA_SU_POLY_OFFSET_FRONT_OFFSET * 4);
|
|
static_assert(offsetof(LatteContextRegister, PA_SU_POLY_OFFSET_BACK_SCALE) == Latte::REGADDR::PA_SU_POLY_OFFSET_BACK_SCALE * 4);
|
|
static_assert(offsetof(LatteContextRegister, PA_SU_POLY_OFFSET_BACK_OFFSET) == Latte::REGADDR::PA_SU_POLY_OFFSET_BACK_OFFSET * 4);
|
|
static_assert(offsetof(LatteContextRegister, SQ_VTX_SEMANTIC_X) == Latte::REGADDR::SQ_VTX_SEMANTIC_0 * 4);
|
|
static_assert(offsetof(LatteContextRegister, SQ_VTX_SEMANTIC_CLEAR) == Latte::REGADDR::SQ_VTX_SEMANTIC_CLEAR * 4);
|
|
static_assert(offsetof(LatteContextRegister, SQ_TEX_START_PS) == Latte::REGADDR::SQ_TEX_RESOURCE_WORD0_N_PS * 4);
|
|
static_assert(offsetof(LatteContextRegister, SQ_TEX_START_VS) == Latte::REGADDR::SQ_TEX_RESOURCE_WORD0_N_VS * 4);
|
|
static_assert(offsetof(LatteContextRegister, SQ_TEX_START_GS) == Latte::REGADDR::SQ_TEX_RESOURCE_WORD0_N_GS * 4);
|
|
static_assert(offsetof(LatteContextRegister, SQ_TEX_SAMPLER) == Latte::REGADDR::SQ_TEX_SAMPLER_WORD0_0 * 4);
|
|
static_assert(offsetof(LatteContextRegister, SQ_PGM_START_PS) == Latte::REGADDR::SQ_PGM_START_PS * 4);
|
|
static_assert(offsetof(LatteContextRegister, SQ_PGM_RESOURCES_PS) == Latte::REGADDR::SQ_PGM_RESOURCES_PS * 4);
|
|
static_assert(offsetof(LatteContextRegister, SQ_PGM_START_VS) == Latte::REGADDR::SQ_PGM_START_VS * 4);
|
|
static_assert(offsetof(LatteContextRegister, SQ_PGM_RESOURCES_VS) == Latte::REGADDR::SQ_PGM_RESOURCES_VS * 4);
|
|
static_assert(offsetof(LatteContextRegister, SQ_PGM_START_FS) == Latte::REGADDR::SQ_PGM_START_FS * 4);
|
|
static_assert(offsetof(LatteContextRegister, SQ_PGM_RESOURCES_FS) == Latte::REGADDR::SQ_PGM_RESOURCES_FS * 4);
|
|
static_assert(offsetof(LatteContextRegister, SQ_PGM_START_ES) == Latte::REGADDR::SQ_PGM_START_ES * 4);
|
|
static_assert(offsetof(LatteContextRegister, SQ_PGM_RESOURCES_ES) == Latte::REGADDR::SQ_PGM_RESOURCES_ES * 4);
|
|
static_assert(offsetof(LatteContextRegister, SQ_PGM_START_GS) == Latte::REGADDR::SQ_PGM_START_GS * 4);
|
|
static_assert(offsetof(LatteContextRegister, SQ_PGM_RESOURCES_GS) == Latte::REGADDR::SQ_PGM_RESOURCES_GS * 4);
|
|
static_assert(offsetof(LatteContextRegister, SPI_VS_OUT_CONFIG) == Latte::REGADDR::SPI_VS_OUT_CONFIG * 4);
|
|
static_assert(offsetof(LatteContextRegister, LATTE_SPI_VS_OUT_ID_N) == Latte::REGADDR::SPI_VS_OUT_ID_0 * 4);
|