Add option to reflect buffer blocks & variables separately to uniforms
authorbaldurk <baldurk@baldurk.org>
Wed, 30 Jan 2019 14:18:43 +0000 (14:18 +0000)
committerbaldurk <baldurk@baldurk.org>
Mon, 4 Feb 2019 12:02:59 +0000 (12:02 +0000)
* Also note the uniform indices of atomic counter buffers

15 files changed:
StandAlone/StandAlone.cpp
Test/baseResults/hlsl.automap.frag.out
Test/baseResults/hlsl.reflection.binding.frag.out
Test/baseResults/hlsl.reflection.vert.out
Test/baseResults/hlsl.shift.per-set.frag.out
Test/baseResults/reflection.frag.out
Test/baseResults/reflection.options.frag.out
Test/baseResults/reflection.options.vert.out
Test/baseResults/reflection.vert.out
Test/reflection.options.vert
Test/runtests
glslang/MachineIndependent/ShaderLang.cpp
glslang/MachineIndependent/reflection.cpp
glslang/MachineIndependent/reflection.h
glslang/Public/ShaderLang.h

index 7588320..52fd80c 100644 (file)
@@ -530,6 +530,8 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
                         ReflectOptions |= EShReflectionBasicArraySuffix;
                     } else if (lowerword == "reflect-intermediate-io") {
                         ReflectOptions |= EShReflectionIntermediateIO;
+                    } else if (lowerword == "reflect-separate-buffers") {
+                        ReflectOptions |= EShReflectionSeparateBuffers;
                     } else if (lowerword == "resource-set-bindings" ||  // synonyms
                                lowerword == "resource-set-binding"  ||
                                lowerword == "rsb") {
@@ -1529,6 +1531,7 @@ void usage()
            "  --reflect-basic-array-suffix      arrays of basic types will have trailing [0]\n"
            "  --reflect-intermediate-io         reflection includes inputs/outputs of linked shaders\n"
            "                                    rather than just vertex/fragment\n"
+           "  --reflect-separate-buffers        reflect buffer variables and blocks separately to uniforms\n"
            "  --resource-set-binding [stage] name set binding\n"
            "                                    set descriptor set and binding for\n"
            "                                    individual resources\n"
index 51a15db..fb914ec 100644 (file)
@@ -25,6 +25,10 @@ u6: offset -1, type ffffffff, size 0, index -1, binding 46, stages 0, numMembers
 cb: offset -1, type ffffffff, size 4, index -1, binding 51, stages 0, numMembers 1
 tb: offset -1, type ffffffff, size 4, index -1, binding 17, stages 0, numMembers 1
 
+Buffer variable reflection:
+
+Buffer block reflection:
+
 Pipeline input reflection:
 
 Pipeline output reflection:
index da452cf..8d5743e 100644 (file)
@@ -15,6 +15,10 @@ Uniform block reflection:
 cbuff1: offset -1, type ffffffff, size 24, index -1, binding 2, stages 0, numMembers 3
 cbuff2: offset -1, type ffffffff, size 24, index -1, binding 3, stages 0, numMembers 3
 
+Buffer variable reflection:
+
+Buffer block reflection:
+
 Pipeline input reflection:
 
 Pipeline output reflection:
index 97c8466..c936748 100644 (file)
@@ -67,6 +67,10 @@ nested: offset -1, type ffffffff, size 32, index -1, binding -1, stages 0, numMe
 abl: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0, numMembers 1
 abl2: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0, numMembers 1
 
+Buffer variable reflection:
+
+Buffer block reflection:
+
 Pipeline input reflection:
 attributeFloat: offset 0, type 1406, size 0, index 0, binding -1, stages 0
 attributeFloat2: offset 0, type 8b50, size 0, index 0, binding -1, stages 0
index a6aa7a0..a0eb574 100644 (file)
@@ -226,6 +226,10 @@ u6: offset -1, type ffffffff, size 0, index -1, binding 34, stages 0, numMembers
 cb: offset -1, type ffffffff, size 4, index -1, binding 51, stages 0, numMembers 1
 tb: offset -1, type ffffffff, size 4, index -1, binding 27, stages 0, numMembers 1
 
+Buffer variable reflection:
+
+Buffer block reflection:
+
 Pipeline input reflection:
 
 Pipeline output reflection:
index d3d90a2..65a8786 100644 (file)
@@ -3,6 +3,10 @@ Uniform reflection:
 
 Uniform block reflection:
 
+Buffer variable reflection:
+
+Buffer block reflection:
+
 Pipeline input reflection:
 
 Pipeline output reflection:
index d0fe56e..a0cecef 100644 (file)
@@ -3,6 +3,10 @@ Uniform reflection:
 
 Uniform block reflection:
 
+Buffer variable reflection:
+
+Buffer block reflection:
+
 Pipeline input reflection:
 inval: offset 0, type 1406, size 0, index 0, binding -1, stages 0
 
index b9247a0..add7396 100644 (file)
@@ -1,5 +1,13 @@
 reflection.options.vert
 Uniform reflection:
+UBO.verts[0].position[0]: offset 0, type 1406, size 1, index 0, binding -1, stages 1, arrayStride 4, topLevelArrayStride 24
+UBO.verts[1].position[0]: offset 24, type 1406, size 1, index 0, binding -1, stages 1, arrayStride 4, topLevelArrayStride 24
+UBO.flt[0]: offset 48, type 1406, size 8, index 0, binding -1, stages 1, arrayStride 4, topLevelArrayStride 4
+
+Uniform block reflection:
+UBO: offset -1, type ffffffff, size 80, index -1, binding -1, stages 0, numMembers 5
+
+Buffer variable reflection:
 t[0].v[0].position[0]: offset 0, type 1406, size 3, index 0, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
 t[0].v[1].position[0]: offset 24, type 1406, size 3, index 0, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
 t[0].v[2].position[0]: offset 48, type 1406, size 3, index 0, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72
@@ -10,7 +18,7 @@ MultipleArrays.tri[0].v[0].position[0]: offset 0, type 1406, size 1, index 1, bi
 MultipleArrays.vert[0].position[0]: offset 360, type 1406, size 1, index 1, binding -1, stages 1, arrayStride 4, topLevelArrayStride 24
 MultipleArrays.f[0]: offset 480, type 1406, size 5, index 1, binding -1, stages 1, arrayStride 4, topLevelArrayStride 4
 
-Uniform block reflection:
+Buffer block reflection:
 VertexCollection: offset -1, type ffffffff, size 360, index -1, binding -1, stages 0, numMembers 6
 MultipleArrays: offset -1, type ffffffff, size 500, index -1, binding -1, stages 0, numMembers 9
 
index a7793c7..6baa8ac 100644 (file)
@@ -146,6 +146,10 @@ buf4: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0, numMembe
 nested2: offset -1, type ffffffff, size 208, index -1, binding -1, stages 0, numMembers 15
 VertexCollection: offset -1, type ffffffff, size 360, index -1, binding -1, stages 0, numMembers 30
 
+Buffer variable reflection:
+
+Buffer block reflection:
+
 Pipeline input reflection:
 attributeFloat: offset 0, type 1406, size 0, index 0, binding -1, stages 0
 attributeFloat2: offset 0, type 8b50, size 0, index 0, binding -1, stages 0
index cfb2b0d..001537e 100644 (file)
@@ -19,6 +19,11 @@ buffer MultipleArrays {
     float f[5];\r
 } multiarray;\r
 \r
+uniform UBO {\r
+    VertexInfo verts[2];\r
+    float flt[8];\r
+} ubo;\r
+\r
 out float outval;\r
 \r
 void main()\r
@@ -30,6 +35,8 @@ void main()
     f += multiarray.tri[gl_InstanceID].v[0].position[0];\r
     f += multiarray.vert[gl_InstanceID].position[0];\r
     f += multiarray.f[gl_InstanceID];\r
+    f += ubo.verts[gl_InstanceID].position[0];\r
+    f += ubo.flt[gl_InstanceID];\r
     TriangleInfo tlocal[5] = t;\r
     outval = f;\r
 }\r
