summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon/VertexLoaderARM64.cpp
diff options
context:
space:
mode:
authorPokechu22 <Pokechu022@gmail.com>2022-07-04 19:20:15 -0700
committerPokechu22 <Pokechu022@gmail.com>2022-09-18 23:33:24 -0700
commitd80201a57f6433bf660be2a1aecd60b97ddb6599 (patch)
tree75d4b958215832967e4e4a8882c9e34c32302d94 /Source/Core/VideoCommon/VertexLoaderARM64.cpp
parentf148de161f3126d2b328d5c022acb04379f1da1f (diff)
VertexLoaderARM64: Fix direct normal+tangent+binormal with index3 set
Fixes https://bugs.dolphin-emu.org/issues/12952
Diffstat (limited to 'Source/Core/VideoCommon/VertexLoaderARM64.cpp')
-rw-r--r--Source/Core/VideoCommon/VertexLoaderARM64.cpp45
1 files changed, 26 insertions, 19 deletions
diff --git a/Source/Core/VideoCommon/VertexLoaderARM64.cpp b/Source/Core/VideoCommon/VertexLoaderARM64.cpp
index 3d64e85cb7..99ba5b3357 100644
--- a/Source/Core/VideoCommon/VertexLoaderARM64.cpp
+++ b/Source/Core/VideoCommon/VertexLoaderARM64.cpp
@@ -102,9 +102,10 @@ std::pair<Arm64Gen::ARM64Reg, u32> VertexLoaderARM64::GetVertexAddr(CPArray arra
}
}
-int VertexLoaderARM64::ReadVertex(VertexComponentFormat attribute, ComponentFormat format,
- int count_in, int count_out, bool dequantize, u8 scaling_exponent,
- AttributeFormat* native_format, ARM64Reg reg, u32 offset)
+void VertexLoaderARM64::ReadVertex(VertexComponentFormat attribute, ComponentFormat format,
+ int count_in, int count_out, bool dequantize,
+ u8 scaling_exponent, AttributeFormat* native_format,
+ ARM64Reg reg, u32 offset)
{
ARM64Reg coords = count_in == 3 ? ARM64Reg::Q31 : ARM64Reg::D31;
ARM64Reg scale = count_in == 3 ? ARM64Reg::Q30 : ARM64Reg::D30;
@@ -113,7 +114,6 @@ int VertexLoaderARM64::ReadVertex(VertexComponentFormat attribute, ComponentForm
int load_bytes = elem_size * count_in;
int load_size = GetLoadSize(load_bytes);
load_size <<= 3;
- elem_size <<= 3;
m_float_emit.LDUR(load_size, coords, reg, offset);
@@ -189,8 +189,6 @@ int VertexLoaderARM64::ReadVertex(VertexComponentFormat attribute, ComponentForm
if (attribute == VertexComponentFormat::Direct)
m_src_ofs += load_bytes;
-
- return load_bytes;
}
void VertexLoaderARM64::ReadColor(VertexComponentFormat attribute, ColorFormat format, ARM64Reg reg,
@@ -400,23 +398,32 @@ void VertexLoaderARM64::GenerateVertexLoader()
static constexpr Common::EnumMap<u8, static_cast<ComponentFormat>(7)> SCALE_MAP = {7, 6, 15, 14,
0, 0, 0, 0};
const u8 scaling_exponent = SCALE_MAP[m_VtxAttr.g0.NormalFormat];
- const int limit = m_VtxAttr.g0.NormalElements == NormalComponentCount::NTB ? 3 : 1;
- ARM64Reg reg{};
- u32 offset{};
- for (int i = 0; i < limit; i++)
+ // Normal
+ auto [reg, offset] = GetVertexAddr(CPArray::Normal, m_VtxDesc.low.Normal);
+ ReadVertex(m_VtxDesc.low.Normal, m_VtxAttr.g0.NormalFormat, 3, 3, true, scaling_exponent,
+ &m_native_vtx_decl.normals[0], reg, offset);
+
+ if (m_VtxAttr.g0.NormalElements == NormalComponentCount::NTB)
{
- if (!i || m_VtxAttr.g0.NormalIndex3)
- {
- const int elem_size = GetElementSize(m_VtxAttr.g0.NormalFormat);
+ const bool index3 = IsIndexed(m_VtxDesc.low.Normal) && m_VtxAttr.g0.NormalIndex3;
+ const int elem_size = GetElementSize(m_VtxAttr.g0.NormalFormat);
+ const int load_bytes = elem_size * 3;
+ // Tangent
+ // If in Index3 mode, and indexed components are used, replace the index with a new index.
+ if (index3)
std::tie(reg, offset) = GetVertexAddr(CPArray::Normal, m_VtxDesc.low.Normal);
- offset += i * elem_size * 3;
- }
- int bytes_read = ReadVertex(m_VtxDesc.low.Normal, m_VtxAttr.g0.NormalFormat, 3, 3, true,
- scaling_exponent, &m_native_vtx_decl.normals[i], reg, offset);
-
- offset += bytes_read;
+ // The tangent comes after the normal; even in index3 mode, an extra offset of load_bytes is
+ // applied. Note that this is different from adding 1 to the index, as the stride for indices
+ // may be different from the size of the tangent itself.
+ ReadVertex(m_VtxDesc.low.Normal, m_VtxAttr.g0.NormalFormat, 3, 3, true, scaling_exponent,
+ &m_native_vtx_decl.normals[1], reg, offset + load_bytes);
+ // Binormal
+ if (index3)
+ std::tie(reg, offset) = GetVertexAddr(CPArray::Normal, m_VtxDesc.low.Normal);
+ ReadVertex(m_VtxDesc.low.Normal, m_VtxAttr.g0.NormalFormat, 3, 3, true, scaling_exponent,
+ &m_native_vtx_decl.normals[2], reg, offset + load_bytes * 2);
}
}