Bläddra i källkod

Store constant buffer pointer directly to the ShaderProgram parameters to avoid indirection and if statement choosing between VS & PS parameters.

Lasse Öörni 10 år sedan
förälder
incheckning
0c58651c5c

+ 40 - 140
Source/Urho3D/Graphics/Direct3D11/D3D11Graphics.cpp

@@ -1145,20 +1145,10 @@ void Graphics::SetShaderParameter(StringHash param, const float* data, unsigned
     if (!shaderProgram_ || (i = shaderProgram_->parameters_.Find(param)) == shaderProgram_->parameters_.End())
         return;
 
-    if (i->second_.type_ == VS)
-    {
-        ConstantBuffer* buffer = shaderProgram_->vsConstantBuffers_[i->second_.buffer_];
-        if (!buffer->IsDirty())
-            dirtyConstantBuffers_.Push(buffer);
-        buffer->SetParameter(i->second_.offset_, count * sizeof(float), data);
-    }
-    else
-    {
-        ConstantBuffer* buffer = shaderProgram_->psConstantBuffers_[i->second_.buffer_];
-        if (!buffer->IsDirty())
-            dirtyConstantBuffers_.Push(buffer);
-        buffer->SetParameter(i->second_.offset_, count * sizeof(float), data);
-    }
+    ConstantBuffer* buffer = i->second_.bufferPtr_;
+    if (!buffer->IsDirty())
+        dirtyConstantBuffers_.Push(buffer);
+    buffer->SetParameter(i->second_.offset_, count * sizeof(float), data);
 }
 
 void Graphics::SetShaderParameter(StringHash param, float value)
@@ -1167,20 +1157,10 @@ void Graphics::SetShaderParameter(StringHash param, float value)
     if (!shaderProgram_ || (i = shaderProgram_->parameters_.Find(param)) == shaderProgram_->parameters_.End())
         return;
 
-    if (i->second_.type_ == VS)
-    {
-        ConstantBuffer* buffer = shaderProgram_->vsConstantBuffers_[i->second_.buffer_];
-        if (!buffer->IsDirty())
-            dirtyConstantBuffers_.Push(buffer);
-        buffer->SetParameter(i->second_.offset_, sizeof(float), &value);
-    }
-    else
-    {
-        ConstantBuffer* buffer = shaderProgram_->psConstantBuffers_[i->second_.buffer_];
-        if (!buffer->IsDirty())
-            dirtyConstantBuffers_.Push(buffer);
-        buffer->SetParameter(i->second_.offset_, sizeof(float), &value);
-    }
+    ConstantBuffer* buffer = i->second_.bufferPtr_;
+    if (!buffer->IsDirty())
+        dirtyConstantBuffers_.Push(buffer);
+    buffer->SetParameter(i->second_.offset_, sizeof(float), &value);
 }
 
 void Graphics::SetShaderParameter(StringHash param, bool value)
@@ -1189,20 +1169,10 @@ void Graphics::SetShaderParameter(StringHash param, bool value)
     if (!shaderProgram_ || (i = shaderProgram_->parameters_.Find(param)) == shaderProgram_->parameters_.End())
         return;
 
-    if (i->second_.type_ == VS)
-    {
-        ConstantBuffer* buffer = shaderProgram_->vsConstantBuffers_[i->second_.buffer_];
-        if (!buffer->IsDirty())
-            dirtyConstantBuffers_.Push(buffer);
-        buffer->SetParameter(i->second_.offset_, sizeof(bool), &value);
-    }
-    else
-    {
-        ConstantBuffer* buffer = shaderProgram_->psConstantBuffers_[i->second_.buffer_];
-        if (!buffer->IsDirty())
-            dirtyConstantBuffers_.Push(buffer);
-        buffer->SetParameter(i->second_.offset_, sizeof(bool), &value);
-    }
+    ConstantBuffer* buffer = i->second_.bufferPtr_;
+    if (!buffer->IsDirty())
+        dirtyConstantBuffers_.Push(buffer);
+    buffer->SetParameter(i->second_.offset_, sizeof(bool), &value);
 }
 
 void Graphics::SetShaderParameter(StringHash param, const Color& color)
@@ -1211,20 +1181,10 @@ void Graphics::SetShaderParameter(StringHash param, const Color& color)
     if (!shaderProgram_ || (i = shaderProgram_->parameters_.Find(param)) == shaderProgram_->parameters_.End())
         return;
 
