diff --git a/Test/baseResults/spv.xfbOffsetOnBlockMembersAssignment.vert.out b/Test/baseResults/spv.xfbOffsetOnBlockMembersAssignment.vert.out new file mode 100644 index 0000000000000000000000000000000000000000..066aa3a0872ad2810b8b52ff16bb04d9d28aab63 --- /dev/null +++ b/Test/baseResults/spv.xfbOffsetOnBlockMembersAssignment.vert.out @@ -0,0 +1,76 @@ +spv.xfbOffsetOnBlockMembersAssignment.vert +// Module Version 10000 +// Generated by (magic number): 80007 +// Id's are bound by 33 + + Capability Shader + Capability TransformFeedback + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Vertex 4 "main" 10 27 31 32 + ExecutionMode 4 Xfb + Source GLSL 450 + Name 4 "main" + Name 8 "block2" + MemberName 8(block2) 0 "y1_out" + MemberName 8(block2) 1 "y2_out" + Name 10 "" + Name 25 "gl_PerVertex" + MemberName 25(gl_PerVertex) 0 "gl_Position" + MemberName 25(gl_PerVertex) 1 "gl_PointSize" + MemberName 25(gl_PerVertex) 2 "gl_ClipDistance" + MemberName 25(gl_PerVertex) 3 "gl_CullDistance" + Name 27 "" + Name 31 "gl_VertexID" + Name 32 "gl_InstanceID" + MemberDecorate 8(block2) 0 Offset 0 + MemberDecorate 8(block2) 1 Offset 4 + Decorate 8(block2) Block + Decorate 10 Location 5 + Decorate 10 XfbBuffer 2 + Decorate 10 XfbStride 20 + MemberDecorate 25(gl_PerVertex) 0 BuiltIn Position + MemberDecorate 25(gl_PerVertex) 1 BuiltIn PointSize + MemberDecorate 25(gl_PerVertex) 2 BuiltIn ClipDistance + MemberDecorate 25(gl_PerVertex) 3 BuiltIn CullDistance + Decorate 25(gl_PerVertex) Block + Decorate 27 XfbBuffer 0 + Decorate 27 XfbStride 0 + Decorate 31(gl_VertexID) BuiltIn VertexId + Decorate 32(gl_InstanceID) BuiltIn InstanceId + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeFloat 32 + 7: TypeVector 6(float) 4 + 8(block2): TypeStruct 6(float) 7(fvec4) + 9: TypePointer Output 8(block2) + 10: 9(ptr) Variable Output + 11: TypeInt 32 1 + 12: 11(int) Constant 0 + 13: 6(float) Constant 1088421888 + 14: TypePointer Output 6(float) + 16: 11(int) Constant 1 + 17: 6(float) Constant 1065353216 + 18: 6(float) Constant 0 + 19: 7(fvec4) ConstantComposite 17 18 18 17 + 20: TypePointer Output 7(fvec4) + 22: TypeInt 32 0 + 23: 22(int) Constant 1 + 24: TypeArray 6(float) 23 +25(gl_PerVertex): TypeStruct 7(fvec4) 6(float) 24 24 + 26: TypePointer Output 25(gl_PerVertex) + 27: 26(ptr) Variable Output + 28: 7(fvec4) ConstantComposite 18 18 18 18 + 30: TypePointer Input 11(int) + 31(gl_VertexID): 30(ptr) Variable Input +32(gl_InstanceID): 30(ptr) Variable Input + 4(main): 2 Function None 3 + 5: Label + 15: 14(ptr) AccessChain 10 12 + Store 15 13 + 21: 20(ptr) AccessChain 10 16 + Store 21 19 + 29: 20(ptr) AccessChain 27 12 + Store 29 28 + Return + FunctionEnd diff --git a/Test/baseResults/spv.xfbOverlapOffsetCheckWithBlockAndMember.vert.out b/Test/baseResults/spv.xfbOverlapOffsetCheckWithBlockAndMember.vert.out new file mode 100644 index 0000000000000000000000000000000000000000..ebc496299b9eee5c1763a625da06fa9e82ee4f56 --- /dev/null +++ b/Test/baseResults/spv.xfbOverlapOffsetCheckWithBlockAndMember.vert.out @@ -0,0 +1,88 @@ +spv.xfbOverlapOffsetCheckWithBlockAndMember.vert +// Module Version 10000 +// Generated by (magic number): 80007 +// Id's are bound by 39 + + Capability Shader + Capability TransformFeedback + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Vertex 4 "main" 10 33 37 38 + ExecutionMode 4 Xfb + Source GLSL 450 + Name 4 "main" + Name 8 "block2" + MemberName 8(block2) 0 "v" + MemberName 8(block2) 1 "u" + MemberName 8(block2) 2 "w" + MemberName 8(block2) 3 "x" + Name 10 "" + Name 31 "gl_PerVertex" + MemberName 31(gl_PerVertex) 0 "gl_Position" + MemberName 31(gl_PerVertex) 1 "gl_PointSize" + MemberName 31(gl_PerVertex) 2 "gl_ClipDistance" + MemberName 31(gl_PerVertex) 3 "gl_CullDistance" + Name 33 "" + Name 37 "gl_VertexID" + Name 38 "gl_InstanceID" + MemberDecorate 8(block2) 0 Offset 12 + MemberDecorate 8(block2) 1 Offset 28 + MemberDecorate 8(block2) 2 Offset 40 + MemberDecorate 8(block2) 3 Offset 56 + Decorate 8(block2) Block + Decorate 10 Location 5 + Decorate 10 XfbBuffer 3 + Decorate 10 XfbStride 72 + MemberDecorate 31(gl_PerVertex) 0 BuiltIn Position + MemberDecorate 31(gl_PerVertex) 1 BuiltIn PointSize + MemberDecorate 31(gl_PerVertex) 2 BuiltIn ClipDistance + MemberDecorate 31(gl_PerVertex) 3 BuiltIn CullDistance + Decorate 31(gl_PerVertex) Block + Decorate 33 XfbBuffer 0 + Decorate 33 XfbStride 0 + Decorate 37(gl_VertexID) BuiltIn VertexId + Decorate 38(gl_InstanceID) BuiltIn InstanceId + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeFloat 32 + 7: TypeVector 6(float) 4 + 8(block2): TypeStruct 7(fvec4) 6(float) 7(fvec4) 7(fvec4) + 9: TypePointer Output 8(block2) + 10: 9(ptr) Variable Output + 11: TypeInt 32 1 + 12: 11(int) Constant 0 + 13: 6(float) Constant 1065353216 + 14: 6(float) Constant 0 + 15: 7(fvec4) ConstantComposite 13 14 13 14 + 16: TypePointer Output 7(fvec4) + 18: 11(int) Constant 1 + 19: 6(float) Constant 1084227584 + 20: TypePointer Output 6(float) + 22: 11(int) Constant 2 + 23: 7(fvec4) ConstantComposite 13 14 14 13 + 25: 11(int) Constant 3 + 26: 7(fvec4) ConstantComposite 19 14 14 14 + 28: TypeInt 32 0 + 29: 28(int) Constant 1 + 30: TypeArray 6(float) 29 +31(gl_PerVertex): TypeStruct 7(fvec4) 6(float) 30 30 + 32: TypePointer Output 31(gl_PerVertex) + 33: 32(ptr) Variable Output + 34: 7(fvec4) ConstantComposite 14 14 14 14 + 36: TypePointer Input 11(int) + 37(gl_VertexID): 36(ptr) Variable Input +38(gl_InstanceID): 36(ptr) Variable Input + 4(main): 2 Function None 3 + 5: Label + 17: 16(ptr) AccessChain 10 12 + Store 17 15 + 21: 20(ptr) AccessChain 10 18 + Store 21 19 + 24: 16(ptr) AccessChain 10 22 + Store 24 23 + 27: 16(ptr) AccessChain 10 25 + Store 27 26 + 35: 16(ptr) AccessChain 33 12 + Store 35 34 + Return + FunctionEnd diff --git a/Test/spv.xfbOffsetOnBlockMembersAssignment.vert b/Test/spv.xfbOffsetOnBlockMembersAssignment.vert new file mode 100644 index 0000000000000000000000000000000000000000..40943f77a9d60d994c9833b7d1b5188ac997c38b --- /dev/null +++ b/Test/spv.xfbOffsetOnBlockMembersAssignment.vert @@ -0,0 +1,13 @@ +#version 450 + +layout(xfb_buffer=2) out; +layout(location=5, xfb_offset=0) out block2 { + float y1_out; + vec4 y2_out; +}; + +void main() { + y1_out = 7.0; + y2_out = vec4(1.0, 0.0, 0.0, 1.0); + gl_Position = vec4(0.0); +} diff --git a/Test/spv.xfbOverlapOffsetCheckWithBlockAndMember.vert b/Test/spv.xfbOverlapOffsetCheckWithBlockAndMember.vert new file mode 100644 index 0000000000000000000000000000000000000000..3f493dc11f01f739a63c7aa44619b0b3b8606cfa --- /dev/null +++ b/Test/spv.xfbOverlapOffsetCheckWithBlockAndMember.vert @@ -0,0 +1,19 @@ +#version 450 + +/* block definition from GLSL spec 4.60, section 4.4.2, Output Layout Qualifiers */ + +layout(location=5, xfb_buffer = 3, xfb_offset = 12) out block2 { + vec4 v; // v will be written to byte offsets 12 through 27 of buffer + float u; // u will be written to offset 28 + layout(xfb_offset = 40) vec4 w; + vec4 x; // x will be written to offset 56, the next available offset +}; + +void main() { + v = vec4(1.0, 0.0, 1.0, 0.0); + u = 5.0; + w = vec4(1.0, 0.0, 0.0, 1.0); + x = vec4(5.0, 0.0, 0.0, 0.0); + + gl_Position = vec4(0.0); +} diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index fba75dda26ca6948496c8143d9eb29f3dc356798..ad1645de0b7d30a2611fe42fe776db27a21d28d0 100755 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -6843,6 +6843,16 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con layoutMemberLocationArrayCheck(loc, memberWithLocation, arraySizes); + // Ensure that the block has an XfbBuffer assigned. This is needed + // because if the block has a XfbOffset assigned, then it is + // assumed that it has implicitly assigned the current global + // XfbBuffer, and because it's members need to be assigned a + // XfbOffset if they lack it. + if (currentBlockQualifier.storage == EvqVaryingOut && globalOutputDefaults.hasXfbBuffer()) { + if (!currentBlockQualifier.hasXfbBuffer() && currentBlockQualifier.hasXfbOffset()) + currentBlockQualifier.layoutXfbBuffer = globalOutputDefaults.layoutXfbBuffer; + } + // Process the members fixBlockLocations(loc, currentBlockQualifier, typeList, memberWithLocation, memberWithoutLocation); fixXfbOffsets(currentBlockQualifier, typeList); diff --git a/gtests/Spv.FromFile.cpp b/gtests/Spv.FromFile.cpp index bc05eede95af0f1dd02a9a2e6eba91bd2f2fdbf1..ee8cf001dca495a74b12f4e255ef83b72bcc0610 100644 --- a/gtests/Spv.FromFile.cpp +++ b/gtests/Spv.FromFile.cpp @@ -440,7 +440,9 @@ INSTANTIATE_TEST_CASE_P( "spv.rankShift.comp", "spv.specConst.vert", "spv.OVR_multiview.vert", + "spv.xfbOffsetOnBlockMembersAssignment.vert", "spv.xfbOffsetOnStructMembersAssignment.vert", + "spv.xfbOverlapOffsetCheckWithBlockAndMember.vert", })), FileNameAsCustomTestSuffix );