diff --git a/glslang/MachineIndependent/ShaderLang.cpp b/glslang/MachineIndependent/ShaderLang.cpp index 5fd6f421..b6af0374 100644 --- a/glslang/MachineIndependent/ShaderLang.cpp +++ b/glslang/MachineIndependent/ShaderLang.cpp @@ -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(); } diff --git a/glslang/MachineIndependent/reflection.cpp b/glslang/MachineIndependent/reflection.cpp index 19e08e16..d3e04af7 100644 --- a/glslang/MachineIndependent/reflection.cpp +++ b/glslang/MachineIndependent/reflection.cpp @@ -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); diff --git a/glslang/MachineIndependent/reflection.h b/glslang/MachineIndependent/reflection.h index 42f0ccd8..5d930c7a 100644 --- a/glslang/MachineIndependent/reflection.h +++ b/glslang/MachineIndependent/reflection.h @@ -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 diff --git a/glslang/Public/ShaderLang.h b/glslang/Public/ShaderLang.h index c45df689..f49e7b03 100644 --- a/glslang/Public/ShaderLang.h +++ b/glslang/Public/ShaderLang.h @@ -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: