//
// Copyright 2020 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

#include <algorithm>
#include <cstring>
#include <functional>
#include <numeric>
#include <unordered_map>
#include <unordered_set>

#include "compiler/translator/Compiler.h"
#include "compiler/translator/ImmutableStringBuilder.h"
#include "compiler/translator/msl/AstHelpers.h"
#include "compiler/translator/msl/ModifyStruct.h"
#include "compiler/translator/msl/TranslatorMSL.h"
#include "compiler/translator/tree_util/IntermNode_util.h"

using namespace sh;

////////////////////////////////////////////////////////////////////////////////

size_t ModifiedStructMachineries::size() const
{
    return ordering.size();
}

const ModifiedStructMachinery &ModifiedStructMachineries::at(size_t index) const
{
    ASSERT(index < size());
    const TStructure *s              = ordering[index];
    const ModifiedStructMachinery *m = find(*s);
    ASSERT(m);
    return *m;
}

const ModifiedStructMachinery *ModifiedStructMachineries::find(const TStructure &s) const
{
    auto iter = originalToMachinery.find(&s);
    if (iter == originalToMachinery.end())
    {
        return nullptr;
    }
    return &iter->second;
}

void ModifiedStructMachineries::insert(const TStructure &s,
                                       const ModifiedStructMachinery &machinery)
{
    ASSERT(!find(s));
    originalToMachinery[&s] = machinery;
    ordering.push_back(&s);
}

////////////////////////////////////////////////////////////////////////////////

namespace
{

TIntermTyped &Flatten(SymbolEnv &symbolEnv, TIntermTyped &node)
{
    auto &type = node.getType();
    ASSERT(type.isArray());

    auto &retType = InnermostType(type);
    retType.makeArray(1);

    return symbolEnv.callFunctionOverload(Name("flatten"), retType, *new TIntermSequence{&node});
}

struct FlattenArray
{};

struct PathItem
{
    enum class Type
    {
        Field,         // Struct field indexing.
        Index,         // Array, vector, or matrix indexing.
        FlattenArray,  // Array of any rank -> pointer of innermost type.
    };

    PathItem(const TField &field) : field(&field), type(Type::Field) {}
    PathItem(int index) : index(index), type(Type::Index) {}
    PathItem(unsigned index) : PathItem(static_cast<int>(index)) {}
    PathItem(FlattenArray flatten) : type(Type::FlattenArray) {}

    union
    {
        const TField *field;
        int index;
    };
    Type type;
};

TIntermTyped &BuildPathAccess(SymbolEnv &symbolEnv,
                              const TVariable &var,
                              const std::vector<PathItem> &path)
{
    TIntermTyped *curr = new TIntermSymbol(&var);
    for (const PathItem &item : path)
    {
        switch (item.type)
        {
            case PathItem::Type::Field:
                curr = &AccessField(*curr, Name(*item.field));
                break;
            case PathItem::Type::Index:
                curr = &AccessIndex(*curr, item.index);
                break;
            case PathItem::Type::FlattenArray:
            {
                curr = &Flatten(symbolEnv, *curr);
            }
            break;
        }
    }
    return *curr;
}

////////////////////////////////////////////////////////////////////////////////

using OriginalParam = const TVariable &;
using ModifiedParam = const TVariable &;

using OriginalAccess = TIntermTyped;
using ModifiedAccess = TIntermTyped;

struct Access
{
    OriginalAccess &original;
    ModifiedAccess &modified;

    struct Env
    {
        const ConvertType type;
    };
};

using ConversionFunc = std::function<Access(Access::Env &, OriginalAccess &, ModifiedAccess &)>;

class ConvertStructState : angle::NonCopyable
{
  private:
    struct ConversionInfo
    {
        ConversionFunc stdFunc;
        const TFunction *astFunc;
        std::vector<PathItem> pathItems;
        Name modifiedFieldName;
    };

  public:
    ConvertStructState(TCompiler &compiler,
                       SymbolEnv &symbolEnv,
                       IdGen &idGen,
                       const ModifyStructConfig &config,
                       ModifiedStructMachineries &outMachineries,
                       const bool isUBO,
                       const bool useAttributeAliasing)
        : mCompiler(compiler),
          config(config),
          symbolEnv(symbolEnv),
          modifiedFields(*new TFieldList()),
          symbolTable(symbolEnv.symbolTable()),
          idGen(idGen),
          outMachineries(outMachineries),
          isUBO(isUBO),
          useAttributeAliasing(useAttributeAliasing)
    {}

    ~ConvertStructState()
    {
    }

    void publish(const TStructure &originalStruct, const Name &modifiedStructName)
    {
        const bool isOriginalToModified = config.convertType == ConvertType::OriginalToModified;

        auto &modifiedStruct = *new TStructure(&symbolTable, modifiedStructName.rawName(),
                                               &modifiedFields, modifiedStructName.symbolType());

        auto &func = *new TFunction(
            &symbolTable,
            idGen.createNewName(isOriginalToModified ? "originalToModified" : "modifiedToOriginal")
                .rawName(),
            SymbolType::AngleInternal, new TType(TBasicType::EbtVoid), false);

        OriginalParam originalParam =
            CreateInstanceVariable(symbolTable, originalStruct, Name("original"));
        ModifiedParam modifiedParam =
            CreateInstanceVariable(symbolTable, modifiedStruct, Name("modified"));

        symbolEnv.markAsReference(originalParam, AddressSpace::Thread);
        symbolEnv.markAsReference(modifiedParam, config.externalAddressSpace);
        if (isOriginalToModified)
        {
            func.addParameter(&originalParam);
            func.addParameter(&modifiedParam);
        }
        else
        {
            func.addParameter(&modifiedParam);
            func.addParameter(&originalParam);
        }

        TIntermBlock &body = *new TIntermBlock();

        Access::Env env{config.convertType};

        for (ConversionInfo &info : conversionInfos)
        {
            auto convert = [&](OriginalAccess &original, ModifiedAccess &modified) {
                if (info.astFunc)
                {
                    ASSERT(!info.stdFunc);
                    TIntermTyped &src  = isOriginalToModified ? modified : original;
                    TIntermTyped &dest = isOriginalToModified ? original : modified;
                    body.appendStatement(TIntermAggregate::CreateFunctionCall(
                        *info.astFunc, new TIntermSequence{&dest, &src}));
                }
                else
                {
                    ASSERT(info.stdFunc);
                    Access access      = info.stdFunc(env, original, modified);
                    TIntermTyped &src  = isOriginalToModified ? access.original : access.modified;
                    TIntermTyped &dest = isOriginalToModified ? access.modified : access.original;
                    body.appendStatement(new TIntermBinary(TOperator::EOpAssign, &dest, &src));
                }
            };
            OriginalAccess *original = &BuildPathAccess(symbolEnv, originalParam, info.pathItems);
            ModifiedAccess *modified = &AccessField(modifiedParam, info.modifiedFieldName);
            if (useAttributeAliasing)
            {
                std::ostringstream aliasedName;
                aliasedName << "ANGLE_ALIASED_" << info.modifiedFieldName;

                TType *placeholderType = new TType(modified->getType());
                placeholderType->setQualifier(EvqSpecConst);

                modified = new TIntermSymbol(
                    new TVariable(&symbolTable, sh::ImmutableString(aliasedName.str()),
                                  placeholderType, SymbolType::AngleInternal));
            }
            const TType ot = original->getType();
            const TType mt = modified->getType();
            ASSERT(ot.isArray() == mt.isArray());

            // Clip distance output uses float[n] type, so the field must be assigned per-element
            // when filling the modified struct. Explicit path name is used because original types
            // are not available here.
            if (ot.isArray() &&
                (ot.getLayoutQualifier().matrixPacking == EmpRowMajor || ot != mt ||
                 info.modifiedFieldName == Name("gl_ClipDistance", SymbolType::BuiltIn)))
            {
                ASSERT(ot.getArraySizes() == mt.getArraySizes());
                if (ot.isArrayOfArrays())
                {
                    original = &Flatten(symbolEnv, *original);
                    modified = &Flatten(symbolEnv, *modified);
                }
                const int volume = static_cast<int>(ot.getArraySizeProduct());
                for (int i = 0; i < volume; ++i)
                {
                    if (i != 0)
                    {
                        original = original->deepCopy();
                        modified = modified->deepCopy();
                    }
                    OriginalAccess &o = AccessIndex(*original, i);
                    OriginalAccess &m = AccessIndex(*modified, i);
                    convert(o, m);
                }
            }
            else
            {
                convert(*original, *modified);
            }
        }

        auto *funcProto = new TIntermFunctionPrototype(&func);
        auto *funcDef   = new TIntermFunctionDefinition(funcProto, &body);

        ModifiedStructMachinery machinery;
        machinery.modifiedStruct                   = &modifiedStruct;
        machinery.getConverter(config.convertType) = funcDef;

        outMachineries.insert(originalStruct, machinery);
    }

