Add support for querying vertex attributes in reflection API
authorThomas Perl <m@thp.io>
Tue, 17 May 2016 11:59:13 +0000 (13:59 +0200)
committerThomas Perl <m@thp.io>
Thu, 19 May 2016 07:16:19 +0000 (09:16 +0200)
glslang/MachineIndependent/ShaderLang.cpp
glslang/MachineIndependent/reflection.cpp
glslang/MachineIndependent/reflection.h
glslang/Public/ShaderLang.h

index 5fd6f42..b6af037 100644 (file)
@@ -1572,6 +1572,9 @@ int TProgram::getUniformBlockIndex(int index)        { return reflection->getUni
 int TProgram::getUniformType(int index)              { return reflection->getUniform(index).glDefineType; }
 int TProgram::getUniformBufferOffset(int index)      { return reflection->getUniform(index).offset; }
 int TProgram::getUniformArraySize(int index)         { return reflection->getUniform(index).size; }
+int TProgram::getNumLiveAttributes()                 { return reflection->getNumAttributes(); }
+const char* TProgram::getAttributeName(int index)    { return reflection->getAttribute(index).name.c_str(); }
+int TProgram::getAttributeType(int index)            { return reflection->getAttribute(index).glDefineType; }
 
 void TProgram::dumpReflection()                      { reflection->dump(); }
 
index 19e08e1..d3e04af 100644 (file)
@@ -108,6 +108,22 @@ public:
         }
     }
 
+    void addAttribute(const TIntermSymbol& base)
+    {
+        if (processedDerefs.find(&base) == processedDerefs.end()) {
+            processedDerefs.insert(&base);
+
+            const TString &name = base.getName();
+            const TType &type = base.getType();
+
+            TReflection::TNameToIndex::const_iterator it = reflection.nameToIndex.find(name);
+            if (it == reflection.nameToIndex.end()) {
+                reflection.nameToIndex[name] = (int)reflection.indexToAttribute.size();
+                reflection.indexToAttribute.push_back(TObjectReflection(name, 0, mapToGlType(type), 0, 0));
+            }
+        }
+    }
+
     // Lookup or calculate the offset of a block member, using the recursively
     // defined block offset rules.
     int getOffset(const TType& type, int index)
@@ -671,6 +687,9 @@ void TLiveTraverser::visitSymbol(TIntermSymbol* base)
 {
     if (base->getQualifier().storage == EvqUniform)
         addUniform(*base);
+
+    if (intermediate.getStage() == EShLangVertex && base->getQualifier().isPipeInput())
+        addAttribute(*base);
 }
 
 // To prune semantically dead paths.
@@ -728,6 +747,11 @@ void TReflection::dump()
         indexToUniformBlock[i].dump();
     printf("\n");
 
+    printf("Vertex attribute reflection:\n");
+    for (size_t i = 0; i < indexToAttribute.size(); ++i)
+        indexToAttribute[i].dump();
+    printf("\n");
+
     //printf("Live names\n");
     //for (TNameToIndex::const_iterator it = nameToIndex.begin(); it != nameToIndex.end(); ++it)
     //    printf("%s: %d\n", it->first.c_str(), it->second);
index 42f0ccd..5d930c7 100644 (file)
@@ -93,7 +93,17 @@ public:
             return badReflection;
     }
 
-    // for mapping any name to its index (both block names and uniforms names)
+    // for mapping an attribute index to the attribute's description
+    int getNumAttributes() { return (int)indexToAttribute.size(); }
+    const TObjectReflection& getAttribute(int i) const
+    {
+        if (i >= 0 && i < (int)indexToAttribute.size())
+            return indexToAttribute[i];
+        else
+            return badReflection;
+    }
+
+    // for mapping any name to its index (block names, uniform names and attribute names)
     int getIndex(const char* name) const 
     {
         TNameToIndex::const_iterator it = nameToIndex.find(name);
@@ -116,6 +126,7 @@ protected:
     TNameToIndex nameToIndex;        // maps names to indexes; can hold all types of data: uniform/buffer and which function names have been processed
     TMapIndexToReflection indexToUniform;
     TMapIndexToReflection indexToUniformBlock;
+    TMapIndexToReflection indexToAttribute;
 };
 
 } // end namespace glslang
index c45df68..f49e7b0 100644 (file)
@@ -461,6 +461,9 @@ public:
     int getUniformType(int index);                   // can be used for glGetActiveUniformsiv(GL_UNIFORM_TYPE)
     int getUniformBufferOffset(int index);           // can be used for glGetActiveUniformsiv(GL_UNIFORM_OFFSET)
     int getUniformArraySize(int index);              // can be used for glGetActiveUniformsiv(GL_UNIFORM_SIZE)
+    int getNumLiveAttributes();                      // can be used for glGetProgramiv(GL_ACTIVE_ATTRIBUTES)
+    const char *getAttributeName(int index);         // can be used for glGetActiveAttrib()
+    int getAttributeType(int index);                 // can be used for glGetActiveAttrib()
     void dumpReflection();
 
 protected: