Auto push constant blocks (#2764)
* add ability to upgrade uniform block to push constants assuming it fits within the size limit imposed by the caller * allow selecting the packing for the auto push constants * check the size using the potential layout packing of the push constants
This commit is contained in:
parent
c2604615f4
commit
3f04389a18
4 changed files with 57 additions and 2 deletions
|
|
@ -741,6 +741,16 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isUniform() const
|
||||||
|
{
|
||||||
|
switch (storage) {
|
||||||
|
case EvqUniform:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool isIo() const
|
bool isIo() const
|
||||||
{
|
{
|
||||||
switch (storage) {
|
switch (storage) {
|
||||||
|
|
|
||||||
|
|
@ -1633,6 +1633,37 @@ bool TGlslIoMapper::doMap(TIoMapResolver* resolver, TInfoSink& infoSink) {
|
||||||
return TVarEntryInfo::TOrderByPriority()(p1.second, p2.second);
|
return TVarEntryInfo::TOrderByPriority()(p1.second, p2.second);
|
||||||
});
|
});
|
||||||
resolver->endResolve(EShLangCount);
|
resolver->endResolve(EShLangCount);
|
||||||
|
if (autoPushConstantBlockName.length()) {
|
||||||
|
bool upgraded = false;
|
||||||
|
for (size_t stage = 0; stage < EShLangCount; stage++) {
|
||||||
|
if (intermediates[stage] != nullptr) {
|
||||||
|
TVarLiveMap** pUniformVarMap = uniformResolve.uniformVarMap;
|
||||||
|
auto at = pUniformVarMap[stage]->find(autoPushConstantBlockName);
|
||||||
|
if (at == pUniformVarMap[stage]->end())
|
||||||
|
continue;
|
||||||
|
TQualifier& qualifier = at->second.symbol->getQualifier();
|
||||||
|
if (!qualifier.isUniform())
|
||||||
|
continue;
|
||||||
|
TType& t = at->second.symbol->getWritableType();
|
||||||
|
int size, stride;
|
||||||
|
TIntermediate::getBaseAlignment(t, size, stride, autoPushConstantBlockPacking,
|
||||||
|
qualifier.layoutMatrix == ElmRowMajor);
|
||||||
|
if (size <= int(autoPushConstantMaxSize)) {
|
||||||
|
qualifier.setBlockStorage(EbsPushConstant);
|
||||||
|
qualifier.layoutPacking = autoPushConstantBlockPacking;
|
||||||
|
upgraded = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If it's been upgraded to push_constant, then remove it from the uniformVector
|
||||||
|
// so it doesn't get a set/binding assigned to it.
|
||||||
|
if (upgraded) {
|
||||||
|
auto at = std::find_if(uniformVector.begin(), uniformVector.end(),
|
||||||
|
[this](const TVarLivePair& p) { return p.first == autoPushConstantBlockName; });
|
||||||
|
if (at != uniformVector.end())
|
||||||
|
uniformVector.erase(at);
|
||||||
|
}
|
||||||
|
}
|
||||||
for (size_t stage = 0; stage < EShLangCount; stage++) {
|
for (size_t stage = 0; stage < EShLangCount; stage++) {
|
||||||
if (intermediates[stage] != nullptr) {
|
if (intermediates[stage] != nullptr) {
|
||||||
// traverse each stage, set new location to each input/output and unifom symbol, set new binding to
|
// traverse each stage, set new location to each input/output and unifom symbol, set new binding to
|
||||||
|
|
|
||||||
|
|
@ -291,7 +291,7 @@ public:
|
||||||
bool virtual doMap(TIoMapResolver*, TInfoSink&) { return true; }
|
bool virtual doMap(TIoMapResolver*, TInfoSink&) { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
// I/O mapper for OpenGL
|
// I/O mapper for GLSL
|
||||||
class TGlslIoMapper : public TIoMapper {
|
class TGlslIoMapper : public TIoMapper {
|
||||||
public:
|
public:
|
||||||
TGlslIoMapper() {
|
TGlslIoMapper() {
|
||||||
|
|
@ -301,6 +301,8 @@ public:
|
||||||
memset(intermediates, 0, sizeof(TIntermediate*) * (EShLangCount + 1));
|
memset(intermediates, 0, sizeof(TIntermediate*) * (EShLangCount + 1));
|
||||||
profile = ENoProfile;
|
profile = ENoProfile;
|
||||||
version = 0;
|
version = 0;
|
||||||
|
autoPushConstantMaxSize = 128;
|
||||||
|
autoPushConstantBlockPacking = ElpStd430;
|
||||||
}
|
}
|
||||||
virtual ~TGlslIoMapper() {
|
virtual ~TGlslIoMapper() {
|
||||||
for (size_t stage = 0; stage < EShLangCount; stage++) {
|
for (size_t stage = 0; stage < EShLangCount; stage++) {
|
||||||
|
|
@ -319,6 +321,13 @@ public:
|
||||||
if (intermediates[stage] != nullptr)
|
if (intermediates[stage] != nullptr)
|
||||||
intermediates[stage] = nullptr;
|
intermediates[stage] = nullptr;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
// If set, the uniform block with the given name will be changed to be backed by
|
||||||
|
// push_constant if it's size is <= maxSize
|
||||||
|
void setAutoPushConstantBlock(const char* name, unsigned int maxSize, TLayoutPacking packing) {
|
||||||
|
autoPushConstantBlockName = name;
|
||||||
|
autoPushConstantMaxSize = maxSize;
|
||||||
|
autoPushConstantBlockPacking = packing;
|
||||||
}
|
}
|
||||||
// grow the reflection stage by stage
|
// grow the reflection stage by stage
|
||||||
bool addStage(EShLanguage, TIntermediate&, TInfoSink&, TIoMapResolver*) override;
|
bool addStage(EShLanguage, TIntermediate&, TInfoSink&, TIoMapResolver*) override;
|
||||||
|
|
@ -329,6 +338,11 @@ public:
|
||||||
bool hadError = false;
|
bool hadError = false;
|
||||||
EProfile profile;
|
EProfile profile;
|
||||||
int version;
|
int version;
|
||||||
|
|
||||||
|
private:
|
||||||
|
TString autoPushConstantBlockName;
|
||||||
|
unsigned int autoPushConstantMaxSize;
|
||||||
|
TLayoutPacking autoPushConstantBlockPacking;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
|
|
||||||
|
|
@ -1934,7 +1934,7 @@ int TIntermediate::getBaseAlignment(const TType& type, int& size, int& stride, T
|
||||||
}
|
}
|
||||||
|
|
||||||
// rule 9
|
// rule 9
|
||||||
if (type.getBasicType() == EbtStruct) {
|
if (type.getBasicType() == EbtStruct || type.getBasicType() == EbtBlock) {
|
||||||
const TTypeList& memberList = *type.getStruct();
|
const TTypeList& memberList = *type.getStruct();
|
||||||
|
|
||||||
size = 0;
|
size = 0;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue