diff --git a/Test/baseResults/spv.debugInfo.1.1.frag.out b/Test/baseResults/spv.debugInfo.1.1.frag.out index b730376250bb23f43e8823479c1c31acfeac111b..9bd14910bfd940b6b4d715a31ed1ee92e3740cbf 100644 --- a/Test/baseResults/spv.debugInfo.1.1.frag.out +++ b/Test/baseResults/spv.debugInfo.1.1.frag.out @@ -94,6 +94,7 @@ void main() MemberDecorate 54(ubuf) 0 Offset 0 Decorate 54(ubuf) Block Decorate 56 DescriptorSet 3 + Decorate 69(s2d) Location 0 Decorate 69(s2d) DescriptorSet 3 3: TypeVoid 4: TypeFunction 3 diff --git a/Test/baseResults/spv.debugInfo.frag.out b/Test/baseResults/spv.debugInfo.frag.out index de54415127da24566c35d77d52797a4f74495a58..0bb266bde7245c736257cfba52f41eda103ae358 100644 --- a/Test/baseResults/spv.debugInfo.frag.out +++ b/Test/baseResults/spv.debugInfo.frag.out @@ -97,6 +97,7 @@ void main() Decorate 54(ubuf) Block Decorate 56 DescriptorSet 3 Decorate 56 Binding 0 + Decorate 69(s2d) Location 0 Decorate 69(s2d) DescriptorSet 3 Decorate 69(s2d) Binding 1 3: TypeVoid diff --git a/glslang/MachineIndependent/iomapper.cpp b/glslang/MachineIndependent/iomapper.cpp index a7deb9d504c9690c3d38b6784f13f84a9f662573..68172538d323d2ead6c3b3e3ef965bf9538fed56 100644 --- a/glslang/MachineIndependent/iomapper.cpp +++ b/glslang/MachineIndependent/iomapper.cpp @@ -431,7 +431,8 @@ struct TDefaultIoResolverBase : public glslang::TIoMapResolver // no locations added if already present, a built-in variable, a block, or an opaque if (type.getQualifier().hasLocation() || type.isBuiltIn() || - type.getBasicType() == EbtBlock || type.containsOpaque()) + type.getBasicType() == EbtBlock || + (type.containsOpaque() && intermediate.getSpv().openGl == 0)) return -1; // no locations on blocks of built-in variables @@ -442,7 +443,11 @@ struct TDefaultIoResolverBase : public glslang::TIoMapResolver return -1; } - return nextUniformLocation++; + int location = nextUniformLocation; + + nextUniformLocation += TIntermediate::computeTypeUniformLocationSize(type); + + return location; } bool validateInOut(EShLanguage /*stage*/, const char* /*name*/, const TType& /*type*/, bool /*is_live*/) override { diff --git a/glslang/MachineIndependent/linkValidate.cpp b/glslang/MachineIndependent/linkValidate.cpp index 9aba27922c93804040e0fd19d86bf048c0a95bdb..aa9c5121bc1332f28d5e098bb7ed8ed03a771ed8 100644 --- a/glslang/MachineIndependent/linkValidate.cpp +++ b/glslang/MachineIndependent/linkValidate.cpp @@ -962,6 +962,36 @@ int TIntermediate::computeTypeLocationSize(const TType& type, EShLanguage stage) return 1; } +// Same as computeTypeLocationSize but for uniforms +int TIntermediate::computeTypeUniformLocationSize(const TType& type) +{ + // "Individual elements of a uniform array are assigned + // consecutive locations with the first element taking location + // location." + if (type.isArray()) { + // TODO: perf: this can be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness + TType elementType(type, 0); + if (type.isImplicitlySizedArray()) { + // TODO: are there valid cases of having an implicitly-sized array with a location? If so, running this code too early. + return computeTypeUniformLocationSize(elementType); + } else + return type.getOuterArraySize() * computeTypeUniformLocationSize(elementType); + } + + // "Each subsequent inner-most member or element gets incremental + // locations for the entire structure or array." + if (type.isStruct()) { + int size = 0; + for (int member = 0; member < (int)type.getStruct()->size(); ++member) { + TType memberType(type, member); + size += computeTypeUniformLocationSize(memberType); + } + return size; + } + + return 1; +} + // Accumulate xfb buffer ranges and check for collisions as the accumulation is done. // // Returns < 0 if no collision, >= 0 if collision and the value returned is a colliding value. diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h index d6ecbe340ce8ece9e0a3b73fe274142d63d7b9e7..d6f13ae4ed49b4c2ad56997ff9149381e0c69c38 100644 --- a/glslang/MachineIndependent/localintermediate.h +++ b/glslang/MachineIndependent/localintermediate.h @@ -590,6 +590,7 @@ public: int addUsedOffsets(int binding, int offset, int numOffsets); bool addUsedConstantId(int id); static int computeTypeLocationSize(const TType&, EShLanguage); + static int computeTypeUniformLocationSize(const TType&); bool setXfbBufferStride(int buffer, unsigned stride) {