From 1dc5dcf0a5e0e7a0c9cdc3d49698dd44a0bd5cc1 Mon Sep 17 00:00:00 2001 From: baldurk Date: Tue, 29 Jan 2019 15:30:48 +0000 Subject: [PATCH 1/9] Move TObjectReflection into public interface to clean up reflection * Forwarding functions are left to preserve source compatibility with code using the old queries. --- glslang/MachineIndependent/ShaderLang.cpp | 30 ++-- glslang/MachineIndependent/reflection.cpp | 29 ++++ glslang/MachineIndependent/reflection.h | 41 ------ glslang/Public/ShaderLang.h | 159 +++++++++++++++++++--- 4 files changed, 177 insertions(+), 82 deletions(-) diff --git a/glslang/MachineIndependent/ShaderLang.cpp b/glslang/MachineIndependent/ShaderLang.cpp index 3d93aa29..6b330c87 100755 --- a/glslang/MachineIndependent/ShaderLang.cpp +++ b/glslang/MachineIndependent/ShaderLang.cpp @@ -1983,27 +1983,15 @@ bool TProgram::buildReflection() return true; } -int TProgram::getNumLiveUniformVariables() const { return reflection->getNumUniforms(); } -int TProgram::getNumLiveUniformBlocks() const { return reflection->getNumUniformBlocks(); } -const char* TProgram::getUniformName(int index) const { return reflection->getUniform(index).name.c_str(); } -const char* TProgram::getUniformBlockName(int index) const { return reflection->getUniformBlock(index).name.c_str(); } -int TProgram::getUniformBlockSize(int index) const { return reflection->getUniformBlock(index).size; } -int TProgram::getUniformIndex(const char* name) const { return reflection->getIndex(name); } -int TProgram::getUniformBinding(int index) const { return reflection->getUniform(index).getBinding(); } -EShLanguageMask TProgram::getUniformStages(int index) const { return reflection->getUniform(index).stages; } -int TProgram::getUniformBlockBinding(int index) const { return reflection->getUniformBlock(index).getBinding(); } -int TProgram::getUniformBlockIndex(int index) const { return reflection->getUniform(index).index; } -int TProgram::getUniformBlockCounterIndex(int index) const { return reflection->getUniformBlock(index).counterIndex; } -int TProgram::getUniformType(int index) const { return reflection->getUniform(index).glDefineType; } -int TProgram::getUniformBufferOffset(int index) const { return reflection->getUniform(index).offset; } -int TProgram::getUniformArraySize(int index) const { return reflection->getUniform(index).size; } -int TProgram::getNumLiveAttributes() const { return reflection->getNumAttributes(); } -const char* TProgram::getAttributeName(int index) const { return reflection->getAttribute(index).name.c_str(); } -int TProgram::getAttributeType(int index) const { return reflection->getAttribute(index).glDefineType; } -const TType* TProgram::getAttributeTType(int index) const { return reflection->getAttribute(index).getType(); } -const TType* TProgram::getUniformTType(int index) const { return reflection->getUniform(index).getType(); } -const TType* TProgram::getUniformBlockTType(int index) const { return reflection->getUniformBlock(index).getType(); } -unsigned TProgram::getLocalSize(int dim) const { return reflection->getLocalSize(dim); } +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::getNumAttributes() const { return reflection->getNumAttributes(); } +const TObjectReflection& TProgram::getAttribute(int index) const { return reflection->getAttribute(index); } void TProgram::dumpReflection() { reflection->dump(); } diff --git a/glslang/MachineIndependent/reflection.cpp b/glslang/MachineIndependent/reflection.cpp index b6966863..caa5cbfd 100644 --- a/glslang/MachineIndependent/reflection.cpp +++ b/glslang/MachineIndependent/reflection.cpp @@ -832,6 +832,35 @@ void TReflectionTraverser::visitSymbol(TIntermSymbol* base) addAttribute(*base); } +// +// Implement TObjectReflection methods. +// + +TObjectReflection::TObjectReflection(const std::string &pName, const TType &pType, int pOffset, int pGLDefineType, + int pSize, int pIndex) + : name(pName), offset(pOffset), glDefineType(pGLDefineType), size(pSize), index(pIndex), counterIndex(-1), + stages(EShLanguageMask(0)), type(pType.clone()) +{ +} + +int TObjectReflection::getBinding() const +{ + if (type == nullptr || !type->getQualifier().hasBinding()) + return -1; + return type->getQualifier().layoutBinding; +} + +void TObjectReflection::dump() const +{ + printf("%s: offset %d, type %x, size %d, index %d, binding %d, stages %d", name.c_str(), offset, glDefineType, size, + index, getBinding(), stages); + + if (counterIndex != -1) + printf(", counter %d", counterIndex); + + printf("\n"); +} + // // Implement TReflection methods. // diff --git a/glslang/MachineIndependent/reflection.h b/glslang/MachineIndependent/reflection.h index dab9ab08..6c1d106d 100644 --- a/glslang/MachineIndependent/reflection.h +++ b/glslang/MachineIndependent/reflection.h @@ -52,47 +52,6 @@ class TIntermediate; class TIntermAggregate; class TReflectionTraverser; -// Data needed for just a single object at the granularity exchanged by the reflection API -class TObjectReflection { -public: - TObjectReflection(const std::string& pName, const TType& pType, int pOffset, int pGLDefineType, int pSize, int pIndex) : - name(pName), offset(pOffset), - glDefineType(pGLDefineType), size(pSize), index(pIndex), counterIndex(-1), stages(EShLanguageMask(0)), type(pType.clone()) { } - - const TType* getType() const { return type; } - int getBinding() const - { - if (type == nullptr || !type->getQualifier().hasBinding()) - return -1; - return type->getQualifier().layoutBinding; - } - void dump() const - { - printf("%s: offset %d, type %x, size %d, index %d, binding %d, stages %d", - name.c_str(), offset, glDefineType, size, index, getBinding(), stages ); - - if (counterIndex != -1) - printf(", counter %d", counterIndex); - - printf("\n"); - } - static TObjectReflection badReflection() { return TObjectReflection(); } - - std::string name; - int offset; - int glDefineType; - int size; // data size in bytes for a block, array size for a (non-block) object that's an array - int index; - int counterIndex; - EShLanguageMask stages; - -protected: - TObjectReflection() : - offset(-1), glDefineType(-1), size(-1), index(-1), counterIndex(-1), stages(EShLanguageMask(0)), type(nullptr) { } - - const TType* type; -}; - // The full reflection database class TReflection { public: diff --git a/glslang/Public/ShaderLang.h b/glslang/Public/ShaderLang.h index d73021c4..341fdb2f 100755 --- a/glslang/Public/ShaderLang.h +++ b/glslang/Public/ShaderLang.h @@ -599,6 +599,35 @@ private: TShader& operator=(TShader&); }; +// +// A reflection database and its interface, consistent with the OpenGL API reflection queries. +// + +// Data needed for just a single object at the granularity exchanged by the reflection API +class TObjectReflection { +public: + TObjectReflection(const std::string& pName, const TType& pType, int pOffset, int pGLDefineType, int pSize, int pIndex); + + const TType* getType() const { return type; } + int getBinding() const; + void dump() const; + static TObjectReflection badReflection() { return TObjectReflection(); } + + std::string name; + int offset; + int glDefineType; + int size; // data size in bytes for a block, array size for a (non-block) object that's an array + int index; + int counterIndex; + EShLanguageMask stages; + +protected: + TObjectReflection() : + offset(-1), glDefineType(-1), size(-1), index(-1), counterIndex(-1), stages(EShLanguageMask(0)), type(nullptr) { } + + const TType* type; +}; + class TReflection; class TIoMapper; @@ -689,27 +718,117 @@ public: // Reflection Interface bool buildReflection(); // call first, to do liveness analysis, index mapping, etc.; returns false on failure - int getNumLiveUniformVariables() const; // can be used for glGetProgramiv(GL_ACTIVE_UNIFORMS) - int getNumLiveUniformBlocks() const; // can be used for glGetProgramiv(GL_ACTIVE_UNIFORM_BLOCKS) - const char* getUniformName(int index) const; // can be used for "name" part of glGetActiveUniform() - const char* getUniformBlockName(int blockIndex) const; // can be used for glGetActiveUniformBlockName() - int getUniformBlockSize(int blockIndex) const; // can be used for glGetActiveUniformBlockiv(UNIFORM_BLOCK_DATA_SIZE) - int getUniformIndex(const char* name) const; // can be used for glGetUniformIndices() - int getUniformBinding(int index) const; // returns the binding number - EShLanguageMask getUniformStages(int index) const; // returns Shaders Stages where a Uniform is present - int getUniformBlockBinding(int index) const; // returns the block binding number - int getUniformBlockIndex(int index) const; // can be used for glGetActiveUniformsiv(GL_UNIFORM_BLOCK_INDEX) - int getUniformBlockCounterIndex(int index) const; // returns block index of associated counter. - int getUniformType(int index) const; // can be used for glGetActiveUniformsiv(GL_UNIFORM_TYPE) - int getUniformBufferOffset(int index) const; // can be used for glGetActiveUniformsiv(GL_UNIFORM_OFFSET) - int getUniformArraySize(int index) const; // can be used for glGetActiveUniformsiv(GL_UNIFORM_SIZE) - int getNumLiveAttributes() const; // can be used for glGetProgramiv(GL_ACTIVE_ATTRIBUTES) + unsigned getLocalSize(int dim) const; // return dim'th local size - const char *getAttributeName(int index) const; // can be used for glGetActiveAttrib() - int getAttributeType(int index) const; // can be used for glGetActiveAttrib() - const TType* getUniformTType(int index) const; // returns a TType* - const TType* getUniformBlockTType(int index) const; // returns a TType* - const TType* getAttributeTType(int index) const; // returns a TType* + int getReflectionIndex(const char *name) const; + + int getNumUniformVariables() const; + const TObjectReflection& getUniform(int index) const; + int getNumUniformBlocks() const; + const TObjectReflection& getUniformBlock(int index) const; + int getNumAttributes() const; + const TObjectReflection& getAttribute(int index) const; + + // Legacy Reflection Interface - expressed in terms of above interface + int getNumLiveUniformVariables() const // can be used for glGetProgramiv(GL_ACTIVE_UNIFORMS) + { + return getNumUniformVariables(); + } + + int getNumLiveUniformBlocks() const // can be used for glGetProgramiv(GL_ACTIVE_UNIFORM_BLOCKS) + { + return getNumUniformBlocks(); + } + + int getNumLiveAttributes() const // can be used for glGetProgramiv(GL_ACTIVE_ATTRIBUTES) + { + return getNumAttributes(); + } + + int getUniformIndex(const char* name) const // can be used for glGetUniformIndices() + { + return getReflectionIndex(name); + } + + const char* getUniformName(int index) const // can be used for "name" part of glGetActiveUniform() + { + return getUniform(index).name.c_str(); + } + + int getUniformBinding(int index) const // returns the binding number + { + return getUniform(index).getBinding(); + } + + EShLanguageMask getUniformStages(int index) const // returns Shaders Stages where a Uniform is present + { + return getUniform(index).stages; + } + + int getUniformBlockIndex(int index) const // can be used for glGetActiveUniformsiv(GL_UNIFORM_BLOCK_INDEX) + { + return getUniform(index).index; + } + + int getUniformType(int index) const // can be used for glGetActiveUniformsiv(GL_UNIFORM_TYPE) + { + return getUniform(index).glDefineType; + } + + int getUniformBufferOffset(int index) const // can be used for glGetActiveUniformsiv(GL_UNIFORM_OFFSET) + { + return getUniform(index).offset; + } + + int getUniformArraySize(int index) const // can be used for glGetActiveUniformsiv(GL_UNIFORM_SIZE) + { + return getUniform(index).size; + } + + const TType* getUniformTType(int index) const // returns a TType* + { + return getUniform(index).getType(); + } + + const char* getUniformBlockName(int index) const // can be used for glGetActiveUniformBlockName() + { + return getUniformBlock(index).name.c_str(); + } + + int getUniformBlockSize(int index) const // can be used for glGetActiveUniformBlockiv(UNIFORM_BLOCK_DATA_SIZE) + { + return getUniformBlock(index).size; + } + + int getUniformBlockBinding(int index) const // returns the block binding number + { + return getUniformBlock(index).getBinding(); + } + + int getUniformBlockCounterIndex(int index) const // returns block index of associated counter. + { + return getUniformBlock(index).counterIndex; + } + + const TType* getUniformBlockTType(int index) const // returns a TType* + { + return getUniformBlock(index).getType(); + } + + const char* getAttributeName(int index) const // can be used for glGetActiveAttrib() + { + return getAttribute(index).name.c_str(); + } + + int getAttributeType(int index) const // can be used for glGetActiveAttrib() + { + return getAttribute(index).glDefineType; + } + + const TType* getAttributeTType(int index) const // returns a TType* + { + return getAttribute(index).getType(); + } void dumpReflection(); From 6d477858251f76852210810eedb1dd71a8089c54 Mon Sep 17 00:00:00 2001 From: baldurk Date: Tue, 29 Jan 2019 15:45:56 +0000 Subject: [PATCH 2/9] Add options to control how reflection information is built --- StandAlone/StandAlone.cpp | 3 ++- glslang/MachineIndependent/ShaderLang.cpp | 4 ++-- glslang/MachineIndependent/reflection.h | 4 +++- glslang/Public/ShaderLang.h | 11 ++++++++++- 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/StandAlone/StandAlone.cpp b/StandAlone/StandAlone.cpp index 42a46cee..d26040c6 100644 --- a/StandAlone/StandAlone.cpp +++ b/StandAlone/StandAlone.cpp @@ -152,6 +152,7 @@ void ProcessConfigFile() } } +int ReflectOptions = EShReflectionDefault; int Options = 0; const char* ExecutableName = nullptr; const char* binaryFileName = nullptr; @@ -1051,7 +1052,7 @@ void CompileAndLinkShaderUnits(std::vector compUnits) // Reflect if (Options & EOptionDumpReflection) { - program.buildReflection(); + program.buildReflection(ReflectOptions); program.dumpReflection(); } diff --git a/glslang/MachineIndependent/ShaderLang.cpp b/glslang/MachineIndependent/ShaderLang.cpp index 6b330c87..3e77292f 100755 --- a/glslang/MachineIndependent/ShaderLang.cpp +++ b/glslang/MachineIndependent/ShaderLang.cpp @@ -1966,12 +1966,12 @@ const char* TProgram::getInfoDebugLog() // Reflection implementation. // -bool TProgram::buildReflection() +bool TProgram::buildReflection(int opts) { if (! linked || reflection) return false; - reflection = new TReflection; + reflection = new TReflection((EShReflectionOptions)opts); for (int s = 0; s < EShLangCount; ++s) { if (intermediate[s]) { diff --git a/glslang/MachineIndependent/reflection.h b/glslang/MachineIndependent/reflection.h index 6c1d106d..c4464aab 100644 --- a/glslang/MachineIndependent/reflection.h +++ b/glslang/MachineIndependent/reflection.h @@ -55,7 +55,7 @@ class TReflectionTraverser; // The full reflection database class TReflection { public: - TReflection() : badReflection(TObjectReflection::badReflection()) + TReflection(EShReflectionOptions opts) : options(opts), badReflection(TObjectReflection::badReflection()) { for (int dim=0; dim<3; ++dim) localSize[dim] = 0; @@ -125,6 +125,8 @@ protected: typedef std::map TNameToIndex; typedef std::vector TMapIndexToReflection; + EShReflectionOptions options; + TObjectReflection badReflection; // return for queries of -1 or generally out of range; has expected descriptions with in it for this TNameToIndex nameToIndex; // maps names to indexes; can hold all types of data: uniform/buffer and which function names have been processed TMapIndexToReflection indexToUniform; diff --git a/glslang/Public/ShaderLang.h b/glslang/Public/ShaderLang.h index 341fdb2f..3bb9f5e8 100755 --- a/glslang/Public/ShaderLang.h +++ b/glslang/Public/ShaderLang.h @@ -239,6 +239,13 @@ enum EShMessages { EShMsgHlslDX9Compatible = (1 << 13), // enable HLSL DX9 compatible mode (right now only for samplers) }; +// +// Options for building reflection +// +typedef enum { + EShReflectionDefault = 0, // default is original behaviour before options were added +} EShReflectionOptions; + // // Build a table for bindings. This can be used for locating // attributes, uniforms, globals, etc., as needed. @@ -717,7 +724,9 @@ public: TIntermediate* getIntermediate(EShLanguage stage) const { return intermediate[stage]; } // Reflection Interface - bool buildReflection(); // call first, to do liveness analysis, index mapping, etc.; returns false on failure + + // call first, to do liveness analysis, index mapping, etc.; returns false on failure + bool buildReflection(int opts = EShReflectionDefault); unsigned getLocalSize(int dim) const; // return dim'th local size int getReflectionIndex(const char *name) const; From 15c37f79a909260d4b22b57fc04223a40565b710 Mon Sep 17 00:00:00 2001 From: baldurk Date: Tue, 29 Jan 2019 12:12:59 +0000 Subject: [PATCH 3/9] Include array index in reflected uniform names more consistently * This comes from the resolution of issues 4, 5 & 6 in ARB_program_interface_query, stating that uniform buffers should have their members expanded out as normal and arrays should have elements added. * If a buffer block has a large array e.g. [10000] we don't want to iterate over every array element. Instead we should only expand out the first [0] element, then expand as normal from there. * The array name should still be appended with [0] to indicate that it's an array. --- StandAlone/StandAlone.cpp | 3 ++ Test/baseResults/reflection.options.vert.out | 15 ++++++++ Test/baseResults/reflection.vert.out | 38 ++++++++++++++++++++ Test/reflection.options.vert | 23 ++++++++++++ Test/reflection.vert | 18 ++++++++++ Test/runtests | 2 ++ glslang/MachineIndependent/reflection.cpp | 27 ++++++++++++-- glslang/Public/ShaderLang.h | 1 + 8 files changed, 124 insertions(+), 3 deletions(-) create mode 100644 Test/baseResults/reflection.options.vert.out create mode 100644 Test/reflection.options.vert diff --git a/StandAlone/StandAlone.cpp b/StandAlone/StandAlone.cpp index d26040c6..fd69810b 100644 --- a/StandAlone/StandAlone.cpp +++ b/StandAlone/StandAlone.cpp @@ -524,6 +524,8 @@ void ProcessArguments(std::vector>& workItem Options |= EOptionNoStorageFormat; } else if (lowerword == "relaxed-errors") { Options |= EOptionRelaxedErrors; + } else if (lowerword == "reflect-strict-array-suffix") { + ReflectOptions |= EShReflectionStrictArraySuffix; } else if (lowerword == "resource-set-bindings" || // synonyms lowerword == "resource-set-binding" || lowerword == "rsb") { @@ -1519,6 +1521,7 @@ void usage() " --invert-y | --iy invert position.Y output in vertex shader\n" " --keep-uncalled | --ku don't eliminate uncalled functions\n" " --no-storage-format | --nsf use Unknown image format\n" + " --reflect-strict-array-suffix use strict array suffix rules when reflecting\n" " --resource-set-binding [stage] name set binding\n" " set descriptor set and binding for\n" " individual resources\n" diff --git a/Test/baseResults/reflection.options.vert.out b/Test/baseResults/reflection.options.vert.out new file mode 100644 index 00000000..a4bf815b --- /dev/null +++ b/Test/baseResults/reflection.options.vert.out @@ -0,0 +1,15 @@ +reflection.options.vert +Uniform reflection: +t[0].v[0].position: offset 0, type 1406, size 3, index 0, binding -1, stages 1 +t[0].v[1].position: offset 24, type 1406, size 3, index 0, binding -1, stages 1 +t[0].v[2].position: offset 48, type 1406, size 3, index 0, binding -1, stages 1 +t[0].v[0].normal: offset 12, type 1406, size 3, index 0, binding -1, stages 1 +t[0].v[1].normal: offset 36, type 1406, size 3, index 0, binding -1, stages 1 +t[0].v[2].normal: offset 60, type 1406, size 3, index 0, binding -1, stages 1 + +Uniform block reflection: +VertexCollection: offset -1, type ffffffff, size 360, index -1, binding -1, stages 0 + +Vertex attribute reflection: +gl_InstanceID: offset 0, type 1404, size 0, index 0, binding -1, stages 0 + diff --git a/Test/baseResults/reflection.vert.out b/Test/baseResults/reflection.vert.out index 5d135236..30aa7a3b 100644 --- a/Test/baseResults/reflection.vert.out +++ b/Test/baseResults/reflection.vert.out @@ -84,6 +84,43 @@ nested2.b[2].a: offset 80, type 1406, size 1, index 16, binding -1, stages 1 nested2.b[3].a: offset 96, type 1406, size 1, index 16, binding -1, stages 1 nested2.c.a: offset 112, type 1406, size 1, index 16, binding -1, stages 1 nested2.d.a: offset 144, type 1406, size 1, index 16, binding -1, stages 1 +t.v.position: offset 0, type 1406, size 1, index 17, binding -1, stages 1 +t.v[0].position: offset 0, type 1406, size 3, index 17, binding -1, stages 1 +t.v[1].position: offset 24, type 1406, size 3, index 17, binding -1, stages 1 +t.v[2].position: offset 48, type 1406, size 3, index 17, binding -1, stages 1 +t.v[0].normal: offset 12, type 1406, size 3, index 17, binding -1, stages 1 +t.v[1].normal: offset 36, type 1406, size 3, index 17, binding -1, stages 1 +t.v[2].normal: offset 60, type 1406, size 3, index 17, binding -1, stages 1 +t[0].v[0].position: offset 0, type 1406, size 3, index 17, binding -1, stages 1 +t[0].v[0].normal: offset 12, type 1406, size 3, index 17, binding -1, stages 1 +t[0].v[1].position: offset 24, type 1406, size 3, index 17, binding -1, stages 1 +t[0].v[1].normal: offset 36, type 1406, size 3, index 17, binding -1, stages 1 +t[0].v[2].position: offset 48, type 1406, size 3, index 17, binding -1, stages 1 +t[0].v[2].normal: offset 60, type 1406, size 3, index 17, binding -1, stages 1 +t[1].v[0].position: offset 72, type 1406, size 3, index 17, binding -1, stages 1 +t[1].v[0].normal: offset 84, type 1406, size 3, index 17, binding -1, stages 1 +t[1].v[1].position: offset 96, type 1406, size 3, index 17, binding -1, stages 1 +t[1].v[1].normal: offset 108, type 1406, size 3, index 17, binding -1, stages 1 +t[1].v[2].position: offset 120, type 1406, size 3, index 17, binding -1, stages 1 +t[1].v[2].normal: offset 132, type 1406, size 3, index 17, binding -1, stages 1 +t[2].v[0].position: offset 144, type 1406, size 3, index 17, binding -1, stages 1 +t[2].v[0].normal: offset 156, type 1406, size 3, index 17, binding -1, stages 1 +t[2].v[1].position: offset 168, type 1406, size 3, index 17, binding -1, stages 1 +t[2].v[1].normal: offset 180, type 1406, size 3, index 17, binding -1, stages 1 +t[2].v[2].position: offset 192, type 1406, size 3, index 17, binding -1, stages 1 +t[2].v[2].normal: offset 204, type 1406, size 3, index 17, binding -1, stages 1 +t[3].v[0].position: offset 216, type 1406, size 3, index 17, binding -1, stages 1 +t[3].v[0].normal: offset 228, type 1406, size 3, index 17, binding -1, stages 1 +t[3].v[1].position: offset 240, type 1406, size 3, index 17, binding -1, stages 1 +t[3].v[1].normal: offset 252, type 1406, size 3, index 17, binding -1, stages 1 +t[3].v[2].position: offset 264, type 1406, size 3, index 17, binding -1, stages 1 +t[3].v[2].normal: offset 276, type 1406, size 3, index 17, binding -1, stages 1 +t[4].v[0].position: offset 288, type 1406, size 3, index 17, binding -1, stages 1 +t[4].v[0].normal: offset 300, type 1406, size 3, index 17, binding -1, stages 1 +t[4].v[1].position: offset 312, type 1406, size 3, index 17, binding -1, stages 1 +t[4].v[1].normal: offset 324, type 1406, size 3, index 17, binding -1, stages 1 +t[4].v[2].position: offset 336, type 1406, size 3, index 17, binding -1, stages 1 +t[4].v[2].normal: offset 348, type 1406, size 3, index 17, binding -1, stages 1 anonMember1: offset 0, type 8b51, size 1, index 0, binding -1, stages 1 uf1: offset -1, type 1406, size 1, index -1, binding -1, stages 1 uf2: offset -1, type 1406, size 1, index -1, binding -1, stages 1 @@ -107,6 +144,7 @@ buf2: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0 buf3: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0 buf4: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0 nested2: offset -1, type ffffffff, size 208, index -1, binding -1, stages 0 +VertexCollection: offset -1, type ffffffff, size 360, index -1, binding -1, stages 0 Vertex attribute reflection: attributeFloat: offset 0, type 1406, size 0, index 0, binding -1, stages 0 diff --git a/Test/reflection.options.vert b/Test/reflection.options.vert new file mode 100644 index 00000000..c671a625 --- /dev/null +++ b/Test/reflection.options.vert @@ -0,0 +1,23 @@ +#version 440 core + +struct VertexInfo { + float position[3]; + float normal[3]; +}; + +struct TriangleInfo { + VertexInfo v[3]; +}; + +buffer VertexCollection { + TriangleInfo t[5]; +}; + +void main() +{ + float f; + f += t[0].v[0].position[0]; + f += t[gl_InstanceID].v[gl_InstanceID].position[gl_InstanceID]; + f += t[gl_InstanceID].v[gl_InstanceID].normal[gl_InstanceID]; + TriangleInfo tlocal[5] = t; +} diff --git a/Test/reflection.vert b/Test/reflection.vert index 9b3b45c9..76ec5a30 100644 --- a/Test/reflection.vert +++ b/Test/reflection.vert @@ -161,6 +161,19 @@ buffer buf4 { N2 runtimeArray[]; } buf4i; +struct VertexInfo { + float position[3]; + float normal[3]; +}; + +struct TriangleInfo { + VertexInfo v[3]; +}; + +buffer VertexCollection { + TriangleInfo t[5]; +}; + void main() { liveFunction1(image_ui2D, sampler_2D, sampler_2DMSArray); @@ -216,4 +229,9 @@ void main() N1 b[4] = nest2.b; f += nest2.c[1].a; f += nest2.d[gl_InstanceID].a; + + f += t[0].v[0].position[0]; + f += t[gl_InstanceID].v[gl_InstanceID].position[gl_InstanceID]; + f += t[gl_InstanceID].v[gl_InstanceID].normal[gl_InstanceID]; + TriangleInfo tlocal[5] = t; } diff --git a/Test/runtests b/Test/runtests index c88cb590..890ebac5 100755 --- a/Test/runtests +++ b/Test/runtests @@ -32,6 +32,8 @@ 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 reflection.options.vert > $TARGETDIR/reflection.options.vert.out +diff -b $BASEDIR/reflection.options.vert.out $TARGETDIR/reflection.options.vert.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 $EXE -D -Od -e main -l -q -C -V -Od hlsl.reflection.binding.frag > $TARGETDIR/hlsl.reflection.binding.frag.out diff --git a/glslang/MachineIndependent/reflection.cpp b/glslang/MachineIndependent/reflection.cpp index caa5cbfd..0f46daad 100644 --- a/glslang/MachineIndependent/reflection.cpp +++ b/glslang/MachineIndependent/reflection.cpp @@ -223,6 +223,16 @@ public: void blowUpActiveAggregate(const TType& baseType, const TString& baseName, const TList& derefs, TList::const_iterator deref, int offset, int blockIndex, int arraySize) { + // when strictArraySuffix is enabled, we closely follow the rules from ARB_program_interface_query. + // Broadly: + // * arrays-of-structs always have a [x] suffix. + // * with array-of-struct variables in the root of a buffer block, only ever return [0]. + // * otherwise, array suffixes are added whenever we iterate, even if that means expanding out an array. + const bool strictArraySuffix = (reflection.options & EShReflectionStrictArraySuffix); + + // is this variable inside a buffer block. This flag is set back to false after we iterate inside the first array element. + bool blockParent = (baseType.getBasicType() == EbtBlock && baseType.getQualifier().storage == EvqBuffer); + // process the part of the dereference chain that was explicit in the shader TString name = baseName; const TType* terminalType = &baseType; @@ -237,7 +247,9 @@ public: // Visit all the indices of this array, and for each one add on the remaining dereferencing for (int i = 0; i < std::max(visitNode->getLeft()->getType().getOuterArraySize(), 1); ++i) { TString newBaseName = name; - if (baseType.getBasicType() != EbtBlock) + if (strictArraySuffix && blockParent) + newBaseName.append(TString("[0]")); + else if (strictArraySuffix || baseType.getBasicType() != EbtBlock) newBaseName.append(TString("[") + String(i) + "]"); TList::const_iterator nextDeref = deref; ++nextDeref; @@ -253,12 +265,15 @@ public: } case EOpIndexDirect: index = visitNode->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst(); - if (baseType.getBasicType() != EbtBlock) { + if (strictArraySuffix && blockParent) { + name.append(TString("[0]")); + } else if (strictArraySuffix || baseType.getBasicType() != EbtBlock) { name.append(TString("[") + String(index) + "]"); if (offset >= 0) offset += getArrayStride(baseType, visitNode->getLeft()->getType()) * index; } + blockParent = false; break; case EOpIndexDirectStruct: index = visitNode->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst(); @@ -286,7 +301,13 @@ public: if (offset >= 0) stride = getArrayStride(baseType, *terminalType); - for (int i = 0; i < std::max(terminalType->getOuterArraySize(), 1); ++i) { + int arrayIterateSize = std::max(terminalType->getOuterArraySize(), 1); + + // for top-level arrays in blocks, only expand [0] to avoid explosion of items + if (strictArraySuffix && blockParent) + arrayIterateSize = 1; + + for (int i = 0; i < arrayIterateSize; ++i) { TString newBaseName = name; newBaseName.append(TString("[") + String(i) + "]"); TType derefType(*terminalType, 0); diff --git a/glslang/Public/ShaderLang.h b/glslang/Public/ShaderLang.h index 3bb9f5e8..3866f2de 100755 --- a/glslang/Public/ShaderLang.h +++ b/glslang/Public/ShaderLang.h @@ -244,6 +244,7 @@ enum EShMessages { // typedef enum { EShReflectionDefault = 0, // default is original behaviour before options were added + EShReflectionStrictArraySuffix = (1 << 0), // reflection will follow stricter rules for array-of-structs suffixes } EShReflectionOptions; // From edf8212ab8c01f3ee5cc4384b8590c2ce67f92a8 Mon Sep 17 00:00:00 2001 From: baldurk Date: Tue, 29 Jan 2019 15:49:00 +0000 Subject: [PATCH 4/9] Add an option to report array variables with trailing [0] suffix * This is as expected by ARB_program_interface_query --- StandAlone/StandAlone.cpp | 3 +++ Test/baseResults/reflection.options.vert.out | 12 ++++++------ Test/runtests | 2 +- glslang/MachineIndependent/reflection.cpp | 4 ++++ glslang/Public/ShaderLang.h | 1 + 5 files changed, 15 insertions(+), 7 deletions(-) diff --git a/StandAlone/StandAlone.cpp b/StandAlone/StandAlone.cpp index fd69810b..c9b1eded 100644 --- a/StandAlone/StandAlone.cpp +++ b/StandAlone/StandAlone.cpp @@ -526,6 +526,8 @@ void ProcessArguments(std::vector>& workItem Options |= EOptionRelaxedErrors; } else if (lowerword == "reflect-strict-array-suffix") { ReflectOptions |= EShReflectionStrictArraySuffix; + } else if (lowerword == "reflect-basic-array-suffix") { + ReflectOptions |= EShReflectionBasicArraySuffix; } else if (lowerword == "resource-set-bindings" || // synonyms lowerword == "resource-set-binding" || lowerword == "rsb") { @@ -1522,6 +1524,7 @@ void usage() " --keep-uncalled | --ku don't eliminate uncalled functions\n" " --no-storage-format | --nsf use Unknown image format\n" " --reflect-strict-array-suffix use strict array suffix rules when reflecting\n" + " --reflect-basic-array-suffix arrays of basic types will have trailing [0]\n" " --resource-set-binding [stage] name set binding\n" " set descriptor set and binding for\n" " individual resources\n" diff --git a/Test/baseResults/reflection.options.vert.out b/Test/baseResults/reflection.options.vert.out index a4bf815b..22177c7c 100644 --- a/Test/baseResults/reflection.options.vert.out +++ b/Test/baseResults/reflection.options.vert.out @@ -1,11 +1,11 @@ reflection.options.vert Uniform reflection: -t[0].v[0].position: offset 0, type 1406, size 3, index 0, binding -1, stages 1 -t[0].v[1].position: offset 24, type 1406, size 3, index 0, binding -1, stages 1 -t[0].v[2].position: offset 48, type 1406, size 3, index 0, binding -1, stages 1 -t[0].v[0].normal: offset 12, type 1406, size 3, index 0, binding -1, stages 1 -t[0].v[1].normal: offset 36, type 1406, size 3, index 0, binding -1, stages 1 -t[0].v[2].normal: offset 60, type 1406, size 3, index 0, binding -1, stages 1 +t[0].v[0].position[0]: offset 0, type 1406, size 3, index 0, binding -1, stages 1 +t[0].v[1].position[0]: offset 24, type 1406, size 3, index 0, binding -1, stages 1 +t[0].v[2].position[0]: offset 48, type 1406, size 3, index 0, binding -1, stages 1 +t[0].v[0].normal[0]: offset 12, type 1406, size 3, index 0, binding -1, stages 1 +t[0].v[1].normal[0]: offset 36, type 1406, size 3, index 0, binding -1, stages 1 +t[0].v[2].normal[0]: offset 60, type 1406, size 3, index 0, binding -1, stages 1 Uniform block reflection: VertexCollection: offset -1, type ffffffff, size 360, index -1, binding -1, stages 0 diff --git a/Test/runtests b/Test/runtests index 890ebac5..c01366e6 100755 --- a/Test/runtests +++ b/Test/runtests @@ -32,7 +32,7 @@ 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 reflection.options.vert > $TARGETDIR/reflection.options.vert.out +$EXE -l -q -C --reflect-strict-array-suffix --reflect-basic-array-suffix reflection.options.vert > $TARGETDIR/reflection.options.vert.out diff -b $BASEDIR/reflection.options.vert.out $TARGETDIR/reflection.options.vert.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 diff --git a/glslang/MachineIndependent/reflection.cpp b/glslang/MachineIndependent/reflection.cpp index 0f46daad..ec627a18 100644 --- a/glslang/MachineIndependent/reflection.cpp +++ b/glslang/MachineIndependent/reflection.cpp @@ -341,6 +341,10 @@ public: return; } + if ((reflection.options & EShReflectionBasicArraySuffix) && terminalType->isArray()) { + name.append(TString("[0]")); + } + // Finally, add a full string to the reflection database, and update the array size if necessary. // If the dereferenced entity to record is an array, compute the size and update the maximum size. diff --git a/glslang/Public/ShaderLang.h b/glslang/Public/ShaderLang.h index 3866f2de..9a1f4bf0 100755 --- a/glslang/Public/ShaderLang.h +++ b/glslang/Public/ShaderLang.h @@ -245,6 +245,7 @@ enum EShMessages { typedef enum { EShReflectionDefault = 0, // default is original behaviour before options were added 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 } EShReflectionOptions; // From 0af5e3e3460ae2f867be51e2994211bf6a35a87f Mon Sep 17 00:00:00 2001 From: baldurk Date: Tue, 29 Jan 2019 16:04:44 +0000 Subject: [PATCH 5/9] Reflect pipeline outputs as well as inputs, optionally from other stages * We add an option to reflect inputs from other stages than vertex, if only a later subset of the stages is linked into the program. --- StandAlone/StandAlone.cpp | 4 ++ Test/baseResults/hlsl.automap.frag.out | 5 ++- .../hlsl.reflection.binding.frag.out | 5 ++- Test/baseResults/hlsl.reflection.vert.out | 4 +- Test/baseResults/hlsl.shift.per-set.frag.out | 5 ++- Test/baseResults/reflection.frag.out | 9 +++++ Test/baseResults/reflection.options.frag.out | 10 +++++ Test/baseResults/reflection.options.vert.out | 5 ++- Test/baseResults/reflection.vert.out | 4 +- Test/reflection.frag | 8 ++++ Test/reflection.options.vert | 3 ++ Test/reflection.vert | 4 ++ Test/runtests | 6 ++- glslang/MachineIndependent/ShaderLang.cpp | 23 +++++++++-- glslang/MachineIndependent/reflection.cpp | 40 +++++++++++++++---- glslang/MachineIndependent/reflection.h | 31 ++++++++++---- glslang/Public/ShaderLang.h | 15 ++++--- 17 files changed, 149 insertions(+), 32 deletions(-) create mode 100644 Test/baseResults/reflection.frag.out create mode 100644 Test/baseResults/reflection.options.frag.out create mode 100644 Test/reflection.frag diff --git a/StandAlone/StandAlone.cpp b/StandAlone/StandAlone.cpp index c9b1eded..7588320f 100644 --- a/StandAlone/StandAlone.cpp +++ b/StandAlone/StandAlone.cpp @@ -528,6 +528,8 @@ void ProcessArguments(std::vector>& workItem ReflectOptions |= EShReflectionStrictArraySuffix; } else if (lowerword == "reflect-basic-array-suffix") { ReflectOptions |= EShReflectionBasicArraySuffix; + } else if (lowerword == "reflect-intermediate-io") { + ReflectOptions |= EShReflectionIntermediateIO; } else if (lowerword == "resource-set-bindings" || // synonyms lowerword == "resource-set-binding" || lowerword == "rsb") { @@ -1525,6 +1527,8 @@ void usage() " --no-storage-format | --nsf use Unknown image format\n" " --reflect-strict-array-suffix use strict array suffix rules when reflecting\n" " --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" " --resource-set-binding [stage] name set binding\n" " set descriptor set and binding for\n" " individual resources\n" diff --git a/Test/baseResults/hlsl.automap.frag.out b/Test/baseResults/hlsl.automap.frag.out index b9ab49cd..7a871a7b 100644 --- a/Test/baseResults/hlsl.automap.frag.out +++ b/Test/baseResults/hlsl.automap.frag.out @@ -25,5 +25,8 @@ u6: offset -1, type ffffffff, size 0, index -1, binding 46, stages 0 cb: offset -1, type ffffffff, size 4, index -1, binding 51, stages 0 tb: offset -1, type ffffffff, size 4, index -1, binding 17, stages 0 -Vertex attribute reflection: +Pipeline input reflection: + +Pipeline output reflection: +@entryPointOutput: offset 0, type 8b52, size 0, index 0, binding -1, stages 0 diff --git a/Test/baseResults/hlsl.reflection.binding.frag.out b/Test/baseResults/hlsl.reflection.binding.frag.out index 464ce0f7..3c0d134d 100644 --- a/Test/baseResults/hlsl.reflection.binding.frag.out +++ b/Test/baseResults/hlsl.reflection.binding.frag.out @@ -15,5 +15,8 @@ Uniform block reflection: cbuff1: offset -1, type ffffffff, size 24, index -1, binding 2, stages 0 cbuff2: offset -1, type ffffffff, size 24, index -1, binding 3, stages 0 -Vertex attribute reflection: +Pipeline input reflection: + +Pipeline output reflection: +psout.Color: offset 0, type 8b52, size 0, index 0, binding -1, stages 0 diff --git a/Test/baseResults/hlsl.reflection.vert.out b/Test/baseResults/hlsl.reflection.vert.out index 3403bd35..92cb6ab1 100644 --- a/Test/baseResults/hlsl.reflection.vert.out +++ b/Test/baseResults/hlsl.reflection.vert.out @@ -67,10 +67,12 @@ nested: offset -1, type ffffffff, size 32, index -1, binding -1, stages 0 abl: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0 abl2: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0 -Vertex attribute 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 attributeFloat3: offset 0, type 8b51, size 0, index 0, binding -1, stages 0 attributeFloat4: offset 0, type 8b52, size 0, index 0, binding -1, stages 0 attributeMat4: offset 0, type 8b5c, size 0, index 0, binding -1, stages 0 +Pipeline output reflection: + diff --git a/Test/baseResults/hlsl.shift.per-set.frag.out b/Test/baseResults/hlsl.shift.per-set.frag.out index 7c7d3830..02c6e4a2 100644 --- a/Test/baseResults/hlsl.shift.per-set.frag.out +++ b/Test/baseResults/hlsl.shift.per-set.frag.out @@ -226,5 +226,8 @@ u6: offset -1, type ffffffff, size 0, index -1, binding 34, stages 0 cb: offset -1, type ffffffff, size 4, index -1, binding 51, stages 0 tb: offset -1, type ffffffff, size 4, index -1, binding 27, stages 0 -Vertex attribute reflection: +Pipeline input reflection: + +Pipeline output reflection: +@entryPointOutput: offset 0, type 8b52, size 0, index 0, binding -1, stages 0 diff --git a/Test/baseResults/reflection.frag.out b/Test/baseResults/reflection.frag.out new file mode 100644 index 00000000..d3d90a27 --- /dev/null +++ b/Test/baseResults/reflection.frag.out @@ -0,0 +1,9 @@ +reflection.frag +Uniform reflection: + +Uniform block reflection: + +Pipeline input reflection: + +Pipeline output reflection: + diff --git a/Test/baseResults/reflection.options.frag.out b/Test/baseResults/reflection.options.frag.out new file mode 100644 index 00000000..d0fe56e3 --- /dev/null +++ b/Test/baseResults/reflection.options.frag.out @@ -0,0 +1,10 @@ +reflection.frag +Uniform reflection: + +Uniform block reflection: + +Pipeline input reflection: +inval: offset 0, type 1406, size 0, index 0, binding -1, stages 0 + +Pipeline output reflection: + diff --git a/Test/baseResults/reflection.options.vert.out b/Test/baseResults/reflection.options.vert.out index 22177c7c..178779a3 100644 --- a/Test/baseResults/reflection.options.vert.out +++ b/Test/baseResults/reflection.options.vert.out @@ -10,6 +10,9 @@ t[0].v[2].normal[0]: offset 60, type 1406, size 3, index 0, binding -1, stages 1 Uniform block reflection: VertexCollection: offset -1, type ffffffff, size 360, index -1, binding -1, stages 0 -Vertex attribute reflection: +Pipeline input reflection: gl_InstanceID: offset 0, type 1404, size 0, index 0, binding -1, stages 0 +Pipeline output reflection: +outval: offset 0, type 1406, size 0, index 0, binding -1, stages 0 + diff --git a/Test/baseResults/reflection.vert.out b/Test/baseResults/reflection.vert.out index 30aa7a3b..fd3c8fe0 100644 --- a/Test/baseResults/reflection.vert.out +++ b/Test/baseResults/reflection.vert.out @@ -146,7 +146,7 @@ buf4: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0 nested2: offset -1, type ffffffff, size 208, index -1, binding -1, stages 0 VertexCollection: offset -1, type ffffffff, size 360, index -1, binding -1, stages 0 -Vertex attribute 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 attributeFloat3: offset 0, type 8b51, size 0, index 0, binding -1, stages 0 @@ -154,3 +154,5 @@ attributeFloat4: offset 0, type 8b52, size 0, index 0, binding -1, stages 0 attributeMat4: offset 0, type 8b5c, size 0, index 0, binding -1, stages 0 gl_InstanceID: offset 0, type 1404, size 0, index 0, binding -1, stages 0 +Pipeline output reflection: + diff --git a/Test/reflection.frag b/Test/reflection.frag new file mode 100644 index 00000000..92996531 --- /dev/null +++ b/Test/reflection.frag @@ -0,0 +1,8 @@ +#version 440 core + +in float inval; + +void main() +{ + float f = inval; +} diff --git a/Test/reflection.options.vert b/Test/reflection.options.vert index c671a625..5a8d2194 100644 --- a/Test/reflection.options.vert +++ b/Test/reflection.options.vert @@ -13,6 +13,8 @@ buffer VertexCollection { TriangleInfo t[5]; }; +out float outval; + void main() { float f; @@ -20,4 +22,5 @@ void main() f += t[gl_InstanceID].v[gl_InstanceID].position[gl_InstanceID]; f += t[gl_InstanceID].v[gl_InstanceID].normal[gl_InstanceID]; TriangleInfo tlocal[5] = t; + outval = f; } diff --git a/Test/reflection.vert b/Test/reflection.vert index 76ec5a30..939e52a3 100644 --- a/Test/reflection.vert +++ b/Test/reflection.vert @@ -174,6 +174,8 @@ buffer VertexCollection { TriangleInfo t[5]; }; +out float outval; + void main() { liveFunction1(image_ui2D, sampler_2D, sampler_2DMSArray); @@ -234,4 +236,6 @@ void main() f += t[gl_InstanceID].v[gl_InstanceID].position[gl_InstanceID]; f += t[gl_InstanceID].v[gl_InstanceID].normal[gl_InstanceID]; TriangleInfo tlocal[5] = t; + + outval = f; } diff --git a/Test/runtests b/Test/runtests index c01366e6..44d3dc35 100755 --- a/Test/runtests +++ b/Test/runtests @@ -32,8 +32,12 @@ 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 reflection.options.vert > $TARGETDIR/reflection.options.vert.out +$EXE -l -q -C --reflect-strict-array-suffix --reflect-basic-array-suffix --reflect-intermediate-io 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 +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 $EXE -D -Od -e main -l -q -C -V -Od hlsl.reflection.binding.frag > $TARGETDIR/hlsl.reflection.binding.frag.out diff --git a/glslang/MachineIndependent/ShaderLang.cpp b/glslang/MachineIndependent/ShaderLang.cpp index 3e77292f..a32d6053 100755 --- a/glslang/MachineIndependent/ShaderLang.cpp +++ b/glslang/MachineIndependent/ShaderLang.cpp @@ -1971,7 +1971,22 @@ bool TProgram::buildReflection(int opts) if (! linked || reflection) return false; - reflection = new TReflection((EShReflectionOptions)opts); + int firstStage = EShLangVertex, lastStage = EShLangFragment; + + if (opts & EShReflectionIntermediateIO) { + // if we're reflecting intermediate I/O, determine the first and last stage linked and use those as the + // boundaries for which stages generate pipeline inputs/outputs + firstStage = EShLangCount; + lastStage = 0; + for (int s = 0; s < EShLangCount; ++s) { + if (intermediate[s]) { + firstStage = std::min(firstStage, s); + lastStage = std::max(lastStage, s); + } + } + } + + reflection = new TReflection((EShReflectionOptions)opts, (EShLanguage)firstStage, (EShLanguage)lastStage); for (int s = 0; s < EShLangCount; ++s) { if (intermediate[s]) { @@ -1990,8 +2005,10 @@ int TProgram::getNumUniformVariables() const { return ref 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::getNumAttributes() const { return reflection->getNumAttributes(); } -const TObjectReflection& TProgram::getAttribute(int index) const { return reflection->getAttribute(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); } void TProgram::dumpReflection() { reflection->dump(); } diff --git a/glslang/MachineIndependent/reflection.cpp b/glslang/MachineIndependent/reflection.cpp index ec627a18..1d90fcf1 100644 --- a/glslang/MachineIndependent/reflection.cpp +++ b/glslang/MachineIndependent/reflection.cpp @@ -97,7 +97,7 @@ public: } } - void addAttribute(const TIntermSymbol& base) + void addPipeInput(const TIntermSymbol& base) { if (processedDerefs.find(&base) == processedDerefs.end()) { processedDerefs.insert(&base); @@ -107,8 +107,24 @@ public: TReflection::TNameToIndex::const_iterator it = reflection.nameToIndex.find(name.c_str()); if (it == reflection.nameToIndex.end()) { - reflection.nameToIndex[name.c_str()] = (int)reflection.indexToAttribute.size(); - reflection.indexToAttribute.push_back(TObjectReflection(name.c_str(), type, 0, mapToGlType(type), 0, 0)); + reflection.nameToIndex[name.c_str()] = (int)reflection.indexToPipeInput.size(); + reflection.indexToPipeInput.push_back(TObjectReflection(name.c_str(), type, 0, mapToGlType(type), 0, 0)); + } + } + } + + void addPipeOutput(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.c_str()); + if (it == reflection.nameToIndex.end()) { + reflection.nameToIndex[name.c_str()] = (int)reflection.indexToPipeOutput.size(); + reflection.indexToPipeOutput.push_back(TObjectReflection(name.c_str(), type, 0, mapToGlType(type), 0, 0)); } } } @@ -853,8 +869,11 @@ void TReflectionTraverser::visitSymbol(TIntermSymbol* base) if (base->getQualifier().storage == EvqUniform) addUniform(*base); - if (intermediate.getStage() == EShLangVertex && base->getQualifier().isPipeInput()) - addAttribute(*base); + if (intermediate.getStage() == reflection.firstStage && base->getQualifier().isPipeInput()) + addPipeInput(*base); + + if (intermediate.getStage() == reflection.lastStage && base->getQualifier().isPipeOutput()) + addPipeOutput(*base); } // @@ -964,9 +983,14 @@ 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("Pipeline input reflection:\n"); + for (size_t i = 0; i < indexToPipeInput.size(); ++i) + indexToPipeInput[i].dump(); + printf("\n"); + + printf("Pipeline output reflection:\n"); + for (size_t i = 0; i < indexToPipeOutput.size(); ++i) + indexToPipeOutput[i].dump(); printf("\n"); if (getLocalSize(0) > 1) { diff --git a/glslang/MachineIndependent/reflection.h b/glslang/MachineIndependent/reflection.h index c4464aab..ccd87f1a 100644 --- a/glslang/MachineIndependent/reflection.h +++ b/glslang/MachineIndependent/reflection.h @@ -55,7 +55,8 @@ class TReflectionTraverser; // The full reflection database class TReflection { public: - TReflection(EShReflectionOptions opts) : options(opts), badReflection(TObjectReflection::badReflection()) + TReflection(EShReflectionOptions opts, EShLanguage first, EShLanguage last) + : options(opts), firstStage(first), lastStage(last), badReflection(TObjectReflection::badReflection()) { for (int dim=0; dim<3; ++dim) localSize[dim] = 0; @@ -86,17 +87,27 @@ public: return badReflection; } - // for mapping an attribute index to the attribute's description - int getNumAttributes() { return (int)indexToAttribute.size(); } - const TObjectReflection& getAttribute(int i) const + // for mapping an pipeline input index to the input's description + int getNumPipeInputs() { return (int)indexToPipeInput.size(); } + const TObjectReflection& getPipeInput(int i) const { - if (i >= 0 && i < (int)indexToAttribute.size()) - return indexToAttribute[i]; + if (i >= 0 && i < (int)indexToPipeInput.size()) + return indexToPipeInput[i]; else return badReflection; } - // for mapping any name to its index (block names, uniform names and attribute names) + // for mapping an pipeline output index to the output's description + int getNumPipeOutputs() { return (int)indexToPipeOutput.size(); } + const TObjectReflection& getPipeOutput(int i) const + { + if (i >= 0 && i < (int)indexToPipeOutput.size()) + return indexToPipeOutput[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 { TNameToIndex::const_iterator it = nameToIndex.find(name); @@ -127,11 +138,15 @@ protected: EShReflectionOptions options; + EShLanguage firstStage; + EShLanguage lastStage; + TObjectReflection badReflection; // return for queries of -1 or generally out of range; has expected descriptions with in it for this 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; + TMapIndexToReflection indexToPipeInput; + TMapIndexToReflection indexToPipeOutput; unsigned int localSize[3]; }; diff --git a/glslang/Public/ShaderLang.h b/glslang/Public/ShaderLang.h index 9a1f4bf0..98529256 100755 --- a/glslang/Public/ShaderLang.h +++ b/glslang/Public/ShaderLang.h @@ -246,6 +246,7 @@ typedef enum { EShReflectionDefault = 0, // default is original behaviour before options were added 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 } EShReflectionOptions; // @@ -737,8 +738,10 @@ public: const TObjectReflection& getUniform(int index) const; int getNumUniformBlocks() const; const TObjectReflection& getUniformBlock(int index) const; - int getNumAttributes() const; - const TObjectReflection& getAttribute(int index) const; + int getNumPipeInputs() const; + const TObjectReflection& getPipeInput(int index) const; + int getNumPipeOutputs() const; + const TObjectReflection& getPipeOutput(int index) const; // Legacy Reflection Interface - expressed in terms of above interface int getNumLiveUniformVariables() const // can be used for glGetProgramiv(GL_ACTIVE_UNIFORMS) @@ -753,7 +756,7 @@ public: int getNumLiveAttributes() const // can be used for glGetProgramiv(GL_ACTIVE_ATTRIBUTES) { - return getNumAttributes(); + return getNumPipeInputs(); } int getUniformIndex(const char* name) const // can be used for glGetUniformIndices() @@ -828,17 +831,17 @@ public: const char* getAttributeName(int index) const // can be used for glGetActiveAttrib() { - return getAttribute(index).name.c_str(); + return getPipeInput(index).name.c_str(); } int getAttributeType(int index) const // can be used for glGetActiveAttrib() { - return getAttribute(index).glDefineType; + return getPipeInput(index).glDefineType; } const TType* getAttributeTType(int index) const // returns a TType* { - return getAttribute(index).getType(); + return getPipeInput(index).getType(); } void dumpReflection(); From 4a2aa822366ffc632900fec1d2650727fc3d0e2b Mon Sep 17 00:00:00 2001 From: baldurk Date: Tue, 29 Jan 2019 19:10:56 +0000 Subject: [PATCH 6/9] Reflect array stride, top-level array stride, and block member count --- Test/baseResults/hlsl.automap.frag.out | 20 +- .../hlsl.reflection.binding.frag.out | 8 +- Test/baseResults/hlsl.reflection.vert.out | 96 ++++----- Test/baseResults/hlsl.shift.per-set.frag.out | 20 +- Test/baseResults/reflection.options.vert.out | 18 +- Test/baseResults/reflection.vert.out | 196 +++++++++--------- Test/reflection.options.vert | 9 + glslang/MachineIndependent/reflection.cpp | 94 ++++++++- glslang/Public/ShaderLang.h | 12 +- 9 files changed, 283 insertions(+), 190 deletions(-) diff --git a/Test/baseResults/hlsl.automap.frag.out b/Test/baseResults/hlsl.automap.frag.out index 7a871a7b..51a15db4 100644 --- a/Test/baseResults/hlsl.automap.frag.out +++ b/Test/baseResults/hlsl.automap.frag.out @@ -3,8 +3,8 @@ Uniform reflection: t1: offset -1, type 8b5d, size 1, index -1, binding 11, stages 16 t2: offset -1, type 8b5e, size 1, index -1, binding 12, stages 16 t3: offset -1, type 8b5f, size 1, index -1, binding 13, stages 16 -t4.@data: offset 0, type 8b52, size 1, index 0, binding -1, stages 16 -t5.@data: offset 0, type 1405, size 0, index 1, binding -1, stages 16 +t4.@data: offset 0, type 8b52, size 1, index 0, binding -1, stages 16, arrayStride 16, topLevelArrayStride 16 +t5.@data: offset 0, type 1405, size 0, index 1, binding -1, stages 16, arrayStride 4, topLevelArrayStride 4 t6: offset -1, type 8dc2, size 1, index -1, binding 16, stages 16 s1: offset -1, type 0, size 1, index -1, binding 31, stages 16 s2: offset -1, type 0, size 1, index -1, binding 32, stages 16 @@ -12,18 +12,18 @@ u1: offset -1, type 904c, size 1, index -1, binding 41, stages 16 u2: offset -1, type 904d, size 1, index -1, binding 42, stages 16 u3: offset -1, type 904e, size 1, index -1, binding 43, stages 16 u4: offset -1, type 9051, size 1, index -1, binding 44, stages 16 -u5.@data: offset 0, type 1405, size 0, index 2, binding -1, stages 16 -u6.@data: offset 0, type 1406, size 1, index 3, binding -1, stages 16 +u5.@data: offset 0, type 1405, size 0, index 2, binding -1, stages 16, arrayStride 4, topLevelArrayStride 4 +u6.@data: offset 0, type 1406, size 1, index 3, binding -1, stages 16, arrayStride 4, topLevelArrayStride 4 cb1: offset 0, type 1404, size 1, index 4, binding -1, stages 16 tb1: offset 0, type 1404, size 1, index 5, binding -1, stages 16 Uniform block reflection: -t4: offset -1, type ffffffff, size 0, index -1, binding 14, stages 0 -t5: offset -1, type ffffffff, size 0, index -1, binding 15, stages 0 -u5: offset -1, type ffffffff, size 0, index -1, binding 45, stages 0 -u6: offset -1, type ffffffff, size 0, index -1, binding 46, stages 0 -cb: offset -1, type ffffffff, size 4, index -1, binding 51, stages 0 -tb: offset -1, type ffffffff, size 4, index -1, binding 17, stages 0 +t4: offset -1, type ffffffff, size 0, index -1, binding 14, stages 0, numMembers 1 +t5: offset -1, type ffffffff, size 0, index -1, binding 15, stages 0, numMembers 1 +u5: offset -1, type ffffffff, size 0, index -1, binding 45, stages 0, numMembers 1 +u6: offset -1, type ffffffff, size 0, index -1, binding 46, stages 0, numMembers 1 +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 Pipeline input reflection: diff --git a/Test/baseResults/hlsl.reflection.binding.frag.out b/Test/baseResults/hlsl.reflection.binding.frag.out index 3c0d134d..da452cf3 100644 --- a/Test/baseResults/hlsl.reflection.binding.frag.out +++ b/Test/baseResults/hlsl.reflection.binding.frag.out @@ -2,8 +2,8 @@ hlsl.reflection.binding.frag Uniform reflection: t1: offset -1, type 8b5d, size 1, index -1, binding 15, stages 16 s1: offset -1, type 0, size 1, index -1, binding 5, stages 16 -t1a: offset -1, type 8b5d, size 1, index -1, binding 16, stages 16 -s1a: offset -1, type 0, size 1, index -1, binding 6, stages 16 +t1a: offset -1, type 8b5d, size 1, index -1, binding 16, stages 16, arrayStride 4, topLevelArrayStride 4 +s1a: offset -1, type 0, size 1, index -1, binding 6, stages 16, arrayStride 4, topLevelArrayStride 4 c1_a: offset 0, type 8b52, size 1, index 0, binding -1, stages 16 c1_b: offset 16, type 1404, size 1, index 0, binding -1, stages 16 c1_c: offset 20, type 1406, size 1, index 0, binding -1, stages 16 @@ -12,8 +12,8 @@ c2_b: offset 16, type 1404, size 1, index 1, binding -1, stages 16 c2_c: offset 20, type 1406, size 1, index 1, binding -1, stages 16 Uniform block reflection: -cbuff1: offset -1, type ffffffff, size 24, index -1, binding 2, stages 0 -cbuff2: offset -1, type ffffffff, size 24, index -1, binding 3, stages 0 +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 Pipeline input reflection: diff --git a/Test/baseResults/hlsl.reflection.vert.out b/Test/baseResults/hlsl.reflection.vert.out index 92cb6ab1..97c8466a 100644 --- a/Test/baseResults/hlsl.reflection.vert.out +++ b/Test/baseResults/hlsl.reflection.vert.out @@ -7,65 +7,65 @@ scalarAfterm23: offset 48, type 1404, size 1, index 0, binding -1, stages 1 c_m23: offset 16, type 8b67, size 1, index 2, binding -1, stages 1 c_scalarAfterm23: offset 48, type 1404, size 1, index 2, binding -1, stages 1 scalarBeforeArray: offset 96, type 1404, size 1, index 0, binding -1, stages 1 -floatArray: offset 112, type 1406, size 5, index 0, binding -1, stages 1 +floatArray: offset 112, type 1406, size 5, index 0, binding -1, stages 1, arrayStride 16, topLevelArrayStride 16 scalarAfterArray: offset 192, type 1404, size 1, index 0, binding -1, stages 1 -m22: offset 208, type 8b5a, size 9, index 0, binding -1, stages 1 -dm22: offset 32, type 8b5a, size 4, index 1, binding -1, stages 1 +m22: offset 208, type 8b5a, size 9, index 0, binding -1, stages 1, arrayStride 32, topLevelArrayStride 32 +dm22: offset 32, type 8b5a, size 4, index 1, binding -1, stages 1, arrayStride 32, topLevelArrayStride 32 foo.n1.a: offset 0, type 1406, size 1, index 3, binding -1, stages 1 foo.n2.b: offset 16, type 1406, size 1, index 3, binding -1, stages 1 foo.n2.c: offset 20, type 1406, size 1, index 3, binding -1, stages 1 foo.n2.d: offset 24, type 1406, size 1, index 3, binding -1, stages 1 -deepA.d2.d1[2].va: offset 440, type 8b50, size 2, index 1, binding -1, stages 1 -deepB.d2.d1.va: offset 984, type 8b50, size 2, index 1, binding -1, stages 1 -deepB.d2.d1[0].va: offset 984, type 8b50, size 2, index 1, binding -1, stages 1 -deepB.d2.d1[1].va: offset 1016, type 8b50, size 2, index 1, binding -1, stages 1 -deepB.d2.d1[2].va: offset 1048, type 8b50, size 2, index 1, binding -1, stages 1 -deepB.d2.d1[3].va: offset 1080, type 8b50, size 2, index 1, binding -1, stages 1 -deepC.iv4: offset 1568, type 8b52, size 1, index 1, binding -1, stages 1 -deepC.d2.i: offset 1584, type 1404, size 1, index 1, binding -1, stages 1 -deepC.d2.d1[0].va: offset 1592, type 8b50, size 3, index 1, binding -1, stages 1 -deepC.d2.d1[0].b: offset 1616, type 8b56, size 1, index 1, binding -1, stages 1 -deepC.d2.d1[1].va: offset 1624, type 8b50, size 3, index 1, binding -1, stages 1 -deepC.d2.d1[1].b: offset 1648, type 8b56, size 1, index 1, binding -1, stages 1 -deepC.d2.d1[2].va: offset 1656, type 8b50, size 3, index 1, binding -1, stages 1 -deepC.d2.d1[2].b: offset 1680, type 8b56, size 1, index 1, binding -1, stages 1 -deepC.d2.d1[3].va: offset 1688, type 8b50, size 3, index 1, binding -1, stages 1 -deepC.d2.d1[3].b: offset 1712, type 8b56, size 1, index 1, binding -1, stages 1 -deepC.v3: offset 1728, type 8b54, size 1, index 1, binding -1, stages 1 -deepD[0].iv4: offset 2480, type 8b52, size 1, index 1, binding -1, stages 1 -deepD[0].d2.i: offset 2496, type 1404, size 1, index 1, binding -1, stages 1 -deepD[0].d2.d1[0].va: offset 2504, type 8b50, size 3, index 1, binding -1, stages 1 -deepD[0].d2.d1[0].b: offset 2528, type 8b56, size 1, index 1, binding -1, stages 1 -deepD[0].d2.d1[1].va: offset 2536, type 8b50, size 3, index 1, binding -1, stages 1 -deepD[0].d2.d1[1].b: offset 2560, type 8b56, size 1, index 1, binding -1, stages 1 -deepD[0].d2.d1[2].va: offset 2568, type 8b50, size 3, index 1, binding -1, stages 1 -deepD[0].d2.d1[2].b: offset 2592, type 8b56, size 1, index 1, binding -1, stages 1 -deepD[0].d2.d1[3].va: offset 2600, type 8b50, size 3, index 1, binding -1, stages 1 -deepD[0].d2.d1[3].b: offset 2624, type 8b56, size 1, index 1, binding -1, stages 1 -deepD[0].v3: offset 2640, type 8b54, size 1, index 1, binding -1, stages 1 -deepD[1].iv4: offset 2784, type 8b52, size 1, index 1, binding -1, stages 1 -deepD[1].d2.i: offset 2800, type 1404, size 1, index 1, binding -1, stages 1 -deepD[1].d2.d1[0].va: offset 2808, type 8b50, size 3, index 1, binding -1, stages 1 -deepD[1].d2.d1[0].b: offset 2832, type 8b56, size 1, index 1, binding -1, stages 1 -deepD[1].d2.d1[1].va: offset 2840, type 8b50, size 3, index 1, binding -1, stages 1 -deepD[1].d2.d1[1].b: offset 2864, type 8b56, size 1, index 1, binding -1, stages 1 -deepD[1].d2.d1[2].va: offset 2872, type 8b50, size 3, index 1, binding -1, stages 1 -deepD[1].d2.d1[2].b: offset 2896, type 8b56, size 1, index 1, binding -1, stages 1 -deepD[1].d2.d1[3].va: offset 2904, type 8b50, size 3, index 1, binding -1, stages 1 -deepD[1].d2.d1[3].b: offset 2928, type 8b56, size 1, index 1, binding -1, stages 1 -deepD[1].v3: offset 2944, type 8b54, size 1, index 1, binding -1, stages 1 +deepA.d2.d1[2].va: offset 440, type 8b50, size 2, index 1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 304 +deepB.d2.d1.va: offset 984, type 8b50, size 2, index 1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 304 +deepB.d2.d1[0].va: offset 984, type 8b50, size 2, index 1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 304 +deepB.d2.d1[1].va: offset 1016, type 8b50, size 2, index 1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 304 +deepB.d2.d1[2].va: offset 1048, type 8b50, size 2, index 1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 304 +deepB.d2.d1[3].va: offset 1080, type 8b50, size 2, index 1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 304 +deepC.iv4: offset 1568, type 8b52, size 1, index 1, binding -1, stages 1, topLevelArrayStride 304 +deepC.d2.i: offset 1584, type 1404, size 1, index 1, binding -1, stages 1, topLevelArrayStride 304 +deepC.d2.d1[0].va: offset 1592, type 8b50, size 3, index 1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 304 +deepC.d2.d1[0].b: offset 1616, type 8b56, size 1, index 1, binding -1, stages 1, topLevelArrayStride 304 +deepC.d2.d1[1].va: offset 1624, type 8b50, size 3, index 1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 304 +deepC.d2.d1[1].b: offset 1648, type 8b56, size 1, index 1, binding -1, stages 1, topLevelArrayStride 304 +deepC.d2.d1[2].va: offset 1656, type 8b50, size 3, index 1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 304 +deepC.d2.d1[2].b: offset 1680, type 8b56, size 1, index 1, binding -1, stages 1, topLevelArrayStride 304 +deepC.d2.d1[3].va: offset 1688, type 8b50, size 3, index 1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 304 +deepC.d2.d1[3].b: offset 1712, type 8b56, size 1, index 1, binding -1, stages 1, topLevelArrayStride 304 +deepC.v3: offset 1728, type 8b54, size 1, index 1, binding -1, stages 1, topLevelArrayStride 304 +deepD[0].iv4: offset 2480, type 8b52, size 1, index 1, binding -1, stages 1, topLevelArrayStride 304 +deepD[0].d2.i: offset 2496, type 1404, size 1, index 1, binding -1, stages 1, topLevelArrayStride 304 +deepD[0].d2.d1[0].va: offset 2504, type 8b50, size 3, index 1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 304 +deepD[0].d2.d1[0].b: offset 2528, type 8b56, size 1, index 1, binding -1, stages 1, topLevelArrayStride 304 +deepD[0].d2.d1[1].va: offset 2536, type 8b50, size 3, index 1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 304 +deepD[0].d2.d1[1].b: offset 2560, type 8b56, size 1, index 1, binding -1, stages 1, topLevelArrayStride 304 +deepD[0].d2.d1[2].va: offset 2568, type 8b50, size 3, index 1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 304 +deepD[0].d2.d1[2].b: offset 2592, type 8b56, size 1, index 1, binding -1, stages 1, topLevelArrayStride 304 +deepD[0].d2.d1[3].va: offset 2600, type 8b50, size 3, index 1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 304 +deepD[0].d2.d1[3].b: offset 2624, type 8b56, size 1, index 1, binding -1, stages 1, topLevelArrayStride 304 +deepD[0].v3: offset 2640, type 8b54, size 1, index 1, binding -1, stages 1, topLevelArrayStride 304 +deepD[1].iv4: offset 2784, type 8b52, size 1, index 1, binding -1, stages 1, topLevelArrayStride 304 +deepD[1].d2.i: offset 2800, type 1404, size 1, index 1, binding -1, stages 1, topLevelArrayStride 304 +deepD[1].d2.d1[0].va: offset 2808, type 8b50, size 3, index 1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 304 +deepD[1].d2.d1[0].b: offset 2832, type 8b56, size 1, index 1, binding -1, stages 1, topLevelArrayStride 304 +deepD[1].d2.d1[1].va: offset 2840, type 8b50, size 3, index 1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 304 +deepD[1].d2.d1[1].b: offset 2864, type 8b56, size 1, index 1, binding -1, stages 1, topLevelArrayStride 304 +deepD[1].d2.d1[2].va: offset 2872, type 8b50, size 3, index 1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 304 +deepD[1].d2.d1[2].b: offset 2896, type 8b56, size 1, index 1, binding -1, stages 1, topLevelArrayStride 304 +deepD[1].d2.d1[3].va: offset 2904, type 8b50, size 3, index 1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 304 +deepD[1].d2.d1[3].b: offset 2928, type 8b56, size 1, index 1, binding -1, stages 1, topLevelArrayStride 304 +deepD[1].v3: offset 2944, type 8b54, size 1, index 1, binding -1, stages 1, topLevelArrayStride 304 foo1: offset 0, type 1406, size 1, index 4, binding -1, stages 1 foo2: offset 0, type 1406, size 1, index 5, binding -1, stages 1 anonMember1: offset 0, type 8b51, size 1, index 0, binding -1, stages 1 uf1: offset 16, type 1406, size 1, index 1, binding -1, stages 1 Uniform block reflection: -nameless: offset -1, type ffffffff, size 496, index -1, binding -1, stages 0 -$Global: offset -1, type ffffffff, size 3088, index -1, binding -1, stages 0 -c_nameless: offset -1, type ffffffff, size 96, index -1, binding -1, stages 0 -nested: offset -1, type ffffffff, size 32, index -1, binding -1, stages 0 -abl: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0 -abl2: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0 +nameless: offset -1, type ffffffff, size 496, index -1, binding -1, stages 0, numMembers 9 +$Global: offset -1, type ffffffff, size 3088, index -1, binding -1, stages 0, numMembers 106 +c_nameless: offset -1, type ffffffff, size 96, index -1, binding -1, stages 0, numMembers 5 +nested: offset -1, type ffffffff, size 32, index -1, binding -1, stages 0, numMembers 4 +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 Pipeline input reflection: attributeFloat: offset 0, type 1406, size 0, index 0, binding -1, stages 0 diff --git a/Test/baseResults/hlsl.shift.per-set.frag.out b/Test/baseResults/hlsl.shift.per-set.frag.out index 02c6e4a2..a6aa7a01 100644 --- a/Test/baseResults/hlsl.shift.per-set.frag.out +++ b/Test/baseResults/hlsl.shift.per-set.frag.out @@ -203,8 +203,8 @@ Uniform reflection: t1: offset -1, type 8b5d, size 1, index -1, binding 21, stages 16 t2: offset -1, type 8b5e, size 1, index -1, binding 22, stages 16 t3: offset -1, type 8b5f, size 1, index -1, binding 26, stages 16 -t4.@data: offset 0, type 8b52, size 1, index 0, binding -1, stages 16 -t5.@data: offset 0, type 1405, size 0, index 1, binding -1, stages 16 +t4.@data: offset 0, type 8b52, size 1, index 0, binding -1, stages 16, arrayStride 16, topLevelArrayStride 16 +t5.@data: offset 0, type 1405, size 0, index 1, binding -1, stages 16, arrayStride 4, topLevelArrayStride 4 t6: offset -1, type 8dc2, size 1, index -1, binding 23, stages 16 s1: offset -1, type 0, size 1, index -1, binding 11, stages 16 s2: offset -1, type 0, size 1, index -1, binding 17, stages 16 @@ -212,19 +212,19 @@ u1: offset -1, type 904c, size 1, index -1, binding 31, stages 16 u2: offset -1, type 904d, size 1, index -1, binding 42, stages 16 u3: offset -1, type 904e, size 1, index -1, binding 43, stages 16 u4: offset -1, type 9051, size 1, index -1, binding 34, stages 16 -u5.@data: offset 0, type 1405, size 0, index 2, binding -1, stages 16 -u6.@data: offset 0, type 1406, size 1, index 3, binding -1, stages 16 +u5.@data: offset 0, type 1405, size 0, index 2, binding -1, stages 16, arrayStride 4, topLevelArrayStride 4 +u6.@data: offset 0, type 1406, size 1, index 3, binding -1, stages 16, arrayStride 4, topLevelArrayStride 4 cb1: offset 0, type 1404, size 1, index 4, binding -1, stages 16 tb1: offset 0, type 1404, size 1, index 5, binding -1, stages 16 ts6: offset -1, type 8b5f, size 1, index -1, binding 71, stages 16 Uniform block reflection: -t4: offset -1, type ffffffff, size 0, index -1, binding 21, stages 0 -t5: offset -1, type ffffffff, size 0, index -1, binding 22, stages 0 -u5: offset -1, type ffffffff, size 0, index -1, binding 44, stages 0 -u6: offset -1, type ffffffff, size 0, index -1, binding 34, stages 0 -cb: offset -1, type ffffffff, size 4, index -1, binding 51, stages 0 -tb: offset -1, type ffffffff, size 4, index -1, binding 27, stages 0 +t4: offset -1, type ffffffff, size 0, index -1, binding 21, stages 0, numMembers 1 +t5: offset -1, type ffffffff, size 0, index -1, binding 22, stages 0, numMembers 1 +u5: offset -1, type ffffffff, size 0, index -1, binding 44, stages 0, numMembers 1 +u6: offset -1, type ffffffff, size 0, index -1, binding 34, stages 0, numMembers 1 +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 Pipeline input reflection: diff --git a/Test/baseResults/reflection.options.vert.out b/Test/baseResults/reflection.options.vert.out index 178779a3..b9247a0a 100644 --- a/Test/baseResults/reflection.options.vert.out +++ b/Test/baseResults/reflection.options.vert.out @@ -1,14 +1,18 @@ reflection.options.vert Uniform reflection: -t[0].v[0].position[0]: offset 0, type 1406, size 3, index 0, binding -1, stages 1 -t[0].v[1].position[0]: offset 24, type 1406, size 3, index 0, binding -1, stages 1 -t[0].v[2].position[0]: offset 48, type 1406, size 3, index 0, binding -1, stages 1 -t[0].v[0].normal[0]: offset 12, type 1406, size 3, index 0, binding -1, stages 1 -t[0].v[1].normal[0]: offset 36, type 1406, size 3, index 0, binding -1, stages 1 -t[0].v[2].normal[0]: offset 60, type 1406, size 3, index 0, binding -1, stages 1 +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 +t[0].v[0].normal[0]: offset 12, type 1406, size 3, index 0, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72 +t[0].v[1].normal[0]: offset 36, type 1406, size 3, index 0, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72 +t[0].v[2].normal[0]: offset 60, type 1406, size 3, index 0, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72 +MultipleArrays.tri[0].v[0].position[0]: offset 0, type 1406, size 1, index 1, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72 +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: -VertexCollection: offset -1, type ffffffff, size 360, index -1, binding -1, stages 0 +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 Pipeline input reflection: gl_InstanceID: offset 0, type 1404, size 0, index 0, binding -1, stages 0 diff --git a/Test/baseResults/reflection.vert.out b/Test/baseResults/reflection.vert.out index fd3c8fe0..a7793c71 100644 --- a/Test/baseResults/reflection.vert.out +++ b/Test/baseResults/reflection.vert.out @@ -11,140 +11,140 @@ scalarAfterm23: offset 48, type 1404, size 1, index 0, binding -1, stages 1 c_m23: offset 16, type 8b67, size 1, index 2, binding -1, stages 1 c_scalarAfterm23: offset 64, type 1404, size 1, index 2, binding -1, stages 1 scalarBeforeArray: offset 96, type 1404, size 1, index 0, binding -1, stages 1 -floatArray: offset 112, type 1406, size 5, index 0, binding -1, stages 1 +floatArray: offset 112, type 1406, size 5, index 0, binding -1, stages 1, arrayStride 16, topLevelArrayStride 16 scalarAfterArray: offset 192, type 1404, size 1, index 0, binding -1, stages 1 named.memvec2: offset 48, type 8b50, size 1, index 1, binding -1, stages 1 named.memf1: offset 56, type 1406, size 1, index 1, binding -1, stages 1 named.memf2: offset 60, type 8b56, size 1, index 1, binding -1, stages 1 named.memf3: offset 64, type 1404, size 1, index 1, binding -1, stages 1 named.memvec2a: offset 72, type 8b50, size 1, index 1, binding -1, stages 1 -named.m22: offset 80, type 8b5a, size 7, index 1, binding -1, stages 1 -dm22: offset -1, type 8b5a, size 4, index -1, binding -1, stages 1 -m22: offset 208, type 8b5a, size 3, index 0, binding -1, stages 1 +named.m22: offset 80, type 8b5a, size 7, index 1, binding -1, stages 1, arrayStride 32, topLevelArrayStride 32 +dm22: offset -1, type 8b5a, size 4, index -1, binding -1, stages 1, arrayStride 16, topLevelArrayStride 16 +m22: offset 208, type 8b5a, size 3, index 0, binding -1, stages 1, arrayStride 32, topLevelArrayStride 32 nested.foo.n1.a: offset 0, type 1406, size 1, index 3, binding -1, stages 1 nested.foo.n2.b: offset 16, type 1406, size 1, index 3, binding -1, stages 1 nested.foo.n2.c: offset 20, type 1406, size 1, index 3, binding -1, stages 1 nested.foo.n2.d: offset 24, type 1406, size 1, index 3, binding -1, stages 1 -deepA[0].d2.d1[2].va: offset -1, type 8b50, size 2, index -1, binding -1, stages 1 -deepA[1].d2.d1[2].va: offset -1, type 8b50, size 2, index -1, binding -1, stages 1 -deepB[1].d2.d1[0].va: offset -1, type 8b50, size 2, index -1, binding -1, stages 1 -deepB[1].d2.d1[1].va: offset -1, type 8b50, size 2, index -1, binding -1, stages 1 -deepB[1].d2.d1[2].va: offset -1, type 8b50, size 2, index -1, binding -1, stages 1 -deepB[1].d2.d1[3].va: offset -1, type 8b50, size 2, index -1, binding -1, stages 1 -deepB[0].d2.d1[0].va: offset -1, type 8b50, size 2, index -1, binding -1, stages 1 -deepB[0].d2.d1[1].va: offset -1, type 8b50, size 2, index -1, binding -1, stages 1 -deepB[0].d2.d1[2].va: offset -1, type 8b50, size 2, index -1, binding -1, stages 1 -deepB[0].d2.d1[3].va: offset -1, type 8b50, size 2, index -1, binding -1, stages 1 -deepC[1].iv4: offset -1, type 8b52, size 1, index -1, binding -1, stages 1 -deepC[1].d2.i: offset -1, type 1404, size 1, index -1, binding -1, stages 1 -deepC[1].d2.d1[0].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1 -deepC[1].d2.d1[0].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1 -deepC[1].d2.d1[1].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1 -deepC[1].d2.d1[1].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1 -deepC[1].d2.d1[2].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1 -deepC[1].d2.d1[2].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1 -deepC[1].d2.d1[3].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1 -deepC[1].d2.d1[3].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1 -deepC[1].v3: offset -1, type 8b54, size 1, index -1, binding -1, stages 1 +deepA[0].d2.d1[2].va: offset -1, type 8b50, size 2, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 176 +deepA[1].d2.d1[2].va: offset -1, type 8b50, size 2, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 176 +deepB[1].d2.d1[0].va: offset -1, type 8b50, size 2, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 176 +deepB[1].d2.d1[1].va: offset -1, type 8b50, size 2, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 176 +deepB[1].d2.d1[2].va: offset -1, type 8b50, size 2, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 176 +deepB[1].d2.d1[3].va: offset -1, type 8b50, size 2, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 176 +deepB[0].d2.d1[0].va: offset -1, type 8b50, size 2, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 176 +deepB[0].d2.d1[1].va: offset -1, type 8b50, size 2, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 176 +deepB[0].d2.d1[2].va: offset -1, type 8b50, size 2, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 176 +deepB[0].d2.d1[3].va: offset -1, type 8b50, size 2, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 176 +deepC[1].iv4: offset -1, type 8b52, size 1, index -1, binding -1, stages 1, topLevelArrayStride 176 +deepC[1].d2.i: offset -1, type 1404, size 1, index -1, binding -1, stages 1, topLevelArrayStride 176 +deepC[1].d2.d1[0].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 176 +deepC[1].d2.d1[0].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1, topLevelArrayStride 176 +deepC[1].d2.d1[1].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 176 +deepC[1].d2.d1[1].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1, topLevelArrayStride 176 +deepC[1].d2.d1[2].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 176 +deepC[1].d2.d1[2].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1, topLevelArrayStride 176 +deepC[1].d2.d1[3].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 176 +deepC[1].d2.d1[3].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1, topLevelArrayStride 176 +deepC[1].v3: offset -1, type 8b54, size 1, index -1, binding -1, stages 1, topLevelArrayStride 176 deepD[0].iv4: offset -1, type 8b52, size 1, index -1, binding -1, stages 1 deepD[0].d2.i: offset -1, type 1404, size 1, index -1, binding -1, stages 1 -deepD[0].d2.d1[0].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1 +deepD[0].d2.d1[0].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 8 deepD[0].d2.d1[0].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1 -deepD[0].d2.d1[1].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1 +deepD[0].d2.d1[1].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 8 deepD[0].d2.d1[1].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1 -deepD[0].d2.d1[2].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1 +deepD[0].d2.d1[2].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 8 deepD[0].d2.d1[2].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1 -deepD[0].d2.d1[3].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1 +deepD[0].d2.d1[3].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 8 deepD[0].d2.d1[3].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1 deepD[0].v3: offset -1, type 8b54, size 1, index -1, binding -1, stages 1 deepD[1].iv4: offset -1, type 8b52, size 1, index -1, binding -1, stages 1 deepD[1].d2.i: offset -1, type 1404, size 1, index -1, binding -1, stages 1 -deepD[1].d2.d1[0].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1 +deepD[1].d2.d1[0].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 8 deepD[1].d2.d1[0].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1 -deepD[1].d2.d1[1].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1 +deepD[1].d2.d1[1].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 8 deepD[1].d2.d1[1].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1 -deepD[1].d2.d1[2].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1 +deepD[1].d2.d1[2].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 8 deepD[1].d2.d1[2].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1 -deepD[1].d2.d1[3].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1 +deepD[1].d2.d1[3].va: offset -1, type 8b50, size 3, index -1, binding -1, stages 1, arrayStride 8, topLevelArrayStride 8 deepD[1].d2.d1[3].b: offset -1, type 8b56, size 1, index -1, binding -1, stages 1 deepD[1].v3: offset -1, type 8b54, size 1, index -1, binding -1, stages 1 abl.foo: offset 0, type 1406, size 1, index 7, binding -1, stages 1 abl2.foo: offset 0, type 1406, size 1, index 11, binding -1, stages 1 -buf1.runtimeArray: offset 4, type 1406, size 4, index 12, binding -1, stages 1 -buf2.runtimeArray.c: offset 8, type 1406, size 1, index 13, binding -1, stages 1 -buf3.runtimeArray: offset 4, type 1406, size 0, index 14, binding -1, stages 1 -buf4.runtimeArray.c: offset 8, type 1406, size 1, index 15, binding -1, stages 1 +buf1.runtimeArray: offset 4, type 1406, size 4, index 12, binding -1, stages 1, arrayStride 4, topLevelArrayStride 4 +buf2.runtimeArray.c: offset 8, type 1406, size 1, index 13, binding -1, stages 1, topLevelArrayStride 12 +buf3.runtimeArray: offset 4, type 1406, size 0, index 14, binding -1, stages 1, arrayStride 4, topLevelArrayStride 4 +buf4.runtimeArray.c: offset 8, type 1406, size 1, index 15, binding -1, stages 1, topLevelArrayStride 12 nested2.a.n1.a: offset 16, type 1406, size 1, index 16, binding -1, stages 1 nested2.a.n2.b: offset 32, type 1406, size 1, index 16, binding -1, stages 1 nested2.a.n2.c: offset 36, type 1406, size 1, index 16, binding -1, stages 1 nested2.a.n2.d: offset 40, type 1406, size 1, index 16, binding -1, stages 1 -nested2.b[0].a: offset 48, type 1406, size 1, index 16, binding -1, stages 1 -nested2.b[1].a: offset 64, type 1406, size 1, index 16, binding -1, stages 1 -nested2.b[2].a: offset 80, type 1406, size 1, index 16, binding -1, stages 1 -nested2.b[3].a: offset 96, type 1406, size 1, index 16, binding -1, stages 1 -nested2.c.a: offset 112, type 1406, size 1, index 16, binding -1, stages 1 -nested2.d.a: offset 144, type 1406, size 1, index 16, binding -1, stages 1 -t.v.position: offset 0, type 1406, size 1, index 17, binding -1, stages 1 -t.v[0].position: offset 0, type 1406, size 3, index 17, binding -1, stages 1 -t.v[1].position: offset 24, type 1406, size 3, index 17, binding -1, stages 1 -t.v[2].position: offset 48, type 1406, size 3, index 17, binding -1, stages 1 -t.v[0].normal: offset 12, type 1406, size 3, index 17, binding -1, stages 1 -t.v[1].normal: offset 36, type 1406, size 3, index 17, binding -1, stages 1 -t.v[2].normal: offset 60, type 1406, size 3, index 17, binding -1, stages 1 -t[0].v[0].position: offset 0, type 1406, size 3, index 17, binding -1, stages 1 -t[0].v[0].normal: offset 12, type 1406, size 3, index 17, binding -1, stages 1 -t[0].v[1].position: offset 24, type 1406, size 3, index 17, binding -1, stages 1 -t[0].v[1].normal: offset 36, type 1406, size 3, index 17, binding -1, stages 1 -t[0].v[2].position: offset 48, type 1406, size 3, index 17, binding -1, stages 1 -t[0].v[2].normal: offset 60, type 1406, size 3, index 17, binding -1, stages 1 -t[1].v[0].position: offset 72, type 1406, size 3, index 17, binding -1, stages 1 -t[1].v[0].normal: offset 84, type 1406, size 3, index 17, binding -1, stages 1 -t[1].v[1].position: offset 96, type 1406, size 3, index 17, binding -1, stages 1 -t[1].v[1].normal: offset 108, type 1406, size 3, index 17, binding -1, stages 1 -t[1].v[2].position: offset 120, type 1406, size 3, index 17, binding -1, stages 1 -t[1].v[2].normal: offset 132, type 1406, size 3, index 17, binding -1, stages 1 -t[2].v[0].position: offset 144, type 1406, size 3, index 17, binding -1, stages 1 -t[2].v[0].normal: offset 156, type 1406, size 3, index 17, binding -1, stages 1 -t[2].v[1].position: offset 168, type 1406, size 3, index 17, binding -1, stages 1 -t[2].v[1].normal: offset 180, type 1406, size 3, index 17, binding -1, stages 1 -t[2].v[2].position: offset 192, type 1406, size 3, index 17, binding -1, stages 1 -t[2].v[2].normal: offset 204, type 1406, size 3, index 17, binding -1, stages 1 -t[3].v[0].position: offset 216, type 1406, size 3, index 17, binding -1, stages 1 -t[3].v[0].normal: offset 228, type 1406, size 3, index 17, binding -1, stages 1 -t[3].v[1].position: offset 240, type 1406, size 3, index 17, binding -1, stages 1 -t[3].v[1].normal: offset 252, type 1406, size 3, index 17, binding -1, stages 1 -t[3].v[2].position: offset 264, type 1406, size 3, index 17, binding -1, stages 1 -t[3].v[2].normal: offset 276, type 1406, size 3, index 17, binding -1, stages 1 -t[4].v[0].position: offset 288, type 1406, size 3, index 17, binding -1, stages 1 -t[4].v[0].normal: offset 300, type 1406, size 3, index 17, binding -1, stages 1 -t[4].v[1].position: offset 312, type 1406, size 3, index 17, binding -1, stages 1 -t[4].v[1].normal: offset 324, type 1406, size 3, index 17, binding -1, stages 1 -t[4].v[2].position: offset 336, type 1406, size 3, index 17, binding -1, stages 1 -t[4].v[2].normal: offset 348, type 1406, size 3, index 17, binding -1, stages 1 +nested2.b[0].a: offset 48, type 1406, size 1, index 16, binding -1, stages 1, topLevelArrayStride 16 +nested2.b[1].a: offset 64, type 1406, size 1, index 16, binding -1, stages 1, topLevelArrayStride 16 +nested2.b[2].a: offset 80, type 1406, size 1, index 16, binding -1, stages 1, topLevelArrayStride 16 +nested2.b[3].a: offset 96, type 1406, size 1, index 16, binding -1, stages 1, topLevelArrayStride 16 +nested2.c.a: offset 112, type 1406, size 1, index 16, binding -1, stages 1, topLevelArrayStride 16 +nested2.d.a: offset 144, type 1406, size 1, index 16, binding -1, stages 1, topLevelArrayStride 16 +t.v.position: offset 0, type 1406, size 1, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72 +t.v[0].position: offset 0, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72 +t.v[1].position: offset 24, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72 +t.v[2].position: offset 48, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72 +t.v[0].normal: offset 12, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72 +t.v[1].normal: offset 36, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72 +t.v[2].normal: offset 60, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72 +t[0].v[0].position: offset 0, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72 +t[0].v[0].normal: offset 12, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72 +t[0].v[1].position: offset 24, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72 +t[0].v[1].normal: offset 36, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72 +t[0].v[2].position: offset 48, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72 +t[0].v[2].normal: offset 60, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72 +t[1].v[0].position: offset 72, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72 +t[1].v[0].normal: offset 84, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72 +t[1].v[1].position: offset 96, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72 +t[1].v[1].normal: offset 108, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72 +t[1].v[2].position: offset 120, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72 +t[1].v[2].normal: offset 132, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72 +t[2].v[0].position: offset 144, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72 +t[2].v[0].normal: offset 156, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72 +t[2].v[1].position: offset 168, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72 +t[2].v[1].normal: offset 180, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72 +t[2].v[2].position: offset 192, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72 +t[2].v[2].normal: offset 204, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72 +t[3].v[0].position: offset 216, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72 +t[3].v[0].normal: offset 228, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72 +t[3].v[1].position: offset 240, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72 +t[3].v[1].normal: offset 252, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72 +t[3].v[2].position: offset 264, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72 +t[3].v[2].normal: offset 276, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72 +t[4].v[0].position: offset 288, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72 +t[4].v[0].normal: offset 300, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72 +t[4].v[1].position: offset 312, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72 +t[4].v[1].normal: offset 324, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72 +t[4].v[2].position: offset 336, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72 +t[4].v[2].normal: offset 348, type 1406, size 3, index 17, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72 anonMember1: offset 0, type 8b51, size 1, index 0, binding -1, stages 1 uf1: offset -1, type 1406, size 1, index -1, binding -1, stages 1 uf2: offset -1, type 1406, size 1, index -1, binding -1, stages 1 named.member3: offset 32, type 8b52, size 1, index 1, binding -1, stages 1 Uniform block reflection: -nameless: offset -1, type ffffffff, size 496, index -1, binding -1, stages 0 -named: offset -1, type ffffffff, size 304, index -1, binding -1, stages 0 -c_nameless: offset -1, type ffffffff, size 112, index -1, binding -1, stages 0 -nested: offset -1, type ffffffff, size 32, index -1, binding -1, stages 0 -abl[0]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0 -abl[1]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0 -abl[2]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0 -abl[3]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0 -abl2[0]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0 -abl2[1]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0 -abl2[2]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0 -abl2[3]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0 -buf1: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0 -buf2: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0 -buf3: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0 -buf4: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0 -nested2: offset -1, type ffffffff, size 208, index -1, binding -1, stages 0 -VertexCollection: offset -1, type ffffffff, size 360, index -1, binding -1, stages 0 +nameless: offset -1, type ffffffff, size 496, index -1, binding -1, stages 0, numMembers 9 +named: offset -1, type ffffffff, size 304, index -1, binding -1, stages 0, numMembers 10 +c_nameless: offset -1, type ffffffff, size 112, index -1, binding -1, stages 0, numMembers 5 +nested: offset -1, type ffffffff, size 32, index -1, binding -1, stages 0, numMembers 4 +abl[0]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0, numMembers 1 +abl[1]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0, numMembers 1 +abl[2]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0, numMembers 1 +abl[3]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0, numMembers 1 +abl2[0]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0, numMembers 1 +abl2[1]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0, numMembers 1 +abl2[2]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0, numMembers 1 +abl2[3]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0, numMembers 1 +buf1: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0, numMembers 2 +buf2: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0, numMembers 4 +buf3: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0, numMembers 2 +buf4: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0, numMembers 4 +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 Pipeline input reflection: attributeFloat: offset 0, type 1406, size 0, index 0, binding -1, stages 0 diff --git a/Test/reflection.options.vert b/Test/reflection.options.vert index 5a8d2194..cfb2b0d4 100644 --- a/Test/reflection.options.vert +++ b/Test/reflection.options.vert @@ -13,6 +13,12 @@ buffer VertexCollection { TriangleInfo t[5]; }; +buffer MultipleArrays { + TriangleInfo tri[5]; + VertexInfo vert[5]; + float f[5]; +} multiarray; + out float outval; void main() @@ -21,6 +27,9 @@ void main() f += t[0].v[0].position[0]; f += t[gl_InstanceID].v[gl_InstanceID].position[gl_InstanceID]; f += t[gl_InstanceID].v[gl_InstanceID].normal[gl_InstanceID]; + f += multiarray.tri[gl_InstanceID].v[0].position[0]; + f += multiarray.vert[gl_InstanceID].position[0]; + f += multiarray.f[gl_InstanceID]; TriangleInfo tlocal[5] = t; outval = f; } diff --git a/glslang/MachineIndependent/reflection.cpp b/glslang/MachineIndependent/reflection.cpp index 1d90fcf1..b235b465 100644 --- a/glslang/MachineIndependent/reflection.cpp +++ b/glslang/MachineIndependent/reflection.cpp @@ -93,7 +93,7 @@ public: // Use a degenerate (empty) set of dereferences to immediately put as at the end of // the dereference change expected by blowUpActiveAggregate. TList derefs; - blowUpActiveAggregate(base.getType(), base.getName(), derefs, derefs.end(), -1, -1, 0); + blowUpActiveAggregate(base.getType(), base.getName(), derefs, derefs.end(), -1, -1, 0, 0); } } @@ -229,6 +229,36 @@ public: return lastOffset + lastMemberSize; } + // count the total number of leaf members from iterating out of a block type + int countAggregateMembers(const TType& parentType) + { + if (! parentType.isStruct()) + return 1; + + const bool strictArraySuffix = (reflection.options & EShReflectionStrictArraySuffix); + + bool blockParent = (parentType.getBasicType() == EbtBlock && parentType.getQualifier().storage == EvqBuffer); + + const TTypeList &memberList = *parentType.getStruct(); + + int ret = 0; + + for (size_t i = 0; i < memberList.size(); i++) + { + const TType &memberType = *memberList[i].type; + int numMembers = countAggregateMembers(memberType); + // for sized arrays of structs, apply logic to expand out the same as we would below in + // blowUpActiveAggregate + if (memberType.isArray() && ! memberType.getArraySizes()->hasUnsized() && memberType.isStruct()) { + if (! strictArraySuffix || ! blockParent) + numMembers *= memberType.getArraySizes()->getCumulativeSize(); + } + ret += numMembers; + } + + return ret; + } + // Traverse the provided deref chain, including the base, and // - build a full reflection-granularity name, array size, etc. entry out of it, if it goes down to that granularity // - recursively expand any variable array index in the middle of that traversal @@ -237,7 +267,8 @@ public: // arraySize tracks, just for the final dereference in the chain, if there was a specific known size. // 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& derefs, - TList::const_iterator deref, int offset, int blockIndex, int arraySize) + TList::const_iterator deref, int offset, int blockIndex, int arraySize, + int topLevelArrayStride) { // when strictArraySuffix is enabled, we closely follow the rules from ARB_program_interface_query. // Broadly: @@ -260,6 +291,9 @@ public: case EOpIndexIndirect: { int stride = getArrayStride(baseType, visitNode->getLeft()->getType()); + if (topLevelArrayStride == 0) + topLevelArrayStride = stride; + // Visit all the indices of this array, and for each one add on the remaining dereferencing for (int i = 0; i < std::max(visitNode->getLeft()->getType().getOuterArraySize(), 1); ++i) { TString newBaseName = name; @@ -270,16 +304,19 @@ public: TList::const_iterator nextDeref = deref; ++nextDeref; TType derefType(*terminalType, 0); - blowUpActiveAggregate(derefType, newBaseName, derefs, nextDeref, offset, blockIndex, arraySize); + blowUpActiveAggregate(derefType, newBaseName, derefs, nextDeref, offset, blockIndex, arraySize, + topLevelArrayStride); if (offset >= 0) - offset += stride; + offset += stride; } // it was all completed in the recursive calls above return; } - case EOpIndexDirect: + case EOpIndexDirect: { + int stride = getArrayStride(baseType, visitNode->getLeft()->getType()); + index = visitNode->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst(); if (strictArraySuffix && blockParent) { name.append(TString("[0]")); @@ -287,10 +324,15 @@ public: name.append(TString("[") + String(index) + "]"); if (offset >= 0) - offset += getArrayStride(baseType, visitNode->getLeft()->getType()) * index; + offset += stride * index; } + + if (topLevelArrayStride == 0) + topLevelArrayStride = stride; + blockParent = false; break; + } case EOpIndexDirectStruct: index = visitNode->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst(); if (offset >= 0) @@ -317,6 +359,9 @@ public: if (offset >= 0) stride = getArrayStride(baseType, *terminalType); + if (topLevelArrayStride == 0) + topLevelArrayStride = stride; + int arrayIterateSize = std::max(terminalType->getOuterArraySize(), 1); // for top-level arrays in blocks, only expand [0] to avoid explosion of items @@ -329,7 +374,9 @@ public: TType derefType(*terminalType, 0); if (offset >= 0) offset = baseOffset + stride * i; - blowUpActiveAggregate(derefType, newBaseName, derefs, derefs.end(), offset, blockIndex, 0); + + blowUpActiveAggregate(derefType, newBaseName, derefs, derefs.end(), offset, blockIndex, 0, + topLevelArrayStride); } } else { // Visit all members of this aggregate, and for each one, @@ -349,7 +396,15 @@ public: TType derefType(*terminalType, i); if (offset >= 0) offset = baseOffset + memberOffsets[i]; - blowUpActiveAggregate(derefType, newBaseName, derefs, derefs.end(), offset, blockIndex, 0); + + int arrayStride = topLevelArrayStride; + if (terminalType->getBasicType() == EbtBlock && terminalType->getQualifier().storage == EvqBuffer && + derefType.isArray()) { + arrayStride = getArrayStride(baseType, derefType); + } + + blowUpActiveAggregate(derefType, newBaseName, derefs, derefs.end(), offset, blockIndex, 0, + arrayStride); } } @@ -371,9 +426,17 @@ public: 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)); + if (terminalType->isArray()) { + reflection.indexToUniform.back().arrayStride = getArrayStride(baseType, *terminalType); + if (topLevelArrayStride == 0) + topLevelArrayStride = reflection.indexToUniform.back().arrayStride; + } + + reflection.indexToUniform.back().topLevelArrayStride = topLevelArrayStride; } else if (arraySize > 1) { int& reflectedArraySize = reflection.indexToUniform[it->second].size; reflectedArraySize = std::max(arraySize, reflectedArraySize); @@ -465,7 +528,7 @@ public: else baseName = base->getName(); } - blowUpActiveAggregate(base->getType(), baseName, derefs, derefs.begin(), offset, blockIndex, arraySize); + blowUpActiveAggregate(base->getType(), baseName, derefs, derefs.begin(), offset, blockIndex, arraySize, 0); } int addBlockName(const TString& name, const TType& type, int size) @@ -476,6 +539,8 @@ public: blockIndex = (int)reflection.indexToUniformBlock.size(); reflection.nameToIndex[name.c_str()] = blockIndex; reflection.indexToUniformBlock.push_back(TObjectReflection(name.c_str(), type, -1, -1, size, -1)); + + reflection.indexToUniformBlock.back().numMembers = countAggregateMembers(type); } else blockIndex = it->second; @@ -883,7 +948,7 @@ void TReflectionTraverser::visitSymbol(TIntermSymbol* base) TObjectReflection::TObjectReflection(const std::string &pName, const TType &pType, int pOffset, int pGLDefineType, int pSize, int pIndex) : name(pName), offset(pOffset), glDefineType(pGLDefineType), size(pSize), index(pIndex), counterIndex(-1), - stages(EShLanguageMask(0)), type(pType.clone()) + numMembers(-1), arrayStride(0), topLevelArrayStride(0), stages(EShLanguageMask(0)), type(pType.clone()) { } @@ -902,6 +967,15 @@ void TObjectReflection::dump() const if (counterIndex != -1) printf(", counter %d", counterIndex); + if (numMembers != -1) + printf(", numMembers %d", numMembers); + + if (arrayStride != 0) + printf(", arrayStride %d", arrayStride); + + if (topLevelArrayStride != 0) + printf(", topLevelArrayStride %d", topLevelArrayStride); + printf("\n"); } diff --git a/glslang/Public/ShaderLang.h b/glslang/Public/ShaderLang.h index 98529256..827de4eb 100755 --- a/glslang/Public/ShaderLang.h +++ b/glslang/Public/ShaderLang.h @@ -626,14 +626,20 @@ public: std::string name; int offset; int glDefineType; - int size; // data size in bytes for a block, array size for a (non-block) object that's an array + int size; // data size in bytes for a block, array size for a (non-block) object that's an array int index; int counterIndex; + int numMembers; + int arrayStride; // stride of an array variable + int topLevelArrayStride; // stride of the top-level variable in a storage buffer member EShLanguageMask stages; protected: - TObjectReflection() : - offset(-1), glDefineType(-1), size(-1), index(-1), counterIndex(-1), stages(EShLanguageMask(0)), type(nullptr) { } + TObjectReflection() + : offset(-1), glDefineType(-1), size(-1), index(-1), counterIndex(-1), numMembers(-1), arrayStride(0), + topLevelArrayStride(0), stages(EShLanguageMask(0)), type(nullptr) + { + } const TType* type; }; From 657acc0c4077b57a950d04bcf9dab509e1f50525 Mon Sep 17 00:00:00 2001 From: baldurk Date: Wed, 30 Jan 2019 14:18:43 +0000 Subject: [PATCH 7/9] Add option to reflect buffer blocks & variables separately to uniforms * Also note the uniform indices of atomic counter buffers --- StandAlone/StandAlone.cpp | 3 + Test/baseResults/hlsl.automap.frag.out | 4 ++ .../hlsl.reflection.binding.frag.out | 4 ++ Test/baseResults/hlsl.reflection.vert.out | 4 ++ Test/baseResults/hlsl.shift.per-set.frag.out | 4 ++ Test/baseResults/reflection.frag.out | 4 ++ Test/baseResults/reflection.options.frag.out | 4 ++ Test/baseResults/reflection.options.vert.out | 10 +++- Test/baseResults/reflection.vert.out | 4 ++ Test/reflection.options.vert | 7 +++ Test/runtests | 4 +- glslang/MachineIndependent/ShaderLang.cpp | 22 ++++--- glslang/MachineIndependent/reflection.cpp | 59 +++++++++++++------ glslang/MachineIndependent/reflection.h | 47 +++++++++++++++ glslang/Public/ShaderLang.h | 7 +++ 15 files changed, 158 insertions(+), 29 deletions(-) diff --git a/StandAlone/StandAlone.cpp b/StandAlone/StandAlone.cpp index 7588320f..52fd80c6 100644 --- a/StandAlone/StandAlone.cpp +++ b/StandAlone/StandAlone.cpp @@ -530,6 +530,8 @@ void ProcessArguments(std::vector>& 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" diff --git a/Test/baseResults/hlsl.automap.frag.out b/Test/baseResults/hlsl.automap.frag.out index 51a15db4..fb914ece 100644 --- a/Test/baseResults/hlsl.automap.frag.out +++ b/Test/baseResults/hlsl.automap.frag.out @@ -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: diff --git a/Test/baseResults/hlsl.reflection.binding.frag.out b/Test/baseResults/hlsl.reflection.binding.frag.out index da452cf3..8d5743ea 100644 --- a/Test/baseResults/hlsl.reflection.binding.frag.out +++ b/Test/baseResults/hlsl.reflection.binding.frag.out @@ -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: diff --git a/Test/baseResults/hlsl.reflection.vert.out b/Test/baseResults/hlsl.reflection.vert.out index 97c8466a..c9367480 100644 --- a/Test/baseResults/hlsl.reflection.vert.out +++ b/Test/baseResults/hlsl.reflection.vert.out @@ -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 diff --git a/Test/baseResults/hlsl.shift.per-set.frag.out b/Test/baseResults/hlsl.shift.per-set.frag.out index a6aa7a01..a0eb574b 100644 --- a/Test/baseResults/hlsl.shift.per-set.frag.out +++ b/Test/baseResults/hlsl.shift.per-set.frag.out @@ -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: diff --git a/Test/baseResults/reflection.frag.out b/Test/baseResults/reflection.frag.out index d3d90a27..65a8786d 100644 --- a/Test/baseResults/reflection.frag.out +++ b/Test/baseResults/reflection.frag.out @@ -3,6 +3,10 @@ Uniform reflection: Uniform block reflection: +Buffer variable reflection: + +Buffer block reflection: + Pipeline input reflection: Pipeline output reflection: diff --git a/Test/baseResults/reflection.options.frag.out b/Test/baseResults/reflection.options.frag.out index d0fe56e3..a0cecef6 100644 --- a/Test/baseResults/reflection.options.frag.out +++ b/Test/baseResults/reflection.options.frag.out @@ -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 diff --git a/Test/baseResults/reflection.options.vert.out b/Test/baseResults/reflection.options.vert.out index b9247a0a..add73961 100644 --- a/Test/baseResults/reflection.options.vert.out +++ b/Test/baseResults/reflection.options.vert.out @@ -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 diff --git a/Test/baseResults/reflection.vert.out b/Test/baseResults/reflection.vert.out index a7793c71..6baa8ac0 100644 --- a/Test/baseResults/reflection.vert.out +++ b/Test/baseResults/reflection.vert.out @@ -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 diff --git a/Test/reflection.options.vert b/Test/reflection.options.vert index cfb2b0d4..001537e0 100644 --- a/Test/reflection.options.vert +++ b/Test/reflection.options.vert @@ -19,6 +19,11 @@ buffer MultipleArrays { float f[5]; } multiarray; +uniform UBO { + VertexInfo verts[2]; + float flt[8]; +} ubo; + out float outval; void main() @@ -30,6 +35,8 @@ void main() f += multiarray.tri[gl_InstanceID].v[0].position[0]; f += multiarray.vert[gl_InstanceID].position[0]; f += multiarray.f[gl_InstanceID]; + f += ubo.verts[gl_InstanceID].position[0]; + f += ubo.flt[gl_InstanceID]; TriangleInfo tlocal[5] = t; outval = f; } diff --git a/Test/runtests b/Test/runtests index 44d3dc35..d3705034 100755 --- a/Test/runtests +++ b/Test/runtests @@ -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 diff --git a/glslang/MachineIndependent/ShaderLang.cpp b/glslang/MachineIndependent/ShaderLang.cpp index a32d6053..63d3fc46 100755 --- a/glslang/MachineIndependent/ShaderLang.cpp +++ b/glslang/MachineIndependent/ShaderLang.cpp @@ -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(); } diff --git a/glslang/MachineIndependent/reflection.cpp b/glslang/MachineIndependent/reflection.cpp index b235b465..a7d9b13a 100644 --- a/glslang/MachineIndependent/reflection.cpp +++ b/glslang/MachineIndependent/reflection.cpp @@ -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 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& derefs, TList::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(indexToUniform[i].stages | 1 << intermediate.getStage()); } + + for (int i = 0; i < int(indexToBufferVariable.size()); ++i) { + indexToBufferVariable[i].stages = + static_cast(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(); diff --git a/glslang/MachineIndependent/reflection.h b/glslang/MachineIndependent/reflection.h index ccd87f1a..44b17a05 100644 --- a/glslang/MachineIndependent/reflection.h +++ b/glslang/MachineIndependent/reflection.h @@ -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 TNameToIndex; typedef std::map TNameToIndex; typedef std::vector TMapIndexToReflection; + typedef std::vector 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]; }; diff --git a/glslang/Public/ShaderLang.h b/glslang/Public/ShaderLang.h index 827de4eb..7aaaaf3a 100755 --- a/glslang/Public/ShaderLang.h +++ b/glslang/Public/ShaderLang.h @@ -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) From a972e73ad78904064b2155a06550fdf20fcd33b6 Mon Sep 17 00:00:00 2001 From: baldurk Date: Wed, 30 Jan 2019 15:34:02 +0000 Subject: [PATCH 8/9] Add option to reflect all block members, inactive or active. * The stages mask is more fine-grained, and each variable or block's mask indicates which stages it's active in. --- StandAlone/StandAlone.cpp | 3 + Test/baseResults/hlsl.automap.frag.out | 14 +-- .../hlsl.reflection.binding.frag.out | 6 +- Test/baseResults/hlsl.reflection.vert.out | 22 ++-- Test/baseResults/hlsl.shift.per-set.frag.out | 14 +-- .../baseResults/reflection.linked.options.out | 21 ++++ Test/baseResults/reflection.linked.out | 20 ++++ Test/baseResults/reflection.options.frag.out | 2 +- Test/baseResults/reflection.options.vert.out | 32 +++-- Test/baseResults/reflection.vert.out | 48 ++++---- Test/reflection.linked.frag | 19 +++ Test/reflection.linked.vert | 19 +++ Test/reflection.options.vert | 2 + Test/reflection.vert | 1 + Test/runtests | 8 +- glslang/MachineIndependent/reflection.cpp | 110 ++++++++++++++++-- glslang/Public/ShaderLang.h | 1 + 17 files changed, 265 insertions(+), 77 deletions(-) create mode 100644 Test/baseResults/reflection.linked.options.out create mode 100644 Test/baseResults/reflection.linked.out create mode 100644 Test/reflection.linked.frag create mode 100644 Test/reflection.linked.vert diff --git a/StandAlone/StandAlone.cpp b/StandAlone/StandAlone.cpp index 52fd80c6..8906493d 100644 --- a/StandAlone/StandAlone.cpp +++ b/StandAlone/StandAlone.cpp @@ -532,6 +532,8 @@ void ProcessArguments(std::vector>& workItem ReflectOptions |= EShReflectionIntermediateIO; } else if (lowerword == "reflect-separate-buffers") { ReflectOptions |= EShReflectionSeparateBuffers; + } else if (lowerword == "reflect-all-block-variables") { + ReflectOptions |= EShReflectionAllBlockVariables; } else if (lowerword == "resource-set-bindings" || // synonyms lowerword == "resource-set-binding" || lowerword == "rsb") { @@ -1532,6 +1534,7 @@ void usage() " --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" + " --reflect-all-block-variables reflect all variables in blocks, whether inactive or active\n" " --resource-set-binding [stage] name set binding\n" " set descriptor set and binding for\n" " individual resources\n" diff --git a/Test/baseResults/hlsl.automap.frag.out b/Test/baseResults/hlsl.automap.frag.out index fb914ece..48f232c6 100644 --- a/Test/baseResults/hlsl.automap.frag.out +++ b/Test/baseResults/hlsl.automap.frag.out @@ -18,12 +18,12 @@ cb1: offset 0, type 1404, size 1, index 4, binding -1, stages 16 tb1: offset 0, type 1404, size 1, index 5, binding -1, stages 16 Uniform block reflection: -t4: offset -1, type ffffffff, size 0, index -1, binding 14, stages 0, numMembers 1 -t5: offset -1, type ffffffff, size 0, index -1, binding 15, stages 0, numMembers 1 -u5: offset -1, type ffffffff, size 0, index -1, binding 45, stages 0, numMembers 1 -u6: offset -1, type ffffffff, size 0, index -1, binding 46, stages 0, numMembers 1 -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 +t4: offset -1, type ffffffff, size 0, index -1, binding 14, stages 16, numMembers 1 +t5: offset -1, type ffffffff, size 0, index -1, binding 15, stages 16, numMembers 1 +u5: offset -1, type ffffffff, size 0, index -1, binding 45, stages 16, numMembers 1 +u6: offset -1, type ffffffff, size 0, index -1, binding 46, stages 16, numMembers 1 +cb: offset -1, type ffffffff, size 4, index -1, binding 51, stages 16, numMembers 1 +tb: offset -1, type ffffffff, size 4, index -1, binding 17, stages 16, numMembers 1 Buffer variable reflection: @@ -32,5 +32,5 @@ Buffer block reflection: Pipeline input reflection: Pipeline output reflection: -@entryPointOutput: offset 0, type 8b52, size 0, index 0, binding -1, stages 0 +@entryPointOutput: offset 0, type 8b52, size 0, index 0, binding -1, stages 16 diff --git a/Test/baseResults/hlsl.reflection.binding.frag.out b/Test/baseResults/hlsl.reflection.binding.frag.out index 8d5743ea..484cfc6a 100644 --- a/Test/baseResults/hlsl.reflection.binding.frag.out +++ b/Test/baseResults/hlsl.reflection.binding.frag.out @@ -12,8 +12,8 @@ c2_b: offset 16, type 1404, size 1, index 1, binding -1, stages 16 c2_c: offset 20, type 1406, size 1, index 1, binding -1, stages 16 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 +cbuff1: offset -1, type ffffffff, size 24, index -1, binding 2, stages 16, numMembers 3 +cbuff2: offset -1, type ffffffff, size 24, index -1, binding 3, stages 16, numMembers 3 Buffer variable reflection: @@ -22,5 +22,5 @@ Buffer block reflection: Pipeline input reflection: Pipeline output reflection: -psout.Color: offset 0, type 8b52, size 0, index 0, binding -1, stages 0 +psout.Color: offset 0, type 8b52, size 0, index 0, binding -1, stages 16 diff --git a/Test/baseResults/hlsl.reflection.vert.out b/Test/baseResults/hlsl.reflection.vert.out index c9367480..30c6c9fe 100644 --- a/Test/baseResults/hlsl.reflection.vert.out +++ b/Test/baseResults/hlsl.reflection.vert.out @@ -60,23 +60,23 @@ anonMember1: offset 0, type 8b51, size 1, index 0, binding -1, stages 1 uf1: offset 16, type 1406, size 1, index 1, binding -1, stages 1 Uniform block reflection: -nameless: offset -1, type ffffffff, size 496, index -1, binding -1, stages 0, numMembers 9 -$Global: offset -1, type ffffffff, size 3088, index -1, binding -1, stages 0, numMembers 106 -c_nameless: offset -1, type ffffffff, size 96, index -1, binding -1, stages 0, numMembers 5 -nested: offset -1, type ffffffff, size 32, index -1, binding -1, stages 0, numMembers 4 -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 +nameless: offset -1, type ffffffff, size 496, index -1, binding -1, stages 1, numMembers 9 +$Global: offset -1, type ffffffff, size 3088, index -1, binding -1, stages 1, numMembers 106 +c_nameless: offset -1, type ffffffff, size 96, index -1, binding -1, stages 1, numMembers 5 +nested: offset -1, type ffffffff, size 32, index -1, binding -1, stages 1, numMembers 4 +abl: offset -1, type ffffffff, size 4, index -1, binding -1, stages 1, numMembers 1 +abl2: offset -1, type ffffffff, size 4, index -1, binding -1, stages 1, 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 -attributeFloat3: offset 0, type 8b51, size 0, index 0, binding -1, stages 0 -attributeFloat4: offset 0, type 8b52, size 0, index 0, binding -1, stages 0 -attributeMat4: offset 0, type 8b5c, size 0, index 0, binding -1, stages 0 +attributeFloat: offset 0, type 1406, size 0, index 0, binding -1, stages 1 +attributeFloat2: offset 0, type 8b50, size 0, index 0, binding -1, stages 1 +attributeFloat3: offset 0, type 8b51, size 0, index 0, binding -1, stages 1 +attributeFloat4: offset 0, type 8b52, size 0, index 0, binding -1, stages 1 +attributeMat4: offset 0, type 8b5c, size 0, index 0, binding -1, stages 1 Pipeline output reflection: diff --git a/Test/baseResults/hlsl.shift.per-set.frag.out b/Test/baseResults/hlsl.shift.per-set.frag.out index a0eb574b..da2e544e 100644 --- a/Test/baseResults/hlsl.shift.per-set.frag.out +++ b/Test/baseResults/hlsl.shift.per-set.frag.out @@ -219,12 +219,12 @@ tb1: offset 0, type 1404, size 1, index 5, binding -1, stages 16 ts6: offset -1, type 8b5f, size 1, index -1, binding 71, stages 16 Uniform block reflection: -t4: offset -1, type ffffffff, size 0, index -1, binding 21, stages 0, numMembers 1 -t5: offset -1, type ffffffff, size 0, index -1, binding 22, stages 0, numMembers 1 -u5: offset -1, type ffffffff, size 0, index -1, binding 44, stages 0, numMembers 1 -u6: offset -1, type ffffffff, size 0, index -1, binding 34, stages 0, numMembers 1 -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 +t4: offset -1, type ffffffff, size 0, index -1, binding 21, stages 16, numMembers 1 +t5: offset -1, type ffffffff, size 0, index -1, binding 22, stages 16, numMembers 1 +u5: offset -1, type ffffffff, size 0, index -1, binding 44, stages 16, numMembers 1 +u6: offset -1, type ffffffff, size 0, index -1, binding 34, stages 16, numMembers 1 +cb: offset -1, type ffffffff, size 4, index -1, binding 51, stages 16, numMembers 1 +tb: offset -1, type ffffffff, size 4, index -1, binding 27, stages 16, numMembers 1 Buffer variable reflection: @@ -233,5 +233,5 @@ Buffer block reflection: Pipeline input reflection: Pipeline output reflection: -@entryPointOutput: offset 0, type 8b52, size 0, index 0, binding -1, stages 0 +@entryPointOutput: offset 0, type 8b52, size 0, index 0, binding -1, stages 16 diff --git a/Test/baseResults/reflection.linked.options.out b/Test/baseResults/reflection.linked.options.out new file mode 100644 index 00000000..b121626f --- /dev/null +++ b/Test/baseResults/reflection.linked.options.out @@ -0,0 +1,21 @@ +reflection.linked.vert +reflection.linked.frag +Uniform reflection: +ubo_block.unused_uniform: offset 0, type 1406, size 1, index 0, binding -1, stages 0 +ubo_block.shared_uniform: offset 4, type 1406, size 1, index 0, binding -1, stages 17 +ubo_block.vsonly_uniform: offset 8, type 1406, size 1, index 0, binding -1, stages 1 +ubo_block.fsonly_uniform: offset 12, type 1406, size 1, index 0, binding -1, stages 16 + +Uniform block reflection: +ubo_block: offset -1, type ffffffff, size 16, index -1, binding 0, stages 17, numMembers 4 + +Buffer variable reflection: + +Buffer block reflection: + +Pipeline input reflection: +vertin: offset 0, type 1406, size 0, index 0, binding -1, stages 1 + +Pipeline output reflection: +fragout: offset 0, type 1406, size 0, index 0, binding -1, stages 16 + diff --git a/Test/baseResults/reflection.linked.out b/Test/baseResults/reflection.linked.out new file mode 100644 index 00000000..bc61fadf --- /dev/null +++ b/Test/baseResults/reflection.linked.out @@ -0,0 +1,20 @@ +reflection.linked.vert +reflection.linked.frag +Uniform reflection: +ubo_block.shared_uniform: offset 4, type 1406, size 1, index 0, binding -1, stages 17 +ubo_block.vsonly_uniform: offset 8, type 1406, size 1, index 0, binding -1, stages 17 +ubo_block.fsonly_uniform: offset 12, type 1406, size 1, index 0, binding -1, stages 16 + +Uniform block reflection: +ubo_block: offset -1, type ffffffff, size 16, index -1, binding 0, stages 17, numMembers 4 + +Buffer variable reflection: + +Buffer block reflection: + +Pipeline input reflection: +vertin: offset 0, type 1406, size 0, index 0, binding -1, stages 1 + +Pipeline output reflection: +fragout: offset 0, type 1406, size 0, index 0, binding -1, stages 16 + diff --git a/Test/baseResults/reflection.options.frag.out b/Test/baseResults/reflection.options.frag.out index a0cecef6..f3ea4cad 100644 --- a/Test/baseResults/reflection.options.frag.out +++ b/Test/baseResults/reflection.options.frag.out @@ -8,7 +8,7 @@ Buffer variable reflection: Buffer block reflection: Pipeline input reflection: -inval: offset 0, type 1406, size 0, index 0, binding -1, stages 0 +inval: offset 0, type 1406, size 0, index 0, binding -1, stages 16 Pipeline output reflection: diff --git a/Test/baseResults/reflection.options.vert.out b/Test/baseResults/reflection.options.vert.out index add73961..0a3b1188 100644 --- a/Test/baseResults/reflection.options.vert.out +++ b/Test/baseResults/reflection.options.vert.out @@ -1,30 +1,40 @@ 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.verts[0].position[0]: offset 0, type 1406, size 3, index 0, binding -1, stages 1, arrayStride 4, topLevelArrayStride 24 +UBO.verts[0].normal[0]: offset 12, type 1406, size 3, index 0, binding -1, stages 0, arrayStride 4, topLevelArrayStride 24 +UBO.verts[1].position[0]: offset 24, type 1406, size 3, index 0, binding -1, stages 1, arrayStride 4, topLevelArrayStride 24 +UBO.verts[1].normal[0]: offset 36, type 1406, size 3, index 0, binding -1, stages 0, arrayStride 4, topLevelArrayStride 24 UBO.flt[0]: offset 48, type 1406, size 8, index 0, binding -1, stages 1, arrayStride 4, topLevelArrayStride 4 +UBO.unused: offset 80, type 8dc8, size 1, index 0, binding -1, stages 0 Uniform block reflection: -UBO: offset -1, type ffffffff, size 80, index -1, binding -1, stages 0, numMembers 5 +UBO: offset -1, type ffffffff, size 96, index -1, binding -1, stages 1, numMembers 6 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 t[0].v[0].normal[0]: offset 12, 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[1].normal[0]: offset 36, 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 t[0].v[2].normal[0]: offset 60, type 1406, size 3, index 0, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72 -MultipleArrays.tri[0].v[0].position[0]: offset 0, type 1406, size 1, index 1, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72 -MultipleArrays.vert[0].position[0]: offset 360, type 1406, size 1, index 1, binding -1, stages 1, arrayStride 4, topLevelArrayStride 24 +padding[0]: offset 360, type 1405, size 10, index 0, binding -1, stages 0, arrayStride 4, topLevelArrayStride 4 +MultipleArrays.tri[0].v[0].position[0]: offset 0, type 1406, size 3, index 1, binding -1, stages 1, arrayStride 4, topLevelArrayStride 72 +MultipleArrays.tri[0].v[0].normal[0]: offset 12, type 1406, size 3, index 1, binding -1, stages 0, arrayStride 4, topLevelArrayStride 72 +MultipleArrays.tri[0].v[1].position[0]: offset 24, type 1406, size 3, index 1, binding -1, stages 0, arrayStride 4, topLevelArrayStride 72 +MultipleArrays.tri[0].v[1].normal[0]: offset 36, type 1406, size 3, index 1, binding -1, stages 0, arrayStride 4, topLevelArrayStride 72 +MultipleArrays.tri[0].v[2].position[0]: offset 48, type 1406, size 3, index 1, binding -1, stages 0, arrayStride 4, topLevelArrayStride 72 +MultipleArrays.tri[0].v[2].normal[0]: offset 60, type 1406, size 3, index 1, binding -1, stages 0, arrayStride 4, topLevelArrayStride 72 +MultipleArrays.vert[0].position[0]: offset 360, type 1406, size 3, index 1, binding -1, stages 1, arrayStride 4, topLevelArrayStride 24 +MultipleArrays.vert[0].normal[0]: offset 372, type 1406, size 3, index 1, binding -1, stages 0, arrayStride 4, topLevelArrayStride 24 MultipleArrays.f[0]: offset 480, type 1406, size 5, index 1, binding -1, stages 1, arrayStride 4, topLevelArrayStride 4 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 +VertexCollection: offset -1, type ffffffff, size 400, index -1, binding -1, stages 1, numMembers 7 +MultipleArrays: offset -1, type ffffffff, size 500, index -1, binding -1, stages 1, numMembers 9 Pipeline input reflection: -gl_InstanceID: offset 0, type 1404, size 0, index 0, binding -1, stages 0 +gl_InstanceID: offset 0, type 1404, size 0, index 0, binding -1, stages 1 Pipeline output reflection: -outval: offset 0, type 1406, size 0, index 0, binding -1, stages 0 +outval: offset 0, type 1406, size 0, index 0, binding -1, stages 1 diff --git a/Test/baseResults/reflection.vert.out b/Test/baseResults/reflection.vert.out index 6baa8ac0..f1219ef6 100644 --- a/Test/baseResults/reflection.vert.out +++ b/Test/baseResults/reflection.vert.out @@ -127,36 +127,36 @@ uf2: offset -1, type 1406, size 1, index -1, binding -1, stages 1 named.member3: offset 32, type 8b52, size 1, index 1, binding -1, stages 1 Uniform block reflection: -nameless: offset -1, type ffffffff, size 496, index -1, binding -1, stages 0, numMembers 9 -named: offset -1, type ffffffff, size 304, index -1, binding -1, stages 0, numMembers 10 -c_nameless: offset -1, type ffffffff, size 112, index -1, binding -1, stages 0, numMembers 5 -nested: offset -1, type ffffffff, size 32, index -1, binding -1, stages 0, numMembers 4 -abl[0]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0, numMembers 1 -abl[1]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0, numMembers 1 -abl[2]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0, numMembers 1 -abl[3]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0, numMembers 1 -abl2[0]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0, numMembers 1 -abl2[1]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0, numMembers 1 -abl2[2]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0, numMembers 1 -abl2[3]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0, numMembers 1 -buf1: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0, numMembers 2 -buf2: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0, numMembers 4 -buf3: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0, numMembers 2 -buf4: offset -1, type ffffffff, size 4, index -1, binding -1, stages 0, numMembers 4 -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 +nameless: offset -1, type ffffffff, size 496, index -1, binding -1, stages 1, numMembers 9 +named: offset -1, type ffffffff, size 304, index -1, binding -1, stages 1, numMembers 10 +c_nameless: offset -1, type ffffffff, size 112, index -1, binding -1, stages 1, numMembers 5 +nested: offset -1, type ffffffff, size 32, index -1, binding -1, stages 1, numMembers 4 +abl[0]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 1, numMembers 1 +abl[1]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 1, numMembers 1 +abl[2]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 1, numMembers 1 +abl[3]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 1, numMembers 1 +abl2[0]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 1, numMembers 1 +abl2[1]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 1, numMembers 1 +abl2[2]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 1, numMembers 1 +abl2[3]: offset -1, type ffffffff, size 4, index -1, binding -1, stages 1, numMembers 1 +buf1: offset -1, type ffffffff, size 4, index -1, binding -1, stages 1, numMembers 2 +buf2: offset -1, type ffffffff, size 4, index -1, binding -1, stages 1, numMembers 4 +buf3: offset -1, type ffffffff, size 4, index -1, binding -1, stages 1, numMembers 2 +buf4: offset -1, type ffffffff, size 4, index -1, binding -1, stages 1, numMembers 4 +nested2: offset -1, type ffffffff, size 208, index -1, binding -1, stages 1, numMembers 15 +VertexCollection: offset -1, type ffffffff, size 400, index -1, binding -1, stages 1, numMembers 31 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 -attributeFloat3: offset 0, type 8b51, size 0, index 0, binding -1, stages 0 -attributeFloat4: offset 0, type 8b52, size 0, index 0, binding -1, stages 0 -attributeMat4: offset 0, type 8b5c, size 0, index 0, binding -1, stages 0 -gl_InstanceID: offset 0, type 1404, size 0, index 0, binding -1, stages 0 +attributeFloat: offset 0, type 1406, size 0, index 0, binding -1, stages 1 +attributeFloat2: offset 0, type 8b50, size 0, index 0, binding -1, stages 1 +attributeFloat3: offset 0, type 8b51, size 0, index 0, binding -1, stages 1 +attributeFloat4: offset 0, type 8b52, size 0, index 0, binding -1, stages 1 +attributeMat4: offset 0, type 8b5c, size 0, index 0, binding -1, stages 1 +gl_InstanceID: offset 0, type 1404, size 0, index 0, binding -1, stages 1 Pipeline output reflection: diff --git a/Test/reflection.linked.frag b/Test/reflection.linked.frag new file mode 100644 index 00000000..4a88ec49 --- /dev/null +++ b/Test/reflection.linked.frag @@ -0,0 +1,19 @@ +#version 440 core + +layout(binding = 0, std140) uniform ubo_block { + float unused_uniform; + float shared_uniform; + float vsonly_uniform; + float fsonly_uniform; +} ubo; + +in float vertout; + +out float fragout; + +void main() +{ + fragout = vertout; + fragout += ubo.shared_uniform; + fragout += ubo.fsonly_uniform; +} diff --git a/Test/reflection.linked.vert b/Test/reflection.linked.vert new file mode 100644 index 00000000..e28142de --- /dev/null +++ b/Test/reflection.linked.vert @@ -0,0 +1,19 @@ +#version 440 core + +layout(binding = 0, std140) uniform ubo_block { + float unused_uniform; + float shared_uniform; + float vsonly_uniform; + float fsonly_uniform; +} ubo; + +in float vertin; + +out float vertout; + +void main() +{ + vertout = vertin; + vertout += ubo.shared_uniform; + vertout += ubo.vsonly_uniform; +} diff --git a/Test/reflection.options.vert b/Test/reflection.options.vert index 001537e0..b8ecc895 100644 --- a/Test/reflection.options.vert +++ b/Test/reflection.options.vert @@ -11,6 +11,7 @@ struct TriangleInfo { buffer VertexCollection { TriangleInfo t[5]; + uint padding[10]; }; buffer MultipleArrays { @@ -22,6 +23,7 @@ buffer MultipleArrays { uniform UBO { VertexInfo verts[2]; float flt[8]; + uvec4 unused; } ubo; out float outval; diff --git a/Test/reflection.vert b/Test/reflection.vert index 939e52a3..0f14c826 100644 --- a/Test/reflection.vert +++ b/Test/reflection.vert @@ -172,6 +172,7 @@ struct TriangleInfo { buffer VertexCollection { TriangleInfo t[5]; + uint padding[10]; }; out float outval; diff --git a/Test/runtests b/Test/runtests index d3705034..f659da4d 100755 --- a/Test/runtests +++ b/Test/runtests @@ -32,12 +32,16 @@ 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 --reflect-separate-buffers 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 --reflect-all-block-variables 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 --reflect-separate-buffers 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 --reflect-all-block-variables reflection.frag > $TARGETDIR/reflection.options.frag.out diff -b $BASEDIR/reflection.options.frag.out $TARGETDIR/reflection.options.frag.out || HASERROR=1 +$EXE -l -q -C reflection.linked.vert reflection.linked.frag > $TARGETDIR/reflection.linked.out +diff -b $BASEDIR/reflection.linked.out $TARGETDIR/reflection.linked.out || HASERROR=1 +$EXE -l -q -C --reflect-strict-array-suffix --reflect-basic-array-suffix --reflect-intermediate-io --reflect-separate-buffers --reflect-all-block-variables reflection.linked.vert reflection.linked.frag > $TARGETDIR/reflection.linked.options.out +diff -b $BASEDIR/reflection.linked.options.out $TARGETDIR/reflection.linked.options.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 $EXE -D -Od -e main -l -q -C -V -Od hlsl.reflection.binding.frag > $TARGETDIR/hlsl.reflection.binding.frag.out diff --git a/glslang/MachineIndependent/reflection.cpp b/glslang/MachineIndependent/reflection.cpp index a7d9b13a..df818796 100644 --- a/glslang/MachineIndependent/reflection.cpp +++ b/glslang/MachineIndependent/reflection.cpp @@ -94,7 +94,7 @@ public: // the dereference change expected by blowUpActiveAggregate. TList derefs; blowUpActiveAggregate(base.getType(), base.getName(), derefs, derefs.end(), -1, -1, 0, 0, - base.getQualifier().storage); + base.getQualifier().storage, true); } } @@ -110,6 +110,12 @@ public: if (it == reflection.nameToIndex.end()) { reflection.nameToIndex[name.c_str()] = (int)reflection.indexToPipeInput.size(); reflection.indexToPipeInput.push_back(TObjectReflection(name.c_str(), type, 0, mapToGlType(type), 0, 0)); + + EShLanguageMask& stages = reflection.indexToPipeInput.back().stages; + stages = static_cast(stages | 1 << intermediate.getStage()); + } else { + EShLanguageMask& stages = reflection.indexToPipeInput[it->second].stages; + stages = static_cast(stages | 1 << intermediate.getStage()); } } } @@ -126,6 +132,12 @@ public: if (it == reflection.nameToIndex.end()) { reflection.nameToIndex[name.c_str()] = (int)reflection.indexToPipeOutput.size(); reflection.indexToPipeOutput.push_back(TObjectReflection(name.c_str(), type, 0, mapToGlType(type), 0, 0)); + + EShLanguageMask& stages = reflection.indexToPipeOutput.back().stages; + stages = static_cast(stages | 1 << intermediate.getStage()); + } else { + EShLanguageMask& stages = reflection.indexToPipeOutput[it->second].stages; + stages = static_cast(stages | 1 << intermediate.getStage()); } } } @@ -269,7 +281,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& derefs, TList::const_iterator deref, int offset, int blockIndex, int arraySize, - int topLevelArrayStride, TStorageQualifier baseStorage) + int topLevelArrayStride, TStorageQualifier baseStorage, bool active) { // when strictArraySuffix is enabled, we closely follow the rules from ARB_program_interface_query. // Broadly: @@ -306,7 +318,7 @@ public: ++nextDeref; TType derefType(*terminalType, 0); blowUpActiveAggregate(derefType, newBaseName, derefs, nextDeref, offset, blockIndex, arraySize, - topLevelArrayStride, baseStorage); + topLevelArrayStride, baseStorage, active); if (offset >= 0) offset += stride; @@ -377,7 +389,7 @@ public: offset = baseOffset + stride * i; blowUpActiveAggregate(derefType, newBaseName, derefs, derefs.end(), offset, blockIndex, 0, - topLevelArrayStride, baseStorage); + topLevelArrayStride, baseStorage, active); } } else { // Visit all members of this aggregate, and for each one, @@ -393,7 +405,9 @@ public: for (int i = 0; i < (int)typeList.size(); ++i) { TString newBaseName = name; - newBaseName.append(TString(".") + typeList[i].type->getFieldName()); + if (newBaseName.size() > 0) + newBaseName.append("."); + newBaseName.append(typeList[i].type->getFieldName()); TType derefType(*terminalType, i); if (offset >= 0) offset = baseOffset + memberOffsets[i]; @@ -405,7 +419,7 @@ public: } blowUpActiveAggregate(derefType, newBaseName, derefs, derefs.end(), offset, blockIndex, 0, - arrayStride, baseStorage); + arrayStride, baseStorage, active); } } @@ -442,9 +456,21 @@ public: reflection.atomicCounterUniformIndices.push_back(uniformIndex); variables.back().topLevelArrayStride = topLevelArrayStride; - } else if (arraySize > 1) { - int& reflectedArraySize = variables[it->second].size; - reflectedArraySize = std::max(arraySize, reflectedArraySize); + + if ((reflection.options & EShReflectionAllBlockVariables) && active) { + EShLanguageMask& stages = variables.back().stages; + stages = static_cast(stages | 1 << intermediate.getStage()); + } + } else { + if (arraySize > 1) { + int& reflectedArraySize = variables[it->second].size; + reflectedArraySize = std::max(arraySize, reflectedArraySize); + } + + if ((reflection.options & EShReflectionAllBlockVariables) && active) { + EShLanguageMask& stages = variables[it->second].stages; + stages = static_cast(stages | 1 << intermediate.getStage()); + } } } @@ -494,6 +520,10 @@ public: anonymous = IsAnonymous(base->getName()); const TString& blockName = base->getType().getTypeName(); + TString baseName; + + if (! anonymous) + baseName = blockName; if (base->getType().isArray()) { TType derefType(base->getType(), 0); @@ -502,8 +532,56 @@ public: for (int e = 0; e < base->getType().getCumulativeArraySize(); ++e) blockIndex = addBlockName(blockName + "[" + String(e) + "]", derefType, getBlockSize(base->getType())); + baseName.append(TString("[0]")); } else blockIndex = addBlockName(blockName, base->getType(), getBlockSize(base->getType())); + + if (reflection.options & EShReflectionAllBlockVariables) { + // Use a degenerate (empty) set of dereferences to immediately put as at the end of + // the dereference change expected by blowUpActiveAggregate. + TList derefs; + + // because we don't have any derefs, the first thing blowUpActiveAggregate will do is iterate over each + // member in the struct definition. This will lose any information about whether the parent was a buffer + // block. So if we're using strict array rules which don't expand the first child of a buffer block we + // instead iterate over the children here. + const bool strictArraySuffix = (reflection.options & EShReflectionStrictArraySuffix); + bool blockParent = (base->getType().getBasicType() == EbtBlock && base->getQualifier().storage == EvqBuffer); + + if (strictArraySuffix && blockParent) { + const TTypeList& typeList = *base->getType().getStruct(); + + TVector memberOffsets; + + memberOffsets.resize(typeList.size()); + getOffsets(base->getType(), memberOffsets); + + for (int i = 0; i < (int)typeList.size(); ++i) { + TType derefType(base->getType(), i); + TString name = baseName; + if (name.size() > 0) + name.append("."); + name.append(typeList[i].type->getFieldName()); + + // if this member is an array, store the top-level array stride but start the explosion from + // the inner struct type. + if (derefType.isArray() && derefType.isStruct()) { + name.append("[0]"); + blowUpActiveAggregate(TType(derefType, 0), name, derefs, derefs.end(), memberOffsets[i], + blockIndex, 0, getArrayStride(base->getType(), derefType), + base->getQualifier().storage, false); + } else { + blowUpActiveAggregate(derefType, name, derefs, derefs.end(), memberOffsets[i], blockIndex, + 0, 0, base->getQualifier().storage, false); + } + } + } else { + // otherwise - if we're not using strict array suffix rules, or this isn't a block so we are + // expanding root arrays anyway, just start the iteration from the base block type. + blowUpActiveAggregate(base->getType(), baseName, derefs, derefs.end(), 0, blockIndex, 0, 0, + base->getQualifier().storage, false); + } + } } // Process the dereference chain, backward, accumulating the pieces for later forward traversal. @@ -534,7 +612,7 @@ public: baseName = base->getName(); } blowUpActiveAggregate(base->getType(), baseName, derefs, derefs.begin(), offset, blockIndex, arraySize, 0, - base->getQualifier().storage); + base->getQualifier().storage, true); } int addBlockName(const TString& name, const TType& type, int size) @@ -549,9 +627,16 @@ public: blocks.push_back(TObjectReflection(name.c_str(), type, -1, -1, size, -1)); blocks.back().numMembers = countAggregateMembers(type); - } else + + EShLanguageMask& stages = blocks.back().stages; + stages = static_cast(stages | 1 << intermediate.getStage()); + } else { blockIndex = it->second; + EShLanguageMask& stages = blocks[blockIndex].stages; + stages = static_cast(stages | 1 << intermediate.getStage()); + } + return blockIndex; } @@ -1018,6 +1103,9 @@ void TReflection::buildCounterIndices(const TIntermediate& intermediate) // build Shader Stages mask for all uniforms void TReflection::buildUniformStageMask(const TIntermediate& intermediate) { + if (options & EShReflectionAllBlockVariables) + return; + for (int i = 0; i < int(indexToUniform.size()); ++i) { indexToUniform[i].stages = static_cast(indexToUniform[i].stages | 1 << intermediate.getStage()); } diff --git a/glslang/Public/ShaderLang.h b/glslang/Public/ShaderLang.h index 7aaaaf3a..3512cede 100755 --- a/glslang/Public/ShaderLang.h +++ b/glslang/Public/ShaderLang.h @@ -248,6 +248,7 @@ typedef enum { 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 + EShReflectionAllBlockVariables = (1 << 4), // reflect all variables in blocks, even if they are inactive } EShReflectionOptions; // From 4513df917589b0fadbea4e47eaa22cf863dd978a Mon Sep 17 00:00:00 2001 From: baldurk Date: Fri, 8 Feb 2019 10:48:48 +0000 Subject: [PATCH 9/9] Reflow for better readability --- StandAlone/StandAlone.cpp | 13 ++-- glslang/Public/ShaderLang.h | 121 ++++++++++++------------------------ 2 files changed, 49 insertions(+), 85 deletions(-) diff --git a/StandAlone/StandAlone.cpp b/StandAlone/StandAlone.cpp index 8906493d..740ec7bd 100644 --- a/StandAlone/StandAlone.cpp +++ b/StandAlone/StandAlone.cpp @@ -1529,12 +1529,15 @@ void usage() " --invert-y | --iy invert position.Y output in vertex shader\n" " --keep-uncalled | --ku don't eliminate uncalled functions\n" " --no-storage-format | --nsf use Unknown image format\n" - " --reflect-strict-array-suffix use strict array suffix rules when reflecting\n" + " --reflect-strict-array-suffix use strict array suffix rules when\n" + " reflecting\n" " --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" - " --reflect-all-block-variables reflect all variables in blocks, whether inactive or active\n" + " --reflect-intermediate-io reflection includes inputs/outputs of linked\n" + " shaders rather than just vertex/fragment\n" + " --reflect-separate-buffers reflect buffer variables and blocks\n" + " separately to uniforms\n" + " --reflect-all-block-variables reflect all variables in blocks, whether\n" + " inactive or active\n" " --resource-set-binding [stage] name set binding\n" " set descriptor set and binding for\n" " individual resources\n" diff --git a/glslang/Public/ShaderLang.h b/glslang/Public/ShaderLang.h index 3512cede..73942436 100755 --- a/glslang/Public/ShaderLang.h +++ b/glslang/Public/ShaderLang.h @@ -758,105 +758,66 @@ public: 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) - { - return getNumUniformVariables(); - } - int getNumLiveUniformBlocks() const // can be used for glGetProgramiv(GL_ACTIVE_UNIFORM_BLOCKS) - { - return getNumUniformBlocks(); - } + // can be used for glGetProgramiv(GL_ACTIVE_UNIFORMS) + int getNumLiveUniformVariables() const { return getNumUniformVariables(); } - int getNumLiveAttributes() const // can be used for glGetProgramiv(GL_ACTIVE_ATTRIBUTES) - { - return getNumPipeInputs(); - } + // can be used for glGetProgramiv(GL_ACTIVE_UNIFORM_BLOCKS) + int getNumLiveUniformBlocks() const { return getNumUniformBlocks(); } - int getUniformIndex(const char* name) const // can be used for glGetUniformIndices() - { - return getReflectionIndex(name); - } + // can be used for glGetProgramiv(GL_ACTIVE_ATTRIBUTES) + int getNumLiveAttributes() const { return getNumPipeInputs(); } - const char* getUniformName(int index) const // can be used for "name" part of glGetActiveUniform() - { - return getUniform(index).name.c_str(); - } + // can be used for glGetUniformIndices() + int getUniformIndex(const char *name) const { return getReflectionIndex(name); } - int getUniformBinding(int index) const // returns the binding number - { - return getUniform(index).getBinding(); - } + // can be used for "name" part of glGetActiveUniform() + const char *getUniformName(int index) const { return getUniform(index).name.c_str(); } - EShLanguageMask getUniformStages(int index) const // returns Shaders Stages where a Uniform is present - { - return getUniform(index).stages; - } + // returns the binding number + int getUniformBinding(int index) const { return getUniform(index).getBinding(); } - int getUniformBlockIndex(int index) const // can be used for glGetActiveUniformsiv(GL_UNIFORM_BLOCK_INDEX) - { - return getUniform(index).index; - } + // returns Shaders Stages where a Uniform is present + EShLanguageMask getUniformStages(int index) const { return getUniform(index).stages; } - int getUniformType(int index) const // can be used for glGetActiveUniformsiv(GL_UNIFORM_TYPE) - { - return getUniform(index).glDefineType; - } + // can be used for glGetActiveUniformsiv(GL_UNIFORM_BLOCK_INDEX) + int getUniformBlockIndex(int index) const { return getUniform(index).index; } - int getUniformBufferOffset(int index) const // can be used for glGetActiveUniformsiv(GL_UNIFORM_OFFSET) - { - return getUniform(index).offset; - } + // can be used for glGetActiveUniformsiv(GL_UNIFORM_TYPE) + int getUniformType(int index) const { return getUniform(index).glDefineType; } - int getUniformArraySize(int index) const // can be used for glGetActiveUniformsiv(GL_UNIFORM_SIZE) - { - return getUniform(index).size; - } + // can be used for glGetActiveUniformsiv(GL_UNIFORM_OFFSET) + int getUniformBufferOffset(int index) const { return getUniform(index).offset; } - const TType* getUniformTType(int index) const // returns a TType* - { - return getUniform(index).getType(); - } + // can be used for glGetActiveUniformsiv(GL_UNIFORM_SIZE) + int getUniformArraySize(int index) const { return getUniform(index).size; } - const char* getUniformBlockName(int index) const // can be used for glGetActiveUniformBlockName() - { - return getUniformBlock(index).name.c_str(); - } + // returns a TType* + const TType *getUniformTType(int index) const { return getUniform(index).getType(); } - int getUniformBlockSize(int index) const // can be used for glGetActiveUniformBlockiv(UNIFORM_BLOCK_DATA_SIZE) - { - return getUniformBlock(index).size; - } + // can be used for glGetActiveUniformBlockName() + const char *getUniformBlockName(int index) const { return getUniformBlock(index).name.c_str(); } - int getUniformBlockBinding(int index) const // returns the block binding number - { - return getUniformBlock(index).getBinding(); - } + // can be used for glGetActiveUniformBlockiv(UNIFORM_BLOCK_DATA_SIZE) + int getUniformBlockSize(int index) const { return getUniformBlock(index).size; } - int getUniformBlockCounterIndex(int index) const // returns block index of associated counter. - { - return getUniformBlock(index).counterIndex; - } + // returns the block binding number + int getUniformBlockBinding(int index) const { return getUniformBlock(index).getBinding(); } - const TType* getUniformBlockTType(int index) const // returns a TType* - { - return getUniformBlock(index).getType(); - } + // returns block index of associated counter. + int getUniformBlockCounterIndex(int index) const { return getUniformBlock(index).counterIndex; } - const char* getAttributeName(int index) const // can be used for glGetActiveAttrib() - { - return getPipeInput(index).name.c_str(); - } + // returns a TType* + const TType *getUniformBlockTType(int index) const { return getUniformBlock(index).getType(); } - int getAttributeType(int index) const // can be used for glGetActiveAttrib() - { - return getPipeInput(index).glDefineType; - } + // can be used for glGetActiveAttrib() + const char *getAttributeName(int index) const { return getPipeInput(index).name.c_str(); } - const TType* getAttributeTType(int index) const // returns a TType* - { - return getPipeInput(index).getType(); - } + // can be used for glGetActiveAttrib() + int getAttributeType(int index) const { return getPipeInput(index).glDefineType; } + + // returns a TType* + const TType *getAttributeTType(int index) const { return getPipeInput(index).getType(); } void dumpReflection();