-    if (i->second_.type_ == VS)
-    {
-        ConstantBuffer* buffer = shaderProgram_->vsConstantBuffers_[i->second_.buffer_];
-        if (!buffer->IsDirty())
-            dirtyConstantBuffers_.Push(buffer);
-        buffer->SetParameter(i->second_.offset_, sizeof(Color), &color);
-    }
-    else
-    {
-        ConstantBuffer* buffer = shaderProgram_->psConstantBuffers_[i->second_.buffer_];
-        if (!buffer->IsDirty())
-            dirtyConstantBuffers_.Push(buffer);
-        buffer->SetParameter(i->second_.offset_, sizeof(Color), &color);
-    }
+    ConstantBuffer* buffer = i->second_.bufferPtr_;
+    if (!buffer->IsDirty())
+        dirtyConstantBuffers_.Push(buffer);
+    buffer->SetParameter(i->second_.offset_, sizeof(Color), &color);
 }
 
 void Graphics::SetShaderParameter(StringHash param, const Vector2& vector)
@@ -1233,20 +1193,10 @@ void Graphics::SetShaderParameter(StringHash param, const Vector2& vector)
     if (!shaderProgram_ || (i = shaderProgram_->parameters_.Find(param)) == shaderProgram_->parameters_.End())
         return;
 
-    if (i->second_.type_ == VS)
-    {
-        ConstantBuffer* buffer = shaderProgram_->vsConstantBuffers_[i->second_.buffer_];
-        if (!buffer->IsDirty())
-            dirtyConstantBuffers_.Push(buffer);
-        buffer->SetParameter(i->second_.offset_, sizeof(Vector2), &vector);
-    }
-    else
-    {
-        ConstantBuffer* buffer = shaderProgram_->psConstantBuffers_[i->second_.buffer_];
-        if (!buffer->IsDirty())
-            dirtyConstantBuffers_.Push(buffer);
-        buffer->SetParameter(i->second_.offset_, sizeof(Vector2), &vector);
-    }
+    ConstantBuffer* buffer = i->second_.bufferPtr_;
+    if (!buffer->IsDirty())
+        dirtyConstantBuffers_.Push(buffer);
+    buffer->SetParameter(i->second_.offset_, sizeof(Vector2), &vector);
 }
 
 void Graphics::SetShaderParameter(StringHash param, const Matrix3& matrix)
@@ -1255,20 +1205,10 @@ void Graphics::SetShaderParameter(StringHash param, const Matrix3& matrix)
     if (!shaderProgram_ || (i = shaderProgram_->parameters_.Find(param)) == shaderProgram_->parameters_.End())
         return;
 
-    if (i->second_.type_ == VS)
-    {
-        ConstantBuffer* buffer = shaderProgram_->vsConstantBuffers_[i->second_.buffer_];
-        if (!buffer->IsDirty())
-            dirtyConstantBuffers_.Push(buffer);
-        buffer->SetVector3ArrayParameter(i->second_.offset_, 3, &matrix);
-    }
-    else
-    {
-        ConstantBuffer* buffer = shaderProgram_->psConstantBuffers_[i->second_.buffer_];
-        if (!buffer->IsDirty())
-            dirtyConstantBuffers_.Push(buffer);
-        buffer->SetVector3ArrayParameter(i->second_.offset_, 3, &matrix);
-    }
+    ConstantBuffer* buffer = i->second_.bufferPtr_;
+    if (!buffer->IsDirty())
+        dirtyConstantBuffers_.Push(buffer);
+    buffer->SetVector3ArrayParameter(i->second_.offset_, 3, &matrix);
 }
 
 void Graphics::SetShaderParameter(StringHash param, const Vector3& vector)
@@ -1277,20 +1217,10 @@ void Graphics::SetShaderParameter(StringHash param, const Vector3& vector)
     if (!shaderProgram_ || (i = shaderProgram_->parameters_.Find(param)) == shaderProgram_->parameters_.End())
         return;
 
-    if (i->second_.type_ == VS)
-    {
-        ConstantBuffer* buffer = shaderProgram_->vsConstantBuffers_[i->second_.buffer_];
-        if (!buffer->IsDirty())
-            dirtyConstantBuffers_.Push(buffer);
-        buffer->SetParameter(i->second_.offset_, sizeof(Vector3), &vector);
-    }
-    else
-    {
-        ConstantBuffer* buffer = shaderProgram_->psConstantBuffers_[i->second_.buffer_];
-        if (!buffer->IsDirty())
-            dirtyConstantBuffers_.Push(buffer);
-        buffer->SetParameter(i->second_.offset_, sizeof(Vector3), &vector);
-    }
+    ConstantBuffer* buffer = i->second_.bufferPtr_;
+    if (!buffer->IsDirty())
+        dirtyConstantBuffers_.Push(buffer);
+    buffer->SetParameter(i->second_.offset_, sizeof(Vector3), &vector);
 }
 
 void Graphics::SetShaderParameter(StringHash param, const Matrix4& matrix)