    ImmutableString rootFieldName() const
    {
        if (!pathItems.empty())
        {
            if (pathItems[0].type == PathItem::Type::Field)
            {
                return pathItems[0].field->name();
            }
        }
        UNREACHABLE();
        return kEmptyImmutableString;
    }

    void pushPath(PathItem const &item) { pathItems.push_back(item); }

    void popPath()
    {
        ASSERT(!pathItems.empty());
        pathItems.pop_back();
        if (pathItems.empty())
        {
            // Next push will start a new root output variable to linearize.
            mSubfieldIndex = 0;
        }
    }

    void finalize(const bool allowPadding)
    {
        ASSERT(!finalized);
        finalized = true;
        introducePacking();
        ASSERT(metalLayoutTotal == Layout::Identity());
        // Only pad substructs. We don't want to pad the structure that contains all the UBOs, only
        // individual UBOs.
        if (allowPadding)
            introducePadding();
    }

    void addModifiedField(const TField &field,
                          TType &newType,
                          TLayoutBlockStorage storage,
                          TLayoutMatrixPacking packing,
                          const AddressSpace *addressSpace)
    {
        TLayoutQualifier layoutQualifier = newType.getLayoutQualifier();
        layoutQualifier.blockStorage     = storage;
        layoutQualifier.matrixPacking    = packing;
        newType.setLayoutQualifier(layoutQualifier);
        sh::ImmutableString newName  = field.name();
        sh::SymbolType newSymbolType = field.symbolType();
        if (pathItems.size() > 1)
        {
            // Current state is linearizing a root input field into multiple modified fields. The
            // new fields need unique names. Generate the new names into AngleInternal namespace.
            // The user could choose a clashing name in UserDefined namespace.
            newSymbolType = SymbolType::AngleInternal;
            // The user specified root field name is currently used as the basis for the MSL vs-fs
            // interface matching. The field linearization itself is deterministic, so subfield
            // index is sufficient to define all the entries in MSL interface in all the compatible
            // VS and FS MSL programs.
            newName = BuildConcatenatedImmutableString(rootFieldName(), '_', mSubfieldIndex);
            ++mSubfieldIndex;
        }
        TField *modifiedField = new TField(&newType, newName, field.line(), newSymbolType);
        if (addressSpace)
        {
            symbolEnv.markAsPointer(*modifiedField, *addressSpace);
        }
        if (symbolEnv.isUBO(field))
        {
            symbolEnv.markAsUBO(*modifiedField);
        }
        modifiedFields.push_back(modifiedField);
    }

    void addConversion(const ConversionFunc &func)
    {
        ASSERT(!modifiedFields.empty());
        conversionInfos.push_back({func, nullptr, pathItems, Name(*modifiedFields.back())});
    }

    void addConversion(const TFunction &func)
    {
        ASSERT(!modifiedFields.empty());
        conversionInfos.push_back({{}, &func, pathItems, Name(*modifiedFields.back())});
    }

    bool hasPacking() const { return containsPacked; }

    bool hasPadding() const { return padFieldCount > 0; }

    bool recurse(const TStructure &structure,
                 ModifiedStructMachinery &outMachinery,
                 const bool isUBORecurse)
    {
        const ModifiedStructMachinery *m = outMachineries.find(structure);
        if (m == nullptr)
        {
            TranslatorMetalReflection *reflection = mtl::getTranslatorMetalReflection(&mCompiler);
            reflection->addOriginalName(structure.uniqueId().get(), structure.name().data());
            const Name name = idGen.createNewName(structure.name().data());
            if (!TryCreateModifiedStruct(mCompiler, symbolEnv, idGen, config, structure, name,
                                         outMachineries, isUBORecurse, config.allowPadding, false))
            {
                return false;
            }
            m = outMachineries.find(structure);
            ASSERT(m);
        }
        outMachinery = *m;
        return true;
    }

    bool getIsUBO() const { return isUBO; }

  private:
    void addPadding(size_t padAmount, bool updateLayout)
    {
        if (padAmount == 0)
        {
            return;
        }

        const size_t begin = modifiedFields.size();

        // Iteratively adding in scalar or vector padding because some struct types will not
        // allow matrix or array members.
        while (padAmount > 0)
        {
            TType *padType;
            if (padAmount >= 16)
            {
                padAmount -= 16;
                padType = new TType(TBasicType::EbtFloat, 4);
            }
            else if (padAmount >= 8)
            {
                padAmount -= 8;
                padType = new TType(TBasicType::EbtFloat, 2);
            }
            else if (padAmount >= 4)
            {
                padAmount -= 4;
                padType = new TType(TBasicType::EbtFloat);
            }
            else if (padAmount >= 2)
            {
                padAmount -= 2;
                padType = new TType(TBasicType::EbtBool, 2);
            }
            else
            {
                ASSERT(padAmount == 1);
                padAmount -= 1;
                padType = new TType(TBasicType::EbtBool);
            }

            if (padType->getBasicType() != EbtBool)
            {
                padType->setPrecision(EbpLow);
            }

            if (updateLayout)
            {
                metalLayoutTotal += MetalLayoutOf(*padType);
            }

            const Name name = idGen.createNewName("pad");
            modifiedFields.push_back(
                new TField(padType, name.rawName(), kNoSourceLoc, name.symbolType()));
            ++padFieldCount;
        }

        std::reverse(modifiedFields.begin() + begin, modifiedFields.end());
    }

    void introducePacking()
    {
        if (!config.allowPacking)
        {
            return;
        }

        auto setUnpackedStorage = [](TType &type) {
            TLayoutBlockStorage storage = type.getLayoutQualifier().blockStorage;
            switch (storage)
            {
                case TLayoutBlockStorage::EbsShared:
                    storage = TLayoutBlockStorage::EbsStd140;
                    break;
                case TLayoutBlockStorage::EbsPacked:
                    storage = TLayoutBlockStorage::EbsStd430;
                    break;
                case TLayoutBlockStorage::EbsStd140:
                case TLayoutBlockStorage::EbsStd430:
                case TLayoutBlockStorage::EbsUnspecified:
                    break;
            }
            SetBlockStorage(type, storage);
        };

        Layout glslLayoutTotal = Layout::Identity();
        const size_t size      = modifiedFields.size();

        for (size_t i = 0; i < size; ++i)
        {
            TField &curr           = *modifiedFields[i];
            TType &currType        = *curr.type();
            const bool canBePacked = CanBePacked(currType);

            auto dontPack = [&]() {
                if (canBePacked)
                {
                    setUnpackedStorage(currType);
                }
                glslLayoutTotal += GlslLayoutOf(currType);
            };

            if (!CanBePacked(currType))
            {
                dontPack();
                continue;
            }

            const Layout packedGlslLayout           = GlslLayoutOf(currType);
            const TLayoutBlockStorage packedStorage = currType.getLayoutQualifier().blockStorage;
            setUnpackedStorage(currType);
            const Layout unpackedGlslLayout = GlslLayoutOf(currType);
            SetBlockStorage(currType, packedStorage);

            ASSERT(packedGlslLayout.sizeOf <= unpackedGlslLayout.sizeOf);
            if (packedGlslLayout.sizeOf == unpackedGlslLayout.sizeOf)
            {
                dontPack();
                continue;
            }

            const size_t j = i + 1;
            if (j == size)
            {
                dontPack();
                break;
            }

            const size_t pad            = unpackedGlslLayout.sizeOf - packedGlslLayout.sizeOf;
            const TField &next          = *modifiedFields[j];
            const Layout nextGlslLayout = GlslLayoutOf(*next.type());

            if (pad < nextGlslLayout.sizeOf)
            {
                dontPack();
                continue;
            }

            symbolEnv.markAsPacked(curr);
            glslLayoutTotal += packedGlslLayout;
            containsPacked = true;
        }
    }

