diff options
Diffstat (limited to 'src/3rdparty/angle/src/compiler/translator/Types.cpp')
-rw-r--r-- | src/3rdparty/angle/src/compiler/translator/Types.cpp | 1045 |
1 files changed, 919 insertions, 126 deletions
diff --git a/src/3rdparty/angle/src/compiler/translator/Types.cpp b/src/3rdparty/angle/src/compiler/translator/Types.cpp index 87fdfe0d54..530ffe3aeb 100644 --- a/src/3rdparty/angle/src/compiler/translator/Types.cpp +++ b/src/3rdparty/angle/src/compiler/translator/Types.cpp @@ -5,58 +5,394 @@ // #if defined(_MSC_VER) -#pragma warning(disable: 4718) +#pragma warning(disable : 4718) #endif #include "compiler/translator/Types.h" +#include "compiler/translator/InfoSink.h" +#include "compiler/translator/IntermNode.h" +#include "compiler/translator/SymbolTable.h" #include <algorithm> #include <climits> -const char* getBasicString(TBasicType t) +namespace sh +{ + +const char *getBasicString(TBasicType t) { switch (t) { - case EbtVoid: return "void"; break; - case EbtFloat: return "float"; break; - case EbtInt: return "int"; break; - case EbtUInt: return "uint"; break; - case EbtBool: return "bool"; break; - case EbtSampler2D: return "sampler2D"; break; - case EbtSampler3D: return "sampler3D"; break; - case EbtSamplerCube: return "samplerCube"; break; - case EbtSamplerExternalOES: return "samplerExternalOES"; break; - case EbtSampler2DRect: return "sampler2DRect"; break; - case EbtSampler2DArray: return "sampler2DArray"; break; - case EbtISampler2D: return "isampler2D"; break; - case EbtISampler3D: return "isampler3D"; break; - case EbtISamplerCube: return "isamplerCube"; break; - case EbtISampler2DArray: return "isampler2DArray"; break; - case EbtUSampler2D: return "usampler2D"; break; - case EbtUSampler3D: return "usampler3D"; break; - case EbtUSamplerCube: return "usamplerCube"; break; - case EbtUSampler2DArray: return "usampler2DArray"; break; - case EbtSampler2DShadow: return "sampler2DShadow"; break; - case EbtSamplerCubeShadow: return "samplerCubeShadow"; break; - case EbtSampler2DArrayShadow: return "sampler2DArrayShadow"; break; - case EbtStruct: return "structure"; break; - case EbtInterfaceBlock: return "interface block"; break; - default: UNREACHABLE(); return "unknown type"; + case EbtVoid: + return "void"; + case EbtFloat: + return "float"; + case EbtInt: + return "int"; + case EbtUInt: + return "uint"; + case EbtBool: + return "bool"; + case EbtYuvCscStandardEXT: + return "yuvCscStandardEXT"; + case EbtSampler2D: + return "sampler2D"; + case EbtSampler3D: + return "sampler3D"; + case EbtSamplerCube: + return "samplerCube"; + case EbtSamplerExternalOES: + return "samplerExternalOES"; + case EbtSamplerExternal2DY2YEXT: + return "__samplerExternal2DY2YEXT"; + case EbtSampler2DRect: + return "sampler2DRect"; + case EbtSampler2DArray: + return "sampler2DArray"; + case EbtSampler2DMS: + return "sampler2DMS"; + case EbtISampler2D: + return "isampler2D"; + case EbtISampler3D: + return "isampler3D"; + case EbtISamplerCube: + return "isamplerCube"; + case EbtISampler2DArray: + return "isampler2DArray"; + case EbtISampler2DMS: + return "isampler2DMS"; + case EbtUSampler2D: + return "usampler2D"; + case EbtUSampler3D: + return "usampler3D"; + case EbtUSamplerCube: + return "usamplerCube"; + case EbtUSampler2DArray: + return "usampler2DArray"; + case EbtUSampler2DMS: + return "usampler2DMS"; + case EbtSampler2DShadow: + return "sampler2DShadow"; + case EbtSamplerCubeShadow: + return "samplerCubeShadow"; + case EbtSampler2DArrayShadow: + return "sampler2DArrayShadow"; + case EbtStruct: + return "structure"; + case EbtInterfaceBlock: + return "interface block"; + case EbtImage2D: + return "image2D"; + case EbtIImage2D: + return "iimage2D"; + case EbtUImage2D: + return "uimage2D"; + case EbtImage3D: + return "image3D"; + case EbtIImage3D: + return "iimage3D"; + case EbtUImage3D: + return "uimage3D"; + case EbtImage2DArray: + return "image2DArray"; + case EbtIImage2DArray: + return "iimage2DArray"; + case EbtUImage2DArray: + return "uimage2DArray"; + case EbtImageCube: + return "imageCube"; + case EbtIImageCube: + return "iimageCube"; + case EbtUImageCube: + return "uimageCube"; + case EbtAtomicCounter: + return "atomic_uint"; + default: + UNREACHABLE(); + return "unknown type"; } } +// TType implementation. +TType::TType() + : type(EbtVoid), + precision(EbpUndefined), + qualifier(EvqGlobal), + invariant(false), + memoryQualifier(TMemoryQualifier::Create()), + layoutQualifier(TLayoutQualifier::Create()), + primarySize(0), + secondarySize(0), + mArraySizes(nullptr), + mInterfaceBlock(nullptr), + mStructure(nullptr), + mIsStructSpecifier(false), + mMangledName(nullptr) +{ +} + +TType::TType(TBasicType t, unsigned char ps, unsigned char ss) + : type(t), + precision(EbpUndefined), + qualifier(EvqGlobal), + invariant(false), + memoryQualifier(TMemoryQualifier::Create()), + layoutQualifier(TLayoutQualifier::Create()), + primarySize(ps), + secondarySize(ss), + mArraySizes(nullptr), + mInterfaceBlock(nullptr), + mStructure(nullptr), + mIsStructSpecifier(false), + mMangledName(nullptr) +{ +} + +TType::TType(TBasicType t, TPrecision p, TQualifier q, unsigned char ps, unsigned char ss) + : type(t), + precision(p), + qualifier(q), + invariant(false), + memoryQualifier(TMemoryQualifier::Create()), + layoutQualifier(TLayoutQualifier::Create()), + primarySize(ps), + secondarySize(ss), + mArraySizes(nullptr), + mInterfaceBlock(nullptr), + mStructure(nullptr), + mIsStructSpecifier(false), + mMangledName(nullptr) +{ +} + TType::TType(const TPublicType &p) - : type(p.type), precision(p.precision), qualifier(p.qualifier), invariant(p.invariant), - layoutQualifier(p.layoutQualifier), primarySize(p.primarySize), secondarySize(p.secondarySize), - array(p.array), arraySize(p.arraySize), interfaceBlock(0), structure(0) + : type(p.getBasicType()), + precision(p.precision), + qualifier(p.qualifier), + invariant(p.invariant), + memoryQualifier(p.memoryQualifier), + layoutQualifier(p.layoutQualifier), + primarySize(p.getPrimarySize()), + secondarySize(p.getSecondarySize()), + mArraySizes(nullptr), + mInterfaceBlock(nullptr), + mStructure(nullptr), + mIsStructSpecifier(false), + mMangledName(nullptr) { - if (p.userDef) - structure = p.userDef->getStruct(); + ASSERT(primarySize <= 4); + ASSERT(secondarySize <= 4); + if (p.isArray()) + { + mArraySizes = new TVector<unsigned int>(*p.arraySizes); + } + if (p.getUserDef()) + { + mStructure = p.getUserDef(); + mIsStructSpecifier = p.isStructSpecifier(); + } } -bool TStructure::equals(const TStructure &other) const +TType::TType(TStructure *userDef) + : type(EbtStruct), + precision(EbpUndefined), + qualifier(EvqTemporary), + invariant(false), + memoryQualifier(TMemoryQualifier::Create()), + layoutQualifier(TLayoutQualifier::Create()), + primarySize(1), + secondarySize(1), + mArraySizes(nullptr), + mInterfaceBlock(nullptr), + mStructure(userDef), + mIsStructSpecifier(false), + mMangledName(nullptr) { - return (uniqueId() == other.uniqueId()); +} + +TType::TType(TInterfaceBlock *interfaceBlockIn, + TQualifier qualifierIn, + TLayoutQualifier layoutQualifierIn) + : type(EbtInterfaceBlock), + precision(EbpUndefined), + qualifier(qualifierIn), + invariant(false), + memoryQualifier(TMemoryQualifier::Create()), + layoutQualifier(layoutQualifierIn), + primarySize(1), + secondarySize(1), + mArraySizes(nullptr), + mInterfaceBlock(interfaceBlockIn), + mStructure(0), + mIsStructSpecifier(false), + mMangledName(nullptr) +{ +} + +TType::TType(const TType &t) + : type(t.type), + precision(t.precision), + qualifier(t.qualifier), + invariant(t.invariant), + memoryQualifier(t.memoryQualifier), + layoutQualifier(t.layoutQualifier), + primarySize(t.primarySize), + secondarySize(t.secondarySize), + mArraySizes(t.mArraySizes ? new TVector<unsigned int>(*t.mArraySizes) : nullptr), + mInterfaceBlock(t.mInterfaceBlock), + mStructure(t.mStructure), + mIsStructSpecifier(t.mIsStructSpecifier), + mMangledName(t.mMangledName) +{ +} + +TType &TType::operator=(const TType &t) +{ + type = t.type; + precision = t.precision; + qualifier = t.qualifier; + invariant = t.invariant; + memoryQualifier = t.memoryQualifier; + layoutQualifier = t.layoutQualifier; + primarySize = t.primarySize; + secondarySize = t.secondarySize; + mArraySizes = t.mArraySizes ? new TVector<unsigned int>(*t.mArraySizes) : nullptr; + mInterfaceBlock = t.mInterfaceBlock; + mStructure = t.mStructure; + mIsStructSpecifier = t.mIsStructSpecifier; + mMangledName = t.mMangledName; + return *this; +} + +bool TType::canBeConstructed() const +{ + switch (type) + { + case EbtFloat: + case EbtInt: + case EbtUInt: + case EbtBool: + case EbtStruct: + return true; + default: + return false; + } +} + +const char *TType::getBuiltInTypeNameString() const +{ + if (isMatrix()) + { + switch (getCols()) + { + case 2: + switch (getRows()) + { + case 2: + return "mat2"; + case 3: + return "mat2x3"; + case 4: + return "mat2x4"; + default: + UNREACHABLE(); + return nullptr; + } + case 3: + switch (getRows()) + { + case 2: + return "mat3x2"; + case 3: + return "mat3"; + case 4: + return "mat3x4"; + default: + UNREACHABLE(); + return nullptr; + } + case 4: + switch (getRows()) + { + case 2: + return "mat4x2"; + case 3: + return "mat4x3"; + case 4: + return "mat4"; + default: + UNREACHABLE(); + return nullptr; + } + default: + UNREACHABLE(); + return nullptr; + } + } + if (isVector()) + { + switch (getBasicType()) + { + case EbtFloat: + switch (getNominalSize()) + { + case 2: + return "vec2"; + case 3: + return "vec3"; + case 4: + return "vec4"; + default: + UNREACHABLE(); + return nullptr; + } + case EbtInt: + switch (getNominalSize()) + { + case 2: + return "ivec2"; + case 3: + return "ivec3"; + case 4: + return "ivec4"; + default: + UNREACHABLE(); + return nullptr; + } + case EbtBool: + switch (getNominalSize()) + { + case 2: + return "bvec2"; + case 3: + return "bvec3"; + case 4: + return "bvec4"; + default: + UNREACHABLE(); + return nullptr; + } + case EbtUInt: + switch (getNominalSize()) + { + case 2: + return "uvec2"; + case 3: + return "uvec3"; + case 4: + return "uvec4"; + default: + UNREACHABLE(); + return nullptr; + } + default: + UNREACHABLE(); + return nullptr; + } + } + ASSERT(getBasicType() != EbtStruct); + ASSERT(getBasicType() != EbtInterfaceBlock); + return getBasicString(); } TString TType::getCompleteString() const @@ -69,8 +405,14 @@ TString TType::getCompleteString() const stream << getQualifierString() << " "; if (precision != EbpUndefined) stream << getPrecisionString() << " "; - if (array) - stream << "array[" << getArraySize() << "] of "; + if (mArraySizes) + { + for (auto arraySizeIter = mArraySizes->rbegin(); arraySizeIter != mArraySizes->rend(); + ++arraySizeIter) + { + stream << "array[" << (*arraySizeIter) << "] of "; + } + } if (isMatrix()) stream << getCols() << "X" << getRows() << " matrix of "; else if (isVector()) @@ -83,7 +425,7 @@ TString TType::getCompleteString() const // // Recursively generate mangled names. // -TString TType::buildMangledName() const +const char *TType::buildMangledName() const { TString mangledName; if (isMatrix()) @@ -93,78 +435,132 @@ TString TType::buildMangledName() const switch (type) { - case EbtFloat: - mangledName += 'f'; - break; - case EbtInt: - mangledName += 'i'; - break; - case EbtUInt: - mangledName += 'u'; - break; - case EbtBool: - mangledName += 'b'; - break; - case EbtSampler2D: - mangledName += "s2"; - break; - case EbtSampler3D: - mangledName += "s3"; - break; - case EbtSamplerCube: - mangledName += "sC"; - break; - case EbtSampler2DArray: - mangledName += "s2a"; - break; - case EbtSamplerExternalOES: - mangledName += "sext"; - break; - case EbtSampler2DRect: - mangledName += "s2r"; - break; - case EbtISampler2D: - mangledName += "is2"; - break; - case EbtISampler3D: - mangledName += "is3"; - break; - case EbtISamplerCube: - mangledName += "isC"; - break; - case EbtISampler2DArray: - mangledName += "is2a"; - break; - case EbtUSampler2D: - mangledName += "us2"; - break; - case EbtUSampler3D: - mangledName += "us3"; - break; - case EbtUSamplerCube: - mangledName += "usC"; - break; - case EbtUSampler2DArray: - mangledName += "us2a"; - break; - case EbtSampler2DShadow: - mangledName += "s2s"; - break; - case EbtSamplerCubeShadow: - mangledName += "sCs"; - break; - case EbtSampler2DArrayShadow: - mangledName += "s2as"; - break; - case EbtStruct: - mangledName += structure->mangledName(); - break; - case EbtInterfaceBlock: - mangledName += interfaceBlock->mangledName(); - break; - default: - // EbtVoid, EbtAddress and non types - break; + case EbtFloat: + mangledName += 'f'; + break; + case EbtInt: + mangledName += 'i'; + break; + case EbtUInt: + mangledName += 'u'; + break; + case EbtBool: + mangledName += 'b'; + break; + case EbtYuvCscStandardEXT: + mangledName += "ycs"; + break; + case EbtSampler2D: + mangledName += "s2"; + break; + case EbtSampler3D: + mangledName += "s3"; + break; + case EbtSamplerCube: + mangledName += "sC"; + break; + case EbtSampler2DArray: + mangledName += "s2a"; + break; + case EbtSamplerExternalOES: + mangledName += "sext"; + break; + case EbtSamplerExternal2DY2YEXT: + mangledName += "sext2y2y"; + break; + case EbtSampler2DRect: + mangledName += "s2r"; + break; + case EbtSampler2DMS: + mangledName += "s2ms"; + break; + case EbtISampler2D: + mangledName += "is2"; + break; + case EbtISampler3D: + mangledName += "is3"; + break; + case EbtISamplerCube: + mangledName += "isC"; + break; + case EbtISampler2DArray: + mangledName += "is2a"; + break; + case EbtISampler2DMS: + mangledName += "is2ms"; + break; + case EbtUSampler2D: + mangledName += "us2"; + break; + case EbtUSampler3D: + mangledName += "us3"; + break; + case EbtUSamplerCube: + mangledName += "usC"; + break; + case EbtUSampler2DArray: + mangledName += "us2a"; + break; + case EbtUSampler2DMS: + mangledName += "us2ms"; + break; + case EbtSampler2DShadow: + mangledName += "s2s"; + break; + case EbtSamplerCubeShadow: + mangledName += "sCs"; + break; + case EbtSampler2DArrayShadow: + mangledName += "s2as"; + break; + case EbtImage2D: + mangledName += "im2"; + break; + case EbtIImage2D: + mangledName += "iim2"; + break; + case EbtUImage2D: + mangledName += "uim2"; + break; + case EbtImage3D: + mangledName += "im3"; + break; + case EbtIImage3D: + mangledName += "iim3"; + break; + case EbtUImage3D: + mangledName += "uim3"; + break; + case EbtImage2DArray: + mangledName += "im2a"; + break; + case EbtIImage2DArray: + mangledName += "iim2a"; + break; + case EbtUImage2DArray: + mangledName += "uim2a"; + break; + case EbtImageCube: + mangledName += "imc"; + break; + case EbtIImageCube: + mangledName += "iimc"; + break; + case EbtUImageCube: + mangledName += "uimc"; + break; + case EbtAtomicCounter: + mangledName += "ac"; + break; + case EbtStruct: + mangledName += mStructure->mangledName(); + break; + case EbtInterfaceBlock: + mangledName += mInterfaceBlock->mangledName(); + break; + default: + // EbtVoid, EbtAddress and non types + break; } if (isMatrix()) @@ -178,15 +574,25 @@ TString TType::buildMangledName() const mangledName += static_cast<char>('0' + getNominalSize()); } - if (isArray()) + if (mArraySizes) { - char buf[20]; - snprintf(buf, sizeof(buf), "%d", arraySize); - mangledName += '['; - mangledName += buf; - mangledName += ']'; + for (unsigned int arraySize : *mArraySizes) + { + char buf[20]; + snprintf(buf, sizeof(buf), "%d", arraySize); + mangledName += '['; + mangledName += buf; + mangledName += ']'; + } } - return mangledName; + + mangledName += ';'; + + // Copy string contents into a pool-allocated buffer, so we never need to call delete. + size_t requiredSize = mangledName.size() + 1; + char *buffer = reinterpret_cast<char *>(GetGlobalPoolAllocator()->allocate(requiredSize)); + memcpy(buffer, mangledName.c_str(), requiredSize); + return buffer; } size_t TType::getObjectSize() const @@ -194,23 +600,265 @@ size_t TType::getObjectSize() const size_t totalSize; if (getBasicType() == EbtStruct) - totalSize = structure->objectSize(); + totalSize = mStructure->objectSize(); else totalSize = primarySize * secondarySize; - if (isArray()) + if (totalSize == 0) + return 0; + + if (mArraySizes) { - // TODO: getArraySize() returns an int, not a size_t - size_t currentArraySize = getArraySize(); - if (currentArraySize > INT_MAX / totalSize) - totalSize = INT_MAX; - else - totalSize *= currentArraySize; + for (size_t arraySize : *mArraySizes) + { + if (arraySize > INT_MAX / totalSize) + totalSize = INT_MAX; + else + totalSize *= arraySize; + } } return totalSize; } +int TType::getLocationCount() const +{ + int count = 1; + + if (getBasicType() == EbtStruct) + { + count = mStructure->getLocationCount(); + } + + if (count == 0) + { + return 0; + } + + if (mArraySizes) + { + for (unsigned int arraySize : *mArraySizes) + { + if (arraySize > static_cast<unsigned int>(std::numeric_limits<int>::max() / count)) + { + count = std::numeric_limits<int>::max(); + } + else + { + count *= static_cast<int>(arraySize); + } + } + } + + return count; +} + +unsigned int TType::getArraySizeProduct() const +{ + if (!mArraySizes) + return 1u; + + unsigned int product = 1u; + + for (unsigned int arraySize : *mArraySizes) + { + product *= arraySize; + } + return product; +} + +bool TType::isUnsizedArray() const +{ + if (!mArraySizes) + return false; + + for (unsigned int arraySize : *mArraySizes) + { + if (arraySize == 0u) + { + return true; + } + } + return false; +} + +bool TType::sameNonArrayType(const TType &right) const +{ + return (type == right.type && primarySize == right.primarySize && + secondarySize == right.secondarySize && mStructure == right.mStructure); +} + +bool TType::isElementTypeOf(const TType &arrayType) const +{ + if (!sameNonArrayType(arrayType)) + { + return false; + } + if (arrayType.getNumArraySizes() != getNumArraySizes() + 1u) + { + return false; + } + if (isArray()) + { + for (size_t i = 0; i < mArraySizes->size(); ++i) + { + if ((*mArraySizes)[i] != (*arrayType.mArraySizes)[i]) + { + return false; + } + } + } + return true; +} + +void TType::sizeUnsizedArrays(const TVector<unsigned int> *newArraySizes) +{ + size_t newArraySizesSize = newArraySizes ? newArraySizes->size() : 0; + for (size_t i = 0u; i < getNumArraySizes(); ++i) + { + if ((*mArraySizes)[i] == 0) + { + if (i < newArraySizesSize) + { + ASSERT(newArraySizes != nullptr); + (*mArraySizes)[i] = (*newArraySizes)[i]; + } + else + { + (*mArraySizes)[i] = 1u; + } + } + } + invalidateMangledName(); +} + +void TType::sizeOutermostUnsizedArray(unsigned int arraySize) +{ + ASSERT(isArray()); + ASSERT(mArraySizes->back() == 0u); + mArraySizes->back() = arraySize; +} + +void TType::setBasicType(TBasicType t) +{ + if (type != t) + { + type = t; + invalidateMangledName(); + } +} + +void TType::setPrimarySize(unsigned char ps) +{ + if (primarySize != ps) + { + ASSERT(ps <= 4); + primarySize = ps; + invalidateMangledName(); + } +} + +void TType::setSecondarySize(unsigned char ss) +{ + if (secondarySize != ss) + { + ASSERT(ss <= 4); + secondarySize = ss; + invalidateMangledName(); + } +} + +void TType::makeArray(unsigned int s) +{ + if (!mArraySizes) + mArraySizes = new TVector<unsigned int>(); + + mArraySizes->push_back(s); + invalidateMangledName(); +} + +void TType::makeArrays(const TVector<unsigned int> &sizes) +{ + if (!mArraySizes) + mArraySizes = new TVector<unsigned int>(); + + mArraySizes->insert(mArraySizes->end(), sizes.begin(), sizes.end()); + invalidateMangledName(); +} + +void TType::setArraySize(size_t arrayDimension, unsigned int s) +{ + ASSERT(mArraySizes != nullptr); + ASSERT(arrayDimension < mArraySizes->size()); + if (mArraySizes->at(arrayDimension) != s) + { + (*mArraySizes)[arrayDimension] = s; + invalidateMangledName(); + } +} + +void TType::toArrayElementType() +{ + ASSERT(mArraySizes != nullptr); + if (mArraySizes->size() > 0) + { + mArraySizes->pop_back(); + invalidateMangledName(); + } +} + +void TType::setInterfaceBlock(TInterfaceBlock *interfaceBlockIn) +{ + if (mInterfaceBlock != interfaceBlockIn) + { + mInterfaceBlock = interfaceBlockIn; + invalidateMangledName(); + } +} + +void TType::setStruct(TStructure *s) +{ + if (mStructure != s) + { + mStructure = s; + invalidateMangledName(); + } +} + +const char *TType::getMangledName() const +{ + if (mMangledName == nullptr) + { + mMangledName = buildMangledName(); + } + + return mMangledName; +} + +void TType::realize() +{ + getMangledName(); +} + +void TType::invalidateMangledName() +{ + mMangledName = nullptr; +} + +// TStructure implementation. +TStructure::TStructure(TSymbolTable *symbolTable, const TString *name, TFieldList *fields) + : TFieldListCollection(name, fields), + mDeepestNesting(0), + mUniqueId(symbolTable->nextUniqueId()), + mAtGlobalScope(false) +{ +} + +bool TStructure::equals(const TStructure &other) const +{ + return (uniqueId() == other.uniqueId()); +} + bool TStructure::containsArrays() const { for (size_t i = 0; i < mFields->size(); ++i) @@ -244,6 +892,66 @@ bool TStructure::containsSamplers() const return false; } +void TType::createSamplerSymbols(const TString &namePrefix, + const TString &apiNamePrefix, + TVector<TIntermSymbol *> *outputSymbols, + TMap<TIntermSymbol *, TString> *outputSymbolsToAPINames, + TSymbolTable *symbolTable) const +{ + if (isStructureContainingSamplers()) + { + if (isArray()) + { + TType elementType(*this); + elementType.toArrayElementType(); + for (unsigned int arrayIndex = 0u; arrayIndex < getOutermostArraySize(); ++arrayIndex) + { + TStringStream elementName; + elementName << namePrefix << "_" << arrayIndex; + TStringStream elementApiName; + elementApiName << apiNamePrefix << "[" << arrayIndex << "]"; + elementType.createSamplerSymbols(elementName.str(), elementApiName.str(), + outputSymbols, outputSymbolsToAPINames, + symbolTable); + } + } + else + { + mStructure->createSamplerSymbols(namePrefix, apiNamePrefix, outputSymbols, + outputSymbolsToAPINames, symbolTable); + } + return; + } + + ASSERT(IsSampler(type)); + TIntermSymbol *symbol = new TIntermSymbol(symbolTable->nextUniqueId(), namePrefix, *this); + outputSymbols->push_back(symbol); + if (outputSymbolsToAPINames) + { + (*outputSymbolsToAPINames)[symbol] = apiNamePrefix; + } +} + +void TStructure::createSamplerSymbols(const TString &namePrefix, + const TString &apiNamePrefix, + TVector<TIntermSymbol *> *outputSymbols, + TMap<TIntermSymbol *, TString> *outputSymbolsToAPINames, + TSymbolTable *symbolTable) const +{ + ASSERT(containsSamplers()); + for (auto &field : *mFields) + { + const TType *fieldType = field->type(); + if (IsSampler(fieldType->getBasicType()) || fieldType->isStructureContainingSamplers()) + { + TString fieldName = namePrefix + "_" + field->name(); + TString fieldApiName = apiNamePrefix + "." + field->name(); + fieldType->createSamplerSymbols(fieldName, fieldApiName, outputSymbols, + outputSymbolsToAPINames, symbolTable); + } + } +} + TString TFieldListCollection::buildMangledName(const TString &mangledNamePrefix) const { TString mangledName(mangledNamePrefix); @@ -259,9 +967,9 @@ TString TFieldListCollection::buildMangledName(const TString &mangledNamePrefix) size_t TFieldListCollection::calculateObjectSize() const { size_t size = 0; - for (size_t i = 0; i < mFields->size(); ++i) + for (const TField *field : *mFields) { - size_t fieldSize = (*mFields)[i]->type()->getObjectSize(); + size_t fieldSize = field->type()->getObjectSize(); if (fieldSize > INT_MAX - size) size = INT_MAX; else @@ -270,6 +978,24 @@ size_t TFieldListCollection::calculateObjectSize() const return size; } +int TFieldListCollection::getLocationCount() const +{ + int count = 0; + for (const TField *field : *mFields) + { + int fieldCount = field->type()->getLocationCount(); + if (fieldCount > std::numeric_limits<int>::max() - count) + { + count = std::numeric_limits<int>::max(); + } + else + { + count += fieldCount; + } + } + return count; +} + int TStructure::calculateDeepestNesting() const { int maxNesting = 0; @@ -277,3 +1003,70 @@ int TStructure::calculateDeepestNesting() const maxNesting = std::max(maxNesting, (*mFields)[i]->type()->getDeepestStructNesting()); return 1 + maxNesting; } + +// TPublicType implementation. +void TPublicType::initialize(const TTypeSpecifierNonArray &typeSpecifier, TQualifier q) +{ + typeSpecifierNonArray = typeSpecifier; + layoutQualifier = TLayoutQualifier::Create(); + memoryQualifier = TMemoryQualifier::Create(); + qualifier = q; + invariant = false; + precision = EbpUndefined; + arraySizes = nullptr; +} + +void TPublicType::initializeBasicType(TBasicType basicType) +{ + typeSpecifierNonArray.type = basicType; + typeSpecifierNonArray.primarySize = 1; + typeSpecifierNonArray.secondarySize = 1; + layoutQualifier = TLayoutQualifier::Create(); + memoryQualifier = TMemoryQualifier::Create(); + qualifier = EvqTemporary; + invariant = false; + precision = EbpUndefined; + arraySizes = nullptr; +} + +bool TPublicType::isStructureContainingArrays() const +{ + if (!typeSpecifierNonArray.userDef) + { + return false; + } + + return typeSpecifierNonArray.userDef->containsArrays(); +} + +bool TPublicType::isStructureContainingType(TBasicType t) const +{ + if (!typeSpecifierNonArray.userDef) + { + return false; + } + + return typeSpecifierNonArray.userDef->containsType(t); +} + +void TPublicType::setArraySizes(TVector<unsigned int> *sizes) +{ + arraySizes = sizes; +} + +bool TPublicType::isArray() const +{ + return arraySizes && !arraySizes->empty(); +} + +void TPublicType::clearArrayness() +{ + arraySizes = nullptr; +} + +bool TPublicType::isAggregate() const +{ + return isArray() || typeSpecifierNonArray.isMatrix() || typeSpecifierNonArray.isVector(); +} + +} // namespace sh |