diff options
| author | Anthony <Helios747@users.noreply.github.com> | 2017-07-30 01:00:16 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-07-30 01:00:16 -0700 |
| commit | ba57605266b9ab178963bf56e146f355d1b93cd4 (patch) | |
| tree | 0ddc89cfca6db3d343d317c18b7c07c9ab83e9c4 /Source/Core/VideoCommon/VertexLoaderManager.cpp | |
| parent | 5bad2ee4a4129e734ff4f4d861cedc4cd573df55 (diff) | |
| parent | b154edb4fbdb327920a33b44f35f34cdf2636d6f (diff) | |
Merge pull request #5702 from stenzek/ubershaders
Ubershaders 2.0
Diffstat (limited to 'Source/Core/VideoCommon/VertexLoaderManager.cpp')
| -rw-r--r-- | Source/Core/VideoCommon/VertexLoaderManager.cpp | 77 |
1 files changed, 70 insertions, 7 deletions
diff --git a/Source/Core/VideoCommon/VertexLoaderManager.cpp b/Source/Core/VideoCommon/VertexLoaderManager.cpp index d3f51ddfd9..bb52197585 100644 --- a/Source/Core/VideoCommon/VertexLoaderManager.cpp +++ b/Source/Core/VideoCommon/VertexLoaderManager.cpp @@ -44,13 +44,6 @@ static VertexLoaderMap s_vertex_loader_map; u8* cached_arraybases[12]; -// Used in the Vulkan backend - -NativeVertexFormatMap* GetNativeVertexFormatMap() -{ - return &s_native_vertex_map; -} - void Init() { MarkAllDirty(); @@ -133,6 +126,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; @@ -208,6 +270,7 @@ int RunVertices(int vtx_attr_group, int primitive, int count, DataReader src, bo } s_current_vtx_fmt = loader->m_native_vertex_format; g_current_components = loader->m_native_components; + VertexShaderManager::SetVertexFormat(loader->m_native_components); // if cull mode is CULL_ALL, tell VertexManager to skip triangles and quads. // They still need to go through vertex loading, because we need to calculate a zfreeze refrence |
