Merge pull request #12684 from Pokechu22/invalid-vertex-component
Fix out of bounds accesses for invalid vertex component formats
This commit is contained in:
commit
ad331205d1
|
@ -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.");
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
|
|
@ -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,
|
||||
}),
|
||||
};
|
||||
|
||||
|
|
|
@ -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::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::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>
|
||||
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];
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
|
|
@ -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++)
|
||||
|
|
|
@ -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::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::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>
|
||||
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];
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -121,7 +121,9 @@ INSTANTIATE_TEST_SUITE_P(
|
|||
::testing::Values(VertexComponentFormat::Direct, VertexComponentFormat::Index8,
|
||||
VertexComponentFormat::Index16),
|
||||
::testing::Values(ComponentFormat::UByte, ComponentFormat::Byte, ComponentFormat::UShort,
|
||||
ComponentFormat::Short, ComponentFormat::Float),
|
||||
ComponentFormat::Short, ComponentFormat::Float,
|
||||
ComponentFormat::InvalidFloat5, ComponentFormat::InvalidFloat6,
|
||||
ComponentFormat::InvalidFloat7),
|
||||
::testing::Values(CoordComponentCount::XY, CoordComponentCount::XYZ),
|
||||
::testing::Values(0, 1, 31) // frac
|
||||
));
|
||||
|
@ -170,10 +172,12 @@ TEST_P(VertexLoaderParamTest, PositionAll)
|
|||
{
|
||||
input_size = addr == VertexComponentFormat::Index8 ? 1 : 2;
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
if (addr == VertexComponentFormat::Index8)
|
||||
Input<u8>(i);
|
||||
else
|
||||
Input<u16>(i);
|
||||
}
|
||||
VertexLoaderManager::cached_arraybases[CPArray::Position] = m_src.GetPointer();
|
||||
g_main_cp_state.array_strides[CPArray::Position] = elem_count * elem_size;
|
||||
}
|
||||
|
@ -195,6 +199,9 @@ TEST_P(VertexLoaderParamTest, PositionAll)
|
|||
Input(MathUtil::SaturatingCast<s16>(value));
|
||||
break;
|
||||
case ComponentFormat::Float:
|
||||
case ComponentFormat::InvalidFloat5:
|
||||
case ComponentFormat::InvalidFloat6:
|
||||
case ComponentFormat::InvalidFloat7:
|
||||
Input(value);
|
||||
break;
|
||||
}
|
||||
|
@ -202,7 +209,7 @@ TEST_P(VertexLoaderParamTest, PositionAll)
|
|||
|
||||
RunVertices(count);
|
||||
|
||||
float scale = 1.f / (1u << (format == ComponentFormat::Float ? 0 : frac));
|
||||
float scale = 1.f / (1u << (format >= ComponentFormat::Float ? 0 : frac));
|
||||
for (auto iter = values.begin(); iter != values.end();)
|
||||
{
|
||||
float f, g;
|
||||
|
@ -225,6 +232,9 @@ TEST_P(VertexLoaderParamTest, PositionAll)
|
|||
g = MathUtil::SaturatingCast<s16>(*iter++);
|
||||
break;
|
||||
case ComponentFormat::Float:
|
||||
case ComponentFormat::InvalidFloat5:
|
||||
case ComponentFormat::InvalidFloat6:
|
||||
case ComponentFormat::InvalidFloat7:
|
||||
f = *iter++;
|
||||
g = *iter++;
|
||||
break;
|
||||
|
@ -543,7 +553,9 @@ INSTANTIATE_TEST_SUITE_P(
|
|||
::testing::Values(VertexComponentFormat::NotPresent, VertexComponentFormat::Direct,
|
||||
VertexComponentFormat::Index8, VertexComponentFormat::Index16),
|
||||
::testing::Values(ComponentFormat::UByte, ComponentFormat::Byte, ComponentFormat::UShort,
|
||||
ComponentFormat::Short, ComponentFormat::Float),
|
||||
ComponentFormat::Short, ComponentFormat::Float,
|
||||
ComponentFormat::InvalidFloat5, ComponentFormat::InvalidFloat6,
|
||||
ComponentFormat::InvalidFloat7),
|
||||
::testing::Values(NormalComponentCount::N, NormalComponentCount::NTB),
|
||||
::testing::Values(false, true)));
|
||||
|
||||
|
@ -609,7 +621,9 @@ TEST_P(VertexLoaderNormalTest, NormalAll)
|
|||
Input<s16>(value * (1 << 14));
|
||||
break;
|
||||
case ComponentFormat::Float:
|
||||
default:
|
||||
case ComponentFormat::InvalidFloat5:
|
||||
case ComponentFormat::InvalidFloat6:
|
||||
case ComponentFormat::InvalidFloat7:
|
||||
Input<float>(value);
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue