mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-12 23:48:35 +02:00
VertexLoaderManager: Add methods to generate "uber" vertex formats
These vertex formats enable all attributes. Inactive attributes are set to offset=0, and the smallest type possible. This "optimization" stops the NV compiler from generating variants of vertex shaders.
This commit is contained in:
parent
f48ef65bec
commit
38c48ff72e
@ -133,6 +133,75 @@ void MarkAllDirty()
|
|||||||
g_preprocess_cp_state.attr_dirty = BitSet32::AllTrue(8);
|
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)
|
static VertexLoaderBase* RefreshLoader(int vtx_attr_group, bool preprocess = false)
|
||||||
{
|
{
|
||||||
CPState* state = preprocess ? &g_preprocess_cp_state : &g_main_cp_state;
|
CPState* state = preprocess ? &g_preprocess_cp_state : &g_main_cp_state;
|
||||||
|
@ -26,6 +26,16 @@ void MarkAllDirty();
|
|||||||
|
|
||||||
NativeVertexFormatMap* GetNativeVertexFormatMap();
|
NativeVertexFormatMap* GetNativeVertexFormatMap();
|
||||||
|
|
||||||
|
// Creates or obtains a pointer to a VertexFormat representing decl.
|
||||||
|
// If this results in a VertexFormat being created, if the game later uses a matching vertex
|
||||||
|
// declaration, the one that was previously created will be used.
|
||||||
|
NativeVertexFormat* GetOrCreateMatchingFormat(const PortableVertexDeclaration& decl);
|
||||||
|
|
||||||
|
// For vertex ubershaders, all attributes need to be present, even when the vertex
|
||||||
|
// format does not contain them. This function returns a vertex format with dummy
|
||||||
|
// offsets set to the unused attributes.
|
||||||
|
NativeVertexFormat* GetUberVertexFormat(const PortableVertexDeclaration& decl);
|
||||||
|
|
||||||
// Returns -1 if buf_size is insufficient, else the amount of bytes consumed
|
// Returns -1 if buf_size is insufficient, else the amount of bytes consumed
|
||||||
int RunVertices(int vtx_attr_group, int primitive, int count, DataReader src, bool is_preprocess);
|
int RunVertices(int vtx_attr_group, int primitive, int count, DataReader src, bool is_preprocess);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user