diff --git a/Test/440.vert b/Test/440.vert index 2e61f7975..4ab6f2ee2 100644 --- a/Test/440.vert +++ b/Test/440.vert @@ -174,6 +174,12 @@ out layout(xfb_buffer=7, xfb_offset=0) bblck10 { // link ERROR, implicit stride float f; } bbinst10; +layout(xfb_buffer = 3) out; +layout(xfb_offset = 32) out gl_PerVertex { + layout(xfb_buffer = 2) float gl_PointSize; // ERROR, change in xfb_buffer + vec4 gl_Position; +}; + int drawParamsBad() { return gl_BaseVertexARB + gl_BaseInstanceARB + gl_DrawIDARB; // ERROR, extension not requested diff --git a/Test/baseResults/400.geom.out b/Test/baseResults/400.geom.out index 1d009d9ca..52ebebced 100644 --- a/Test/baseResults/400.geom.out +++ b/Test/baseResults/400.geom.out @@ -1,7 +1,7 @@ 400.geom ERROR: 0:12: 'invocations' : can only apply to a standalone qualifier ERROR: 0:20: 'patch' : not supported in this stage: geometry -ERROR: 0:20: 'gl_PointSize' : cannot add layout to redeclared block member +ERROR: 0:20: 'gl_PointSize' : cannot add non-XFB layout to redeclared block member ERROR: 0:20: 'gl_PointSize' : cannot add patch to redeclared block member ERROR: 0:25: 'length' : array must first be sized by a redeclaration or layout qualifier ERROR: 0:36: 'length' : array must first be sized by a redeclaration or layout qualifier diff --git a/Test/baseResults/440.vert.out b/Test/baseResults/440.vert.out index 8eafb0aea..33738aaa5 100644 --- a/Test/baseResults/440.vert.out +++ b/Test/baseResults/440.vert.out @@ -46,51 +46,52 @@ 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:179: 'gl_BaseVertexARB' : required extension not requested: GL_ARB_shader_draw_parameters -ERROR: 0:179: 'gl_BaseInstanceARB' : required extension not requested: GL_ARB_shader_draw_parameters -ERROR: 0:179: 'gl_DrawIDARB' : required extension not requested: GL_ARB_shader_draw_parameters -ERROR: 0:187: 'assign' : l-value required "gl_BaseVertexARB" (can't modify shader input) -ERROR: 0:188: 'assign' : l-value required "gl_BaseInstanceARB" (can't modify shader input) -ERROR: 0:189: 'assign' : l-value required "gl_DrawIDARB" (can't modify shader input) -ERROR: 0:190: 'glBaseInstanceARB' : undeclared identifier -ERROR: 54 compilation errors. No code generated. +ERROR: 0:179: 'xfb_buffer' : member cannot contradict block (or what block inherited from global) +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 +ERROR: 0:193: 'assign' : l-value required "gl_BaseVertexARB" (can't modify shader input) +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. Shader version: 440 Requested GL_ARB_shader_draw_parameters in xfb mode ERROR: node is still EOpNull! -0:177 Function Definition: drawParamsBad( ( global int) -0:177 Function Parameters: -0:179 Sequence -0:179 Branch: Return with expression -0:179 add ( temp int) -0:179 add ( temp int) -0:179 'gl_BaseVertexARB' ( in int BaseVertex) -0:179 'gl_BaseInstanceARB' ( in int BaseInstance) -0:179 'gl_DrawIDARB' ( in int DrawId) -0:184 Function Definition: drawParams( ( global int) -0:184 Function Parameters: -0:186 Sequence -0:186 Branch: Return with expression -0:186 add ( temp int) -0:186 add ( temp int) -0:186 'gl_BaseVertexARB' ( in int BaseVertex) -0:186 'gl_BaseInstanceARB' ( in int BaseInstance) -0:186 'gl_DrawIDARB' ( in int DrawId) -0:187 move second child to first child ( temp int) -0:187 'gl_BaseVertexARB' ( in int BaseVertex) -0:187 Constant: -0:187 3 (const int) -0:188 move second child to first child ( temp int) -0:188 'gl_BaseInstanceARB' ( in int BaseInstance) -0:188 Constant: -0:188 3 (const int) -0:189 move second child to first child ( temp int) -0:189 'gl_DrawIDARB' ( in int DrawId) -0:189 Constant: -0:189 3 (const int) -0:190 'glBaseInstanceARB' ( temp float) +0:183 Function Definition: drawParamsBad( ( global int) +0:183 Function Parameters: +0:185 Sequence +0:185 Branch: Return with expression +0:185 add ( temp int) +0:185 add ( temp int) +0:185 'gl_BaseVertexARB' ( in int BaseVertex) +0:185 'gl_BaseInstanceARB' ( in int BaseInstance) +0:185 'gl_DrawIDARB' ( in int DrawId) +0:190 Function Definition: drawParams( ( global int) +0:190 Function Parameters: +0:192 Sequence +0:192 Branch: Return with expression +0:192 add ( temp int) +0:192 add ( temp int) +0:192 'gl_BaseVertexARB' ( in int BaseVertex) +0:192 'gl_BaseInstanceARB' ( in int BaseInstance) +0:192 'gl_DrawIDARB' ( in int DrawId) +0:193 move second child to first child ( temp int) +0:193 'gl_BaseVertexARB' ( in int BaseVertex) +0:193 Constant: +0:193 3 (const int) +0:194 move second child to first child ( temp int) +0:194 'gl_BaseInstanceARB' ( in int BaseInstance) +0:194 Constant: +0:194 3 (const int) +0:195 move second child to first child ( temp int) +0:195 'gl_DrawIDARB' ( in int DrawId) +0:195 Constant: +0:195 3 (const int) +0:196 'glBaseInstanceARB' ( temp float) 0:? Linker Objects 0:? 'a' (layout( location=2 component=2) in 2-component vector of float) 0:? 'b' (layout( location=2 component=1) in float) @@ -153,6 +154,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:? 'gl_VertexID' ( gl_VertexId int VertexId) 0:? 'gl_InstanceID' ( gl_InstanceId int InstanceId) @@ -235,6 +237,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:? 'gl_VertexID' ( gl_VertexId int VertexId) 0:? 'gl_InstanceID' ( gl_InstanceId int InstanceId) diff --git a/Test/baseResults/spv.builtInXFB.vert.out b/Test/baseResults/spv.builtInXFB.vert.out new file mode 100755 index 000000000..741030e95 --- /dev/null +++ b/Test/baseResults/spv.builtInXFB.vert.out @@ -0,0 +1,47 @@ +spv.builtInXFB.vert +// Module Version 10000 +// Generated by (magic number): 80002 +// Id's are bound by 21 + + Capability Shader + Capability TransformFeedback + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Vertex 4 "main" 10 + ExecutionMode 4 Xfb + Source GLSL 450 + Name 4 "main" + Name 8 "gl_PerVertex" + MemberName 8(gl_PerVertex) 0 "gl_Position" + MemberName 8(gl_PerVertex) 1 "gl_PointSize" + Name 10 "" + MemberDecorate 8(gl_PerVertex) 0 Offset 20 + MemberDecorate 8(gl_PerVertex) 0 BuiltIn Position + MemberDecorate 8(gl_PerVertex) 1 Offset 16 + MemberDecorate 8(gl_PerVertex) 1 BuiltIn PointSize + Decorate 8(gl_PerVertex) Block + Decorate 8(gl_PerVertex) XfbBuffer 0 + Decorate 10 XfbBuffer 0 + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeFloat 32 + 7: TypeVector 6(float) 4 + 8(gl_PerVertex): TypeStruct 7(fvec4) 6(float) + 9: TypePointer Output 8(gl_PerVertex) + 10: 9(ptr) Variable Output + 11: TypeInt 32 1 + 12: 11(int) Constant 0 + 13: 6(float) Constant 1065353216 + 14: 7(fvec4) ConstantComposite 13 13 13 13 + 15: TypePointer Output 7(fvec4) + 17: 11(int) Constant 1 + 18: 6(float) Constant 1073741824 + 19: TypePointer Output 6(float) + 4(main): 2 Function None 3 + 5: Label + 16: 15(ptr) AccessChain 10 12 + Store 16 14 + 20: 19(ptr) AccessChain 10 17 + Store 20 18 + Return + FunctionEnd diff --git a/Test/spv.builtInXFB.vert b/Test/spv.builtInXFB.vert new file mode 100644 index 000000000..619bc1e2f --- /dev/null +++ b/Test/spv.builtInXFB.vert @@ -0,0 +1,15 @@ +#version 450 + +layout(xfb_buffer = 1, xfb_stride = 64) out; + +layout (xfb_buffer = 1, xfb_offset = 16) out gl_PerVertex +{ + float gl_PointSize; + vec4 gl_Position; +}; + +void main() +{ + gl_Position = vec4(1.0); + gl_PointSize = 2.0; +} \ No newline at end of file diff --git a/glslang/Include/Types.h b/glslang/Include/Types.h index d23b61531..cc847b5e7 100644 --- a/glslang/Include/Types.h +++ b/glslang/Include/Types.h @@ -650,15 +650,19 @@ public: layoutXfbOffset = layoutXfbOffsetEnd; } - bool hasLayout() const + bool hasNonXfbLayout() const { return hasUniformLayout() || hasAnyLocation() || hasStream() || - hasXfb() || hasFormat() || layoutPushConstant; } + bool hasLayout() const + { + return hasNonXfbLayout() || + hasXfb(); + } TLayoutMatrix layoutMatrix : 3; TLayoutPacking layoutPacking : 4; int layoutOffset; diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index a24949795..80471c448 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -3478,17 +3478,24 @@ void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newT return; } + // 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; + fixBlockXfbOffsets(currentBlockQualifier, newTypeList); + } + // Edit and error check the container against the redeclaration // - remove unused members // - ensure remaining qualifiers/types match + TType& type = block->getWritableType(); #ifdef NV_EXTENSIONS // if gl_PerVertex is redeclared for the purpose of passing through "gl_Position" - // for passthrough purpose, the redclared block should have the same qualifers as + // for passthrough purpose, the redeclared block should have the same qualifers as // the current one - if (currentBlockQualifier.layoutPassthrough) - { + if (currentBlockQualifier.layoutPassthrough) { type.getQualifier().layoutPassthrough = currentBlockQualifier.layoutPassthrough; type.getQualifier().storage = currentBlockQualifier.storage; type.getQualifier().layoutStream = currentBlockQualifier.layoutStream; @@ -3529,10 +3536,12 @@ void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newT arrayLimitCheck(loc, member->type->getFieldName(), newType.getOuterArraySize()); if (newType.getQualifier().isMemory()) error(memberLoc, "cannot add memory qualifier to redeclared block member", member->type->getFieldName().c_str(), ""); - if (newType.getQualifier().hasLayout()) - error(memberLoc, "cannot add layout to redeclared block member", member->type->getFieldName().c_str(), ""); + if (newType.getQualifier().hasNonXfbLayout()) + 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) + 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; oldType.getQualifier().invariant = newType.getQualifier().invariant; @@ -3540,6 +3549,7 @@ void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newT oldType.getQualifier().smooth = newType.getQualifier().smooth; oldType.getQualifier().flat = newType.getQualifier().flat; oldType.getQualifier().nopersp = newType.getQualifier().nopersp; + oldType.getQualifier().layoutXfbOffset = newType.getQualifier().layoutXfbOffset; if (oldType.isImplicitlySizedArray() && newType.isExplicitlySizedArray()) oldType.changeOuterArraySize(newType.getOuterArraySize()); diff --git a/gtests/Spv.FromFile.cpp b/gtests/Spv.FromFile.cpp index f19d85e9e..9a44fa42f 100644 --- a/gtests/Spv.FromFile.cpp +++ b/gtests/Spv.FromFile.cpp @@ -232,6 +232,7 @@ INSTANTIATE_TEST_CASE_P( "spv.bool.vert", "spv.boolInBlock.frag", "spv.branch-return.vert", + "spv.builtInXFB.vert", "spv.conditionalDiscard.frag", "spv.conversion.frag", "spv.dataOut.frag",