Explorar o código

Optimize Shader::SanitateDefines(). In debug mode, check that shader code uses each define.

Lasse Öörni %!s(int64=12) %!d(string=hai) anos
pai
achega
1a1fe9a24f

+ 15 - 3
Source/Engine/Graphics/OpenGL/OGLShaderVariation.cpp

@@ -23,6 +23,7 @@
 #include "Precompiled.h"
 #include "Graphics.h"
 #include "GraphicsImpl.h"
+#include "Log.h"
 #include "Shader.h"
 #include "ShaderProgram.h"
 #include "ShaderVariation.h"
@@ -104,17 +105,28 @@ bool ShaderVariation::Create()
         return false;
     }
     
+    const String& originalShaderCode = owner_->GetSourceCode(shaderType_);
     String shaderCode;
-    
     // Distinguish between VS and PS compile in case the shader code wants to include/omit different things
     shaderCode += shaderType_ == VS ? "#define COMPILEVS\n" : "#define COMPILEPS\n";
     
     // Prepend the defines to the shader code
     Vector<String> defineVec = defines_.Split(' ');
     for (unsigned i = 0; i < defineVec.Size(); ++i)
-        shaderCode += "#define " + defineVec[i].Replaced('=', ' ') + "\n";
+    {
+        // Add extra space for the checking code below
+        String defineString = "#define " + defineVec[i].Replaced('=', ' ') + " \n";
+        shaderCode += defineString;
+        
+        // In debug mode, check that all defines are referenced by the shader code
+        #ifdef _DEBUG
+        String defineCheck = defineString.Substring(8, defineString.Find(' ', 8) - 8);
+        if (originalShaderCode.Find(defineCheck) == String::NPOS)
+            LOGWARNING("Shader " + GetName() + " does not use the define " + defineCheck);
+        #endif
+    }
     
-    shaderCode += owner_->GetSourceCode(shaderType_);
+    shaderCode += originalShaderCode;
     
     const char* shaderCStr = shaderCode.CString();
     glShaderSource(object_, 1, &shaderCStr, 0);

+ 21 - 1
Source/Engine/Graphics/Shader.cpp

@@ -190,9 +190,29 @@ bool Shader::ProcessSource(String& code, Deserializer& source)
 String Shader::SanitateDefines(const String& definesIn)
 {
     String ret;
+    ret.Reserve(definesIn.Length());
+    
     unsigned numSpaces = 0;
+    unsigned start = 0, end = definesIn.Length();
     
+    // Trim spaces from start & begin. Do not use String::Trimmed() as we also need to trim spaces from the middle
     for (unsigned i = 0; i < definesIn.Length(); ++i)
+    {
+        if (definesIn[i] != ' ')
+        {
+            start = i;
+            break;
+        }
+    }
+    for (unsigned i = definesIn.Length() - 1; i < definesIn.Length(); --i)
+    {
+        if (definesIn[i] != ' ')
+        {
+            end = i + 1;
+            break;
+        }
+    }
+    for (unsigned i = start; i < end; ++i)
     {
         // Ensure only one space in a row
         if (definesIn[i] == ' ')
@@ -204,7 +224,7 @@ String Shader::SanitateDefines(const String& definesIn)
             ret += definesIn[i];
     }
     
-    return ret.Trimmed();
+    return ret;
 }
 
 }