SPV: Fix #807: use --hlsl-offsets to allow hlsl-style offsets in a buffer.

Corresponds to the EShMsgHlslOffsets flag in messages.
Works for both GLSL and HLSL.
diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
index 1e03909..aae3f49 100755
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -2728,7 +2728,23 @@
     int memberSize;
     int dummyStride;
     int memberAlignment = glslangIntermediate->getBaseAlignment(memberType, memberSize, dummyStride, explicitLayout == glslang::ElpStd140, matrixLayout == glslang::ElmRowMajor);
+
+    // Adjust alignment for HLSL rules
+    if (glslangIntermediate->usingHlslOFfsets() &&
+        ! memberType.isArray() && memberType.isVector()) {
+        int dummySize;
+        int componentAlignment = glslangIntermediate->getBaseAlignmentScalar(memberType, dummySize);
+        if (componentAlignment <= 4)
+            memberAlignment = componentAlignment;
+    }
+
+    // Bump up to member alignment
     glslang::RoundToPow2(currentOffset, memberAlignment);
+
+    // Bump up to vec4 if there is a bad straddle
+    if (glslangIntermediate->improperStraddle(memberType, memberSize, currentOffset))
+        glslang::RoundToPow2(currentOffset, 16);
+
     nextOffset = currentOffset + memberSize;
 }
 
diff --git a/StandAlone/StandAlone.cpp b/StandAlone/StandAlone.cpp
index 56d6619..60dbc4d 100644
--- a/StandAlone/StandAlone.cpp
+++ b/StandAlone/StandAlone.cpp
@@ -86,6 +86,7 @@
     EOptionFlattenUniformArrays = (1 << 20),
     EOptionNoStorageFormat      = (1 << 21),
     EOptionKeepUncalled         = (1 << 22),
+    EOptionHlslOffsets          = (1 << 23),
 };
 
 //
@@ -311,8 +312,7 @@
                         } else
                             Error("no <C-variable-name> provided for --variable-name");
                         break;
-                    }
-                    else if (lowerword == "source-entrypoint" || // synonyms
+                    } else if (lowerword == "source-entrypoint" || // synonyms
                                lowerword == "sep") {
                         sourceEntryPointName = argv[1];
                         if (argc > 0) {
@@ -324,6 +324,8 @@
                     } else if (lowerword == "keep-uncalled" || // synonyms
                                lowerword == "ku") {
                         Options |= EOptionKeepUncalled;
+                    } else if (lowerword == "hlsl-offsets") {
+                        Options |= EOptionHlslOffsets;
                     } else {
                         usage();
                     }
@@ -471,6 +473,8 @@
         messages = (EShMessages)(messages | EShMsgCascadingErrors);
     if (Options & EOptionKeepUncalled)
         messages = (EShMessages)(messages | EShMsgKeepUncalled);
+    if (Options & EOptionHlslOffsets)
+        messages = (EShMessages)(messages | EShMsgHlslOffsets);
 }
 
 //
@@ -998,8 +1002,13 @@
            "\n"
            "  --keep-uncalled                         don't eliminate uncalled functions when linking\n"
            "  --ku                                    synonym for --keep-uncalled\n"
-           "  --variable-name <name>                  Creates a C header file that contains a uint32_t array named <name> initialized with the shader binary code.\n"
-           "  --vn <name>                             synonym for --variable-name <name>.\n"
+           "\n"
+           "  --variable-name <name>                  Creates a C header file that contains a uint32_t array named <name>\n"
+           "                                          initialized with the shader binary code.\n"
+           "  --vn <name>                             synonym for --variable-name <name>\n"
+           "\n"
+           "  --hlsl-offsets                          Allow block offsets to follow HLSL rules instead of GLSL rules.\n"
+           "                                          Works independently of source language.\n"
            );
 
     exit(EFailUsage);
