diff --git a/Source/Core/VideoCommon/VertexLoader.cpp b/Source/Core/VideoCommon/VertexLoader.cpp index da8e0d2e05..0d49ef1a4b 100644 --- a/Source/Core/VideoCommon/VertexLoader.cpp +++ b/Source/Core/VideoCommon/VertexLoader.cpp @@ -79,13 +79,9 @@ VertexLoader::VertexLoader(const TVtxDesc& vtx_desc, const VAT& vtx_attr) void VertexLoader::CompileVertexTranslator() { - m_VertexSize = 0; - // Reset pipeline m_numPipelineStages = 0; - u32 components = 0; - // Position in pc vertex format. int nat_offset = 0; @@ -93,71 +89,24 @@ void VertexLoader::CompileVertexTranslator() if (m_VtxDesc.low.PosMatIdx) { WriteCall(PosMtx_ReadDirect_UByte); - components |= VB_HAS_POSMTXIDX; m_native_vtx_decl.posmtx.components = 4; m_native_vtx_decl.posmtx.enable = true; m_native_vtx_decl.posmtx.offset = nat_offset; m_native_vtx_decl.posmtx.type = VAR_UNSIGNED_BYTE; m_native_vtx_decl.posmtx.integer = true; nat_offset += 4; - m_VertexSize += 1; } - if (m_VtxDesc.low.Tex0MatIdx) + for (auto texmtxidx : m_VtxDesc.low.TexMatIdx) { - m_VertexSize += 1; - components |= VB_HAS_TEXMTXIDX0; - WriteCall(TexMtx_ReadDirect_UByte); - } - if (m_VtxDesc.low.Tex1MatIdx) - { - m_VertexSize += 1; - components |= VB_HAS_TEXMTXIDX1; - WriteCall(TexMtx_ReadDirect_UByte); - } - if (m_VtxDesc.low.Tex2MatIdx) - { - m_VertexSize += 1; - components |= VB_HAS_TEXMTXIDX2; - WriteCall(TexMtx_ReadDirect_UByte); - } - if (m_VtxDesc.low.Tex3MatIdx) - { - m_VertexSize += 1; - components |= VB_HAS_TEXMTXIDX3; - WriteCall(TexMtx_ReadDirect_UByte); - } - if (m_VtxDesc.low.Tex4MatIdx) - { - m_VertexSize += 1; - components |= VB_HAS_TEXMTXIDX4; - WriteCall(TexMtx_ReadDirect_UByte); - } - if (m_VtxDesc.low.Tex5MatIdx) - { - m_VertexSize += 1; - components |= VB_HAS_TEXMTXIDX5; - WriteCall(TexMtx_ReadDirect_UByte); - } - if (m_VtxDesc.low.Tex6MatIdx) - { - m_VertexSize += 1; - components |= VB_HAS_TEXMTXIDX6; - WriteCall(TexMtx_ReadDirect_UByte); - } - if (m_VtxDesc.low.Tex7MatIdx) - { - m_VertexSize += 1; - components |= VB_HAS_TEXMTXIDX7; - WriteCall(TexMtx_ReadDirect_UByte); + if (texmtxidx) + WriteCall(TexMtx_ReadDirect_UByte); } // Write vertex position loader WriteCall(VertexLoader_Position::GetFunction(m_VtxDesc.low.Position, m_VtxAttr.g0.PosFormat, m_VtxAttr.g0.PosElements)); - m_VertexSize += VertexLoader_Position::GetSize(m_VtxDesc.low.Position, m_VtxAttr.g0.PosFormat, - m_VtxAttr.g0.PosElements); int pos_elements = m_VtxAttr.g0.PosElements == CoordComponentCount::XY ? 2 : 3; m_native_vtx_decl.position.components = pos_elements; m_native_vtx_decl.position.enable = true; @@ -169,10 +118,6 @@ void VertexLoader::CompileVertexTranslator() // Normals if (m_VtxDesc.low.Normal != VertexComponentFormat::NotPresent) { - m_VertexSize += - VertexLoader_Normal::GetSize(m_VtxDesc.low.Normal, m_VtxAttr.g0.NormalFormat, - m_VtxAttr.g0.NormalElements, m_VtxAttr.g0.NormalIndex3); - TPipelineFunction pFunc = VertexLoader_Normal::GetFunction(m_VtxDesc.low.Normal, m_VtxAttr.g0.NormalFormat, m_VtxAttr.g0.NormalElements, m_VtxAttr.g0.NormalIndex3); @@ -194,10 +139,6 @@ void VertexLoader::CompileVertexTranslator() m_native_vtx_decl.normals[i].integer = false; nat_offset += 12; } - - components |= VB_HAS_NRM0; - if (m_VtxAttr.g0.NormalElements == NormalComponentCount::NBT) - components |= VB_HAS_NRM1 | VB_HAS_NRM2; } for (size_t i = 0; i < m_VtxDesc.low.Color.Size(); i++) @@ -206,8 +147,6 @@ void VertexLoader::CompileVertexTranslator() m_native_vtx_decl.colors[i].type = VAR_UNSIGNED_BYTE; m_native_vtx_decl.colors[i].integer = false; - m_VertexSize += - VertexLoader_Color::GetSize(m_VtxDesc.low.Color[i], m_VtxAttr.GetColorFormat(i)); TPipelineFunction pFunc = VertexLoader_Color::GetFunction(m_VtxDesc.low.Color[i], m_VtxAttr.GetColorFormat(i)); @@ -218,7 +157,6 @@ void VertexLoader::CompileVertexTranslator() if (m_VtxDesc.low.Color[i] != VertexComponentFormat::NotPresent) { - components |= VB_HAS_COL0 << i; m_native_vtx_decl.colors[i].offset = nat_offset; m_native_vtx_decl.colors[i].enable = true; nat_offset += 4; @@ -245,25 +183,21 @@ void VertexLoader::CompileVertexTranslator() ASSERT_MSG(VIDEO, elements == TexComponentCount::S || elements == TexComponentCount::ST, "Invalid number of texture coordinates elements!\n(elements = %d)", (u32)elements); - components |= VB_HAS_UV0 << i; WriteCall(VertexLoader_TextCoord::GetFunction(tc, format, elements)); - m_VertexSize += VertexLoader_TextCoord::GetSize(tc, format, elements); } - if (components & (VB_HAS_TEXMTXIDX0 << i)) + if (m_VtxDesc.low.TexMatIdx[i]) { m_native_vtx_decl.texcoords[i].enable = true; + m_native_vtx_decl.texcoords[i].components = 3; + nat_offset += 12; if (tc != VertexComponentFormat::NotPresent) { // if texmtx is included, texcoord will always be 3 floats, z will be the texmtx index - m_native_vtx_decl.texcoords[i].components = 3; - nat_offset += 12; WriteCall(elements == TexComponentCount::ST ? TexMtx_Write_Float : TexMtx_Write_Float2); } else { - m_native_vtx_decl.texcoords[i].components = 3; - nat_offset += 12; WriteCall(TexMtx_Write_Float3); } } @@ -280,17 +214,21 @@ void VertexLoader::CompileVertexTranslator() if (tc == VertexComponentFormat::NotPresent) { // if there's more tex coords later, have to write a dummy call - size_t j = i + 1; - for (; j < m_VtxDesc.high.TexCoord.Size(); ++j) + bool has_more = false; + for (size_t j = 0; j < m_VtxDesc.high.TexCoord.Size(); ++j) { if (m_VtxDesc.high.TexCoord[j] != VertexComponentFormat::NotPresent) { + has_more = true; WriteCall(VertexLoader_TextCoord::GetDummyFunction()); // important to get indices right! break; } + else if (m_VtxDesc.low.TexMatIdx[i]) + { + has_more = true; + } } - // tricky! - if (j == 8 && !((components & VB_HAS_TEXMTXIDXALL) & (VB_HAS_TEXMTXIDXALL << (i + 1)))) + if (!has_more) { // no more tex coords and tex matrices, so exit loop break; @@ -304,7 +242,6 @@ void VertexLoader::CompileVertexTranslator() WriteCall(SkipVertex); } - m_native_components = components; m_native_vtx_decl.stride = nat_offset; } diff --git a/Source/Core/VideoCommon/VertexLoaderARM64.cpp b/Source/Core/VideoCommon/VertexLoaderARM64.cpp index 4030a50808..e546c42be8 100644 --- a/Source/Core/VideoCommon/VertexLoaderARM64.cpp +++ b/Source/Core/VideoCommon/VertexLoaderARM64.cpp @@ -423,7 +423,6 @@ void VertexLoaderARM64::GenerateVertexLoader() STR(IndexType::Unsigned, scratch1_reg, EncodeRegTo64(scratch2_reg), 0); SetJumpTarget(dont_store); - m_native_components |= VB_HAS_POSMTXIDX; m_native_vtx_decl.posmtx.components = 4; m_native_vtx_decl.posmtx.enable = true; m_native_vtx_decl.posmtx.offset = m_dst_ofs; @@ -486,10 +485,6 @@ void VertexLoaderARM64::GenerateVertexLoader() else offset += bytes_read; } - - m_native_components |= VB_HAS_NRM0; - if (m_VtxAttr.g0.NormalElements == NormalComponentCount::NBT) - m_native_components |= VB_HAS_NRM1 | VB_HAS_NRM2; } for (size_t i = 0; i < m_VtxDesc.low.Color.Size(); i++) @@ -508,7 +503,6 @@ void VertexLoaderARM64::GenerateVertexLoader() s32 offset = GetAddressImm(ARRAY_COLOR0 + int(i), m_VtxDesc.low.Color[i], EncodeRegTo64(scratch1_reg), align); ReadColor(m_VtxDesc.low.Color[i], m_VtxAttr.GetColorFormat(i), offset); - m_native_components |= VB_HAS_COL0 << i; m_native_vtx_decl.colors[i].components = 4; m_native_vtx_decl.colors[i].enable = true; m_native_vtx_decl.colors[i].offset = m_dst_ofs; @@ -527,8 +521,6 @@ void VertexLoaderARM64::GenerateVertexLoader() int elements = m_VtxAttr.GetTexElements(i) == TexComponentCount::S ? 1 : 2; if (m_VtxDesc.high.TexCoord[i] != VertexComponentFormat::NotPresent) { - m_native_components |= VB_HAS_UV0 << i; - int elem_size = GetElementSize(m_VtxAttr.GetTexFormat(i)); int load_bytes = elem_size * (elements + 2); int load_size = GetLoadSize(load_bytes); @@ -543,7 +535,6 @@ void VertexLoaderARM64::GenerateVertexLoader() } if (m_VtxDesc.low.TexMatIdx[i]) { - m_native_components |= VB_HAS_TEXMTXIDX0 << i; m_native_vtx_decl.texcoords[i].components = 3; m_native_vtx_decl.texcoords[i].enable = true; m_native_vtx_decl.texcoords[i].type = VAR_FLOAT; @@ -609,7 +600,7 @@ void VertexLoaderARM64::GenerateVertexLoader() FlushIcache(); - m_VertexSize = m_src_ofs; + ASSERT(m_vertex_size == m_src_ofs); m_native_vtx_decl.stride = m_dst_ofs; } diff --git a/Source/Core/VideoCommon/VertexLoaderBase.cpp b/Source/Core/VideoCommon/VertexLoaderBase.cpp index 84d7eb43c0..51f9fda359 100644 --- a/Source/Core/VideoCommon/VertexLoaderBase.cpp +++ b/Source/Core/VideoCommon/VertexLoaderBase.cpp @@ -19,6 +19,10 @@ #include "VideoCommon/DataReader.h" #include "VideoCommon/VertexLoader.h" +#include "VideoCommon/VertexLoader_Color.h" +#include "VideoCommon/VertexLoader_Normal.h" +#include "VideoCommon/VertexLoader_Position.h" +#include "VideoCommon/VertexLoader_TextCoord.h" #ifdef _M_X86_64 #include "VideoCommon/VertexLoaderX64.h" @@ -35,20 +39,22 @@ public: : VertexLoaderBase(vtx_desc, vtx_attr), a(std::move(a_)), b(std::move(b_)) { ASSERT(a && b); - if (a->m_VertexSize == b->m_VertexSize && a->m_native_components == b->m_native_components && + if (a->m_vertex_size == b->m_vertex_size && a->m_native_components == b->m_native_components && a->m_native_vtx_decl.stride == b->m_native_vtx_decl.stride) { - m_VertexSize = a->m_VertexSize; - m_native_components = a->m_native_components; + // These are generated from the VAT and vertex desc, so they should match. + // m_native_vtx_decl.stride isn't set yet, though. + ASSERT(m_vertex_size == a->m_vertex_size && m_native_components == a->m_native_components); + memcpy(&m_native_vtx_decl, &a->m_native_vtx_decl, sizeof(PortableVertexDeclaration)); } else { - ERROR_LOG_FMT(VIDEO, "Can't compare vertex loaders that expect different vertex formats!"); - ERROR_LOG_FMT(VIDEO, "a: m_VertexSize {}, m_native_components {:#010x}, stride {}", - a->m_VertexSize, a->m_native_components, a->m_native_vtx_decl.stride); - ERROR_LOG_FMT(VIDEO, "b: m_VertexSize {}, m_native_components {:#010x}, stride {}", - b->m_VertexSize, b->m_native_components, b->m_native_vtx_decl.stride); + PanicAlertFmt("Can't compare vertex loaders that expect different vertex formats!\n" + "a: m_vertex_size {}, m_native_components {:#010x}, stride {}\n" + "b: m_vertex_size {}, m_native_components {:#010x}, stride {}", + a->m_vertex_size, a->m_native_components, a->m_native_vtx_decl.stride, + b->m_vertex_size, b->m_native_components, b->m_native_vtx_decl.stride); } } int RunVertices(DataReader src, DataReader dst, int count) override @@ -91,6 +97,62 @@ private: std::vector buffer_b; }; +u32 VertexLoaderBase::GetVertexSize(const TVtxDesc& vtx_desc, const VAT& vtx_attr) +{ + u32 size = 0; + if (vtx_desc.low.PosMatIdx) + size++; + for (auto texmtxidx : vtx_desc.low.TexMatIdx) + { + if (texmtxidx) + size++; + } + size += VertexLoader_Position::GetSize(vtx_desc.low.Position, vtx_attr.g0.PosFormat, + vtx_attr.g0.PosElements); + size += VertexLoader_Normal::GetSize(vtx_desc.low.Normal, vtx_attr.g0.NormalFormat, + vtx_attr.g0.NormalElements, vtx_attr.g0.NormalIndex3); + for (u32 i = 0; i < vtx_desc.low.Color.Size(); i++) + { + size += VertexLoader_Color::GetSize(vtx_desc.low.Color[i], vtx_attr.GetColorFormat(i)); + } + for (u32 i = 0; i < vtx_desc.high.TexCoord.Size(); i++) + { + size += VertexLoader_TextCoord::GetSize(vtx_desc.high.TexCoord[i], vtx_attr.GetTexFormat(i), + vtx_attr.GetTexElements(i)); + } + return size; +} + +u32 VertexLoaderBase::GetVertexComponents(const TVtxDesc& vtx_desc, const VAT& vtx_attr) +{ + u32 components = 0; + if (vtx_desc.low.PosMatIdx) + components |= VB_HAS_POSMTXIDX; + for (u32 i = 0; i < vtx_desc.low.TexMatIdx.Size(); i++) + { + if (vtx_desc.low.TexMatIdx[i]) + components |= VB_HAS_TEXMTXIDX0 << i; + } + // Vertices always have positions; thus there is no VB_HAS_POS as it would always be set + if (vtx_desc.low.Normal != VertexComponentFormat::NotPresent) + { + components |= VB_HAS_NRM0; + if (vtx_attr.g0.NormalElements == NormalComponentCount::NBT) + components |= VB_HAS_NRM1 | VB_HAS_NRM2; + } + for (u32 i = 0; i < vtx_desc.low.Color.Size(); i++) + { + if (vtx_desc.low.Color[i] != VertexComponentFormat::NotPresent) + components |= VB_HAS_COL0 << i; + } + for (u32 i = 0; i < vtx_desc.high.TexCoord.Size(); i++) + { + if (vtx_desc.high.TexCoord[i] != VertexComponentFormat::NotPresent) + components |= VB_HAS_UV0 << i; + } + return components; +} + std::unique_ptr VertexLoaderBase::CreateVertexLoader(const TVtxDesc& vtx_desc, const VAT& vtx_attr) { diff --git a/Source/Core/VideoCommon/VertexLoaderBase.h b/Source/Core/VideoCommon/VertexLoaderBase.h index 2c787479b6..2e73fbad1d 100644 --- a/Source/Core/VideoCommon/VertexLoaderBase.h +++ b/Source/Core/VideoCommon/VertexLoaderBase.h @@ -60,15 +60,17 @@ struct hash class VertexLoaderBase { public: + static u32 GetVertexSize(const TVtxDesc& vtx_desc, const VAT& vtx_attr); + static u32 GetVertexComponents(const TVtxDesc& vtx_desc, const VAT& vtx_attr); static std::unique_ptr CreateVertexLoader(const TVtxDesc& vtx_desc, const VAT& vtx_attr); virtual ~VertexLoaderBase() {} virtual int RunVertices(DataReader src, DataReader dst, int count) = 0; // per loader public state - int m_VertexSize = 0; // number of bytes of a raw GC vertex PortableVertexDeclaration m_native_vtx_decl{}; - u32 m_native_components = 0; + const u32 m_vertex_size; // number of bytes of a raw GC vertex + const u32 m_native_components; // used by VertexLoaderManager NativeVertexFormat* m_native_vertex_format = nullptr; @@ -76,7 +78,10 @@ public: protected: VertexLoaderBase(const TVtxDesc& vtx_desc, const VAT& vtx_attr) - : m_VtxDesc{vtx_desc}, m_VtxAttr{vtx_attr} {}; + : m_VtxDesc{vtx_desc}, m_VtxAttr{vtx_attr}, m_vertex_size{GetVertexSize(vtx_desc, vtx_attr)}, + m_native_components{GetVertexComponents(vtx_desc, vtx_attr)} + { + } // GC vertex format const VAT m_VtxAttr; diff --git a/Source/Core/VideoCommon/VertexLoaderManager.cpp b/Source/Core/VideoCommon/VertexLoaderManager.cpp index ab362fc29c..c657ed7989 100644 --- a/Source/Core/VideoCommon/VertexLoaderManager.cpp +++ b/Source/Core/VideoCommon/VertexLoaderManager.cpp @@ -247,7 +247,7 @@ int RunVertices(int vtx_attr_group, int primitive, int count, DataReader src, bo VertexLoaderBase* loader = RefreshLoader(vtx_attr_group, is_preprocess); - int size = count * loader->m_VertexSize; + int size = count * loader->m_vertex_size; if ((int)src.size() < size) return -1; diff --git a/Source/Core/VideoCommon/VertexLoaderX64.cpp b/Source/Core/VideoCommon/VertexLoaderX64.cpp index e6d94693b8..89eb841f5e 100644 --- a/Source/Core/VideoCommon/VertexLoaderX64.cpp +++ b/Source/Core/VideoCommon/VertexLoaderX64.cpp @@ -418,7 +418,6 @@ void VertexLoaderX64::GenerateVertexLoader() MOV(32, MPIC(VertexLoaderManager::position_matrix_index, count_reg, SCALE_4), R(scratch1)); SetJumpTarget(dont_store); - m_native_components |= VB_HAS_POSMTXIDX; m_native_vtx_decl.posmtx.components = 4; m_native_vtx_decl.posmtx.enable = true; m_native_vtx_decl.posmtx.offset = m_dst_ofs; @@ -457,10 +456,6 @@ void VertexLoaderX64::GenerateVertexLoader() data.AddMemOffset(ReadVertex(data, m_VtxDesc.low.Normal, m_VtxAttr.g0.NormalFormat, 3, 3, true, scaling_exponent, &m_native_vtx_decl.normals[i])); } - - m_native_components |= VB_HAS_NRM0; - if (m_VtxAttr.g0.NormalElements == NormalComponentCount::NBT) - m_native_components |= VB_HAS_NRM1 | VB_HAS_NRM2; } for (size_t i = 0; i < m_VtxDesc.low.Color.Size(); i++) @@ -469,7 +464,6 @@ void VertexLoaderX64::GenerateVertexLoader() { data = GetVertexAddr(ARRAY_COLOR0 + int(i), m_VtxDesc.low.Color[i]); ReadColor(data, m_VtxDesc.low.Color[i], m_VtxAttr.GetColorFormat(i)); - m_native_components |= VB_HAS_COL0 << i; m_native_vtx_decl.colors[i].components = 4; m_native_vtx_decl.colors[i].enable = true; m_native_vtx_decl.colors[i].offset = m_dst_ofs; @@ -489,11 +483,9 @@ void VertexLoaderX64::GenerateVertexLoader() ReadVertex(data, m_VtxDesc.high.TexCoord[i], m_VtxAttr.GetTexFormat(i), elements, m_VtxDesc.low.TexMatIdx[i] ? 2 : elements, m_VtxAttr.g0.ByteDequant, scaling_exponent, &m_native_vtx_decl.texcoords[i]); - m_native_components |= VB_HAS_UV0 << i; } if (m_VtxDesc.low.TexMatIdx[i]) { - m_native_components |= VB_HAS_TEXMTXIDX0 << i; m_native_vtx_decl.texcoords[i].components = 3; m_native_vtx_decl.texcoords[i].enable = true; m_native_vtx_decl.texcoords[i].type = VAR_FLOAT; @@ -544,7 +536,7 @@ void VertexLoaderX64::GenerateVertexLoader() RET(); } - m_VertexSize = m_src_ofs; + ASSERT(m_vertex_size == m_src_ofs); m_native_vtx_decl.stride = m_dst_ofs; } diff --git a/Source/UnitTests/VideoCommon/VertexLoaderTest.cpp b/Source/UnitTests/VideoCommon/VertexLoaderTest.cpp index 7f9dbdec84..925a13114a 100644 --- a/Source/UnitTests/VideoCommon/VertexLoaderTest.cpp +++ b/Source/UnitTests/VideoCommon/VertexLoaderTest.cpp @@ -62,7 +62,7 @@ protected: void CreateAndCheckSizes(size_t input_size, size_t output_size) { m_loader = VertexLoaderBase::CreateVertexLoader(m_vtx_desc, m_vtx_attr); - ASSERT_EQ((int)input_size, m_loader->m_VertexSize); + ASSERT_EQ(input_size, m_loader->m_vertex_size); ASSERT_EQ((int)output_size, m_loader->m_native_vtx_decl.stride); }