From 7b9fa25bad300f4919e38ce0295ac2c279ed95cc Mon Sep 17 00:00:00 2001 From: John Kessenich Date: Thu, 21 Jan 2016 18:56:57 -0700 Subject: [PATCH] SPV: Add recursive distrubition of 'location' across structure members. --- SPIRV/GlslangToSpv.cpp | 20 ++++++++++---- Test/baseResults/spv.430.vert.out | 45 ++++++++++++++++++++++++------- Test/spv.430.vert | 4 +++ 3 files changed, 55 insertions(+), 14 deletions(-) diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index c1743757..01f3f903 100755 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -437,15 +437,17 @@ void InheritQualifiers(glslang::TQualifier& child, const glslang::TQualifier& pa child.patch = true; if (parent.sample) child.sample = true; + + child.layoutLocation = parent.layoutLocation; } bool HasNonLayoutQualifiers(const glslang::TQualifier& qualifier) { - // This should list qualifiers that simultaneous satisify: + // This should list qualifiers that simultaneous satisfy: // - struct members can inherit from a struct declaration // - effect decorations on the struct members (note smooth does not, and expecting something like volatile to effect the whole object) // - are not part of the offset/st430/etc or row/column-major layout - return qualifier.invariant || qualifier.nopersp || qualifier.flat || qualifier.centroid || qualifier.patch || qualifier.sample; + return qualifier.invariant || qualifier.nopersp || qualifier.flat || qualifier.centroid || qualifier.patch || qualifier.sample || qualifier.hasLocation(); } // @@ -1528,7 +1530,7 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty } // Do full recursive conversion of an arbitrary glslang type to a SPIR-V Id. -// explicitLayout can be kept the same throughout the heirarchical recursive walk. +// explicitLayout can be kept the same throughout the hierarchical recursive walk. spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& type, glslang::TLayoutPacking explicitLayout, const glslang::TQualifier& qualifier) { spv::Id spvType = spv::NoResult; @@ -1588,6 +1590,7 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty int memberDelta = 0; // how much the member's index changes from glslang to SPIR-V, normally 0, except sometimes for blocks if (type.getBasicType() == glslang::EbtBlock) memberRemapper[glslangStruct].resize(glslangStruct->size()); + int locationOffset = 0; // for use across struct members, when they are called recursively for (int i = 0; i < (int)glslangStruct->size(); i++) { glslang::TType& glslangType = *(*glslangStruct)[i].type; if (glslangType.hiddenMember()) { @@ -1600,6 +1603,10 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty // modify just this child's view of the qualifier glslang::TQualifier subQualifier = glslangType.getQualifier(); InheritQualifiers(subQualifier, qualifier); + if (qualifier.hasLocation()) { + subQualifier.layoutLocation += locationOffset; + locationOffset += glslangIntermediate->computeTypeLocationSize(glslangType); + } structFields.push_back(convertGlslangToSpvType(glslangType, explicitLayout, subQualifier)); } } @@ -1611,6 +1618,7 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty // Name and decorate the non-hidden members int offset = -1; + locationOffset = 0; // for use within the members of this struct, right now for (int i = 0; i < (int)glslangStruct->size(); i++) { glslang::TType& glslangType = *(*glslangStruct)[i].type; int member = i; @@ -1628,8 +1636,10 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty addMemberDecoration(spvType, member, TranslatePrecisionDecoration(glslangType)); addMemberDecoration(spvType, member, TranslateInterpolationDecoration(subQualifier)); addMemberDecoration(spvType, member, TranslateInvariantDecoration(subQualifier)); - if (glslangType.getQualifier().hasLocation()) - builder.addMemberDecoration(spvType, member, spv::DecorationLocation, glslangType.getQualifier().layoutLocation); + if (qualifier.hasLocation()) { + builder.addMemberDecoration(spvType, member, spv::DecorationLocation, qualifier.layoutLocation + locationOffset); + locationOffset += glslangIntermediate->computeTypeLocationSize(glslangType); + } if (glslangType.getQualifier().hasComponent()) builder.addMemberDecoration(spvType, member, spv::DecorationComponent, glslangType.getQualifier().layoutComponent); if (glslangType.getQualifier().hasXfbOffset()) diff --git a/Test/baseResults/spv.430.vert.out b/Test/baseResults/spv.430.vert.out index 186406d5..750fff07 100755 --- a/Test/baseResults/spv.430.vert.out +++ b/Test/baseResults/spv.430.vert.out @@ -7,12 +7,12 @@ Linked vertex stage: // Module Version 10000 // Generated by (magic number): 80001 -// Id's are bound by 63 +// Id's are bound by 69 Capability Shader 1: ExtInstImport "GLSL.std.450" MemoryModel Logical GLSL450 - EntryPoint Vertex 4 "main" 12 23 34 44 45 61 62 + EntryPoint Vertex 4 "main" 12 23 34 44 45 65 67 68 Source GLSL 430 Name 4 "main" Name 10 "gl_PerVertex" @@ -33,8 +33,17 @@ Linked vertex stage: Name 55 "sampb1" Name 58 "sampb2" Name 59 "sampb4" - Name 61 "gl_VertexID" - Name 62 "gl_InstanceID" + Name 62 "S" + MemberName 62(S) 0 "a" + MemberName 62(S) 1 "b" + MemberName 62(S) 2 "c" + Name 63 "SS" + MemberName 63(SS) 0 "b" + MemberName 63(SS) 1 "s" + MemberName 63(SS) 2 "c" + Name 65 "var" + Name 67 "gl_VertexID" + Name 68 "gl_InstanceID" MemberDecorate 10(gl_PerVertex) 0 BuiltIn ClipDistance Decorate 10(gl_PerVertex) Block Decorate 34(badorder3) Flat @@ -49,8 +58,20 @@ Linked vertex stage: Decorate 55(sampb1) Binding 4 Decorate 58(sampb2) Binding 5 Decorate 59(sampb4) Binding 31 - Decorate 61(gl_VertexID) BuiltIn VertexId - Decorate 62(gl_InstanceID) BuiltIn InstanceId + MemberDecorate 62(S) 0 Flat + MemberDecorate 62(S) 0 Location 1 + MemberDecorate 62(S) 1 Flat + MemberDecorate 62(S) 1 Location 2 + MemberDecorate 62(S) 2 Flat + MemberDecorate 62(S) 2 Location 3 + MemberDecorate 63(SS) 0 Flat + MemberDecorate 63(SS) 0 Location 0 + MemberDecorate 63(SS) 1 Flat + MemberDecorate 63(SS) 1 Location 1 + MemberDecorate 63(SS) 2 Flat + MemberDecorate 63(SS) 2 Location 4 + Decorate 67(gl_VertexID) BuiltIn VertexId + Decorate 68(gl_InstanceID) BuiltIn InstanceId 2: TypeVoid 3: TypeFunction 2 6: TypeFloat 32 @@ -97,9 +118,15 @@ Linked vertex stage: 57: TypePointer UniformConstant 56 58(sampb2): 57(ptr) Variable UniformConstant 59(sampb4): 54(ptr) Variable UniformConstant - 60: TypePointer Input 13(int) - 61(gl_VertexID): 60(ptr) Variable Input -62(gl_InstanceID): 60(ptr) Variable Input + 60: TypeVector 7(int) 2 + 61: TypeVector 6(float) 3 + 62(S): TypeStruct 6(float) 60(ivec2) 61(fvec3) + 63(SS): TypeStruct 19(fvec4) 62(S) 19(fvec4) + 64: TypePointer Output 63(SS) + 65(var): 64(ptr) Variable Output + 66: TypePointer Input 13(int) + 67(gl_VertexID): 66(ptr) Variable Input +68(gl_InstanceID): 66(ptr) Variable Input 4(main): 2 Function None 3 5: Label 18: 17(ptr) AccessChain 12 14 15 diff --git a/Test/spv.430.vert b/Test/spv.430.vert index 55cb60b1..b5571ccc 100644 --- a/Test/spv.430.vert +++ b/Test/spv.430.vert @@ -30,3 +30,7 @@ layout(binding = 7) uniform anonblock { int aoeu; } ; layout(binding = 4) uniform sampler2D sampb1; layout(binding = 5) uniform sampler2D sampb2[10]; layout(binding = 31) uniform sampler2D sampb4; + +struct S { mediump float a; highp uvec2 b; highp vec3 c; }; +struct SS { vec4 b; S s; vec4 c; }; +layout(location = 0) flat out SS var;