diff --git a/glslang/MachineIndependent/iomapper.cpp b/glslang/MachineIndependent/iomapper.cpp index 9585627086edfabb601b40a7947db2b3d64cdceb..fc85e97898c76f79d336747954e208df85d47206 100644 --- a/glslang/MachineIndependent/iomapper.cpp +++ b/glslang/MachineIndependent/iomapper.cpp @@ -423,14 +423,14 @@ struct TDefaultIoResolverBase : public glslang::TIoMapResolver return -1; // 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; // no locations on blocks of built-in variables if (type.isStruct()) { if (type.getStruct()->size() < 1) return -1; - if ((*type.getStruct())[0].type->getQualifier().builtIn != EbvNone) + if ((*type.getStruct())[0].type->isBuiltIn()) return -1; } diff --git a/hlsl/hlslGrammar.cpp b/hlsl/hlslGrammar.cpp index 05c95d36ae167a07fc9f11769b68fef959ddd146..0e8614cf37f36f7c133a1ffa575e3ecb6ff3809a 100755 --- a/hlsl/hlslGrammar.cpp +++ b/hlsl/hlslGrammar.cpp @@ -616,7 +616,7 @@ bool HlslGrammar::acceptFullySpecifiedType(TType& type, TIntermNode*& nodeList) qualifier.readonly = type.getQualifier().readonly; } - if (type.getQualifier().builtIn != EbvNone) + if (type.isBuiltIn()) qualifier.builtIn = type.getQualifier().builtIn; type.getQualifier() = qualifier; diff --git a/hlsl/hlslParseHelper.cpp b/hlsl/hlslParseHelper.cpp index 32d106791d60a4ffd204dd433a1aa306a5868607..9915de5026bca40cb37564c45427f64f805cf526 100755 --- a/hlsl/hlslParseHelper.cpp +++ b/hlsl/hlslParseHelper.cpp @@ -1121,58 +1121,51 @@ bool HlslParseContext::isBuiltInMethod(const TSourceLoc&, TIntermTyped* base, co 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 // 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) { // 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); } // Recursive implementation of split(). // 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()) { 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); - - 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. + if (ioType->type->isBuiltIn()) { + // move out the built-in + splitBuiltIn(name, *ioType->type, type.getArraySizes(), outerQualifier); ioType = userStructure->erase(ioType); } else { - split(*ioType->type, - name + (name.empty() ? "" : "_") + ioType->type->getFieldName(), - outerStructType); + split(*ioType->type, name + (name.empty() ? "" : "_") + ioType->type->getFieldName(), outerQualifier); ++ioType; } } @@ -1258,10 +1251,9 @@ int HlslParseContext::addFlattenedMember(const TVariable& variable, const TType& if (flattenData.nextBinding != TQualifier::layoutBindingEnd) memberVariable->getWritableType().getQualifier().layoutBinding = flattenData.nextBinding++; - if (memberVariable->getType().getQualifier().builtIn == EbvNone) { + if (!memberVariable->getType().isBuiltIn()) { // inherited locations must be auto bumped, not replicated - if (flattenData.nextLocation != TQualifier::layoutLocationEnd && - memberVariable->getType().getQualifier().builtIn == EbvNone) { + if (flattenData.nextLocation != TQualifier::layoutLocationEnd) { memberVariable->getWritableType().getQualifier().layoutLocation = flattenData.nextLocation; flattenData.nextLocation += intermediate.computeTypeLocationSize(memberVariable->getType()); nextOutLocation = std::max(nextOutLocation, flattenData.nextLocation); @@ -2530,8 +2522,10 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op if (split && derefType.isBuiltIn()) { // copy from interstage IO built-in if needed const TIntermTyped* outer = isLeft ? outerLeft : outerRight; - subTree = intermediate.addSymbol(*splitBuiltIns.find( - HlslParseContext::tInterstageIoData(derefType, outer->getType()))->second); + subTree = intermediate.addSymbol( + *splitBuiltIns.find(HlslParseContext::tInterstageIoData( + derefType.getQualifier().builtIn, + outer->getType().getQualifier().storage))->second); // Arrayness of builtIn symbols isn't handled by the normal recursion: // it's been extracted and moved to the built-in. diff --git a/hlsl/hlslParseHelper.h b/hlsl/hlslParseHelper.h index b615a13e9c7f35f128363bbab2ae3e8287b7f2f1..9a30e0ae348948934241279635eb52bd1668dc3e 100755 --- a/hlsl/hlslParseHelper.h +++ b/hlsl/hlslParseHelper.h @@ -252,8 +252,9 @@ protected: bool isFinalFlattening(const TType& type) const { return !(type.isStruct() || type.isArray()); } // 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 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(int id) const { return splitNonIoVars.find(id) != splitNonIoVars.end(); } TVariable* getSplitNonIoVar(int id) const; @@ -393,10 +394,6 @@ protected: tInterstageIoData(TBuiltInVariable bi, TStorageQualifier q) : builtIn(bi), storage(q) { } - tInterstageIoData(const TType& memberType, const TType& storageType) : - builtIn(memberType.getQualifier().builtIn), - storage(storageType.getQualifier().storage) { } - TBuiltInVariable builtIn; TStorageQualifier storage;