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/440.vert b/Test/440.vert
index 2e61f79757055e99f902c2a20a28c94ed732fa35..4ab6f2ee21ecd6e1cdd0d507656482c93afb7bae 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 1d009d9ca8167e4f00aff74fb8f0444fa8734bf2..52ebebcedbedefce6951139182bc5cf3309e0674 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 8eafb0aea1d44f6ee26a7f6844759b721522ba2c..33738aaa596932582384346ae66b52fec306d66d 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 0000000000000000000000000000000000000000..f13dfe1b24b130cff5e161500508cb8a64c023d4
--- /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 10 XfbBuffer 1
+                              Decorate 10 XfbStride 64
+               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/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.builtInXFB.vert b/Test/spv.builtInXFB.vert
new file mode 100644
index 0000000000000000000000000000000000000000..619bc1e2fd00574f14a62484425a5ff0c62e6c1c
--- /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/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/Include/Types.h b/glslang/Include/Types.h
index d23b615312a04b9039f384ec40a87a2b4c671808..cc847b5e7f316293a5c5e9d90e42c588ba29d952 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 a24949795b803ac7a368967eef49db9eccbc6369..78a5d8ee6484082f7d423a6c3be8f0070a58be04 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,7 +3549,9 @@ 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.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 f19d85e9ec9d1100c0b592e9578a64aa62732d3d..da80b1168896b07fdddb0776513753a9c8110531 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",
@@ -328,6 +329,7 @@ INSTANTIATE_TEST_CASE_P(
         "spv.storageBuffer.vert",
         "spv.precise.tese",
         "spv.precise.tesc",
+        "spv.xfb.vert",
     })),
     FileNameAsCustomTestSuffix
 );