summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/iomapper.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/iomapper.cpp')
-rw-r--r--3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/iomapper.cpp200
1 files changed, 164 insertions, 36 deletions
diff --git a/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/iomapper.cpp b/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/iomapper.cpp
index 04868f16aa5..bebf775d918 100644
--- a/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/iomapper.cpp
+++ b/3rdparty/bgfx/3rdparty/glslang/glslang/MachineIndependent/iomapper.cpp
@@ -66,11 +66,14 @@ namespace glslang {
struct TVarEntryInfo
{
- int id;
- TIntermSymbol* symbol;
- bool live;
- int newBinding;
- int newSet;
+ int id;
+ TIntermSymbol* symbol;
+ bool live;
+ int newBinding;
+ int newSet;
+ int newLocation;
+ int newComponent;
+ int newIndex;
struct TOrderById
{
@@ -113,70 +116,109 @@ typedef std::vector<TVarEntryInfo> TVarLiveMap;
class TVarGatherTraverser : public TLiveTraverser
{
public:
- TVarGatherTraverser(const TIntermediate& i, TVarLiveMap& vars, bool traverseDeadCode)
+ TVarGatherTraverser(const TIntermediate& i, bool traverseDeadCode, TVarLiveMap& inList, TVarLiveMap& outList, TVarLiveMap& uniformList)
: TLiveTraverser(i, traverseDeadCode, true, true, false)
- , varLiveList(vars)
+ , inputList(inList)
+ , outputList(outList)
+ , uniformList(uniformList)
{
}
virtual void visitSymbol(TIntermSymbol* base)
{
- if (base->getQualifier().storage == EvqUniform) {
+ TVarLiveMap* target = nullptr;
+ if (base->getQualifier().storage == EvqVaryingIn)
+ target = &inputList;
+ else if (base->getQualifier().storage == EvqVaryingOut)
+ target = &outputList;
+ else if (base->getQualifier().isUniformOrBuffer())
+ target = &uniformList;
+
+ if (target) {
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)
+ TVarLiveMap::iterator at = std::lower_bound(target->begin(), target->end(), ent, TVarEntryInfo::TOrderById());
+ if (at != target->end() && at->id == ent.id)
at->live = at->live || !traverseAll; // update live state
else
- varLiveList.insert(at, ent);
+ target->insert(at, ent);
}
}
private:
- TVarLiveMap& varLiveList;
+ TVarLiveMap& inputList;
+ TVarLiveMap& outputList;
+ TVarLiveMap& uniformList;
};
class TVarSetTraverser : public TLiveTraverser
{
public:
- TVarSetTraverser(const TIntermediate& i, const TVarLiveMap& vars)
+ TVarSetTraverser(const TIntermediate& i, const TVarLiveMap& inList, const TVarLiveMap& outList, const TVarLiveMap& uniformList)
: TLiveTraverser(i, true, true, true, false)
- , varLiveList(vars)
+ , inputList(inList)
+ , outputList(outList)
+ , uniformList(uniformList)
{
}
virtual void visitSymbol(TIntermSymbol* base)
{
+ const TVarLiveMap* source;
+ if (base->getQualifier().storage == EvqVaryingIn)
+ source = &inputList;
+ else if (base->getQualifier().storage == EvqVaryingOut)
+ source = &outputList;
+ else if (base->getQualifier().isUniformOrBuffer())
+ source = &uniformList;
+ else
+ return;
+
TVarEntryInfo ent = { base->getId() };
- TVarLiveMap::const_iterator at = std::lower_bound(varLiveList.begin(), varLiveList.end(), ent, TVarEntryInfo::TOrderById());
- if (at == varLiveList.end())
+ TVarLiveMap::const_iterator at = std::lower_bound(source->begin(), source->end(), ent, TVarEntryInfo::TOrderById());
+ if (at == source->end())
return;
- if (!(at->id == ent.id))
+
+ if (at->id != ent.id)
return;
if (at->newBinding != -1)
base->getWritableType().getQualifier().layoutBinding = at->newBinding;
if (at->newSet != -1)
base->getWritableType().getQualifier().layoutSet = at->newSet;
+ if (at->newLocation != -1)
+ base->getWritableType().getQualifier().layoutLocation = at->newLocation;
+ if (at->newComponent != -1)
+ base->getWritableType().getQualifier().layoutComponent = at->newComponent;
+ if (at->newIndex != -1)
+ base->getWritableType().getQualifier().layoutIndex = at->newIndex;
}
private:
- const TVarLiveMap& varLiveList;
+ const TVarLiveMap& inputList;
+ const TVarLiveMap& outputList;
+ const TVarLiveMap& uniformList;
};
-struct TResolverAdaptor
+struct TResolverUniformAdaptor
{
- TResolverAdaptor(EShLanguage s, TIoMapResolver& r, TInfoSink& i, bool& e)
- : stage(s)
- , resolver(r)
+ TResolverUniformAdaptor(EShLanguage s, TIoMapResolver& r, TInfoSink& i, bool& e, TIntermediate& interm)
+ : resolver(r)
+ , stage(s)
, infoSink(i)
, error(e)
+ , intermediate(interm)
{
}
inline void operator()(TVarEntryInfo& ent)
{
+ ent.newLocation = -1;
+ ent.newComponent = -1;
+ ent.newBinding = -1;
+ ent.newSet = -1;
+ ent.newIndex = -1;
const bool isValid = resolver.validateBinding(stage, ent.symbol->getName().c_str(), ent.symbol->getType(), ent.live);
if (isValid) {
ent.newBinding = resolver.resolveBinding(stage, ent.symbol->getName().c_str(), ent.symbol->getType(), ent.live);
@@ -209,15 +251,69 @@ struct TResolverAdaptor
TIoMapResolver& resolver;
TInfoSink& infoSink;
bool& error;
+ TIntermediate& intermediate;
private:
- TResolverAdaptor& operator=(TResolverAdaptor&);
+ TResolverUniformAdaptor& operator=(TResolverUniformAdaptor&);
+};
+
+struct TResolverInOutAdaptor
+{
+ TResolverInOutAdaptor(EShLanguage s, TIoMapResolver& r, TInfoSink& i, bool& e, TIntermediate& interm)
+ : resolver(r)
+ , stage(s)
+ , infoSink(i)
+ , error(e)
+ , intermediate(interm)
+ {
+ }
+
+ inline void operator()(TVarEntryInfo& ent)
+ {
+ ent.newLocation = -1;
+ ent.newComponent = -1;
+ ent.newBinding = -1;
+ ent.newSet = -1;
+ ent.newIndex = -1;
+ const bool isValid = resolver.validateInOut(stage,
+ ent.symbol->getName().c_str(),
+ ent.symbol->getType(),
+ ent.live);
+ if (isValid) {
+ ent.newLocation = resolver.resolveInOutLocation(stage,
+ ent.symbol->getName().c_str(),
+ ent.symbol->getType(),
+ ent.live);
+ ent.newComponent = resolver.resolveInOutComponent(stage,
+ ent.symbol->getName().c_str(),
+ ent.symbol->getType(),
+ ent.live);
+ ent.newIndex = resolver.resolveInOutIndex(stage,
+ ent.symbol->getName().c_str(),
+ ent.symbol->getType(),
+ ent.live);
+ } else {
+ TString errorMsg = "Invalid shader In/Out variable semantic: ";
+ errorMsg += ent.symbol->getType().getQualifier().semanticName;
+ infoSink.info.message(EPrefixInternalError, errorMsg.c_str());
+ error = true;
+ }
+ }
+
+ EShLanguage stage;
+ TIoMapResolver& resolver;
+ TInfoSink& infoSink;
+ bool& error;
+ TIntermediate& intermediate;
+
+private:
+ TResolverInOutAdaptor& operator=(TResolverInOutAdaptor&);
};
/*
* Basic implementation of glslang::TIoMapResolver that replaces the
- * previous offset behaviour.
- * It does the same, uses the offsets for th corresponding uniform
+ * previous offset behavior.
+ * It does the same, uses the offsets for the corresponding uniform
* types. Also respects the EOptionAutoMapBindings flag and binds
* them if needed.
*/
@@ -227,6 +323,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 +378,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 +408,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 +428,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;
@@ -338,6 +444,23 @@ struct TDefaultIoResolver : public glslang::TIoMapResolver
return type.getQualifier().layoutSet;
return 0;
}
+
+ bool validateInOut(EShLanguage stage, const char* name, const TType& type, bool is_live) override
+ {
+ return true;
+ }
+ int resolveInOutLocation(EShLanguage stage, const char* name, const TType& type, bool is_live) override
+ {
+ return -1;
+ }
+ int resolveInOutComponent(EShLanguage stage, const char* name, const TType& type, bool is_live) override
+ {
+ return -1;
+ }
+ int resolveInOutIndex(EShLanguage stage, const char* name, const TType& type, bool is_live) override
+ {
+ return -1;
+ }
};
// Map I/O variables to provided offsets, and make bindings for
@@ -351,6 +474,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,14 +493,15 @@ 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;
}
- TVarLiveMap varMap;
- TVarGatherTraverser iter_binding_all(intermediate, varMap, true);
- TVarGatherTraverser iter_binding_live(intermediate, varMap, false);
+ TVarLiveMap inVarMap, outVarMap, uniformVarMap;
+ TVarGatherTraverser iter_binding_all(intermediate, true, inVarMap, outVarMap, uniformVarMap);
+ TVarGatherTraverser iter_binding_live(intermediate, false, inVarMap, outVarMap, uniformVarMap);
root->traverse(&iter_binding_all);
iter_binding_live.pushFunction(intermediate.getEntryPointMangledName().c_str());
@@ -388,16 +513,19 @@ bool TIoMapper::addStage(EShLanguage stage, TIntermediate &intermediate, TInfoSi
}
// sort entries by priority. see TVarEntryInfo::TOrderByPriority for info.
- std::sort(varMap.begin(), varMap.end(), TVarEntryInfo::TOrderByPriority());
+ std::sort(uniformVarMap.begin(), uniformVarMap.end(), TVarEntryInfo::TOrderByPriority());
bool hadError = false;
- TResolverAdaptor doResolve(stage, *resolver, infoSink, hadError);
- std::for_each(varMap.begin(), varMap.end(), doResolve);
+ TResolverUniformAdaptor uniformResolve(stage, *resolver, infoSink, hadError, intermediate);
+ TResolverInOutAdaptor inOutResolve(stage, *resolver, infoSink, hadError, intermediate);
+ std::for_each(inVarMap.begin(), inVarMap.end(), inOutResolve);
+ std::for_each(outVarMap.begin(), outVarMap.end(), inOutResolve);
+ std::for_each(uniformVarMap.begin(), uniformVarMap.end(), uniformResolve);
if (!hadError) {
// sort by id again, so we can use lower bound to find entries
- std::sort(varMap.begin(), varMap.end(), TVarEntryInfo::TOrderById());
- TVarSetTraverser iter_iomap(intermediate, varMap);
+ std::sort(uniformVarMap.begin(), uniformVarMap.end(), TVarEntryInfo::TOrderById());
+ TVarSetTraverser iter_iomap(intermediate, inVarMap, outVarMap, uniformVarMap);
root->traverse(&iter_iomap);
}