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:
parent
a8d3db6b32
commit
670271890d
@ -245,7 +245,7 @@ spv::ExecutionModel TranslateExecutionModel(EShLanguage stage)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Translate glslang type to SPIR-V storage class.
|
// 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())
|
if (type.getQualifier().isPipeInput())
|
||||||
return spv::StorageClassInput;
|
return spv::StorageClassInput;
|
||||||
@ -255,6 +255,8 @@ spv::StorageClass TranslateStorageClass(const glslang::TType& type)
|
|||||||
return spv::StorageClassAtomicCounter;
|
return spv::StorageClassAtomicCounter;
|
||||||
else if (type.containsOpaque())
|
else if (type.containsOpaque())
|
||||||
return spv::StorageClassUniformConstant;
|
return spv::StorageClassUniformConstant;
|
||||||
|
else if (useStorageBuffer && type.getQualifier().storage == glslang::EvqBuffer)
|
||||||
|
return spv::StorageClassStorageBuffer;
|
||||||
else if (type.getQualifier().isUniformOrBuffer()) {
|
else if (type.getQualifier().isUniformOrBuffer()) {
|
||||||
if (type.getQualifier().layoutPushConstant)
|
if (type.getQualifier().layoutPushConstant)
|
||||||
return spv::StorageClassPushConstant;
|
return spv::StorageClassPushConstant;
|
||||||
@ -310,12 +312,12 @@ spv::Decoration TranslatePrecisionDecoration(const glslang::TType& type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Translate glslang type to SPIR-V block decorations.
|
// 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) {
|
if (type.getBasicType() == glslang::EbtBlock) {
|
||||||
switch (type.getQualifier().storage) {
|
switch (type.getQualifier().storage) {
|
||||||
case glslang::EvqUniform: return spv::DecorationBlock;
|
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::EvqVaryingIn: return spv::DecorationBlock;
|
||||||
case glslang::EvqVaryingOut: return spv::DecorationBlock;
|
case glslang::EvqVaryingOut: return spv::DecorationBlock;
|
||||||
default:
|
default:
|
||||||
@ -2071,7 +2073,7 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol*
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Now, handle actual variables
|
// Now, handle actual variables
|
||||||
spv::StorageClass storageClass = TranslateStorageClass(node->getType());
|
spv::StorageClass storageClass = TranslateStorageClass(node->getType(), glslangIntermediate->usingStorageBuffer());
|
||||||
spv::Id spvType = convertGlslangToSpvType(node->getType());
|
spv::Id spvType = convertGlslangToSpvType(node->getType());
|
||||||
|
|
||||||
#ifdef AMD_EXTENSIONS
|
#ifdef AMD_EXTENSIONS
|
||||||
@ -2491,7 +2493,7 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type,
|
|||||||
|
|
||||||
// Decorate the structure
|
// Decorate the structure
|
||||||
addDecoration(spvType, TranslateLayoutDecoration(type, qualifier.layoutMatrix));
|
addDecoration(spvType, TranslateLayoutDecoration(type, qualifier.layoutMatrix));
|
||||||
addDecoration(spvType, TranslateBlockDecoration(type));
|
addDecoration(spvType, TranslateBlockDecoration(type, glslangIntermediate->usingStorageBuffer()));
|
||||||
if (type.getQualifier().hasStream() && glslangIntermediate->isMultiStream()) {
|
if (type.getQualifier().hasStream() && glslangIntermediate->isMultiStream()) {
|
||||||
builder.addCapability(spv::CapabilityGeometryStreams);
|
builder.addCapability(spv::CapabilityGeometryStreams);
|
||||||
builder.addDecoration(spvType, spv::DecorationStream, type.getQualifier().layoutStream);
|
builder.addDecoration(spvType, spv::DecorationStream, type.getQualifier().layoutStream);
|
||||||
@ -2834,7 +2836,7 @@ void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslF
|
|||||||
(paramType.getBasicType() == glslang::EbtBlock &&
|
(paramType.getBasicType() == glslang::EbtBlock &&
|
||||||
paramType.getQualifier().storage == glslang::EvqBuffer) || // SSBO
|
paramType.getQualifier().storage == glslang::EvqBuffer) || // SSBO
|
||||||
(p == 0 && implicitThis)) // implicit 'this'
|
(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)
|
else if (paramType.getQualifier().storage != glslang::EvqConstReadOnly)
|
||||||
typeId = builder.makePointer(spv::StorageClassFunction, typeId);
|
typeId = builder.makePointer(spv::StorageClassFunction, typeId);
|
||||||
else
|
else
|
||||||
|
@ -180,7 +180,7 @@ const char* ExecutionModeString(int mode)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const int StorageClassCeiling = 12;
|
const int StorageClassCeiling = 13;
|
||||||
|
|
||||||
const char* StorageClassString(int StorageClass)
|
const char* StorageClassString(int StorageClass)
|
||||||
{
|
{
|
||||||
@ -197,6 +197,7 @@ const char* StorageClassString(int StorageClass)
|
|||||||
case 9: return "PushConstant";
|
case 9: return "PushConstant";
|
||||||
case 10: return "AtomicCounter";
|
case 10: return "AtomicCounter";
|
||||||
case 11: return "Image";
|
case 11: return "Image";
|
||||||
|
case 12: return "StorageBuffer";
|
||||||
|
|
||||||
case StorageClassCeiling:
|
case StorageClassCeiling:
|
||||||
default: return "Bad";
|
default: return "Bad";
|
||||||
|
68
Test/baseResults/spv.storageBuffer.vert.out
Executable file
68
Test/baseResults/spv.storageBuffer.vert.out
Executable 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
|
16
Test/spv.storageBuffer.vert
Normal file
16
Test/spv.storageBuffer.vert
Normal 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;
|
||||||
|
}
|
@ -255,6 +255,10 @@ void TParseContext::handlePragma(const TSourceLoc& loc, const TVector<TString>&
|
|||||||
error(loc, "\")\" expected to end 'debug' pragma", "#pragma", "");
|
error(loc, "\")\" expected to end 'debug' pragma", "#pragma", "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
} else if (spvVersion.spv > 0 && tokens[0].compare("use_storage_buffer") == 0) {
|
||||||
|
if (tokens.size() != 1)
|
||||||
|
error(loc, "extra tokens", "#pragma", "");
|
||||||
|
intermediate.setUseStorageBuffer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,7 +178,8 @@ public:
|
|||||||
autoMapBindings(false),
|
autoMapBindings(false),
|
||||||
flattenUniformArrays(false),
|
flattenUniformArrays(false),
|
||||||
useUnknownFormat(false),
|
useUnknownFormat(false),
|
||||||
hlslOffsets(false)
|
hlslOffsets(false),
|
||||||
|
useStorageBuffer(false)
|
||||||
{
|
{
|
||||||
localSize[0] = 1;
|
localSize[0] = 1;
|
||||||
localSize[1] = 1;
|
localSize[1] = 1;
|
||||||
@ -219,6 +220,8 @@ public:
|
|||||||
bool getNoStorageFormat() const { return useUnknownFormat; }
|
bool getNoStorageFormat() const { return useUnknownFormat; }
|
||||||
void setHlslOffsets() { hlslOffsets = true; }
|
void setHlslOffsets() { hlslOffsets = true; }
|
||||||
bool usingHlslOFfsets() const { return hlslOffsets; }
|
bool usingHlslOFfsets() const { return hlslOffsets; }
|
||||||
|
void setUseStorageBuffer() { useStorageBuffer = true; }
|
||||||
|
bool usingStorageBuffer() const { return useStorageBuffer; }
|
||||||
|
|
||||||
void setVersion(int v) { version = v; }
|
void setVersion(int v) { version = v; }
|
||||||
int getVersion() const { return version; }
|
int getVersion() const { return version; }
|
||||||
@ -506,6 +509,7 @@ protected:
|
|||||||
bool flattenUniformArrays;
|
bool flattenUniformArrays;
|
||||||
bool useUnknownFormat;
|
bool useUnknownFormat;
|
||||||
bool hlslOffsets;
|
bool hlslOffsets;
|
||||||
|
bool useStorageBuffer;
|
||||||
|
|
||||||
typedef std::list<TCall> TGraph;
|
typedef std::list<TCall> TGraph;
|
||||||
TGraph callGraph;
|
TGraph callGraph;
|
||||||
|
@ -303,6 +303,7 @@ INSTANTIATE_TEST_CASE_P(
|
|||||||
"spv.specConstant.comp",
|
"spv.specConstant.comp",
|
||||||
"spv.specConstantComposite.vert",
|
"spv.specConstantComposite.vert",
|
||||||
"spv.specConstantOperations.vert",
|
"spv.specConstantOperations.vert",
|
||||||
|
"spv.storageBuffer.vert",
|
||||||
"spv.precise.tese",
|
"spv.precise.tese",
|
||||||
"spv.precise.tesc",
|
"spv.precise.tesc",
|
||||||
})),
|
})),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user