diff --git a/Test/baseResults/hlsl.hlslOffset.vert.out b/Test/baseResults/hlsl.hlslOffset.vert.out
new file mode 100644
index 0000000..380a086
--- /dev/null
+++ b/Test/baseResults/hlsl.hlslOffset.vert.out
@@ -0,0 +1,84 @@
+hlsl.hlslOffset.vert
+Shader version: 450
+0:? Sequence
+0:20  Function Definition: @main( ( temp void)
+0:20    Function Parameters: 
+0:20  Function Definition: main( ( temp void)
+0:20    Function Parameters: 
+0:?     Sequence
+0:20      Function Call: @main( ( temp void)
+0:?   Linker Objects
+0:?     'anon@0' (layout( row_major std140) uniform block{layout( row_major std140) uniform float m0, layout( row_major std140) uniform 3-component vector of float m4, layout( row_major std140) uniform float m16, layout( row_major std140 offset=20) uniform 3-component vector of float m20, layout( row_major std140 offset=36) uniform 3-component vector of float m36, layout( row_major std140 offset=56) uniform 2-component vector of float m56, layout( row_major std140) uniform float m64, layout( row_major std140) uniform 2-component vector of float m68, layout( row_major std140) uniform float m76, layout( row_major std140) uniform float m80, layout( row_major std140) uniform 1-element array of 2-component vector of float m96})
+
+
+Linked vertex stage:
+
+
+Shader version: 450
+0:? Sequence
+0:20  Function Definition: @main( ( temp void)
+0:20    Function Parameters: 
+0:20  Function Definition: main( ( temp void)
+0:20    Function Parameters: 
+0:?     Sequence
+0:20      Function Call: @main( ( temp void)
+0:?   Linker Objects
+0:?     'anon@0' (layout( row_major std140) uniform block{layout( row_major std140) uniform float m0, layout( row_major std140) uniform 3-component vector of float m4, layout( row_major std140) uniform float m16, layout( row_major std140 offset=20) uniform 3-component vector of float m20, layout( row_major std140 offset=36) uniform 3-component vector of float m36, layout( row_major std140 offset=56) uniform 2-component vector of float m56, layout( row_major std140) uniform float m64, layout( row_major std140) uniform 2-component vector of float m68, layout( row_major std140) uniform float m76, layout( row_major std140) uniform float m80, layout( row_major std140) uniform 1-element array of 2-component vector of float m96})
+
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 18
+
+                              Capability Shader
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint Vertex 4  "main"
+                              Name 4  "main"
+                              Name 6  "@main("
+                              Name 15  "b"
+                              MemberName 15(b) 0  "m0"
+                              MemberName 15(b) 1  "m4"
+                              MemberName 15(b) 2  "m16"
+                              MemberName 15(b) 3  "m20"
+                              MemberName 15(b) 4  "m36"
+                              MemberName 15(b) 5  "m56"
+                              MemberName 15(b) 6  "m64"
+                              MemberName 15(b) 7  "m68"
+                              MemberName 15(b) 8  "m76"
+                              MemberName 15(b) 9  "m80"
+                              MemberName 15(b) 10  "m96"
+                              Name 17  ""
+                              Decorate 14 ArrayStride 16
+                              MemberDecorate 15(b) 0 Offset 0
+                              MemberDecorate 15(b) 1 Offset 4
+                              MemberDecorate 15(b) 2 Offset 16
+                              MemberDecorate 15(b) 3 Offset 20
+                              MemberDecorate 15(b) 4 Offset 36
+                              MemberDecorate 15(b) 5 Offset 56
+                              MemberDecorate 15(b) 6 Offset 64
+                              MemberDecorate 15(b) 7 Offset 68
+                              MemberDecorate 15(b) 8 Offset 76
+                              MemberDecorate 15(b) 9 Offset 80
+                              MemberDecorate 15(b) 10 Offset 96
+                              Decorate 15(b) Block
+                              Decorate 17 DescriptorSet 0
+               2:             TypeVoid
+               3:             TypeFunction 2
+               9:             TypeFloat 32
+              10:             TypeVector 9(float) 3
+              11:             TypeVector 9(float) 2
+              12:             TypeInt 32 0
+              13:     12(int) Constant 1
+              14:             TypeArray 11(fvec2) 13
+           15(b):             TypeStruct 9(float) 10(fvec3) 9(float) 10(fvec3) 10(fvec3) 11(fvec2) 9(float) 11(fvec2) 9(float) 9(float) 14
+              16:             TypePointer Uniform 15(b)
+              17:     16(ptr) Variable Uniform
+         4(main):           2 Function None 3
+               5:             Label
+               8:           2 FunctionCall 6(@main()
+                              Return
+                              FunctionEnd
+       6(@main():           2 Function None 3
+               7:             Label
+                              Return
+                              FunctionEnd
diff --git a/Test/baseResults/spv.hlslOffsets.vert.out b/Test/baseResults/spv.hlslOffsets.vert.out
new file mode 100644
index 0000000..c1f6cb2
--- /dev/null
+++ b/Test/baseResults/spv.hlslOffsets.vert.out
@@ -0,0 +1,78 @@
+spv.hlslOffsets.vert
+Warning, version 450 is not yet complete; most version-specific features are present, but some are missing.
+
+Shader version: 450
+0:? Sequence
+0:27  Function Definition: main( ( global void)
+0:27    Function Parameters: 
+0:?   Linker Objects
+0:?     'anon@0' (layout( column_major std430) buffer block{layout( column_major std430) buffer highp float m0, layout( column_major std430) buffer highp 3-component vector of float m4, layout( column_major std430) buffer highp float m16, layout( column_major std430 offset=20) buffer highp 3-component vector of float m20, layout( column_major std430) buffer highp 3-component vector of float m32, layout( column_major std430) buffer highp 2-component vector of float m48, layout( column_major std430) buffer highp 2-component vector of float m56, layout( column_major std430) buffer highp float m64, layout( column_major std430) buffer highp 2-component vector of float m68, layout( column_major std430) buffer highp float m76, layout( column_major std430) buffer highp float m80, layout( column_major std430 offset=88) buffer highp 2-component vector of float m88, layout( column_major std430) buffer highp 2-component vector of float m96, layout( column_major std430) buffer 2-component vector of double m112})
+
+
+Linked vertex stage:
+
+
+Shader version: 450
+0:? Sequence
+0:27  Function Definition: main( ( global void)
+0:27    Function Parameters: 
+0:?   Linker Objects
+0:?     'anon@0' (layout( column_major std430) buffer block{layout( column_major std430) buffer highp float m0, layout( column_major std430) buffer highp 3-component vector of float m4, layout( column_major std430) buffer highp float m16, layout( column_major std430 offset=20) buffer highp 3-component vector of float m20, layout( column_major std430) buffer highp 3-component vector of float m32, layout( column_major std430) buffer highp 2-component vector of float m48, layout( column_major std430) buffer highp 2-component vector of float m56, layout( column_major std430) buffer highp float m64, layout( column_major std430) buffer highp 2-component vector of float m68, layout( column_major std430) buffer highp float m76, layout( column_major std430) buffer highp float m80, layout( column_major std430 offset=88) buffer highp 2-component vector of float m88, layout( column_major std430) buffer highp 2-component vector of float m96, layout( column_major std430) buffer 2-component vector of double m112})
+
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 14
+
+                              Capability Shader
+                              Capability Float64
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint Vertex 4  "main"
+                              Source GLSL 450
+                              Name 4  "main"
+                              Name 11  "block"
+                              MemberName 11(block) 0  "m0"
+                              MemberName 11(block) 1  "m4"
+                              MemberName 11(block) 2  "m16"
+                              MemberName 11(block) 3  "m20"
+                              MemberName 11(block) 4  "m32"
+                              MemberName 11(block) 5  "m48"
+                              MemberName 11(block) 6  "m56"
+                              MemberName 11(block) 7  "m64"
+                              MemberName 11(block) 8  "m68"
+                              MemberName 11(block) 9  "m76"
+                              MemberName 11(block) 10  "m80"
+                              MemberName 11(block) 11  "m88"
+                              MemberName 11(block) 12  "m96"
+                              MemberName 11(block) 13  "m112"
+                              Name 13  ""
+                              MemberDecorate 11(block) 0 Offset 0
+                              MemberDecorate 11(block) 1 Offset 4
+                              MemberDecorate 11(block) 2 Offset 16
+                              MemberDecorate 11(block) 3 Offset 20
+                              MemberDecorate 11(block) 4 Offset 32
+                              MemberDecorate 11(block) 5 Offset 48
+                              MemberDecorate 11(block) 6 Offset 56
+                              MemberDecorate 11(block) 7 Offset 64
+                              MemberDecorate 11(block) 8 Offset 68
+                              MemberDecorate 11(block) 9 Offset 76
+                              MemberDecorate 11(block) 10 Offset 80
+                              MemberDecorate 11(block) 11 Offset 88
+                              MemberDecorate 11(block) 12 Offset 96
+                              MemberDecorate 11(block) 13 Offset 112
+                              Decorate 11(block) BufferBlock
+                              Decorate 13 DescriptorSet 0
+               2:             TypeVoid
+               3:             TypeFunction 2
+               6:             TypeFloat 32
+               7:             TypeVector 6(float) 3
+               8:             TypeVector 6(float) 2
+               9:             TypeFloat 64
+              10:             TypeVector 9(float) 2
+       11(block):             TypeStruct 6(float) 7(fvec3) 6(float) 7(fvec3) 7(fvec3) 8(fvec2) 8(fvec2) 6(float) 8(fvec2) 6(float) 6(float) 8(fvec2) 8(fvec2) 10(fvec2)
+              12:             TypePointer Uniform 11(block)
+              13:     12(ptr) Variable Uniform
+         4(main):           2 Function None 3
+               5:             Label
+                              Return
+                              FunctionEnd
diff --git a/Test/hlsl.hlslOffset.vert b/Test/hlsl.hlslOffset.vert
new file mode 100755
index 0000000..aa95f6a
--- /dev/null
+++ b/Test/hlsl.hlslOffset.vert
@@ -0,0 +1,20 @@
+cbuffer b {

+    float m0;

+    float3 m4;

+    //////

+    float m16;

+    float3 m20 : packoffset(c1.y);

+    /////

+    float3 m36 : packoffset(c2.y);

+    /////

+    float2 m56 : packoffset(c3.z);

+    /////

+    float m64;

+    float2 m68;

+    float m76;

+    //////

+    float m80;

+    float2 m96[1];

+};

+

+void main() {}

diff --git a/Test/runtests b/Test/runtests
index 86ffef3..efc449d 100755
--- a/Test/runtests
+++ b/Test/runtests
@@ -73,6 +73,20 @@
 $EXE -i -S vert nosuffix > $TARGETDIR/nosuffix.out
 diff -b $BASEDIR/nosuffix.out $TARGETDIR/nosuffix.out || HASERROR=1
 
+#
+# Testing --hlsl-offsets
+#
+echo Running hlsl offsets
+$EXE -i --hlsl-offsets -H spv.hlslOffsets.vert > $TARGETDIR/spv.hlslOffsets.vert.out
+diff -b $BASEDIR/spv.hlslOffsets.vert.out $TARGETDIR/spv.hlslOffsets.vert.out || HASERROR=1
+
+echo Running hlsl offsets
+$EXE -i  --hlsl-offsets -D -e main -H hlsl.hlslOffset.vert > $TARGETDIR/hlsl.hlslOffset.vert.out
+diff -b $BASEDIR/hlsl.hlslOffset.vert.out $TARGETDIR/hlsl.hlslOffset.vert.out || HASERROR=1
+
+#
+# Final checking
+#
 if [ $HASERROR -eq 0 ]
 then
     echo Tests Succeeded.
diff --git a/Test/spv.hlslOffsets.vert b/Test/spv.hlslOffsets.vert
new file mode 100755
index 0000000..87e32a7
--- /dev/null
+++ b/Test/spv.hlslOffsets.vert
@@ -0,0 +1,27 @@
+#version 450

+

+buffer block {

+    float m0;

+    vec3 m4;

+    //////

+    float m16;

+    layout(offset=20) vec3 m20;

+    /////

+    vec3 m32;

+    /////

+    vec2 m48;

+    vec2 m56;

+    ////

+    float m64;

+    vec2 m68;

+    float m76;

+    //////

+    float m80;

+    layout(offset=88) vec2 m88;

+    //////

+    vec2 m96;

+    ///////

+    dvec2 m112;

+};

+

+void main() {}
\ No newline at end of file
diff --git a/glslang/Include/revision.h b/glslang/Include/revision.h
index 2704df3..8632bea 100644
--- a/glslang/Include/revision.h
+++ b/glslang/Include/revision.h
@@ -2,5 +2,5 @@
 // For the version, it uses the latest git tag followed by the number of commits.
 // For the date, it uses the current date (when then script is run).
 
-#define GLSLANG_REVISION "Overload400-PrecQual.1974"
-#define GLSLANG_DATE "04-Apr-2017"
+#define GLSLANG_REVISION "Overload400-PrecQual.1978"
+#define GLSLANG_DATE "05-Apr-2017"
diff --git a/glslang/MachineIndependent/ShaderLang.cpp b/glslang/MachineIndependent/ShaderLang.cpp
index 5a8f679..f7596d9 100644
--- a/glslang/MachineIndependent/ShaderLang.cpp
+++ b/glslang/MachineIndependent/ShaderLang.cpp
@@ -726,6 +726,8 @@
     intermediate.setSpv(spvVersion);
     if (spvVersion.vulkan >= 100)
         intermediate.setOriginUpperLeft();
+    if (messages & EShMsgHlslOffsets) // source-language independent
+        intermediate.setHlslOffsets();
     SetupBuiltinSymbolTable(version, profile, spvVersion, source);
 
     TSymbolTable* cachedTable = SharedSymbolTables[MapVersionToIndex(version)]
diff --git a/glslang/MachineIndependent/linkValidate.cpp b/glslang/MachineIndependent/linkValidate.cpp
index 0328009..4bb2951 100644
--- a/glslang/MachineIndependent/linkValidate.cpp
+++ b/glslang/MachineIndependent/linkValidate.cpp
@@ -1047,9 +1047,9 @@
 
 const int baseAlignmentVec4Std140 = 16;
 
-// Return the size and alignment of a scalar.
+// Return the size and alignment of a component of the given type.
 // The size is returned in the 'size' parameter
-// Return value is the alignment of the type.
+// Return value is the alignment..
 int TIntermediate::getBaseAlignmentScalar(const TType& type, int& size)
 {
     switch (type.getBasicType()) {
@@ -1219,4 +1219,14 @@
     return baseAlignmentVec4Std140;
 }
 
+// To aid the basic HLSL rule about crossing vec4 boundaries.
+bool TIntermediate::improperStraddle(const TType& type, int size, int offset)
+{
+    if (! type.isVector() || type.isArray())
+        return false;
+
+    return size <= 16 ? offset / 16 != (offset + size - 1) / 16
+                      : offset % 16 != 0;
+}
+
 } // end namespace glslang
diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h
index 5460dd5..2cd912b 100644
--- a/glslang/MachineIndependent/localintermediate.h
+++ b/glslang/MachineIndependent/localintermediate.h
@@ -177,7 +177,8 @@
         shiftSsboBinding(0),
         autoMapBindings(false),
         flattenUniformArrays(false),
-        useUnknownFormat(false)
+        useUnknownFormat(false),
+        hlslOffsets(false)
     {
         localSize[0] = 1;
         localSize[1] = 1;
@@ -216,6 +217,8 @@
     bool getFlattenUniformArrays()        const { return flattenUniformArrays; }
     void setNoStorageFormat(bool b)             { useUnknownFormat = b; }
     bool getNoStorageFormat()             const { return useUnknownFormat; }
+    void setHlslOffsets()         { hlslOffsets = true; }
+    bool usingHlslOFfsets() const { return hlslOffsets; }
 
     void setVersion(int v) { version = v; }
     int getVersion() const { return version; }
@@ -413,7 +416,9 @@
     }
     int addXfbBufferOffset(const TType&);
     unsigned int computeTypeXfbSize(const TType&, bool& containsDouble) const;
+    static int getBaseAlignmentScalar(const TType&, int& size);
     static int getBaseAlignment(const TType&, int& size, int& stride, bool std140, bool rowMajor);
+    static bool improperStraddle(const TType& type, int size, int offset);
     bool promote(TIntermOperator*);
 
 #ifdef NV_EXTENSIONS
@@ -443,7 +448,6 @@
     void inOutLocationCheck(TInfoSink&);
     TIntermSequence& findLinkerObjects() const;
     bool userOutputUsed() const;
-    static int getBaseAlignmentScalar(const TType&, int& size);
     bool isSpecializationOperation(const TIntermOperator&) const;
     bool promoteUnary(TIntermUnary&);
     bool promoteBinary(TIntermBinary&);
@@ -499,6 +503,7 @@
     bool autoMapBindings;
     bool flattenUniformArrays;
     bool useUnknownFormat;
+    bool hlslOffsets;
 
     typedef std::list<TCall> TGraph;
     TGraph callGraph;
diff --git a/glslang/Public/ShaderLang.h b/glslang/Public/ShaderLang.h
index 8d8abd7..ace20cb 100644
--- a/glslang/Public/ShaderLang.h
+++ b/glslang/Public/ShaderLang.h
@@ -147,6 +147,7 @@
     EShMsgReadHlsl         = (1 << 6),  // use HLSL parsing rules and semantics
     EShMsgCascadingErrors  = (1 << 7),  // get cascading errors; risks error-recovery issues, instead of an early exit
     EShMsgKeepUncalled     = (1 << 8),  // for testing, don't eliminate uncalled functions
+    EShMsgHlslOffsets      = (1 << 9),  // allow block offsets to follow HLSL rules instead of GLSL rules
 };
 
 //