Browse Source

When building input layouts, put VS element hash to the upper 32 bits to reduce possibility of collisions.

Lasse Öörni 9 years ago
parent
commit
d492d32f41

+ 3 - 4
Source/Urho3D/Graphics/Direct3D11/D3D11Graphics.cpp

@@ -2581,18 +2581,17 @@ void Graphics::PrepareDraw()
         // Do not create input layout if no vertex buffers / elements
         if (newVertexDeclarationHash)
         {
-            /// \todo Is this safe? (Should preferably use non-overlapping bits)
+            /// \todo Using a 64bit total hash for vertex shader and vertex buffer elements hash may not guarantee uniqueness
             newVertexDeclarationHash += vertexShader_->GetElementHash();
             if (newVertexDeclarationHash != vertexDeclarationHash_)
             {
-                HashMap<unsigned long long, SharedPtr<VertexDeclaration> >::Iterator
-                    i = vertexDeclarations_.Find(newVertexDeclarationHash);
+                HashMap<unsigned long long, SharedPtr<VertexDeclaration> >::Iterator i = 
+                    vertexDeclarations_.Find(newVertexDeclarationHash);
                 if (i == vertexDeclarations_.End())
                 {
                     SharedPtr<VertexDeclaration> newVertexDeclaration(new VertexDeclaration(this, vertexShader_, vertexBuffers_));
                     i = vertexDeclarations_.Insert(MakePair(newVertexDeclarationHash, newVertexDeclaration));
                 }
-
                 impl_->deviceContext_->IASetInputLayout((ID3D11InputLayout*)i->second_->GetInputLayout());
                 vertexDeclarationHash_ = newVertexDeclarationHash;
             }

+ 4 - 2
Source/Urho3D/Graphics/Direct3D11/D3D11ShaderVariation.cpp

@@ -210,6 +210,7 @@ bool ShaderVariation::LoadByteCode(const String& binaryShaderName)
     /*unsigned short shaderType = */file->ReadUShort();
     /*unsigned short shaderModel = */file->ReadUShort();
     elementHash_ = file->ReadUInt();
+    elementHash_ <<= 32;
 
     unsigned numParameters = file->ReadUInt();
     for (unsigned i = 0; i < numParameters; ++i)
@@ -379,10 +380,11 @@ void ShaderVariation::ParseParameters(unsigned char* bufData, unsigned bufSize)
             VertexElementSemantic semantic = (VertexElementSemantic)GetStringListIndex(paramDesc.SemanticName, elementSemanticNames, MAX_VERTEX_ELEMENT_SEMANTICS, true);
             if (semantic != MAX_VERTEX_ELEMENT_SEMANTICS)
             {
-                elementHash_ <<= 6;
+                elementHash_ <<= 4;
                 elementHash_ += ((int)semantic + 1) * (paramDesc.SemanticIndex + 1);
             }
         }
+        elementHash_ <<= 32;
     }
 
     HashMap<String, unsigned> cbRegisterMap;
@@ -439,7 +441,7 @@ void ShaderVariation::SaveByteCode(const String& binaryShaderName)
     file->WriteFileID("USHD");
     file->WriteShort((unsigned short)type_);
     file->WriteShort(4);
-    file->WriteUInt(elementHash_);
+    file->WriteUInt(elementHash_ >> 32);
 
     file->WriteUInt(parameters_.Size());
     for (HashMap<StringHash, ShaderParameter>::ConstIterator i = parameters_.Begin(); i != parameters_.End(); ++i)

+ 1 - 1
Source/Urho3D/Graphics/Direct3D11/D3D11ShaderVariation.h

@@ -150,7 +150,7 @@ private:
     /// Shader type.
     ShaderType type_;
     /// Vertex element hash for vertex shaders. Zero for pixel shaders. Note that hashing is different than vertex buffers.
-    unsigned elementHash_;
+    unsigned long long elementHash_;
     /// Shader parameters.
     HashMap<StringHash, ShaderParameter> parameters_;
     /// Texture unit use flags.