@@ -1299,20 +1229,10 @@ void Graphics::SetShaderParameter(StringHash param, const Matrix4& matrix)
     if (!shaderProgram_ || (i = shaderProgram_->parameters_.Find(param)) == shaderProgram_->parameters_.End())
         return;
 
-    if (i->second_.type_ == VS)
-    {
-        ConstantBuffer* buffer = shaderProgram_->vsConstantBuffers_[i->second_.buffer_];
-        if (!buffer->IsDirty())
-            dirtyConstantBuffers_.Push(buffer);
-        buffer->SetParameter(i->second_.offset_, sizeof(Matrix4), &matrix);
-    }
-    else
-    {
-        ConstantBuffer* buffer = shaderProgram_->psConstantBuffers_[i->second_.buffer_];
-        if (!buffer->IsDirty())
-            dirtyConstantBuffers_.Push(buffer);
-        buffer->SetParameter(i->second_.offset_, sizeof(Matrix4), &matrix);
-    }
+    ConstantBuffer* buffer = i->second_.bufferPtr_;
+    if (!buffer->IsDirty())
+        dirtyConstantBuffers_.Push(buffer);
+    buffer->SetParameter(i->second_.offset_, sizeof(Matrix4), &matrix);
 }
 
 void Graphics::SetShaderParameter(StringHash param, const Vector4& vector)
@@ -1321,20 +1241,10 @@ void Graphics::SetShaderParameter(StringHash param, const Vector4& vector)
     if (!shaderProgram_ || (i = shaderProgram_->parameters_.Find(param)) == shaderProgram_->parameters_.End())
         return;
 
-    if (i->second_.type_ == VS)
-    {
-        ConstantBuffer* buffer = shaderProgram_->vsConstantBuffers_[i->second_.buffer_];
-        if (!buffer->IsDirty())
-            dirtyConstantBuffers_.Push(buffer);
-        buffer->SetParameter(i->second_.offset_, sizeof(Vector4), &vector);
-    }
-    else
-    {
-        ConstantBuffer* buffer = shaderProgram_->psConstantBuffers_[i->second_.buffer_];
-        if (!buffer->IsDirty())
-            dirtyConstantBuffers_.Push(buffer);
-        buffer->SetParameter(i->second_.offset_, sizeof(Vector4), &vector);
-    }
+    ConstantBuffer* buffer = i->second_.bufferPtr_;
+    if (!buffer->IsDirty())
+        dirtyConstantBuffers_.Push(buffer);
+    buffer->SetParameter(i->second_.offset_, sizeof(Vector4), &vector);
 }
 
 void Graphics::SetShaderParameter(StringHash param, const Matrix3x4& matrix)
@@ -1343,20 +1253,10 @@ void Graphics::SetShaderParameter(StringHash param, const Matrix3x4& matrix)
     if (!shaderProgram_ || (i = shaderProgram_->parameters_.Find(param)) == shaderProgram_->parameters_.End())
         return;
 
-    if (i->second_.type_ == VS)
-    {
-        ConstantBuffer* buffer = shaderProgram_->vsConstantBuffers_[i->second_.buffer_];
-        if (!buffer->IsDirty())
-            dirtyConstantBuffers_.Push(buffer);
-        buffer->SetParameter(i->second_.offset_, sizeof(Matrix3x4), &matrix);
-    }
-    else
-    {
-        ConstantBuffer* buffer = shaderProgram_->psConstantBuffers_[i->second_.buffer_];
-        if (!buffer->IsDirty())
-            dirtyConstantBuffers_.Push(buffer);
-        buffer->SetParameter(i->second_.offset_, sizeof(Matrix3x4), &matrix);
-    }
+    ConstantBuffer* buffer = i->second_.bufferPtr_;
+    if (!buffer->IsDirty())
+        dirtyConstantBuffers_.Push(buffer);
+    buffer->SetParameter(i->second_.offset_, sizeof(Matrix3x4), &matrix);
 }
 
 void Graphics::SetShaderParameter(StringHash param, const Variant& value)

+ 21 - 12
Source/Urho3D/Graphics/Direct3D11/D3D11ShaderProgram.h

