SPV: Plumb through XFB buffer and stride information.

Also, only emit this XFB information where the SPIR-V spec says
it should be emitted: essentially, on objects.

This and the previous commit together fix #1185.
diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
index 4ae5286..745021f 100755
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -2661,13 +2661,6 @@
         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 @@
             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 @@
         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 741030e..f13dfe1 100755
--- a/Test/baseResults/spv.builtInXFB.vert.out
+++ b/Test/baseResults/spv.builtInXFB.vert.out
@@ -20,8 +20,8 @@
                               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 0000000..f609826
--- /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 0000000..ad762bc
--- /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 80471c4..78a5d8e 100644
--- a/glslang/MachineIndependent/ParseHelper.cpp
+++ b/glslang/MachineIndependent/ParseHelper.cpp
@@ -3550,7 +3550,8 @@
             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 8665176..4d48c68 100644
--- a/glslang/MachineIndependent/localintermediate.h
+++ b/glslang/MachineIndependent/localintermediate.h
@@ -583,6 +583,7 @@
         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 9a44fa4..da80b11 100644
--- a/gtests/Spv.FromFile.cpp
+++ b/gtests/Spv.FromFile.cpp
@@ -329,6 +329,7 @@
         "spv.storageBuffer.vert",
         "spv.precise.tese",
         "spv.precise.tesc",
+        "spv.xfb.vert",
     })),
     FileNameAsCustomTestSuffix
 );