index 44d3dc3..d370503 100755 (executable)
@@ -32,11 +32,11 @@ diff -b $BASEDIR/badMacroArgs.frag.out $TARGETDIR/badMacroArgs.frag.out || HASER
 echo Running reflection...
 $EXE -l -q -C reflection.vert > $TARGETDIR/reflection.vert.out
 diff -b $BASEDIR/reflection.vert.out $TARGETDIR/reflection.vert.out || HASERROR=1
-$EXE -l -q -C --reflect-strict-array-suffix --reflect-basic-array-suffix --reflect-intermediate-io reflection.options.vert > $TARGETDIR/reflection.options.vert.out
+$EXE -l -q -C --reflect-strict-array-suffix --reflect-basic-array-suffix --reflect-intermediate-io --reflect-separate-buffers reflection.options.vert > $TARGETDIR/reflection.options.vert.out
 diff -b $BASEDIR/reflection.options.vert.out $TARGETDIR/reflection.options.vert.out || HASERROR=1
 $EXE -l -q -C reflection.frag > $TARGETDIR/reflection.frag.out
 diff -b $BASEDIR/reflection.frag.out $TARGETDIR/reflection.frag.out || HASERROR=1
-$EXE -l -q -C --reflect-strict-array-suffix --reflect-basic-array-suffix --reflect-intermediate-io reflection.frag > $TARGETDIR/reflection.options.frag.out
+$EXE -l -q -C --reflect-strict-array-suffix --reflect-basic-array-suffix --reflect-intermediate-io --reflect-separate-buffers reflection.frag > $TARGETDIR/reflection.options.frag.out
 diff -b $BASEDIR/reflection.options.frag.out $TARGETDIR/reflection.options.frag.out || HASERROR=1
 $EXE -D -Od -e flizv -l -q -C -V -Od hlsl.reflection.vert > $TARGETDIR/hlsl.reflection.vert.out
 diff -b $BASEDIR/hlsl.reflection.vert.out $TARGETDIR/hlsl.reflection.vert.out || HASERROR=1
