SPV: Support test #pragma for generating the StorageBuffer storage class.

Longer term, this storage class should be generated based on the mode
of compilation.
diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp
index 4a16f6a..9e5676d 100755
--- a/SPIRV/GlslangToSpv.cpp
+++ b/SPIRV/GlslangToSpv.cpp
@@ -245,7 +245,7 @@
 }
 
 // Translate glslang type to SPIR-V storage class.
-spv::StorageClass TranslateStorageClass(const glslang::TType& type)
+spv::StorageClass TranslateStorageClass(const glslang::TType& type, bool useStorageBuffer)
 {
     if (type.getQualifier().isPipeInput())
         return spv::StorageClassInput;
@@ -255,6 +255,8 @@
         return spv::StorageClassAtomicCounter;
     else if (type.containsOpaque())
         return spv::StorageClassUniformConstant;
+    else if (useStorageBuffer && type.getQualifier().storage == glslang::EvqBuffer)
+        return spv::StorageClassStorageBuffer;
     else if (type.getQualifier().isUniformOrBuffer()) {
         if (type.getQualifier().layoutPushConstant)
             return spv::StorageClassPushConstant;
@@ -310,12 +312,12 @@
 }
 
 // Translate glslang type to SPIR-V block decorations.
-spv::Decoration TranslateBlockDecoration(const glslang::TType& type)
+spv::Decoration TranslateBlockDecoration(const glslang::TType& type, bool useStorageBuffer)
 {
     if (type.getBasicType() == glslang::EbtBlock) {
         switch (type.getQualifier().storage) {
         case glslang::EvqUniform:      return spv::DecorationBlock;
-        case glslang::EvqBuffer:       return spv::DecorationBufferBlock;
+        case glslang::EvqBuffer:       return useStorageBuffer ? spv::DecorationBlock : spv::DecorationBufferBlock;
         case glslang::EvqVaryingIn:    return spv::DecorationBlock;
         case glslang::EvqVaryingOut:   return spv::DecorationBlock;
         default:
@@ -2071,7 +2073,7 @@
     }
 
     // Now, handle actual variables
-    spv::StorageClass storageClass = TranslateStorageClass(node->getType());
+    spv::StorageClass storageClass = TranslateStorageClass(node->getType(), glslangIntermediate->usingStorageBuffer());
     spv::Id spvType = convertGlslangToSpvType(node->getType());
 
 #ifdef AMD_EXTENSIONS
@@ -2491,7 +2493,7 @@
 
     // Decorate the structure
     addDecoration(spvType, TranslateLayoutDecoration(type, qualifier.layoutMatrix));
-    addDecoration(spvType, TranslateBlockDecoration(type));
+    addDecoration(spvType, TranslateBlockDecoration(type, glslangIntermediate->usingStorageBuffer()));
     if (type.getQualifier().hasStream() && glslangIntermediate->isMultiStream()) {
         builder.addCapability(spv::CapabilityGeometryStreams);
         builder.addDecoration(spvType, spv::DecorationStream, type.getQualifier().layoutStream);
@@ -2834,7 +2836,7 @@
                 (paramType.getBasicType() == glslang::EbtBlock &&
                  paramType.getQualifier().storage == glslang::EvqBuffer) ||  // SSBO
                 (p == 0 && implicitThis))                                    // implicit 'this'
-                typeId = builder.makePointer(TranslateStorageClass(paramType), typeId);
+                typeId = builder.makePointer(TranslateStorageClass(paramType, glslangIntermediate->usingStorageBuffer()), typeId);
             else if (paramType.getQualifier().storage != glslang::EvqConstReadOnly)
                 typeId = builder.makePointer(spv::StorageClassFunction, typeId);
             else
diff --git a/SPIRV/doc.cpp b/SPIRV/doc.cpp
index b844584..49b734b 100755
--- a/SPIRV/doc.cpp
+++ b/SPIRV/doc.cpp
@@ -180,7 +180,7 @@
     }
 }
 
-const int StorageClassCeiling = 12;
+const int StorageClassCeiling = 13;
 
 const char* StorageClassString(int StorageClass)
 {
@@ -197,6 +197,7 @@
     case 9:  return "PushConstant";
     case 10: return "AtomicCounter";
     case 11: return "Image";
+    case 12: return "StorageBuffer";
 
     case StorageClassCeiling:
     default: return "Bad";
diff --git a/Test/baseResults/spv.storageBuffer.vert.out b/Test/baseResults/spv.storageBuffer.vert.out
new file mode 100755
index 0000000..2bf4549
--- /dev/null
+++ b/Test/baseResults/spv.storageBuffer.vert.out
@@ -0,0 +1,68 @@
+spv.storageBuffer.vert
+Warning, version 450 is not yet complete; most version-specific features are present, but some are missing.
+
+// Module Version 10000
+// Generated by (magic number): 80001
+// Id's are bound by 31
+
+                              Capability Shader
+               1:             ExtInstImport  "GLSL.std.450"
+                              MemoryModel Logical GLSL450
+                              EntryPoint Vertex 4  "main" 13
+                              Source GLSL 450
+                              Name 4  "main"
+                              Name 11  "gl_PerVertex"
+                              MemberName 11(gl_PerVertex) 0  "gl_Position"
+                              MemberName 11(gl_PerVertex) 1  "gl_PointSize"
+                              MemberName 11(gl_PerVertex) 2  "gl_ClipDistance"
+                              MemberName 11(gl_PerVertex) 3  "gl_CullDistance"
+                              Name 13  ""
+                              Name 16  "ub"
+                              MemberName 16(ub) 0  "a"
+                              Name 18  "ubi"
+                              Name 22  "bb"
+                              MemberName 22(bb) 0  "b"
+                              Name 24  "bbi"
+                              MemberDecorate 11(gl_PerVertex) 0 BuiltIn Position
+                              MemberDecorate 11(gl_PerVertex) 1 BuiltIn PointSize
+                              MemberDecorate 11(gl_PerVertex) 2 BuiltIn ClipDistance
+                              MemberDecorate 11(gl_PerVertex) 3 BuiltIn CullDistance
+                              Decorate 11(gl_PerVertex) Block
+                              MemberDecorate 16(ub) 0 Offset 0
+                              Decorate 16(ub) Block
+                              Decorate 18(ubi) DescriptorSet 0
+                              MemberDecorate 22(bb) 0 Offset 0
+                              Decorate 22(bb) Block
+                              Decorate 24(bbi) DescriptorSet 0
+               2:             TypeVoid
+               3:             TypeFunction 2
+               6:             TypeFloat 32
+               7:             TypeVector 6(float) 4
+               8:             TypeInt 32 0
+               9:      8(int) Constant 1
+              10:             TypeArray 6(float) 9
+11(gl_PerVertex):             TypeStruct 7(fvec4) 6(float) 10 10
+              12:             TypePointer Output 11(gl_PerVertex)
+              13:     12(ptr) Variable Output
+              14:             TypeInt 32 1
+              15:     14(int) Constant 0
+          16(ub):             TypeStruct 7(fvec4)
+              17:             TypePointer Uniform 16(ub)
+         18(ubi):     17(ptr) Variable Uniform
+              19:             TypePointer Uniform 7(fvec4)
+          22(bb):             TypeStruct 7(fvec4)
+              23:             TypePointer StorageBuffer 22(bb)
+         24(bbi):     23(ptr) Variable StorageBuffer
+              25:             TypePointer StorageBuffer 7(fvec4)
+              29:             TypePointer Output 7(fvec4)
+         4(main):           2 Function None 3
+               5:             Label
+              20:     19(ptr) AccessChain 18(ubi) 15
+              21:    7(fvec4) Load 20
+              26:     25(ptr) AccessChain 24(bbi) 15
+              27:    7(fvec4) Load 26
+              28:    7(fvec4) FAdd 21 27
+              30:     29(ptr) AccessChain 13 15
+                              Store 30 28
+                              Return
+                              FunctionEnd
diff --git a/Test/spv.storageBuffer.vert b/Test/spv.storageBuffer.vert
new file mode 100644
index 0000000..6dd629e
--- /dev/null
+++ b/Test/spv.storageBuffer.vert
@@ -0,0 +1,16 @@
+#version 450

+

+#pragma use_storage_buffer

+

+uniform ub {

+    vec4 a;

+} ubi;

+

+buffer bb {

+    vec4 b;

+} bbi;

+

+void main()

+{

+    gl_Position = ubi.a + bbi.b;

+}

diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp
index bc43986..b7240ea 100644
--- a/glslang/MachineIndependent/ParseHelper.cpp
+++ b/glslang/MachineIndependent/ParseHelper.cpp
@@ -255,6 +255,10 @@
             error(loc, "\")\" expected to end 'debug' pragma", "#pragma", "");
             return;
         }
+    } else if (spvVersion.spv > 0 && tokens[0].compare("use_storage_buffer") == 0) {
+        if (tokens.size() != 1)
+            error(loc, "extra tokens", "#pragma", "");
+        intermediate.setUseStorageBuffer();
     }
 }
 
diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h
index ece390e..0bd9d16 100644
--- a/glslang/MachineIndependent/localintermediate.h
+++ b/glslang/MachineIndependent/localintermediate.h
@@ -178,7 +178,8 @@
         autoMapBindings(false),
         flattenUniformArrays(false),
         useUnknownFormat(false),
-        hlslOffsets(false)
+        hlslOffsets(false),
+        useStorageBuffer(false)
     {
         localSize[0] = 1;
         localSize[1] = 1;
@@ -219,6 +220,8 @@
     bool getNoStorageFormat()             const { return useUnknownFormat; }
     void setHlslOffsets()         { hlslOffsets = true; }
     bool usingHlslOFfsets() const { return hlslOffsets; }
+    void setUseStorageBuffer() { useStorageBuffer = true; }
+    bool usingStorageBuffer() const { return useStorageBuffer; }
 
     void setVersion(int v) { version = v; }
     int getVersion() const { return version; }
@@ -506,6 +509,7 @@
     bool flattenUniformArrays;
     bool useUnknownFormat;
     bool hlslOffsets;
+    bool useStorageBuffer;
 
     typedef std::list<TCall> TGraph;
     TGraph callGraph;
diff --git a/gtests/Spv.FromFile.cpp b/gtests/Spv.FromFile.cpp
index a8d4b01..e05900b 100644
--- a/gtests/Spv.FromFile.cpp
+++ b/gtests/Spv.FromFile.cpp
@@ -303,6 +303,7 @@
         "spv.specConstant.comp",
         "spv.specConstantComposite.vert",
         "spv.specConstantOperations.vert",
+        "spv.storageBuffer.vert",
         "spv.precise.tese",
         "spv.precise.tesc",
     })),