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

Longer term, this storage class should be generated based on the mode
of compilation.
This commit is contained in:
John Kessenich 2017-04-19 18:34:49 -06:00
parent a8d3db6b32
commit 670271890d
7 changed files with 104 additions and 8 deletions

View File

@ -245,7 +245,7 @@ spv::ExecutionModel TranslateExecutionModel(EShLanguage stage)
}
// 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 @@ spv::StorageClass TranslateStorageClass(const glslang::TType& type)
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 @@ spv::Decoration TranslatePrecisionDecoration(const glslang::TType& type)
}
// 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 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol*
}
// 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 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type,
// 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 @@ void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslF
(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

View File

@ -180,7 +180,7 @@ const char* ExecutionModeString(int mode)
}
}
const int StorageClassCeiling = 12;
const int StorageClassCeiling = 13;
const char* StorageClassString(int StorageClass)
{
@ -197,6 +197,7 @@ const char* StorageClassString(int StorageClass)
case 9: return "PushConstant";
case 10: return "AtomicCounter";
case 11: return "Image";
case 12: return "StorageBuffer";
case StorageClassCeiling:
default: return "Bad";

View File

@ -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

View File

@ -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;
}

View File

@ -255,6 +255,10 @@ void TParseContext::handlePragma(const TSourceLoc& loc, const TVector<TString>&
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();
}
}

View File

@ -178,7 +178,8 @@ public:
autoMapBindings(false),
flattenUniformArrays(false),
useUnknownFormat(false),
hlslOffsets(false)
hlslOffsets(false),
useStorageBuffer(false)
{
localSize[0] = 1;
localSize[1] = 1;
@ -219,6 +220,8 @@ public:
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 @@ protected:
bool flattenUniformArrays;
bool useUnknownFormat;
bool hlslOffsets;
bool useStorageBuffer;
typedef std::list<TCall> TGraph;
TGraph callGraph;

View File

@ -303,6 +303,7 @@ INSTANTIATE_TEST_CASE_P(
"spv.specConstant.comp",
"spv.specConstantComposite.vert",
"spv.specConstantOperations.vert",
"spv.storageBuffer.vert",
"spv.precise.tese",
"spv.precise.tesc",
})),