Add reflection queries for thread local size and ssbo auto-binding

New command line option --shift-ssbo-binding mirrors --shift-ubo-binding, etc.

New reflection query getLocalSize(int dim) queries local size, e.g, CS threads.
This commit is contained in:
steve-lunarg 2017-02-21 17:19:08 -07:00
parent 5da1f038d8
commit 932bb5cc4e
11 changed files with 265 additions and 15 deletions

View File

@ -169,6 +169,7 @@ std::array<unsigned int, EShLangCount> baseSamplerBinding;
std::array<unsigned int, EShLangCount> baseTextureBinding;
std::array<unsigned int, EShLangCount> baseImageBinding;
std::array<unsigned int, EShLangCount> baseUboBinding;
std::array<unsigned int, EShLangCount> baseSsboBinding;
//
// Create the default name for saving a binary if -o is not provided.
@ -258,6 +259,7 @@ void ProcessArguments(int argc, char* argv[])
baseTextureBinding.fill(0);
baseImageBinding.fill(0);
baseUboBinding.fill(0);
baseSsboBinding.fill(0);
ExecutableName = argv[0];
NumWorkItems = argc; // will include some empties where the '-' options were, but it doesn't matter, they'll be 0
@ -292,6 +294,10 @@ void ProcessArguments(int argc, char* argv[])
lowerword == "shift-ubo-binding" ||
lowerword == "sub") {
ProcessBindingBase(argc, argv, baseUboBinding);
} else if (lowerword == "shift-ssbo-bindings" || // synonyms
lowerword == "shift-ssbo-binding" ||
lowerword == "sbb") {
ProcessBindingBase(argc, argv, baseSsboBinding);
} else if (lowerword == "auto-map-bindings" || // synonyms
lowerword == "auto-map-binding" ||
lowerword == "amb") {
@ -582,6 +588,7 @@ void CompileAndLinkShaderUnits(std::vector<ShaderCompUnit> compUnits)
shader->setShiftTextureBinding(baseTextureBinding[compUnit.stage]);
shader->setShiftImageBinding(baseImageBinding[compUnit.stage]);
shader->setShiftUboBinding(baseUboBinding[compUnit.stage]);
shader->setShiftSsboBinding(baseSsboBinding[compUnit.stage]);
shader->setFlattenUniformArrays((Options & EOptionFlattenUniformArrays) != 0);
shader->setNoStorageFormat((Options & EOptionNoStorageFormat) != 0);
@ -984,6 +991,9 @@ void usage()
" --shift-UBO-binding [stage] num set base binding number for UBOs\n"
" --sub [stage] num synonym for --shift-UBO-binding\n"
"\n"
" --shift-ssbo-binding [stage] num set base binding number for SSBOs\n"
" --sbb [stage] num synonym for --shift-ssbo-binding\n"
"\n"
" --auto-map-bindings automatically bind uniform variables without\n"
" explicit bindings.\n"
" --amb synonym for --auto-map-bindings\n"

View File

@ -0,0 +1,153 @@
spv.ssbo.autoassign.frag
// Module Version 10000
// Generated by (magic number): 80001
// Id's are bound by 95
Capability Shader
1: ExtInstImport "GLSL.std.450"
MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main" 88 91
ExecutionMode 4 OriginUpperLeft
Name 4 "main"
Name 11 "@main(vf4;"
Name 10 "pos"
Name 13 "vTmp"
Name 14 "BufType"
MemberName 14(BufType) 0 "va"
MemberName 14(BufType) 1 "vb"
Name 16 "SB0"
MemberName 16(SB0) 0 "SB0"
Name 18 ""
Name 26 "TestCB"
MemberName 26(TestCB) 0 "W"
MemberName 26(TestCB) 1 "H"
Name 28 ""
Name 55 "SB1"
MemberName 55(SB1) 0 "SB1"
Name 57 ""
Name 86 "pos"
Name 88 "pos"
Name 91 "@entryPointOutput"
Name 92 "param"
MemberDecorate 14(BufType) 0 NonWritable
MemberDecorate 14(BufType) 0 Offset 0
MemberDecorate 14(BufType) 1 NonWritable
MemberDecorate 14(BufType) 1 Offset 16
Decorate 15 ArrayStride 32
MemberDecorate 16(SB0) 0 NonWritable
MemberDecorate 16(SB0) 0 Offset 0
Decorate 16(SB0) BufferBlock
Decorate 18 DescriptorSet 0
Decorate 18 Binding 30
MemberDecorate 26(TestCB) 0 Offset 0
MemberDecorate 26(TestCB) 1 Offset 4
Decorate 26(TestCB) Block
Decorate 28 DescriptorSet 0
Decorate 28 Binding 15
Decorate 54 ArrayStride 32
MemberDecorate 55(SB1) 0 Offset 0
Decorate 55(SB1) BufferBlock
Decorate 57 DescriptorSet 0
Decorate 57 Binding 31
Decorate 88(pos) Location 0
Decorate 91(@entryPointOutput) Location 0
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
7: TypeVector 6(float) 4
8: TypePointer Function 7(fvec4)
9: TypeFunction 7(fvec4) 8(ptr)
14(BufType): TypeStruct 7(fvec4) 7(fvec4)
15: TypeRuntimeArray 14(BufType)
16(SB0): TypeStruct 15
17: TypePointer Uniform 16(SB0)
18: 17(ptr) Variable Uniform
19: TypeInt 32 1
20: 19(int) Constant 0
21: TypeInt 32 0
22: 21(int) Constant 1
23: TypePointer Function 6(float)
26(TestCB): TypeStruct 21(int) 21(int)
27: TypePointer Uniform 26(TestCB)
28: 27(ptr) Variable Uniform
29: TypePointer Uniform 21(int)
34: 21(int) Constant 0
38: TypePointer Uniform 7(fvec4)
50: 19(int) Constant 1
54: TypeRuntimeArray 14(BufType)
55(SB1): TypeStruct 54
56: TypePointer Uniform 55(SB1)
57: 56(ptr) Variable Uniform
87: TypePointer Input 7(fvec4)
88(pos): 87(ptr) Variable Input
90: TypePointer Output 7(fvec4)
91(@entryPointOutput): 90(ptr) Variable Output
4(main): 2 Function None 3
5: Label
86(pos): 8(ptr) Variable Function
92(param): 8(ptr) Variable Function
89: 7(fvec4) Load 88(pos)
Store 86(pos) 89
93: 7(fvec4) Load 86(pos)
Store 92(param) 93
94: 7(fvec4) FunctionCall 11(@main(vf4;) 92(param)
Store 91(@entryPointOutput) 94
Return
FunctionEnd
11(@main(vf4;): 7(fvec4) Function None 9
10(pos): 8(ptr) FunctionParameter
12: Label
13(vTmp): 8(ptr) Variable Function
24: 23(ptr) AccessChain 10(pos) 22
25: 6(float) Load 24
30: 29(ptr) AccessChain 28 20
31: 21(int) Load 30
32: 6(float) ConvertUToF 31
33: 6(float) FMul 25 32
35: 23(ptr) AccessChain 10(pos) 34
36: 6(float) Load 35
37: 6(float) FAdd 33 36
39: 38(ptr) AccessChain 18 20 37 20
40: 7(fvec4) Load 39
41: 23(ptr) AccessChain 10(pos) 22
42: 6(float) Load 41
43: 29(ptr) AccessChain 28 20
44: 21(int) Load 43
45: 6(float) ConvertUToF 44
46: 6(float) FMul 42 45
47: 23(ptr) AccessChain 10(pos) 34
48: 6(float) Load 47
49: 6(float) FAdd 46 48
51: 38(ptr) AccessChain 18 20 49 50
52: 7(fvec4) Load 51
53: 7(fvec4) FAdd 40 52
Store 13(vTmp) 53
58: 23(ptr) AccessChain 10(pos) 22
59: 6(float) Load 58
60: 29(ptr) AccessChain 28 20
61: 21(int) Load 60
62: 6(float) ConvertUToF 61
63: 6(float) FMul 59 62
64: 23(ptr) AccessChain 10(pos) 34
65: 6(float) Load 64
66: 6(float) FAdd 63 65
67: 38(ptr) AccessChain 57 20 66 20
68: 7(fvec4) Load 67
69: 23(ptr) AccessChain 10(pos) 22
70: 6(float) Load 69
71: 29(ptr) AccessChain 28 20
72: 21(int) Load 71
73: 6(float) ConvertUToF 72
74: 6(float) FMul 70 73
75: 23(ptr) AccessChain 10(pos) 34
76: 6(float) Load 75
77: 6(float) FAdd 74 76
78: 38(ptr) AccessChain 57 20 77 50
79: 7(fvec4) Load 78
80: 7(fvec4) FAdd 68 79
81: 7(fvec4) Load 13(vTmp)
82: 7(fvec4) FAdd 81 80
Store 13(vTmp) 82
83: 7(fvec4) Load 13(vTmp)
ReturnValue 83
FunctionEnd

View File

@ -0,0 +1,24 @@
cbuffer TestCB
{
uint W;
uint H;
};
struct BufType
{
float4 va;
float4 vb;
};
StructuredBuffer < BufType > SB0;
RWStructuredBuffer < BufType > SB1;
float4 main(float4 pos : POS) : SV_Target0
{
float4 vTmp = SB0[pos.y * W + pos.x].va + SB0[pos.y * W + pos.x].vb;
vTmp += SB1[pos.y * W + pos.x].va + SB1[pos.y * W + pos.x].vb;
return vTmp;
}

View File

@ -1557,6 +1557,7 @@ void TShader::setShiftSamplerBinding(unsigned int base) { intermediate->setShift
void TShader::setShiftTextureBinding(unsigned int base) { intermediate->setShiftTextureBinding(base); }
void TShader::setShiftImageBinding(unsigned int base) { intermediate->setShiftImageBinding(base); }
void TShader::setShiftUboBinding(unsigned int base) { intermediate->setShiftUboBinding(base); }
void TShader::setShiftSsboBinding(unsigned int base) { intermediate->setShiftSsboBinding(base); }
void TShader::setAutoMapBindings(bool map) { intermediate->setAutoMapBindings(map); }
void TShader::setFlattenUniformArrays(bool flatten) { intermediate->setFlattenUniformArrays(flatten); }
void TShader::setNoStorageFormat(bool useUnknownFormat) { intermediate->setNoStorageFormat(useUnknownFormat); }
@ -1784,6 +1785,7 @@ int TProgram::getAttributeType(int index) const { return reflection
const TType* TProgram::getAttributeTType(int index) const { return reflection->getAttribute(index).getType(); }
const TType* TProgram::getUniformTType(int index) const { return reflection->getUniform(index).getType(); }
const TType* TProgram::getUniformBlockTType(int index) const { return reflection->getUniformBlock(index).getType(); }
unsigned TProgram::getLocalSize(int dim) const { return reflection->getLocalSize(dim); }
void TProgram::dumpReflection() { reflection->dump(); }

View File

@ -122,7 +122,7 @@ public:
virtual void visitSymbol(TIntermSymbol* base)
{
if (base->getQualifier().storage == EvqUniform) {
if (base->getType().getQualifier().isUniformOrBuffer()) {
TVarEntryInfo ent = { base->getId(), base, !traverseAll };
TVarLiveMap::iterator at = std::lower_bound(varLiveList.begin(), varLiveList.end(), ent, TVarEntryInfo::TOrderById());
if (at != varLiveList.end() && at->id == ent.id)
@ -227,6 +227,7 @@ struct TDefaultIoResolver : public glslang::TIoMapResolver
int baseTextureBinding;
int baseImageBinding;
int baseUboBinding;
int baseSsboBinding;
bool doAutoMapping;
typedef std::vector<int> TSlotSet;
typedef std::unordered_map<int, TSlotSet> TSlotSetMap;
@ -281,8 +282,11 @@ struct TDefaultIoResolver : public glslang::TIoMapResolver
return checkEmpty(set, baseTextureBinding + type.getQualifier().layoutBinding);
}
if (type.getQualifier().isUniformOrBuffer())
if (type.getQualifier().storage == EvqUniform)
return checkEmpty(set, baseUboBinding + type.getQualifier().layoutBinding);
if (type.getQualifier().storage == EvqBuffer)
return checkEmpty(set, baseSsboBinding + type.getQualifier().layoutBinding);
}
return true;
}
@ -308,8 +312,11 @@ struct TDefaultIoResolver : public glslang::TIoMapResolver
return reserveSlot(set, baseTextureBinding + type.getQualifier().layoutBinding);
}
if (type.getQualifier().isUniformOrBuffer())
if (type.getQualifier().storage == EvqUniform)
return reserveSlot(set, baseUboBinding + type.getQualifier().layoutBinding);
if (type.getQualifier().storage == EvqBuffer)
return reserveSlot(set, baseSsboBinding + type.getQualifier().layoutBinding);
} else if (is_live && doAutoMapping) {
// find free slot, the caller did make sure it passes all vars with binding
// first and now all are passed that do not have a binding and needs one
@ -325,8 +332,11 @@ struct TDefaultIoResolver : public glslang::TIoMapResolver
return getFreeSlot(set, baseTextureBinding);
}
if (type.getQualifier().isUniformOrBuffer())
if (type.getQualifier().storage == EvqUniform)
return getFreeSlot(set, baseUboBinding);
if (type.getQualifier().storage == EvqBuffer)
return getFreeSlot(set, baseSsboBinding);
}
return -1;
@ -351,6 +361,7 @@ bool TIoMapper::addStage(EShLanguage stage, TIntermediate &intermediate, TInfoSi
intermediate.getShiftTextureBinding() == 0 &&
intermediate.getShiftImageBinding() == 0 &&
intermediate.getShiftUboBinding() == 0 &&
intermediate.getShiftSsboBinding() == 0 &&
intermediate.getAutoMapBindings() == false &&
resolver == nullptr)
return true;
@ -369,6 +380,7 @@ bool TIoMapper::addStage(EShLanguage stage, TIntermediate &intermediate, TInfoSi
defaultResolver.baseTextureBinding = intermediate.getShiftTextureBinding();
defaultResolver.baseImageBinding = intermediate.getShiftImageBinding();
defaultResolver.baseUboBinding = intermediate.getShiftUboBinding();
defaultResolver.baseSsboBinding = intermediate.getShiftSsboBinding();
defaultResolver.doAutoMapping = intermediate.getAutoMapBindings();
resolver = &defaultResolver;

View File

@ -174,6 +174,7 @@ public:
shiftTextureBinding(0),
shiftImageBinding(0),
shiftUboBinding(0),
shiftSsboBinding(0),
autoMapBindings(false),
flattenUniformArrays(false),
useUnknownFormat(false)
@ -207,6 +208,8 @@ public:
unsigned int getShiftImageBinding() const { return shiftImageBinding; }
void setShiftUboBinding(unsigned int shift) { shiftUboBinding = shift; }
unsigned int getShiftUboBinding() const { return shiftUboBinding; }
void setShiftSsboBinding(unsigned int shift) { shiftSsboBinding = shift; }
unsigned int getShiftSsboBinding() const { return shiftSsboBinding; }
void setAutoMapBindings(bool map) { autoMapBindings = map; }
bool getAutoMapBindings() const { return autoMapBindings; }
void setFlattenUniformArrays(bool flatten) { flattenUniformArrays = flatten; }
@ -485,6 +488,7 @@ protected:
unsigned int shiftTextureBinding;
unsigned int shiftImageBinding;
unsigned int shiftUboBinding;
unsigned int shiftSsboBinding;
bool autoMapBindings;
bool flattenUniformArrays;
bool useUnknownFormat;

View File

@ -696,14 +696,27 @@ void TReflectionTraverser::visitSymbol(TIntermSymbol* base)
// Implement TReflection methods.
//
// Track any required attribute reflection, such as compute shader numthreads.
//
void TReflection::buildAttributeReflection(EShLanguage stage, const TIntermediate& intermediate)
{
if (stage == EShLangCompute) {
// Remember thread dimensions
for (int dim=0; dim<3; ++dim)
localSize[dim] = intermediate.getLocalSize(dim);
}
}
// Merge live symbols from 'intermediate' into the existing reflection database.
//
// Returns false if the input is too malformed to do this.
bool TReflection::addStage(EShLanguage, const TIntermediate& intermediate)
bool TReflection::addStage(EShLanguage stage, const TIntermediate& intermediate)
{
if (intermediate.getNumEntryPoints() != 1 || intermediate.isRecursive())
return false;
buildAttributeReflection(stage, intermediate);
TReflectionTraverser it(intermediate, *this);
// put the entry point on the list of functions to process
@ -736,6 +749,16 @@ void TReflection::dump()
indexToAttribute[i].dump();
printf("\n");
if (getLocalSize(0) > 1) {
static const char* axis[] = { "X", "Y", "Z" };
for (int dim=0; dim<3; ++dim)
if (getLocalSize(dim) > 1)
printf("Local size %s: %d\n", axis[dim], getLocalSize(dim));
printf("\n");
}
// printf("Live names\n");
// for (TNameToIndex::const_iterator it = nameToIndex.begin(); it != nameToIndex.end(); ++it)
// printf("%s: %d\n", it->first.c_str(), it->second);

View File

@ -89,7 +89,12 @@ protected:
// The full reflection database
class TReflection {
public:
TReflection() : badReflection(TObjectReflection::badReflection()) { }
TReflection() : badReflection(TObjectReflection::badReflection())
{
for (int dim=0; dim<3; ++dim)
localSize[dim] = 0;
}
virtual ~TReflection() {}
// grow the reflection stage by stage
@ -135,11 +140,16 @@ public:
return it->second;
}
// Thread local size
unsigned getLocalSize(int dim) const { return dim <= 2 ? localSize[dim] : 0; }
void dump();
protected:
friend class glslang::TReflectionTraverser;
void buildAttributeReflection(EShLanguage, const TIntermediate&);
// Need a TString hash: typedef std::unordered_map<TString, int> TNameToIndex;
typedef std::map<TString, int> TNameToIndex;
typedef std::vector<TObjectReflection> TMapIndexToReflection;
@ -149,6 +159,8 @@ protected:
TMapIndexToReflection indexToUniform;
TMapIndexToReflection indexToUniformBlock;
TMapIndexToReflection indexToAttribute;
unsigned int localSize[3];
};
} // end namespace glslang

View File

@ -310,6 +310,7 @@ public:
void setShiftTextureBinding(unsigned int base);
void setShiftImageBinding(unsigned int base);
void setShiftUboBinding(unsigned int base);
void setShiftSsboBinding(unsigned int base);
void setAutoMapBindings(bool map);
void setFlattenUniformArrays(bool flatten);
void setNoStorageFormat(bool useUnknownFormat);
@ -514,6 +515,7 @@ public:
int getUniformBufferOffset(int index) const; // can be used for glGetActiveUniformsiv(GL_UNIFORM_OFFSET)
int getUniformArraySize(int index) const; // can be used for glGetActiveUniformsiv(GL_UNIFORM_SIZE)
int getNumLiveAttributes() const; // can be used for glGetProgramiv(GL_ACTIVE_ATTRIBUTES)
unsigned getLocalSize(int dim) const; // return dim'th local size
const char *getAttributeName(int index) const; // can be used for glGetActiveAttrib()
int getAttributeType(int index) const; // can be used for glGetActiveAttrib()
const TType* getUniformTType(int index) const; // returns a TType*

View File

@ -48,6 +48,7 @@ struct IoMapData {
int baseTextureBinding;
int baseImageBinding;
int baseUboBinding;
int baseSsboBinding;
bool autoMapBindings;
bool flattenUniforms;
};
@ -129,6 +130,7 @@ TEST_P(HlslIoMap, FromFile)
GetParam().baseTextureBinding,
GetParam().baseImageBinding,
GetParam().baseUboBinding,
GetParam().baseSsboBinding,
GetParam().autoMapBindings,
GetParam().flattenUniforms);
}
@ -143,6 +145,7 @@ TEST_P(GlslIoMap, FromFile)
GetParam().baseTextureBinding,
GetParam().baseImageBinding,
GetParam().baseUboBinding,
GetParam().baseSsboBinding,
GetParam().autoMapBindings,
GetParam().flattenUniforms);
}
@ -301,15 +304,16 @@ INSTANTIATE_TEST_CASE_P(
INSTANTIATE_TEST_CASE_P(
Hlsl, HlslIoMap,
::testing::ValuesIn(std::vector<IoMapData>{
{ "spv.register.autoassign.frag", "main_ep", 5, 10, 0, 20, true, false },
{ "spv.register.noautoassign.frag", "main_ep", 5, 10, 0, 15, false, false },
{ "spv.register.autoassign-2.frag", "main", 5, 10, 0, 15, true, true },
{ "spv.buffer.autoassign.frag", "main", 5, 10, 0, 15, true, true },
{ "spv.rw.autoassign.frag", "main", 5, 10, 20, 15, true, true },
{ "spv.register.autoassign.frag", "main_ep", 5, 10, 0, 20, 30, true, false },
{ "spv.register.noautoassign.frag", "main_ep", 5, 10, 0, 15, 30, false, false },
{ "spv.register.autoassign-2.frag", "main", 5, 10, 0, 15, 30, true, true },
{ "spv.buffer.autoassign.frag", "main", 5, 10, 0, 15, 30, true, true },
{ "spv.ssbo.autoassign.frag", "main", 5, 10, 0, 15, 30, true, true },
{ "spv.rw.autoassign.frag", "main", 5, 10, 20, 15, 30, true, true },
{ "spv.register.autoassign.rangetest.frag", "main",
glslang::TQualifier::layoutBindingEnd-2,
glslang::TQualifier::layoutBindingEnd+5,
20, true, false },
20, 30, true, false },
}),
FileNameAsCustomTestSuffixIoMap
);
@ -318,8 +322,8 @@ INSTANTIATE_TEST_CASE_P(
INSTANTIATE_TEST_CASE_P(
Hlsl, GlslIoMap,
::testing::ValuesIn(std::vector<IoMapData>{
{ "spv.glsl.register.autoassign.frag", "main", 5, 10, 0, 20, true, false },
{ "spv.glsl.register.noautoassign.frag", "main", 5, 10, 0, 15, false, false },
{ "spv.glsl.register.autoassign.frag", "main", 5, 10, 0, 20, 30, true, false },
{ "spv.glsl.register.noautoassign.frag", "main", 5, 10, 0, 15, 30, false, false },
}),
FileNameAsCustomTestSuffixIoMap
);

View File

@ -241,6 +241,7 @@ public:
int baseTextureBinding,
int baseImageBinding,
int baseUboBinding,
int baseSsboBinding,
bool autoMapBindings,
bool flattenUniformArrays)
{
@ -251,6 +252,7 @@ public:
shader.setShiftTextureBinding(baseTextureBinding);
shader.setShiftImageBinding(baseImageBinding);
shader.setShiftUboBinding(baseUboBinding);
shader.setShiftSsboBinding(baseSsboBinding);
shader.setAutoMapBindings(autoMapBindings);
shader.setFlattenUniformArrays(flattenUniformArrays);
@ -430,6 +432,7 @@ public:
int baseTextureBinding,
int baseImageBinding,
int baseUboBinding,
int baseSsboBinding,
bool autoMapBindings,
bool flattenUniformArrays)
{
@ -443,7 +446,8 @@ public:
const EShMessages controls = DeriveOptions(source, semantics, target);
GlslangResult result = compileLinkIoMap(testName, input, entryPointName, controls,
baseSamplerBinding, baseTextureBinding, baseImageBinding, baseUboBinding,
baseSamplerBinding, baseTextureBinding, baseImageBinding,
baseUboBinding, baseSsboBinding,
autoMapBindings,
flattenUniformArrays);