    void introducePadding()
    {
        if (!config.allowPadding)
        {
            return;
        }

        MetalLayoutOfConfig layoutConfig;
        layoutConfig.disablePacking             = !config.allowPacking;
        layoutConfig.assumeStructsAreTailPadded = true;

        TFieldList fields = std::move(modifiedFields);
        ASSERT(!fields.empty());  // GLSL requires at least one member.

        const TField *const first = fields.front();

        for (TField *field : fields)
        {
            const TType &type = *field->type();

            const Layout glslLayout  = GlslLayoutOf(type);
            const Layout metalLayout = MetalLayoutOf(type, layoutConfig);

            size_t prePadAmount = 0;
            if (glslLayout.alignOf > metalLayout.alignOf && field != first)
            {
                const size_t prePaddedSize = metalLayoutTotal.sizeOf;
                metalLayoutTotal.requireAlignment(glslLayout.alignOf, true);
                const size_t paddedSize = metalLayoutTotal.sizeOf;
                prePadAmount            = paddedSize - prePaddedSize;
                metalLayoutTotal += metalLayout;
                addPadding(prePadAmount, false);  // Note: requireAlignment() already updated layout
            }
            else
            {
                metalLayoutTotal += metalLayout;
            }

            modifiedFields.push_back(field);

            if (glslLayout.sizeOf > metalLayout.sizeOf && field != fields.back())
            {
                const bool updateLayout = true;  // XXX: Correct?
                const size_t padAmount  = glslLayout.sizeOf - metalLayout.sizeOf;
                addPadding(padAmount, updateLayout);
            }
        }
    }

  public:
    TCompiler &mCompiler;
    const ModifyStructConfig &config;
    SymbolEnv &symbolEnv;

  private:
    TFieldList &modifiedFields;
    Layout metalLayoutTotal = Layout::Identity();
    size_t padFieldCount    = 0;
    bool containsPacked     = false;
    bool finalized          = false;

    std::vector<PathItem> pathItems;

    int mSubfieldIndex = 0;

