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 CalculateVertexElementSizes(int vatIndex, const CPMemory& cp const VAT& vtxAttr = cpMem.vtxAttr[vatIndex]; // Colors - const std::array colDesc{ - vtxDesc.Color0, - vtxDesc.Color1, - }; - const std::array colComp{ + const std::array colComp{ vtxAttr.g0.Color0Comp, vtxAttr.g0.Color1Comp, }; - const std::array tcElements{ + const std::array 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 tcFormat{ + const std::array 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 CalculateVertexElementSizes(int vatIndex, const CPMemory& cp std::array 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 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 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 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 +#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 { - NOT_PRESENT = 0, - DIRECT = 1, - INDEX8 = 2, - INDEX16 = 3, - - MASK_INDEXED = 2, + NotPresent = 0, + Direct = 1, + Index8 = 2, + Index16 = 3, +}; +template <> +struct fmt::formatter : EnumFormatter +{ + formatter() : EnumFormatter({"Not present", "Direct", "8-bit index", "16-bit index"}) {} }; -enum +constexpr bool IsIndexed(VertexComponentFormat format) { - FORMAT_UBYTE = 0, // 2 Cmp - FORMAT_BYTE = 1, // 3 Cmp - FORMAT_USHORT = 2, - FORMAT_SHORT = 3, - FORMAT_FLOAT = 4, + 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 : EnumFormatter +{ + formatter() : EnumFormatter({"Unsigned Byte", "Byte", "Unsigned Short", "Short", "Float"}) {} }; -enum +constexpr u32 GetElementSize(ComponentFormat format) { - 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, -}; - -#pragma pack(4) -union TVtxDesc -{ - u64 Hex; - struct + switch (format) { - // 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; + 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; + } +} - // 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; +enum class CoordComponentCount +{ + XY = 0, + XYZ = 1, +}; +template <> +struct fmt::formatter : EnumFormatter +{ + formatter() : EnumFormatter({"2 (x, y)", "3 (x, y, z)"}) {} +}; + +enum class NormalComponentCount +{ + N = 0, + NBT = 1, +}; +template <> +struct fmt::formatter : EnumFormatter +{ + formatter() : EnumFormatter({"1 (n)", "3 (n, b, t)"}) {} +}; + +enum class ColorComponentCount +{ + RGB = 0, + RGBA = 1, +}; +template <> +struct fmt::formatter : EnumFormatter +{ + 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 : EnumFormatter +{ + 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) {} +}; + +enum class TexComponentCount +{ + S = 0, + ST = 1, +}; +template <> +struct fmt::formatter : EnumFormatter +{ + formatter() : EnumFormatter({"1 (s)", "2 (s, t)"}) {} +}; + +struct TVtxDesc +{ + union Low + { + // 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; }; - struct - { - u32 Hex0, Hex1; - }; + Low low; + High high; - // Easily index into the Position..Tex7Coord fields. - u32 GetVertexArrayStatus(int idx) { return (Hex >> (9 + idx * 2)) & 0x3; } + // 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(GetLegacyHex()); } + // Only *1* bit is used in this + u32 GetLegacyHex1() const { return static_cast(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 + #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 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 pos_mode{{ - "Inv", - "Dir", - "I8", - "I16", - }}; - static constexpr std::array pos_formats{{ - "u8", - "s8", - "u16", - "s16", - "flt", - "Inv", - "Inv", - "Inv", - }}; - static constexpr std::array color_format{{ - "565", - "888", - "888x", - "4444", - "6666", - "8888", - "Inv", - "Inv", - }}; + dest += fmt::format("{}b skin: {} P: {} {}-{} ", m_VertexSize, m_VtxDesc.low.PosMatIdx, + m_VtxAttr.PosElements, m_VtxDesc.low.Position, m_VtxAttr.PosFormat); - 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) + 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 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 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++) { - // 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.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++) + { + 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 #include #include @@ -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 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 m_loader; }; -class VertexLoaderParamTest : public VertexLoaderTest, - public ::testing::WithParamInterface> +class VertexLoaderParamTest + : public VertexLoaderTest, + public ::testing::WithParamInterface< + std::tuple> { }; -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 values = { std::numeric_limits::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(i); else Input(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(1); Input(0); @@ -246,47 +253,49 @@ TEST_F(VertexLoaderTest, PositionIndex16FloatXY) } class VertexLoaderSpeedTest : public VertexLoaderTest, - public ::testing::WithParamInterface> + public ::testing::WithParamInterface> { }; -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(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(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(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(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_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 = 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_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);