SPV: Distinguish between SPV and non-SPV rules for member overlap.

This commit is contained in:
John Kessenich 2016-10-07 11:50:25 -06:00
parent 087a454af2
commit 19bdf90eba
6 changed files with 94 additions and 15 deletions

View File

@ -0,0 +1,59 @@
spv.offsets.frag
Warning, version 450 is not yet complete; most version-specific features are present, but some are missing.
Linked fragment stage:
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 15
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main"
ExecutionMode 4 OriginUpperLeft
Source GLSL 450
Name 4 "main"
Name 7 "n1"
MemberName 7(n1) 0 "a"
MemberName 7(n1) 1 "b"
MemberName 7(n1) 2 "c"
MemberName 7(n1) 3 "d"
Name 9 "i1"
Name 12 "n2"
MemberName 12(n2) 0 "e"
MemberName 12(n2) 1 "f"
MemberName 12(n2) 2 "g"
MemberName 12(n2) 3 "h"
Name 14 "i2"
MemberDecorate 7(n1) 0 Offset 8
MemberDecorate 7(n1) 1 Offset 4
MemberDecorate 7(n1) 2 Offset 0
MemberDecorate 7(n1) 3 Offset 12
Decorate 7(n1) Block
Decorate 9(i1) DescriptorSet 0
Decorate 9(i1) Binding 0
MemberDecorate 12(n2) 0 Offset 32
MemberDecorate 12(n2) 1 Offset 48
MemberDecorate 12(n2) 2 Offset 16
MemberDecorate 12(n2) 3 Offset 0
Decorate 12(n2) BufferBlock
Decorate 14(i2) DescriptorSet 0
Decorate 14(i2) Binding 1
2: TypeVoid
3: TypeFunction 2
6: TypeInt 32 1
7(n1): TypeStruct 6(int) 6(int) 6(int) 6(int)
8: TypePointer Uniform 7(n1)
9(i1): 8(ptr) Variable Uniform
10: TypeFloat 32
11: TypeVector 10(float) 3
12(n2): TypeStruct 11(fvec3) 11(fvec3) 11(fvec3) 11(fvec3)
13: TypePointer Uniform 12(n2)
14(i2): 13(ptr) Variable Uniform
4(main): 2 Function None 3
5: Label
Return
FunctionEnd

17
Test/spv.offsets.frag Executable file
View File

@ -0,0 +1,17 @@
#version 450
layout(set = 0, binding = 0, std140) uniform n1 {
layout(offset = 8) int a;
layout(offset = 4) int b;
layout(offset = 0) int c;
layout(offset = 12) int d;
} i1;
layout(set = 0, binding = 1, std430) buffer n2 {
layout(offset = 32) vec3 e;
vec3 f;
layout(offset = 16) vec3 g;
layout(offset = 0) vec3 h;
} i2;
void main() {}

View File

@ -2,5 +2,5 @@
// For the version, it uses the latest git tag followed by the number of commits.
// For the date, it uses the current date (when then script is run).
#define GLSLANG_REVISION "Overload400-PrecQual.1559"
#define GLSLANG_DATE "06-Oct-2016"
#define GLSLANG_REVISION "Overload400-PrecQual.1560"
#define GLSLANG_DATE "07-Oct-2016"

View File

@ -5946,8 +5946,9 @@ void TParseContext::fixBlockUniformOffsets(TQualifier& qualifier, TTypeList& typ
if (! IsMultipleOfPow2(memberQualifier.layoutOffset, memberAlignment))
error(memberLoc, "must be a multiple of the member's alignment", "offset", "");
// "It is a compile-time error to specify an offset that is smaller than the offset of the previous
// GLSL: "It is a compile-time error to specify an offset that is smaller than the offset of the previous
// member in the block or that lies within the previous member of the block"
if (spvVersion.spv == 0) {
if (memberQualifier.layoutOffset < offset)
error(memberLoc, "cannot lie in previous members", "offset", "");
@ -5956,6 +5957,12 @@ void TParseContext::fixBlockUniformOffsets(TQualifier& qualifier, TTypeList& typ
// "The actual offset of a member is computed as
// follows: If offset was declared, start with that offset, otherwise start with the next available offset."
offset = std::max(offset, memberQualifier.layoutOffset);
} else {
// TODO: Vulkan: "It is a compile-time error to have any offset, explicit or assigned,
// that lies within another member of the block."
offset = memberQualifier.layoutOffset;
}
}
// "The actual alignment of a member will be the greater of the specified align alignment and the standard

View File

@ -230,6 +230,7 @@ INSTANTIATE_TEST_CASE_P(
"spv.newTexture.frag",
"spv.noDeadDecorations.vert",
"spv.nonSquare.vert",
"spv.offsets.frag",
"spv.Operations.frag",
"spv.intOps.vert",
"spv.precision.frag",

View File

@ -4731,11 +4731,6 @@ void HlslParseContext::fixBlockUniformOffsets(const TQualifier& qualifier, TType
if (! IsMultipleOfPow2(memberQualifier.layoutOffset, memberAlignment))
error(memberLoc, "must be a multiple of the member's alignment", "offset", "");
// "It is a compile-time error to specify an offset that is smaller than the offset of the previous
// member in the block or that lies within the previous member of the block"
if (memberQualifier.layoutOffset < offset)
error(memberLoc, "cannot lie in previous members", "offset", "");
// "The offset qualifier forces the qualified member to start at or after the specified
// integral-constant expression, which will be its byte offset from the beginning of the buffer.
// "The actual offset of a member is computed as