    std::vector<ConversionInfo> conversionInfos;
    TSymbolTable &symbolTable;
    IdGen &idGen;
    ModifiedStructMachineries &outMachineries;
    const bool isUBO;
    const bool useAttributeAliasing;
};

////////////////////////////////////////////////////////////////////////////////

using ModifyFunc = bool (*)(ConvertStructState &state,
                            const TField &field,
                            const TLayoutBlockStorage storage,
                            const TLayoutMatrixPacking packing);

bool ModifyRecursive(ConvertStructState &state,
                     const TField &field,
                     const TLayoutBlockStorage storage,
                     const TLayoutMatrixPacking packing);

bool IdentityModify(ConvertStructState &state,
                    const TField &field,
                    const TLayoutBlockStorage storage,
                    const TLayoutMatrixPacking packing)
{
    const TType &type = *field.type();
    state.addModifiedField(field, CloneType(type), storage, packing, nullptr);
    state.addConversion([=](Access::Env &, OriginalAccess &o, ModifiedAccess &m) {
        return Access{o, m};
    });
    return false;
}

bool InlineStruct(ConvertStructState &state,
                  const TField &field,
                  const TLayoutBlockStorage storage,
                  const TLayoutMatrixPacking packing)
{
    const TType &type              = *field.type();
    const TStructure *substructure = state.symbolEnv.remap(type.getStruct());
    if (!substructure)
    {
        return false;
    }
    if (type.isArray())
    {
        return false;
    }
    if (!state.config.inlineStruct(field))
    {
        return false;
    }

    const TFieldList &subfields = substructure->fields();
    for (const TField *subfield : subfields)
    {
        const TType &subtype                  = *subfield->type();
        const TLayoutBlockStorage substorage  = Overlay(storage, subtype);
        const TLayoutMatrixPacking subpacking = Overlay(packing, subtype);
        ModifyRecursive(state, *subfield, substorage, subpacking);
    }

    return true;
}

bool RecurseStruct(ConvertStructState &state,
                   const TField &field,
                   const TLayoutBlockStorage storage,
                   const TLayoutMatrixPacking packing)
{
    const TType &type              = *field.type();
    const TStructure *substructure = state.symbolEnv.remap(type.getStruct());
    if (!substructure)
    {
        return false;
    }
    if (!state.config.recurseStruct(field))
    {
        return false;
    }

    ModifiedStructMachinery machinery;
    if (!state.recurse(*substructure, machinery, state.getIsUBO()))
    {
        return false;
    }

    TType &newType = *new TType(machinery.modifiedStruct, false);
    if (type.isArray())
    {
        newType.makeArrays(type.getArraySizes());
    }

    TIntermFunctionDefinition *converter = machinery.getConverter(state.config.convertType);
    ASSERT(converter);

    state.addModifiedField(field, newType, storage, packing, state.symbolEnv.isPointer(field));
    if (state.symbolEnv.isPointer(field))
    {
        state.symbolEnv.removePointer(field);
    }
    state.addConversion(*converter->getFunction());

    return true;
}

bool SplitMatrixColumns(ConvertStructState &state,
                        const TField &field,
                        const TLayoutBlockStorage storage,
                        const TLayoutMatrixPacking packing)
{
    const TType &type = *field.type();
    if (!type.isMatrix())
    {
        return false;
    }

    if (!state.config.splitMatrixColumns(field))
    {
        return false;
    }

    const uint8_t cols = type.getCols();
    TType &rowType     = DropColumns(type);

    for (uint8_t c = 0; c < cols; ++c)
    {
        state.pushPath(c);

        state.addModifiedField(field, rowType, storage, packing, state.symbolEnv.isPointer(field));
        if (state.symbolEnv.isPointer(field))
        {
            state.symbolEnv.removePointer(field);
        }
        state.addConversion([=](Access::Env &, OriginalAccess &o, ModifiedAccess &m) {
            return Access{o, m};
        });

        state.popPath();
    }

    return true;
}

bool SaturateMatrixRows(ConvertStructState &state,
                        const TField &field,
                        const TLayoutBlockStorage storage,
                        const TLayoutMatrixPacking packing)
{
    const TType &type = *field.type();
    if (!type.isMatrix())
    {
        return false;
    }
    const bool isRowMajor    = type.getLayoutQualifier().matrixPacking == EmpRowMajor;
    const uint8_t rows       = type.getRows();
    const uint8_t saturation = state.config.saturateMatrixRows(field);
    if (saturation <= rows)
    {
        return false;
    }

    const uint8_t cols = type.getCols();
    TType &satType     = SetMatrixRowDim(type, saturation);
    state.addModifiedField(field, satType, storage, packing, state.symbolEnv.isPointer(field));
    if (state.symbolEnv.isPointer(field))
    {
        state.symbolEnv.removePointer(field);
    }

    for (uint8_t c = 0; c < cols; ++c)
    {
        for (uint8_t r = 0; r < rows; ++r)
        {
            state.addConversion([=](Access::Env &, OriginalAccess &o, ModifiedAccess &m) {
                uint8_t firstModifiedIndex  = isRowMajor ? r : c;
                uint8_t secondModifiedIndex = isRowMajor ? c : r;
                auto &o_                    = AccessIndex(AccessIndex(o, c), r);
                auto &m_ = AccessIndex(AccessIndex(m, firstModifiedIndex), secondModifiedIndex);
                return Access{o_, m_};
            });
        }
    }

    return true;
}

bool TestBoolToUint(ConvertStructState &state, const TField &field)
{
    if (field.type()->getBasicType() != TBasicType::EbtBool)
    {
        return false;
    }
    if (!state.config.promoteBoolToUint(field))
    {
        return false;
    }
    return true;
}

Access ConvertBoolToUint(ConvertType convertType, OriginalAccess &o, ModifiedAccess &m)
{
    auto coerce = [](TIntermTyped &to, TIntermTyped &from) -> TIntermTyped & {
        return *TIntermAggregate::CreateConstructor(to.getType(), new TIntermSequence{&from});
    };
    switch (convertType)
    {
        case ConvertType::OriginalToModified:
            return Access{coerce(m, o), m};
        case ConvertType::ModifiedToOriginal:
            return Access{o, coerce(o, m)};
    }
}

bool SaturateScalarOrVectorCommon(ConvertStructState &state,
                                  const TField &field,
                                  const TLayoutBlockStorage storage,
                                  const TLayoutMatrixPacking packing,
                                  const bool array)
{
    const TType &type = *field.type();
    if (type.isArray() != array)
    {
        return false;
    }
    if (!((type.isRank0() && HasScalarBasicType(type)) || type.isVector()))
    {
        return false;
    }
    const auto saturator =
        array ? state.config.saturateScalarOrVectorArrays : state.config.saturateScalarOrVector;
    const uint8_t dim        = type.getNominalSize();
    const uint8_t saturation = saturator(field);
    if (saturation <= dim)
    {
        return false;
    }

    TType &satType        = SetVectorDim(type, saturation);
    const bool boolToUint = TestBoolToUint(state, field);
    if (boolToUint)
    {
        satType.setBasicType(TBasicType::EbtUInt);
    }
    state.addModifiedField(field, satType, storage, packing, state.symbolEnv.isPointer(field));
    if (state.symbolEnv.isPointer(field))
    {
        state.symbolEnv.removePointer(field);
    }

    for (uint8_t d = 0; d < dim; ++d)
    {
        state.addConversion([=](Access::Env &env, OriginalAccess &o, ModifiedAccess &m) {
            auto &o_ = dim > 1 ? AccessIndex(o, d) : o;
            auto &m_ = AccessIndex(m, d);
            if (boolToUint)
            {
                return ConvertBoolToUint(env.type, o_, m_);
            }
            else
            {
                return Access{o_, m_};
            }
        });
    }

    return true;
}

bool SaturateScalarOrVectorArrays(ConvertStructState &state,
                                  const TField &field,
                                  const TLayoutBlockStorage storage,
                                  const TLayoutMatrixPacking packing)
{
    return SaturateScalarOrVectorCommon(state, field, storage, packing, true);
}

bool SaturateScalarOrVector(ConvertStructState &state,
                            const TField &field,
                            const TLayoutBlockStorage storage,
                            const TLayoutMatrixPacking packing)
{
    return SaturateScalarOrVectorCommon(state, field, storage, packing, false);
}

bool PromoteBoolToUint(ConvertStructState &state,
                       const TField &field,
                       const TLayoutBlockStorage storage,
                       const TLayoutMatrixPacking packing)
{
    if (!TestBoolToUint(state, field))
    {
        return false;
    }

    auto &promotedType = CloneType(*field.type());
    promotedType.setBasicType(TBasicType::EbtUInt);
    state.addModifiedField(field, promotedType, storage, packing, state.symbolEnv.isPointer(field));
    if (state.symbolEnv.isPointer(field))
    {
        state.symbolEnv.removePointer(field);
    }

    state.addConversion([=](Access::Env &env, OriginalAccess &o, ModifiedAccess &m) {
        return ConvertBoolToUint(env.type, o, m);
    });

    return true;
}

bool ModifyCommon(ConvertStructState &state,
                  const TField &field,
                  const TLayoutBlockStorage storage,
                  const TLayoutMatrixPacking packing)
{
    ModifyFunc funcs[] = {
        InlineStruct,                  //
        RecurseStruct,                 //
        SplitMatrixColumns,            //
        SaturateMatrixRows,            //
        SaturateScalarOrVectorArrays,  //
        SaturateScalarOrVector,        //
        PromoteBoolToUint,             //
    };

    for (ModifyFunc func : funcs)
    {
        if (func(state, field, storage, packing))
        {
            return true;
        }
    }

    return IdentityModify(state, field, storage, packing);
}

bool InlineArray(ConvertStructState &state,
                 const TField &field,
                 const TLayoutBlockStorage storage,
                 const TLayoutMatrixPacking packing)
{
    const TType &type = *field.type();
    if (!type.isArray())
    {
        return false;
    }
    if (!state.config.inlineArray(field))
    {
        return false;
    }

    const unsigned volume = type.getArraySizeProduct();
    const bool isMultiDim = type.isArrayOfArrays();

    auto &innermostType = InnermostType(type);

    if (isMultiDim)
    {
        state.pushPath(FlattenArray());
    }

    for (unsigned i = 0; i < volume; ++i)
    {
        state.pushPath(i);
        TType setType(innermostType);
        if (setType.getLayoutQualifier().locationsSpecified)
        {
            TLayoutQualifier qualifier(innermostType.getLayoutQualifier());
            qualifier.location           = innermostType.getLayoutQualifier().location + i;
            qualifier.locationsSpecified = 1;
            setType.setLayoutQualifier(qualifier);
        }
        const TField innermostField(&setType, field.name(), field.line(), field.symbolType());
        ModifyCommon(state, innermostField, storage, packing);
        state.popPath();
    }

    if (isMultiDim)
    {
        state.popPath();
    }

    return true;
}

bool ModifyRecursive(ConvertStructState &state,
                     const TField &field,
                     const TLayoutBlockStorage storage,
                     const TLayoutMatrixPacking packing)
{
    state.pushPath(field);

    bool modified;
    if (InlineArray(state, field, storage, packing))
    {
        modified = true;
    }
    else
    {
        modified = ModifyCommon(state, field, storage, packing);
    }

    state.popPath();

    return modified;
}

}  // anonymous namespace

