summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorPokechu22 <Pokechu022@gmail.com>2021-02-08 15:22:10 -0800
committerPokechu22 <Pokechu022@gmail.com>2021-03-06 19:27:08 -0800
commitf749fcfa9f42cda679ff7f4288c8418d2b56b08d (patch)
tree5bcc8c255eae974638c20f1a4e76a22fcaee69e4 /Source
parentc27efb3f1fefa49db7962532865fbbe483f248f1 (diff)
Convert CPMemory to BitField and enum class
Additionally, VCacheEnhance has been added to UVAT_group1. According to YAGCD, this field is always 1. TVtxDesc also now has separate low and high fields whose hex values correspond with the proper registers, instead of having one 33-bit value. This change was made in a way that should be backwards-compatible.
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/Core/FifoPlayer/FifoAnalyzer.cpp58
-rw-r--r--Source/Core/Core/FifoPlayer/FifoRecordAnalyzer.cpp21
-rw-r--r--Source/Core/VideoBackends/Software/SWVertexLoader.cpp4
-rw-r--r--Source/Core/VideoCommon/CPMemory.cpp4
-rw-r--r--Source/Core/VideoCommon/CPMemory.h377
-rw-r--r--Source/Core/VideoCommon/VertexLoader.cpp148
-rw-r--r--Source/Core/VideoCommon/VertexLoaderARM64.cpp145
-rw-r--r--Source/Core/VideoCommon/VertexLoaderARM64.h14
-rw-r--r--Source/Core/VideoCommon/VertexLoaderBase.cpp66
-rw-r--r--Source/Core/VideoCommon/VertexLoaderBase.h4
-rw-r--r--Source/Core/VideoCommon/VertexLoaderManager.cpp33
-rw-r--r--Source/Core/VideoCommon/VertexLoaderX64.cpp125
-rw-r--r--Source/Core/VideoCommon/VertexLoaderX64.h13
-rw-r--r--Source/Core/VideoCommon/VertexLoader_Normal.cpp11
-rw-r--r--Source/Core/VideoCommon/VertexLoader_Normal.h10
-rw-r--r--Source/Core/VideoCommon/VertexLoader_Position.cpp11
-rw-r--r--Source/Core/VideoCommon/VertexLoader_Position.h10
-rw-r--r--Source/Core/VideoCommon/VertexLoader_TextCoord.cpp11
-rw-r--r--Source/Core/VideoCommon/VertexLoader_TextCoord.h10
-rw-r--r--Source/Core/VideoCommon/VertexShaderManager.cpp6
-rw-r--r--Source/UnitTests/VideoCommon/VertexLoaderTest.cpp223
21 files changed, 703 insertions, 601 deletions
diff --git a/Source/Core/Core/FifoPlayer/FifoAnalyzer.cpp b/Source/Core/Core/FifoPlayer/FifoAnalyzer.cpp
index 35305bcff3..bf435d32b2 100644
--- a/Source/Core/Core/FifoPlayer/FifoAnalyzer.cpp
+++ b/Source/Core/Core/FifoPlayer/FifoAnalyzer.cpp
@@ -49,21 +49,17 @@ std::array<int, 21> CalculateVertexElementSizes(int vatIndex, const CPMemory& cp
const VAT& vtxAttr = cpMem.vtxAttr[vatIndex];
// Colors
- const std::array<u64, 2> colDesc{
- vtxDesc.Color0,
- vtxDesc.Color1,
- };
- const std::array<u32, 2> colComp{
+ const std::array<ColorFormat, 2> colComp{
vtxAttr.g0.Color0Comp,
vtxAttr.g0.Color1Comp,
};
- const std::array<u32, 8> tcElements{
+ const std::array<TexComponentCount, 8> tcElements{
vtxAttr.g0.Tex0CoordElements, vtxAttr.g1.Tex1CoordElements, vtxAttr.g1.Tex2CoordElements,
vtxAttr.g1.Tex3CoordElements, vtxAttr.g1.Tex4CoordElements, vtxAttr.g2.Tex5CoordElements,
vtxAttr.g2.Tex6CoordElements, vtxAttr.g2.Tex7CoordElements,
};
- const std::array<u32, 8> tcFormat{
+ const std::array<ComponentFormat, 8> tcFormat{
vtxAttr.g0.Tex0CoordFormat, vtxAttr.g1.Tex1CoordFormat, vtxAttr.g1.Tex2CoordFormat,
vtxAttr.g1.Tex3CoordFormat, vtxAttr.g1.Tex4CoordFormat, vtxAttr.g2.Tex5CoordFormat,
vtxAttr.g2.Tex6CoordFormat, vtxAttr.g2.Tex7CoordFormat,
@@ -72,21 +68,20 @@ std::array<int, 21> CalculateVertexElementSizes(int vatIndex, const CPMemory& cp
std::array<int, 21> sizes{};
// Add position and texture matrix indices
- u64 vtxDescHex = cpMem.vtxDesc.Hex;
- for (int i = 0; i < 9; ++i)
+ sizes[0] = vtxDesc.low.PosMatIdx;
+ for (size_t i = 0; i < vtxDesc.low.TexMatIdx.Size(); ++i)
{
- sizes[i] = vtxDescHex & 1;
- vtxDescHex >>= 1;
+ sizes[i + 1] = vtxDesc.low.TexMatIdx[i];
}
// Position
- sizes[9] = VertexLoader_Position::GetSize(vtxDesc.Position, vtxAttr.g0.PosFormat,
+ sizes[9] = VertexLoader_Position::GetSize(vtxDesc.low.Position, vtxAttr.g0.PosFormat,
vtxAttr.g0.PosElements);
// Normals
- if (vtxDesc.Normal != NOT_PRESENT)
+ if (vtxDesc.low.Normal != VertexComponentFormat::NotPresent)
{
- sizes[10] = VertexLoader_Normal::GetSize(vtxDesc.Normal, vtxAttr.g0.NormalFormat,
+ sizes[10] = VertexLoader_Normal::GetSize(vtxDesc.low.Normal, vtxAttr.g0.NormalFormat,
vtxAttr.g0.NormalElements, vtxAttr.g0.NormalIndex3);
}
else
@@ -95,33 +90,33 @@ std::array<int, 21> CalculateVertexElementSizes(int vatIndex, const CPMemory& cp
}
// Colors
- for (size_t i = 0; i < colDesc.size(); i++)
+ for (size_t i = 0; i < vtxDesc.low.Color.Size(); i++)
{
int size = 0;
- switch (colDesc[i])
+ switch (vtxDesc.low.Color[i])
{
- case NOT_PRESENT:
+ case VertexComponentFormat::NotPresent:
break;
- case DIRECT:
+ case VertexComponentFormat::Direct:
switch (colComp[i])
{
- case FORMAT_16B_565:
+ case ColorFormat::RGB565:
size = 2;
break;
- case FORMAT_24B_888:
+ case ColorFormat::RGB888:
size = 3;
break;
- case FORMAT_32B_888x:
+ case ColorFormat::RGB888x:
size = 4;
break;
- case FORMAT_16B_4444:
+ case ColorFormat::RGBA4444:
size = 2;
break;
- case FORMAT_24B_6666:
+ case ColorFormat::RGBA6666:
size = 3;
break;
- case FORMAT_32B_8888:
+ case ColorFormat::RGBA8888:
size = 4;
break;
default:
@@ -129,10 +124,10 @@ std::array<int, 21> CalculateVertexElementSizes(int vatIndex, const CPMemory& cp
break;
}
break;
- case INDEX8:
+ case VertexComponentFormat::Index8:
size = 1;
break;
- case INDEX16:
+ case VertexComponentFormat::Index16:
size = 2;
break;
}
@@ -141,11 +136,10 @@ std::array<int, 21> CalculateVertexElementSizes(int vatIndex, const CPMemory& cp
}
// Texture coordinates
- vtxDescHex = vtxDesc.Hex >> 17;
for (size_t i = 0; i < tcFormat.size(); i++)
{
- sizes[13 + i] = VertexLoader_TextCoord::GetSize(vtxDescHex & 3, tcFormat[i], tcElements[i]);
- vtxDescHex >>= 2;
+ sizes[13 + i] =
+ VertexLoader_TextCoord::GetSize(vtxDesc.high.TexCoord[i], tcFormat[i], tcElements[i]);
}
return sizes;
@@ -267,13 +261,11 @@ void LoadCPReg(u32 subCmd, u32 value, CPMemory& cpMem)
switch (subCmd & 0xF0)
{
case 0x50:
- cpMem.vtxDesc.Hex &= ~0x1FFFF; // keep the Upper bits
- cpMem.vtxDesc.Hex |= value;
+ cpMem.vtxDesc.low.Hex = value;
break;
case 0x60:
- cpMem.vtxDesc.Hex &= 0x1FFFF; // keep the lower 17Bits
- cpMem.vtxDesc.Hex |= (u64)value << 17;
+ cpMem.vtxDesc.high.Hex = value;
break;
case 0x70:
diff --git a/Source/Core/Core/FifoPlayer/FifoRecordAnalyzer.cpp b/Source/Core/Core/FifoPlayer/FifoRecordAnalyzer.cpp
index 284ecba620..992df015a9 100644
--- a/Source/Core/Core/FifoPlayer/FifoRecordAnalyzer.cpp
+++ b/Source/Core/Core/FifoPlayer/FifoRecordAnalyzer.cpp
@@ -6,6 +6,7 @@
#include <algorithm>
+#include "Common/MsgHandler.h"
#include "Core/FifoPlayer/FifoAnalyzer.h"
#include "Core/FifoPlayer/FifoRecorder.h"
#include "Core/HW/Memmap.h"
@@ -44,14 +45,28 @@ void FifoRecordAnalyzer::WriteVertexArray(int arrayIndex, const u8* vertexData,
int numVertices)
{
// Skip if not indexed array
- int arrayType = (s_CpMem.vtxDesc.Hex >> (9 + (arrayIndex * 2))) & 3;
- if (arrayType < 2)
+ VertexComponentFormat arrayType;
+ if (arrayIndex == ARRAY_POSITION)
+ arrayType = s_CpMem.vtxDesc.low.Position;
+ else if (arrayIndex == ARRAY_NORMAL)
+ arrayType = s_CpMem.vtxDesc.low.Normal;
+ else if (arrayIndex == ARRAY_COLOR || arrayIndex == ARRAY_COLOR2)
+ arrayType = s_CpMem.vtxDesc.low.Color[arrayIndex - ARRAY_COLOR];
+ else if (arrayIndex >= ARRAY_POSITION && arrayIndex < ARRAY_POSITION + 8)
+ arrayType = s_CpMem.vtxDesc.high.TexCoord[arrayIndex - ARRAY_POSITION];
+ else
+ {
+ PanicAlertFmt("Invalid arrayIndex {}", arrayIndex);
+ return;
+ }
+
+ if (!IsIndexed(arrayType))
return;
int maxIndex = 0;
// Determine min and max indices
- if (arrayType == INDEX8)
+ if (arrayType == VertexComponentFormat::Index8)
{
for (int i = 0; i < numVertices; ++i)
{
diff --git a/Source/Core/VideoBackends/Software/SWVertexLoader.cpp b/Source/Core/VideoBackends/Software/SWVertexLoader.cpp
index 3e90f69614..fdcafc71bf 100644
--- a/Source/Core/VideoBackends/Software/SWVertexLoader.cpp
+++ b/Source/Core/VideoBackends/Software/SWVertexLoader.cpp
@@ -183,8 +183,8 @@ static void ParseColorAttributes(InputVertexData* dst, DataReader& src,
const auto set_default_color = [](u8* color, int i) {
// The default alpha channel seems to depend on the number of components in the vertex format.
const auto& g0 = g_main_cp_state.vtx_attr[g_main_cp_state.last_id].g0;
- const u32 color_elements = i == 0 ? g0.Color0Elements : g0.Color1Elements;
- color[0] = color_elements == 0 ? 255 : 0;
+ const auto color_elements = i == 0 ? g0.Color0Elements.Value() : g0.Color1Elements.Value();
+ color[0] = color_elements == ColorComponentCount::RGB ? 255 : 0;
color[1] = 255;
color[2] = 255;
color[3] = 255;
diff --git a/Source/Core/VideoCommon/CPMemory.cpp b/Source/Core/VideoCommon/CPMemory.cpp
index 52384cddaf..b4d118bbb4 100644
--- a/Source/Core/VideoCommon/CPMemory.cpp
+++ b/Source/Core/VideoCommon/CPMemory.cpp
@@ -17,7 +17,9 @@ void DoCPState(PointerWrap& p)
p.DoArray(g_main_cp_state.array_strides);
p.Do(g_main_cp_state.matrix_index_a);
p.Do(g_main_cp_state.matrix_index_b);
- p.Do(g_main_cp_state.vtx_desc.Hex);
+ u64 vtx_desc = g_main_cp_state.vtx_desc.GetLegacyHex();
+ p.Do(vtx_desc);
+ g_main_cp_state.vtx_desc.SetLegacyHex(vtx_desc);
p.DoArray(g_main_cp_state.vtx_attr);
p.DoMarker("CP Memory");
if (p.mode == PointerWrap::MODE_READ)
diff --git a/Source/Core/VideoCommon/CPMemory.h b/Source/Core/VideoCommon/CPMemory.h
index 03794a7e0d..83550eb5f2 100644
--- a/Source/Core/VideoCommon/CPMemory.h
+++ b/Source/Core/VideoCommon/CPMemory.h
@@ -4,8 +4,11 @@
#pragma once
+#include "Common/BitField.h"
#include "Common/BitSet.h"
#include "Common/CommonTypes.h"
+#include "Common/EnumFormatter.h"
+#include "Common/MsgHandler.h"
enum
{
@@ -50,176 +53,262 @@ enum
};
// Vertex components
-enum
+enum class VertexComponentFormat
+{
+ NotPresent = 0,
+ Direct = 1,
+ Index8 = 2,
+ Index16 = 3,
+};
+template <>
+struct fmt::formatter<VertexComponentFormat> : EnumFormatter<VertexComponentFormat::Index16>
{
- NOT_PRESENT = 0,
- DIRECT = 1,
- INDEX8 = 2,
- INDEX16 = 3,
+ formatter() : EnumFormatter({"Not present", "Direct", "8-bit index", "16-bit index"}) {}
+};
- MASK_INDEXED = 2,
+constexpr bool IsIndexed(VertexComponentFormat format)
+{
+ return format == VertexComponentFormat::Index8 || format == VertexComponentFormat::Index16;
+}
+
+enum class ComponentFormat
+{
+ UByte = 0, // Invalid for normals
+ Byte = 1,
+ UShort = 2, // Invalid for normals
+ Short = 3,
+ Float = 4,
+};
+template <>
+struct fmt::formatter<ComponentFormat> : EnumFormatter<ComponentFormat::Float>
+{
+ formatter() : EnumFormatter({"Unsigned Byte", "Byte", "Unsigned Short", "Short", "Float"}) {}
};
-enum
+constexpr u32 GetElementSize(ComponentFormat format)
+{
+ switch (format)
+ {
+ case ComponentFormat::UByte:
+ case ComponentFormat::Byte:
+ return 1;
+ case ComponentFormat::UShort:
+ case ComponentFormat::Short:
+ return 2;
+ case ComponentFormat::Float:
+ return 4;
+ default:
+ PanicAlertFmt("Unknown format {}", format);
+ return 0;
+ }
+}
+
+enum class CoordComponentCount
+{
+ XY = 0,
+ XYZ = 1,
+};
+template <>
+struct fmt::formatter<CoordComponentCount> : EnumFormatter<CoordComponentCount::XYZ>
{
- FORMAT_UBYTE = 0, // 2 Cmp
- FORMAT_BYTE = 1, // 3 Cmp
- FORMAT_USHORT = 2,
- FORMAT_SHORT = 3,
- FORMAT_FLOAT = 4,
+ formatter() : EnumFormatter({"2 (x, y)", "3 (x, y, z)"}) {}
};
-enum
+enum class NormalComponentCount
+{
+ N = 0,
+ NBT = 1,
+};
+template <>
+struct fmt::formatter<NormalComponentCount> : EnumFormatter<NormalComponentCount::NBT>
{
- FORMAT_16B_565 = 0, // NA
- FORMAT_24B_888 = 1,
- FORMAT_32B_888x = 2,
- FORMAT_16B_4444 = 3,
- FORMAT_24B_6666 = 4,
- FORMAT_32B_8888 = 5,
+ formatter() : EnumFormatter({"1 (n)", "3 (n, b, t)"}) {}
};
-#pragma pack(4)
-union TVtxDesc
+enum class ColorComponentCount
{
- u64 Hex;
- struct
- {
- // 0: not present
- // 1: present
- u64 PosMatIdx : 1;
- u64 Tex0MatIdx : 1;
- u64 Tex1MatIdx : 1;
- u64 Tex2MatIdx : 1;
- u64 Tex3MatIdx : 1;
- u64 Tex4MatIdx : 1;
- u64 Tex5MatIdx : 1;
- u64 Tex6MatIdx : 1;
- u64 Tex7MatIdx : 1;
-
- // 00: not present
- // 01: direct
- // 10: 8 bit index
- // 11: 16 bit index
- u64 Position : 2;
- u64 Normal : 2;
- u64 Color0 : 2;
- u64 Color1 : 2;
- u64 Tex0Coord : 2;
- u64 Tex1Coord : 2;
- u64 Tex2Coord : 2;
- u64 Tex3Coord : 2;
- u64 Tex4Coord : 2;
- u64 Tex5Coord : 2;
- u64 Tex6Coord : 2;
- u64 Tex7Coord : 2;
- u64 : 31;
+ RGB = 0,
+ RGBA = 1,
+};
+template <>
+struct fmt::formatter<ColorComponentCount> : EnumFormatter<ColorComponentCount::RGBA>
+{
+ formatter() : EnumFormatter({"3 (r, g, b)", "4 (r, g, b, a)"}) {}
+};
+
+enum class ColorFormat
+{
+ RGB565 = 0, // 16b
+ RGB888 = 1, // 24b
+ RGB888x = 2, // 32b
+ RGBA4444 = 3, // 16b
+ RGBA6666 = 4, // 24b
+ RGBA8888 = 5, // 32b
+};
+template <>
+struct fmt::formatter<ColorFormat> : EnumFormatter<ColorFormat::RGBA8888>
+{
+ static constexpr array_type names = {
+ "RGB 16 bits 565", "RGB 24 bits 888", "RGB 32 bits 888x",
+ "RGBA 16 bits 4444", "RGBA 24 bits 6666", "RGBA 32 bits 8888",
};
+ formatter() : EnumFormatter(names) {}
+};
- struct
+enum class TexComponentCount
+{
+ S = 0,
+ ST = 1,
+};
+template <>
+struct fmt::formatter<TexComponentCount> : EnumFormatter<TexComponentCount::ST>
+{
+ formatter() : EnumFormatter({"1 (s)", "2 (s, t)"}) {}
+};
+
+struct TVtxDesc
+{
+ union Low
{
- u32 Hex0, Hex1;
+ // false: not present
+ // true: present
+ BitField<0, 1, bool, u32> PosMatIdx;
+ BitField<1, 1, bool, u32> Tex0MatIdx;
+ BitField<2, 1, bool, u32> Tex1MatIdx;
+ BitField<3, 1, bool, u32> Tex2MatIdx;
+ BitField<4, 1, bool, u32> Tex3MatIdx;
+ BitField<5, 1, bool, u32> Tex4MatIdx;
+ BitField<6, 1, bool, u32> Tex5MatIdx;
+ BitField<7, 1, bool, u32> Tex6MatIdx;
+ BitField<8, 1, bool, u32> Tex7MatIdx;
+ BitFieldArray<1, 1, 8, bool, u32> TexMatIdx;
+
+ BitField<9, 2, VertexComponentFormat> Position;
+ BitField<11, 2, VertexComponentFormat> Normal;
+ BitField<13, 2, VertexComponentFormat> Color0;
+ BitField<15, 2, VertexComponentFormat> Color1;
+ BitFieldArray<13, 2, 2, VertexComponentFormat> Color;
+
+ u32 Hex;
+ };
+ union High
+ {
+ BitField<0, 2, VertexComponentFormat> Tex0Coord;
+ BitField<2, 2, VertexComponentFormat> Tex1Coord;
+ BitField<4, 2, VertexComponentFormat> Tex2Coord;
+ BitField<6, 2, VertexComponentFormat> Tex3Coord;
+ BitField<8, 2, VertexComponentFormat> Tex4Coord;
+ BitField<10, 2, VertexComponentFormat> Tex5Coord;
+ BitField<12, 2, VertexComponentFormat> Tex6Coord;
+ BitField<14, 2, VertexComponentFormat> Tex7Coord;
+ BitFieldArray<0, 2, 8, VertexComponentFormat> TexCoord;
+
+ u32 Hex;
};
- // Easily index into the Position..Tex7Coord fields.
- u32 GetVertexArrayStatus(int idx) { return (Hex >> (9 + idx * 2)) & 0x3; }
+ Low low;
+ High high;
+
+ // This structure was originally packed into bits 0..32, using 33 total bits.
+ // The actual format has 17 bits in the low one and 16 bits in the high one,
+ // but the old format is still supported for compatibility.
+ u64 GetLegacyHex() const { return (low.Hex & 0x1FFFF) | (u64(high.Hex) << 17); }
+ u32 GetLegacyHex0() const { return static_cast<u32>(GetLegacyHex()); }
+ // Only *1* bit is used in this
+ u32 GetLegacyHex1() const { return static_cast<u32>(GetLegacyHex() >> 32); }
+ void SetLegacyHex(u64 value)
+ {
+ low.Hex = value & 0x1FFFF;
+ high.Hex = value >> 17;
+ }
};
union UVAT_group0
{
u32 Hex;
- struct
- {
- // 0:8
- u32 PosElements : 1;
- u32 PosFormat : 3;
- u32 PosFrac : 5;
- // 9:12
- u32 NormalElements : 1;
- u32 NormalFormat : 3;
- // 13:16
- u32 Color0Elements : 1;
- u32 Color0Comp : 3;
- // 17:20
- u32 Color1Elements : 1;
- u32 Color1Comp : 3;
- // 21:29
- u32 Tex0CoordElements : 1;
- u32 Tex0CoordFormat : 3;
- u32 Tex0Frac : 5;
- // 30:31
- u32 ByteDequant : 1;
- u32 NormalIndex3 : 1;
- };
+ // 0:8
+ BitField<0, 1, CoordComponentCount> PosElements;
+ BitField<1, 3, ComponentFormat> PosFormat;
+ BitField<4, 5, u32> PosFrac;
+ // 9:12
+ BitField<9, 1, NormalComponentCount> NormalElements;
+ BitField<10, 3, ComponentFormat> NormalFormat;
+ // 13:16
+ BitField<13, 1, ColorComponentCount> Color0Elements;
+ BitField<14, 3, ColorFormat> Color0Comp;
+ // 17:20
+ BitField<17, 1, ColorComponentCount> Color1Elements;
+ BitField<18, 3, ColorFormat> Color1Comp;
+ // 21:29
+ BitField<21, 1, TexComponentCount> Tex0CoordElements;
+ BitField<22, 3, ComponentFormat> Tex0CoordFormat;
+ BitField<25, 5, u32> Tex0Frac;
+ // 30:31
+ BitField<30, 1, u32> ByteDequant;
+ BitField<31, 1, u32> NormalIndex3;
};
union UVAT_group1
{
u32 Hex;
- struct
- {
- // 0:8
- u32 Tex1CoordElements : 1;
- u32 Tex1CoordFormat : 3;
- u32 Tex1Frac : 5;
- // 9:17
- u32 Tex2CoordElements : 1;
- u32 Tex2CoordFormat : 3;
- u32 Tex2Frac : 5;
- // 18:26
- u32 Tex3CoordElements : 1;
- u32 Tex3CoordFormat : 3;
- u32 Tex3Frac : 5;
- // 27:30
- u32 Tex4CoordElements : 1;
- u32 Tex4CoordFormat : 3;
- //
- u32 : 1;
- };
+ // 0:8
+ BitField<0, 1, TexComponentCount> Tex1CoordElements;
+ BitField<1, 3, ComponentFormat> Tex1CoordFormat;
+ BitField<4, 5, u32> Tex1Frac;
+ // 9:17
+ BitField<9, 1, TexComponentCount> Tex2CoordElements;
+ BitField<10, 3, ComponentFormat> Tex2CoordFormat;
+ BitField<13, 5, u32> Tex2Frac;
+ // 18:26
+ BitField<18, 1, TexComponentCount> Tex3CoordElements;
+ BitField<19, 3, ComponentFormat> Tex3CoordFormat;
+ BitField<22, 5, u32> Tex3Frac;
+ // 27:30
+ BitField<27, 1, TexComponentCount> Tex4CoordElements;
+ BitField<28, 3, ComponentFormat> Tex4CoordFormat;
+ // 31
+ BitField<31, 1, u32> VCacheEnhance;
};
union UVAT_group2
{
u32 Hex;
- struct
- {
- // 0:4
- u32 Tex4Frac : 5;
- // 5:13
- u32 Tex5CoordElements : 1;
- u32 Tex5CoordFormat : 3;
- u32 Tex5Frac : 5;
- // 14:22
- u32 Tex6CoordElements : 1;
- u32 Tex6CoordFormat : 3;
- u32 Tex6Frac : 5;
- // 23:31
- u32 Tex7CoordElements : 1;
- u32 Tex7CoordFormat : 3;
- u32 Tex7Frac : 5;
- };
+ // 0:4
+ BitField<0, 5, u32> Tex4Frac;
+ // 5:13
+ BitField<5, 1, TexComponentCount> Tex5CoordElements;
+ BitField<6, 3, ComponentFormat> Tex5CoordFormat;
+ BitField<9, 5, u32> Tex5Frac;
+ // 14:22
+ BitField<14, 1, TexComponentCount> Tex6CoordElements;
+ BitField<15, 3, ComponentFormat> Tex6CoordFormat;
+ BitField<18, 5, u32> Tex6Frac;
+ // 23:31
+ BitField<23, 1, TexComponentCount> Tex7CoordElements;
+ BitField<24, 3, ComponentFormat> Tex7CoordFormat;
+ BitField<27, 5, u32> Tex7Frac;
};
struct ColorAttr
{
- u8 Elements;
- u8 Comp;
+ ColorComponentCount Elements;
+ ColorFormat Comp;
};
struct TexAttr
{
- u8 Elements;
- u8 Format;
+ TexComponentCount Elements;
+ ComponentFormat Format;
u8 Frac;
};
struct TVtxAttr
{
- u8 PosElements;
- u8 PosFormat;
+ CoordComponentCount PosElements;
+ ComponentFormat PosFormat;
u8 PosFrac;
- u8 NormalElements;
- u8 NormalFormat;
+ NormalComponentCount NormalElements;
+ ComponentFormat NormalFormat;
ColorAttr color[2];
TexAttr texCoord[8];
bool ByteDequant;
@@ -229,39 +318,23 @@ struct TVtxAttr
// Matrix indices
union TMatrixIndexA
{
- struct
- {
- u32 PosNormalMtxIdx : 6;
- u32 Tex0MtxIdx : 6;
- u32 Tex1MtxIdx : 6;
- u32 Tex2MtxIdx : 6;
- u32 Tex3MtxIdx : 6;
- };
- struct
- {
- u32 Hex : 30;
- u32 unused : 2;
- };
+ BitField<0, 6, u32> PosNormalMtxIdx;
+ BitField<6, 6, u32> Tex0MtxIdx;
+ BitField<12, 6, u32> Tex1MtxIdx;
+ BitField<18, 6, u32> Tex2MtxIdx;
+ BitField<24, 6, u32> Tex3MtxIdx;
+ u32 Hex;
};
union TMatrixIndexB
{
- struct
- {
- u32 Tex4MtxIdx : 6;
- u32 Tex5MtxIdx : 6;
- u32 Tex6MtxIdx : 6;
- u32 Tex7MtxIdx : 6;
- };
- struct
- {
- u32 Hex : 24;
- u32 unused : 8;
- };
+ BitField<0, 6, u32> Tex4MtxIdx;
+ BitField<6, 6, u32> Tex5MtxIdx;
+ BitField<12, 6, u32> Tex6MtxIdx;
+ BitField<18, 6, u32> Tex7MtxIdx;
+ u32 Hex;
};
-#pragma pack()
-
struct VAT
{
UVAT_group0 g0;
diff --git a/Source/Core/VideoCommon/VertexLoader.cpp b/Source/Core/VideoCommon/VertexLoader.cpp
index d3584ddbeb..f06b60a430 100644
--- a/Source/Core/VideoCommon/VertexLoader.cpp
+++ b/Source/Core/VideoCommon/VertexLoader.cpp
@@ -2,11 +2,12 @@
// Licensed under GPLv2+
// Refer to the license.txt file included.
+#include "VideoCommon/VertexLoader.h"
+
#include "Common/Assert.h"
#include "Common/CommonTypes.h"
#include "VideoCommon/DataReader.h"
-#include "VideoCommon/VertexLoader.h"
#include "VideoCommon/VertexLoaderManager.h"
#include "VideoCommon/VertexLoaderUtils.h"
#include "VideoCommon/VertexLoader_Color.h"
@@ -84,20 +85,13 @@ void VertexLoader::CompileVertexTranslator()
// Reset pipeline
m_numPipelineStages = 0;
- // Colors
- const u64 col[2] = {m_VtxDesc.Color0, m_VtxDesc.Color1};
- // TextureCoord
- const u64 tc[8] = {m_VtxDesc.Tex0Coord, m_VtxDesc.Tex1Coord, m_VtxDesc.Tex2Coord,
- m_VtxDesc.Tex3Coord, m_VtxDesc.Tex4Coord, m_VtxDesc.Tex5Coord,
- m_VtxDesc.Tex6Coord, m_VtxDesc.Tex7Coord};
-
u32 components = 0;
// Position in pc vertex format.
int nat_offset = 0;
// Position Matrix Index
- if (m_VtxDesc.PosMatIdx)
+ if (m_VtxDesc.low.PosMatIdx)
{
WriteCall(PosMtx_ReadDirect_UByte);
components |= VB_HAS_POSMTXIDX;
@@ -110,49 +104,49 @@ void VertexLoader::CompileVertexTranslator()
m_VertexSize += 1;
}
- if (m_VtxDesc.Tex0MatIdx)
+ if (m_VtxDesc.low.Tex0MatIdx)
{
m_VertexSize += 1;
components |= VB_HAS_TEXMTXIDX0;
WriteCall(TexMtx_ReadDirect_UByte);
}
- if (m_VtxDesc.Tex1MatIdx)
+ if (m_VtxDesc.low.Tex1MatIdx)
{
m_VertexSize += 1;
components |= VB_HAS_TEXMTXIDX1;
WriteCall(TexMtx_ReadDirect_UByte);
}
- if (m_VtxDesc.Tex2MatIdx)
+ if (m_VtxDesc.low.Tex2MatIdx)
{
m_VertexSize += 1;
components |= VB_HAS_TEXMTXIDX2;
WriteCall(TexMtx_ReadDirect_UByte);
}
- if (m_VtxDesc.Tex3MatIdx)
+ if (m_VtxDesc.low.Tex3MatIdx)
{
m_VertexSize += 1;
components |= VB_HAS_TEXMTXIDX3;
WriteCall(TexMtx_ReadDirect_UByte);
}
- if (m_VtxDesc.Tex4MatIdx)
+ if (m_VtxDesc.low.Tex4MatIdx)
{
m_VertexSize += 1;
components |= VB_HAS_TEXMTXIDX4;
WriteCall(TexMtx_ReadDirect_UByte);
}
- if (m_VtxDesc.Tex5MatIdx)
+ if (m_VtxDesc.low.Tex5MatIdx)
{
m_VertexSize += 1;
components |= VB_HAS_TEXMTXIDX5;
WriteCall(TexMtx_ReadDirect_UByte);
}
- if (m_VtxDesc.Tex6MatIdx)
+ if (m_VtxDesc.low.Tex6MatIdx)
{
m_VertexSize += 1;
components |= VB_HAS_TEXMTXIDX6;
WriteCall(TexMtx_ReadDirect_UByte);
}
- if (m_VtxDesc.Tex7MatIdx)
+ if (m_VtxDesc.low.Tex7MatIdx)
{
m_VertexSize += 1;
components |= VB_HAS_TEXMTXIDX7;
@@ -160,12 +154,12 @@ void VertexLoader::CompileVertexTranslator()
}
// Write vertex position loader
- WriteCall(VertexLoader_Position::GetFunction(m_VtxDesc.Position, m_VtxAttr.PosFormat,
+ WriteCall(VertexLoader_Position::GetFunction(m_VtxDesc.low.Position, m_VtxAttr.PosFormat,
m_VtxAttr.PosElements));
- m_VertexSize += VertexLoader_Position::GetSize(m_VtxDesc.Position, m_VtxAttr.PosFormat,
+ m_VertexSize += VertexLoader_Position::GetSize(m_VtxDesc.low.Position, m_VtxAttr.PosFormat,
m_VtxAttr.PosElements);
- int pos_elements = m_VtxAttr.PosElements + 2;
+ int pos_elements = m_VtxAttr.PosElements == CoordComponentCount::XY ? 2 : 3;
m_native_vtx_decl.position.components = pos_elements;
m_native_vtx_decl.position.enable = true;
m_native_vtx_decl.position.offset = nat_offset;
@@ -174,23 +168,24 @@ void VertexLoader::CompileVertexTranslator()
nat_offset += pos_elements * sizeof(float);
// Normals
- if (m_VtxDesc.Normal != NOT_PRESENT)
+ if (m_VtxDesc.low.Normal != VertexComponentFormat::NotPresent)
{
- m_VertexSize += VertexLoader_Normal::GetSize(m_VtxDesc.Normal, m_VtxAttr.NormalFormat,
+ m_VertexSize += VertexLoader_Normal::GetSize(m_VtxDesc.low.Normal, m_VtxAttr.NormalFormat,
m_VtxAttr.NormalElements, m_VtxAttr.NormalIndex3);
- TPipelineFunction pFunc = VertexLoader_Normal::GetFunction(
- m_VtxDesc.Normal, m_VtxAttr.NormalFormat, m_VtxAttr.NormalElements, m_VtxAttr.NormalIndex3);
+ TPipelineFunction pFunc =
+ VertexLoader_Normal::GetFunction(m_VtxDesc.low.Normal, m_VtxAttr.NormalFormat,
+ m_VtxAttr.NormalElements, m_VtxAttr.NormalIndex3);
if (pFunc == nullptr)
{
PanicAlertFmt("VertexLoader_Normal::GetFunction({} {} {} {}) returned zero!",
- m_VtxDesc.Normal, m_VtxAttr.NormalFormat, m_VtxAttr.NormalElements,
+ m_VtxDesc.low.Normal, m_VtxAttr.NormalFormat, m_VtxAttr.NormalElements,
m_VtxAttr.NormalIndex3);
}
WriteCall(pFunc);
- for (int i = 0; i < (vtx_attr.NormalElements ? 3 : 1); i++)
+ for (int i = 0; i < (vtx_attr.NormalElements == NormalComponentCount::NBT ? 3 : 1); i++)
{
m_native_vtx_decl.normals[i].components = 3;
m_native_vtx_decl.normals[i].enable = true;
@@ -201,43 +196,43 @@ void VertexLoader::CompileVertexTranslator()
}
components |= VB_HAS_NRM0;
- if (m_VtxAttr.NormalElements == 1)
+ if (m_VtxAttr.NormalElements == NormalComponentCount::NBT)
components |= VB_HAS_NRM1 | VB_HAS_NRM2;
}
- for (int i = 0; i < 2; i++)
+ for (size_t i = 0; i < m_VtxDesc.low.Color.Size(); i++)
{
m_native_vtx_decl.colors[i].components = 4;
m_native_vtx_decl.colors[i].type = VAR_UNSIGNED_BYTE;
m_native_vtx_decl.colors[i].integer = false;
- switch (col[i])
+ switch (m_VtxDesc.low.Color[i])
{
- case NOT_PRESENT:
+ case VertexComponentFormat::NotPresent:
break;
- case DIRECT:
+ case VertexComponentFormat::Direct:
switch (m_VtxAttr.color[i].Comp)
{
- case FORMAT_16B_565:
+ case ColorFormat::RGB565:
m_VertexSize += 2;
WriteCall(Color_ReadDirect_16b_565);
break;
- case FORMAT_24B_888:
+ case ColorFormat::RGB888:
m_VertexSize += 3;
WriteCall(Color_ReadDirect_24b_888);
break;
- case FORMAT_32B_888x:
+ case ColorFormat::RGB888x:
m_VertexSize += 4;
WriteCall(Color_ReadDirect_32b_888x);
break;
- case FORMAT_16B_4444:
+ case ColorFormat::RGBA4444:
m_VertexSize += 2;
WriteCall(Color_ReadDirect_16b_4444);
break;
- case FORMAT_24B_6666:
+ case ColorFormat::RGBA6666:
m_VertexSize += 3;
WriteCall(Color_ReadDirect_24b_6666);
break;
- case FORMAT_32B_8888:
+ case ColorFormat::RGBA8888:
m_VertexSize += 4;
WriteCall(Color_ReadDirect_32b_8888);
break;
@@ -246,26 +241,26 @@ void VertexLoader::CompileVertexTranslator()
break;
}
break;
- case INDEX8:
+ case VertexComponentFormat::Index8:
m_VertexSize += 1;
switch (m_VtxAttr.color[i].Comp)
{
- case FORMAT_16B_565:
+ case ColorFormat::RGB565:
WriteCall(Color_ReadIndex8_16b_565);
break;
- case FORMAT_24B_888:
+ case ColorFormat::RGB888:
WriteCall(Color_ReadIndex8_24b_888);
break;
- case FORMAT_32B_888x:
+ case ColorFormat::RGB888x:
WriteCall(Color_ReadIndex8_32b_888x);
break;
- case FORMAT_16B_4444:
+ case ColorFormat::RGBA4444:
WriteCall(Color_ReadIndex8_16b_4444);
break;
- case FORMAT_24B_6666:
+ case ColorFormat::RGBA6666:
WriteCall(Color_ReadIndex8_24b_6666);
break;
- case FORMAT_32B_8888:
+ case ColorFormat::RGBA8888:
WriteCall(Color_ReadIndex8_32b_8888);
break;
default:
@@ -273,26 +268,26 @@ void VertexLoader::CompileVertexTranslator()
break;
}
break;
- case INDEX16:
+ case VertexComponentFormat::Index16:
m_VertexSize += 2;
switch (m_VtxAttr.color[i].Comp)
{
- case FORMAT_16B_565:
+ case ColorFormat::RGB565:
WriteCall(Color_ReadIndex16_16b_565);
break;
- case FORMAT_24B_888:
+ case ColorFormat::RGB888:
WriteCall(Color_ReadIndex16_24b_888);
break;
- case FORMAT_32B_888x:
+ case ColorFormat::RGB888x:
WriteCall(Color_ReadIndex16_32b_888x);
break;
- case FORMAT_16B_4444:
+ case ColorFormat::RGBA4444:
WriteCall(Color_ReadIndex16_16b_4444);
break;
- case FORMAT_24B_6666:
+ case ColorFormat::RGBA6666:
WriteCall(Color_ReadIndex16_24b_6666);
break;
- case FORMAT_32B_8888:
+ case ColorFormat::RGBA8888:
WriteCall(Color_ReadIndex16_32b_8888);
break;
default:
@@ -302,7 +297,7 @@ void VertexLoader::CompileVertexTranslator()
break;
}
// Common for the three bottom cases
- if (col[i] != NOT_PRESENT)
+ if (m_VtxDesc.low.Color[i] != VertexComponentFormat::NotPresent)
{
components |= VB_HAS_COL0 << i;
m_native_vtx_decl.colors[i].offset = nat_offset;
@@ -312,38 +307,40 @@ void VertexLoader::CompileVertexTranslator()
}
// Texture matrix indices (remove if corresponding texture coordinate isn't enabled)
- for (int i = 0; i < 8; i++)
+ for (size_t i = 0; i < m_VtxDesc.high.TexCoord.Size(); i++)
{
m_native_vtx_decl.texcoords[i].offset = nat_offset;
m_native_vtx_decl.texcoords[i].type = VAR_FLOAT;
m_native_vtx_decl.texcoords[i].integer = false;
- const int format = m_VtxAttr.texCoord[i].Format;
- const int elements = m_VtxAttr.texCoord[i].Elements;
+ const auto tc = m_VtxDesc.high.TexCoord[i].Value();
+ const auto format = m_VtxAttr.texCoord[i].Format;
+ const auto elements = m_VtxAttr.texCoord[i].Elements;
- if (tc[i] != NOT_PRESENT)
+ if (tc != VertexComponentFormat::NotPresent)
{
- ASSERT_MSG(VIDEO, DIRECT <= tc[i] && tc[i] <= INDEX16,
- "Invalid texture coordinates!\n(tc[i] = %d)", (u32)tc[i]);
- ASSERT_MSG(VIDEO, FORMAT_UBYTE <= format && format <= FORMAT_FLOAT,
- "Invalid texture coordinates format!\n(format = %d)", format);
- ASSERT_MSG(VIDEO, 0 <= elements && elements <= 1,
- "Invalid number of texture coordinates elements!\n(elements = %d)", elements);
+ ASSERT_MSG(VIDEO, VertexComponentFormat::Direct <= tc && tc <= VertexComponentFormat::Index16,
+ "Invalid texture coordinates!\n(tc = %d)", (u32)tc);
+ ASSERT_MSG(VIDEO, ComponentFormat::UByte <= format && format <= ComponentFormat::Float,
+ "Invalid texture coordinates format!\n(format = %d)", (u32)format);
+ ASSERT_MSG(VIDEO, elements == TexComponentCount::S || elements == TexComponentCount::ST,
+ "Invalid number of texture coordinates elements!\n(elements = %d)", (u32)elements);
components |= VB_HAS_UV0 << i;
- WriteCall(VertexLoader_TextCoord::GetFunction(tc[i], format, elements));
- m_VertexSize += VertexLoader_TextCoord::GetSize(tc[i], format, elements);
+ WriteCall(VertexLoader_TextCoord::GetFunction(tc, format, elements));
+ m_VertexSize += VertexLoader_TextCoord::GetSize(tc, format, elements);
}
if (components & (VB_HAS_TEXMTXIDX0 << i))
{
m_native_vtx_decl.texcoords[i].enable = true;
- if (tc[i] != NOT_PRESENT)
+ if (tc != VertexComponentFormat::NotPresent)
{
// if texmtx is included, texcoord will always be 3 floats, z will be the texmtx index
m_native_vtx_decl.texcoords[i].components = 3;
nat_offset += 12;
- WriteCall(m_VtxAttr.texCoord[i].Elements ? TexMtx_Write_Float : TexMtx_Write_Float2);
+ WriteCall(m_VtxAttr.texCoord[i].Elements == TexComponentCount::ST ? TexMtx_Write_Float :
+ TexMtx_Write_Float2);
}
else
{
@@ -354,21 +351,22 @@ void VertexLoader::CompileVertexTranslator()
}
else
{
- if (tc[i] != NOT_PRESENT)
+ if (tc != VertexComponentFormat::NotPresent)
{
m_native_vtx_decl.texcoords[i].enable = true;
- m_native_vtx_decl.texcoords[i].components = vtx_attr.texCoord[i].Elements ? 2 : 1;
- nat_offset += 4 * (vtx_attr.texCoord[i].Elements ? 2 : 1);
+ m_native_vtx_decl.texcoords[i].components =
+ vtx_attr.texCoord[i].Elements == TexComponentCount::ST ? 2 : 1;
+ nat_offset += 4 * (vtx_attr.texCoord[i].Elements == TexComponentCount::ST ? 2 : 1);
}
}
- if (tc[i] == NOT_PRESENT)
+ if (tc == VertexComponentFormat::NotPresent)
{
// if there's more tex coords later, have to write a dummy call
- int j = i + 1;
- for (; j < 8; ++j)
+ size_t j = i + 1;
+ for (; j < m_VtxDesc.high.TexCoord.Size(); ++j)
{
- if (tc[j] != NOT_PRESENT)
+ if (m_VtxDesc.high.TexCoord[j] != VertexComponentFormat::NotPresent)
{
WriteCall(VertexLoader_TextCoord::GetDummyFunction()); // important to get indices right!
break;
@@ -383,8 +381,8 @@ void VertexLoader::CompileVertexTranslator()
}
}
- // indexed position formats may skip a the vertex
- if (m_VtxDesc.Position & 2)
+ // indexed position formats may skip the vertex
+ if (IsIndexed(m_VtxDesc.low.Position))
{
WriteCall(SkipVertex);
}
diff --git a/Source/Core/VideoCommon/VertexLoaderARM64.cpp b/Source/Core/VideoCommon/VertexLoaderARM64.cpp
index 06c3fe2340..f56314f6c1 100644
--- a/Source/Core/VideoCommon/VertexLoaderARM64.cpp
+++ b/Source/Core/VideoCommon/VertexLoaderARM64.cpp
@@ -3,6 +3,9 @@
// Refer to the license.txt file included.
#include "VideoCommon/VertexLoaderARM64.h"
+
+#include <array>
+
#include "Common/CommonTypes.h"
#include "VideoCommon/DataReader.h"
#include "VideoCommon/VertexLoaderManager.h"
@@ -45,11 +48,11 @@ VertexLoaderARM64::VertexLoaderARM64(const TVtxDesc& vtx_desc, const VAT& vtx_at
WriteProtect();
}
-void VertexLoaderARM64::GetVertexAddr(int array, u64 attribute, ARM64Reg reg)
+void VertexLoaderARM64::GetVertexAddr(int array, VertexComponentFormat attribute, ARM64Reg reg)
{
- if (attribute & MASK_INDEXED)
+ if (IsIndexed(attribute))
{
- if (attribute == INDEX8)
+ if (attribute == VertexComponentFormat::Index8)
{
if (m_src_ofs < 4096)
{
@@ -83,7 +86,8 @@ void VertexLoaderARM64::GetVertexAddr(int array, u64 attribute, ARM64Reg reg)
if (array == ARRAY_POSITION)
{
- EOR(scratch2_reg, scratch1_reg, 0, attribute == INDEX8 ? 7 : 15); // 0xFF : 0xFFFF
+ EOR(scratch2_reg, scratch1_reg, 0,
+ attribute == VertexComponentFormat::Index8 ? 7 : 15); // 0xFF : 0xFFFF
m_skip_vertex = CBZ(scratch2_reg);
}
@@ -97,23 +101,24 @@ void VertexLoaderARM64::GetVertexAddr(int array, u64 attribute, ARM64Reg reg)
ADD(reg, src_reg, m_src_ofs);
}
-s32 VertexLoaderARM64::GetAddressImm(int array, u64 attribute, Arm64Gen::ARM64Reg reg, u32 align)
+s32 VertexLoaderARM64::GetAddressImm(int array, VertexComponentFormat attribute,
+ Arm64Gen::ARM64Reg reg, u32 align)
{
- if (attribute & MASK_INDEXED || (m_src_ofs > 255 && (m_src_ofs & (align - 1))))
+ if (IsIndexed(attribute) || (m_src_ofs > 255 && (m_src_ofs & (align - 1))))
GetVertexAddr(array, attribute, reg);
else
return m_src_ofs;
return -1;
}
-int VertexLoaderARM64::ReadVertex(u64 attribute, int format, int count_in, int count_out,
- bool dequantize, u8 scaling_exponent,
+int VertexLoaderARM64::ReadVertex(VertexComponentFormat attribute, ComponentFormat format,
+ int count_in, int count_out, bool dequantize, u8 scaling_exponent,
AttributeFormat* native_format, s32 offset)
{
ARM64Reg coords = count_in == 3 ? Q31 : D31;
ARM64Reg scale = count_in == 3 ? Q30 : D30;
- int elem_size = 1 << (format / 2);
+ int elem_size = GetElementSize(format);
int load_bytes = elem_size * count_in;
int load_size =
load_bytes == 1 ? 1 : load_bytes <= 2 ? 2 : load_bytes <= 4 ? 4 : load_bytes <= 8 ? 8 : 16;
@@ -136,24 +141,24 @@ int VertexLoaderARM64::ReadVertex(u64 attribute, int format, int count_in, int c
m_float_emit.LDR(load_size, IndexType::Unsigned, coords, src_reg, offset);
}
- if (format != FORMAT_FLOAT)
+ if (format != ComponentFormat::Float)
{
// Extend and convert to float
switch (format)
{
- case FORMAT_UBYTE:
+ case ComponentFormat::UByte:
m_float_emit.UXTL(8, EncodeRegToDouble(coords), EncodeRegToDouble(coords));
m_float_emit.UXTL(16, EncodeRegToDouble(coords), EncodeRegToDouble(coords));
break;
- case FORMAT_BYTE:
+ case ComponentFormat::Byte:
m_float_emit.SXTL(8, EncodeRegToDouble(coords), EncodeRegToDouble(coords));
m_float_emit.SXTL(16, EncodeRegToDouble(coords), EncodeRegToDouble(coords));
break;
- case FORMAT_USHORT:
+ case ComponentFormat::UShort:
m_float_emit.REV16(8, EncodeRegToDouble(coords), EncodeRegToDouble(coords));
m_float_emit.UXTL(16, EncodeRegToDouble(coords), EncodeRegToDouble(coords));
break;
- case FORMAT_SHORT:
+ case ComponentFormat::Short:
m_float_emit.REV16(8, EncodeRegToDouble(coords), EncodeRegToDouble(coords));
m_float_emit.SXTL(16, EncodeRegToDouble(coords), EncodeRegToDouble(coords));
break;
@@ -207,20 +212,20 @@ int VertexLoaderARM64::ReadVertex(u64 attribute, int format, int count_in, int c
native_format->integer = false;
m_dst_ofs += sizeof(float) * count_out;
- if (attribute == DIRECT)
+ if (attribute == VertexComponentFormat::Direct)
m_src_ofs += load_bytes;
return load_bytes;
}
-void VertexLoaderARM64::ReadColor(u64 attribute, int format, s32 offset)
+void VertexLoaderARM64::ReadColor(VertexComponentFormat attribute, ColorFormat format, s32 offset)
{
int load_bytes = 0;
switch (format)
{
- case FORMAT_24B_888:
- case FORMAT_32B_888x:
- case FORMAT_32B_8888:
+ case ColorFormat::RGB888:
+ case ColorFormat::RGB888x:
+ case ColorFormat::RGBA8888:
if (offset == -1)
LDR(IndexType::Unsigned, scratch2_reg, EncodeRegTo64(scratch1_reg), 0);
else if (offset & 3) // Not aligned - unscaled
@@ -228,13 +233,13 @@ void VertexLoaderARM64::ReadColor(u64 attribute, int format, s32 offset)
else
LDR(IndexType::Unsigned, scratch2_reg, src_reg, offset);
- if (format != FORMAT_32B_8888)
+ if (format != ColorFormat::RGBA8888)
ORRI2R(scratch2_reg, scratch2_reg, 0xFF000000);
STR(IndexType::Unsigned, scratch2_reg, dst_reg, m_dst_ofs);
- load_bytes = 3 + (format != FORMAT_24B_888);
+ load_bytes = format == ColorFormat::RGB888 ? 3 : 4;
break;
- case FORMAT_16B_565:
+ case ColorFormat::RGB565:
// RRRRRGGG GGGBBBBB
// AAAAAAAA BBBBBBBB GGGGGGGG RRRRRRRR
if (offset == -1)
@@ -270,7 +275,7 @@ void VertexLoaderARM64::ReadColor(u64 attribute, int format, s32 offset)
load_bytes = 2;
break;
- case FORMAT_16B_4444:
+ case ColorFormat::RGBA4444:
// BBBBAAAA RRRRGGGG
// REV16 - RRRRGGGG BBBBAAAA
// AAAAAAAA BBBBBBBB GGGGGGGG RRRRRRRR
@@ -303,7 +308,7 @@ void VertexLoaderARM64::ReadColor(u64 attribute, int format, s32 offset)
load_bytes = 2;
break;
- case FORMAT_24B_6666:
+ case ColorFormat::RGBA6666:
// RRRRRRGG GGGGBBBB BBAAAAAA
// AAAAAAAA BBBBBBBB GGGGGGGG RRRRRRRR
if (offset == -1)
@@ -349,7 +354,7 @@ void VertexLoaderARM64::ReadColor(u64 attribute, int format, s32 offset)
load_bytes = 3;
break;
}
- if (attribute == DIRECT)
+ if (attribute == VertexComponentFormat::Direct)
m_src_ofs += load_bytes;
}
@@ -370,24 +375,19 @@ void VertexLoaderARM64::GenerateVertexLoader()
// We can touch all except v8-v15
// If we need to use those, we need to retain the lower 64bits(!) of the register
- const u64 tc[8] = {
- m_VtxDesc.Tex0Coord, m_VtxDesc.Tex1Coord, m_VtxDesc.Tex2Coord, m_VtxDesc.Tex3Coord,
- m_VtxDesc.Tex4Coord, m_VtxDesc.Tex5Coord, m_VtxDesc.Tex6Coord, m_VtxDesc.Tex7Coord,
- };
-
bool has_tc = false;
bool has_tc_scale = false;
- for (int i = 0; i < 8; i++)
+ for (size_t i = 0; i < m_VtxDesc.high.TexCoord.Size(); i++)
{
- has_tc |= tc[i] != 0;
+ has_tc |= m_VtxDesc.high.TexCoord[i] != VertexComponentFormat::NotPresent;
has_tc_scale |= !!m_VtxAttr.texCoord[i].Frac;
}
- bool need_scale =
- (m_VtxAttr.ByteDequant && m_VtxAttr.PosFrac) || (has_tc && has_tc_scale) || m_VtxDesc.Normal;
+ bool need_scale = (m_VtxAttr.ByteDequant && m_VtxAttr.PosFrac) || (has_tc && has_tc_scale) ||
+ (m_VtxDesc.low.Normal != VertexComponentFormat::NotPresent);
AlignCode16();
- if (m_VtxDesc.Position & MASK_INDEXED)
+ if (IsIndexed(m_VtxDesc.low.Position))
MOV(skipped_reg, WZR);
MOV(saved_count, count_reg);
@@ -399,7 +399,7 @@ void VertexLoaderARM64::GenerateVertexLoader()
const u8* loop_start = GetCodePtr();
- if (m_VtxDesc.PosMatIdx)
+ if (m_VtxDesc.low.PosMatIdx)
{
LDRB(IndexType::Unsigned, scratch1_reg, src_reg, m_src_ofs);
AND(scratch1_reg, scratch1_reg, 0, 5);
@@ -422,50 +422,47 @@ void VertexLoaderARM64::GenerateVertexLoader()
m_dst_ofs += sizeof(u32);
}
- u32 texmatidx_ofs[8];
- const u64 tm[8] = {
- m_VtxDesc.Tex0MatIdx, m_VtxDesc.Tex1MatIdx, m_VtxDesc.Tex2MatIdx, m_VtxDesc.Tex3MatIdx,
- m_VtxDesc.Tex4MatIdx, m_VtxDesc.Tex5MatIdx, m_VtxDesc.Tex6MatIdx, m_VtxDesc.Tex7MatIdx,
- };
- for (int i = 0; i < 8; i++)
+ std::array<u32, 8> texmatidx_ofs;
+ for (size_t i = 0; i < m_VtxDesc.low.TexMatIdx.Size(); i++)
{
- if (tm[i])
+ if (m_VtxDesc.low.TexMatIdx[i])
texmatidx_ofs[i] = m_src_ofs++;
}
// Position
{
- int elem_size = 1 << (m_VtxAttr.PosFormat / 2);
- int load_bytes = elem_size * (m_VtxAttr.PosElements + 2);
+ int elem_size = GetElementSize(m_VtxAttr.PosFormat);
+ int pos_elements = m_VtxAttr.PosElements == CoordComponentCount::XY ? 2 : 3;
+ int load_bytes = elem_size * pos_elements;
int load_size =
load_bytes == 1 ? 1 : load_bytes <= 2 ? 2 : load_bytes <= 4 ? 4 : load_bytes <= 8 ? 8 : 16;
load_size <<= 3;
- s32 offset =
- GetAddressImm(ARRAY_POSITION, m_VtxDesc.Position, EncodeRegTo64(scratch1_reg), load_size);
- int pos_elements = m_VtxAttr.PosElements + 2;
- ReadVertex(m_VtxDesc.Position, m_VtxAttr.PosFormat, pos_elements, pos_elements,
+ s32 offset = GetAddressImm(ARRAY_POSITION, m_VtxDesc.low.Position, EncodeRegTo64(scratch1_reg),
+ load_size);
+ ReadVertex(m_VtxDesc.low.Position, m_VtxAttr.PosFormat, pos_elements, pos_elements,
m_VtxAttr.ByteDequant, m_VtxAttr.PosFrac, &m_native_vtx_decl.position, offset);
}
- if (m_VtxDesc.Normal)
+ if (m_VtxDesc.low.Normal != VertexComponentFormat::NotPresent)
{
static const u8 map[8] = {7, 6, 15, 14};
- u8 scaling_exponent = map[m_VtxAttr.NormalFormat];
+ const u8 scaling_exponent = map[u32(m_VtxAttr.NormalFormat)];
+ const int limit = m_VtxAttr.NormalElements == NormalComponentCount::NBT ? 3 : 1;
s32 offset = -1;
- for (int i = 0; i < (m_VtxAttr.NormalElements ? 3 : 1); i++)
+ for (int i = 0; i < (m_VtxAttr.NormalElements == NormalComponentCount::NBT ? 3 : 1); i++)
{
if (!i || m_VtxAttr.NormalIndex3)
{
- int elem_size = 1 << (m_VtxAttr.NormalFormat / 2);
+ int elem_size = GetElementSize(m_VtxAttr.NormalFormat);
int load_bytes = elem_size * 3;
int load_size = load_bytes == 1 ?
1 :
load_bytes <= 2 ? 2 : load_bytes <= 4 ? 4 : load_bytes <= 8 ? 8 : 16;
- offset = GetAddressImm(ARRAY_NORMAL, m_VtxDesc.Normal, EncodeRegTo64(scratch1_reg),
+ offset = GetAddressImm(ARRAY_NORMAL, m_VtxDesc.low.Normal, EncodeRegTo64(scratch1_reg),
load_size << 3);
if (offset == -1)
@@ -473,7 +470,7 @@ void VertexLoaderARM64::GenerateVertexLoader()
else
offset += i * elem_size * 3;
}
- int bytes_read = ReadVertex(m_VtxDesc.Normal, m_VtxAttr.NormalFormat, 3, 3, true,
+ int bytes_read = ReadVertex(m_VtxDesc.low.Normal, m_VtxAttr.NormalFormat, 3, 3, true,
scaling_exponent, &m_native_vtx_decl.normals[i], offset);
if (offset == -1)
@@ -483,25 +480,26 @@ void VertexLoaderARM64::GenerateVertexLoader()
}
m_native_components |= VB_HAS_NRM0;
- if (m_VtxAttr.NormalElements)
+ if (m_VtxAttr.NormalElements == NormalComponentCount::NBT)
m_native_components |= VB_HAS_NRM1 | VB_HAS_NRM2;
}
- const u64 col[2] = {m_VtxDesc.Color0, m_VtxDesc.Color1};
- for (int i = 0; i < 2; i++)
+ for (size_t i = 0; i < m_VtxDesc.low.Color.Size(); i++)
{
m_native_vtx_decl.colors[i].components = 4;
m_native_vtx_decl.colors[i].type = VAR_UNSIGNED_BYTE;
m_native_vtx_decl.colors[i].integer = false;
- if (col[i])
+ if (m_VtxDesc.low.Color[i] != VertexComponentFormat::NotPresent)
{
u32 align = 4;
- if (m_VtxAttr.color[i].Comp == FORMAT_16B_565 || m_VtxAttr.color[i].Comp == FORMAT_16B_4444)
+ if (m_VtxAttr.color[i].Comp == ColorFormat::RGB565 ||
+ m_VtxAttr.color[i].Comp == ColorFormat::RGBA4444)
align = 2;
- s32 offset = GetAddressImm(ARRAY_COLOR + i, col[i], EncodeRegTo64(scratch1_reg), align);
- ReadColor(col[i], m_VtxAttr.color[i].Comp, offset);
+ s32 offset = GetAddressImm(ARRAY_COLOR + int(i), m_VtxDesc.low.Color[i],
+ EncodeRegTo64(scratch1_reg), align);
+ ReadColor(m_VtxDesc.low.Color[i], m_VtxAttr.color[i].Comp, offset);
m_native_components |= VB_HAS_COL0 << i;
m_native_vtx_decl.colors[i].components = 4;
m_native_vtx_decl.colors[i].enable = true;
@@ -512,31 +510,32 @@ void VertexLoaderARM64::GenerateVertexLoader()
}
}
- for (int i = 0; i < 8; i++)
+ for (size_t i = 0; i < m_VtxDesc.high.TexCoord.Size(); i++)
{
m_native_vtx_decl.texcoords[i].offset = m_dst_ofs;
m_native_vtx_decl.texcoords[i].type = VAR_FLOAT;
m_native_vtx_decl.texcoords[i].integer = false;
- int elements = m_VtxAttr.texCoord[i].Elements + 1;
- if (tc[i])
+ int elements = m_VtxAttr.texCoord[i].Elements == TexComponentCount::S ? 1 : 2;
+ if (m_VtxDesc.high.TexCoord[i] != VertexComponentFormat::NotPresent)
{
m_native_components |= VB_HAS_UV0 << i;
- int elem_size = 1 << (m_VtxAttr.texCoord[i].Format / 2);
+ int elem_size = GetElementSize(m_VtxAttr.texCoord[i].Format);
int load_bytes = elem_size * (elements + 2);
int load_size = load_bytes == 1 ?
1 :
load_bytes <= 2 ? 2 : load_bytes <= 4 ? 4 : load_bytes <= 8 ? 8 : 16;
load_size <<= 3;
- s32 offset =
- GetAddressImm(ARRAY_TEXCOORD0 + i, tc[i], EncodeRegTo64(scratch1_reg), load_size);
+ s32 offset = GetAddressImm(ARRAY_TEXCOORD0 + int(i), m_VtxDesc.high.TexCoord[i],
+ EncodeRegTo64(scratch1_reg), load_size);
u8 scaling_exponent = m_VtxAttr.texCoord[i].Frac;
- ReadVertex(tc[i], m_VtxAttr.texCoord[i].Format, elements, tm[i] ? 2 : elements,
- m_VtxAttr.ByteDequant, scaling_exponent, &m_native_vtx_decl.texcoords[i], offset);
+ ReadVertex(m_VtxDesc.high.TexCoord[i], m_VtxAttr.texCoord[i].Format, elements,
+ m_VtxDesc.low.TexMatIdx[i] ? 2 : elements, m_VtxAttr.ByteDequant, scaling_exponent,
+ &m_native_vtx_decl.texcoords[i], offset);
}
- if (tm[i])
+ if (m_VtxDesc.low.TexMatIdx[i])
{
m_native_components |= VB_HAS_TEXMTXIDX0 << i;
m_native_vtx_decl.texcoords[i].components = 3;
@@ -547,7 +546,7 @@ void VertexLoaderARM64::GenerateVertexLoader()
LDRB(IndexType::Unsigned, scratch2_reg, src_reg, texmatidx_ofs[i]);
m_float_emit.UCVTF(S31, scratch2_reg);
- if (tc[i])
+ if (m_VtxDesc.high.TexCoord[i] != VertexComponentFormat::NotPresent)
{
m_float_emit.STR(32, IndexType::Unsigned, D31, dst_reg, m_dst_ofs);
m_dst_ofs += sizeof(float);
@@ -587,7 +586,7 @@ void VertexLoaderARM64::GenerateVertexLoader()
SUB(count_reg, count_reg, 1);
CBNZ(count_reg, loop_start);
- if (m_VtxDesc.Position & MASK_INDEXED)
+ if (IsIndexed(m_VtxDesc.low.Position))
{
SUB(W0, saved_count, skipped_reg);
RET(X30);
diff --git a/Source/Core/VideoCommon/VertexLoaderARM64.h b/Source/Core/VideoCommon/VertexLoaderARM64.h
index 3df60a9685..b7faec0239 100644
--- a/Source/Core/VideoCommon/VertexLoaderARM64.h
+++ b/Source/Core/VideoCommon/VertexLoaderARM64.h
@@ -9,6 +9,9 @@
#include "VideoCommon/VertexLoaderBase.h"
class DataReader;
+enum class VertexComponentFormat;
+enum class ComponentFormat;
+enum class ColorFormat;
class VertexLoaderARM64 : public VertexLoaderBase, public Arm64Gen::ARM64CodeBlock
{
@@ -25,10 +28,11 @@ private:
u32 m_dst_ofs = 0;
Arm64Gen::FixupBranch m_skip_vertex;
Arm64Gen::ARM64FloatEmitter m_float_emit;
- void GetVertexAddr(int array, u64 attribute, Arm64Gen::ARM64Reg reg);
- s32 GetAddressImm(int array, u64 attribute, Arm64Gen::ARM64Reg reg, u32 align);
- int ReadVertex(u64 attribute, int format, int count_in, int count_out, bool dequantize,
- u8 scaling_exponent, AttributeFormat* native_format, s32 offset = -1);
- void ReadColor(u64 attribute, int format, s32 offset);
+ void GetVertexAddr(int array, VertexComponentFormat attribute, Arm64Gen::ARM64Reg reg);
+ s32 GetAddressImm(int array, VertexComponentFormat attribute, Arm64Gen::ARM64Reg reg, u32 align);
+ int ReadVertex(VertexComponentFormat attribute, ComponentFormat format, int count_in,
+ int count_out, bool dequantize, u8 scaling_exponent,
+ AttributeFormat* native_format, s32 offset = -1);
+ void ReadColor(VertexComponentFormat attribute, ColorFormat format, s32 offset);
void GenerateVertexLoader();
};
diff --git a/Source/Core/VideoCommon/VertexLoaderBase.cpp b/Source/Core/VideoCommon/VertexLoaderBase.cpp
index c5baa503e6..483d46dd08 100644
--- a/Source/Core/VideoCommon/VertexLoaderBase.cpp
+++ b/Source/Core/VideoCommon/VertexLoaderBase.cpp
@@ -81,64 +81,33 @@ std::string VertexLoaderBase::ToString() const
dest += GetName();
dest += ": ";
- static constexpr std::array<const char*, 4> pos_mode{{
- "Inv",
- "Dir",
- "I8",
- "I16",
- }};
- static constexpr std::array<const char*, 8> pos_formats{{
- "u8",
- "s8",
- "u16",
- "s16",
- "flt",
- "Inv",
- "Inv",
- "Inv",
- }};
- static constexpr std::array<const char*, 8> color_format{{
- "565",
- "888",
- "888x",
- "4444",
- "6666",
- "8888",
- "Inv",
- "Inv",
- }};
-
- dest += fmt::format("{}b skin: {} P: {} {}-{} ", m_VertexSize, m_VtxDesc.PosMatIdx,
- m_VtxAttr.PosElements ? 3 : 2, pos_mode[m_VtxDesc.Position],
- pos_formats[m_VtxAttr.PosFormat]);
-
- if (m_VtxDesc.Normal)
+ dest += fmt::format("{}b skin: {} P: {} {}-{} ", m_VertexSize, m_VtxDesc.low.PosMatIdx,
+ m_VtxAttr.PosElements, m_VtxDesc.low.Position, m_VtxAttr.PosFormat);
+
+ if (m_VtxDesc.low.Normal != VertexComponentFormat::NotPresent)
{
- dest += fmt::format("Nrm: {} {}-{} ", m_VtxAttr.NormalElements, pos_mode[m_VtxDesc.Normal],
- pos_formats[m_VtxAttr.NormalFormat]);
+ dest += fmt::format("Nrm: {} {}-{} ", m_VtxAttr.NormalElements, m_VtxDesc.low.Normal,
+ m_VtxAttr.NormalFormat);
}
- const std::array<u64, 2> color_mode{{m_VtxDesc.Color0, m_VtxDesc.Color1}};
- for (size_t i = 0; i < color_mode.size(); i++)
+ for (size_t i = 0; i < g_main_cp_state.vtx_desc.low.Color.Size(); i++)
{
- if (color_mode[i] == 0)
+ if (g_main_cp_state.vtx_desc.low.Color[i] == VertexComponentFormat::NotPresent)
continue;
const auto& color = m_VtxAttr.color[i];
- dest += fmt::format("C{}: {} {}-{} ", i, color.Elements, pos_mode[color_mode[i]],
- color_format[color.Comp]);
+ dest += fmt::format("C{}: {} {}-{} ", i, color.Elements, g_main_cp_state.vtx_desc.low.Color[i],
+ color.Comp);
}
- const std::array<u64, 8> tex_mode{{m_VtxDesc.Tex0Coord, m_VtxDesc.Tex1Coord, m_VtxDesc.Tex2Coord,
- m_VtxDesc.Tex3Coord, m_VtxDesc.Tex4Coord, m_VtxDesc.Tex5Coord,
- m_VtxDesc.Tex6Coord, m_VtxDesc.Tex7Coord}};
- for (size_t i = 0; i < tex_mode.size(); i++)
+
+ for (size_t i = 0; i < g_main_cp_state.vtx_desc.high.TexCoord.Size(); i++)
{
- if (tex_mode[i] == 0)
+ if (g_main_cp_state.vtx_desc.high.TexCoord[i] == VertexComponentFormat::NotPresent)
continue;
const auto& tex_coord = m_VtxAttr.texCoord[i];
- dest += fmt::format("T{}: {} {}-{} ", i, tex_coord.Elements, pos_mode[tex_mode[i]],
- pos_formats[tex_coord.Format]);
+ dest += fmt::format("T{}: {} {}-{} ", i, tex_coord.Elements,
+ g_main_cp_state.vtx_desc.high.TexCoord[i], tex_coord.Format);
}
dest += fmt::format(" - {} v", m_numLoadedVertices);
return dest;
@@ -200,8 +169,9 @@ public:
{
ERROR_LOG_FMT(VIDEO,
"The two vertex loaders have loaded different data "
- "(guru meditation {:#018x}, {:#010x}, {:#010x}, {:#010x}).",
- m_VtxDesc.Hex, m_vat.g0.Hex, m_vat.g1.Hex, m_vat.g2.Hex);
+ "(guru meditation {:#010x}, {:#010x}, {:#010x}, {:#010x}, {:#010x}).",
+ m_VtxDesc.low.Hex, m_VtxDesc.high.Hex, m_vat.g0.Hex, m_vat.g1.Hex,
+ m_vat.g2.Hex);
}
memcpy(dst.GetPointer(), buffer_a.data(), count_a * m_native_vtx_decl.stride);
diff --git a/Source/Core/VideoCommon/VertexLoaderBase.h b/Source/Core/VideoCommon/VertexLoaderBase.h
index 29b53d3c58..77b66f629b 100644
--- a/Source/Core/VideoCommon/VertexLoaderBase.h
+++ b/Source/Core/VideoCommon/VertexLoaderBase.h
@@ -23,8 +23,8 @@ public:
VertexLoaderUID() {}
VertexLoaderUID(const TVtxDesc& vtx_desc, const VAT& vat)
{
- vid[0] = vtx_desc.Hex & 0xFFFFFFFF;
- vid[1] = vtx_desc.Hex >> 32;
+ vid[0] = vtx_desc.GetLegacyHex0();
+ vid[1] = vtx_desc.GetLegacyHex1();
vid[2] = vat.g0.Hex;
vid[3] = vat.g1.Hex;
vid[4] = vat.g2.Hex;
diff --git a/Source/Core/VideoCommon/VertexLoaderManager.cpp b/Source/Core/VideoCommon/VertexLoaderManager.cpp
index 93322de512..4dcc211178 100644
--- a/Source/Core/VideoCommon/VertexLoaderManager.cpp
+++ b/Source/Core/VideoCommon/VertexLoaderManager.cpp
@@ -77,11 +77,26 @@ void UpdateVertexArrayPointers()
// But the vertex arrays with invalid addresses aren't actually enabled.
// Note: Only array bases 0 through 11 are used by the Vertex loaders.
// 12 through 15 are used for loading data into xfmem.
- for (int i = 0; i < 12; i++)
+ // We also only update the array base if the vertex description states we are going to use it.
+ if (IsIndexed(g_main_cp_state.vtx_desc.low.Position))
+ cached_arraybases[ARRAY_POSITION] =
+ Memory::GetPointer(g_main_cp_state.array_bases[ARRAY_POSITION]);
+
+ if (IsIndexed(g_main_cp_state.vtx_desc.low.Normal))
+ cached_arraybases[ARRAY_NORMAL] = Memory::GetPointer(g_main_cp_state.array_bases[ARRAY_NORMAL]);
+
+ for (size_t i = 0; i < g_main_cp_state.vtx_desc.low.Color.Size(); i++)
+ {
+ if (IsIndexed(g_main_cp_state.vtx_desc.low.Color[i]))
+ cached_arraybases[ARRAY_COLOR + i] =
+ Memory::GetPointer(g_main_cp_state.array_bases[ARRAY_COLOR + i]);
+ }
+
+ for (size_t i = 0; i < g_main_cp_state.vtx_desc.high.TexCoord.Size(); i++)
{
- // Only update the array base if the vertex description states we are going to use it.
- if (g_main_cp_state.vtx_desc.GetVertexArrayStatus(i) & MASK_INDEXED)
- cached_arraybases[i] = Memory::GetPointer(g_main_cp_state.array_bases[i]);
+ if (IsIndexed(g_main_cp_state.vtx_desc.high.TexCoord[i]))
+ cached_arraybases[ARRAY_TEXCOORD0 + i] =
+ Memory::GetPointer(g_main_cp_state.array_bases[ARRAY_TEXCOORD0 + i]);
}
g_main_cp_state.bases_dirty = false;
@@ -317,15 +332,13 @@ void LoadCPReg(u32 sub_cmd, u32 value, bool is_preprocess)
break;
case VCD_LO:
- state->vtx_desc.Hex &= ~0x1FFFF; // keep the Upper bits
- state->vtx_desc.Hex |= value;
+ state->vtx_desc.low.Hex = value;
state->attr_dirty = BitSet32::AllTrue(CP_NUM_VAT_REG);
state->bases_dirty = true;
break;
case VCD_HI:
- state->vtx_desc.Hex &= 0x1FFFF; // keep the lower 17Bits
- state->vtx_desc.Hex |= (u64)value << 17;
+ state->vtx_desc.high.Hex = value;
state->attr_dirty = BitSet32::AllTrue(CP_NUM_VAT_REG);
state->bases_dirty = true;
break;
@@ -371,8 +384,8 @@ void FillCPMemoryArray(u32* memory)
{
memory[MATINDEX_A] = g_main_cp_state.matrix_index_a.Hex;
memory[MATINDEX_B] = g_main_cp_state.matrix_index_b.Hex;
- memory[VCD_LO] = (u32)g_main_cp_state.vtx_desc.Hex;
- memory[VCD_HI] = (u32)(g_main_cp_state.vtx_desc.Hex >> 17);
+ memory[VCD_LO] = g_main_cp_state.vtx_desc.low.Hex;
+ memory[VCD_HI] = g_main_cp_state.vtx_desc.high.Hex;
for (int i = 0; i < CP_NUM_VAT_REG; ++i)
{
diff --git a/Source/Core/VideoCommon/VertexLoaderX64.cpp b/Source/Core/VideoCommon/VertexLoaderX64.cpp
index 96832e3449..44d85c42e4 100644
--- a/Source/Core/VideoCommon/VertexLoaderX64.cpp
+++ b/Source/Core/VideoCommon/VertexLoaderX64.cpp
@@ -2,6 +2,9 @@
// Licensed under GPLv2+
// Refer to the license.txt file included.
+#include "VideoCommon/VertexLoaderX64.h"
+
+#include <array>
#include <cstring>
#include <string>
@@ -15,7 +18,6 @@
#include "Common/x64Emitter.h"
#include "VideoCommon/DataReader.h"
#include "VideoCommon/VertexLoaderManager.h"
-#include "VideoCommon/VertexLoaderX64.h"
using namespace Gen;
@@ -55,12 +57,12 @@ VertexLoaderX64::VertexLoaderX64(const TVtxDesc& vtx_desc, const VAT& vtx_att)
JitRegister::Register(region, GetCodePtr(), name.c_str());
}
-OpArg VertexLoaderX64::GetVertexAddr(int array, u64 attribute)
+OpArg VertexLoaderX64::GetVertexAddr(int array, VertexComponentFormat attribute)
{
OpArg data = MDisp(src_reg, m_src_ofs);
- if (attribute & MASK_INDEXED)
+ if (IsIndexed(attribute))
{
- int bits = attribute == INDEX8 ? 8 : 16;
+ int bits = attribute == VertexComponentFormat::Index8 ? 8 : 16;
LoadAndSwap(bits, scratch1, data);
m_src_ofs += bits / 8;
if (array == ARRAY_POSITION)
@@ -78,8 +80,8 @@ OpArg VertexLoaderX64::GetVertexAddr(int array, u64 attribute)
}
}
-int VertexLoaderX64::ReadVertex(OpArg data, u64 attribute, int format, int count_in, int count_out,
- bool dequantize, u8 scaling_exponent,
+int VertexLoaderX64::ReadVertex(OpArg data, VertexComponentFormat attribute, ComponentFormat format,
+ int count_in, int count_out, bool dequantize, u8 scaling_exponent,
AttributeFormat* native_format)
{
static const __m128i shuffle_lut[5][3] = {
@@ -115,7 +117,7 @@ int VertexLoaderX64::ReadVertex(OpArg data, u64 attribute, int format, int count
X64Reg coords = XMM0;
- int elem_size = 1 << (format / 2);
+ int elem_size = GetElementSize(format);
int load_bytes = elem_size * count_in;
OpArg dest = MDisp(dst_reg, m_dst_ofs);
@@ -127,7 +129,7 @@ int VertexLoaderX64::ReadVertex(OpArg data, u64 attribute, int format, int count
m_dst_ofs += sizeof(float) * count_out;
- if (attribute == DIRECT)
+ if (attribute == VertexComponentFormat::Direct)
m_src_ofs += load_bytes;
if (cpu_info.bSSSE3)
@@ -139,12 +141,12 @@ int VertexLoaderX64::ReadVertex(OpArg data, u64 attribute, int format, int count
else
MOVD_xmm(coords, data);
- PSHUFB(coords, MPIC(&shuffle_lut[format][count_in - 1]));
+ PSHUFB(coords, MPIC(&shuffle_lut[u32(format)][count_in - 1]));
// Sign-extend.
- if (format == FORMAT_BYTE)
+ if (format == ComponentFormat::Byte)
PSRAD(coords, 24);
- if (format == FORMAT_SHORT)
+ if (format == ComponentFormat::Short)
PSRAD(coords, 16);
}
else
@@ -153,20 +155,20 @@ int VertexLoaderX64::ReadVertex(OpArg data, u64 attribute, int format, int count
X64Reg temp = XMM1;
switch (format)
{
- case FORMAT_UBYTE:
+ case ComponentFormat::UByte:
MOVD_xmm(coords, data);
PXOR(temp, R(temp));
PUNPCKLBW(coords, R(temp));
PUNPCKLWD(coords, R(temp));
break;
- case FORMAT_BYTE:
+ case ComponentFormat::Byte:
MOVD_xmm(coords, data);
PUNPCKLBW(coords, R(coords));
PUNPCKLWD(coords, R(coords));
PSRAD(coords, 24);
break;
- case FORMAT_USHORT:
- case FORMAT_SHORT:
+ case ComponentFormat::UShort:
+ case ComponentFormat::Short:
switch (count_in)
{
case 1:
@@ -185,12 +187,12 @@ int VertexLoaderX64::ReadVertex(OpArg data, u64 attribute, int format, int count
PSHUFLW(coords, R(coords), 0xAC); // ..Z.Y.X.
break;
}
- if (format == FORMAT_SHORT)
+ if (format == ComponentFormat::Short)
PSRAD(coords, 16);
else
PSRLD(coords, 16);
break;
- case FORMAT_FLOAT:
+ case ComponentFormat::Float:
// Floats don't need to be scaled or converted,
// so we can just load/swap/store them directly
// and return early.
@@ -231,7 +233,7 @@ int VertexLoaderX64::ReadVertex(OpArg data, u64 attribute, int format, int count
}
}
- if (format != FORMAT_FLOAT)
+ if (format != ComponentFormat::Float)
{
CVTDQ2PS(coords, R(coords));
@@ -265,22 +267,22 @@ int VertexLoaderX64::ReadVertex(OpArg data, u64 attribute, int format, int count
return load_bytes;
}
-void VertexLoaderX64::ReadColor(OpArg data, u64 attribute, int format)
+void VertexLoaderX64::ReadColor(OpArg data, VertexComponentFormat attribute, ColorFormat format)
{
int load_bytes = 0;
switch (format)
{
- case FORMAT_24B_888:
- case FORMAT_32B_888x:
- case FORMAT_32B_8888:
+ case ColorFormat::RGB888:
+ case ColorFormat::RGB888x:
+ case ColorFormat::RGBA8888:
MOV(32, R(scratch1), data);
- if (format != FORMAT_32B_8888)
+ if (format != ColorFormat::RGBA8888)
OR(32, R(scratch1), Imm32(0xFF000000));
MOV(32, MDisp(dst_reg, m_dst_ofs), R(scratch1));
- load_bytes = 3 + (format != FORMAT_24B_888);
+ load_bytes = format == ColorFormat::RGB888 ? 3 : 4;
break;
- case FORMAT_16B_565:
+ case ColorFormat::RGB565:
// RRRRRGGG GGGBBBBB
// AAAAAAAA BBBBBBBB GGGGGGGG RRRRRRRR
LoadAndSwap(16, scratch1, data);
@@ -320,7 +322,7 @@ void VertexLoaderX64::ReadColor(OpArg data, u64 attribute, int format)
load_bytes = 2;
break;
- case FORMAT_16B_4444:
+ case ColorFormat::RGBA4444:
// RRRRGGGG BBBBAAAA
// AAAAAAAA BBBBBBBB GGGGGGGG RRRRRRRR
LoadAndSwap(16, scratch1, data);
@@ -348,7 +350,7 @@ void VertexLoaderX64::ReadColor(OpArg data, u64 attribute, int format)
load_bytes = 2;
break;
- case FORMAT_24B_6666:
+ case ColorFormat::RGBA6666:
// RRRRRRGG GGGGBBBB BBAAAAAA
// AAAAAAAA BBBBBBBB GGGGGGGG RRRRRRRR
data.AddMemOffset(-1); // subtract one from address so we can use a 32bit load and bswap
@@ -380,7 +382,7 @@ void VertexLoaderX64::ReadColor(OpArg data, u64 attribute, int format)
load_bytes = 3;
break;
}
- if (attribute == DIRECT)
+ if (attribute == VertexComponentFormat::Direct)
m_src_ofs += load_bytes;
}
@@ -399,14 +401,14 @@ void VertexLoaderX64::GenerateVertexLoader()
MOV(64, R(base_reg), R(ABI_PARAM4));
- if (m_VtxDesc.Position & MASK_INDEXED)
+ if (IsIndexed(m_VtxDesc.low.Position))
XOR(32, R(skipped_reg), R(skipped_reg));
// TODO: load constants into registers outside the main loop
const u8* loop_start = GetCodePtr();
- if (m_VtxDesc.PosMatIdx)
+ if (m_VtxDesc.low.PosMatIdx)
{
MOVZX(32, 8, scratch1, MDisp(src_reg, m_src_ofs));
AND(32, R(scratch1), Imm8(0x3F));
@@ -428,51 +430,47 @@ void VertexLoaderX64::GenerateVertexLoader()
m_dst_ofs += sizeof(u32);
}
- u32 texmatidx_ofs[8];
- const u64 tm[8] = {
- m_VtxDesc.Tex0MatIdx, m_VtxDesc.Tex1MatIdx, m_VtxDesc.Tex2MatIdx, m_VtxDesc.Tex3MatIdx,
- m_VtxDesc.Tex4MatIdx, m_VtxDesc.Tex5MatIdx, m_VtxDesc.Tex6MatIdx, m_VtxDesc.Tex7MatIdx,
- };
- for (int i = 0; i < 8; i++)
+ std::array<u32, 8> texmatidx_ofs;
+ for (size_t i = 0; i < m_VtxDesc.low.TexMatIdx.Size(); i++)
{
- if (tm[i])
+ if (m_VtxDesc.low.TexMatIdx[i])
texmatidx_ofs[i] = m_src_ofs++;
}
- OpArg data = GetVertexAddr(ARRAY_POSITION, m_VtxDesc.Position);
- int pos_elements = 2 + m_VtxAttr.PosElements;
- ReadVertex(data, m_VtxDesc.Position, m_VtxAttr.PosFormat, pos_elements, pos_elements,
+ OpArg data = GetVertexAddr(ARRAY_POSITION, m_VtxDesc.low.Position);
+ int pos_elements = m_VtxAttr.PosElements == CoordComponentCount::XY ? 2 : 3;
+ ReadVertex(data, m_VtxDesc.low.Position, m_VtxAttr.PosFormat, pos_elements, pos_elements,
m_VtxAttr.ByteDequant, m_VtxAttr.PosFrac, &m_native_vtx_decl.position);
- if (m_VtxDesc.Normal)
+ if (m_VtxDesc.low.Normal != VertexComponentFormat::NotPresent)
{
static const u8 map[8] = {7, 6, 15, 14};
- u8 scaling_exponent = map[m_VtxAttr.NormalFormat];
+ const u8 scaling_exponent = map[u32(m_VtxAttr.NormalFormat)];
+ const int limit = m_VtxAttr.NormalElements == NormalComponentCount::NBT ? 3 : 1;
- for (int i = 0; i < (m_VtxAttr.NormalElements ? 3 : 1); i++)
+ for (int i = 0; i < limit; i++)
{
if (!i || m_VtxAttr.NormalIndex3)
{
- data = GetVertexAddr(ARRAY_NORMAL, m_VtxDesc.Normal);
- int elem_size = 1 << (m_VtxAttr.NormalFormat / 2);
+ data = GetVertexAddr(ARRAY_NORMAL, m_VtxDesc.low.Normal);
+ int elem_size = GetElementSize(m_VtxAttr.NormalFormat);
data.AddMemOffset(i * elem_size * 3);
}
- data.AddMemOffset(ReadVertex(data, m_VtxDesc.Normal, m_VtxAttr.NormalFormat, 3, 3, true,
+ data.AddMemOffset(ReadVertex(data, m_VtxDesc.low.Normal, m_VtxAttr.NormalFormat, 3, 3, true,
scaling_exponent, &m_native_vtx_decl.normals[i]));
}
m_native_components |= VB_HAS_NRM0;
- if (m_VtxAttr.NormalElements)
+ if (m_VtxAttr.NormalElements == NormalComponentCount::NBT)
m_native_components |= VB_HAS_NRM1 | VB_HAS_NRM2;
}
- const u64 col[2] = {m_VtxDesc.Color0, m_VtxDesc.Color1};
- for (int i = 0; i < 2; i++)
+ for (size_t i = 0; i < m_VtxDesc.low.Color.Size(); i++)
{
- if (col[i])
+ if (m_VtxDesc.low.Color[i] != VertexComponentFormat::NotPresent)
{
- data = GetVertexAddr(ARRAY_COLOR + i, col[i]);
- ReadColor(data, col[i], m_VtxAttr.color[i].Comp);
+ data = GetVertexAddr(ARRAY_COLOR + int(i), m_VtxDesc.low.Color[i]);
+ ReadColor(data, m_VtxDesc.low.Color[i], m_VtxAttr.color[i].Comp);
m_native_components |= VB_HAS_COL0 << i;
m_native_vtx_decl.colors[i].components = 4;
m_native_vtx_decl.colors[i].enable = true;
@@ -483,22 +481,19 @@ void VertexLoaderX64::GenerateVertexLoader()
}
}
- const u64 tc[8] = {
- m_VtxDesc.Tex0Coord, m_VtxDesc.Tex1Coord, m_VtxDesc.Tex2Coord, m_VtxDesc.Tex3Coord,
- m_VtxDesc.Tex4Coord, m_VtxDesc.Tex5Coord, m_VtxDesc.Tex6Coord, m_VtxDesc.Tex7Coord,
- };
- for (int i = 0; i < 8; i++)
+ for (size_t i = 0; i < m_VtxDesc.high.TexCoord.Size(); i++)
{
- int elements = m_VtxAttr.texCoord[i].Elements + 1;
- if (tc[i])
+ int elements = m_VtxAttr.texCoord[i].Elements == TexComponentCount::ST ? 2 : 1;
+ if (m_VtxDesc.high.TexCoord[i] != VertexComponentFormat::NotPresent)
{
- data = GetVertexAddr(ARRAY_TEXCOORD0 + i, tc[i]);
+ data = GetVertexAddr(ARRAY_TEXCOORD0 + int(i), m_VtxDesc.high.TexCoord[i]);
u8 scaling_exponent = m_VtxAttr.texCoord[i].Frac;
- ReadVertex(data, tc[i], m_VtxAttr.texCoord[i].Format, elements, tm[i] ? 2 : elements,
- m_VtxAttr.ByteDequant, scaling_exponent, &m_native_vtx_decl.texcoords[i]);
+ ReadVertex(data, m_VtxDesc.high.TexCoord[i], m_VtxAttr.texCoord[i].Format, elements,
+ m_VtxDesc.low.TexMatIdx[i] ? 2 : elements, m_VtxAttr.ByteDequant, scaling_exponent,
+ &m_native_vtx_decl.texcoords[i]);
m_native_components |= VB_HAS_UV0 << i;
}
- if (tm[i])
+ if (m_VtxDesc.low.TexMatIdx[i])
{
m_native_components |= VB_HAS_TEXMTXIDX0 << i;
m_native_vtx_decl.texcoords[i].components = 3;
@@ -506,7 +501,7 @@ void VertexLoaderX64::GenerateVertexLoader()
m_native_vtx_decl.texcoords[i].type = VAR_FLOAT;
m_native_vtx_decl.texcoords[i].integer = false;
MOVZX(64, 8, scratch1, MDisp(src_reg, texmatidx_ofs[i]));
- if (tc[i])
+ if (m_VtxDesc.high.TexCoord[i] != VertexComponentFormat::NotPresent)
{
CVTSI2SS(XMM0, R(scratch1));
MOVSS(MDisp(dst_reg, m_dst_ofs), XMM0);
@@ -537,7 +532,7 @@ void VertexLoaderX64::GenerateVertexLoader()
ABI_PopRegistersAndAdjustStack(regs, 0);
- if (m_VtxDesc.Position & MASK_INDEXED)
+ if (IsIndexed(m_VtxDesc.low.Position))
{
SUB(32, R(ABI_RETURN), R(skipped_reg));
RET();
diff --git a/Source/Core/VideoCommon/VertexLoaderX64.h b/Source/Core/VideoCommon/VertexLoaderX64.h
index 8bd1e777ff..0344d7f1c9 100644
--- a/Source/Core/VideoCommon/VertexLoaderX64.h
+++ b/Source/Core/VideoCommon/VertexLoaderX64.h
@@ -8,6 +8,10 @@
#include "Common/x64Emitter.h"
#include "VideoCommon/VertexLoaderBase.h"
+enum class VertexComponentFormat;
+enum class ComponentFormat;
+enum class ColorFormat;
+
class VertexLoaderX64 : public VertexLoaderBase, public Gen::X64CodeBlock
{
public:
@@ -22,9 +26,10 @@ private:
u32 m_src_ofs = 0;
u32 m_dst_ofs = 0;
Gen::FixupBranch m_skip_vertex;
- Gen::OpArg GetVertexAddr(int array, u64 attribute);
- int ReadVertex(Gen::OpArg data, u64 attribute, int format, int count_in, int count_out,
- bool dequantize, u8 scaling_exponent, AttributeFormat* native_format);
- void ReadColor(Gen::OpArg data, u64 attribute, int format);
+ Gen::OpArg GetVertexAddr(int array, VertexComponentFormat attribute);
+ int ReadVertex(Gen::OpArg data, VertexComponentFormat attribute, ComponentFormat format,
+ int count_in, int count_out, bool dequantize, u8 scaling_exponent,
+ AttributeFormat* native_format);
+ void ReadColor(Gen::OpArg data, VertexComponentFormat attribute, ColorFormat format);
void GenerateVertexLoader();
};
diff --git a/Source/Core/VideoCommon/VertexLoader_Normal.cpp b/Source/Core/VideoCommon/VertexLoader_Normal.cpp
index b5caee8a72..c59b3bc13e 100644
--- a/Source/Core/VideoCommon/VertexLoader_Normal.cpp
+++ b/Source/Core/VideoCommon/VertexLoader_Normal.cpp
@@ -230,12 +230,15 @@ constexpr Types InitializeTable()
constexpr Types s_table = InitializeTable();
} // Anonymous namespace
-u32 VertexLoader_Normal::GetSize(u64 type, u32 format, u32 elements, u32 index3)
+u32 VertexLoader_Normal::GetSize(VertexComponentFormat type, ComponentFormat format,
+ NormalComponentCount elements, u32 index3)
{
- return s_table[type][index3][elements][format].gc_size;
+ return s_table[u32(type)][index3][u32(elements)][u32(format)].gc_size;
}
-TPipelineFunction VertexLoader_Normal::GetFunction(u64 type, u32 format, u32 elements, u32 index3)
+TPipelineFunction VertexLoader_Normal::GetFunction(VertexComponentFormat type,
+ ComponentFormat format,
+ NormalComponentCount elements, u32 index3)
{
- return s_table[type][index3][elements][format].function;
+ return s_table[u32(type)][index3][u32(elements)][u32(format)].function;
}
diff --git a/Source/Core/VideoCommon/VertexLoader_Normal.h b/Source/Core/VideoCommon/VertexLoader_Normal.h
index c2f782af7a..49aa1defa2 100644
--- a/Source/Core/VideoCommon/VertexLoader_Normal.h
+++ b/Source/Core/VideoCommon/VertexLoader_Normal.h
@@ -7,10 +7,16 @@
#include "Common/CommonTypes.h"
#include "VideoCommon/VertexLoader.h"
+enum class VertexComponentFormat;
+enum class ComponentFormat;
+enum class NormalComponentCount;
+
class VertexLoader_Normal
{
public:
- static u32 GetSize(u64 type, u32 format, u32 elements, u32 index3);
+ static u32 GetSize(VertexComponentFormat type, ComponentFormat format,
+ NormalComponentCount elements, u32 index3);
- static TPipelineFunction GetFunction(u64 type, u32 format, u32 elements, u32 index3);
+ static TPipelineFunction GetFunction(VertexComponentFormat type, ComponentFormat format,
+ NormalComponentCount elements, u32 index3);
};
diff --git a/Source/Core/VideoCommon/VertexLoader_Position.cpp b/Source/Core/VideoCommon/VertexLoader_Position.cpp
index 9808c76e65..6bdbb39d35 100644
--- a/Source/Core/VideoCommon/VertexLoader_Position.cpp
+++ b/Source/Core/VideoCommon/VertexLoader_Position.cpp
@@ -200,12 +200,15 @@ constexpr u32 s_table_read_position_vertex_size[4][8][2] = {
};
} // Anonymous namespace
-u32 VertexLoader_Position::GetSize(u64 type, u32 format, u32 elements)
+u32 VertexLoader_Position::GetSize(VertexComponentFormat type, ComponentFormat format,
+ CoordComponentCount elements)
{
- return s_table_read_position_vertex_size[type][format][elements];
+ return s_table_read_position_vertex_size[u32(type)][u32(format)][u32(elements)];
}
-TPipelineFunction VertexLoader_Position::GetFunction(u64 type, u32 format, u32 elements)
+TPipelineFunction VertexLoader_Position::GetFunction(VertexComponentFormat type,
+ ComponentFormat format,
+ CoordComponentCount elements)
{
- return s_table_read_position[type][format][elements];
+ return s_table_read_position[u32(type)][u32(format)][u32(elements)];
}
diff --git a/Source/Core/VideoCommon/VertexLoader_Position.h b/Source/Core/VideoCommon/VertexLoader_Position.h
index a38d277278..74208c2f8d 100644
--- a/Source/Core/VideoCommon/VertexLoader_Position.h
+++ b/Source/Core/VideoCommon/VertexLoader_Position.h
@@ -7,10 +7,16 @@
#include "Common/CommonTypes.h"
#include "VideoCommon/VertexLoader.h"
+enum class VertexComponentFormat;
+enum class ComponentFormat;
+enum class CoordComponentCount;
+
class VertexLoader_Position
{
public:
- static u32 GetSize(u64 type, u32 format, u32 elements);
+ static u32 GetSize(VertexComponentFormat type, ComponentFormat format,
+ CoordComponentCount elements);
- static TPipelineFunction GetFunction(u64 type, u32 format, u32 elements);
+ static TPipelineFunction GetFunction(VertexComponentFormat type, ComponentFormat format,
+ CoordComponentCount elements);
};
diff --git a/Source/Core/VideoCommon/VertexLoader_TextCoord.cpp b/Source/Core/VideoCommon/VertexLoader_TextCoord.cpp
index 26c1c7f256..7f1de2f487 100644
--- a/Source/Core/VideoCommon/VertexLoader_TextCoord.cpp
+++ b/Source/Core/VideoCommon/VertexLoader_TextCoord.cpp
@@ -191,14 +191,17 @@ constexpr u32 s_table_read_tex_coord_vertex_size[4][8][2] = {
};
} // Anonymous namespace
-u32 VertexLoader_TextCoord::GetSize(u64 type, u32 format, u32 elements)
+u32 VertexLoader_TextCoord::GetSize(VertexComponentFormat type, ComponentFormat format,
+ TexComponentCount elements)
{
- return s_table_read_tex_coord_vertex_size[type][format][elements];
+ return s_table_read_tex_coord_vertex_size[u32(type)][u32(format)][u32(elements)];
}
-TPipelineFunction VertexLoader_TextCoord::GetFunction(u64 type, u32 format, u32 elements)
+TPipelineFunction VertexLoader_TextCoord::GetFunction(VertexComponentFormat type,
+ ComponentFormat format,
+ TexComponentCount elements)
{
- return s_table_read_tex_coord[type][format][elements];
+ return s_table_read_tex_coord[u32(type)][u32(format)][u32(elements)];
}
TPipelineFunction VertexLoader_TextCoord::GetDummyFunction()
diff --git a/Source/Core/VideoCommon/VertexLoader_TextCoord.h b/Source/Core/VideoCommon/VertexLoader_TextCoord.h
index 48b9a8e136..dc5e62f648 100644
--- a/Source/Core/VideoCommon/VertexLoader_TextCoord.h
+++ b/Source/Core/VideoCommon/VertexLoader_TextCoord.h
@@ -7,12 +7,18 @@
#include "Common/CommonTypes.h"
#include "VideoCommon/VertexLoader.h"
+enum class VertexComponentFormat;
+enum class ComponentFormat;
+enum class TexComponentCount;
+
class VertexLoader_TextCoord
{
public:
- static u32 GetSize(u64 type, u32 format, u32 elements);
+ static u32 GetSize(VertexComponentFormat type, ComponentFormat format,
+ TexComponentCount elements);
- static TPipelineFunction GetFunction(u64 type, u32 format, u32 elements);
+ static TPipelineFunction GetFunction(VertexComponentFormat type, ComponentFormat format,
+ TexComponentCount elements);
// It is important to synchronize tcIndex.
static TPipelineFunction GetDummyFunction();
diff --git a/Source/Core/VideoCommon/VertexShaderManager.cpp b/Source/Core/VideoCommon/VertexShaderManager.cpp
index 9c82d9b431..121d6f1a21 100644
--- a/Source/Core/VideoCommon/VertexShaderManager.cpp
+++ b/Source/Core/VideoCommon/VertexShaderManager.cpp
@@ -618,9 +618,9 @@ void VertexShaderManager::SetVertexFormat(u32 components)
// The default alpha channel seems to depend on the number of components in the vertex format.
// If the vertex attribute has an alpha channel, zero is used, otherwise one.
- const u32 color_chan_alpha =
- (g_main_cp_state.vtx_attr[g_main_cp_state.last_id].g0.Color0Elements ^ 1) |
- ((g_main_cp_state.vtx_attr[g_main_cp_state.last_id].g0.Color1Elements ^ 1) << 1);
+ const auto g0 = g_main_cp_state.vtx_attr[g_main_cp_state.last_id].g0;
+ const u32 color_chan_alpha = (g0.Color0Elements == ColorComponentCount::RGB ? 1 : 0) |
+ (g0.Color1Elements == ColorComponentCount::RGB ? 2 : 0);
if (color_chan_alpha != constants.color_chan_alpha)
{
constants.color_chan_alpha = color_chan_alpha;
diff --git a/Source/UnitTests/VideoCommon/VertexLoaderTest.cpp b/Source/UnitTests/VideoCommon/VertexLoaderTest.cpp
index 666476dfce..bb09b1608e 100644
--- a/Source/UnitTests/VideoCommon/VertexLoaderTest.cpp
+++ b/Source/UnitTests/VideoCommon/VertexLoaderTest.cpp
@@ -28,7 +28,7 @@ TEST(VertexLoaderUID, UniqueEnough)
memset(&vat, 0, sizeof(vat));
uids.insert(VertexLoaderUID(vtx_desc, vat));
- vtx_desc.Hex = 0xFEDCBA9876543210ull;
+ vtx_desc.SetLegacyHex(0xFEDCBA9876543210ull);
EXPECT_EQ(uids.end(), uids.find(VertexLoaderUID(vtx_desc, vat)));
uids.insert(VertexLoaderUID(vtx_desc, vat));
@@ -106,29 +106,37 @@ protected:
std::unique_ptr<VertexLoaderBase> m_loader;
};
-class VertexLoaderParamTest : public VertexLoaderTest,
- public ::testing::WithParamInterface<std::tuple<int, int, int, int>>
+class VertexLoaderParamTest
+ : public VertexLoaderTest,
+ public ::testing::WithParamInterface<
+ std::tuple<VertexComponentFormat, ComponentFormat, CoordComponentCount, int>>
{
};
-INSTANTIATE_TEST_CASE_P(AllCombinations, VertexLoaderParamTest,
- ::testing::Combine(::testing::Values(DIRECT, INDEX8, INDEX16),
- ::testing::Values(FORMAT_UBYTE, FORMAT_BYTE,
- FORMAT_USHORT, FORMAT_SHORT,
- FORMAT_FLOAT),
- ::testing::Values(0, 1), // elements
- ::testing::Values(0, 1, 31) // frac
- ));
+INSTANTIATE_TEST_CASE_P(
+ AllCombinations, VertexLoaderParamTest,
+ ::testing::Combine(
+ ::testing::Values(VertexComponentFormat::Direct, VertexComponentFormat::Index8,
+ VertexComponentFormat::Index16),
+ ::testing::Values(ComponentFormat::UByte, ComponentFormat::Byte, ComponentFormat::UShort,
+ ComponentFormat::Short, ComponentFormat::Float),
+ ::testing::Values(CoordComponentCount::XY, CoordComponentCount::XYZ),
+ ::testing::Values(0, 1, 31) // frac
+ ));
TEST_P(VertexLoaderParamTest, PositionAll)
{
- int addr, format, elements, frac;
+ VertexComponentFormat addr;
+ ComponentFormat format;
+ CoordComponentCount elements;
+ int frac;
std::tie(addr, format, elements, frac) = GetParam();
- this->m_vtx_desc.Position = addr;
+ this->m_vtx_desc.low.Position = addr;
this->m_vtx_attr.g0.PosFormat = format;
this->m_vtx_attr.g0.PosElements = elements;
this->m_vtx_attr.g0.PosFrac = frac;
this->m_vtx_attr.g0.ByteDequant = true;
- elements += 2;
+ const u32 elem_size = GetElementSize(format);
+ const u32 elem_count = elements == CoordComponentCount::XY ? 2 : 3;
std::vector<float> values = {
std::numeric_limits<float>::lowest(),
@@ -153,38 +161,37 @@ TEST_P(VertexLoaderParamTest, PositionAll)
ASSERT_EQ(0u, values.size() % 2);
ASSERT_EQ(0u, values.size() % 3);
- int count = (int)values.size() / elements;
- u32 elem_size = 1 << (format / 2);
- size_t input_size = elements * elem_size;
- if (addr & MASK_INDEXED)
+ int count = (int)values.size() / elem_count;
+ size_t input_size = elem_count * elem_size;
+ if (IsIndexed(addr))
{
- input_size = addr - 1;
+ input_size = addr == VertexComponentFormat::Index8 ? 1 : 2;
for (int i = 0; i < count; i++)
- if (addr == INDEX8)
+ if (addr == VertexComponentFormat::Index8)
Input<u8>(i);
else
Input<u16>(i);
VertexLoaderManager::cached_arraybases[ARRAY_POSITION] = m_src.GetPointer();
- g_main_cp_state.array_strides[ARRAY_POSITION] = elements * elem_size;
+ g_main_cp_state.array_strides[ARRAY_POSITION] = elem_count * elem_size;
}
- CreateAndCheckSizes(input_size, elements * sizeof(float));
+ CreateAndCheckSizes(input_size, elem_count * sizeof(float));
for (float value : values)
{
switch (format)
{
- case FORMAT_UBYTE:
+ case ComponentFormat::UByte:
Input((u8)value);
break;
- case FORMAT_BYTE:
+ case ComponentFormat::Byte:
Input((s8)value);
break;
- case FORMAT_USHORT:
+ case ComponentFormat::UShort:
Input((u16)value);
break;
- case FORMAT_SHORT:
+ case ComponentFormat::Short:
Input((s16)value);
break;
- case FORMAT_FLOAT:
+ case ComponentFormat::Float:
Input(value);
break;
}
@@ -192,29 +199,29 @@ TEST_P(VertexLoaderParamTest, PositionAll)
RunVertices(count);
- float scale = 1.f / (1u << (format == FORMAT_FLOAT ? 0 : frac));
+ float scale = 1.f / (1u << (format == ComponentFormat::Float ? 0 : frac));
for (auto iter = values.begin(); iter != values.end();)
{
float f, g;
switch (format)
{
- case FORMAT_UBYTE:
+ case ComponentFormat::UByte:
f = (u8)*iter++;
g = (u8)*iter++;
break;
- case FORMAT_BYTE:
+ case ComponentFormat::Byte:
f = (s8)*iter++;
g = (s8)*iter++;
break;
- case FORMAT_USHORT:
+ case ComponentFormat::UShort:
f = (u16)*iter++;
g = (u16)*iter++;
break;
- case FORMAT_SHORT:
+ case ComponentFormat::Short:
f = (s16)*iter++;
g = (s16)*iter++;
break;
- case FORMAT_FLOAT:
+ case ComponentFormat::Float:
f = *iter++;
g = *iter++;
break;
@@ -228,8 +235,8 @@ TEST_P(VertexLoaderParamTest, PositionAll)
TEST_F(VertexLoaderTest, PositionIndex16FloatXY)
{
- m_vtx_desc.Position = INDEX16;
- m_vtx_attr.g0.PosFormat = FORMAT_FLOAT;
+ m_vtx_desc.low.Position = VertexComponentFormat::Index16;
+ m_vtx_attr.g0.PosFormat = ComponentFormat::Float;
CreateAndCheckSizes(sizeof(u16), 2 * sizeof(float));
Input<u16>(1);
Input<u16>(0);
@@ -246,47 +253,49 @@ TEST_F(VertexLoaderTest, PositionIndex16FloatXY)
}
class VertexLoaderSpeedTest : public VertexLoaderTest,
- public ::testing::WithParamInterface<std::tuple<int, int>>
+ public ::testing::WithParamInterface<std::tuple<ComponentFormat, int>>
{
};
-INSTANTIATE_TEST_CASE_P(FormatsAndElements, VertexLoaderSpeedTest,
- ::testing::Combine(::testing::Values(FORMAT_UBYTE, FORMAT_BYTE,
- FORMAT_USHORT, FORMAT_SHORT,
- FORMAT_FLOAT),
- ::testing::Values(0, 1) // elements
- ));
+INSTANTIATE_TEST_CASE_P(
+ FormatsAndElements, VertexLoaderSpeedTest,
+ ::testing::Combine(::testing::Values(ComponentFormat::UByte, ComponentFormat::Byte,
+ ComponentFormat::UShort, ComponentFormat::Short,
+ ComponentFormat::Float),
+ ::testing::Values(0, 1)));
TEST_P(VertexLoaderSpeedTest, PositionDirectAll)
{
- int format, elements;
- std::tie(format, elements) = GetParam();
- const char* map[] = {"u8", "s8", "u16", "s16", "float"};
- printf("format: %s, elements: %d\n", map[format], elements);
- m_vtx_desc.Position = DIRECT;
+ ComponentFormat format;
+ int elements_i;
+ std::tie(format, elements_i) = GetParam();
+ CoordComponentCount elements = static_cast<CoordComponentCount>(elements_i);
+ fmt::print("format: {}, elements: {}\n", format, elements);
+ const u32 elem_count = elements == CoordComponentCount::XY ? 2 : 3;
+ m_vtx_desc.low.Position = VertexComponentFormat::Direct;
m_vtx_attr.g0.PosFormat = format;
m_vtx_attr.g0.PosElements = elements;
- elements += 2;
- size_t elem_size = static_cast<size_t>(1) << (format / 2);
- CreateAndCheckSizes(elements * elem_size, elements * sizeof(float));
+ const size_t elem_size = GetElementSize(format);
+ CreateAndCheckSizes(elem_count * elem_size, elem_count * sizeof(float));
for (int i = 0; i < 1000; ++i)
RunVertices(100000);
}
TEST_P(VertexLoaderSpeedTest, TexCoordSingleElement)
{
- int format, elements;
- std::tie(format, elements) = GetParam();
- const char* map[] = {"u8", "s8", "u16", "s16", "float"};
- printf("format: %s, elements: %d\n", map[format], elements);
- m_vtx_desc.Position = DIRECT;
- m_vtx_attr.g0.PosFormat = FORMAT_BYTE;
- m_vtx_desc.Tex0Coord = DIRECT;
+ ComponentFormat format;
+ int elements_i;
+ std::tie(format, elements_i) = GetParam();
+ TexComponentCount elements = static_cast<TexComponentCount>(elements_i);
+ fmt::print("format: {}, elements: {}\n", format, elements);
+ const u32 elem_count = elements == TexComponentCount::S ? 1 : 2;
+ m_vtx_desc.low.Position = VertexComponentFormat::Direct;
+ m_vtx_attr.g0.PosFormat = ComponentFormat::Byte;
+ m_vtx_desc.high.Tex0Coord = VertexComponentFormat::Direct;
m_vtx_attr.g0.Tex0CoordFormat = format;
m_vtx_attr.g0.Tex0CoordElements = elements;
- elements += 1;
- size_t elem_size = static_cast<size_t>(1) << (format / 2);
- CreateAndCheckSizes(2 * sizeof(s8) + elements * elem_size,
- 2 * sizeof(float) + elements * sizeof(float));
+ const size_t elem_size = GetElementSize(format);
+ CreateAndCheckSizes(2 * sizeof(s8) + elem_count * elem_size,
+ 2 * sizeof(float) + elem_count * sizeof(float));
for (int i = 0; i < 1000; ++i)
RunVertices(100000);
}
@@ -294,52 +303,52 @@ TEST_P(VertexLoaderSpeedTest, TexCoordSingleElement)
TEST_F(VertexLoaderTest, LargeFloatVertexSpeed)
{
// Enables most attributes in floating point indexed mode to test speed.
- m_vtx_desc.PosMatIdx = 1;
- m_vtx_desc.Tex0MatIdx = 1;
- m_vtx_desc.Tex1MatIdx = 1;
- m_vtx_desc.Tex2MatIdx = 1;
- m_vtx_desc.Tex3MatIdx = 1;
- m_vtx_desc.Tex4MatIdx = 1;
- m_vtx_desc.Tex5MatIdx = 1;
- m_vtx_desc.Tex6MatIdx = 1;
- m_vtx_desc.Tex7MatIdx = 1;
- m_vtx_desc.Position = INDEX16;
- m_vtx_desc.Normal = INDEX16;
- m_vtx_desc.Color0 = INDEX16;
- m_vtx_desc.Color1 = INDEX16;
- m_vtx_desc.Tex0Coord = INDEX16;
- m_vtx_desc.Tex1Coord = INDEX16;
- m_vtx_desc.Tex2Coord = INDEX16;
- m_vtx_desc.Tex3Coord = INDEX16;
- m_vtx_desc.Tex4Coord = INDEX16;
- m_vtx_desc.Tex5Coord = INDEX16;
- m_vtx_desc.Tex6Coord = INDEX16;
- m_vtx_desc.Tex7Coord = INDEX16;
-
- m_vtx_attr.g0.PosElements = 1; // XYZ
- m_vtx_attr.g0.PosFormat = FORMAT_FLOAT;
- m_vtx_attr.g0.NormalElements = 1; // NBT
- m_vtx_attr.g0.NormalFormat = FORMAT_FLOAT;
- m_vtx_attr.g0.Color0Elements = 1; // Has Alpha
- m_vtx_attr.g0.Color0Comp = FORMAT_32B_8888;
- m_vtx_attr.g0.Color1Elements = 1; // Has Alpha
- m_vtx_attr.g0.Color1Comp = FORMAT_32B_8888;
- m_vtx_attr.g0.Tex0CoordElements = 1; // ST
- m_vtx_attr.g0.Tex0CoordFormat = FORMAT_FLOAT;
- m_vtx_attr.g1.Tex1CoordElements = 1; // ST
- m_vtx_attr.g1.Tex1CoordFormat = FORMAT_FLOAT;
- m_vtx_attr.g1.Tex2CoordElements = 1; // ST
- m_vtx_attr.g1.Tex2CoordFormat = FORMAT_FLOAT;
- m_vtx_attr.g1.Tex3CoordElements = 1; // ST
- m_vtx_attr.g1.Tex3CoordFormat = FORMAT_FLOAT;
- m_vtx_attr.g1.Tex4CoordElements = 1; // ST
- m_vtx_attr.g1.Tex4CoordFormat = FORMAT_FLOAT;
- m_vtx_attr.g2.Tex5CoordElements = 1; // ST
- m_vtx_attr.g2.Tex5CoordFormat = FORMAT_FLOAT;
- m_vtx_attr.g2.Tex6CoordElements = 1; // ST
- m_vtx_attr.g2.Tex6CoordFormat = FORMAT_FLOAT;
- m_vtx_attr.g2.Tex7CoordElements = 1; // ST
- m_vtx_attr.g2.Tex7CoordFormat = FORMAT_FLOAT;
+ m_vtx_desc.low.PosMatIdx = 1;
+ m_vtx_desc.low.Tex0MatIdx = 1;
+ m_vtx_desc.low.Tex1MatIdx = 1;
+ m_vtx_desc.low.Tex2MatIdx = 1;
+ m_vtx_desc.low.Tex3MatIdx = 1;
+ m_vtx_desc.low.Tex4MatIdx = 1;
+ m_vtx_desc.low.Tex5MatIdx = 1;
+ m_vtx_desc.low.Tex6MatIdx = 1;
+ m_vtx_desc.low.Tex7MatIdx = 1;
+ m_vtx_desc.low.Position = VertexComponentFormat::Index16;
+ m_vtx_desc.low.Normal = VertexComponentFormat::Index16;
+ m_vtx_desc.low.Color0 = VertexComponentFormat::Index16;
+ m_vtx_desc.low.Color1 = VertexComponentFormat::Index16;
+ m_vtx_desc.high.Tex0Coord = VertexComponentFormat::Index16;
+ m_vtx_desc.high.Tex1Coord = VertexComponentFormat::Index16;
+ m_vtx_desc.high.Tex2Coord = VertexComponentFormat::Index16;
+ m_vtx_desc.high.Tex3Coord = VertexComponentFormat::Index16;
+ m_vtx_desc.high.Tex4Coord = VertexComponentFormat::Index16;
+ m_vtx_desc.high.Tex5Coord = VertexComponentFormat::Index16;
+ m_vtx_desc.high.Tex6Coord = VertexComponentFormat::Index16;
+ m_vtx_desc.high.Tex7Coord = VertexComponentFormat::Index16;
+
+ m_vtx_attr.g0.PosElements = CoordComponentCount::XYZ;
+ m_vtx_attr.g0.PosFormat = ComponentFormat::Float;
+ m_vtx_attr.g0.NormalElements = NormalComponentCount::NBT;
+ m_vtx_attr.g0.NormalFormat = ComponentFormat::Float;
+ m_vtx_attr.g0.Color0Elements = ColorComponentCount::RGBA;
+ m_vtx_attr.g0.Color0Comp = ColorFormat::RGBA8888;
+ m_vtx_attr.g0.Color1Elements = ColorComponentCount::RGBA;
+ m_vtx_attr.g0.Color1Comp = ColorFormat::RGBA8888;
+ m_vtx_attr.g0.Tex0CoordElements = TexComponentCount::ST;
+ m_vtx_attr.g0.Tex0CoordFormat = ComponentFormat::Float;
+ m_vtx_attr.g1.Tex1CoordElements = TexComponentCount::ST;
+ m_vtx_attr.g1.Tex1CoordFormat = ComponentFormat::Float;
+ m_vtx_attr.g1.Tex2CoordElements = TexComponentCount::ST;
+ m_vtx_attr.g1.Tex2CoordFormat = ComponentFormat::Float;
+ m_vtx_attr.g1.Tex3CoordElements = TexComponentCount::ST;
+ m_vtx_attr.g1.Tex3CoordFormat = ComponentFormat::Float;
+ m_vtx_attr.g1.Tex4CoordElements = TexComponentCount::ST;
+ m_vtx_attr.g1.Tex4CoordFormat = ComponentFormat::Float;
+ m_vtx_attr.g2.Tex5CoordElements = TexComponentCount::ST;
+ m_vtx_attr.g2.Tex5CoordFormat = ComponentFormat::Float;
+ m_vtx_attr.g2.Tex6CoordElements = TexComponentCount::ST;
+ m_vtx_attr.g2.Tex6CoordFormat = ComponentFormat::Float;
+ m_vtx_attr.g2.Tex7CoordElements = TexComponentCount::ST;
+ m_vtx_attr.g2.Tex7CoordFormat = ComponentFormat::Float;
CreateAndCheckSizes(33, 156);