diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index 4ae52861e83e11182343d3360c2ba78c669d2b37..745021f2650858aef6c17adb9486973f9f743377 100755 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -2661,13 +2661,6 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type, builder.addCapability(spv::CapabilityGeometryStreams); builder.addDecoration(spvType, spv::DecorationStream, type.getQualifier().layoutStream); } - if (glslangIntermediate->getXfbMode()) { - builder.addCapability(spv::CapabilityTransformFeedback); - if (type.getQualifier().hasXfbStride()) - builder.addDecoration(spvType, spv::DecorationXfbStride, type.getQualifier().layoutXfbStride); - if (type.getQualifier().hasXfbBuffer()) - builder.addDecoration(spvType, spv::DecorationXfbBuffer, type.getQualifier().layoutXfbBuffer); - } } // Turn the expression forming the array size into an id. @@ -5508,15 +5501,6 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol builder.addDecoration(id, spv::DecorationIndex, symbol->getQualifier().layoutIndex); if (symbol->getQualifier().hasComponent()) builder.addDecoration(id, spv::DecorationComponent, symbol->getQualifier().layoutComponent); - if (glslangIntermediate->getXfbMode()) { - builder.addCapability(spv::CapabilityTransformFeedback); - if (symbol->getQualifier().hasXfbStride()) - builder.addDecoration(id, spv::DecorationXfbStride, symbol->getQualifier().layoutXfbStride); - if (symbol->getQualifier().hasXfbBuffer()) - builder.addDecoration(id, spv::DecorationXfbBuffer, symbol->getQualifier().layoutXfbBuffer); - if (symbol->getQualifier().hasXfbOffset()) - builder.addDecoration(id, spv::DecorationOffset, symbol->getQualifier().layoutXfbOffset); - } // atomic counters use this: if (symbol->getQualifier().hasOffset()) builder.addDecoration(id, spv::DecorationOffset, symbol->getQualifier().layoutOffset); @@ -5543,8 +5527,14 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol builder.addCapability(spv::CapabilityTransformFeedback); if (symbol->getQualifier().hasXfbStride()) builder.addDecoration(id, spv::DecorationXfbStride, symbol->getQualifier().layoutXfbStride); - if (symbol->getQualifier().hasXfbBuffer()) + if (symbol->getQualifier().hasXfbBuffer()) { builder.addDecoration(id, spv::DecorationXfbBuffer, symbol->getQualifier().layoutXfbBuffer); + unsigned stride = glslangIntermediate->getXfbStride(symbol->getQualifier().layoutXfbBuffer); + if (stride != glslang::TQualifier::layoutXfbStrideEnd) + builder.addDecoration(id, spv::DecorationXfbStride, stride); + } + if (symbol->getQualifier().hasXfbOffset()) + builder.addDecoration(id, spv::DecorationOffset, symbol->getQualifier().layoutXfbOffset); } if (symbol->getType().isImage()) { diff --git a/Test/baseResults/spv.builtInXFB.vert.out b/Test/baseResults/spv.builtInXFB.vert.out index 741030e9511dff3463969d85d537794160f5aec1..f13dfe1b24b130cff5e161500508cb8a64c023d4 100755 --- a/Test/baseResults/spv.builtInXFB.vert.out +++ b/Test/baseResults/spv.builtInXFB.vert.out @@ -20,8 +20,8 @@ spv.builtInXFB.vert 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 + Decorate 10 XfbBuffer 1 + Decorate 10 XfbStride 64 2: TypeVoid 3: TypeFunction 2 6: TypeFloat 32 diff --git a/Test/baseResults/spv.xfb.vert.out b/Test/baseResults/spv.xfb.vert.out new file mode 100755 index 0000000000000000000000000000000000000000..f609826818c075f54aa432fc59bd2602ca1afff9 --- /dev/null +++ b/Test/baseResults/spv.xfb.vert.out @@ -0,0 +1,55 @@ +spv.xfb.vert +// Module Version 10000 +// Generated by (magic number): 80002 +// Id's are bound by 16 + + Capability Shader + Capability TransformFeedback + 1: ExtInstImport "GLSL.std.450" + MemoryModel Logical GLSL450 + EntryPoint Vertex 4 "main" 8 11 14 15 + ExecutionMode 4 Xfb + Source GLSL 450 + Name 4 "main" + Name 8 "out1" + Name 9 "outXfb" + MemberName 9(outXfb) 0 "out2" + Name 11 "" + Name 12 "outXfb2" + MemberName 12(outXfb2) 0 "out3" + Name 14 "" + Name 15 "out4" + Decorate 8(out1) Location 0 + Decorate 8(out1) XfbBuffer 3 + Decorate 8(out1) XfbStride 48 + Decorate 8(out1) Offset 12 + MemberDecorate 9(outXfb) 0 Offset 8 + Decorate 9(outXfb) Block + Decorate 11 Location 1 + Decorate 11 XfbBuffer 2 + Decorate 11 XfbStride 32 + MemberDecorate 12(outXfb2) 0 Offset 60 + Decorate 12(outXfb2) Block + Decorate 14 Location 3 + Decorate 14 XfbBuffer 1 + Decorate 14 XfbStride 64 + Decorate 15(out4) Location 4 + Decorate 15(out4) XfbBuffer 0 + Decorate 15(out4) XfbStride 8 + Decorate 15(out4) Offset 4 + 2: TypeVoid + 3: TypeFunction 2 + 6: TypeFloat 32 + 7: TypePointer Output 6(float) + 8(out1): 7(ptr) Variable Output + 9(outXfb): TypeStruct 6(float) + 10: TypePointer Output 9(outXfb) + 11: 10(ptr) Variable Output + 12(outXfb2): TypeStruct 6(float) + 13: TypePointer Output 12(outXfb2) + 14: 13(ptr) Variable Output + 15(out4): 7(ptr) Variable Output + 4(main): 2 Function None 3 + 5: Label + Return + FunctionEnd diff --git a/Test/spv.xfb.vert b/Test/spv.xfb.vert new file mode 100644 index 0000000000000000000000000000000000000000..ad762bc214917f2230e51acd19d04ca3dc9c8713 --- /dev/null +++ b/Test/spv.xfb.vert @@ -0,0 +1,20 @@ +#version 450 + +layout(xfb_buffer = 3) out; +layout(xfb_stride = 48) out; +layout(xfb_offset = 12, location = 0) out float out1; + +layout(xfb_buffer = 2) out; +layout(location=1) out outXfb { + layout(xfb_buffer = 2, xfb_stride = 32, xfb_offset = 8) float out2; +}; + +layout(xfb_buffer = 1, location=3) out outXfb2 { + layout(xfb_stride = 64, xfb_offset = 60) float out3; +}; + +layout(location = 4, xfb_buffer = 0, xfb_offset = 4) out float out4; + +void main() +{ +} \ No newline at end of file diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index 80471c448bf92a4f71f334be4a742e017065a5ef..78a5d8ee6484082f7d423a6c3be8f0070a58be04 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -3550,7 +3550,8 @@ 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) + type.getQualifier().layoutXfbBuffer = currentBlockQualifier.layoutXfbBuffer; if (oldType.isImplicitlySizedArray() && newType.isExplicitlySizedArray()) oldType.changeOuterArraySize(newType.getOuterArraySize()); diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h index 8665176963e93de607e05ee45e75616580e34a6d..4d48c68d49dda701d7bcce8d72187f8f20af3ba1 100644 --- a/glslang/MachineIndependent/localintermediate.h +++ b/glslang/MachineIndependent/localintermediate.h @@ -583,6 +583,7 @@ public: xfbBuffers[buffer].stride = stride; return true; } + unsigned getXfbStride(int buffer) const { return xfbBuffers[buffer].stride; } int addXfbBufferOffset(const TType&); unsigned int computeTypeXfbSize(const TType&, bool& containsDouble) const; static int getBaseAlignmentScalar(const TType&, int& size); diff --git a/gtests/Spv.FromFile.cpp b/gtests/Spv.FromFile.cpp index 9a44fa42f32d746b50cbb9b6fe596768176a6cf3..da80b1168896b07fdddb0776513753a9c8110531 100644 --- a/gtests/Spv.FromFile.cpp +++ b/gtests/Spv.FromFile.cpp @@ -329,6 +329,7 @@ INSTANTIATE_TEST_CASE_P( "spv.storageBuffer.vert", "spv.precise.tese", "spv.precise.tesc", + "spv.xfb.vert", })), FileNameAsCustomTestSuffix );