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",
})),