index a32d605..63d3fc4 100755 (executable)
@@ -2001,14 +2001,20 @@ bool TProgram::buildReflection(int opts)
 unsigned TProgram::getLocalSize(int dim) const                      { return reflection->getLocalSize(dim); }
 int TProgram::getReflectionIndex(const char* name) const            { return reflection->getIndex(name); }
 
-int TProgram::getNumUniformVariables() const                        { return reflection->getNumUniforms(); }
-const TObjectReflection& TProgram::getUniform(int index) const      { return reflection->getUniform(index); }
-int TProgram::getNumUniformBlocks() const                           { return reflection->getNumUniformBlocks(); }
-const TObjectReflection& TProgram::getUniformBlock(int index) const { return reflection->getUniformBlock(index); }
-int TProgram::getNumPipeInputs() const                              { return reflection->getNumPipeInputs(); }
-const TObjectReflection& TProgram::getPipeInput(int index) const    { return reflection->getPipeInput(index); }
-int TProgram::getNumPipeOutputs() const                             { return reflection->getNumPipeOutputs(); }
-const TObjectReflection& TProgram::getPipeOutput(int index) const   { return reflection->getPipeOutput(index); }
+int TProgram::getNumUniformVariables() const                          { return reflection->getNumUniforms(); }
+const TObjectReflection& TProgram::getUniform(int index) const        { return reflection->getUniform(index); }
+int TProgram::getNumUniformBlocks() const                             { return reflection->getNumUniformBlocks(); }
+const TObjectReflection& TProgram::getUniformBlock(int index) const   { return reflection->getUniformBlock(index); }
+int TProgram::getNumPipeInputs() const                                { return reflection->getNumPipeInputs(); }
+const TObjectReflection& TProgram::getPipeInput(int index) const      { return reflection->getPipeInput(index); }
+int TProgram::getNumPipeOutputs() const                               { return reflection->getNumPipeOutputs(); }
+const TObjectReflection& TProgram::getPipeOutput(int index) const     { return reflection->getPipeOutput(index); }
+int TProgram::getNumBufferVariables() const                           { return reflection->getNumBufferVariables(); }
+const TObjectReflection& TProgram::getBufferVariable(int index) const { return reflection->getBufferVariable(index); }
+int TProgram::getNumBufferBlocks() const                              { return reflection->getNumStorageBuffers(); }
+const TObjectReflection& TProgram::getBufferBlock(int index) const    { return reflection->getStorageBufferBlock(index); }
+int TProgram::getNumAtomicCounters() const                            { return reflection->getNumAtomicCounters(); }
+const TObjectReflection& TProgram::getAtomicCounter(int index) const  { return reflection->getAtomicCounter(index); }
 
 void TProgram::dumpReflection()                      { reflection->dump(); }
 
