SPV: Give error on not assigning locations to I/O.
Also, provides an option to auto-assign locations. Existing tests use this option, to avoid the error message, however, it is not fully implemented yet.
This commit is contained in:
parent
24e895b4a3
commit
71facdf435
14 changed files with 97 additions and 10 deletions
|
|
@ -4332,6 +4332,18 @@ void TParseContext::layoutObjectCheck(const TSourceLoc& loc, const TSymbol& symb
|
|||
default:
|
||||
break;
|
||||
}
|
||||
} else if (spvVersion.spv > 0) {
|
||||
switch (qualifier.storage) {
|
||||
case EvqVaryingIn:
|
||||
case EvqVaryingOut:
|
||||
if (! parsingBuiltins && qualifier.builtIn == EbvNone) {
|
||||
if (!intermediate.getAutoMapLocations())
|
||||
error(loc, "SPIR-V requires location for user input/output", "location", "");
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check packing and matrix
|
||||
|
|
@ -5022,6 +5034,8 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden
|
|||
|
||||
// look for errors in layout qualifier use
|
||||
layoutObjectCheck(loc, *symbol);
|
||||
|
||||
// fix up
|
||||
fixOffset(loc, *symbol);
|
||||
|
||||
return initNode;
|
||||
|
|
@ -5728,6 +5742,7 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con
|
|||
// Check for general layout qualifier errors
|
||||
layoutObjectCheck(loc, variable);
|
||||
|
||||
// fix up
|
||||
if (isIoResizeArray(blockType)) {
|
||||
ioArraySymbolResizeList.push_back(&variable);
|
||||
checkIoArraysConsistency(loc, true);
|
||||
|
|
|
|||
|
|
@ -1571,6 +1571,8 @@ void TShader::setShiftUavBinding(unsigned int base) { intermediate->setShift
|
|||
void TShader::setShiftSsboBinding(unsigned int base) { intermediate->setShiftSsboBinding(base); }
|
||||
// Enables binding automapping using TIoMapper
|
||||
void TShader::setAutoMapBindings(bool map) { intermediate->setAutoMapBindings(map); }
|
||||
// Fragile: currently within one stage: simple auto-assignment of location
|
||||
void TShader::setAutoMapLocations(bool map) { intermediate->setAutoMapLocations(map); }
|
||||
// See comment above TDefaultHlslIoMapper in iomapper.cpp:
|
||||
void TShader::setHlslIoMapping(bool hlslIoMap) { intermediate->setHlslIoMapping(hlslIoMap); }
|
||||
void TShader::setFlattenUniformArrays(bool flatten) { intermediate->setFlattenUniformArrays(flatten); }
|
||||
|
|
|
|||
|
|
@ -214,6 +214,8 @@ struct TNotifyUniformAdaptor
|
|||
{
|
||||
resolver.notifyBinding(stage, ent.symbol->getName().c_str(), ent.symbol->getType(), ent.live);
|
||||
}
|
||||
private:
|
||||
TNotifyUniformAdaptor& operator=(TNotifyUniformAdaptor&);
|
||||
};
|
||||
|
||||
struct TNotifyInOutAdaptor
|
||||
|
|
@ -229,6 +231,8 @@ struct TNotifyInOutAdaptor
|
|||
{
|
||||
resolver.notifyInOut(stage, ent.symbol->getName().c_str(), ent.symbol->getType(), ent.live);
|
||||
}
|
||||
private:
|
||||
TNotifyInOutAdaptor& operator=(TNotifyInOutAdaptor&);
|
||||
};
|
||||
|
||||
struct TResolverUniformAdaptor
|
||||
|
|
@ -350,7 +354,8 @@ struct TDefaultIoResolverBase : public glslang::TIoMapResolver
|
|||
int baseSsboBinding;
|
||||
int baseUavBinding;
|
||||
std::vector<std::string> baseResourceSetBinding;
|
||||
bool doAutoMapping;
|
||||
bool doAutoBindingMapping;
|
||||
bool doAutoLocationMapping;
|
||||
typedef std::vector<int> TSlotSet;
|
||||
typedef std::unordered_map<int, TSlotSet> TSlotSetMap;
|
||||
TSlotSetMap slots;
|
||||
|
|
@ -401,9 +406,19 @@ struct TDefaultIoResolverBase : public glslang::TIoMapResolver
|
|||
{
|
||||
return true;
|
||||
}
|
||||
int resolveInOutLocation(EShLanguage /*stage*/, const char* /*name*/, const TType& /*type*/, bool /*is_live*/) override
|
||||
int resolveInOutLocation(EShLanguage /*stage*/, const char* /*name*/, const TType& type, bool /*is_live*/) override
|
||||
{
|
||||
return -1;
|
||||
if (!doAutoLocationMapping || type.getQualifier().hasLocation())
|
||||
return -1;
|
||||
|
||||
// Placeholder.
|
||||
// TODO: It would be nice to flesh this out using
|
||||
// intermediate->computeTypeLocationSize(type), or functions that call it like
|
||||
// intermediate->addUsedLocation()
|
||||
// These in turn would want the intermediate, which is not available here, but
|
||||
// is available in many places, and a lot of copying from it could be saved if
|
||||
// it were just available.
|
||||
return 0;
|
||||
}
|
||||
int resolveInOutComponent(EShLanguage /*stage*/, const char* /*name*/, const TType& /*type*/, bool /*is_live*/) override
|
||||
{
|
||||
|
|
@ -493,7 +508,7 @@ struct TDefaultIoResolver : public TDefaultIoResolverBase
|
|||
|
||||
if (isUboType(type))
|
||||
return reserveSlot(set, baseUboBinding + type.getQualifier().layoutBinding);
|
||||
} else if (is_live && doAutoMapping) {
|
||||
} 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
|
||||
|
||||
|
|
@ -607,7 +622,7 @@ struct TDefaultHlslIoResolver : public TDefaultIoResolverBase
|
|||
|
||||
if (isUboType(type))
|
||||
return reserveSlot(set, baseUboBinding + type.getQualifier().layoutBinding);
|
||||
} else if (is_live && doAutoMapping) {
|
||||
} 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
|
||||
|
||||
|
|
@ -659,6 +674,7 @@ bool TIoMapper::addStage(EShLanguage stage, TIntermediate &intermediate, TInfoSi
|
|||
intermediate.getShiftUavBinding() == 0 &&
|
||||
intermediate.getResourceSetBinding().empty() &&
|
||||
intermediate.getAutoMapBindings() == false &&
|
||||
intermediate.getAutoMapLocations() == false &&
|
||||
resolver == nullptr)
|
||||
return true;
|
||||
|
||||
|
|
@ -689,7 +705,8 @@ bool TIoMapper::addStage(EShLanguage stage, TIntermediate &intermediate, TInfoSi
|
|||
resolverBase->baseSsboBinding = intermediate.getShiftSsboBinding();
|
||||
resolverBase->baseUavBinding = intermediate.getShiftUavBinding();
|
||||
resolverBase->baseResourceSetBinding = intermediate.getResourceSetBinding();
|
||||
resolverBase->doAutoMapping = intermediate.getAutoMapBindings();
|
||||
resolverBase->doAutoBindingMapping = intermediate.getAutoMapBindings();
|
||||
resolverBase->doAutoLocationMapping = intermediate.getAutoMapLocations();
|
||||
|
||||
resolver = resolverBase;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -860,7 +860,7 @@ int TIntermediate::checkLocationRange(int set, const TIoRange& range, const TTyp
|
|||
return -1; // no collision
|
||||
}
|
||||
|
||||
// Accumulate locations used for inputs, outputs, and uniforms, and check for collisions
|
||||
// Accumulate bindings and offsets, and check for collisions
|
||||
// as the accumulation is done.
|
||||
//
|
||||
// Returns < 0 if no collision, >= 0 if collision and the value returned is a colliding value.
|
||||
|
|
|
|||
|
|
@ -177,6 +177,7 @@ public:
|
|||
shiftSsboBinding(0),
|
||||
shiftUavBinding(0),
|
||||
autoMapBindings(false),
|
||||
autoMapLocations(false),
|
||||
flattenUniformArrays(false),
|
||||
useUnknownFormat(false),
|
||||
hlslOffsets(false),
|
||||
|
|
@ -218,9 +219,11 @@ public:
|
|||
unsigned int getShiftUavBinding() const { return shiftUavBinding; }
|
||||
void setResourceSetBinding(const std::vector<std::string>& shift) { resourceSetBinding = shift; }
|
||||
const std::vector<std::string>& getResourceSetBinding() const { return resourceSetBinding; }
|
||||
void setAutoMapBindings(bool map) { autoMapBindings = map; }
|
||||
void setAutoMapBindings(bool map) { autoMapBindings = map; }
|
||||
bool getAutoMapBindings() const { return autoMapBindings; }
|
||||
void setFlattenUniformArrays(bool flatten) { flattenUniformArrays = flatten; }
|
||||
void setAutoMapLocations(bool map) { autoMapLocations = map; }
|
||||
bool getAutoMapLocations() const { return autoMapLocations; }
|
||||
void setFlattenUniformArrays(bool flatten) { flattenUniformArrays = flatten; }
|
||||
bool getFlattenUniformArrays() const { return flattenUniformArrays; }
|
||||
void setNoStorageFormat(bool b) { useUnknownFormat = b; }
|
||||
bool getNoStorageFormat() const { return useUnknownFormat; }
|
||||
|
|
@ -516,6 +519,7 @@ protected:
|
|||
unsigned int shiftUavBinding;
|
||||
std::vector<std::string> resourceSetBinding;
|
||||
bool autoMapBindings;
|
||||
bool autoMapLocations;
|
||||
bool flattenUniformArrays;
|
||||
bool useUnknownFormat;
|
||||
bool hlslOffsets;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue