Non-functional: HLSL: Simplify I/O logic for splitting.
This commit is contained in:
parent
4cf5266042
commit
6042eb475b
@ -1370,15 +1370,12 @@ public:
|
||||
virtual bool isImage() const { return basicType == EbtSampler && getSampler().isImage(); }
|
||||
virtual bool isSubpass() const { return basicType == EbtSampler && getSampler().isSubpass(); }
|
||||
|
||||
virtual bool isBuiltInInterstageIO(EShLanguage language) const
|
||||
{
|
||||
return isPerVertexAndBuiltIn(language) || isLooseAndBuiltIn(language);
|
||||
}
|
||||
virtual bool isBuiltIn() const { return getQualifier().builtIn != EbvNone; }
|
||||
|
||||
// Return true if this is an interstage IO builtin
|
||||
virtual bool isPerVertexAndBuiltIn(EShLanguage language) const
|
||||
// Return true if this is a per-vertex built-in
|
||||
virtual bool isPerVertexBuiltIn(EShLanguage language) const
|
||||
{
|
||||
if (language == EShLangFragment)
|
||||
if (getQualifier().builtIn == EbvNone || language == EShLangFragment)
|
||||
return false;
|
||||
|
||||
// Any non-fragment stage
|
||||
@ -1401,15 +1398,6 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
// Return true if this is a loose builtin
|
||||
virtual bool isLooseAndBuiltIn(EShLanguage language) const
|
||||
{
|
||||
if (getQualifier().builtIn == EbvNone)
|
||||
return false;
|
||||
|
||||
return !isPerVertexAndBuiltIn(language);
|
||||
}
|
||||
|
||||
// return true if this type contains any subtype which satisfies the given predicate.
|
||||
template <typename P>
|
||||
bool contains(P predicate) const
|
||||
@ -1451,10 +1439,10 @@ public:
|
||||
return contains([](const TType* t) { return t->isOpaque(); } );
|
||||
}
|
||||
|
||||
// Recursively checks if the type contains an interstage IO builtin
|
||||
virtual bool containsBuiltInInterstageIO(EShLanguage language) const
|
||||
// Recursively checks if the type contains a built-in variable
|
||||
virtual bool containsBuiltIn() const
|
||||
{
|
||||
return contains([language](const TType* t) { return t->isBuiltInInterstageIO(language); } );
|
||||
return contains([](const TType* t) { return t->isBuiltIn(); } );
|
||||
}
|
||||
|
||||
virtual bool containsNonOpaque() const
|
||||
|
@ -1126,39 +1126,32 @@ TType& HlslParseContext::split(TType& type, TString name, const TType* outerStru
|
||||
// We can ignore arrayness: it's uninvolved.
|
||||
if (type.isStruct()) {
|
||||
TTypeList* userStructure = type.getWritableStruct();
|
||||
for (auto ioType = userStructure->begin(); ioType != userStructure->end(); ) {
|
||||
if (ioType->type->getQualifier().builtIn != EbvNone) {
|
||||
// split out built-in interstage IO
|
||||
const TType& memberType = *ioType->type;
|
||||
TVariable* ioVar = makeInternalVariable(name + (name.empty() ? "" : "_") + memberType.getFieldName(),
|
||||
memberType);
|
||||
|
||||
// Get iterator to (now at end) set of built-in interstage IO members
|
||||
const auto firstIo = std::stable_partition(userStructure->begin(), userStructure->end(),
|
||||
[this](const TTypeLoc& t) {
|
||||
return !t.type->isBuiltInInterstageIO(language);
|
||||
});
|
||||
if (arraySizes)
|
||||
ioVar->getWritableType().newArraySizes(*arraySizes);
|
||||
|
||||
// Move those to the built-in IO. However, we also propagate arrayness (just one level is handled
|
||||
// now) to this variable.
|
||||
for (auto ioType = firstIo; ioType != userStructure->end(); ++ioType) {
|
||||
const TType& memberType = *ioType->type;
|
||||
TVariable* ioVar = makeInternalVariable(name + (name.empty() ? "" : "_") + memberType.getFieldName(),
|
||||
memberType);
|
||||
fixBuiltInIoType(ioVar->getWritableType());
|
||||
|
||||
if (arraySizes)
|
||||
ioVar->getWritableType().newArraySizes(*arraySizes);
|
||||
interstageBuiltInIo[tInterstageIoData(memberType, *outerStructType)] = ioVar;
|
||||
|
||||
fixBuiltInIoType(ioVar->getWritableType());
|
||||
// Merge qualifier from the user structure
|
||||
mergeQualifiers(ioVar->getWritableType().getQualifier(), outerStructType->getQualifier());
|
||||
|
||||
interstageBuiltInIo[tInterstageIoData(memberType, *outerStructType)] = 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);
|
||||
} else {
|
||||
split(*ioType->type,
|
||||
name + (name.empty() ? "" : "_") + ioType->type->getFieldName(),
|
||||
outerStructType);
|
||||
++ioType;
|
||||
}
|
||||
}
|
||||
|
||||
// Erase the IO vars from the user structure.
|
||||
userStructure->erase(firstIo, userStructure->end());
|
||||
|
||||
// Recurse further into the members.
|
||||
for (unsigned int i = 0; i < userStructure->size(); ++i)
|
||||
split(*(*userStructure)[i].type,
|
||||
name + (name.empty() ? "" : "_") + (*userStructure)[i].type->getFieldName(),
|
||||
outerStructType);
|
||||
}
|
||||
|
||||
return type;
|
||||
@ -1556,7 +1549,7 @@ void HlslParseContext::addInterstageIoToLinkage()
|
||||
TVariable* var = interstageBuiltInIo[io[idx]];
|
||||
|
||||
// Add the loose interstage IO to the linkage
|
||||
if (var->getType().isLooseAndBuiltIn(language))
|
||||
if (! var->getType().isPerVertexBuiltIn(language))
|
||||
trackLinkage(*var);
|
||||
}
|
||||
}
|
||||
@ -1906,8 +1899,8 @@ TIntermNode* HlslParseContext::transformEntryPoint(const TSourceLoc& loc, TFunct
|
||||
if ((language == EShLangVertex && qualifier == EvqVaryingIn) ||
|
||||
(language == EShLangFragment && qualifier == EvqVaryingOut))
|
||||
flatten(variable);
|
||||
// Structs contain interstage IO must be split
|
||||
else if (variable.getType().containsBuiltInInterstageIO(language))
|
||||
// Structs containing built-ins must be split
|
||||
else if (variable.getType().containsBuiltIn())
|
||||
split(variable);
|
||||
}
|
||||
|
||||
@ -2530,7 +2523,7 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op
|
||||
|
||||
TIntermTyped* subTree;
|
||||
const TType derefType(node->getType(), member);
|
||||
if (split && derefType.isBuiltInInterstageIO(language)) {
|
||||
if (split && derefType.isBuiltIn()) {
|
||||
// copy from interstage IO built-in if needed
|
||||
const TIntermTyped* outer = isLeft ? outerLeft : outerRight;
|
||||
subTree = intermediate.addSymbol(*interstageBuiltInIo.find(
|
||||
@ -2644,8 +2637,8 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op
|
||||
assignList = intermediate.growAggregate(assignList, clipCullAssign, loc);
|
||||
|
||||
} else if (!isFlattenLeft && !isFlattenRight &&
|
||||
!typeL.containsBuiltInInterstageIO(language) &&
|
||||
!typeR.containsBuiltInInterstageIO(language)) {
|
||||
!typeL.containsBuiltIn() &&
|
||||
!typeR.containsBuiltIn()) {
|
||||
// If this is the final flattening (no nested types below to flatten)
|
||||
// we'll copy the member, else recurse into the type hierarchy.
|
||||
// However, if splitting the struct, that means we can copy a whole
|
||||
@ -2661,8 +2654,8 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op
|
||||
traverse(subLeft, subRight, subSplitLeft, subSplitRight);
|
||||
}
|
||||
|
||||
memberL += (typeL.isBuiltInInterstageIO(language) ? 0 : 1);
|
||||
memberR += (typeR.isBuiltInInterstageIO(language) ? 0 : 1);
|
||||
memberL += (typeL.isBuiltIn() ? 0 : 1);
|
||||
memberR += (typeR.isBuiltIn() ? 0 : 1);
|
||||
}
|
||||
} else {
|
||||
// Member copy
|
||||
@ -9197,7 +9190,7 @@ void HlslParseContext::addPatchConstantInvocation()
|
||||
TVariable* pcfOutput = makeInternalVariable("@patchConstantOutput", outType);
|
||||
pcfOutput->getWritableType().getQualifier().storage = EvqVaryingOut;
|
||||
|
||||
if (pcfOutput->getType().containsBuiltInInterstageIO(language))
|
||||
if (pcfOutput->getType().containsBuiltIn())
|
||||
split(*pcfOutput);
|
||||
|
||||
assignToInterface(*pcfOutput);
|
||||
|
Loading…
x
Reference in New Issue
Block a user