index b235b46..a7d9b13 100644 (file)
@@ -93,7 +93,8 @@ public:
             // Use a degenerate (empty) set of dereferences to immediately put as at the end of
             // the dereference change expected by blowUpActiveAggregate.
             TList<TIntermBinary*> derefs;
-            blowUpActiveAggregate(base.getType(), base.getName(), derefs, derefs.end(), -1, -1, 0, 0);
+            blowUpActiveAggregate(base.getType(), base.getName(), derefs, derefs.end(), -1, -1, 0, 0,
+                                  base.getQualifier().storage);
         }
     }
 
@@ -268,7 +269,7 @@ public:
     // A value of 0 for arraySize will mean to use the full array's size.
     void blowUpActiveAggregate(const TType& baseType, const TString& baseName, const TList<TIntermBinary*>& derefs,
                                TList<TIntermBinary*>::const_iterator deref, int offset, int blockIndex, int arraySize,
-                               int topLevelArrayStride)
+                               int topLevelArrayStride, TStorageQualifier baseStorage)
     {
         // when strictArraySuffix is enabled, we closely follow the rules from ARB_program_interface_query.
         // Broadly:
@@ -305,7 +306,7 @@ public:
                     ++nextDeref;
                     TType derefType(*terminalType, 0);
                     blowUpActiveAggregate(derefType, newBaseName, derefs, nextDeref, offset, blockIndex, arraySize,
-                                          topLevelArrayStride);
+                                          topLevelArrayStride, baseStorage);
 
                     if (offset >= 0)
                         offset += stride;
@@ -376,7 +377,7 @@ public:
                         offset = baseOffset + stride * i;
 
                     blowUpActiveAggregate(derefType, newBaseName, derefs, derefs.end(), offset, blockIndex, 0,
-                                          topLevelArrayStride);
+                                          topLevelArrayStride, baseStorage);
                 }
             } else {
                 // Visit all members of this aggregate, and for each one,
@@ -404,7 +405,7 @@ public:
                     }
 
                     blowUpActiveAggregate(derefType, newBaseName, derefs, derefs.end(), offset, blockIndex, 0,
-                                          arrayStride);
+                                          arrayStride, baseStorage);
                 }
             }
 
@@ -423,22 +424,26 @@ public:
         if (arraySize == 0)
             arraySize = mapToGlArraySize(*terminalType);
 
