Non-functional HLSL: Factor out built-ins from splitting and related simplifications.
This commit is contained in:
parent
eaed06823a
commit
ecd08bc36c
@ -423,14 +423,14 @@ struct TDefaultIoResolverBase : public glslang::TIoMapResolver
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
// no locations added if already present, or a built-in variable
|
// no locations added if already present, or a built-in variable
|
||||||
if (type.getQualifier().hasLocation() || type.getQualifier().builtIn != EbvNone)
|
if (type.getQualifier().hasLocation() || type.isBuiltIn())
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
// no locations on blocks of built-in variables
|
// no locations on blocks of built-in variables
|
||||||
if (type.isStruct()) {
|
if (type.isStruct()) {
|
||||||
if (type.getStruct()->size() < 1)
|
if (type.getStruct()->size() < 1)
|
||||||
return -1;
|
return -1;
|
||||||
if ((*type.getStruct())[0].type->getQualifier().builtIn != EbvNone)
|
if ((*type.getStruct())[0].type->isBuiltIn())
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -616,7 +616,7 @@ bool HlslGrammar::acceptFullySpecifiedType(TType& type, TIntermNode*& nodeList)
|
|||||||
qualifier.readonly = type.getQualifier().readonly;
|
qualifier.readonly = type.getQualifier().readonly;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type.getQualifier().builtIn != EbvNone)
|
if (type.isBuiltIn())
|
||||||
qualifier.builtIn = type.getQualifier().builtIn;
|
qualifier.builtIn = type.getQualifier().builtIn;
|
||||||
|
|
||||||
type.getQualifier() = qualifier;
|
type.getQualifier() = qualifier;
|
||||||
|
|||||||
@ -1121,58 +1121,51 @@ bool HlslParseContext::isBuiltInMethod(const TSourceLoc&, TIntermTyped* base, co
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Independently establish a built-in that is a member of a structure.
|
||||||
|
// 'arraySizes' are what's desired for the independent built-in, whatever
|
||||||
|
// the higher-level source/expression of them was.
|
||||||
|
void HlslParseContext::splitBuiltIn(const TString& baseName, const TType& memberType, const TArraySizes* arraySizes,
|
||||||
|
const TQualifier& outerQualifier)
|
||||||
|
{
|
||||||
|
TVariable* ioVar = makeInternalVariable(baseName + (baseName.empty() ? "" : "_") + memberType.getFieldName(), memberType);
|
||||||
|
|
||||||
|
if (arraySizes)
|
||||||
|
ioVar->getWritableType().newArraySizes(*arraySizes);
|
||||||
|
|
||||||
|
fixBuiltInIoType(ioVar->getWritableType());
|
||||||
|
|
||||||
|
splitBuiltIns[tInterstageIoData(memberType.getQualifier().builtIn, outerQualifier.storage)] = ioVar;
|
||||||
|
if (!isClipOrCullDistance(ioVar->getType()))
|
||||||
|
trackLinkage(*ioVar);
|
||||||
|
|
||||||
|
// Merge qualifier from the user structure
|
||||||
|
mergeQualifiers(ioVar->getWritableType().getQualifier(), outerQualifier);
|
||||||
|
}
|
||||||
|
|
||||||
// Split a type into
|
// Split a type into
|
||||||
// 1. a struct of non-I/O members
|
// 1. a struct of non-I/O members
|
||||||
// 2. a collection of flattened I/O variables
|
// 2. a collection of independent I/O variables
|
||||||
void HlslParseContext::split(const TVariable& variable)
|
void HlslParseContext::split(const TVariable& variable)
|
||||||
{
|
{
|
||||||
// Create a new variable:
|
// Create a new variable:
|
||||||
TType& splitType = split(*variable.getType().clone(), variable.getName());
|
const TType& clonedType = *variable.getType().clone();
|
||||||
|
const TType& splitType = split(clonedType, variable.getName(), clonedType.getQualifier());
|
||||||
splitNonIoVars[variable.getUniqueId()] = makeInternalVariable(variable.getName(), splitType);
|
splitNonIoVars[variable.getUniqueId()] = makeInternalVariable(variable.getName(), splitType);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recursive implementation of split().
|
// Recursive implementation of split().
|
||||||
// Returns reference to the modified type.
|
// Returns reference to the modified type.
|
||||||
TType& HlslParseContext::split(TType& type, TString name, const TType* outerStructType)
|
const TType& HlslParseContext::split(const TType& type, const TString& name, const TQualifier& outerQualifier)
|
||||||
{
|
{
|
||||||
const TArraySizes* arraySizes = nullptr;
|
|
||||||
|
|
||||||
// At the outer-most scope, remember the struct type so we can examine its storage class
|
|
||||||
// at deeper levels.
|
|
||||||
if (outerStructType == nullptr)
|
|
||||||
outerStructType = &type;
|
|
||||||
|
|
||||||
if (type.isArray())
|
|
||||||
arraySizes = &type.getArraySizes();
|
|
||||||
|
|
||||||
// We can ignore arrayness: it's uninvolved.
|
|
||||||
if (type.isStruct()) {
|
if (type.isStruct()) {
|
||||||
TTypeList* userStructure = type.getWritableStruct();
|
TTypeList* userStructure = type.getWritableStruct();
|
||||||
for (auto ioType = userStructure->begin(); ioType != userStructure->end(); ) {
|
for (auto ioType = userStructure->begin(); ioType != userStructure->end(); ) {
|
||||||
if (ioType->type->getQualifier().builtIn != EbvNone) {
|
if (ioType->type->isBuiltIn()) {
|
||||||
// split out built-in interstage IO
|
// move out the built-in
|
||||||
const TType& memberType = *ioType->type;
|
splitBuiltIn(name, *ioType->type, type.getArraySizes(), outerQualifier);
|
||||||
TVariable* ioVar = makeInternalVariable(name + (name.empty() ? "" : "_") + memberType.getFieldName(),
|
|
||||||
memberType);
|
|
||||||
|
|
||||||
if (arraySizes)
|
|
||||||
ioVar->getWritableType().newArraySizes(*arraySizes);
|
|
||||||
|
|
||||||
fixBuiltInIoType(ioVar->getWritableType());
|
|
||||||
|
|
||||||
splitBuiltIns[tInterstageIoData(memberType, *outerStructType)] = ioVar;
|
|
||||||
if (!isClipOrCullDistance(ioVar->getType()))
|
|
||||||
trackLinkage(*ioVar);
|
|
||||||
|
|
||||||
// Merge qualifier from the user structure
|
|
||||||
mergeQualifiers(ioVar->getWritableType().getQualifier(), outerStructType->getQualifier());
|
|
||||||
|
|
||||||
// Erase the IO vars from the user structure.
|
|
||||||
ioType = userStructure->erase(ioType);
|
ioType = userStructure->erase(ioType);
|
||||||
} else {
|
} else {
|
||||||
split(*ioType->type,
|
split(*ioType->type, name + (name.empty() ? "" : "_") + ioType->type->getFieldName(), outerQualifier);
|
||||||
name + (name.empty() ? "" : "_") + ioType->type->getFieldName(),
|
|
||||||
outerStructType);
|
|
||||||
++ioType;
|
++ioType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1258,10 +1251,9 @@ int HlslParseContext::addFlattenedMember(const TVariable& variable, const TType&
|
|||||||
if (flattenData.nextBinding != TQualifier::layoutBindingEnd)
|
if (flattenData.nextBinding != TQualifier::layoutBindingEnd)
|
||||||
memberVariable->getWritableType().getQualifier().layoutBinding = flattenData.nextBinding++;
|
memberVariable->getWritableType().getQualifier().layoutBinding = flattenData.nextBinding++;
|
||||||
|
|
||||||
if (memberVariable->getType().getQualifier().builtIn == EbvNone) {
|
if (!memberVariable->getType().isBuiltIn()) {
|
||||||
// inherited locations must be auto bumped, not replicated
|
// inherited locations must be auto bumped, not replicated
|
||||||
if (flattenData.nextLocation != TQualifier::layoutLocationEnd &&
|
if (flattenData.nextLocation != TQualifier::layoutLocationEnd) {
|
||||||
memberVariable->getType().getQualifier().builtIn == EbvNone) {
|
|
||||||
memberVariable->getWritableType().getQualifier().layoutLocation = flattenData.nextLocation;
|
memberVariable->getWritableType().getQualifier().layoutLocation = flattenData.nextLocation;
|
||||||
flattenData.nextLocation += intermediate.computeTypeLocationSize(memberVariable->getType());
|
flattenData.nextLocation += intermediate.computeTypeLocationSize(memberVariable->getType());
|
||||||
nextOutLocation = std::max(nextOutLocation, flattenData.nextLocation);
|
nextOutLocation = std::max(nextOutLocation, flattenData.nextLocation);
|
||||||
@ -2530,8 +2522,10 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op
|
|||||||
if (split && derefType.isBuiltIn()) {
|
if (split && derefType.isBuiltIn()) {
|
||||||
// copy from interstage IO built-in if needed
|
// copy from interstage IO built-in if needed
|
||||||
const TIntermTyped* outer = isLeft ? outerLeft : outerRight;
|
const TIntermTyped* outer = isLeft ? outerLeft : outerRight;
|
||||||
subTree = intermediate.addSymbol(*splitBuiltIns.find(
|
subTree = intermediate.addSymbol(
|
||||||
HlslParseContext::tInterstageIoData(derefType, outer->getType()))->second);
|
*splitBuiltIns.find(HlslParseContext::tInterstageIoData(
|
||||||
|
derefType.getQualifier().builtIn,
|
||||||
|
outer->getType().getQualifier().storage))->second);
|
||||||
|
|
||||||
// Arrayness of builtIn symbols isn't handled by the normal recursion:
|
// Arrayness of builtIn symbols isn't handled by the normal recursion:
|
||||||
// it's been extracted and moved to the built-in.
|
// it's been extracted and moved to the built-in.
|
||||||
|
|||||||
@ -252,8 +252,9 @@ protected:
|
|||||||
bool isFinalFlattening(const TType& type) const { return !(type.isStruct() || type.isArray()); }
|
bool isFinalFlattening(const TType& type) const { return !(type.isStruct() || type.isArray()); }
|
||||||
|
|
||||||
// Structure splitting (splits interstage built-in types into its own struct)
|
// Structure splitting (splits interstage built-in types into its own struct)
|
||||||
TType& split(TType& type, TString name, const TType* outerStructType = nullptr);
|
|
||||||
void split(const TVariable&);
|
void split(const TVariable&);
|
||||||
|
void splitBuiltIn(const TString& baseName, const TType& memberType, const TArraySizes*, const TQualifier&);
|
||||||
|
const TType& split(const TType& type, const TString& name, const TQualifier&);
|
||||||
bool wasSplit(const TIntermTyped* node) const;
|
bool wasSplit(const TIntermTyped* node) const;
|
||||||
bool wasSplit(int id) const { return splitNonIoVars.find(id) != splitNonIoVars.end(); }
|
bool wasSplit(int id) const { return splitNonIoVars.find(id) != splitNonIoVars.end(); }
|
||||||
TVariable* getSplitNonIoVar(int id) const;
|
TVariable* getSplitNonIoVar(int id) const;
|
||||||
@ -393,10 +394,6 @@ protected:
|
|||||||
tInterstageIoData(TBuiltInVariable bi, TStorageQualifier q) :
|
tInterstageIoData(TBuiltInVariable bi, TStorageQualifier q) :
|
||||||
builtIn(bi), storage(q) { }
|
builtIn(bi), storage(q) { }
|
||||||
|
|
||||||
tInterstageIoData(const TType& memberType, const TType& storageType) :
|
|
||||||
builtIn(memberType.getQualifier().builtIn),
|
|
||||||
storage(storageType.getQualifier().storage) { }
|
|
||||||
|
|
||||||
TBuiltInVariable builtIn;
|
TBuiltInVariable builtIn;
|
||||||
TStorageQualifier storage;
|
TStorageQualifier storage;
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user