@@ -31,23 +31,13 @@ namespace Urho3D
 {
 
 /// Combined information for specific vertex and pixel shaders.
-class ShaderProgram : public RefCounted
+class URHO3D_API ShaderProgram : public RefCounted
 {
 public:
     /// Construct.
     ShaderProgram(Graphics* graphics, ShaderVariation* vertexShader, ShaderVariation* pixelShader)
     {
-        const HashMap<StringHash, ShaderParameter>& vsParams = vertexShader->GetParameters();
-        for (HashMap<StringHash, ShaderParameter>::ConstIterator i = vsParams.Begin(); i != vsParams.End(); ++i)
-            parameters_[i->first_] = i->second_;
-
-        const HashMap<StringHash, ShaderParameter>& psParams = pixelShader->GetParameters();
-        for (HashMap<StringHash, ShaderParameter>::ConstIterator i = psParams.Begin(); i != psParams.End(); ++i)
-            parameters_[i->first_] = i->second_;
-
-        // Optimize shader parameter lookup by rehashing to next power of two
-        parameters_.Rehash(NextPowerOfTwo(parameters_.Size()));
-
+        // Create needed constant buffers
         const unsigned* vsBufferSizes = vertexShader->GetConstantBufferSizes();
         for (unsigned i = 0; i < MAX_SHADER_PARAMETER_GROUPS; ++i)
         {
@@ -61,6 +51,25 @@ public:
             if (psBufferSizes[i])
                 psConstantBuffers_[i] = graphics->GetOrCreateConstantBuffer(PS, i, psBufferSizes[i]);
         }
+
+        // Copy parameters. Add direct links to constant buffers.
+        const HashMap<StringHash, ShaderParameter>& vsParams = vertexShader->GetParameters();
+        for (HashMap<StringHash, ShaderParameter>::ConstIterator i = vsParams.Begin(); i != vsParams.End(); ++i)
+        {
+            parameters_[i->first_] = i->second_;
+            parameters_[i->first_].bufferPtr_ = vsConstantBuffers_[i->second_.buffer_].Get();
+        }
+
+        const HashMap<StringHash, ShaderParameter>& psParams = pixelShader->GetParameters();
+        for (HashMap<StringHash, ShaderParameter>::ConstIterator i = psParams.Begin(); i != psParams.End(); ++i)
+        {
+            parameters_[i->first_] = i->second_;
+            parameters_[i->first_].bufferPtr_ = psConstantBuffers_[i->second_.buffer_].Get();
+        }
+
+        // Optimize shader parameter lookup by rehashing to next power of two
+        parameters_.Rehash(NextPowerOfTwo(parameters_.Size()));
+
     }
 
     /// Destruct.

+ 9 - 4
Source/Urho3D/Graphics/Direct3D11/D3D11ShaderVariation.h

@@ -31,6 +31,7 @@
 namespace Urho3D
 {
 
+class ConstantBuffer;
 class Shader;
 
 /// %Shader parameter definition.
@@ -41,17 +42,19 @@ struct ShaderParameter
         type_(VS),
         buffer_(0),
         offset_(0),
-        size_(0)
+        size_(0),
+        bufferPtr_(0)
     {
     }
     
     /// Construct with parameters.
-    ShaderParameter(ShaderType type, const String& name, unsigned buffer, unsigned offset, unsigned size) :
+    ShaderParameter(ShaderType type, const String& name, unsigned buffer, unsigned offset, unsigned size, ConstantBuffer* ptr = 0) :
         type_(type),
         name_(name),
         buffer_(buffer),
         offset_(offset),
-        size_(size)
+        size_(size),
+        bufferPtr_(ptr)
     {
     }
     
@@ -63,8 +66,10 @@ struct ShaderParameter
     unsigned buffer_;
     /// Offset in constant buffer.
     unsigned offset_;
-    /// Size of parameter in bytes
+    /// Size of parameter in bytes.
     unsigned size_;
+    /// Constant buffer pointer. Defined only in shader programs.
+    ConstantBuffer* bufferPtr_;
 };
 
 /// Vertex or pixel shader on the GPU.

+ 1 - 1
Source/Urho3D/Graphics/Direct3D11/D3D11Texture3D.cpp

@@ -499,7 +499,7 @@ bool Texture3D::GetData(unsigned level, void* dest) const
     graphics_->GetImpl()->GetDeviceContext()->Map((ID3D11Resource*)stagingTexture, 0, D3D11_MAP_READ, 0, &mappedData);
     if (mappedData.pData)
     {
-        for (unsigned page = 0; page < levelDepth; ++page)
+        for (int page = 0; page < levelDepth; ++page)
         {
             for (unsigned row = 0; row < numRows; ++row)
             {