+        TReflection::TMapIndexToReflection& variables = reflection.GetVariableMapForStorage(baseStorage);
+
         TReflection::TNameToIndex::const_iterator it = reflection.nameToIndex.find(name.c_str());
         if (it == reflection.nameToIndex.end()) {
-            reflection.nameToIndex[name.c_str()] = (int)reflection.indexToUniform.size();
-
-            reflection.indexToUniform.push_back(TObjectReflection(name.c_str(), *terminalType, offset,
-                                                                  mapToGlType(*terminalType),
-                                                                  arraySize, blockIndex));
+            int uniformIndex = (int)variables.size();
+            reflection.nameToIndex[name.c_str()] = uniformIndex;
+            variables.push_back(TObjectReflection(name.c_str(), *terminalType, offset, mapToGlType(*terminalType),
+                                                  arraySize, blockIndex));
             if (terminalType->isArray()) {
-                reflection.indexToUniform.back().arrayStride = getArrayStride(baseType, *terminalType);
+                variables.back().arrayStride = getArrayStride(baseType, *terminalType);
                 if (topLevelArrayStride == 0)
-                    topLevelArrayStride = reflection.indexToUniform.back().arrayStride;
+                    topLevelArrayStride = variables.back().arrayStride;
             }
 
-            reflection.indexToUniform.back().topLevelArrayStride = topLevelArrayStride;
+            if ((reflection.options & EShReflectionSeparateBuffers) && terminalType->getBasicType() == EbtAtomicUint)
+                reflection.atomicCounterUniformIndices.push_back(uniformIndex);
+
+            variables.back().topLevelArrayStride = topLevelArrayStride;
         } else if (arraySize > 1) {
-            int& reflectedArraySize = reflection.indexToUniform[it->second].size;
+            int& reflectedArraySize = variables[it->second].size;
             reflectedArraySize = std::max(arraySize, reflectedArraySize);
         }
     }
@@ -528,19 +533,22 @@ public:
             else
                 baseName = base->getName();
         }
-        blowUpActiveAggregate(base->getType(), baseName, derefs, derefs.begin(), offset, blockIndex, arraySize, 0);
+        blowUpActiveAggregate(base->getType(), baseName, derefs, derefs.begin(), offset, blockIndex, arraySize, 0,
+                              base->getQualifier().storage);
     }
 
     int addBlockName(const TString& name, const TType& type, int size)
     {
+        TReflection::TMapIndexToReflection& blocks = reflection.GetBlockMapForStorage(type.getQualifier().storage);
+
         int blockIndex;
         TReflection::TNameToIndex::const_iterator it = reflection.nameToIndex.find(name.c_str());
         if (reflection.nameToIndex.find(name.c_str()) == reflection.nameToIndex.end()) {
-            blockIndex = (int)reflection.indexToUniformBlock.size();
+            blockIndex = (int)blocks.size();
             reflection.nameToIndex[name.c_str()] = blockIndex;
-            reflection.indexToUniformBlock.push_back(TObjectReflection(name.c_str(), type, -1, -1, size, -1));
+            blocks.push_back(TObjectReflection(name.c_str(), type, -1, -1, size, -1));
 
-            reflection.indexToUniformBlock.back().numMembers = countAggregateMembers(type);
+            blocks.back().numMembers = countAggregateMembers(type);
         } else
             blockIndex = it->second;
 
@@ -1013,6 +1021,11 @@ void TReflection::buildUniformStageMask(const TIntermediate& intermediate)
     for (int i = 0; i < int(indexToUniform.size()); ++i) {
         indexToUniform[i].stages = static_cast<EShLanguageMask>(indexToUniform[i].stages | 1 << intermediate.getStage());
     }
+
+    for (int i = 0; i < int(indexToBufferVariable.size()); ++i) {
+        indexToBufferVariable[i].stages =
+            static_cast<EShLanguageMask>(indexToBufferVariable[i].stages | 1 << intermediate.getStage());
+    }
 }
 
 // Merge live symbols from 'intermediate' into the existing reflection database.
@@ -1057,6 +1070,16 @@ void TReflection::dump()
         indexToUniformBlock[i].dump();
     printf("\n");
 
+    printf("Buffer variable reflection:\n");
+    for (size_t i = 0; i < indexToBufferVariable.size(); ++i)
+      indexToBufferVariable[i].dump();
+    printf("\n");
+
+    printf("Buffer block reflection:\n");
+    for (size_t i = 0; i < indexToBufferBlock.size(); ++i)
+      indexToBufferBlock[i].dump();
+    printf("\n");
+
     printf("Pipeline input reflection:\n");
     for (size_t i = 0; i < indexToPipeInput.size(); ++i)
         indexToPipeInput[i].dump();
