//
// Copyright 2014 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.
//
// ResourcesHLSL.cpp:
//   Methods for GLSL to HLSL translation for uniforms and interface blocks.
//

#include "compiler/translator/ResourcesHLSL.h"

#include "common/utilities.h"
#include "compiler/translator/AtomicCounterFunctionHLSL.h"
#include "compiler/translator/ImmutableStringBuilder.h"
#include "compiler/translator/StructureHLSL.h"
#include "compiler/translator/UtilsHLSL.h"
#include "compiler/translator/blocklayoutHLSL.h"
#include "compiler/translator/util.h"
#include "nb/cpp14oncpp11.h"

namespace sh
{

namespace
{

CONSTEXPR const ImmutableString kAngleDecorString("angle_");

static const char *UniformRegisterPrefix(const TType &type)
{
    if (IsSampler(type.getBasicType()))
    {
        return "s";
    }
    else
    {
        return "c";
    }
}

static TString InterfaceBlockFieldTypeString(const TField &field, TLayoutBlockStorage blockStorage)
{
    const TType &fieldType                   = *field.type();
    const TLayoutMatrixPacking matrixPacking = fieldType.getLayoutQualifier().matrixPacking;
    ASSERT(matrixPacking != EmpUnspecified);
    const TStructure *structure = fieldType.getStruct();

    if (fieldType.isMatrix())
    {
        // Use HLSL row-major packing for GLSL column-major matrices
        const TString &matrixPackString =
            (matrixPacking == EmpRowMajor ? "column_major" : "row_major");
        return matrixPackString + " " + TypeString(fieldType);
    }
    else if (structure)
    {
        // Use HLSL row-major packing for GLSL column-major matrices
        return QualifiedStructNameString(*structure, matrixPacking == EmpColumnMajor,
                                         blockStorage == EbsStd140);
    }
    else
    {
        return TypeString(fieldType);
    }
}

static TString InterfaceBlockStructName(const TInterfaceBlock &interfaceBlock)
{
    return DecoratePrivate(interfaceBlock.name()) + "_type";
}

void OutputUniformIndexArrayInitializer(TInfoSinkBase &out,
                                        const TType &type,
                                        unsigned int startIndex)
{
    out << "{";
    TType elementType(type);
    elementType.toArrayElementType();
    for (unsigned int i = 0u; i < type.getOutermostArraySize(); ++i)
    {
        if (i > 0u)
        {
            out << ", ";
        }
        if (elementType.isArray())
        {
            OutputUniformIndexArrayInitializer(out, elementType,
                                               startIndex + i * elementType.getArraySizeProduct());
        }
        else
        {
            out << (startIndex + i);
        }
    }
    out << "}";
}

}  // anonymous namespace

ResourcesHLSL::ResourcesHLSL(StructureHLSL *structureHLSL,
                             ShShaderOutput outputType,
                             const std::vector<ShaderVariable> &uniforms,
                             unsigned int firstUniformRegister)
    : mUniformRegister(firstUniformRegister),
      mUniformBlockRegister(0),
      mTextureRegister(0),
      mUAVRegister(0),
      mSamplerCount(0),
      mStructureHLSL(structureHLSL),
      mOutputType(outputType),
      mUniforms(uniforms)
{}

void ResourcesHLSL::reserveUniformRegisters(unsigned int registerCount)
{
    mUniformRegister = registerCount;
}

void ResourcesHLSL::reserveUniformBlockRegisters(unsigned int registerCount)
{
    mUniformBlockRegister = registerCount;
}

const ShaderVariable *ResourcesHLSL::findUniformByName(const ImmutableString &name) const
{
    for (size_t uniformIndex = 0; uniformIndex < mUniforms.size(); ++uniformIndex)
    {
        if (name == mUniforms[uniformIndex].name)
        {
            return &mUniforms[uniformIndex];
        }
    }

    return nullptr;
}

unsigned int ResourcesHLSL::assignUniformRegister(const TType &type,
                                                  const ImmutableString &name,
                                                  unsigned int *outRegisterCount)
{
    unsigned int registerIndex;
    const ShaderVariable *uniform = findUniformByName(name);
    ASSERT(uniform);

    if (IsSampler(type.getBasicType()) ||
        (IsImage(type.getBasicType()) && type.getMemoryQualifier().readonly))
    {
        registerIndex = mTextureRegister;
    }
    else if (IsImage(type.getBasicType()))
    {
        registerIndex = mUAVRegister;
    }
    else
    {
        registerIndex = mUniformRegister;
    }

    if (uniform->name == "angle_DrawID" && uniform->mappedName == "angle_DrawID")
    {
        mUniformRegisterMap["gl_DrawID"] = registerIndex;
    }
    else
    {
        mUniformRegisterMap[uniform->name] = registerIndex;
    }

    if (uniform->name == "angle_BaseVertex" && uniform->mappedName == "angle_BaseVertex")
    {
        mUniformRegisterMap["gl_BaseVertex"] = registerIndex;
    }
    else
    {
        mUniformRegisterMap[uniform->name] = registerIndex;
    }

    if (uniform->name == "angle_BaseInstance" && uniform->mappedName == "angle_BaseInstance")
    {
        mUniformRegisterMap["gl_BaseInstance"] = registerIndex;
    }
    else
    {
        mUniformRegisterMap[uniform->name] = registerIndex;
    }

    unsigned int registerCount = HLSLVariableRegisterCount(*uniform, mOutputType);

    if (IsSampler(type.getBasicType()) ||
        (IsImage(type.getBasicType()) && type.getMemoryQualifier().readonly))
    {
        mTextureRegister += registerCount;
    }
    else if (IsImage(type.getBasicType()))
    {
        mUAVRegister += registerCount;
    }
    else
    {
        mUniformRegister += registerCount;
    }
    if (outRegisterCount)
    {
        *outRegisterCount = registerCount;
    }
    return registerIndex;
}

unsigned int ResourcesHLSL::assignSamplerInStructUniformRegister(const TType &type,
                                                                 const TString &name,
                                                                 unsigned int *outRegisterCount)
{
    // Sampler that is a field of a uniform structure.
    ASSERT(IsSampler(type.getBasicType()));
    unsigned int registerIndex                     = mTextureRegister;
    mUniformRegisterMap[std::string(name.c_str())] = registerIndex;
    unsigned int registerCount = type.isArray() ? type.getArraySizeProduct() : 1u;
    mTextureRegister += registerCount;
    if (outRegisterCount)
    {
        *outRegisterCount = registerCount;
    }
    return registerIndex;
}

void ResourcesHLSL::outputHLSLSamplerUniformGroup(
    TInfoSinkBase &out,
    const HLSLTextureGroup textureGroup,
    const TVector<const TVariable *> &group,
    const TMap<const TVariable *, TString> &samplerInStructSymbolsToAPINames,
    unsigned int *groupTextureRegisterIndex)
{
    if (group.empty())
    {
        return;
    }
    unsigned int groupRegisterCount = 0;
    for (const TVariable *uniform : group)
    {
        const TType &type           = uniform->getType();
        const ImmutableString &name = uniform->name();
        unsigned int registerCount;

        // The uniform might be just a regular sampler or one extracted from a struct.
        unsigned int samplerArrayIndex = 0u;
        const ShaderVariable *uniformByName = findUniformByName(name);
        if (uniformByName)
        {
            samplerArrayIndex = assignUniformRegister(type, name, &registerCount);
        }
        else
        {
            ASSERT(samplerInStructSymbolsToAPINames.find(uniform) !=
                   samplerInStructSymbolsToAPINames.end());
            samplerArrayIndex = assignSamplerInStructUniformRegister(
                type, samplerInStructSymbolsToAPINames.at(uniform), &registerCount);
        }
        groupRegisterCount += registerCount;

        if (type.isArray())
        {
            out << "static const uint " << DecorateVariableIfNeeded(*uniform) << ArrayString(type)
                << " = ";
            OutputUniformIndexArrayInitializer(out, type, samplerArrayIndex);
            out << ";\n";
        }
        else
        {
            out << "static const uint " << DecorateVariableIfNeeded(*uniform) << " = "
                << samplerArrayIndex << ";\n";
        }
    }
    TString suffix = TextureGroupSuffix(textureGroup);
    // Since HLSL_TEXTURE_2D is the first group, it has a fixed offset of zero.
    if (textureGroup != HLSL_TEXTURE_2D)
    {
        out << "static const uint textureIndexOffset" << suffix << " = "
            << (*groupTextureRegisterIndex) << ";\n";
        out << "static const uint samplerIndexOffset" << suffix << " = "
            << (*groupTextureRegisterIndex) << ";\n";
    }
    out << "uniform " << TextureString(textureGroup) << " textures" << suffix << "["
        << groupRegisterCount << "]"
        << " : register(t" << (*groupTextureRegisterIndex) << ");\n";
    out << "uniform " << SamplerString(textureGroup) << " samplers" << suffix << "["
        << groupRegisterCount << "]"
        << " : register(s" << (*groupTextureRegisterIndex) << ");\n";
    *groupTextureRegisterIndex += groupRegisterCount;
}

void ResourcesHLSL::outputHLSLImageUniformIndices(TInfoSinkBase &out,
                                                  const TVector<const TVariable *> &group,
                                                  unsigned int imageArrayIndex,
                                                  unsigned int *groupRegisterCount)
{
    for (const TVariable *uniform : group)
    {
        const TType &type           = uniform->getType();
        const ImmutableString &name = uniform->name();
        unsigned int registerCount  = 0;

        assignUniformRegister(type, name, &registerCount);
        *groupRegisterCount += registerCount;

        if (type.isArray())
        {
            out << "static const uint " << DecorateVariableIfNeeded(*uniform) << ArrayString(type)
                << " = ";
            OutputUniformIndexArrayInitializer(out, type, imageArrayIndex);
            out << ";\n";
        }
        else
        {
            out << "static const uint " << DecorateVariableIfNeeded(*uniform) << " = "
                << imageArrayIndex << ";\n";
        }

        imageArrayIndex += registerCount;
    }
}

void ResourcesHLSL::outputHLSLReadonlyImageUniformGroup(TInfoSinkBase &out,
                                                        const HLSLTextureGroup textureGroup,
                                                        const TVector<const TVariable *> &group,
                                                        unsigned int *groupTextureRegisterIndex)
{
    if (group.empty())
    {
        return;
    }

    unsigned int groupRegisterCount = 0;
    outputHLSLImageUniformIndices(out, group, *groupTextureRegisterIndex, &groupRegisterCount);

    TString suffix = TextureGroupSuffix(textureGroup);
    out << "static const uint readonlyImageIndexOffset" << suffix << " = "
        << (*groupTextureRegisterIndex) << ";\n";
    out << "uniform " << TextureString(textureGroup) << " readonlyImages" << suffix << "["
        << groupRegisterCount << "]"
        << " : register(t" << (*groupTextureRegisterIndex) << ");\n";
    *groupTextureRegisterIndex += groupRegisterCount;
}

void ResourcesHLSL::outputHLSLImageUniformGroup(TInfoSinkBase &out,
                                                const HLSLRWTextureGroup textureGroup,
                                                const TVector<const TVariable *> &group,
                                                unsigned int *groupTextureRegisterIndex)
{
    if (group.empty())
    {
        return;
    }

    unsigned int groupRegisterCount = 0;
    outputHLSLImageUniformIndices(out, group, *groupTextureRegisterIndex, &groupRegisterCount);

    TString suffix = RWTextureGroupSuffix(textureGroup);
    out << "static const uint imageIndexOffset" << suffix << " = " << (*groupTextureRegisterIndex)
        << ";\n";
    out << "uniform " << RWTextureString(textureGroup) << " images" << suffix << "["
        << groupRegisterCount << "]"
        << " : register(u" << (*groupTextureRegisterIndex) << ");\n";
    *groupTextureRegisterIndex += groupRegisterCount;
}

void ResourcesHLSL::outputHLSL4_0_FL9_3Sampler(TInfoSinkBase &out,
                                               const TType &type,
                                               const TVariable &variable,
                                               const unsigned int registerIndex)
{
    out << "uniform " << SamplerString(type.getBasicType()) << " sampler_"
        << DecorateVariableIfNeeded(variable) << ArrayString(type) << " : register(s"
        << str(registerIndex) << ");\n";
    out << "uniform " << TextureString(type.getBasicType()) << " texture_"
        << DecorateVariableIfNeeded(variable) << ArrayString(type) << " : register(t"
        << str(registerIndex) << ");\n";
}

void ResourcesHLSL::outputUniform(TInfoSinkBase &out,
                                  const TType &type,
                                  const TVariable &variable,
                                  const unsigned int registerIndex)
{
    const TStructure *structure = type.getStruct();
    // If this is a nameless struct, we need to use its full definition, rather than its (empty)
    // name.
    // TypeString() will invoke defineNameless in this case; qualifier prefixes are unnecessary for
    // nameless structs in ES, as nameless structs cannot be used anywhere that layout qualifiers
    // are permitted.
    const TString &typeName = ((structure && structure->symbolType() != SymbolType::Empty)
                                   ? QualifiedStructNameString(*structure, false, false)
                                   : TypeString(type));

    const TString &registerString =
        TString("register(") + UniformRegisterPrefix(type) + str(registerIndex) + ")";

    out << "uniform " << typeName << " ";

    out << DecorateVariableIfNeeded(variable);

    out << ArrayString(type) << " : " << registerString << ";\n";
}

void ResourcesHLSL::outputAtomicCounterBuffer(TInfoSinkBase &out,
                                              const int binding,
                                              const unsigned int registerIndex)
{
    // Atomic counter memory access is not incoherent
    out << "uniform globallycoherent RWByteAddressBuffer "
        << getAtomicCounterNameForBinding(binding) << " : register(u" << registerIndex << ");\n";
}

void ResourcesHLSL::uniformsHeader(TInfoSinkBase &out,
                                   ShShaderOutput outputType,
                                   const ReferencedVariables &referencedUniforms,
                                   TSymbolTable *symbolTable)
{
    if (!referencedUniforms.empty())
    {
        out << "// Uniforms\n\n";
    }
    // In the case of HLSL 4, sampler uniforms need to be grouped by type before the code is
    // written. They are grouped based on the combination of the HLSL texture type and
    // HLSL sampler type, enumerated in HLSLTextureSamplerGroup.
    TVector<TVector<const TVariable *>> groupedSamplerUniforms(HLSL_TEXTURE_MAX + 1);
    TMap<const TVariable *, TString> samplerInStructSymbolsToAPINames;
    TVector<TVector<const TVariable *>> groupedReadonlyImageUniforms(HLSL_TEXTURE_MAX + 1);
    TVector<TVector<const TVariable *>> groupedImageUniforms(HLSL_RWTEXTURE_MAX + 1);

    TUnorderedMap<int, unsigned int> assignedAtomicCounterBindings;
    unsigned int reservedReadonlyImageRegisterCount = 0, reservedImageRegisterCount = 0;
    for (auto &uniformIt : referencedUniforms)
    {
        // Output regular uniforms. Group sampler uniforms by type.
        const TVariable &variable = *uniformIt.second;
        const TType &type         = variable.getType();

        if (outputType == SH_HLSL_4_1_OUTPUT && IsSampler(type.getBasicType()))
        {
            HLSLTextureGroup group = TextureGroup(type.getBasicType());
            groupedSamplerUniforms[group].push_back(&variable);
        }
        else if (outputType == SH_HLSL_4_0_FL9_3_OUTPUT && IsSampler(type.getBasicType()))
        {
            unsigned int registerIndex = assignUniformRegister(type, variable.name(), nullptr);
            outputHLSL4_0_FL9_3Sampler(out, type, variable, registerIndex);
        }
        else if (outputType == SH_HLSL_4_1_OUTPUT && IsImage(type.getBasicType()))
        {
            if (IsImage2D(type.getBasicType()))
            {
                const ShaderVariable *uniform = findUniformByName(variable.name());
                if (type.getMemoryQualifier().readonly)
                {
                    reservedReadonlyImageRegisterCount +=
                        HLSLVariableRegisterCount(*uniform, mOutputType);
                }
                else
                {
                    reservedImageRegisterCount += HLSLVariableRegisterCount(*uniform, mOutputType);
                }
                continue;
            }
            if (type.getMemoryQualifier().readonly)
            {
                HLSLTextureGroup group = TextureGroup(
                    type.getBasicType(), type.getLayoutQualifier().imageInternalFormat);
                groupedReadonlyImageUniforms[group].push_back(&variable);
            }
            else
            {
                HLSLRWTextureGroup group = RWTextureGroup(
                    type.getBasicType(), type.getLayoutQualifier().imageInternalFormat);
                groupedImageUniforms[group].push_back(&variable);
            }
        }
        else if (outputType == SH_HLSL_4_1_OUTPUT && IsAtomicCounter(type.getBasicType()))
        {
            TLayoutQualifier layout = type.getLayoutQualifier();
            int binding             = layout.binding;
            unsigned int registerIndex;
            if (assignedAtomicCounterBindings.find(binding) == assignedAtomicCounterBindings.end())
            {
                registerIndex                          = mUAVRegister++;
                assignedAtomicCounterBindings[binding] = registerIndex;
                outputAtomicCounterBuffer(out, binding, registerIndex);
            }
            else
            {
                registerIndex = assignedAtomicCounterBindings[binding];
            }
            const ShaderVariable *uniform      = findUniformByName(variable.name());
            mUniformRegisterMap[uniform->name] = registerIndex;
        }
        else
        {
            if (type.isStructureContainingSamplers())
            {
                TVector<const TVariable *> samplerSymbols;
                TMap<const TVariable *, TString> symbolsToAPINames;
                ImmutableStringBuilder namePrefix(kAngleDecorString.length() +
                                                  variable.name().length());
                namePrefix << kAngleDecorString;
                namePrefix << variable.name();
                type.createSamplerSymbols(namePrefix, TString(variable.name().data()),
                                          &samplerSymbols, &symbolsToAPINames, symbolTable);
                for (const TVariable *sampler : samplerSymbols)
                {
                    const TType &samplerType = sampler->getType();

                    if (outputType == SH_HLSL_4_1_OUTPUT)
                    {
                        HLSLTextureGroup group = TextureGroup(samplerType.getBasicType());
                        groupedSamplerUniforms[group].push_back(sampler);
                        samplerInStructSymbolsToAPINames[sampler] = symbolsToAPINames[sampler];
                    }
                    else if (outputType == SH_HLSL_4_0_FL9_3_OUTPUT)
                    {
                        unsigned int registerIndex = assignSamplerInStructUniformRegister(
                            samplerType, symbolsToAPINames[sampler], nullptr);
                        outputHLSL4_0_FL9_3Sampler(out, samplerType, *sampler, registerIndex);
                    }
                    else
                    {
                        ASSERT(outputType == SH_HLSL_3_0_OUTPUT);
                        unsigned int registerIndex = assignSamplerInStructUniformRegister(
                            samplerType, symbolsToAPINames[sampler], nullptr);
                        outputUniform(out, samplerType, *sampler, registerIndex);
                    }
                }
            }
            unsigned int registerIndex = assignUniformRegister(type, variable.name(), nullptr);
            outputUniform(out, type, variable, registerIndex);
        }
    }

    if (outputType == SH_HLSL_4_1_OUTPUT)
    {
        unsigned int groupTextureRegisterIndex = 0;
        // Atomic counters and RW texture share the same resources. Therefore, RW texture need to
        // start counting after the last atomic counter.
        unsigned int groupRWTextureRegisterIndex = mUAVRegister;
        // TEXTURE_2D is special, index offset is assumed to be 0 and omitted in that case.
        ASSERT(HLSL_TEXTURE_MIN == HLSL_TEXTURE_2D);
        for (int groupId = HLSL_TEXTURE_MIN; groupId < HLSL_TEXTURE_MAX; ++groupId)
        {
            outputHLSLSamplerUniformGroup(
                out, HLSLTextureGroup(groupId), groupedSamplerUniforms[groupId],
                samplerInStructSymbolsToAPINames, &groupTextureRegisterIndex);
        }
        mSamplerCount = groupTextureRegisterIndex;

        // Reserve t type register for readonly image2D variables.
        mReadonlyImage2DRegisterIndex = mTextureRegister;
        groupTextureRegisterIndex += reservedReadonlyImageRegisterCount;
        mTextureRegister += reservedReadonlyImageRegisterCount;

        for (int groupId = HLSL_TEXTURE_MIN; groupId < HLSL_TEXTURE_MAX; ++groupId)
        {
            outputHLSLReadonlyImageUniformGroup(out, HLSLTextureGroup(groupId),
                                                groupedReadonlyImageUniforms[groupId],
                                                &groupTextureRegisterIndex);
        }
        mReadonlyImageCount = groupTextureRegisterIndex - mReadonlyImage2DRegisterIndex;
        if (mReadonlyImageCount)
        {
            out << "static const uint readonlyImageIndexStart = " << mReadonlyImage2DRegisterIndex
                << ";\n";
        }

        // Reserve u type register for writable image2D variables.
        mImage2DRegisterIndex = mUAVRegister;
        groupRWTextureRegisterIndex += reservedImageRegisterCount;
        mUAVRegister += reservedImageRegisterCount;

        for (int groupId = HLSL_RWTEXTURE_MIN; groupId < HLSL_RWTEXTURE_MAX; ++groupId)
        {
            outputHLSLImageUniformGroup(out, HLSLRWTextureGroup(groupId),
                                        groupedImageUniforms[groupId],
                                        &groupRWTextureRegisterIndex);
        }
        mImageCount = groupRWTextureRegisterIndex - mImage2DRegisterIndex;
        if (mImageCount)
        {
            out << "static const uint imageIndexStart = " << mImage2DRegisterIndex << ";\n";
        }
    }
}

void ResourcesHLSL::samplerMetadataUniforms(TInfoSinkBase &out, unsigned int regIndex)
{
    // If mSamplerCount is 0 the shader doesn't use any textures for samplers.
    if (mSamplerCount > 0)
    {
        out << "    struct SamplerMetadata\n"
               "    {\n"
               "        int baseLevel;\n"
               "        int internalFormatBits;\n"
               "        int wrapModes;\n"
               "        int padding;\n"
               "        int4 intBorderColor;\n"
               "    };\n"
               "    SamplerMetadata samplerMetadata["
            << mSamplerCount << "] : packoffset(c" << regIndex << ");\n";
    }
}

void ResourcesHLSL::imageMetadataUniforms(TInfoSinkBase &out, unsigned int regIndex)
{
    if (mReadonlyImageCount > 0 || mImageCount > 0)
    {
        out << "    struct ImageMetadata\n"
               "    {\n"
               "        int layer;\n"
               "        uint level;\n"
               "        int2 padding;\n"
               "    };\n";

        if (mReadonlyImageCount > 0)
        {
            out << "    ImageMetadata readonlyImageMetadata[" << mReadonlyImageCount
                << "] : packoffset(c" << regIndex << ");\n";
        }

        if (mImageCount > 0)
        {
            out << "    ImageMetadata imageMetadata[" << mImageCount << "] : packoffset(c"
                << regIndex + mReadonlyImageCount << ");\n";
        }
    }
}

TString ResourcesHLSL::uniformBlocksHeader(
    const ReferencedInterfaceBlocks &referencedInterfaceBlocks)
{
    TString interfaceBlocks;

    for (const auto &blockReference : referencedInterfaceBlocks)
    {
        const TInterfaceBlock &interfaceBlock = *blockReference.second->block;
        const TVariable *instanceVariable     = blockReference.second->instanceVariable;
        if (instanceVariable != nullptr)
        {
            interfaceBlocks += uniformBlockStructString(interfaceBlock);
        }

        unsigned int activeRegister                            = mUniformBlockRegister;
        mUniformBlockRegisterMap[interfaceBlock.name().data()] = activeRegister;

        if (instanceVariable != nullptr && instanceVariable->getType().isArray())
        {
            unsigned int instanceArraySize = instanceVariable->getType().getOutermostArraySize();
            for (unsigned int arrayIndex = 0; arrayIndex < instanceArraySize; arrayIndex++)
            {
                interfaceBlocks += uniformBlockString(interfaceBlock, instanceVariable,
                                                      activeRegister + arrayIndex, arrayIndex);
            }
            mUniformBlockRegister += instanceArraySize;
        }
        else
        {
            interfaceBlocks += uniformBlockString(interfaceBlock, instanceVariable, activeRegister,
                                                  GL_INVALID_INDEX);
            mUniformBlockRegister += 1u;
        }
    }

    return (interfaceBlocks.empty() ? "" : ("// Uniform Blocks\n\n" + interfaceBlocks));
}

TString ResourcesHLSL::shaderStorageBlocksHeader(
    const ReferencedInterfaceBlocks &referencedInterfaceBlocks)
{
    TString interfaceBlocks;

    for (const auto &interfaceBlockReference : referencedInterfaceBlocks)
    {
        const TInterfaceBlock &interfaceBlock = *interfaceBlockReference.second->block;
        const TVariable *instanceVariable     = interfaceBlockReference.second->instanceVariable;

        unsigned int activeRegister                                  = mUAVRegister;
        mShaderStorageBlockRegisterMap[interfaceBlock.name().data()] = activeRegister;

        if (instanceVariable != nullptr && instanceVariable->getType().isArray())
        {
            unsigned int instanceArraySize = instanceVariable->getType().getOutermostArraySize();
            for (unsigned int arrayIndex = 0; arrayIndex < instanceArraySize; arrayIndex++)
            {
                interfaceBlocks += shaderStorageBlockString(
                    interfaceBlock, instanceVariable, activeRegister + arrayIndex, arrayIndex);
            }
            mUAVRegister += instanceArraySize;
        }
        else
        {
            interfaceBlocks += shaderStorageBlockString(interfaceBlock, instanceVariable,
                                                        activeRegister, GL_INVALID_INDEX);
            mUAVRegister += 1u;
        }
    }

    return (interfaceBlocks.empty() ? "" : ("// Shader Storage Blocks\n\n" + interfaceBlocks));
}

TString ResourcesHLSL::uniformBlockString(const TInterfaceBlock &interfaceBlock,
                                          const TVariable *instanceVariable,
                                          unsigned int registerIndex,
                                          unsigned int arrayIndex)
{
    const TString &arrayIndexString = (arrayIndex != GL_INVALID_INDEX ? str(arrayIndex) : "");
    const TString &blockName        = TString(interfaceBlock.name().data()) + arrayIndexString;
    TString hlsl;

    hlsl += "cbuffer " + blockName + " : register(b" + str(registerIndex) +
            ")\n"
            "{\n";

    if (instanceVariable != nullptr)
    {
        hlsl += "    " + InterfaceBlockStructName(interfaceBlock) + " " +
                InterfaceBlockInstanceString(instanceVariable->name(), arrayIndex) + ";\n";
    }
    else
    {
        const TLayoutBlockStorage blockStorage = interfaceBlock.blockStorage();
        hlsl += uniformBlockMembersString(interfaceBlock, blockStorage);
    }

    hlsl += "};\n\n";

    return hlsl;
}

TString ResourcesHLSL::shaderStorageBlockString(const TInterfaceBlock &interfaceBlock,
                                                const TVariable *instanceVariable,
                                                unsigned int registerIndex,
                                                unsigned int arrayIndex)
{
    TString hlsl;
    if (instanceVariable != nullptr)
    {
        hlsl += "RWByteAddressBuffer " +
                InterfaceBlockInstanceString(instanceVariable->name(), arrayIndex) +
                ": register(u" + str(registerIndex) + ");\n";
    }
    else
    {
        hlsl += "RWByteAddressBuffer " + Decorate(interfaceBlock.name()) + ": register(u" +
                str(registerIndex) + ");\n";
    }
    return hlsl;
}

TString ResourcesHLSL::InterfaceBlockInstanceString(const ImmutableString &instanceName,
                                                    unsigned int arrayIndex)
{
    if (arrayIndex != GL_INVALID_INDEX)
    {
        return DecoratePrivate(instanceName) + "_" + str(arrayIndex);
    }
    else
    {
        return Decorate(instanceName);
    }
}

TString ResourcesHLSL::uniformBlockMembersString(const TInterfaceBlock &interfaceBlock,
                                                 TLayoutBlockStorage blockStorage)
{
    TString hlsl;

    Std140PaddingHelper padHelper = mStructureHLSL->getPaddingHelper();

    for (unsigned int typeIndex = 0; typeIndex < interfaceBlock.fields().size(); typeIndex++)
    {
        const TField &field    = *interfaceBlock.fields()[typeIndex];
        const TType &fieldType = *field.type();

        if (blockStorage == EbsStd140)
        {
            // 2 and 3 component vector types in some cases need pre-padding
            hlsl += padHelper.prePaddingString(fieldType);
        }

        hlsl += "    " + InterfaceBlockFieldTypeString(field, blockStorage) + " " +
                Decorate(field.name()) + ArrayString(fieldType).data() + ";\n";

        // must pad out after matrices and arrays, where HLSL usually allows itself room to pack
        // stuff
        if (blockStorage == EbsStd140)
        {
            const bool useHLSLRowMajorPacking =
                (fieldType.getLayoutQualifier().matrixPacking == EmpColumnMajor);
            hlsl += padHelper.postPaddingString(fieldType, useHLSLRowMajorPacking);
        }
    }

    return hlsl;
}

TString ResourcesHLSL::uniformBlockStructString(const TInterfaceBlock &interfaceBlock)
{
    const TLayoutBlockStorage blockStorage = interfaceBlock.blockStorage();

    return "struct " + InterfaceBlockStructName(interfaceBlock) +
           "\n"
           "{\n" +
           uniformBlockMembersString(interfaceBlock, blockStorage) + "};\n\n";
}
}  // namespace sh
