|
|
@@ -351,16 +351,21 @@ private:
|
|
|
// Base class for shared TIoMapResolver services, used by several derivations.
|
|
|
struct TDefaultIoResolverBase : public glslang::TIoMapResolver
|
|
|
{
|
|
|
- int baseSamplerBinding;
|
|
|
- int baseTextureBinding;
|
|
|
- int baseImageBinding;
|
|
|
- int baseUboBinding;
|
|
|
- int baseSsboBinding;
|
|
|
- int baseUavBinding;
|
|
|
- std::vector<std::string> baseResourceSetBinding;
|
|
|
- bool doAutoBindingMapping;
|
|
|
- bool doAutoLocationMapping;
|
|
|
- int nextUniformLocation;
|
|
|
+ TDefaultIoResolverBase(const TIntermediate &intermediate) :
|
|
|
+ intermediate(intermediate),
|
|
|
+ nextUniformLocation(0)
|
|
|
+ { }
|
|
|
+
|
|
|
+ int getBaseBinding(TResourceType res, unsigned int set) const {
|
|
|
+ return selectBaseBinding(intermediate.getShiftBinding(res),
|
|
|
+ intermediate.getShiftBindingForSet(res, set));
|
|
|
+ }
|
|
|
+
|
|
|
+ const std::vector<std::string>& getResourceSetBinding() const { return intermediate.getResourceSetBinding(); }
|
|
|
+
|
|
|
+ bool doAutoBindingMapping() const { return intermediate.getAutoMapBindings(); }
|
|
|
+ bool doAutoLocationMapping() const { return intermediate.getAutoMapLocations(); }
|
|
|
+
|
|
|
typedef std::vector<int> TSlotSet;
|
|
|
typedef std::unordered_map<int, TSlotSet> TSlotSetMap;
|
|
|
TSlotSetMap slots;
|
|
|
@@ -411,15 +416,15 @@ struct TDefaultIoResolverBase : public glslang::TIoMapResolver
|
|
|
return type.getQualifier().layoutSet;
|
|
|
|
|
|
// If a command line or API option requested a single descriptor set, use that (if not overrided by spaceN)
|
|
|
- if (baseResourceSetBinding.size() == 1)
|
|
|
- return atoi(baseResourceSetBinding[0].c_str());
|
|
|
+ if (getResourceSetBinding().size() == 1)
|
|
|
+ return atoi(getResourceSetBinding()[0].c_str());
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
|
int resolveUniformLocation(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& type, bool /*is_live*/) override
|
|
|
{
|
|
|
// kick out of not doing this
|
|
|
- if (!doAutoLocationMapping)
|
|
|
+ if (!doAutoLocationMapping())
|
|
|
return -1;
|
|
|
|
|
|
// no locations added if already present, a built-in variable, a block, or an opaque
|
|
|
@@ -444,7 +449,7 @@ struct TDefaultIoResolverBase : public glslang::TIoMapResolver
|
|
|
int resolveInOutLocation(EShLanguage /*stage*/, const char* /*name*/, const TType& type, bool /*is_live*/) override
|
|
|
{
|
|
|
// kick out of not doing this
|
|
|
- if (!doAutoLocationMapping)
|
|
|
+ if (!doAutoLocationMapping())
|
|
|
return -1;
|
|
|
|
|
|
// no locations added if already present, or a built-in variable
|
|
|
@@ -485,6 +490,14 @@ struct TDefaultIoResolverBase : public glslang::TIoMapResolver
|
|
|
void endResolve(EShLanguage) override {}
|
|
|
|
|
|
protected:
|
|
|
+ const TIntermediate &intermediate;
|
|
|
+ int nextUniformLocation;
|
|
|
+
|
|
|
+ // Return descriptor set specific base if there is one, and the generic base otherwise.
|
|
|
+ int selectBaseBinding(int base, int descriptorSetBase) const {
|
|
|
+ return descriptorSetBase != -1 ? descriptorSetBase : base;
|
|
|
+ }
|
|
|
+
|
|
|
static int getLayoutSet(const glslang::TType& type) {
|
|
|
if (type.getQualifier().hasSet())
|
|
|
return type.getQualifier().layoutSet;
|
|
|
@@ -518,6 +531,8 @@ protected:
|
|
|
*/
|
|
|
struct TDefaultIoResolver : public TDefaultIoResolverBase
|
|
|
{
|
|
|
+ TDefaultIoResolver(const TIntermediate &intermediate) : TDefaultIoResolverBase(intermediate) { }
|
|
|
+
|
|
|
bool validateBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& /*type*/, bool /*is_live*/) override
|
|
|
{
|
|
|
return true;
|
|
|
@@ -529,37 +544,37 @@ struct TDefaultIoResolver : public TDefaultIoResolverBase
|
|
|
|
|
|
if (type.getQualifier().hasBinding()) {
|
|
|
if (isImageType(type))
|
|
|
- return reserveSlot(set, baseImageBinding + type.getQualifier().layoutBinding);
|
|
|
+ return reserveSlot(set, getBaseBinding(EResImage, set) + type.getQualifier().layoutBinding);
|
|
|
|
|
|
if (isTextureType(type))
|
|
|
- return reserveSlot(set, baseTextureBinding + type.getQualifier().layoutBinding);
|
|
|
+ return reserveSlot(set, getBaseBinding(EResTexture, set) + type.getQualifier().layoutBinding);
|
|
|
|
|
|
if (isSsboType(type))
|
|
|
- return reserveSlot(set, baseSsboBinding + type.getQualifier().layoutBinding);
|
|
|
+ return reserveSlot(set, getBaseBinding(EResSsbo, set) + type.getQualifier().layoutBinding);
|
|
|
|
|
|
if (isSamplerType(type))
|
|
|
- return reserveSlot(set, baseSamplerBinding + type.getQualifier().layoutBinding);
|
|
|
+ return reserveSlot(set, getBaseBinding(EResSampler, set) + type.getQualifier().layoutBinding);
|
|
|
|
|
|
if (isUboType(type))
|
|
|
- return reserveSlot(set, baseUboBinding + type.getQualifier().layoutBinding);
|
|
|
- } else if (is_live && doAutoBindingMapping) {
|
|
|
+ return reserveSlot(set, getBaseBinding(EResUbo, set) + type.getQualifier().layoutBinding);
|
|
|
+ } else if (is_live && doAutoBindingMapping()) {
|
|
|
// 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
|
|
|
|
|
|
if (isImageType(type))
|
|
|
- return getFreeSlot(set, baseImageBinding);
|
|
|
+ return getFreeSlot(set, getBaseBinding(EResImage, set));
|
|
|
|
|
|
if (isTextureType(type))
|
|
|
- return getFreeSlot(set, baseTextureBinding);
|
|
|
+ return getFreeSlot(set, getBaseBinding(EResTexture, set));
|
|
|
|
|
|
if (isSsboType(type))
|
|
|
- return getFreeSlot(set, baseSsboBinding);
|
|
|
+ return getFreeSlot(set, getBaseBinding(EResSsbo, set));
|
|
|
|
|
|
if (isSamplerType(type))
|
|
|
- return getFreeSlot(set, baseSamplerBinding);
|
|
|
+ return getFreeSlot(set, getBaseBinding(EResSampler, set));
|
|
|
|
|
|
if (isUboType(type))
|
|
|
- return getFreeSlot(set, baseUboBinding);
|
|
|
+ return getFreeSlot(set, getBaseBinding(EResUbo, set));
|
|
|
}
|
|
|
|
|
|
return -1;
|
|
|
@@ -620,6 +635,8 @@ b – for constant buffer views (CBV)
|
|
|
********************************************************************************/
|
|
|
struct TDefaultHlslIoResolver : public TDefaultIoResolverBase
|
|
|
{
|
|
|
+ TDefaultHlslIoResolver(const TIntermediate &intermediate) : TDefaultIoResolverBase(intermediate) { }
|
|
|
+
|
|
|
bool validateBinding(EShLanguage /*stage*/, const char* /*name*/, const glslang::TType& /*type*/, bool /*is_live*/) override
|
|
|
{
|
|
|
return true;
|
|
|
@@ -631,31 +648,31 @@ struct TDefaultHlslIoResolver : public TDefaultIoResolverBase
|
|
|
|
|
|
if (type.getQualifier().hasBinding()) {
|
|
|
if (isUavType(type))
|
|
|
- return reserveSlot(set, baseUavBinding + type.getQualifier().layoutBinding);
|
|
|
+ return reserveSlot(set, getBaseBinding(EResUav, set) + type.getQualifier().layoutBinding);
|
|
|
|
|
|
if (isSrvType(type))
|
|
|
- return reserveSlot(set, baseTextureBinding + type.getQualifier().layoutBinding);
|
|
|
+ return reserveSlot(set, getBaseBinding(EResTexture, set) + type.getQualifier().layoutBinding);
|
|
|
|
|
|
if (isSamplerType(type))
|
|
|
- return reserveSlot(set, baseSamplerBinding + type.getQualifier().layoutBinding);
|
|
|
+ return reserveSlot(set, getBaseBinding(EResSampler, set) + type.getQualifier().layoutBinding);
|
|
|
|
|
|
if (isUboType(type))
|
|
|
- return reserveSlot(set, baseUboBinding + type.getQualifier().layoutBinding);
|
|
|
- } else if (is_live && doAutoBindingMapping) {
|
|
|
+ return reserveSlot(set, getBaseBinding(EResUbo, set) + type.getQualifier().layoutBinding);
|
|
|
+ } else if (is_live && doAutoBindingMapping()) {
|
|
|
// 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
|
|
|
|
|
|
if (isUavType(type))
|
|
|
- return getFreeSlot(set, baseUavBinding);
|
|
|
+ return getFreeSlot(set, getBaseBinding(EResUav, set));
|
|
|
|
|
|
if (isSrvType(type))
|
|
|
- return getFreeSlot(set, baseTextureBinding);
|
|
|
+ return getFreeSlot(set, getBaseBinding(EResTexture, set));
|
|
|
|
|
|
if (isSamplerType(type))
|
|
|
- return getFreeSlot(set, baseSamplerBinding);
|
|
|
+ return getFreeSlot(set, getBaseBinding(EResSampler, set));
|
|
|
|
|
|
if (isUboType(type))
|
|
|
- return getFreeSlot(set, baseUboBinding);
|
|
|
+ return getFreeSlot(set, getBaseBinding(EResUbo, set));
|
|
|
}
|
|
|
|
|
|
return -1;
|
|
|
@@ -684,17 +701,17 @@ protected:
|
|
|
// Returns false if the input is too malformed to do this.
|
|
|
bool TIoMapper::addStage(EShLanguage stage, TIntermediate &intermediate, TInfoSink &infoSink, TIoMapResolver *resolver)
|
|
|
{
|
|
|
- // Trivial return if there is nothing to do.
|
|
|
- if (intermediate.getShiftSamplerBinding() == 0 &&
|
|
|
- intermediate.getShiftTextureBinding() == 0 &&
|
|
|
- intermediate.getShiftImageBinding() == 0 &&
|
|
|
- intermediate.getShiftUboBinding() == 0 &&
|
|
|
- intermediate.getShiftSsboBinding() == 0 &&
|
|
|
- intermediate.getShiftUavBinding() == 0 &&
|
|
|
- intermediate.getResourceSetBinding().empty() &&
|
|
|
- intermediate.getAutoMapBindings() == false &&
|
|
|
- intermediate.getAutoMapLocations() == false &&
|
|
|
- resolver == nullptr)
|
|
|
+ bool somethingToDo = !intermediate.getResourceSetBinding().empty() ||
|
|
|
+ intermediate.getAutoMapBindings() ||
|
|
|
+ intermediate.getAutoMapLocations();
|
|
|
+
|
|
|
+ for (int res = 0; res < EResCount; ++res) {
|
|
|
+ somethingToDo = somethingToDo ||
|
|
|
+ (intermediate.getShiftBinding(TResourceType(res)) != 0) ||
|
|
|
+ intermediate.hasShiftBindingForSet(TResourceType(res));
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!somethingToDo && resolver == nullptr)
|
|
|
return true;
|
|
|
|
|
|
if (intermediate.getNumEntryPoints() != 1 || intermediate.isRecursive())
|
|
|
@@ -705,30 +722,15 @@ bool TIoMapper::addStage(EShLanguage stage, TIntermediate &intermediate, TInfoSi
|
|
|
return false;
|
|
|
|
|
|
// if no resolver is provided, use the default resolver with the given shifts and auto map settings
|
|
|
- TDefaultIoResolver defaultResolver;
|
|
|
- TDefaultHlslIoResolver defaultHlslResolver;
|
|
|
+ TDefaultIoResolver defaultResolver(intermediate);
|
|
|
+ TDefaultHlslIoResolver defaultHlslResolver(intermediate);
|
|
|
|
|
|
if (resolver == nullptr) {
|
|
|
- TDefaultIoResolverBase* resolverBase;
|
|
|
-
|
|
|
// TODO: use a passed in IO mapper for this
|
|
|
if (intermediate.usingHlslIoMapping())
|
|
|
- resolverBase = &defaultHlslResolver;
|
|
|
+ resolver = &defaultHlslResolver;
|
|
|
else
|
|
|
- resolverBase = &defaultResolver;
|
|
|
-
|
|
|
- resolverBase->baseSamplerBinding = intermediate.getShiftSamplerBinding();
|
|
|
- resolverBase->baseTextureBinding = intermediate.getShiftTextureBinding();
|
|
|
- resolverBase->baseImageBinding = intermediate.getShiftImageBinding();
|
|
|
- resolverBase->baseUboBinding = intermediate.getShiftUboBinding();
|
|
|
- resolverBase->baseSsboBinding = intermediate.getShiftSsboBinding();
|
|
|
- resolverBase->baseUavBinding = intermediate.getShiftUavBinding();
|
|
|
- resolverBase->baseResourceSetBinding = intermediate.getResourceSetBinding();
|
|
|
- resolverBase->doAutoBindingMapping = intermediate.getAutoMapBindings();
|
|
|
- resolverBase->doAutoLocationMapping = intermediate.getAutoMapLocations();
|
|
|
- resolverBase->nextUniformLocation = 0;
|
|
|
-
|
|
|
- resolver = resolverBase;
|
|
|
+ resolver = &defaultResolver;
|
|
|
}
|
|
|
|
|
|
TVarLiveMap inVarMap, outVarMap, uniformVarMap;
|