summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon/VertexLoaderManager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core/VideoCommon/VertexLoaderManager.cpp')
-rw-r--r--Source/Core/VideoCommon/VertexLoaderManager.cpp69
1 files changed, 69 insertions, 0 deletions
diff --git a/Source/Core/VideoCommon/VertexLoaderManager.cpp b/Source/Core/VideoCommon/VertexLoaderManager.cpp
index d3f51ddfd9..cf13b0bcde 100644
--- a/Source/Core/VideoCommon/VertexLoaderManager.cpp
+++ b/Source/Core/VideoCommon/VertexLoaderManager.cpp
@@ -133,6 +133,75 @@ void MarkAllDirty()
g_preprocess_cp_state.attr_dirty = BitSet32::AllTrue(8);
}
+NativeVertexFormat* GetOrCreateMatchingFormat(const PortableVertexDeclaration& decl)
+{
+ auto iter = s_native_vertex_map.find(decl);
+ if (iter == s_native_vertex_map.end())
+ {
+ std::unique_ptr<NativeVertexFormat> fmt = g_vertex_manager->CreateNativeVertexFormat(decl);
+ auto ipair = s_native_vertex_map.emplace(decl, std::move(fmt));
+ iter = ipair.first;
+ }
+
+ return iter->second.get();
+}
+
+NativeVertexFormat* GetUberVertexFormat(const PortableVertexDeclaration& decl)
+{
+ // The padding in the structs can cause the memcmp() in the map to create duplicates.
+ // Avoid this by initializing the padding to zero.
+ PortableVertexDeclaration new_decl;
+ std::memset(&new_decl, 0, sizeof(new_decl));
+ new_decl.stride = decl.stride;
+
+ auto MakeDummyAttribute = [](AttributeFormat& attr, VarType type, int components, bool integer) {
+ attr.type = type;
+ attr.components = components;
+ attr.offset = 0;
+ attr.enable = true;
+ attr.integer = integer;
+ };
+ auto CopyAttribute = [](AttributeFormat& attr, const AttributeFormat& src) {
+ attr.type = src.type;
+ attr.components = src.components;
+ attr.offset = src.offset;
+ attr.enable = src.enable;
+ attr.integer = src.integer;
+ };
+
+ if (decl.position.enable)
+ CopyAttribute(new_decl.position, decl.position);
+ else
+ MakeDummyAttribute(new_decl.position, VAR_FLOAT, 1, false);
+ for (size_t i = 0; i < ArraySize(new_decl.normals); i++)
+ {
+ if (decl.normals[i].enable)
+ CopyAttribute(new_decl.normals[i], decl.normals[i]);
+ else
+ MakeDummyAttribute(new_decl.normals[i], VAR_FLOAT, 1, false);
+ }
+ for (size_t i = 0; i < ArraySize(new_decl.colors); i++)
+ {
+ if (decl.colors[i].enable)
+ CopyAttribute(new_decl.colors[i], decl.colors[i]);
+ else
+ MakeDummyAttribute(new_decl.colors[i], VAR_UNSIGNED_BYTE, 4, false);
+ }
+ for (size_t i = 0; i < ArraySize(new_decl.texcoords); i++)
+ {
+ if (decl.texcoords[i].enable)
+ CopyAttribute(new_decl.texcoords[i], decl.texcoords[i]);
+ else
+ MakeDummyAttribute(new_decl.texcoords[i], VAR_FLOAT, 1, false);
+ }
+ if (decl.posmtx.enable)
+ CopyAttribute(new_decl.posmtx, decl.posmtx);
+ else
+ MakeDummyAttribute(new_decl.posmtx, VAR_UNSIGNED_BYTE, 1, true);
+
+ return GetOrCreateMatchingFormat(new_decl);
+}
+
static VertexLoaderBase* RefreshLoader(int vtx_attr_group, bool preprocess = false)
{
CPState* state = preprocess ? &g_preprocess_cp_state : &g_main_cp_state;