////////////////////////////////////////////////////////////////////////////////

bool sh::TryCreateModifiedStruct(TCompiler &compiler,
                                 SymbolEnv &symbolEnv,
                                 IdGen &idGen,
                                 const ModifyStructConfig &config,
                                 const TStructure &originalStruct,
                                 const Name &modifiedStructName,
                                 ModifiedStructMachineries &outMachineries,
                                 const bool isUBO,
                                 const bool allowPadding,
                                 const bool useAttributeAliasing)
{
    ConvertStructState state(compiler, symbolEnv, idGen, config, outMachineries, isUBO,
                             useAttributeAliasing);
    size_t identicalFieldCount = 0;

    const TFieldList &originalFields = originalStruct.fields();
    for (TField *originalField : originalFields)
    {
        const TType &originalType          = *originalField->type();
        const TLayoutBlockStorage storage  = Overlay(config.initialBlockStorage, originalType);
        const TLayoutMatrixPacking packing = Overlay(config.initialMatrixPacking, originalType);
        if (!ModifyRecursive(state, *originalField, storage, packing))
        {
            ++identicalFieldCount;
        }
    }

    state.finalize(allowPadding);

    if (identicalFieldCount == originalFields.size() && !state.hasPacking() &&
        !state.hasPadding() && !useAttributeAliasing)
    {
        return false;
    }
    state.publish(originalStruct, modifiedStructName);

    return true;
}