index ccd87f1..44b17a0 100644 (file)
@@ -107,6 +107,36 @@ public:
             return badReflection;
     }
 
+    // for mapping from an atomic counter to the uniform index
+    int getNumAtomicCounters() const { return (int)atomicCounterUniformIndices.size(); }
+    const TObjectReflection& getAtomicCounter(int i) const
+    {
+        if (i >= 0 && i < (int)atomicCounterUniformIndices.size())
+            return getUniform(atomicCounterUniformIndices[i]);
+        else
+            return badReflection;
+    }
+
+    // for mapping a buffer variable index to a buffer variable object's description
+    int getNumBufferVariables() { return (int)indexToBufferVariable.size(); }
+    const TObjectReflection& getBufferVariable(int i) const
+    {
+        if (i >= 0 && i < (int)indexToBufferVariable.size())
+            return indexToBufferVariable[i];
+        else
+            return badReflection;
+    }
+    
+    // for mapping a storage block index to the storage block's description
+    int getNumStorageBuffers() const { return (int)indexToBufferBlock.size(); }
+    const TObjectReflection&  getStorageBufferBlock(int i) const
+    {
+        if (i >= 0 && i < (int)indexToBufferBlock.size())
+            return indexToBufferBlock[i];
+        else
+            return badReflection;
+    }
+
     // for mapping any name to its index (block names, uniform names and input/output names)
     int getIndex(const char* name) const
     {
@@ -135,6 +165,20 @@ protected:
     // Need a TString hash: typedef std::unordered_map<TString, int> TNameToIndex;
     typedef std::map<std::string, int> TNameToIndex;
     typedef std::vector<TObjectReflection> TMapIndexToReflection;
+    typedef std::vector<int> TIndices;
+
+    TMapIndexToReflection& GetBlockMapForStorage(TStorageQualifier storage)
+    {
+        if ((options & EShReflectionSeparateBuffers) && storage == EvqBuffer)
+            return indexToBufferBlock;
+        return indexToUniformBlock;
+    }
+    TMapIndexToReflection& GetVariableMapForStorage(TStorageQualifier storage)
+    {
+        if ((options & EShReflectionSeparateBuffers) && storage == EvqBuffer)
+            return indexToBufferVariable;
+        return indexToUniform;
+    }
 
     EShReflectionOptions options;
 
@@ -145,8 +189,11 @@ 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 indexToBufferVariable;
+    TMapIndexToReflection indexToBufferBlock;
     TMapIndexToReflection indexToPipeInput;
     TMapIndexToReflection indexToPipeOutput;
+    TIndices atomicCounterUniformIndices;
 
     unsigned int localSize[3];
 };
index 827de4e..7aaaaf3 100755 (executable)
@@ -247,6 +247,7 @@ typedef enum {
     EShReflectionStrictArraySuffix = (1 << 0), // reflection will follow stricter rules for array-of-structs suffixes
     EShReflectionBasicArraySuffix  = (1 << 1), // arrays of basic types will be appended with [0] as in GL reflection
     EShReflectionIntermediateIO    = (1 << 2), // reflect inputs and outputs to program, even with no vertex shader
+    EShReflectionSeparateBuffers   = (1 << 3), // buffer variables and buffer blocks are reflected separately
 } EShReflectionOptions;
 
 //
@@ -748,6 +749,12 @@ public:
     const TObjectReflection& getPipeInput(int index) const;
     int getNumPipeOutputs() const;
     const TObjectReflection& getPipeOutput(int index) const;
+    int getNumBufferVariables() const;
+    const TObjectReflection& getBufferVariable(int index) const;
+    int getNumBufferBlocks() const;
+    const TObjectReflection& getBufferBlock(int index) const;
+    int getNumAtomicCounters() const;
+    const TObjectReflection& getAtomicCounter(int index) const;
 
     // Legacy Reflection Interface - expressed in terms of above interface
     int getNumLiveUniformVariables() const                 // can be used for glGetProgramiv(GL_ACTIVE_UNIFORMS)