diff --git a/Test/baseResults/440.vert.out b/Test/baseResults/440.vert.out index 33738aaa..41796cb5 100644 --- a/Test/baseResults/440.vert.out +++ b/Test/baseResults/440.vert.out @@ -46,7 +46,9 @@ ERROR: 0:166: 'xfb_buffer' : buffer is too large: gl_MaxTransformFeedbackBuffers ERROR: 0:169: 'xfb_buffer' : buffer is too large: gl_MaxTransformFeedbackBuffers is 4 ERROR: 0:169: 'xfb_stride' : 1/4 stride is too large: gl_MaxTransformFeedbackInterleavedComponents is 64 ERROR: 0:171: 'xfb_buffer' : buffer is too large: gl_MaxTransformFeedbackBuffers is 4 +ERROR: 0:178: 'xfb_offset' : overlapping offsets at offset 36 in buffer 3 ERROR: 0:179: 'xfb_buffer' : member cannot contradict block (or what block inherited from global) +ERROR: 0:178: 'xfb_offset' : overlapping offsets at offset 32 in buffer 3 ERROR: 0:185: 'gl_BaseVertexARB' : required extension not requested: GL_ARB_shader_draw_parameters ERROR: 0:185: 'gl_BaseInstanceARB' : required extension not requested: GL_ARB_shader_draw_parameters ERROR: 0:185: 'gl_DrawIDARB' : required extension not requested: GL_ARB_shader_draw_parameters @@ -54,7 +56,7 @@ ERROR: 0:193: 'assign' : l-value required "gl_BaseVertexARB" (can't modify shad ERROR: 0:194: 'assign' : l-value required "gl_BaseInstanceARB" (can't modify shader input) ERROR: 0:195: 'assign' : l-value required "gl_DrawIDARB" (can't modify shader input) ERROR: 0:196: 'glBaseInstanceARB' : undeclared identifier -ERROR: 55 compilation errors. No code generated. +ERROR: 57 compilation errors. No code generated. Shader version: 440 @@ -154,7 +156,7 @@ ERROR: node is still EOpNull! 0:? 'bbinst9' ( out block{layout( xfb_buffer=4 xfb_offset=1) out bool b, layout( xfb_buffer=4 xfb_offset=12) out structure{ global bool b, global structure{ global int i, global double d, global float f} s, global 2-component vector of float v2} t, layout( xfb_buffer=4 xfb_offset=52) out 3X3 matrix of float m3, layout( xfb_buffer=4 xfb_offset=90) out int i, layout( xfb_buffer=4 xfb_offset=98) out double d, layout( xfb_buffer=4 xfb_offset=108) out structure{ global int a} s}) 0:? 'bm' (layout( xfb_buffer=5 xfb_offset=0) smooth out float) 0:? 'bbinst10' ( out block{layout( xfb_buffer=7 xfb_offset=0) out 4X4 matrix of double m1, layout( xfb_buffer=7 xfb_offset=128) out 4X4 matrix of double m2, layout( xfb_buffer=7 xfb_offset=256) out float f}) -0:? 'anon@0' ( out block{layout( xfb_buffer=0 xfb_offset=36) gl_Position 4-component vector of float Position gl_Position, layout( xfb_buffer=0 xfb_offset=32) gl_PointSize float PointSize gl_PointSize, }) +0:? 'anon@0' ( out block{layout( xfb_buffer=3 xfb_offset=36) gl_Position 4-component vector of float Position gl_Position, layout( xfb_buffer=3 xfb_offset=32) gl_PointSize float PointSize gl_PointSize, }) 0:? 'gl_VertexID' ( gl_VertexId int VertexId) 0:? 'gl_InstanceID' ( gl_InstanceId int InstanceId) @@ -237,7 +239,7 @@ ERROR: node is still EOpNull! 0:? 'bbinst9' ( out block{layout( xfb_buffer=4 xfb_offset=1) out bool b, layout( xfb_buffer=4 xfb_offset=12) out structure{ global bool b, global structure{ global int i, global double d, global float f} s, global 2-component vector of float v2} t, layout( xfb_buffer=4 xfb_offset=52) out 3X3 matrix of float m3, layout( xfb_buffer=4 xfb_offset=90) out int i, layout( xfb_buffer=4 xfb_offset=98) out double d, layout( xfb_buffer=4 xfb_offset=108) out structure{ global int a} s}) 0:? 'bm' (layout( xfb_buffer=5 xfb_offset=0) smooth out float) 0:? 'bbinst10' ( out block{layout( xfb_buffer=7 xfb_offset=0) out 4X4 matrix of double m1, layout( xfb_buffer=7 xfb_offset=128) out 4X4 matrix of double m2, layout( xfb_buffer=7 xfb_offset=256) out float f}) -0:? 'anon@0' ( out block{layout( xfb_buffer=0 xfb_offset=36) gl_Position 4-component vector of float Position gl_Position, layout( xfb_buffer=0 xfb_offset=32) gl_PointSize float PointSize gl_PointSize, }) +0:? 'anon@0' ( out block{layout( xfb_buffer=3 xfb_offset=36) gl_Position 4-component vector of float Position gl_Position, layout( xfb_buffer=3 xfb_offset=32) gl_PointSize float PointSize gl_PointSize, }) 0:? 'gl_VertexID' ( gl_VertexId int VertexId) 0:? 'gl_InstanceID' ( gl_InstanceId int InstanceId) diff --git a/Test/baseResults/spv.xfb2.vert.out b/Test/baseResults/spv.xfb2.vert.out new file mode 100755 index 00000000..0eb91373 --- /dev/null +++ b/Test/baseResults/spv.xfb2.vert.out @@ -0,0 +1,68 @@ +spv.xfb2.vert +// Module Version 10000 +// Generated by (magic number): 80003 +// Id's are bound by 35 + + Capability Shader + Capability TransformFeedback + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Vertex 4 "main" 10 14 + ExecutionMode 4 Xfb + Source GLSL 450 + Name 4 "main" + Name 8 "gl_PerVertex" + MemberName 8(gl_PerVertex) 0 "gl_Position" + Name 10 "" + Name 14 "position" + Name 17 "ComponentsBlock" + MemberName 17(ComponentsBlock) 0 "c1" + MemberName 17(ComponentsBlock) 1 "c2" + Name 19 "components" + MemberDecorate 8(gl_PerVertex) 0 Offset 16 + MemberDecorate 8(gl_PerVertex) 0 BuiltIn Position + Decorate 8(gl_PerVertex) Block + Decorate 10 XfbBuffer 3 + Decorate 10 XfbStride 32 + Decorate 14(position) Location 0 + MemberDecorate 17(ComponentsBlock) 0 Offset 0 + MemberDecorate 17(ComponentsBlock) 1 Offset 16 + Decorate 17(ComponentsBlock) Block + Decorate 19(components) DescriptorSet 0 + Decorate 19(components) Binding 5 + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeFloat 32 + 7: TypeVector 6(float) 4 + 8(gl_PerVertex): TypeStruct 7(fvec4) + 9: TypePointer Output 8(gl_PerVertex) + 10: 9(ptr) Variable Output + 11: TypeInt 32 1 + 12: 11(int) Constant 0 + 13: TypePointer Input 7(fvec4) + 14(position): 13(ptr) Variable Input + 16: TypeVector 6(float) 2 +17(ComponentsBlock): TypeStruct 7(fvec4) 16(fvec2) + 18: TypePointer Uniform 17(ComponentsBlock) + 19(components): 18(ptr) Variable Uniform + 20: TypePointer Uniform 7(fvec4) + 24: 11(int) Constant 1 + 25: TypePointer Uniform 16(fvec2) + 28: 6(float) Constant 0 + 33: TypePointer Output 7(fvec4) + 4(main): 2 Function None 3 + 5: Label + 15: 7(fvec4) Load 14(position) + 21: 20(ptr) AccessChain 19(components) 12 + 22: 7(fvec4) Load 21 + 23: 7(fvec4) FAdd 15 22 + 26: 25(ptr) AccessChain 19(components) 24 + 27: 16(fvec2) Load 26 + 29: 6(float) CompositeExtract 27 0 + 30: 6(float) CompositeExtract 27 1 + 31: 7(fvec4) CompositeConstruct 29 30 28 28 + 32: 7(fvec4) FAdd 23 31 + 34: 33(ptr) AccessChain 10 12 + Store 34 32 + Return + FunctionEnd diff --git a/Test/baseResults/spv.xfb3.vert.out b/Test/baseResults/spv.xfb3.vert.out new file mode 100755 index 00000000..7d31a819 --- /dev/null +++ b/Test/baseResults/spv.xfb3.vert.out @@ -0,0 +1,68 @@ +spv.xfb3.vert +// Module Version 10000 +// Generated by (magic number): 80003 +// Id's are bound by 35 + + Capability Shader + Capability TransformFeedback + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Vertex 4 "main" 10 14 + ExecutionMode 4 Xfb + Source GLSL 450 + Name 4 "main" + Name 8 "gl_PerVertex" + MemberName 8(gl_PerVertex) 0 "gl_Position" + Name 10 "" + Name 14 "position" + Name 17 "ComponentsBlock" + MemberName 17(ComponentsBlock) 0 "c1" + MemberName 17(ComponentsBlock) 1 "c2" + Name 19 "components" + MemberDecorate 8(gl_PerVertex) 0 Offset 16 + MemberDecorate 8(gl_PerVertex) 0 BuiltIn Position + Decorate 8(gl_PerVertex) Block + Decorate 10 XfbBuffer 3 + Decorate 10 XfbStride 80 + Decorate 14(position) Location 0 + MemberDecorate 17(ComponentsBlock) 0 Offset 0 + MemberDecorate 17(ComponentsBlock) 1 Offset 16 + Decorate 17(ComponentsBlock) Block + Decorate 19(components) DescriptorSet 0 + Decorate 19(components) Binding 5 + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeFloat 32 + 7: TypeVector 6(float) 4 + 8(gl_PerVertex): TypeStruct 7(fvec4) + 9: TypePointer Output 8(gl_PerVertex) + 10: 9(ptr) Variable Output + 11: TypeInt 32 1 + 12: 11(int) Constant 0 + 13: TypePointer Input 7(fvec4) + 14(position): 13(ptr) Variable Input + 16: TypeVector 6(float) 2 +17(ComponentsBlock): TypeStruct 7(fvec4) 16(fvec2) + 18: TypePointer Uniform 17(ComponentsBlock) + 19(components): 18(ptr) Variable Uniform + 20: TypePointer Uniform 7(fvec4) + 24: 11(int) Constant 1 + 25: TypePointer Uniform 16(fvec2) + 28: 6(float) Constant 0 + 33: TypePointer Output 7(fvec4) + 4(main): 2 Function None 3 + 5: Label + 15: 7(fvec4) Load 14(position) + 21: 20(ptr) AccessChain 19(components) 12 + 22: 7(fvec4) Load 21 + 23: 7(fvec4) FAdd 15 22 + 26: 25(ptr) AccessChain 19(components) 24 + 27: 16(fvec2) Load 26 + 29: 6(float) CompositeExtract 27 0 + 30: 6(float) CompositeExtract 27 1 + 31: 7(fvec4) CompositeConstruct 29 30 28 28 + 32: 7(fvec4) FAdd 23 31 + 34: 33(ptr) AccessChain 10 12 + Store 34 32 + Return + FunctionEnd diff --git a/Test/spv.xfb2.vert b/Test/spv.xfb2.vert new file mode 100644 index 00000000..895666d9 --- /dev/null +++ b/Test/spv.xfb2.vert @@ -0,0 +1,18 @@ +#version 450 + +layout (location = 0) in vec4 position; +layout (binding = 5) uniform ComponentsBlock +{ + vec4 c1; + vec2 c2; +} components; + +layout (xfb_buffer = 3, xfb_offset = 16) out gl_PerVertex +{ + vec4 gl_Position; +}; + +void main() +{ + gl_Position = position + components.c1 + vec4(components.c2, 0.0, 0.0); +} \ No newline at end of file diff --git a/Test/spv.xfb3.vert b/Test/spv.xfb3.vert new file mode 100644 index 00000000..2eae7c9e --- /dev/null +++ b/Test/spv.xfb3.vert @@ -0,0 +1,18 @@ +#version 450 + +layout (location = 0) in vec4 position; +layout (binding = 5) uniform ComponentsBlock +{ + vec4 c1; + vec2 c2; +} components; + +layout (xfb_buffer = 3, xfb_offset = 16) out gl_PerVertex +{ + layout(xfb_stride = 80) vec4 gl_Position; +}; + +void main() +{ + gl_Position = position + components.c1 + vec4(components.c2, 0.0, 0.0); +} \ No newline at end of file diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index 9254aa62..0f94d791 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -3486,7 +3486,8 @@ void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newT // Fix XFB stuff up, it applies to the order of the redeclaration, not // the order of the original members. if (currentBlockQualifier.storage == EvqVaryingOut && globalOutputDefaults.hasXfbBuffer()) { - currentBlockQualifier.layoutXfbBuffer = globalOutputDefaults.layoutXfbBuffer; + if (!currentBlockQualifier.hasXfbBuffer()) + currentBlockQualifier.layoutXfbBuffer = globalOutputDefaults.layoutXfbBuffer; fixBlockXfbOffsets(currentBlockQualifier, newTypeList); } @@ -3545,7 +3546,8 @@ void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newT error(memberLoc, "cannot add non-XFB layout to redeclared block member", member->type->getFieldName().c_str(), ""); if (newType.getQualifier().patch) error(memberLoc, "cannot add patch to redeclared block member", member->type->getFieldName().c_str(), ""); - if (newType.getQualifier().hasXfbBuffer() && newType.getQualifier().layoutXfbBuffer != currentBlockQualifier.layoutXfbBuffer) + if (newType.getQualifier().hasXfbBuffer() && + newType.getQualifier().layoutXfbBuffer != currentBlockQualifier.layoutXfbBuffer) error(memberLoc, "member cannot contradict block (or what block inherited from global)", "xfb_buffer", ""); oldType.getQualifier().centroid = newType.getQualifier().centroid; oldType.getQualifier().sample = newType.getQualifier().sample; @@ -3555,11 +3557,20 @@ void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newT oldType.getQualifier().flat = newType.getQualifier().flat; oldType.getQualifier().nopersp = newType.getQualifier().nopersp; oldType.getQualifier().layoutXfbOffset = newType.getQualifier().layoutXfbOffset; - if (oldType.getQualifier().layoutXfbOffset != TQualifier::layoutXfbBufferEnd) + oldType.getQualifier().layoutXfbBuffer = newType.getQualifier().layoutXfbBuffer; + oldType.getQualifier().layoutXfbStride = newType.getQualifier().layoutXfbStride; + if (oldType.getQualifier().layoutXfbOffset != TQualifier::layoutXfbBufferEnd) { + // if any member as an xfb_offset, then the block's xfb_buffer inherents current xfb_buffer, + // and for xfb processing, the member needs it as well, along with xfb_stride type.getQualifier().layoutXfbBuffer = currentBlockQualifier.layoutXfbBuffer; + oldType.getQualifier().layoutXfbBuffer = currentBlockQualifier.layoutXfbBuffer; + } if (oldType.isImplicitlySizedArray() && newType.isExplicitlySizedArray()) oldType.changeOuterArraySize(newType.getOuterArraySize()); + // check and process the member's type, which will include managing xfb information + layoutTypeCheck(loc, oldType); + // go to next member ++member; } else { @@ -4803,11 +4814,11 @@ void TParseContext::layoutQualifierCheck(const TSourceLoc& loc, const TQualifier error(loc, "requires uniform or buffer storage qualifier", "binding", ""); } if (qualifier.hasStream()) { - if (qualifier.storage != EvqVaryingOut) + if (!qualifier.isPipeOutput()) error(loc, "can only be used on an output", "stream", ""); } if (qualifier.hasXfb()) { - if (qualifier.storage != EvqVaryingOut) + if (!qualifier.isPipeOutput()) error(loc, "can only be used on an output", "xfb layout qualifier", ""); } if (qualifier.hasUniformLayout()) { diff --git a/gtests/Spv.FromFile.cpp b/gtests/Spv.FromFile.cpp index 85762f4c..3c7643cc 100644 --- a/gtests/Spv.FromFile.cpp +++ b/gtests/Spv.FromFile.cpp @@ -331,6 +331,8 @@ INSTANTIATE_TEST_CASE_P( "spv.precise.tese", "spv.precise.tesc", "spv.xfb.vert", + "spv.xfb2.vert", + "spv.xfb3.vert", })), FileNameAsCustomTestSuffix );