summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorAdmiral H. Curtiss <pikachu025@gmail.com>2024-04-04 22:10:18 +0200
committerGitHub <noreply@github.com>2024-04-04 22:10:18 +0200
commitad331205d1b3c4efb41981a332c9d6fc86009ce3 (patch)
tree8ae92d26c027eaa38af74f5ba3528f5a7087b10e /Source/Core
parent4312840a4b8cd52ce1beee3a13ba12afe2b59e53 (diff)
parenta3951dc2d72ebb6f240d592fdbb348137130ce49 (diff)
Merge pull request #12684 from Pokechu22/invalid-vertex-component
Fix out of bounds accesses for invalid vertex component formats
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/DolphinAnalytics.cpp6
-rw-r--r--Source/Core/Core/DolphinAnalytics.h9
-rw-r--r--Source/Core/VideoBackends/D3D/D3DNativeVertexFormat.cpp26
-rw-r--r--Source/Core/VideoBackends/D3D12/DX12VertexFormat.cpp64
-rw-r--r--Source/Core/VideoBackends/Metal/MTLVertexFormat.mm6
-rw-r--r--Source/Core/VideoBackends/OGL/OGLNativeVertexFormat.cpp5
-rw-r--r--Source/Core/VideoBackends/Software/SWVertexLoader.cpp5
-rw-r--r--Source/Core/VideoBackends/Vulkan/VKVertexFormat.cpp64
-rw-r--r--Source/Core/VideoCommon/CPMemory.h14
-rw-r--r--Source/Core/VideoCommon/VertexLoaderARM64.cpp6
-rw-r--r--Source/Core/VideoCommon/VertexLoaderManager.cpp45
-rw-r--r--Source/Core/VideoCommon/VertexLoaderX64.cpp53
-rw-r--r--Source/Core/VideoCommon/VertexLoader_Normal.cpp38
-rw-r--r--Source/Core/VideoCommon/VertexLoader_Normal.h39
-rw-r--r--Source/Core/VideoCommon/VertexLoader_Position.cpp14
-rw-r--r--Source/Core/VideoCommon/VertexLoader_Position.h14
-rw-r--r--Source/Core/VideoCommon/VertexLoader_TextCoord.cpp14
-rw-r--r--Source/Core/VideoCommon/VertexLoader_TextCoord.h14
18 files changed, 349 insertions, 87 deletions
diff --git a/Source/Core/Core/DolphinAnalytics.cpp b/Source/Core/Core/DolphinAnalytics.cpp
index a7bb39d394..5a5118932b 100644
--- a/Source/Core/Core/DolphinAnalytics.cpp
+++ b/Source/Core/Core/DolphinAnalytics.cpp
@@ -137,7 +137,7 @@ void DolphinAnalytics::ReportGameStart()
}
// Keep in sync with enum class GameQuirk definition.
-constexpr std::array<const char*, 28> GAME_QUIRKS_NAMES{
+constexpr std::array<const char*, 32> GAME_QUIRKS_NAMES{
"directly-reads-wiimote-input",
"uses-DVDLowStopLaser",
"uses-DVDLowOffset",
@@ -166,6 +166,10 @@ constexpr std::array<const char*, 28> GAME_QUIRKS_NAMES{
"mismatched-gpu-tex-coords-between-cp-and-xf",
"mismatched-gpu-matrix-indices-between-cp-and-xf",
"reads-bounding-box",
+ "invalid-position-component-format",
+ "invalid-normal-component-format",
+ "invalid-texture-coordinate-component-format",
+ "invalid-color-component-format",
};
static_assert(GAME_QUIRKS_NAMES.size() == static_cast<u32>(GameQuirk::COUNT),
"Game quirks names and enum definition are out of sync.");
diff --git a/Source/Core/Core/DolphinAnalytics.h b/Source/Core/Core/DolphinAnalytics.h
index 76e69f49c2..7e701c9a36 100644
--- a/Source/Core/Core/DolphinAnalytics.h
+++ b/Source/Core/Core/DolphinAnalytics.h
@@ -94,6 +94,15 @@ enum class GameQuirk
// only a few read them (from PE_BBOX_LEFT etc.)
READS_BOUNDING_BOX,
+ // A few games use invalid vertex component formats, but the two known cases (Fifa Street and
+ // Def Jam: Fight for New York, see https://bugs.dolphin-emu.org/issues/12719) only use invalid
+ // normal formats and lighting is disabled in those cases, so it doesn't end up mattering.
+ // It's possible other games use invalid formats, possibly on other vertex components.
+ INVALID_POSITION_COMPONENT_FORMAT,
+ INVALID_NORMAL_COMPONENT_FORMAT,
+ INVALID_TEXTURE_COORDINATE_COMPONENT_FORMAT,
+ INVALID_COLOR_COMPONENT_FORMAT,
+
COUNT,
};
diff --git a/Source/Core/VideoBackends/D3D/D3DNativeVertexFormat.cpp b/Source/Core/VideoBackends/D3D/D3DNativeVertexFormat.cpp
index 54c1ae8220..0f81db9aaa 100644
--- a/Source/Core/VideoBackends/D3D/D3DNativeVertexFormat.cpp
+++ b/Source/Core/VideoBackends/D3D/D3DNativeVertexFormat.cpp
@@ -25,7 +25,7 @@ Gfx::CreateNativeVertexFormat(const PortableVertexDeclaration& vtx_decl)
DXGI_FORMAT VarToD3D(ComponentFormat t, int size, bool integer)
{
- using FormatMap = Common::EnumMap<DXGI_FORMAT, ComponentFormat::Float>;
+ using FormatMap = Common::EnumMap<DXGI_FORMAT, ComponentFormat::InvalidFloat7>;
static constexpr auto f = [](FormatMap a) { return a; }; // Deduction helper
static constexpr std::array<FormatMap, 4> d3d_float_format_lookup = {
@@ -35,6 +35,9 @@ DXGI_FORMAT VarToD3D(ComponentFormat t, int size, bool integer)
DXGI_FORMAT_R16_UNORM,
DXGI_FORMAT_R16_SNORM,
DXGI_FORMAT_R32_FLOAT,
+ DXGI_FORMAT_R32_FLOAT,
+ DXGI_FORMAT_R32_FLOAT,
+ DXGI_FORMAT_R32_FLOAT,
}),
f({
DXGI_FORMAT_R8G8_UNORM,
@@ -42,6 +45,9 @@ DXGI_FORMAT VarToD3D(ComponentFormat t, int size, bool integer)
DXGI_FORMAT_R16G16_UNORM,
DXGI_FORMAT_R16G16_SNORM,
DXGI_FORMAT_R32G32_FLOAT,
+ DXGI_FORMAT_R32G32_FLOAT,
+ DXGI_FORMAT_R32G32_FLOAT,
+ DXGI_FORMAT_R32G32_FLOAT,
}),
f({
DXGI_FORMAT_UNKNOWN,
@@ -49,6 +55,9 @@ DXGI_FORMAT VarToD3D(ComponentFormat t, int size, bool integer)
DXGI_FORMAT_UNKNOWN,
DXGI_FORMAT_UNKNOWN,
DXGI_FORMAT_R32G32B32_FLOAT,
+ DXGI_FORMAT_R32G32B32_FLOAT,
+ DXGI_FORMAT_R32G32B32_FLOAT,
+ DXGI_FORMAT_R32G32B32_FLOAT,
}),
f({
DXGI_FORMAT_R8G8B8A8_UNORM,
@@ -56,6 +65,9 @@ DXGI_FORMAT VarToD3D(ComponentFormat t, int size, bool integer)
DXGI_FORMAT_R16G16B16A16_UNORM,
DXGI_FORMAT_R16G16B16A16_SNORM,
DXGI_FORMAT_R32G32B32A32_FLOAT,
+ DXGI_FORMAT_R32G32B32A32_FLOAT,
+ DXGI_FORMAT_R32G32B32A32_FLOAT,
+ DXGI_FORMAT_R32G32B32A32_FLOAT,
}),
};
@@ -66,6 +78,9 @@ DXGI_FORMAT VarToD3D(ComponentFormat t, int size, bool integer)
DXGI_FORMAT_R16_UINT,
DXGI_FORMAT_R16_SINT,
DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
}),
f({
DXGI_FORMAT_R8G8_UINT,
@@ -73,6 +88,9 @@ DXGI_FORMAT VarToD3D(ComponentFormat t, int size, bool integer)
DXGI_FORMAT_R16G16_UINT,
DXGI_FORMAT_R16G16_SINT,
DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
}),
f({
DXGI_FORMAT_UNKNOWN,
@@ -80,6 +98,9 @@ DXGI_FORMAT VarToD3D(ComponentFormat t, int size, bool integer)
DXGI_FORMAT_UNKNOWN,
DXGI_FORMAT_UNKNOWN,
DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
}),
f({
DXGI_FORMAT_R8G8B8A8_UINT,
@@ -87,6 +108,9 @@ DXGI_FORMAT VarToD3D(ComponentFormat t, int size, bool integer)
DXGI_FORMAT_R16G16B16A16_UINT,
DXGI_FORMAT_R16G16B16A16_SINT,
DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
+ DXGI_FORMAT_UNKNOWN,
}),
};
diff --git a/Source/Core/VideoBackends/D3D12/DX12VertexFormat.cpp b/Source/Core/VideoBackends/D3D12/DX12VertexFormat.cpp
index 6ba3a8800d..69a1d6a290 100644
--- a/Source/Core/VideoBackends/D3D12/DX12VertexFormat.cpp
+++ b/Source/Core/VideoBackends/D3D12/DX12VertexFormat.cpp
@@ -17,31 +17,45 @@ static DXGI_FORMAT VarToDXGIFormat(ComponentFormat t, u32 components, bool integ
static constexpr auto f = [](ComponentArray a) { return a; }; // Deduction helper
// NOTE: 3-component formats are not valid.
- static constexpr Common::EnumMap<ComponentArray, ComponentFormat::Float> float_type_lookup = {
- f({DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM,
- DXGI_FORMAT_R8G8B8A8_UNORM}), // UByte
- f({DXGI_FORMAT_R8_SNORM, DXGI_FORMAT_R8G8_SNORM, DXGI_FORMAT_R8G8B8A8_SNORM,
- DXGI_FORMAT_R8G8B8A8_SNORM}), // Byte
- f({DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16G16_UNORM, DXGI_FORMAT_R16G16B16A16_UNORM,
- DXGI_FORMAT_R16G16B16A16_UNORM}), // UShort
- f({DXGI_FORMAT_R16_SNORM, DXGI_FORMAT_R16G16_SNORM, DXGI_FORMAT_R16G16B16A16_SNORM,
- DXGI_FORMAT_R16G16B16A16_SNORM}), // Short
- f({DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_R32G32B32_FLOAT,
- DXGI_FORMAT_R32G32B32A32_FLOAT}), // Float
- };
-
- static constexpr Common::EnumMap<ComponentArray, ComponentFormat::Float> integer_type_lookup = {
- f({DXGI_FORMAT_R8_UINT, DXGI_FORMAT_R8G8_UINT, DXGI_FORMAT_R8G8B8A8_UINT,
- DXGI_FORMAT_R8G8B8A8_UINT}), // UByte
- f({DXGI_FORMAT_R8_SINT, DXGI_FORMAT_R8G8_SINT, DXGI_FORMAT_R8G8B8A8_SINT,
- DXGI_FORMAT_R8G8B8A8_SINT}), // Byte
- f({DXGI_FORMAT_R16_UINT, DXGI_FORMAT_R16G16_UINT, DXGI_FORMAT_R16G16B16A16_UINT,
- DXGI_FORMAT_R16G16B16A16_UINT}), // UShort
- f({DXGI_FORMAT_R16_SINT, DXGI_FORMAT_R16G16_SINT, DXGI_FORMAT_R16G16B16A16_SINT,
- DXGI_FORMAT_R16G16B16A16_SINT}), // Short
- f({DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_R32G32B32_FLOAT,
- DXGI_FORMAT_R32G32B32A32_FLOAT}), // Float
- };
+ static constexpr Common::EnumMap<ComponentArray, ComponentFormat::InvalidFloat7>
+ float_type_lookup = {
+ f({DXGI_FORMAT_R8_UNORM, DXGI_FORMAT_R8G8_UNORM, DXGI_FORMAT_R8G8B8A8_UNORM,
+ DXGI_FORMAT_R8G8B8A8_UNORM}), // UByte
+ f({DXGI_FORMAT_R8_SNORM, DXGI_FORMAT_R8G8_SNORM, DXGI_FORMAT_R8G8B8A8_SNORM,
+ DXGI_FORMAT_R8G8B8A8_SNORM}), // Byte
+ f({DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_R16G16_UNORM, DXGI_FORMAT_R16G16B16A16_UNORM,
+ DXGI_FORMAT_R16G16B16A16_UNORM}), // UShort
+ f({DXGI_FORMAT_R16_SNORM, DXGI_FORMAT_R16G16_SNORM, DXGI_FORMAT_R16G16B16A16_SNORM,
+ DXGI_FORMAT_R16G16B16A16_SNORM}), // Short
+ f({DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_R32G32B32_FLOAT,
+ DXGI_FORMAT_R32G32B32A32_FLOAT}), // Float
+ f({DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_R32G32B32_FLOAT,
+ DXGI_FORMAT_R32G32B32A32_FLOAT}), // Invalid
+ f({DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_R32G32B32_FLOAT,
+ DXGI_FORMAT_R32G32B32A32_FLOAT}), // Invalid
+ f({DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_R32G32B32_FLOAT,
+ DXGI_FORMAT_R32G32B32A32_FLOAT}), // Invalid
+ };
+
+ static constexpr Common::EnumMap<ComponentArray, ComponentFormat::InvalidFloat7>
+ integer_type_lookup = {
+ f({DXGI_FORMAT_R8_UINT, DXGI_FORMAT_R8G8_UINT, DXGI_FORMAT_R8G8B8A8_UINT,
+ DXGI_FORMAT_R8G8B8A8_UINT}), // UByte
+ f({DXGI_FORMAT_R8_SINT, DXGI_FORMAT_R8G8_SINT, DXGI_FORMAT_R8G8B8A8_SINT,
+ DXGI_FORMAT_R8G8B8A8_SINT}), // Byte
+ f({DXGI_FORMAT_R16_UINT, DXGI_FORMAT_R16G16_UINT, DXGI_FORMAT_R16G16B16A16_UINT,
+ DXGI_FORMAT_R16G16B16A16_UINT}), // UShort
+ f({DXGI_FORMAT_R16_SINT, DXGI_FORMAT_R16G16_SINT, DXGI_FORMAT_R16G16B16A16_SINT,
+ DXGI_FORMAT_R16G16B16A16_SINT}), // Short
+ f({DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_R32G32B32_FLOAT,
+ DXGI_FORMAT_R32G32B32A32_FLOAT}), // Float
+ f({DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_R32G32B32_FLOAT,
+ DXGI_FORMAT_R32G32B32A32_FLOAT}), // Invalid
+ f({DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_R32G32B32_FLOAT,
+ DXGI_FORMAT_R32G32B32A32_FLOAT}), // Invalid
+ f({DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_R32G32_FLOAT, DXGI_FORMAT_R32G32B32_FLOAT,
+ DXGI_FORMAT_R32G32B32A32_FLOAT}), // Invalid
+ };
ASSERT(components > 0 && components <= 4);
return integer ? integer_type_lookup[t][components - 1] : float_type_lookup[t][components - 1];
diff --git a/Source/Core/VideoBackends/Metal/MTLVertexFormat.mm b/Source/Core/VideoBackends/Metal/MTLVertexFormat.mm
index 5fffad8b57..a73247b4f7 100644
--- a/Source/Core/VideoBackends/Metal/MTLVertexFormat.mm
+++ b/Source/Core/VideoBackends/Metal/MTLVertexFormat.mm
@@ -49,6 +49,9 @@ static MTLVertexFormat ConvertFormat(ComponentFormat format, int count, bool int
default: return MTLVertexFormatInvalid;
}
case ComponentFormat::Float:
+ case ComponentFormat::InvalidFloat5:
+ case ComponentFormat::InvalidFloat6:
+ case ComponentFormat::InvalidFloat7:
switch (count)
{
case 1: return MTLVertexFormatFloat;
@@ -100,6 +103,9 @@ static MTLVertexFormat ConvertFormat(ComponentFormat format, int count, bool int
default: return MTLVertexFormatInvalid;
}
case ComponentFormat::Float:
+ case ComponentFormat::InvalidFloat5:
+ case ComponentFormat::InvalidFloat6:
+ case ComponentFormat::InvalidFloat7:
switch (count)
{
case 1: return MTLVertexFormatFloat;
diff --git a/Source/Core/VideoBackends/OGL/OGLNativeVertexFormat.cpp b/Source/Core/VideoBackends/OGL/OGLNativeVertexFormat.cpp
index f1213fcde5..7e478843b6 100644
--- a/Source/Core/VideoBackends/OGL/OGLNativeVertexFormat.cpp
+++ b/Source/Core/VideoBackends/OGL/OGLNativeVertexFormat.cpp
@@ -26,8 +26,9 @@ OGLGfx::CreateNativeVertexFormat(const PortableVertexDeclaration& vtx_decl)
static inline GLuint VarToGL(ComponentFormat t)
{
- static constexpr Common::EnumMap<GLuint, ComponentFormat::Float> lookup = {
- GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT, GL_FLOAT,
+ static constexpr Common::EnumMap<GLuint, ComponentFormat::InvalidFloat7> lookup = {
+ GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT,
+ GL_FLOAT, GL_FLOAT, GL_FLOAT, GL_FLOAT,
};
return lookup[t];
}
diff --git a/Source/Core/VideoBackends/Software/SWVertexLoader.cpp b/Source/Core/VideoBackends/Software/SWVertexLoader.cpp
index 903b430aff..cfb05d096b 100644
--- a/Source/Core/VideoBackends/Software/SWVertexLoader.cpp
+++ b/Source/Core/VideoBackends/Software/SWVertexLoader.cpp
@@ -149,11 +149,14 @@ static void ReadVertexAttribute(T* dst, DataReader src, const AttributeFormat& f
dst[i_dst] = ReadNormalized<T, s16>(src.Read<s16, swap>());
break;
case ComponentFormat::Float:
+ case ComponentFormat::InvalidFloat5:
+ case ComponentFormat::InvalidFloat6:
+ case ComponentFormat::InvalidFloat7:
dst[i_dst] = ReadNormalized<T, float>(src.Read<float, swap>());
break;
}
- ASSERT_MSG(VIDEO, !format.integer || format.type != ComponentFormat::Float,
+ ASSERT_MSG(VIDEO, !format.integer || (format.type < ComponentFormat::Float),
"only non-float values are allowed to be streamed as integer");
}
for (; i < components; i++)
diff --git a/Source/Core/VideoBackends/Vulkan/VKVertexFormat.cpp b/Source/Core/VideoBackends/Vulkan/VKVertexFormat.cpp
index 65b63b32b9..8fb49f0afd 100644
--- a/Source/Core/VideoBackends/Vulkan/VKVertexFormat.cpp
+++ b/Source/Core/VideoBackends/Vulkan/VKVertexFormat.cpp
@@ -19,31 +19,45 @@ static VkFormat VarToVkFormat(ComponentFormat t, uint32_t components, bool integ
using ComponentArray = std::array<VkFormat, 4>;
static constexpr auto f = [](ComponentArray a) { return a; }; // Deduction helper
- static constexpr Common::EnumMap<ComponentArray, ComponentFormat::Float> float_type_lookup = {
- f({VK_FORMAT_R8_UNORM, VK_FORMAT_R8G8_UNORM, VK_FORMAT_R8G8B8_UNORM,
- VK_FORMAT_R8G8B8A8_UNORM}), // UByte
- f({VK_FORMAT_R8_SNORM, VK_FORMAT_R8G8_SNORM, VK_FORMAT_R8G8B8_SNORM,
- VK_FORMAT_R8G8B8A8_SNORM}), // Byte
- f({VK_FORMAT_R16_UNORM, VK_FORMAT_R16G16_UNORM, VK_FORMAT_R16G16B16_UNORM,
- VK_FORMAT_R16G16B16A16_UNORM}), // UShort
- f({VK_FORMAT_R16_SNORM, VK_FORMAT_R16G16_SNORM, VK_FORMAT_R16G16B16_SNORM,
- VK_FORMAT_R16G16B16A16_SNORM}), // Short
- f({VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32G32_SFLOAT, VK_FORMAT_R32G32B32_SFLOAT,
- VK_FORMAT_R32G32B32A32_SFLOAT}), // Float
- };
-
- static constexpr Common::EnumMap<ComponentArray, ComponentFormat::Float> integer_type_lookup = {
- f({VK_FORMAT_R8_UINT, VK_FORMAT_R8G8_UINT, VK_FORMAT_R8G8B8_UINT,
- VK_FORMAT_R8G8B8A8_UINT}), // UByte
- f({VK_FORMAT_R8_SINT, VK_FORMAT_R8G8_SINT, VK_FORMAT_R8G8B8_SINT,
- VK_FORMAT_R8G8B8A8_SINT}), // Byte
- f({VK_FORMAT_R16_UINT, VK_FORMAT_R16G16_UINT, VK_FORMAT_R16G16B16_UINT,
- VK_FORMAT_R16G16B16A16_UINT}), // UShort
- f({VK_FORMAT_R16_SINT, VK_FORMAT_R16G16_SINT, VK_FORMAT_R16G16B16_SINT,
- VK_FORMAT_R16G16B16A16_SINT}), // Short
- f({VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32G32_SFLOAT, VK_FORMAT_R32G32B32_SFLOAT,
- VK_FORMAT_R32G32B32A32_SFLOAT}), // Float
- };
+ static constexpr Common::EnumMap<ComponentArray, ComponentFormat::InvalidFloat7>
+ float_type_lookup = {
+ f({VK_FORMAT_R8_UNORM, VK_FORMAT_R8G8_UNORM, VK_FORMAT_R8G8B8_UNORM,
+ VK_FORMAT_R8G8B8A8_UNORM}), // UByte
+ f({VK_FORMAT_R8_SNORM, VK_FORMAT_R8G8_SNORM, VK_FORMAT_R8G8B8_SNORM,
+ VK_FORMAT_R8G8B8A8_SNORM}), // Byte
+ f({VK_FORMAT_R16_UNORM, VK_FORMAT_R16G16_UNORM, VK_FORMAT_R16G16B16_UNORM,
+ VK_FORMAT_R16G16B16A16_UNORM}), // UShort
+ f({VK_FORMAT_R16_SNORM, VK_FORMAT_R16G16_SNORM, VK_FORMAT_R16G16B16_SNORM,
+ VK_FORMAT_R16G16B16A16_SNORM}), // Short
+ f({VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32G32_SFLOAT, VK_FORMAT_R32G32B32_SFLOAT,
+ VK_FORMAT_R32G32B32A32_SFLOAT}), // Float
+ f({VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32G32_SFLOAT, VK_FORMAT_R32G32B32_SFLOAT,
+ VK_FORMAT_R32G32B32A32_SFLOAT}), // Invalid
+ f({VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32G32_SFLOAT, VK_FORMAT_R32G32B32_SFLOAT,
+ VK_FORMAT_R32G32B32A32_SFLOAT}), // Invalid
+ f({VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32G32_SFLOAT, VK_FORMAT_R32G32B32_SFLOAT,
+ VK_FORMAT_R32G32B32A32_SFLOAT}), // Invalid
+ };
+
+ static constexpr Common::EnumMap<ComponentArray, ComponentFormat::InvalidFloat7>
+ integer_type_lookup = {
+ f({VK_FORMAT_R8_UINT, VK_FORMAT_R8G8_UINT, VK_FORMAT_R8G8B8_UINT,
+ VK_FORMAT_R8G8B8A8_UINT}), // UByte
+ f({VK_FORMAT_R8_SINT, VK_FORMAT_R8G8_SINT, VK_FORMAT_R8G8B8_SINT,
+ VK_FORMAT_R8G8B8A8_SINT}), // Byte
+ f({VK_FORMAT_R16_UINT, VK_FORMAT_R16G16_UINT, VK_FORMAT_R16G16B16_UINT,
+ VK_FORMAT_R16G16B16A16_UINT}), // UShort
+ f({VK_FORMAT_R16_SINT, VK_FORMAT_R16G16_SINT, VK_FORMAT_R16G16B16_SINT,
+ VK_FORMAT_R16G16B16A16_SINT}), // Short
+ f({VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32G32_SFLOAT, VK_FORMAT_R32G32B32_SFLOAT,
+ VK_FORMAT_R32G32B32A32_SFLOAT}), // Float
+ f({VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32G32_SFLOAT, VK_FORMAT_R32G32B32_SFLOAT,
+ VK_FORMAT_R32G32B32A32_SFLOAT}), // Invalid
+ f({VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32G32_SFLOAT, VK_FORMAT_R32G32B32_SFLOAT,
+ VK_FORMAT_R32G32B32A32_SFLOAT}), // Invalid
+ f({VK_FORMAT_R32_SFLOAT, VK_FORMAT_R32G32_SFLOAT, VK_FORMAT_R32G32B32_SFLOAT,
+ VK_FORMAT_R32G32B32A32_SFLOAT}), // Invalid
+ };
ASSERT(components > 0 && components <= 4);
return integer ? integer_type_lookup[t][components - 1] : float_type_lookup[t][components - 1];
diff --git a/Source/Core/VideoCommon/CPMemory.h b/Source/Core/VideoCommon/CPMemory.h
index 1d55d7bf3c..63e5e2f2c3 100644
--- a/Source/Core/VideoCommon/CPMemory.h
+++ b/Source/Core/VideoCommon/CPMemory.h
@@ -122,7 +122,16 @@ enum class ComponentFormat
UShort = 2, // Invalid for normals
Short = 3,
Float = 4,
-};
+ // Known to be used by Fifa Street and Def Jam: Fight for New York
+ // See https://bugs.dolphin-emu.org/issues/12719
+ // Assumed to behave the same as float, but further testing is needed
+ InvalidFloat5 = 5,
+ // Not known to be used
+ InvalidFloat6 = 6,
+ InvalidFloat7 = 7,
+};
+// NOTE: don't include the invalid formats here, so that EnumFormatter marks them as invalid
+// (EnumFormatter also handles bounds-checking).
template <>
struct fmt::formatter<ComponentFormat> : EnumFormatter<ComponentFormat::Float>
{
@@ -141,6 +150,9 @@ constexpr u32 GetElementSize(ComponentFormat format)
case ComponentFormat::Short:
return 2;
case ComponentFormat::Float:
+ case ComponentFormat::InvalidFloat5:
+ case ComponentFormat::InvalidFloat6:
+ case ComponentFormat::InvalidFloat7:
return 4;
default:
PanicAlertFmt("Unknown format {}", format);
diff --git a/Source/Core/VideoCommon/VertexLoaderARM64.cpp b/Source/Core/VideoCommon/VertexLoaderARM64.cpp
index 2198b0b427..9fd8c0c29c 100644
--- a/Source/Core/VideoCommon/VertexLoaderARM64.cpp
+++ b/Source/Core/VideoCommon/VertexLoaderARM64.cpp
@@ -116,7 +116,7 @@ void VertexLoaderARM64::ReadVertex(VertexComponentFormat attribute, ComponentFor
m_float_emit.LDUR(load_size, coords, reg, offset);
- if (format != ComponentFormat::Float)
+ if (format < ComponentFormat::Float)
{
// Extend and convert to float
switch (format)
@@ -394,8 +394,8 @@ void VertexLoaderARM64::GenerateVertexLoader()
if (m_VtxDesc.low.Normal != VertexComponentFormat::NotPresent)
{
- static constexpr Common::EnumMap<u8, static_cast<ComponentFormat>(7)> SCALE_MAP = {7, 6, 15, 14,
- 0, 0, 0, 0};
+ static constexpr Common::EnumMap<u8, ComponentFormat::InvalidFloat7> SCALE_MAP = {7, 6, 15, 14,
+ 0, 0, 0, 0};
const u8 scaling_exponent = SCALE_MAP[m_VtxAttr.g0.NormalFormat];
// Normal
diff --git a/Source/Core/VideoCommon/VertexLoaderManager.cpp b/Source/Core/VideoCommon/VertexLoaderManager.cpp
index 5da66c273d..8ae9a9aa46 100644
--- a/Source/Core/VideoCommon/VertexLoaderManager.cpp
+++ b/Source/Core/VideoCommon/VertexLoaderManager.cpp
@@ -319,6 +319,51 @@ static void CheckCPConfiguration(int vtx_attr_group)
DolphinAnalytics::Instance().ReportGameQuirk(
GameQuirk::MISMATCHED_GPU_MATRIX_INDICES_BETWEEN_CP_AND_XF);
}
+
+ if (g_main_cp_state.vtx_attr[vtx_attr_group].g0.PosFormat >= ComponentFormat::InvalidFloat5)
+ {
+ WARN_LOG_FMT(VIDEO, "Invalid position format {} for VAT {} - {:08x} {:08x} {:08x}",
+ g_main_cp_state.vtx_attr[vtx_attr_group].g0.PosFormat, vtx_attr_group,
+ g_main_cp_state.vtx_attr[vtx_attr_group].g0.Hex,
+ g_main_cp_state.vtx_attr[vtx_attr_group].g1.Hex,
+ g_main_cp_state.vtx_attr[vtx_attr_group].g2.Hex);
+ DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::INVALID_POSITION_COMPONENT_FORMAT);
+ }
+ if (g_main_cp_state.vtx_attr[vtx_attr_group].g0.NormalFormat >= ComponentFormat::InvalidFloat5)
+ {
+ WARN_LOG_FMT(VIDEO, "Invalid normal format {} for VAT {} - {:08x} {:08x} {:08x}",
+ g_main_cp_state.vtx_attr[vtx_attr_group].g0.NormalFormat, vtx_attr_group,
+ g_main_cp_state.vtx_attr[vtx_attr_group].g0.Hex,
+ g_main_cp_state.vtx_attr[vtx_attr_group].g1.Hex,
+ g_main_cp_state.vtx_attr[vtx_attr_group].g2.Hex);
+ DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::INVALID_NORMAL_COMPONENT_FORMAT);
+ }
+ for (size_t i = 0; i < 8; i++)
+ {
+ if (g_main_cp_state.vtx_attr[vtx_attr_group].GetTexFormat(i) >= ComponentFormat::InvalidFloat5)
+ {
+ WARN_LOG_FMT(VIDEO,
+ "Invalid texture coordinate {} format {} for VAT {} - {:08x} {:08x} {:08x}", i,
+ g_main_cp_state.vtx_attr[vtx_attr_group].GetTexFormat(i), vtx_attr_group,
+ g_main_cp_state.vtx_attr[vtx_attr_group].g0.Hex,
+ g_main_cp_state.vtx_attr[vtx_attr_group].g1.Hex,
+ g_main_cp_state.vtx_attr[vtx_attr_group].g2.Hex);
+ DolphinAnalytics::Instance().ReportGameQuirk(
+ GameQuirk::INVALID_TEXTURE_COORDINATE_COMPONENT_FORMAT);
+ }
+ }
+ for (size_t i = 0; i < 2; i++)
+ {
+ if (g_main_cp_state.vtx_attr[vtx_attr_group].GetColorFormat(i) > ColorFormat::RGBA8888)
+ {
+ WARN_LOG_FMT(VIDEO, "Invalid color {} format {} for VAT {} - {:08x} {:08x} {:08x}", i,
+ g_main_cp_state.vtx_attr[vtx_attr_group].GetColorFormat(i), vtx_attr_group,
+ g_main_cp_state.vtx_attr[vtx_attr_group].g0.Hex,
+ g_main_cp_state.vtx_attr[vtx_attr_group].g1.Hex,
+ g_main_cp_state.vtx_attr[vtx_attr_group].g2.Hex);
+ DolphinAnalytics::Instance().ReportGameQuirk(GameQuirk::INVALID_COLOR_COMPONENT_FORMAT);
+ }
+ }
}
template <bool IsPreprocess>
diff --git a/Source/Core/VideoCommon/VertexLoaderX64.cpp b/Source/Core/VideoCommon/VertexLoaderX64.cpp
index 9aba5a58c8..9934570b55 100644
--- a/Source/Core/VideoCommon/VertexLoaderX64.cpp
+++ b/Source/Core/VideoCommon/VertexLoaderX64.cpp
@@ -83,22 +83,32 @@ void VertexLoaderX64::ReadVertex(OpArg data, VertexComponentFormat attribute,
bool dequantize, u8 scaling_exponent,
AttributeFormat* native_format)
{
- static const __m128i shuffle_lut[5][3] = {
- {_mm_set_epi32(0xFFFFFFFFL, 0xFFFFFFFFL, 0xFFFFFFFFL, 0xFFFFFF00L), // 1x u8
- _mm_set_epi32(0xFFFFFFFFL, 0xFFFFFFFFL, 0xFFFFFF01L, 0xFFFFFF00L), // 2x u8
- _mm_set_epi32(0xFFFFFFFFL, 0xFFFFFF02L, 0xFFFFFF01L, 0xFFFFFF00L)}, // 3x u8
- {_mm_set_epi32(0xFFFFFFFFL, 0xFFFFFFFFL, 0xFFFFFFFFL, 0x00FFFFFFL), // 1x s8
- _mm_set_epi32(0xFFFFFFFFL, 0xFFFFFFFFL, 0x01FFFFFFL, 0x00FFFFFFL), // 2x s8
- _mm_set_epi32(0xFFFFFFFFL, 0x02FFFFFFL, 0x01FFFFFFL, 0x00FFFFFFL)}, // 3x s8
- {_mm_set_epi32(0xFFFFFFFFL, 0xFFFFFFFFL, 0xFFFFFFFFL, 0xFFFF0001L), // 1x u16
- _mm_set_epi32(0xFFFFFFFFL, 0xFFFFFFFFL, 0xFFFF0203L, 0xFFFF0001L), // 2x u16
- _mm_set_epi32(0xFFFFFFFFL, 0xFFFF0405L, 0xFFFF0203L, 0xFFFF0001L)}, // 3x u16
- {_mm_set_epi32(0xFFFFFFFFL, 0xFFFFFFFFL, 0xFFFFFFFFL, 0x0001FFFFL), // 1x s16
- _mm_set_epi32(0xFFFFFFFFL, 0xFFFFFFFFL, 0x0203FFFFL, 0x0001FFFFL), // 2x s16
- _mm_set_epi32(0xFFFFFFFFL, 0x0405FFFFL, 0x0203FFFFL, 0x0001FFFFL)}, // 3x s16
- {_mm_set_epi32(0xFFFFFFFFL, 0xFFFFFFFFL, 0xFFFFFFFFL, 0x00010203L), // 1x float
- _mm_set_epi32(0xFFFFFFFFL, 0xFFFFFFFFL, 0x04050607L, 0x00010203L), // 2x float
- _mm_set_epi32(0xFFFFFFFFL, 0x08090A0BL, 0x04050607L, 0x00010203L)}, // 3x float
+ using ShuffleRow = std::array<__m128i, 3>;
+ static const Common::EnumMap<ShuffleRow, ComponentFormat::InvalidFloat7> shuffle_lut = {
+ ShuffleRow{_mm_set_epi32(0xFFFFFFFFL, 0xFFFFFFFFL, 0xFFFFFFFFL, 0xFFFFFF00L), // 1x u8
+ _mm_set_epi32(0xFFFFFFFFL, 0xFFFFFFFFL, 0xFFFFFF01L, 0xFFFFFF00L), // 2x u8
+ _mm_set_epi32(0xFFFFFFFFL, 0xFFFFFF02L, 0xFFFFFF01L, 0xFFFFFF00L)}, // 3x u8
+ ShuffleRow{_mm_set_epi32(0xFFFFFFFFL, 0xFFFFFFFFL, 0xFFFFFFFFL, 0x00FFFFFFL), // 1x s8
+ _mm_set_epi32(0xFFFFFFFFL, 0xFFFFFFFFL, 0x01FFFFFFL, 0x00FFFFFFL), // 2x s8
+ _mm_set_epi32(0xFFFFFFFFL, 0x02FFFFFFL, 0x01FFFFFFL, 0x00FFFFFFL)}, // 3x s8
+ ShuffleRow{_mm_set_epi32(0xFFFFFFFFL, 0xFFFFFFFFL, 0xFFFFFFFFL, 0xFFFF0001L), // 1x u16
+ _mm_set_epi32(0xFFFFFFFFL, 0xFFFFFFFFL, 0xFFFF0203L, 0xFFFF0001L), // 2x u16
+ _mm_set_epi32(0xFFFFFFFFL, 0xFFFF0405L, 0xFFFF0203L, 0xFFFF0001L)}, // 3x u16
+ ShuffleRow{_mm_set_epi32(0xFFFFFFFFL, 0xFFFFFFFFL, 0xFFFFFFFFL, 0x0001FFFFL), // 1x s16
+ _mm_set_epi32(0xFFFFFFFFL, 0xFFFFFFFFL, 0x0203FFFFL, 0x0001FFFFL), // 2x s16
+ _mm_set_epi32(0xFFFFFFFFL, 0x0405FFFFL, 0x0203FFFFL, 0x0001FFFFL)}, // 3x s16
+ ShuffleRow{_mm_set_epi32(0xFFFFFFFFL, 0xFFFFFFFFL, 0xFFFFFFFFL, 0x00010203L), // 1x float
+ _mm_set_epi32(0xFFFFFFFFL, 0xFFFFFFFFL, 0x04050607L, 0x00010203L), // 2x float
+ _mm_set_epi32(0xFFFFFFFFL, 0x08090A0BL, 0x04050607L, 0x00010203L)}, // 3x float
+ ShuffleRow{_mm_set_epi32(0xFFFFFFFFL, 0xFFFFFFFFL, 0xFFFFFFFFL, 0x00010203L), // 1x invalid
+ _mm_set_epi32(0xFFFFFFFFL, 0xFFFFFFFFL, 0x04050607L, 0x00010203L), // 2x invalid
+ _mm_set_epi32(0xFFFFFFFFL, 0x08090A0BL, 0x04050607L, 0x00010203L)}, // 3x invalid
+ ShuffleRow{_mm_set_epi32(0xFFFFFFFFL, 0xFFFFFFFFL, 0xFFFFFFFFL, 0x00010203L), // 1x invalid
+ _mm_set_epi32(0xFFFFFFFFL, 0xFFFFFFFFL, 0x04050607L, 0x00010203L), // 2x invalid
+ _mm_set_epi32(0xFFFFFFFFL, 0x08090A0BL, 0x04050607L, 0x00010203L)}, // 3x invalid
+ ShuffleRow{_mm_set_epi32(0xFFFFFFFFL, 0xFFFFFFFFL, 0xFFFFFFFFL, 0x00010203L), // 1x invalid
+ _mm_set_epi32(0xFFFFFFFFL, 0xFFFFFFFFL, 0x04050607L, 0x00010203L), // 2x invalid
+ _mm_set_epi32(0xFFFFFFFFL, 0x08090A0BL, 0x04050607L, 0x00010203L)}, // 3x invalid
};
static const __m128 scale_factors[32] = {
_mm_set_ps1(1. / (1u << 0)), _mm_set_ps1(1. / (1u << 1)), _mm_set_ps1(1. / (1u << 2)),
@@ -169,7 +179,7 @@ void VertexLoaderX64::ReadVertex(OpArg data, VertexComponentFormat attribute,
else
MOVD_xmm(coords, data);
- PSHUFB(coords, MPIC(&shuffle_lut[u32(format)][count_in - 1]));
+ PSHUFB(coords, MPIC(&shuffle_lut[format][count_in - 1]));
// Sign-extend.
if (format == ComponentFormat::Byte)
@@ -221,6 +231,9 @@ void VertexLoaderX64::ReadVertex(OpArg data, VertexComponentFormat attribute,
PSRLD(coords, 16);
break;
case ComponentFormat::Float:
+ case ComponentFormat::InvalidFloat5:
+ case ComponentFormat::InvalidFloat6:
+ case ComponentFormat::InvalidFloat7:
// Floats don't need to be scaled or converted,
// so we can just load/swap/store them directly
// and return early.
@@ -254,7 +267,7 @@ void VertexLoaderX64::ReadVertex(OpArg data, VertexComponentFormat attribute,
}
}
- if (format != ComponentFormat::Float)
+ if (format < ComponentFormat::Float)
{
CVTDQ2PS(coords, R(coords));
@@ -458,8 +471,8 @@ void VertexLoaderX64::GenerateVertexLoader()
if (m_VtxDesc.low.Normal != VertexComponentFormat::NotPresent)
{
- static constexpr Common::EnumMap<u8, static_cast<ComponentFormat>(7)> SCALE_MAP = {7, 6, 15, 14,
- 0, 0, 0, 0};
+ static constexpr Common::EnumMap<u8, ComponentFormat::InvalidFloat7> SCALE_MAP = {7, 6, 15, 14,
+ 0, 0, 0, 0};
const u8 scaling_exponent = SCALE_MAP[m_VtxAttr.g0.NormalFormat];
// Normal
diff --git a/Source/Core/VideoCommon/VertexLoader_Normal.cpp b/Source/Core/VideoCommon/VertexLoader_Normal.cpp
index abb6d27da7..b91c7fe127 100644
--- a/Source/Core/VideoCommon/VertexLoader_Normal.cpp
+++ b/Source/Core/VideoCommon/VertexLoader_Normal.cpp
@@ -95,7 +95,7 @@ void Normal_ReadIndex_Indices3(VertexLoader* loader)
}
using Common::EnumMap;
-using Formats = EnumMap<TPipelineFunction, ComponentFormat::Float>;
+using Formats = EnumMap<TPipelineFunction, ComponentFormat::InvalidFloat7>;
using Elements = EnumMap<Formats, NormalComponentCount::NTB>;
using Indices = std::array<Elements, 2>;
using Types = EnumMap<Indices, VertexComponentFormat::Index16>;
@@ -113,11 +113,17 @@ consteval Types InitializeTable()
table[VCF::Direct][false][NCC::N][FMT::UShort] = Normal_ReadDirect<u16, 1>;
table[VCF::Direct][false][NCC::N][FMT::Short] = Normal_ReadDirect<s16, 1>;
table[VCF::Direct][false][NCC::N][FMT::Float] = Normal_ReadDirect<float, 1>;
+ table[VCF::Direct][false][NCC::N][FMT::InvalidFloat5] = Normal_ReadDirect<float, 1>;
+ table[VCF::Direct][false][NCC::N][FMT::InvalidFloat6] = Normal_ReadDirect<float, 1>;
+ table[VCF::Direct][false][NCC::N][FMT::InvalidFloat7] = Normal_ReadDirect<float, 1>;
table[VCF::Direct][false][NCC::NTB][FMT::UByte] = Normal_ReadDirect<u8, 3>;
table[VCF::Direct][false][NCC::NTB][FMT::Byte] = Normal_ReadDirect<s8, 3>;
table[VCF::Direct][false][NCC::NTB][FMT::UShort] = Normal_ReadDirect<u16, 3>;
table[VCF::Direct][false][NCC::NTB][FMT::Short] = Normal_ReadDirect<s16, 3>;
table[VCF::Direct][false][NCC::NTB][FMT::Float] = Normal_ReadDirect<float, 3>;
+ table[VCF::Direct][false][NCC::NTB][FMT::InvalidFloat5] = Normal_ReadDirect<float, 3>;
+ table[VCF::Direct][false][NCC::NTB][FMT::InvalidFloat6] = Normal_ReadDirect<float, 3>;
+ table[VCF::Direct][false][NCC::NTB][FMT::InvalidFloat7] = Normal_ReadDirect<float, 3>;
// Same as above, since there are no indices
table[VCF::Direct][true][NCC::N][FMT::UByte] = Normal_ReadDirect<u8, 1>;
@@ -125,22 +131,34 @@ consteval Types InitializeTable()
table[VCF::Direct][true][NCC::N][FMT::UShort] = Normal_ReadDirect<u16, 1>;
table[VCF::Direct][true][NCC::N][FMT::Short] = Normal_ReadDirect<s16, 1>;
table[VCF::Direct][true][NCC::N][FMT::Float] = Normal_ReadDirect<float, 1>;
+ table[VCF::Direct][true][NCC::N][FMT::InvalidFloat5] = Normal_ReadDirect<float, 1>;
+ table[VCF::Direct][true][NCC::N][FMT::InvalidFloat6] = Normal_ReadDirect<float, 1>;
+ table[VCF::Direct][true][NCC::N][FMT::InvalidFloat7] = Normal_ReadDirect<float, 1>;
table[VCF::Direct][true][NCC::NTB][FMT::UByte] = Normal_ReadDirect<u8, 3>;
table[VCF::Direct][true][NCC::NTB][FMT::Byte] = Normal_ReadDirect<s8, 3>;
table[VCF::Direct][true][NCC::NTB][FMT::UShort] = Normal_ReadDirect<u16, 3>;
table[VCF::Direct][true][NCC::NTB][FMT::Short] = Normal_ReadDirect<s16, 3>;
table[VCF::Direct][true][NCC::NTB][FMT::Float] = Normal_ReadDirect<float, 3>;
+ table[VCF::Direct][true][NCC::NTB][FMT::InvalidFloat5] = Normal_ReadDirect<float, 3>;
+ table[VCF::Direct][true][NCC::NTB][FMT::InvalidFloat6] = Normal_ReadDirect<float, 3>;
+ table[VCF::Direct][true][NCC::NTB][FMT::InvalidFloat7] = Normal_ReadDirect<float, 3>;
table[VCF::Index8][false][NCC::N][FMT::UByte] = Normal_ReadIndex<u8, u8, 1>;
table[VCF::Index8][false][NCC::N][FMT::Byte] = Normal_ReadIndex<u8, s8, 1>;
table[VCF::Index8][false][NCC::N][FMT::UShort] = Normal_ReadIndex<u8, u16, 1>;
table[VCF::Index8][false][NCC::N][FMT::Short] = Normal_ReadIndex<u8, s16, 1>;
table[VCF::Index8][false][NCC::N][FMT::Float] = Normal_ReadIndex<u8, float, 1>;
+ table[VCF::Index8][false][NCC::N][FMT::InvalidFloat5] = Normal_ReadIndex<u8, float, 1>;
+ table[VCF::Index8][false][NCC::N][FMT::InvalidFloat6] = Normal_ReadIndex<u8, float, 1>;
+ table[VCF::Index8][false][NCC::N][FMT::InvalidFloat7] = Normal_ReadIndex<u8, float, 1>;
table[VCF::Index8][false][NCC::NTB][FMT::UByte] = Normal_ReadIndex<u8, u8, 3>;
table[VCF::Index8][false][NCC::NTB][FMT::Byte] = Normal_ReadIndex<u8, s8, 3>;
table[VCF::Index8][false][NCC::NTB][FMT::UShort] = Normal_ReadIndex<u8, u16, 3>;
table[VCF::Index8][false][NCC::NTB][FMT::Short] = Normal_ReadIndex<u8, s16, 3>;
table[VCF::Index8][false][NCC::NTB][FMT::Float] = Normal_ReadIndex<u8, float, 3>;
+ table[VCF::Index8][false][NCC::NTB][FMT::InvalidFloat5] = Normal_ReadIndex<u8, float, 3>;
+ table[VCF::Index8][false][NCC::NTB][FMT::InvalidFloat6] = Normal_ReadIndex<u8, float, 3>;
+ table[VCF::Index8][false][NCC::NTB][FMT::InvalidFloat7] = Normal_ReadIndex<u8, float, 3>;
// Same for NormalComponentCount::N; differs for NTB
table[VCF::Index8][true][NCC::N][FMT::UByte] = Normal_ReadIndex<u8, u8, 1>;
@@ -148,22 +166,34 @@ consteval Types InitializeTable()
table[VCF::Index8][true][NCC::N][FMT::UShort] = Normal_ReadIndex<u8, u16, 1>;
table[VCF::Index8][true][NCC::N][FMT::Short] = Normal_ReadIndex<u8, s16, 1>;
table[VCF::Index8][true][NCC::N][FMT::Float] = Normal_ReadIndex<u8, float, 1>;
+ table[VCF::Index8][true][NCC::N][FMT::InvalidFloat5] = Normal_ReadIndex<u8, float, 1>;
+ table[VCF::Index8][true][NCC::N][FMT::InvalidFloat6] = Normal_ReadIndex<u8, float, 1>;
+ table[VCF::Index8][true][NCC::N][FMT::InvalidFloat7] = Normal_ReadIndex<u8, float, 1>;
table[VCF::Index8][true][NCC::NTB][FMT::UByte] = Normal_ReadIndex_Indices3<u8, u8>;
table[VCF::Index8][true][NCC::NTB][FMT::Byte] = Normal_ReadIndex_Indices3<u8, s8>;
table[VCF::Index8][true][NCC::NTB][FMT::UShort] = Normal_ReadIndex_Indices3<u8, u16>;
table[VCF::Index8][true][NCC::NTB][FMT::Short] = Normal_ReadIndex_Indices3<u8, s16>;
table[VCF::Index8][true][NCC::NTB][FMT::Float] = Normal_ReadIndex_Indices3<u8, float>;
+ table[VCF::Index8][true][NCC::NTB][FMT::InvalidFloat5] = Normal_ReadIndex_Indices3<u8, float>;
+ table[VCF::Index8][true][NCC::NTB][FMT::InvalidFloat6] = Normal_ReadIndex_Indices3<u8, float>;
+ table[VCF::Index8][true][NCC::NTB][FMT::InvalidFloat7] = Normal_ReadIndex_Indices3<u8, float>;
table[VCF::Index16][false][NCC::N][FMT::UByte] = Normal_ReadIndex<u16, u8, 1>;
table[VCF::Index16][false][NCC::N][FMT::Byte] = Normal_ReadIndex<u16, s8, 1>;
table[VCF::Index16][false][NCC::N][FMT::UShort] = Normal_ReadIndex<u16, u16, 1>;
table[VCF::Index16][false][NCC::N][FMT::Short] = Normal_ReadIndex<u16, s16, 1>;
table[VCF::Index16][false][NCC::N][FMT::Float] = Normal_ReadIndex<u16, float, 1>;
+ table[VCF::Index16][false][NCC::N][FMT::InvalidFloat5] = Normal_ReadIndex<u16, float, 1>;
+ table[VCF::Index16][false][NCC::N][FMT::InvalidFloat6] = Normal_ReadIndex<u16, float, 1>;
+ table[VCF::Index16][false][NCC::N][FMT::InvalidFloat7] = Normal_ReadIndex<u16, float, 1>;
table[VCF::Index16][false][NCC::NTB][FMT::UByte] = Normal_ReadIndex<u16, u8, 3>;
table[VCF::Index16][false][NCC::NTB][FMT::Byte] = Normal_ReadIndex<u16, s8, 3>;
table[VCF::Index16][false][NCC::NTB][FMT::UShort] = Normal_ReadIndex<u16, u16, 3>;
table[VCF::Index16][false][NCC::NTB][FMT::Short] = Normal_ReadIndex<u16, s16, 3>;
table[VCF::Index16][false][NCC::NTB][FMT::Float] = Normal_ReadIndex<u16, float, 3>;
+ table[VCF::Index16][false][NCC::NTB][FMT::InvalidFloat5] = Normal_ReadIndex<u16, float, 3>;
+ table[VCF::Index16][false][NCC::NTB][FMT::InvalidFloat6] = Normal_ReadIndex<u16, float, 3>;
+ table[VCF::Index16][false][NCC::NTB][FMT::InvalidFloat7] = Normal_ReadIndex<u16, float, 3>;
// Same for NormalComponentCount::N; differs for NTB
table[VCF::Index16][true][NCC::N][FMT::UByte] = Normal_ReadIndex<u16, u8, 1>;
@@ -171,11 +201,17 @@ consteval Types InitializeTable()
table[VCF::Index16][true][NCC::N][FMT::UShort] = Normal_ReadIndex<u16, u16, 1>;
table[VCF::Index16][true][NCC::N][FMT::Short] = Normal_ReadIndex<u16, s16, 1>;
table[VCF::Index16][true][NCC::N][FMT::Float] = Normal_ReadIndex<u16, float, 1>;
+ table[VCF::Index16][true][NCC::N][FMT::InvalidFloat5] = Normal_ReadIndex<u16, float, 1>;
+ table[VCF::Index16][true][NCC::N][FMT::InvalidFloat6] = Normal_ReadIndex<u16, float, 1>;
+ table[VCF::Index16][true][NCC::N][FMT::InvalidFloat7] = Normal_ReadIndex<u16, float, 1>;
table[VCF::Index16][true][NCC::NTB][FMT::UByte] = Normal_ReadIndex_Indices3<u16, u8>;
table[VCF::Index16][true][NCC::NTB][FMT::Byte] = Normal_ReadIndex_Indices3<u16, s8>;
table[VCF::Index16][true][NCC::NTB][FMT::UShort] = Normal_ReadIndex_Indices3<u16, u16>;
table[VCF::Index16][true][NCC::NTB][FMT::Short] = Normal_ReadIndex_Indices3<u16, s16>;
table[VCF::Index16][true][NCC::NTB][FMT::Float] = Normal_ReadIndex_Indices3<u16, float>;
+ table[VCF::Index16][true][NCC::NTB][FMT::InvalidFloat5] = Normal_ReadIndex_Indices3<u16, float>;
+ table[VCF::Index16][true][NCC::NTB][FMT::InvalidFloat6] = Normal_ReadIndex_Indices3<u16, float>;
+ table[VCF::Index16][true][NCC::NTB][FMT::InvalidFloat7] = Normal_ReadIndex_Indices3<u16, float>;
return table;
}
diff --git a/Source/Core/VideoCommon/VertexLoader_Normal.h b/Source/Core/VideoCommon/VertexLoader_Normal.h
index b5200dc875..0b8c107765 100644
--- a/Source/Core/VideoCommon/VertexLoader_Normal.h
+++ b/Source/Core/VideoCommon/VertexLoader_Normal.h
@@ -27,7 +27,8 @@ private:
using EnumMap = typename Common::EnumMap<T, last_member>;
using SizeTable = EnumMap<
- std::array<EnumMap<EnumMap<u32, ComponentFormat::Float>, NormalComponentCount::NTB>, 2>,
+ std::array<EnumMap<EnumMap<u32, ComponentFormat::InvalidFloat7>, NormalComponentCount::NTB>,
+ 2>,
VertexComponentFormat::Index16>;
static constexpr SizeTable s_table_size = []() consteval
@@ -43,11 +44,17 @@ private:
table[VCF::Direct][false][NCC::N][FMT::UShort] = 6;
table[VCF::Direct][false][NCC::N][FMT::Short] = 6;
table[VCF::Direct][false][NCC::N][FMT::Float] = 12;
+ table[VCF::Direct][false][NCC::N][FMT::InvalidFloat5] = 12;
+ table[VCF::Direct][false][NCC::N][FMT::InvalidFloat6] = 12;
+ table[VCF::Direct][false][NCC::N][FMT::InvalidFloat7] = 12;
table[VCF::Direct][false][NCC::NTB][FMT::UByte] = 9;
table[VCF::Direct][false][NCC::NTB][FMT::Byte] = 9;
table[VCF::Direct][false][NCC::NTB][FMT::UShort] = 18;
table[VCF::Direct][false][NCC::NTB][FMT::Short] = 18;
table[VCF::Direct][false][NCC::NTB][FMT::Float] = 36;
+ table[VCF::Direct][false][NCC::NTB][FMT::InvalidFloat5] = 36;
+ table[VCF::Direct][false][NCC::NTB][FMT::InvalidFloat6] = 36;
+ table[VCF::Direct][false][NCC::NTB][FMT::InvalidFloat7] = 36;
// Same as above, since there are no indices
table[VCF::Direct][true][NCC::N][FMT::UByte] = 3;
@@ -55,22 +62,34 @@ private:
table[VCF::Direct][true][NCC::N][FMT::UShort] = 6;
table[VCF::Direct][true][NCC::N][FMT::Short] = 6;
table[VCF::Direct][true][NCC::N][FMT::Float] = 12;
+ table[VCF::Direct][true][NCC::N][FMT::InvalidFloat5] = 12;
+ table[VCF::Direct][true][NCC::N][FMT::InvalidFloat6] = 12;
+ table[VCF::Direct][true][NCC::N][FMT::InvalidFloat7] = 12;
table[VCF::Direct][true][NCC::NTB][FMT::UByte] = 9;
table[VCF::Direct][true][NCC::NTB][FMT::Byte] = 9;
table[VCF::Direct][true][NCC::NTB][FMT::UShort] = 18;
table[VCF::Direct][true][NCC::NTB][FMT::Short] = 18;
table[VCF::Direct][true][NCC::NTB][FMT::Float] = 36;
+ table[VCF::Direct][true][NCC::NTB][FMT::InvalidFloat5] = 36;
+ table[VCF::Direct][true][NCC::NTB][FMT::InvalidFloat6] = 36;
+ table[VCF::Direct][true][NCC::NTB][FMT::InvalidFloat7] = 36;
table[VCF::Index8][false][NCC::N][FMT::UByte] = 1;
table[VCF::Index8][false][NCC::N][FMT::Byte] = 1;
table[VCF::Index8][false][NCC::N][FMT::UShort] = 1;
table[VCF::Index8][false][NCC::N][FMT::Short] = 1;
table[VCF::Index8][false][NCC::N][FMT::Float] = 1;
+ table[VCF::Index8][false][NCC::N][FMT::InvalidFloat5] = 1;
+ table[VCF::Index8][false][NCC::N][FMT::InvalidFloat6] = 1;
+ table[VCF::Index8][false][NCC::N][FMT::InvalidFloat7] = 1;
table[VCF::Index8][false][NCC::NTB][FMT::UByte] = 1;
table[VCF::Index8][false][NCC::NTB][FMT::Byte] = 1;
table[VCF::Index8][false][NCC::NTB][FMT::UShort] = 1;
table[VCF::Index8][false][NCC::NTB][FMT::Short] = 1;
table[VCF::Index8][false][NCC::NTB][FMT::Float] = 1;
+ table[VCF::Index8][false][NCC::NTB][FMT::InvalidFloat5] = 1;
+ table[VCF::Index8][false][NCC::NTB][FMT::InvalidFloat6] = 1;
+ table[VCF::Index8][false][NCC::NTB][FMT::InvalidFloat7] = 1;
// Same for NormalComponentCount::N; differs for NTB
table[VCF::Index8][true][NCC::N][FMT::UByte] = 1;
@@ -78,22 +97,34 @@ private:
table[VCF::Index8][true][NCC::N][FMT::UShort] = 1;
table[VCF::Index8][true][NCC::N][FMT::Short] = 1;
table[VCF::Index8][true][NCC::N][FMT::Float] = 1;
+ table[VCF::Index8][true][NCC::N][FMT::InvalidFloat5] = 1;
+ table[VCF::Index8][true][NCC::N][FMT::InvalidFloat6] = 1;
+ table[VCF::Index8][true][NCC::N][FMT::InvalidFloat7] = 1;
table[VCF::Index8][true][NCC::NTB][FMT::UByte] = 3;
table[VCF::Index8][true][NCC::NTB][FMT::Byte] = 3;
table[VCF::Index8][true][NCC::NTB][FMT::UShort] = 3;
table[VCF::Index8][true][NCC::NTB][FMT::Short] = 3;
table[VCF::Index8][true][NCC::NTB][FMT::Float] = 3;
+ table[VCF::Index8][true][NCC::NTB][FMT::InvalidFloat5] = 3;
+ table[VCF::Index8][true][NCC::NTB][FMT::InvalidFloat6] = 3;
+ table[VCF::Index8][true][NCC::NTB][FMT::InvalidFloat7] = 3;
table[VCF::Index16][false][NCC::N][FMT::UByte] = 2;
table[VCF::Index16][false][NCC::N][FMT::Byte] = 2;
table[VCF::Index16][false][NCC::N][FMT::UShort] = 2;
table[VCF::Index16][false][NCC::N][FMT::Short] = 2;
table[VCF::Index16][false][NCC::N][FMT::Float] = 2;
+ table[VCF::Index16][false][NCC::N][FMT::InvalidFloat5] = 2;
+ table[VCF::Index16][false][NCC::N][FMT::InvalidFloat6] = 2;
+ table[VCF::Index16][false][NCC::N][FMT::InvalidFloat7] = 2;
table[VCF::Index16][false][NCC::NTB][FMT::UByte] = 2;
table[VCF::Index16][false][NCC::NTB][FMT::Byte] = 2;
table[VCF::Index16][false][NCC::NTB][FMT::UShort] = 2;
table[VCF::Index16][false][NCC::NTB][FMT::Short] = 2;
table[VCF::Index16][false][NCC::NTB][FMT::Float] = 2;
+ table[VCF::Index16][false][NCC::NTB][FMT::InvalidFloat5] = 2;
+ table[VCF::Index16][false][NCC::NTB][FMT::InvalidFloat6] = 2;
+ table[VCF::Index16][false][NCC::NTB][FMT::InvalidFloat7] = 2;
// Same for NormalComponentCount::N; differs for NTB
table[VCF::Index16][true][NCC::N][FMT::UByte] = 2;
@@ -101,11 +132,17 @@ private:
table[VCF::Index16][true][NCC::N][FMT::UShort] = 2;
table[VCF::Index16][true][NCC::N][FMT::Short] = 2;
table[VCF::Index16][true][NCC::N][FMT::Float] = 2;
+ table[VCF::Index16][true][NCC::N][FMT::InvalidFloat5] = 2;
+ table[VCF::Index16][true][NCC::N][FMT::InvalidFloat6] = 2;
+ table[VCF::Index16][true][NCC::N][FMT::InvalidFloat7] = 2;
table[VCF::Index16][true][NCC::NTB][FMT::UByte] = 6;
table[VCF::Index16][true][NCC::NTB][FMT::Byte] = 6;
table[VCF::Index16][true][NCC::NTB][FMT::UShort] = 6;
table[VCF::Index16][true][NCC::NTB][FMT::Short] = 6;
table[VCF::Index16][true][NCC::NTB][FMT::Float] = 6;
+ table[VCF::Index16][true][NCC::NTB][FMT::InvalidFloat5] = 6;
+ table[VCF::Index16][true][NCC::NTB][FMT::InvalidFloat6] = 6;
+ table[VCF::Index16][true][NCC::NTB][FMT::InvalidFloat7] = 6;
return table;
}
diff --git a/Source/Core/VideoCommon/VertexLoader_Position.cpp b/Source/Core/VideoCommon/VertexLoader_Position.cpp
index 946dacdde1..27ea61ea30 100644
--- a/Source/Core/VideoCommon/VertexLoader_Position.cpp
+++ b/Source/Core/VideoCommon/VertexLoader_Position.cpp
@@ -71,7 +71,7 @@ void Pos_ReadIndex(VertexLoader* loader)
}
using ComponentCountRow = Common::EnumMap<TPipelineFunction, CoordComponentCount::XYZ>;
-using ComponentFormatTable = Common::EnumMap<ComponentCountRow, ComponentFormat::Float>;
+using ComponentFormatTable = Common::EnumMap<ComponentCountRow, ComponentFormat::InvalidFloat7>;
using Table = Common::EnumMap<ComponentFormatTable, VertexComponentFormat::Index16>;
constexpr Table s_table_read_position = {
@@ -81,6 +81,9 @@ constexpr Table s_table_read_position = {
ComponentCountRow(nullptr, nullptr),
ComponentCountRow(nullptr, nullptr),
ComponentCountRow(nullptr, nullptr),
+ ComponentCountRow(nullptr, nullptr),
+ ComponentCountRow(nullptr, nullptr),
+ ComponentCountRow(nullptr, nullptr),
}),
ComponentFormatTable({
ComponentCountRow(Pos_ReadDirect<u8, 2>, Pos_ReadDirect<u8, 3>),
@@ -88,6 +91,9 @@ constexpr Table s_table_read_position = {
ComponentCountRow(Pos_ReadDirect<u16, 2>, Pos_ReadDirect<u16, 3>),
ComponentCountRow(Pos_ReadDirect<s16, 2>, Pos_ReadDirect<s16, 3>),
ComponentCountRow(Pos_ReadDirect<float, 2>, Pos_ReadDirect<float, 3>),
+ ComponentCountRow(Pos_ReadDirect<float, 2>, Pos_ReadDirect<float, 3>),
+ ComponentCountRow(Pos_ReadDirect<float, 2>, Pos_ReadDirect<float, 3>),
+ ComponentCountRow(Pos_ReadDirect<float, 2>, Pos_ReadDirect<float, 3>),
}),
ComponentFormatTable({
ComponentCountRow(Pos_ReadIndex<u8, u8, 2>, Pos_ReadIndex<u8, u8, 3>),
@@ -95,6 +101,9 @@ constexpr Table s_table_read_position = {
ComponentCountRow(Pos_ReadIndex<u8, u16, 2>, Pos_ReadIndex<u8, u16, 3>),
ComponentCountRow(Pos_ReadIndex<u8, s16, 2>, Pos_ReadIndex<u8, s16, 3>),
ComponentCountRow(Pos_ReadIndex<u8, float, 2>, Pos_ReadIndex<u8, float, 3>),
+ ComponentCountRow(Pos_ReadIndex<u8, float, 2>, Pos_ReadIndex<u8, float, 3>),
+ ComponentCountRow(Pos_ReadIndex<u8, float, 2>, Pos_ReadIndex<u8, float, 3>),
+ ComponentCountRow(Pos_ReadIndex<u8, float, 2>, Pos_ReadIndex<u8, float, 3>),
}),
ComponentFormatTable({
ComponentCountRow(Pos_ReadIndex<u16, u8, 2>, Pos_ReadIndex<u16, u8, 3>),
@@ -102,6 +111,9 @@ constexpr Table s_table_read_position = {
ComponentCountRow(Pos_ReadIndex<u16, u16, 2>, Pos_ReadIndex<u16, u16, 3>),
ComponentCountRow(Pos_ReadIndex<u16, s16, 2>, Pos_ReadIndex<u16, s16, 3>),
ComponentCountRow(Pos_ReadIndex<u16, float, 2>, Pos_ReadIndex<u16, float, 3>),
+ ComponentCountRow(Pos_ReadIndex<u16, float, 2>, Pos_ReadIndex<u16, float, 3>),
+ ComponentCountRow(Pos_ReadIndex<u16, float, 2>, Pos_ReadIndex<u16, float, 3>),
+ ComponentCountRow(Pos_ReadIndex<u16, float, 2>, Pos_ReadIndex<u16, float, 3>),
}),
};
} // Anonymous namespace
diff --git a/Source/Core/VideoCommon/VertexLoader_Position.h b/Source/Core/VideoCommon/VertexLoader_Position.h
index da095419fd..710e5eee6a 100644
--- a/Source/Core/VideoCommon/VertexLoader_Position.h
+++ b/Source/Core/VideoCommon/VertexLoader_Position.h
@@ -26,8 +26,9 @@ private:
template <typename T, auto last_member>
using EnumMap = typename Common::EnumMap<T, last_member>;
- using SizeTable = EnumMap<EnumMap<EnumMap<u32, CoordComponentCount::XYZ>, ComponentFormat::Float>,
- VertexComponentFormat::Index16>;
+ using SizeTable =
+ EnumMap<EnumMap<EnumMap<u32, CoordComponentCount::XYZ>, ComponentFormat::InvalidFloat7>,
+ VertexComponentFormat::Index16>;
static constexpr SizeTable s_table_size = []() consteval
{
@@ -41,18 +42,27 @@ private:
table[VCF::Direct][FMT::UShort] = {4, 6};
table[VCF::Direct][FMT::Short] = {4, 6};
table[VCF::Direct][FMT::Float] = {8, 12};
+ table[VCF::Direct][FMT::InvalidFloat5] = {8, 12};
+ table[VCF::Direct][FMT::InvalidFloat6] = {8, 12};
+ table[VCF::Direct][FMT::InvalidFloat7] = {8, 12};
table[VCF::Index8][FMT::UByte] = {1, 1};
table[VCF::Index8][FMT::Byte] = {1, 1};
table[VCF::Index8][FMT::UShort] = {1, 1};
table[VCF::Index8][FMT::Short] = {1, 1};
table[VCF::Index8][FMT::Float] = {1, 1};
+ table[VCF::Index8][FMT::InvalidFloat5] = {1, 1};
+ table[VCF::Index8][FMT::InvalidFloat6] = {1, 1};
+ table[VCF::Index8][FMT::InvalidFloat7] = {1, 1};
table[VCF::Index16][FMT::UByte] = {2, 2};
table[VCF::Index16][FMT::Byte] = {2, 2};
table[VCF::Index16][FMT::UShort] = {2, 2};
table[VCF::Index16][FMT::Short] = {2, 2};
table[VCF::Index16][FMT::Float] = {2, 2};
+ table[VCF::Index16][FMT::InvalidFloat5] = {2, 2};
+ table[VCF::Index16][FMT::InvalidFloat6] = {2, 2};
+ table[VCF::Index16][FMT::InvalidFloat7] = {2, 2};
return table;
}
diff --git a/Source/Core/VideoCommon/VertexLoader_TextCoord.cpp b/Source/Core/VideoCommon/VertexLoader_TextCoord.cpp
index fcb2982e6f..2d2766a7ea 100644
--- a/Source/Core/VideoCommon/VertexLoader_TextCoord.cpp
+++ b/Source/Core/VideoCommon/VertexLoader_TextCoord.cpp
@@ -60,7 +60,7 @@ void TexCoord_ReadIndex(VertexLoader* loader)
}
using ComponentCountRow = Common::EnumMap<TPipelineFunction, TexComponentCount::ST>;
-using ComponentFormatTable = Common::EnumMap<ComponentCountRow, ComponentFormat::Float>;
+using ComponentFormatTable = Common::EnumMap<ComponentCountRow, ComponentFormat::InvalidFloat7>;
using Table = Common::EnumMap<ComponentFormatTable, VertexComponentFormat::Index16>;
constexpr Table s_table_read_tex_coord = {
@@ -70,6 +70,9 @@ constexpr Table s_table_read_tex_coord = {
ComponentCountRow(nullptr, nullptr),
ComponentCountRow(nullptr, nullptr),
ComponentCountRow(nullptr, nullptr),
+ ComponentCountRow(nullptr, nullptr),
+ ComponentCountRow(nullptr, nullptr),
+ ComponentCountRow(nullptr, nullptr),
}),
ComponentFormatTable({
ComponentCountRow(TexCoord_ReadDirect<u8, 1>, TexCoord_ReadDirect<u8, 2>),
@@ -77,6 +80,9 @@ constexpr Table s_table_read_tex_coord = {
ComponentCountRow(TexCoord_ReadDirect<u16, 1>, TexCoord_ReadDirect<u16, 2>),
ComponentCountRow(TexCoord_ReadDirect<s16, 1>, TexCoord_ReadDirect<s16, 2>),
ComponentCountRow(TexCoord_ReadDirect<float, 1>, TexCoord_ReadDirect<float, 2>),
+ ComponentCountRow(TexCoord_ReadDirect<float, 1>, TexCoord_ReadDirect<float, 2>),
+ ComponentCountRow(TexCoord_ReadDirect<float, 1>, TexCoord_ReadDirect<float, 2>),
+ ComponentCountRow(TexCoord_ReadDirect<float, 1>, TexCoord_ReadDirect<float, 2>),
}),
ComponentFormatTable({
ComponentCountRow(TexCoord_ReadIndex<u8, u8, 1>, TexCoord_ReadIndex<u8, u8, 2>),
@@ -84,6 +90,9 @@ constexpr Table s_table_read_tex_coord = {
ComponentCountRow(TexCoord_ReadIndex<u8, u16, 1>, TexCoord_ReadIndex<u8, u16, 2>),
ComponentCountRow(TexCoord_ReadIndex<u8, s16, 1>, TexCoord_ReadIndex<u8, s16, 2>),
ComponentCountRow(TexCoord_ReadIndex<u8, float, 1>, TexCoord_ReadIndex<u8, float, 2>),
+ ComponentCountRow(TexCoord_ReadIndex<u8, float, 1>, TexCoord_ReadIndex<u8, float, 2>),
+ ComponentCountRow(TexCoord_ReadIndex<u8, float, 1>, TexCoord_ReadIndex<u8, float, 2>),
+ ComponentCountRow(TexCoord_ReadIndex<u8, float, 1>, TexCoord_ReadIndex<u8, float, 2>),
}),
ComponentFormatTable({
ComponentCountRow(TexCoord_ReadIndex<u16, u8, 1>, TexCoord_ReadIndex<u16, u8, 2>),
@@ -91,6 +100,9 @@ constexpr Table s_table_read_tex_coord = {
ComponentCountRow(TexCoord_ReadIndex<u16, u16, 1>, TexCoord_ReadIndex<u16, u16, 2>),
ComponentCountRow(TexCoord_ReadIndex<u16, s16, 1>, TexCoord_ReadIndex<u16, s16, 2>),
ComponentCountRow(TexCoord_ReadIndex<u16, float, 1>, TexCoord_ReadIndex<u16, float, 2>),
+ ComponentCountRow(TexCoord_ReadIndex<u16, float, 1>, TexCoord_ReadIndex<u16, float, 2>),
+ ComponentCountRow(TexCoord_ReadIndex<u16, float, 1>, TexCoord_ReadIndex<u16, float, 2>),
+ ComponentCountRow(TexCoord_ReadIndex<u16, float, 1>, TexCoord_ReadIndex<u16, float, 2>),
}),
};
} // Anonymous namespace
diff --git a/Source/Core/VideoCommon/VertexLoader_TextCoord.h b/Source/Core/VideoCommon/VertexLoader_TextCoord.h
index c71688e1e2..5593571f07 100644
--- a/Source/Core/VideoCommon/VertexLoader_TextCoord.h
+++ b/Source/Core/VideoCommon/VertexLoader_TextCoord.h
@@ -29,8 +29,9 @@ private:
template <typename T, auto last_member>
using EnumMap = typename Common::EnumMap<T, last_member>;
- using SizeTable = EnumMap<EnumMap<EnumMap<u32, TexComponentCount::ST>, ComponentFormat::Float>,
- VertexComponentFormat::Index16>;
+ using SizeTable =
+ EnumMap<EnumMap<EnumMap<u32, TexComponentCount::ST>, ComponentFormat::InvalidFloat7>,
+ VertexComponentFormat::Index16>;
static constexpr SizeTable s_table_size = []() consteval
{
@@ -44,18 +45,27 @@ private:
table[VCF::Direct][FMT::UShort] = {2, 4};
table[VCF::Direct][FMT::Short] = {2, 4};
table[VCF::Direct][FMT::Float] = {4, 8};
+ table[VCF::Direct][FMT::InvalidFloat5] = {4, 8};
+ table[VCF::Direct][FMT::InvalidFloat6] = {4, 8};
+ table[VCF::Direct][FMT::InvalidFloat7] = {4, 8};
table[VCF::Index8][FMT::UByte] = {1, 1};
table[VCF::Index8][FMT::Byte] = {1, 1};
table[VCF::Index8][FMT::UShort] = {1, 1};
table[VCF::Index8][FMT::Short] = {1, 1};
table[VCF::Index8][FMT::Float] = {1, 1};
+ table[VCF::Index8][FMT::InvalidFloat5] = {1, 1};
+ table[VCF::Index8][FMT::InvalidFloat6] = {1, 1};
+ table[VCF::Index8][FMT::InvalidFloat7] = {1, 1};
table[VCF::Index16][FMT::UByte] = {2, 2};
table[VCF::Index16][FMT::Byte] = {2, 2};
table[VCF::Index16][FMT::UShort] = {2, 2};
table[VCF::Index16][FMT::Short] = {2, 2};
table[VCF::Index16][FMT::Float] = {2, 2};
+ table[VCF::Index16][FMT::InvalidFloat5] = {2, 2};
+ table[VCF::Index16][FMT::InvalidFloat6] = {2, 2};
+ table[VCF::Index16][FMT::InvalidFloat7] = {2, 2};
return table;
}