ソースを参照

Check if shader uses uniforms outside buffer and invalidate all parameter groups in that case, when switching shaders. Add define in Uniforms.glsl which allows to disable constant buffers on OpenGL 3, as using them may actually be slower.

Lasse Öörni 10 年 前
コミット
2cefd437de

+ 2 - 6
Source/Urho3D/Graphics/OpenGL/OGLGraphics.cpp

@@ -1218,14 +1218,9 @@ void Graphics::SetShaders(ShaderVariation* vs, ShaderVariation* ps)
     }
     
     // Update the clip plane uniform on GL3, and set constant buffers
-    bool clearAllParameterGroups = true;
-
     #ifndef GL_ES_VERSION_2_0
     if (gl3Support && shaderProgram_)
     {
-        // When using OpenGL 3, only clear the parameter groups that change their buffer binding
-        clearAllParameterGroups = false;
-
         const SharedPtr<ConstantBuffer>* constantBuffers = shaderProgram_->GetConstantBuffers();
         for (unsigned i = 0; i < MAX_SHADER_PARAMETER_GROUPS * 2; ++i)
         {
@@ -1242,7 +1237,8 @@ void Graphics::SetShaders(ShaderVariation* vs, ShaderVariation* ps)
     }
     #endif
     
-    if (clearAllParameterGroups)
+    // If shader has uniforms outside constant buffers, reset all parameter sources now, as those uniforms are per-program
+    if (shaderProgram_ && shaderProgram_->HasIndividualUniforms())
         ClearParameterSources();
 
     // Store shader combination if shader dumping in progress

+ 8 - 3
Source/Urho3D/Graphics/OpenGL/OGLShaderProgram.cpp

@@ -45,7 +45,8 @@ const char* shaderParameterGroups[] = {
 ShaderProgram::ShaderProgram(Graphics* graphics, ShaderVariation* vertexShader, ShaderVariation* pixelShader) :
     GPUObject(graphics),
     vertexShader_(vertexShader),
-    pixelShader_(pixelShader)
+    pixelShader_(pixelShader),
+    individualUniforms_(false)
 {
     for (unsigned i = 0; i < MAX_TEXTURE_UNITS; ++i)
         useTextureUnit_[i] = false;
@@ -89,6 +90,7 @@ void ShaderProgram::Release()
             useTextureUnit_[i] = false;
         for (unsigned i = 0; i < MAX_SHADER_PARAMETER_GROUPS; ++i)
             constantBuffers_[i].Reset();
+        individualUniforms_ = false;
     }
 }
 
@@ -223,6 +225,7 @@ bool ShaderProgram::Link()
     #endif
 
     // Check for shader parameters and texture units
+    individualUniforms_ = false;
     for (int i = 0; i < uniformCount; ++i)
     {
         unsigned type;
@@ -261,12 +264,14 @@ bool ShaderProgram::Link()
                 if (blockIndex >= 0)
                 {
                     newParam.location_ = blockOffset;
-                    newParam.buffer_ = blockToBinding[blockIndex];
-                    newParam.bufferPtr_ = constantBuffers_[newParam.buffer_];
+                    newParam.bufferPtr_ = constantBuffers_[blockToBinding[blockIndex]];
                 }
             }
             #endif
 
+            if (!newParam.bufferPtr_)
+                individualUniforms_ = true;
+
             if (newParam.location_ >= 0)
                 shaderParameters_[StringHash(paramName)] = newParam;
         }

+ 4 - 3
Source/Urho3D/Graphics/OpenGL/OGLShaderProgram.h

@@ -39,7 +39,6 @@ struct ShaderParameter
 {
     /// Construct with defaults.
     ShaderParameter() :
-        buffer_(M_MAX_UNSIGNED),
         bufferPtr_(0)
     {
     }
@@ -48,8 +47,6 @@ struct ShaderParameter
     int location_;
     /// Element type.
     unsigned type_;
-    /// Constant buffer binding index. M_MAX_UNSIGNED if is a free-standing uniform.
-    unsigned buffer_;
     /// Constant buffer pointer.
     ConstantBuffer* bufferPtr_;
 };
@@ -83,6 +80,8 @@ public:
     const ShaderParameter* GetParameter(StringHash param) const;
     /// Return linker output.
     const String& GetLinkerOutput() const { return linkerOutput_; }
+    /// Return whether has uniforms outside constant buffers.
+    bool HasIndividualUniforms() const { return individualUniforms_; }
     /// Return all constant buffers.
     const SharedPtr<ConstantBuffer>* GetConstantBuffers() const { return &constantBuffers_[0]; }
     
@@ -99,6 +98,8 @@ private:
     SharedPtr<ConstantBuffer> constantBuffers_[MAX_SHADER_PARAMETER_GROUPS * 2];
     /// Shader link error string.
     String linkerOutput_;
+    /// Uniforms outside buffers flag.
+    bool individualUniforms_;
 };
 
 }

+ 8 - 1
bin/CoreData/Shaders/GLSL/Uniforms.glsl

@@ -1,4 +1,8 @@
-#ifndef GL3
+// Use constant buffers if available. Comment out to revert to individual uniforms
+// which may be faster also on OpenGL 3
+#define USE_CBUFFERS
+
+#if !defined(GL3) || !defined(USE_CBUFFERS)
 
 // OpenGL 2 uniforms (no constant buffers)
 
@@ -39,6 +43,9 @@ uniform mat4 cZone;
 #ifdef NUMVERTEXLIGHTS
     uniform vec4 cVertexLights[4*3];
 #endif
+#ifdef GL3
+uniform vec4 cClipPlane;
+#endif
 #endif
 
 #ifdef COMPILEPS