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:
parent
5da1f038d8
commit
932bb5cc4e
11 changed files with 265 additions and 15 deletions
|
|
@ -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(); }
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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*
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue