tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ProgramD3D.cpp (122898B)


      1 //
      2 // Copyright 2014 The ANGLE Project Authors. All rights reserved.
      3 // Use of this source code is governed by a BSD-style license that can be
      4 // found in the LICENSE file.
      5 //
      6 
      7 // ProgramD3D.cpp: Defines the rx::ProgramD3D class which implements rx::ProgramImpl.
      8 
      9 #include "libANGLE/renderer/d3d/ProgramD3D.h"
     10 
     11 #include "common/MemoryBuffer.h"
     12 #include "common/bitset_utils.h"
     13 #include "common/string_utils.h"
     14 #include "common/utilities.h"
     15 #include "libANGLE/Context.h"
     16 #include "libANGLE/Framebuffer.h"
     17 #include "libANGLE/FramebufferAttachment.h"
     18 #include "libANGLE/Program.h"
     19 #include "libANGLE/ProgramLinkedResources.h"
     20 #include "libANGLE/Uniform.h"
     21 #include "libANGLE/VertexArray.h"
     22 #include "libANGLE/features.h"
     23 #include "libANGLE/queryconversions.h"
     24 #include "libANGLE/renderer/ContextImpl.h"
     25 #include "libANGLE/renderer/d3d/ContextD3D.h"
     26 #include "libANGLE/renderer/d3d/DynamicHLSL.h"
     27 #include "libANGLE/renderer/d3d/FramebufferD3D.h"
     28 #include "libANGLE/renderer/d3d/ShaderD3D.h"
     29 #include "libANGLE/renderer/d3d/ShaderExecutableD3D.h"
     30 #include "libANGLE/renderer/d3d/VertexDataManager.h"
     31 #include "libANGLE/renderer/renderer_utils.h"
     32 #include "libANGLE/trace.h"
     33 
     34 using namespace angle;
     35 
     36 namespace rx
     37 {
     38 
     39 namespace
     40 {
     41 
     42 void GetDefaultInputLayoutFromShader(const gl::Context *context,
     43                                     gl::Shader *vertexShader,
     44                                     gl::InputLayout *inputLayoutOut)
     45 {
     46    inputLayoutOut->clear();
     47 
     48    if (!vertexShader)
     49    {
     50        return;
     51    }
     52 
     53    for (const sh::ShaderVariable &shaderAttr : vertexShader->getActiveAttributes(context))
     54    {
     55        if (shaderAttr.type != GL_NONE)
     56        {
     57            GLenum transposedType = gl::TransposeMatrixType(shaderAttr.type);
     58 
     59            for (size_t rowIndex = 0;
     60                 static_cast<int>(rowIndex) < gl::VariableRowCount(transposedType); ++rowIndex)
     61            {
     62                GLenum componentType = gl::VariableComponentType(transposedType);
     63                GLuint components    = static_cast<GLuint>(gl::VariableColumnCount(transposedType));
     64                bool pureInt         = (componentType != GL_FLOAT);
     65 
     66                gl::VertexAttribType attribType =
     67                    gl::FromGLenum<gl::VertexAttribType>(componentType);
     68 
     69                angle::FormatID defaultID =
     70                    gl::GetVertexFormatID(attribType, GL_FALSE, components, pureInt);
     71 
     72                inputLayoutOut->push_back(defaultID);
     73            }
     74        }
     75    }
     76 }
     77 
     78 size_t GetMaxOutputIndex(const std::vector<PixelShaderOutputVariable> &shaderOutputVars,
     79                         size_t location)
     80 {
     81    size_t maxIndex = 0;
     82    for (auto &outputVar : shaderOutputVars)
     83    {
     84        if (outputVar.outputLocation == location)
     85        {
     86            maxIndex = std::max(maxIndex, outputVar.outputIndex);
     87        }
     88    }
     89    return maxIndex;
     90 }
     91 
     92 void GetDefaultOutputLayoutFromShader(
     93    const std::vector<PixelShaderOutputVariable> &shaderOutputVars,
     94    std::vector<GLenum> *outputLayoutOut)
     95 {
     96    outputLayoutOut->clear();
     97 
     98    if (!shaderOutputVars.empty())
     99    {
    100        size_t location = shaderOutputVars[0].outputLocation;
    101        size_t maxIndex = GetMaxOutputIndex(shaderOutputVars, location);
    102        outputLayoutOut->assign(maxIndex + 1,
    103                                GL_COLOR_ATTACHMENT0 + static_cast<unsigned int>(location));
    104    }
    105 }
    106 
    107 void GetDefaultImage2DBindLayoutFromShader(const std::vector<sh::ShaderVariable> &image2DUniforms,
    108                                           gl::ImageUnitTextureTypeMap *image2DBindLayout)
    109 {
    110    image2DBindLayout->clear();
    111 
    112    for (const sh::ShaderVariable &image2D : image2DUniforms)
    113    {
    114        if (gl::IsImage2DType(image2D.type))
    115        {
    116            if (image2D.binding == -1)
    117            {
    118                image2DBindLayout->insert(std::make_pair(0, gl::TextureType::_2D));
    119            }
    120            else
    121            {
    122                for (unsigned int index = 0; index < image2D.getArraySizeProduct(); index++)
    123                {
    124                    image2DBindLayout->insert(
    125                        std::make_pair(image2D.binding + index, gl::TextureType::_2D));
    126                }
    127            }
    128        }
    129    }
    130 }
    131 
    132 gl::PrimitiveMode GetGeometryShaderTypeFromDrawMode(gl::PrimitiveMode drawMode)
    133 {
    134    switch (drawMode)
    135    {
    136        // Uses the point sprite geometry shader.
    137        case gl::PrimitiveMode::Points:
    138            return gl::PrimitiveMode::Points;
    139 
    140        // All line drawing uses the same geometry shader.
    141        case gl::PrimitiveMode::Lines:
    142        case gl::PrimitiveMode::LineStrip:
    143        case gl::PrimitiveMode::LineLoop:
    144            return gl::PrimitiveMode::Lines;
    145 
    146        // The triangle fan primitive is emulated with strips in D3D11.
    147        case gl::PrimitiveMode::Triangles:
    148        case gl::PrimitiveMode::TriangleFan:
    149            return gl::PrimitiveMode::Triangles;
    150 
    151        // Special case for triangle strips.
    152        case gl::PrimitiveMode::TriangleStrip:
    153            return gl::PrimitiveMode::TriangleStrip;
    154 
    155        default:
    156            UNREACHABLE();
    157            return gl::PrimitiveMode::InvalidEnum;
    158    }
    159 }
    160 
    161 bool HasFlatInterpolationVarying(const std::vector<sh::ShaderVariable> &varyings)
    162 {
    163    // Note: this assumes nested structs can only be packed with one interpolation.
    164    for (const auto &varying : varyings)
    165    {
    166        if (varying.interpolation == sh::INTERPOLATION_FLAT)
    167        {
    168            return true;
    169        }
    170    }
    171 
    172    return false;
    173 }
    174 
    175 bool FindFlatInterpolationVaryingPerShader(const gl::Context *context, gl::Shader *shader)
    176 {
    177    ASSERT(shader);
    178    switch (shader->getType())
    179    {
    180        case gl::ShaderType::Vertex:
    181            return HasFlatInterpolationVarying(shader->getOutputVaryings(context));
    182        case gl::ShaderType::Fragment:
    183            return HasFlatInterpolationVarying(shader->getInputVaryings(context));
    184        case gl::ShaderType::Geometry:
    185            return HasFlatInterpolationVarying(shader->getInputVaryings(context)) ||
    186                   HasFlatInterpolationVarying(shader->getOutputVaryings(context));
    187        default:
    188            UNREACHABLE();
    189            return false;
    190    }
    191 }
    192 
    193 bool FindFlatInterpolationVarying(const gl::Context *context,
    194                                  const gl::ShaderMap<gl::Shader *> &shaders)
    195 {
    196    for (gl::ShaderType shaderType : gl::kAllGraphicsShaderTypes)
    197    {
    198        gl::Shader *shader = shaders[shaderType];
    199        if (!shader)
    200        {
    201            continue;
    202        }
    203 
    204        if (FindFlatInterpolationVaryingPerShader(context, shader))
    205        {
    206            return true;
    207        }
    208    }
    209 
    210    return false;
    211 }
    212 
    213 // Helper class that gathers uniform info from the default uniform block.
    214 class UniformEncodingVisitorD3D : public sh::BlockEncoderVisitor
    215 {
    216  public:
    217    UniformEncodingVisitorD3D(gl::ShaderType shaderType,
    218                              HLSLRegisterType registerType,
    219                              sh::BlockLayoutEncoder *encoder,
    220                              D3DUniformMap *uniformMapOut)
    221        : sh::BlockEncoderVisitor("", "", encoder),
    222          mShaderType(shaderType),
    223          mRegisterType(registerType),
    224          mUniformMapOut(uniformMapOut)
    225    {}
    226 
    227    void visitNamedOpaqueObject(const sh::ShaderVariable &sampler,
    228                                const std::string &name,
    229                                const std::string &mappedName,
    230                                const std::vector<unsigned int> &arraySizes) override
    231    {
    232        auto uniformMapEntry = mUniformMapOut->find(name);
    233        if (uniformMapEntry == mUniformMapOut->end())
    234        {
    235            (*mUniformMapOut)[name] =
    236                new D3DUniform(sampler.type, mRegisterType, name, sampler.arraySizes, true);
    237        }
    238    }
    239 
    240    void encodeVariable(const sh::ShaderVariable &variable,
    241                        const sh::BlockMemberInfo &variableInfo,
    242                        const std::string &name,
    243                        const std::string &mappedName) override
    244    {
    245        auto uniformMapEntry   = mUniformMapOut->find(name);
    246        D3DUniform *d3dUniform = nullptr;
    247 
    248        if (uniformMapEntry != mUniformMapOut->end())
    249        {
    250            d3dUniform = uniformMapEntry->second;
    251        }
    252        else
    253        {
    254            d3dUniform =
    255                new D3DUniform(variable.type, mRegisterType, name, variable.arraySizes, true);
    256            (*mUniformMapOut)[name] = d3dUniform;
    257        }
    258 
    259        d3dUniform->registerElement = static_cast<unsigned int>(
    260            sh::BlockLayoutEncoder::GetBlockRegisterElement(variableInfo));
    261        unsigned int reg =
    262            static_cast<unsigned int>(sh::BlockLayoutEncoder::GetBlockRegister(variableInfo));
    263 
    264        ASSERT(mShaderType != gl::ShaderType::InvalidEnum);
    265        d3dUniform->mShaderRegisterIndexes[mShaderType] = reg;
    266    }
    267 
    268  private:
    269    gl::ShaderType mShaderType;
    270    HLSLRegisterType mRegisterType;
    271    D3DUniformMap *mUniformMapOut;
    272 };
    273 
    274 class HLSLBlockLayoutEncoderFactory : public gl::CustomBlockLayoutEncoderFactory
    275 {
    276  public:
    277    sh::BlockLayoutEncoder *makeEncoder() override
    278    {
    279        return new sh::HLSLBlockEncoder(sh::HLSLBlockEncoder::ENCODE_PACKED, false);
    280    }
    281 };
    282 }  // anonymous namespace
    283 
    284 // D3DUniform Implementation
    285 
    286 D3DUniform::D3DUniform(GLenum type,
    287                       HLSLRegisterType reg,
    288                       const std::string &nameIn,
    289                       const std::vector<unsigned int> &arraySizesIn,
    290                       bool defaultBlock)
    291    : typeInfo(gl::GetUniformTypeInfo(type)),
    292      name(nameIn),
    293      arraySizes(arraySizesIn),
    294      mShaderData({}),
    295      regType(reg),
    296      registerCount(0),
    297      registerElement(0)
    298 {
    299    mShaderRegisterIndexes.fill(GL_INVALID_INDEX);
    300 
    301    // We use data storage for default block uniforms to cache values that are sent to D3D during
    302    // rendering
    303    // Uniform blocks/buffers are treated separately by the Renderer (ES3 path only)
    304    if (defaultBlock)
    305    {
    306        // Use the row count as register count, will work for non-square matrices.
    307        registerCount = typeInfo.rowCount * getArraySizeProduct();
    308    }
    309 }
    310 
    311 D3DUniform::~D3DUniform() {}
    312 
    313 unsigned int D3DUniform::getArraySizeProduct() const
    314 {
    315    return gl::ArraySizeProduct(arraySizes);
    316 }
    317 
    318 const uint8_t *D3DUniform::getDataPtrToElement(size_t elementIndex) const
    319 {
    320    ASSERT((!isArray() && elementIndex == 0) ||
    321           (isArray() && elementIndex < getArraySizeProduct()));
    322 
    323    if (isSampler())
    324    {
    325        return reinterpret_cast<const uint8_t *>(&mSamplerData[elementIndex]);
    326    }
    327 
    328    return firstNonNullData() + (elementIndex > 0 ? (typeInfo.internalSize * elementIndex) : 0u);
    329 }
    330 
    331 bool D3DUniform::isSampler() const
    332 {
    333    return typeInfo.isSampler;
    334 }
    335 
    336 bool D3DUniform::isImage() const
    337 {
    338    return typeInfo.isImageType;
    339 }
    340 
    341 bool D3DUniform::isImage2D() const
    342 {
    343    return gl::IsImage2DType(typeInfo.type);
    344 }
    345 
    346 bool D3DUniform::isReferencedByShader(gl::ShaderType shaderType) const
    347 {
    348    return mShaderRegisterIndexes[shaderType] != GL_INVALID_INDEX;
    349 }
    350 
    351 const uint8_t *D3DUniform::firstNonNullData() const
    352 {
    353    if (!mSamplerData.empty())
    354    {
    355        return reinterpret_cast<const uint8_t *>(mSamplerData.data());
    356    }
    357 
    358    for (gl::ShaderType shaderType : gl::AllShaderTypes())
    359    {
    360        if (mShaderData[shaderType])
    361        {
    362            return mShaderData[shaderType];
    363        }
    364    }
    365 
    366    UNREACHABLE();
    367    return nullptr;
    368 }
    369 
    370 // D3DInterfaceBlock Implementation
    371 D3DInterfaceBlock::D3DInterfaceBlock()
    372 {
    373    mShaderRegisterIndexes.fill(GL_INVALID_INDEX);
    374 }
    375 
    376 D3DInterfaceBlock::D3DInterfaceBlock(const D3DInterfaceBlock &other) = default;
    377 
    378 D3DUniformBlock::D3DUniformBlock()
    379 {
    380    mUseStructuredBuffers.fill(false);
    381    mByteWidths.fill(0u);
    382    mStructureByteStrides.fill(0u);
    383 }
    384 
    385 D3DUniformBlock::D3DUniformBlock(const D3DUniformBlock &other) = default;
    386 
    387 // D3DVarying Implementation
    388 
    389 D3DVarying::D3DVarying() : semanticIndex(0), componentCount(0), outputSlot(0) {}
    390 
    391 D3DVarying::D3DVarying(const std::string &semanticNameIn,
    392                       unsigned int semanticIndexIn,
    393                       unsigned int componentCountIn,
    394                       unsigned int outputSlotIn)
    395    : semanticName(semanticNameIn),
    396      semanticIndex(semanticIndexIn),
    397      componentCount(componentCountIn),
    398      outputSlot(outputSlotIn)
    399 {}
    400 
    401 // ProgramD3DMetadata Implementation
    402 
    403 ProgramD3DMetadata::ProgramD3DMetadata(RendererD3D *renderer,
    404                                       const gl::ShaderMap<const ShaderD3D *> &attachedShaders,
    405                                       EGLenum clientType)
    406    : mRendererMajorShaderModel(renderer->getMajorShaderModel()),
    407      mShaderModelSuffix(renderer->getShaderModelSuffix()),
    408      mUsesInstancedPointSpriteEmulation(
    409          renderer->getFeatures().useInstancedPointSpriteEmulation.enabled),
    410      mUsesViewScale(renderer->presentPathFastEnabled()),
    411      mCanSelectViewInVertexShader(renderer->canSelectViewInVertexShader()),
    412      mAttachedShaders(attachedShaders),
    413      mClientType(clientType)
    414 {}
    415 
    416 ProgramD3DMetadata::~ProgramD3DMetadata() = default;
    417 
    418 int ProgramD3DMetadata::getRendererMajorShaderModel() const
    419 {
    420    return mRendererMajorShaderModel;
    421 }
    422 
    423 bool ProgramD3DMetadata::usesBroadcast(const gl::State &data) const
    424 {
    425    const rx::ShaderD3D *shader = mAttachedShaders[gl::ShaderType::Fragment];
    426    return (shader && shader->usesFragColor() && shader->usesMultipleRenderTargets() &&
    427            data.getClientMajorVersion() < 3);
    428 }
    429 
    430 bool ProgramD3DMetadata::usesSecondaryColor() const
    431 {
    432    const rx::ShaderD3D *shader = mAttachedShaders[gl::ShaderType::Fragment];
    433    return (shader && shader->usesSecondaryColor());
    434 }
    435 
    436 bool ProgramD3DMetadata::usesFragDepth() const
    437 {
    438    const rx::ShaderD3D *shader = mAttachedShaders[gl::ShaderType::Fragment];
    439    return (shader && shader->usesFragDepth());
    440 }
    441 
    442 bool ProgramD3DMetadata::usesPointCoord() const
    443 {
    444    const rx::ShaderD3D *shader = mAttachedShaders[gl::ShaderType::Fragment];
    445    return (shader && shader->usesPointCoord());
    446 }
    447 
    448 bool ProgramD3DMetadata::usesFragCoord() const
    449 {
    450    const rx::ShaderD3D *shader = mAttachedShaders[gl::ShaderType::Fragment];
    451    return (shader && shader->usesFragCoord());
    452 }
    453 
    454 bool ProgramD3DMetadata::usesPointSize() const
    455 {
    456    const rx::ShaderD3D *shader = mAttachedShaders[gl::ShaderType::Vertex];
    457    return (shader && shader->usesPointSize());
    458 }
    459 
    460 bool ProgramD3DMetadata::usesInsertedPointCoordValue() const
    461 {
    462    return (!usesPointSize() || !mUsesInstancedPointSpriteEmulation) && usesPointCoord() &&
    463           mRendererMajorShaderModel >= 4;
    464 }
    465 
    466 bool ProgramD3DMetadata::usesViewScale() const
    467 {
    468    return mUsesViewScale;
    469 }
    470 
    471 bool ProgramD3DMetadata::hasANGLEMultiviewEnabled() const
    472 {
    473    const rx::ShaderD3D *shader = mAttachedShaders[gl::ShaderType::Vertex];
    474    return (shader && shader->hasANGLEMultiviewEnabled());
    475 }
    476 
    477 bool ProgramD3DMetadata::usesVertexID() const
    478 {
    479    const rx::ShaderD3D *shader = mAttachedShaders[gl::ShaderType::Vertex];
    480    return (shader && shader->usesVertexID());
    481 }
    482 
    483 bool ProgramD3DMetadata::usesViewID() const
    484 {
    485    const rx::ShaderD3D *shader = mAttachedShaders[gl::ShaderType::Fragment];
    486    return (shader && shader->usesViewID());
    487 }
    488 
    489 bool ProgramD3DMetadata::canSelectViewInVertexShader() const
    490 {
    491    return mCanSelectViewInVertexShader;
    492 }
    493 
    494 bool ProgramD3DMetadata::addsPointCoordToVertexShader() const
    495 {
    496    // PointSprite emulation requiress that gl_PointCoord is present in the vertex shader
    497    // VS_OUTPUT structure to ensure compatibility with the generated PS_INPUT of the pixel shader.
    498    // Even with a geometry shader, the app can render triangles or lines and reference
    499    // gl_PointCoord in the fragment shader, requiring us to provide a placeholder value. For
    500    // simplicity, we always add this to the vertex shader when the fragment shader
    501    // references gl_PointCoord, even if we could skip it in the geometry shader.
    502    return (mUsesInstancedPointSpriteEmulation && usesPointCoord()) ||
    503           usesInsertedPointCoordValue();
    504 }
    505 
    506 bool ProgramD3DMetadata::usesTransformFeedbackGLPosition() const
    507 {
    508    // gl_Position only needs to be outputted from the vertex shader if transform feedback is
    509    // active. This isn't supported on D3D11 Feature Level 9_3, so we don't output gl_Position from
    510    // the vertex shader in this case. This saves us 1 output vector.
    511    return !(mRendererMajorShaderModel >= 4 && mShaderModelSuffix != "");
    512 }
    513 
    514 bool ProgramD3DMetadata::usesSystemValuePointSize() const
    515 {
    516    return !mUsesInstancedPointSpriteEmulation && usesPointSize();
    517 }
    518 
    519 bool ProgramD3DMetadata::usesMultipleFragmentOuts() const
    520 {
    521    const rx::ShaderD3D *shader = mAttachedShaders[gl::ShaderType::Fragment];
    522    return (shader && shader->usesMultipleRenderTargets());
    523 }
    524 
    525 bool ProgramD3DMetadata::usesCustomOutVars() const
    526 {
    527 
    528    const rx::ShaderD3D *shader = mAttachedShaders[gl::ShaderType::Vertex];
    529    int version                 = shader ? shader->getState().getShaderVersion() : -1;
    530 
    531    switch (mClientType)
    532    {
    533        case EGL_OPENGL_API:
    534            return version >= 130;
    535        default:
    536            return version >= 300;
    537    }
    538 }
    539 
    540 const ShaderD3D *ProgramD3DMetadata::getFragmentShader() const
    541 {
    542    return mAttachedShaders[gl::ShaderType::Fragment];
    543 }
    544 
    545 // ProgramD3D::GetExecutableTask class
    546 class ProgramD3D::GetExecutableTask : public Closure, public d3d::Context
    547 {
    548  public:
    549    GetExecutableTask(const gl::Context *context, ProgramD3D *program)
    550        : mProgram(program), mContext(context)
    551    {}
    552 
    553    virtual angle::Result run() = 0;
    554 
    555    void operator()() override { mResult = run(); }
    556 
    557    angle::Result getResult() const { return mResult; }
    558    const gl::InfoLog &getInfoLog() const { return mInfoLog; }
    559    ShaderExecutableD3D *getExecutable() { return mExecutable; }
    560 
    561    void handleResult(HRESULT hr,
    562                      const char *message,
    563                      const char *file,
    564                      const char *function,
    565                      unsigned int line) override
    566    {
    567        mStoredHR       = hr;
    568        mStoredMessage  = message;
    569        mStoredFile     = file;
    570        mStoredFunction = function;
    571        mStoredLine     = line;
    572    }
    573 
    574    void popError(d3d::Context *context)
    575    {
    576        ASSERT(mStoredFile);
    577        ASSERT(mStoredFunction);
    578        context->handleResult(mStoredHR, mStoredMessage.c_str(), mStoredFile, mStoredFunction,
    579                              mStoredLine);
    580    }
    581 
    582  protected:
    583    ProgramD3D *mProgram  = nullptr;
    584    angle::Result mResult = angle::Result::Continue;
    585    gl::InfoLog mInfoLog;
    586    ShaderExecutableD3D *mExecutable = nullptr;
    587    HRESULT mStoredHR                = S_OK;
    588    std::string mStoredMessage;
    589    const char *mStoredFile     = nullptr;
    590    const char *mStoredFunction = nullptr;
    591    unsigned int mStoredLine    = 0;
    592    const gl::Context *mContext = nullptr;
    593 };
    594 
    595 // ProgramD3D Implementation
    596 
    597 ProgramD3D::VertexExecutable::VertexExecutable(const gl::InputLayout &inputLayout,
    598                                               const Signature &signature,
    599                                               ShaderExecutableD3D *shaderExecutable)
    600    : mInputs(inputLayout), mSignature(signature), mShaderExecutable(shaderExecutable)
    601 {}
    602 
    603 ProgramD3D::VertexExecutable::~VertexExecutable()
    604 {
    605    SafeDelete(mShaderExecutable);
    606 }
    607 
    608 // static
    609 ProgramD3D::VertexExecutable::HLSLAttribType ProgramD3D::VertexExecutable::GetAttribType(
    610    GLenum type)
    611 {
    612    switch (type)
    613    {
    614        case GL_INT:
    615            return HLSLAttribType::SIGNED_INT;
    616        case GL_UNSIGNED_INT:
    617            return HLSLAttribType::UNSIGNED_INT;
    618        case GL_SIGNED_NORMALIZED:
    619        case GL_UNSIGNED_NORMALIZED:
    620        case GL_FLOAT:
    621            return HLSLAttribType::FLOAT;
    622        default:
    623            UNREACHABLE();
    624            return HLSLAttribType::FLOAT;
    625    }
    626 }
    627 
    628 // static
    629 void ProgramD3D::VertexExecutable::getSignature(RendererD3D *renderer,
    630                                                const gl::InputLayout &inputLayout,
    631                                                Signature *signatureOut)
    632 {
    633    signatureOut->assign(inputLayout.size(), HLSLAttribType::FLOAT);
    634 
    635    for (size_t index = 0; index < inputLayout.size(); ++index)
    636    {
    637        angle::FormatID vertexFormatID = inputLayout[index];
    638        if (vertexFormatID == angle::FormatID::NONE)
    639            continue;
    640 
    641        VertexConversionType conversionType = renderer->getVertexConversionType(vertexFormatID);
    642        if ((conversionType & VERTEX_CONVERT_GPU) == 0)
    643            continue;
    644 
    645        GLenum componentType   = renderer->getVertexComponentType(vertexFormatID);
    646        (*signatureOut)[index] = GetAttribType(componentType);
    647    }
    648 }
    649 
    650 bool ProgramD3D::VertexExecutable::matchesSignature(const Signature &signature) const
    651 {
    652    size_t limit = std::max(mSignature.size(), signature.size());
    653    for (size_t index = 0; index < limit; ++index)
    654    {
    655        // treat undefined indexes as FLOAT
    656        auto a = index < signature.size() ? signature[index] : HLSLAttribType::FLOAT;
    657        auto b = index < mSignature.size() ? mSignature[index] : HLSLAttribType::FLOAT;
    658        if (a != b)
    659            return false;
    660    }
    661 
    662    return true;
    663 }
    664 
    665 ProgramD3D::PixelExecutable::PixelExecutable(const std::vector<GLenum> &outputSignature,
    666                                             ShaderExecutableD3D *shaderExecutable)
    667    : mOutputSignature(outputSignature), mShaderExecutable(shaderExecutable)
    668 {}
    669 
    670 ProgramD3D::PixelExecutable::~PixelExecutable()
    671 {
    672    SafeDelete(mShaderExecutable);
    673 }
    674 
    675 ProgramD3D::ComputeExecutable::ComputeExecutable(
    676    const gl::ImageUnitTextureTypeMap &signature,
    677    std::unique_ptr<ShaderExecutableD3D> shaderExecutable)
    678    : mSignature(signature), mShaderExecutable(std::move(shaderExecutable))
    679 {}
    680 
    681 ProgramD3D::ComputeExecutable::~ComputeExecutable() {}
    682 
    683 ProgramD3D::Sampler::Sampler()
    684    : active(false), logicalTextureUnit(0), textureType(gl::TextureType::_2D)
    685 {}
    686 
    687 ProgramD3D::Image::Image() : active(false), logicalImageUnit(0) {}
    688 
    689 unsigned int ProgramD3D::mCurrentSerial = 1;
    690 
    691 ProgramD3D::ProgramD3D(const gl::ProgramState &state, RendererD3D *renderer)
    692    : ProgramImpl(state),
    693      mRenderer(renderer),
    694      mDynamicHLSL(nullptr),
    695      mUsesPointSize(false),
    696      mUsesFlatInterpolation(false),
    697      mUsedShaderSamplerRanges({}),
    698      mDirtySamplerMapping(true),
    699      mUsedImageRange({}),
    700      mUsedReadonlyImageRange({}),
    701      mUsedAtomicCounterRange({}),
    702      mSerial(issueSerial())
    703 {
    704    mDynamicHLSL = new DynamicHLSL(renderer);
    705 }
    706 
    707 ProgramD3D::~ProgramD3D()
    708 {
    709    reset();
    710    SafeDelete(mDynamicHLSL);
    711 }
    712 
    713 bool ProgramD3D::usesPointSpriteEmulation() const
    714 {
    715    return mUsesPointSize && mRenderer->getMajorShaderModel() >= 4;
    716 }
    717 
    718 bool ProgramD3D::usesGeometryShaderForPointSpriteEmulation() const
    719 {
    720    return usesPointSpriteEmulation() && !usesInstancedPointSpriteEmulation();
    721 }
    722 
    723 bool ProgramD3D::usesGetDimensionsIgnoresBaseLevel() const
    724 {
    725    return mRenderer->getFeatures().getDimensionsIgnoresBaseLevel.enabled;
    726 }
    727 
    728 bool ProgramD3D::usesGeometryShader(const gl::State &state, const gl::PrimitiveMode drawMode) const
    729 {
    730    if (mHasANGLEMultiviewEnabled && !mRenderer->canSelectViewInVertexShader())
    731    {
    732        return true;
    733    }
    734    if (drawMode != gl::PrimitiveMode::Points)
    735    {
    736        if (!mUsesFlatInterpolation)
    737        {
    738            return false;
    739        }
    740        return state.getProvokingVertex() == gl::ProvokingVertexConvention::LastVertexConvention;
    741    }
    742    return usesGeometryShaderForPointSpriteEmulation();
    743 }
    744 
    745 bool ProgramD3D::usesInstancedPointSpriteEmulation() const
    746 {
    747    return mRenderer->getFeatures().useInstancedPointSpriteEmulation.enabled;
    748 }
    749 
    750 GLint ProgramD3D::getSamplerMapping(gl::ShaderType type,
    751                                    unsigned int samplerIndex,
    752                                    const gl::Caps &caps) const
    753 {
    754    GLint logicalTextureUnit = -1;
    755 
    756    ASSERT(type != gl::ShaderType::InvalidEnum);
    757 
    758    ASSERT(samplerIndex < static_cast<unsigned int>(caps.maxShaderTextureImageUnits[type]));
    759 
    760    const auto &samplers = mShaderSamplers[type];
    761    if (samplerIndex < samplers.size() && samplers[samplerIndex].active)
    762    {
    763        logicalTextureUnit = samplers[samplerIndex].logicalTextureUnit;
    764    }
    765 
    766    if (logicalTextureUnit >= 0 && logicalTextureUnit < caps.maxCombinedTextureImageUnits)
    767    {
    768        return logicalTextureUnit;
    769    }
    770 
    771    return -1;
    772 }
    773 
    774 // Returns the texture type for a given Direct3D 9 sampler type and
    775 // index (0-15 for the pixel shader and 0-3 for the vertex shader).
    776 gl::TextureType ProgramD3D::getSamplerTextureType(gl::ShaderType type,
    777                                                  unsigned int samplerIndex) const
    778 {
    779    ASSERT(type != gl::ShaderType::InvalidEnum);
    780 
    781    const auto &samplers = mShaderSamplers[type];
    782    ASSERT(samplerIndex < samplers.size());
    783    ASSERT(samplers[samplerIndex].active);
    784 
    785    return samplers[samplerIndex].textureType;
    786 }
    787 
    788 gl::RangeUI ProgramD3D::getUsedSamplerRange(gl::ShaderType type) const
    789 {
    790    ASSERT(type != gl::ShaderType::InvalidEnum);
    791    return mUsedShaderSamplerRanges[type];
    792 }
    793 
    794 ProgramD3D::SamplerMapping ProgramD3D::updateSamplerMapping()
    795 {
    796    if (!mDirtySamplerMapping)
    797    {
    798        return SamplerMapping::WasClean;
    799    }
    800 
    801    mDirtySamplerMapping = false;
    802 
    803    // Retrieve sampler uniform values
    804    for (const D3DUniform *d3dUniform : mD3DUniforms)
    805    {
    806        if (!d3dUniform->isSampler())
    807            continue;
    808 
    809        int count = d3dUniform->getArraySizeProduct();
    810 
    811        for (gl::ShaderType shaderType : gl::AllShaderTypes())
    812        {
    813            if (!d3dUniform->isReferencedByShader(shaderType))
    814            {
    815                continue;
    816            }
    817 
    818            unsigned int firstIndex = d3dUniform->mShaderRegisterIndexes[shaderType];
    819 
    820            std::vector<Sampler> &samplers = mShaderSamplers[shaderType];
    821            for (int i = 0; i < count; i++)
    822            {
    823                unsigned int samplerIndex = firstIndex + i;
    824 
    825                if (samplerIndex < samplers.size())
    826                {
    827                    ASSERT(samplers[samplerIndex].active);
    828                    samplers[samplerIndex].logicalTextureUnit = d3dUniform->mSamplerData[i];
    829                }
    830            }
    831        }
    832    }
    833 
    834    return SamplerMapping::WasDirty;
    835 }
    836 
    837 GLint ProgramD3D::getImageMapping(gl::ShaderType type,
    838                                  unsigned int imageIndex,
    839                                  bool readonly,
    840                                  const gl::Caps &caps) const
    841 {
    842    GLint logicalImageUnit = -1;
    843    ASSERT(imageIndex < static_cast<unsigned int>(caps.maxImageUnits));
    844    if (readonly && imageIndex < mReadonlyImages[type].size() &&
    845        mReadonlyImages[type][imageIndex].active)
    846    {
    847        logicalImageUnit = mReadonlyImages[type][imageIndex].logicalImageUnit;
    848    }
    849    else if (imageIndex < mImages[type].size() && mImages[type][imageIndex].active)
    850    {
    851        logicalImageUnit = mImages[type][imageIndex].logicalImageUnit;
    852    }
    853 
    854    if (logicalImageUnit >= 0 && logicalImageUnit < caps.maxImageUnits)
    855    {
    856        return logicalImageUnit;
    857    }
    858 
    859    return -1;
    860 }
    861 
    862 gl::RangeUI ProgramD3D::getUsedImageRange(gl::ShaderType type, bool readonly) const
    863 {
    864    return readonly ? mUsedReadonlyImageRange[type] : mUsedImageRange[type];
    865 }
    866 
    867 class ProgramD3D::LoadBinaryTask : public ProgramD3D::GetExecutableTask
    868 {
    869  public:
    870    LoadBinaryTask(const gl::Context *context,
    871                   ProgramD3D *program,
    872                   gl::BinaryInputStream *stream,
    873                   gl::InfoLog &infoLog)
    874        : ProgramD3D::GetExecutableTask(context, program)
    875    {
    876        ASSERT(mProgram);
    877        ASSERT(stream);
    878 
    879        // Copy the remaining data from the stream locally so that the client can't modify it when
    880        // loading off thread.
    881        size_t dataSize    = stream->remainingSize();
    882        mDataCopySucceeded = mStreamData.resize(dataSize);
    883        if (mDataCopySucceeded)
    884        {
    885            memcpy(mStreamData.data(), stream->data() + stream->offset(), dataSize);
    886        }
    887    }
    888 
    889    angle::Result run() override
    890    {
    891        ANGLE_TRACE_EVENT0("gpu.angle", "ProgramD3D::LoadBinaryTask::run");
    892        if (!mDataCopySucceeded)
    893        {
    894            mInfoLog << "Failed to copy program binary data to local buffer.";
    895            return angle::Result::Incomplete;
    896        }
    897 
    898        gl::BinaryInputStream stream(mStreamData.data(), mStreamData.size());
    899        return mProgram->loadBinaryShaderExecutables(this, &stream, mInfoLog);
    900    }
    901 
    902  private:
    903    bool mDataCopySucceeded;
    904    angle::MemoryBuffer mStreamData;
    905 };
    906 
    907 class ProgramD3D::LoadBinaryLinkEvent final : public LinkEvent
    908 {
    909  public:
    910    LoadBinaryLinkEvent(const gl::Context *context,
    911                        std::shared_ptr<WorkerThreadPool> workerPool,
    912                        ProgramD3D *program,
    913                        gl::BinaryInputStream *stream,
    914                        gl::InfoLog &infoLog)
    915        : mTask(std::make_shared<ProgramD3D::LoadBinaryTask>(context, program, stream, infoLog)),
    916          mWaitableEvent(angle::WorkerThreadPool::PostWorkerTask(workerPool, mTask))
    917    {}
    918 
    919    angle::Result wait(const gl::Context *context) override
    920    {
    921        mWaitableEvent->wait();
    922 
    923        // Continue and Incomplete are not errors. For Stop, pass the error to the ContextD3D.
    924        if (mTask->getResult() != angle::Result::Stop)
    925        {
    926            return angle::Result::Continue;
    927        }
    928 
    929        ContextD3D *contextD3D = GetImplAs<ContextD3D>(context);
    930        mTask->popError(contextD3D);
    931        return angle::Result::Stop;
    932    }
    933 
    934    bool isLinking() override { return !mWaitableEvent->isReady(); }
    935 
    936  private:
    937    std::shared_ptr<ProgramD3D::LoadBinaryTask> mTask;
    938    std::shared_ptr<WaitableEvent> mWaitableEvent;
    939 };
    940 
    941 std::unique_ptr<rx::LinkEvent> ProgramD3D::load(const gl::Context *context,
    942                                                gl::BinaryInputStream *stream,
    943                                                gl::InfoLog &infoLog)
    944 {
    945 
    946    // TODO(jmadill): Use Renderer from contextImpl.
    947 
    948    reset();
    949 
    950    DeviceIdentifier binaryDeviceIdentifier = {};
    951    stream->readBytes(reinterpret_cast<unsigned char *>(&binaryDeviceIdentifier),
    952                      sizeof(DeviceIdentifier));
    953 
    954    DeviceIdentifier identifier = mRenderer->getAdapterIdentifier();
    955    if (memcmp(&identifier, &binaryDeviceIdentifier, sizeof(DeviceIdentifier)) != 0)
    956    {
    957        infoLog << "Invalid program binary, device configuration has changed.";
    958        return nullptr;
    959    }
    960 
    961    int compileFlags = stream->readInt<int>();
    962    if (compileFlags != ANGLE_COMPILE_OPTIMIZATION_LEVEL)
    963    {
    964        infoLog << "Mismatched compilation flags.";
    965        return nullptr;
    966    }
    967 
    968    for (int &index : mAttribLocationToD3DSemantic)
    969    {
    970        stream->readInt(&index);
    971    }
    972 
    973    for (gl::ShaderType shaderType : gl::AllShaderTypes())
    974    {
    975        size_t samplerCount = stream->readInt<size_t>();
    976        for (size_t sampleIndex = 0; sampleIndex < samplerCount; ++sampleIndex)
    977        {
    978            Sampler sampler;
    979            stream->readBool(&sampler.active);
    980            stream->readInt(&sampler.logicalTextureUnit);
    981            stream->readEnum(&sampler.textureType);
    982            mShaderSamplers[shaderType].push_back(sampler);
    983        }
    984 
    985        unsigned int samplerRangeLow, samplerRangeHigh;
    986        stream->readInt(&samplerRangeLow);
    987        stream->readInt(&samplerRangeHigh);
    988        mUsedShaderSamplerRanges[shaderType] = gl::RangeUI(samplerRangeLow, samplerRangeHigh);
    989    }
    990 
    991    for (gl::ShaderType shaderType : {gl::ShaderType::Compute, gl::ShaderType::Fragment})
    992    {
    993        size_t imageCount = stream->readInt<size_t>();
    994        for (size_t imageIndex = 0; imageIndex < imageCount; ++imageIndex)
    995        {
    996            Image image;
    997            stream->readBool(&image.active);
    998            stream->readInt(&image.logicalImageUnit);
    999            mImages[shaderType].push_back(image);
   1000        }
   1001 
   1002        size_t readonlyImageCount = stream->readInt<size_t>();
   1003        for (size_t imageIndex = 0; imageIndex < readonlyImageCount; ++imageIndex)
   1004        {
   1005            Image image;
   1006            stream->readBool(&image.active);
   1007            stream->readInt(&image.logicalImageUnit);
   1008            mReadonlyImages[shaderType].push_back(image);
   1009        }
   1010 
   1011        unsigned int imageRangeLow, imageRangeHigh, readonlyImageRangeLow, readonlyImageRangeHigh;
   1012        stream->readInt(&imageRangeLow);
   1013        stream->readInt(&imageRangeHigh);
   1014        stream->readInt(&readonlyImageRangeLow);
   1015        stream->readInt(&readonlyImageRangeHigh);
   1016        mUsedImageRange[shaderType] = gl::RangeUI(imageRangeLow, imageRangeHigh);
   1017        mUsedReadonlyImageRange[shaderType] =
   1018            gl::RangeUI(readonlyImageRangeLow, readonlyImageRangeHigh);
   1019 
   1020        unsigned int atomicCounterRangeLow, atomicCounterRangeHigh;
   1021        stream->readInt(&atomicCounterRangeLow);
   1022        stream->readInt(&atomicCounterRangeHigh);
   1023        mUsedAtomicCounterRange[shaderType] =
   1024            gl::RangeUI(atomicCounterRangeLow, atomicCounterRangeHigh);
   1025    }
   1026 
   1027    size_t shaderStorageBlockCount = stream->readInt<size_t>();
   1028    if (stream->error())
   1029    {
   1030        infoLog << "Invalid program binary.";
   1031        return nullptr;
   1032    }
   1033 
   1034    ASSERT(mD3DShaderStorageBlocks.empty());
   1035    for (size_t blockIndex = 0; blockIndex < shaderStorageBlockCount; ++blockIndex)
   1036    {
   1037        D3DInterfaceBlock shaderStorageBlock;
   1038        for (gl::ShaderType shaderType : gl::AllShaderTypes())
   1039        {
   1040            stream->readInt(&shaderStorageBlock.mShaderRegisterIndexes[shaderType]);
   1041        }
   1042        mD3DShaderStorageBlocks.push_back(shaderStorageBlock);
   1043    }
   1044 
   1045    for (gl::ShaderType shaderType : {gl::ShaderType::Compute, gl::ShaderType::Fragment})
   1046    {
   1047        size_t image2DUniformCount = stream->readInt<size_t>();
   1048        if (stream->error())
   1049        {
   1050            infoLog << "Invalid program binary.";
   1051            return nullptr;
   1052        }
   1053 
   1054        ASSERT(mImage2DUniforms[shaderType].empty());
   1055        for (size_t image2DUniformIndex = 0; image2DUniformIndex < image2DUniformCount;
   1056             ++image2DUniformIndex)
   1057        {
   1058            sh::ShaderVariable image2Duniform;
   1059            gl::LoadShaderVar(stream, &image2Duniform);
   1060            mImage2DUniforms[shaderType].push_back(image2Duniform);
   1061        }
   1062    }
   1063 
   1064    for (unsigned int ii = 0; ii < gl::IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS; ++ii)
   1065    {
   1066        unsigned int index                             = stream->readInt<unsigned int>();
   1067        mComputeAtomicCounterBufferRegisterIndices[ii] = index;
   1068    }
   1069 
   1070    size_t uniformCount = stream->readInt<size_t>();
   1071    if (stream->error())
   1072    {
   1073        infoLog << "Invalid program binary.";
   1074        return nullptr;
   1075    }
   1076 
   1077    const auto &linkedUniforms = mState.getUniforms();
   1078    ASSERT(mD3DUniforms.empty());
   1079    for (size_t uniformIndex = 0; uniformIndex < uniformCount; uniformIndex++)
   1080    {
   1081        const gl::LinkedUniform &linkedUniform = linkedUniforms[uniformIndex];
   1082 
   1083        D3DUniform *d3dUniform =
   1084            new D3DUniform(linkedUniform.type, HLSLRegisterType::None, linkedUniform.name,
   1085                           linkedUniform.arraySizes, linkedUniform.isInDefaultBlock());
   1086        stream->readEnum(&d3dUniform->regType);
   1087        for (gl::ShaderType shaderType : gl::AllShaderTypes())
   1088        {
   1089            stream->readInt(&d3dUniform->mShaderRegisterIndexes[shaderType]);
   1090        }
   1091        stream->readInt(&d3dUniform->registerCount);
   1092        stream->readInt(&d3dUniform->registerElement);
   1093 
   1094        mD3DUniforms.push_back(d3dUniform);
   1095    }
   1096 
   1097    size_t blockCount = stream->readInt<size_t>();
   1098    if (stream->error())
   1099    {
   1100        infoLog << "Invalid program binary.";
   1101        return nullptr;
   1102    }
   1103 
   1104    ASSERT(mD3DUniformBlocks.empty());
   1105    for (size_t blockIndex = 0; blockIndex < blockCount; ++blockIndex)
   1106    {
   1107        D3DUniformBlock uniformBlock;
   1108        for (gl::ShaderType shaderType : gl::AllShaderTypes())
   1109        {
   1110            stream->readInt(&uniformBlock.mShaderRegisterIndexes[shaderType]);
   1111            stream->readBool(&uniformBlock.mUseStructuredBuffers[shaderType]);
   1112            stream->readInt(&uniformBlock.mByteWidths[shaderType]);
   1113            stream->readInt(&uniformBlock.mStructureByteStrides[shaderType]);
   1114        }
   1115        mD3DUniformBlocks.push_back(uniformBlock);
   1116    }
   1117 
   1118    size_t streamOutVaryingCount = stream->readInt<size_t>();
   1119    mStreamOutVaryings.resize(streamOutVaryingCount);
   1120    for (size_t varyingIndex = 0; varyingIndex < streamOutVaryingCount; ++varyingIndex)
   1121    {
   1122        D3DVarying *varying = &mStreamOutVaryings[varyingIndex];
   1123 
   1124        stream->readString(&varying->semanticName);
   1125        stream->readInt(&varying->semanticIndex);
   1126        stream->readInt(&varying->componentCount);
   1127        stream->readInt(&varying->outputSlot);
   1128    }
   1129 
   1130    for (gl::ShaderType shaderType : gl::AllShaderTypes())
   1131    {
   1132        stream->readString(&mShaderHLSL[shaderType]);
   1133        stream->readBytes(reinterpret_cast<unsigned char *>(&mShaderWorkarounds[shaderType]),
   1134                          sizeof(CompilerWorkaroundsD3D));
   1135    }
   1136 
   1137    stream->readBool(&mUsesFragDepth);
   1138    stream->readBool(&mHasANGLEMultiviewEnabled);
   1139    stream->readBool(&mUsesVertexID);
   1140    stream->readBool(&mUsesViewID);
   1141    stream->readBool(&mUsesPointSize);
   1142    stream->readBool(&mUsesFlatInterpolation);
   1143 
   1144    const size_t pixelShaderKeySize = stream->readInt<size_t>();
   1145    mPixelShaderKey.resize(pixelShaderKeySize);
   1146    for (size_t pixelShaderKeyIndex = 0; pixelShaderKeyIndex < pixelShaderKeySize;
   1147         pixelShaderKeyIndex++)
   1148    {
   1149        stream->readInt(&mPixelShaderKey[pixelShaderKeyIndex].type);
   1150        stream->readString(&mPixelShaderKey[pixelShaderKeyIndex].name);
   1151        stream->readString(&mPixelShaderKey[pixelShaderKeyIndex].source);
   1152        stream->readInt(&mPixelShaderKey[pixelShaderKeyIndex].outputLocation);
   1153        stream->readInt(&mPixelShaderKey[pixelShaderKeyIndex].outputIndex);
   1154    }
   1155 
   1156    stream->readString(&mGeometryShaderPreamble);
   1157 
   1158    return std::make_unique<LoadBinaryLinkEvent>(context, context->getWorkerThreadPool(), this,
   1159                                                 stream, infoLog);
   1160 }
   1161 
   1162 angle::Result ProgramD3D::loadBinaryShaderExecutables(d3d::Context *contextD3D,
   1163                                                      gl::BinaryInputStream *stream,
   1164                                                      gl::InfoLog &infoLog)
   1165 {
   1166    const unsigned char *binary = reinterpret_cast<const unsigned char *>(stream->data());
   1167 
   1168    bool separateAttribs = (mState.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS);
   1169 
   1170    size_t vertexShaderCount = stream->readInt<size_t>();
   1171    for (size_t vertexShaderIndex = 0; vertexShaderIndex < vertexShaderCount; vertexShaderIndex++)
   1172    {
   1173        size_t inputLayoutSize = stream->readInt<size_t>();
   1174        gl::InputLayout inputLayout(inputLayoutSize, angle::FormatID::NONE);
   1175 
   1176        for (size_t inputIndex = 0; inputIndex < inputLayoutSize; inputIndex++)
   1177        {
   1178            inputLayout[inputIndex] = stream->readEnum<angle::FormatID>();
   1179        }
   1180 
   1181        size_t vertexShaderSize                   = stream->readInt<size_t>();
   1182        const unsigned char *vertexShaderFunction = binary + stream->offset();
   1183 
   1184        ShaderExecutableD3D *shaderExecutable = nullptr;
   1185 
   1186        ANGLE_TRY(mRenderer->loadExecutable(contextD3D, vertexShaderFunction, vertexShaderSize,
   1187                                            gl::ShaderType::Vertex, mStreamOutVaryings,
   1188                                            separateAttribs, &shaderExecutable));
   1189 
   1190        if (!shaderExecutable)
   1191        {
   1192            infoLog << "Could not create vertex shader.";
   1193            return angle::Result::Incomplete;
   1194        }
   1195 
   1196        // generated converted input layout
   1197        VertexExecutable::Signature signature;
   1198        VertexExecutable::getSignature(mRenderer, inputLayout, &signature);
   1199 
   1200        // add new binary
   1201        mVertexExecutables.push_back(std::unique_ptr<VertexExecutable>(
   1202            new VertexExecutable(inputLayout, signature, shaderExecutable)));
   1203 
   1204        stream->skip(vertexShaderSize);
   1205    }
   1206 
   1207    size_t pixelShaderCount = stream->readInt<size_t>();
   1208    for (size_t pixelShaderIndex = 0; pixelShaderIndex < pixelShaderCount; pixelShaderIndex++)
   1209    {
   1210        size_t outputCount = stream->readInt<size_t>();
   1211        std::vector<GLenum> outputs(outputCount);
   1212        for (size_t outputIndex = 0; outputIndex < outputCount; outputIndex++)
   1213        {
   1214            stream->readInt(&outputs[outputIndex]);
   1215        }
   1216 
   1217        size_t pixelShaderSize                   = stream->readInt<size_t>();
   1218        const unsigned char *pixelShaderFunction = binary + stream->offset();
   1219        ShaderExecutableD3D *shaderExecutable    = nullptr;
   1220 
   1221        ANGLE_TRY(mRenderer->loadExecutable(contextD3D, pixelShaderFunction, pixelShaderSize,
   1222                                            gl::ShaderType::Fragment, mStreamOutVaryings,
   1223                                            separateAttribs, &shaderExecutable));
   1224 
   1225        if (!shaderExecutable)
   1226        {
   1227            infoLog << "Could not create pixel shader.";
   1228            return angle::Result::Incomplete;
   1229        }
   1230 
   1231        // add new binary
   1232        mPixelExecutables.push_back(
   1233            std::unique_ptr<PixelExecutable>(new PixelExecutable(outputs, shaderExecutable)));
   1234 
   1235        stream->skip(pixelShaderSize);
   1236    }
   1237 
   1238    for (std::unique_ptr<ShaderExecutableD3D> &geometryExe : mGeometryExecutables)
   1239    {
   1240        size_t geometryShaderSize = stream->readInt<size_t>();
   1241        if (geometryShaderSize == 0)
   1242        {
   1243            continue;
   1244        }
   1245 
   1246        const unsigned char *geometryShaderFunction = binary + stream->offset();
   1247 
   1248        ShaderExecutableD3D *geometryExecutable = nullptr;
   1249        ANGLE_TRY(mRenderer->loadExecutable(contextD3D, geometryShaderFunction, geometryShaderSize,
   1250                                            gl::ShaderType::Geometry, mStreamOutVaryings,
   1251                                            separateAttribs, &geometryExecutable));
   1252 
   1253        if (!geometryExecutable)
   1254        {
   1255            infoLog << "Could not create geometry shader.";
   1256            return angle::Result::Incomplete;
   1257        }
   1258 
   1259        geometryExe.reset(geometryExecutable);
   1260 
   1261        stream->skip(geometryShaderSize);
   1262    }
   1263 
   1264    size_t computeShaderCount = stream->readInt<size_t>();
   1265    for (size_t computeShaderIndex = 0; computeShaderIndex < computeShaderCount;
   1266         computeShaderIndex++)
   1267    {
   1268        size_t signatureCount = stream->readInt<size_t>();
   1269        gl::ImageUnitTextureTypeMap signatures;
   1270        for (size_t signatureIndex = 0; signatureIndex < signatureCount; signatureIndex++)
   1271        {
   1272            unsigned int imageUint;
   1273            gl::TextureType textureType;
   1274            stream->readInt(&imageUint);
   1275            stream->readEnum(&textureType);
   1276            signatures.insert(std::pair<unsigned int, gl::TextureType>(imageUint, textureType));
   1277        }
   1278 
   1279        size_t computeShaderSize                   = stream->readInt<size_t>();
   1280        const unsigned char *computeShaderFunction = binary + stream->offset();
   1281 
   1282        ShaderExecutableD3D *computeExecutable = nullptr;
   1283        ANGLE_TRY(mRenderer->loadExecutable(contextD3D, computeShaderFunction, computeShaderSize,
   1284                                            gl::ShaderType::Compute, std::vector<D3DVarying>(),
   1285                                            false, &computeExecutable));
   1286 
   1287        if (!computeExecutable)
   1288        {
   1289            infoLog << "Could not create compute shader.";
   1290            return angle::Result::Incomplete;
   1291        }
   1292 
   1293        // add new binary
   1294        mComputeExecutables.push_back(std::unique_ptr<ComputeExecutable>(new ComputeExecutable(
   1295            signatures, std::unique_ptr<ShaderExecutableD3D>(computeExecutable))));
   1296 
   1297        stream->skip(computeShaderSize);
   1298    }
   1299 
   1300    size_t bindLayoutCount = stream->readInt<size_t>();
   1301    for (size_t bindLayoutIndex = 0; bindLayoutIndex < bindLayoutCount; bindLayoutIndex++)
   1302    {
   1303        mImage2DBindLayoutCache[gl::ShaderType::Compute].insert(
   1304            std::pair<unsigned int, gl::TextureType>(stream->readInt<unsigned int>(),
   1305                                                     gl::TextureType::_2D));
   1306    }
   1307 
   1308    initializeUniformStorage(mState.getExecutable().getLinkedShaderStages());
   1309 
   1310    dirtyAllUniforms();
   1311 
   1312    return angle::Result::Continue;
   1313 }
   1314 
   1315 void ProgramD3D::save(const gl::Context *context, gl::BinaryOutputStream *stream)
   1316 {
   1317    // Output the DeviceIdentifier before we output any shader code
   1318    // When we load the binary again later, we can validate the device identifier before trying to
   1319    // compile any HLSL
   1320    DeviceIdentifier binaryIdentifier = mRenderer->getAdapterIdentifier();
   1321    stream->writeBytes(reinterpret_cast<unsigned char *>(&binaryIdentifier),
   1322                       sizeof(DeviceIdentifier));
   1323 
   1324    stream->writeInt(ANGLE_COMPILE_OPTIMIZATION_LEVEL);
   1325 
   1326    for (int d3dSemantic : mAttribLocationToD3DSemantic)
   1327    {
   1328        stream->writeInt(d3dSemantic);
   1329    }
   1330 
   1331    for (gl::ShaderType shaderType : gl::AllShaderTypes())
   1332    {
   1333        stream->writeInt(mShaderSamplers[shaderType].size());
   1334        for (unsigned int i = 0; i < mShaderSamplers[shaderType].size(); ++i)
   1335        {
   1336            stream->writeBool(mShaderSamplers[shaderType][i].active);
   1337            stream->writeInt(mShaderSamplers[shaderType][i].logicalTextureUnit);
   1338            stream->writeEnum(mShaderSamplers[shaderType][i].textureType);
   1339        }
   1340 
   1341        stream->writeInt(mUsedShaderSamplerRanges[shaderType].low());
   1342        stream->writeInt(mUsedShaderSamplerRanges[shaderType].high());
   1343    }
   1344 
   1345    for (gl::ShaderType shaderType : {gl::ShaderType::Compute, gl::ShaderType::Fragment})
   1346    {
   1347        stream->writeInt(mImages[shaderType].size());
   1348        for (size_t imageIndex = 0; imageIndex < mImages[shaderType].size(); ++imageIndex)
   1349        {
   1350            stream->writeBool(mImages[shaderType][imageIndex].active);
   1351            stream->writeInt(mImages[shaderType][imageIndex].logicalImageUnit);
   1352        }
   1353 
   1354        stream->writeInt(mReadonlyImages[shaderType].size());
   1355        for (size_t imageIndex = 0; imageIndex < mReadonlyImages[shaderType].size(); ++imageIndex)
   1356        {
   1357            stream->writeBool(mReadonlyImages[shaderType][imageIndex].active);
   1358            stream->writeInt(mReadonlyImages[shaderType][imageIndex].logicalImageUnit);
   1359        }
   1360 
   1361        stream->writeInt(mUsedImageRange[shaderType].low());
   1362        stream->writeInt(mUsedImageRange[shaderType].high());
   1363        stream->writeInt(mUsedReadonlyImageRange[shaderType].low());
   1364        stream->writeInt(mUsedReadonlyImageRange[shaderType].high());
   1365        stream->writeInt(mUsedAtomicCounterRange[shaderType].low());
   1366        stream->writeInt(mUsedAtomicCounterRange[shaderType].high());
   1367    }
   1368 
   1369    stream->writeInt(mD3DShaderStorageBlocks.size());
   1370    for (const D3DInterfaceBlock &shaderStorageBlock : mD3DShaderStorageBlocks)
   1371    {
   1372        for (gl::ShaderType shaderType : gl::AllShaderTypes())
   1373        {
   1374            stream->writeIntOrNegOne(shaderStorageBlock.mShaderRegisterIndexes[shaderType]);
   1375        }
   1376    }
   1377 
   1378    for (gl::ShaderType shaderType : {gl::ShaderType::Compute, gl::ShaderType::Fragment})
   1379    {
   1380        stream->writeInt(mImage2DUniforms[shaderType].size());
   1381        for (const sh::ShaderVariable &image2DUniform : mImage2DUniforms[shaderType])
   1382        {
   1383            gl::WriteShaderVar(stream, image2DUniform);
   1384        }
   1385    }
   1386 
   1387    for (unsigned int ii = 0; ii < gl::IMPLEMENTATION_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS; ++ii)
   1388    {
   1389        stream->writeInt(mComputeAtomicCounterBufferRegisterIndices[ii]);
   1390    }
   1391 
   1392    stream->writeInt(mD3DUniforms.size());
   1393    for (const D3DUniform *uniform : mD3DUniforms)
   1394    {
   1395        // Type, name and arraySize are redundant, so aren't stored in the binary.
   1396        stream->writeEnum(uniform->regType);
   1397        for (gl::ShaderType shaderType : gl::AllShaderTypes())
   1398        {
   1399            stream->writeIntOrNegOne(uniform->mShaderRegisterIndexes[shaderType]);
   1400        }
   1401        stream->writeInt(uniform->registerCount);
   1402        stream->writeInt(uniform->registerElement);
   1403    }
   1404 
   1405    stream->writeInt(mD3DUniformBlocks.size());
   1406    for (const D3DUniformBlock &uniformBlock : mD3DUniformBlocks)
   1407    {
   1408        for (gl::ShaderType shaderType : gl::AllShaderTypes())
   1409        {
   1410            stream->writeIntOrNegOne(uniformBlock.mShaderRegisterIndexes[shaderType]);
   1411            stream->writeBool(uniformBlock.mUseStructuredBuffers[shaderType]);
   1412            stream->writeInt(uniformBlock.mByteWidths[shaderType]);
   1413            stream->writeInt(uniformBlock.mStructureByteStrides[shaderType]);
   1414        }
   1415    }
   1416 
   1417    stream->writeInt(mStreamOutVaryings.size());
   1418    for (const D3DVarying &varying : mStreamOutVaryings)
   1419    {
   1420        stream->writeString(varying.semanticName);
   1421        stream->writeInt(varying.semanticIndex);
   1422        stream->writeInt(varying.componentCount);
   1423        stream->writeInt(varying.outputSlot);
   1424    }
   1425 
   1426    for (gl::ShaderType shaderType : gl::AllShaderTypes())
   1427    {
   1428        stream->writeString(mShaderHLSL[shaderType]);
   1429        stream->writeBytes(reinterpret_cast<unsigned char *>(&mShaderWorkarounds[shaderType]),
   1430                           sizeof(CompilerWorkaroundsD3D));
   1431    }
   1432 
   1433    stream->writeBool(mUsesFragDepth);
   1434    stream->writeBool(mHasANGLEMultiviewEnabled);
   1435    stream->writeBool(mUsesVertexID);
   1436    stream->writeBool(mUsesViewID);
   1437    stream->writeBool(mUsesPointSize);
   1438    stream->writeBool(mUsesFlatInterpolation);
   1439 
   1440    const std::vector<PixelShaderOutputVariable> &pixelShaderKey = mPixelShaderKey;
   1441    stream->writeInt(pixelShaderKey.size());
   1442    for (size_t pixelShaderKeyIndex = 0; pixelShaderKeyIndex < pixelShaderKey.size();
   1443         pixelShaderKeyIndex++)
   1444    {
   1445        const PixelShaderOutputVariable &variable = pixelShaderKey[pixelShaderKeyIndex];
   1446        stream->writeInt(variable.type);
   1447        stream->writeString(variable.name);
   1448        stream->writeString(variable.source);
   1449        stream->writeInt(variable.outputLocation);
   1450        stream->writeInt(variable.outputIndex);
   1451    }
   1452 
   1453    stream->writeString(mGeometryShaderPreamble);
   1454 
   1455    stream->writeInt(mVertexExecutables.size());
   1456    for (size_t vertexExecutableIndex = 0; vertexExecutableIndex < mVertexExecutables.size();
   1457         vertexExecutableIndex++)
   1458    {
   1459        VertexExecutable *vertexExecutable = mVertexExecutables[vertexExecutableIndex].get();
   1460 
   1461        const gl::InputLayout &inputLayout = vertexExecutable->inputs();
   1462        stream->writeInt(inputLayout.size());
   1463 
   1464        for (size_t inputIndex = 0; inputIndex < inputLayout.size(); inputIndex++)
   1465        {
   1466            stream->writeEnum(inputLayout[inputIndex]);
   1467        }
   1468 
   1469        size_t vertexShaderSize = vertexExecutable->shaderExecutable()->getLength();
   1470        stream->writeInt(vertexShaderSize);
   1471 
   1472        const uint8_t *vertexBlob = vertexExecutable->shaderExecutable()->getFunction();
   1473        stream->writeBytes(vertexBlob, vertexShaderSize);
   1474    }
   1475 
   1476    stream->writeInt(mPixelExecutables.size());
   1477    for (size_t pixelExecutableIndex = 0; pixelExecutableIndex < mPixelExecutables.size();
   1478         pixelExecutableIndex++)
   1479    {
   1480        PixelExecutable *pixelExecutable = mPixelExecutables[pixelExecutableIndex].get();
   1481 
   1482        const std::vector<GLenum> &outputs = pixelExecutable->outputSignature();
   1483        stream->writeInt(outputs.size());
   1484        for (size_t outputIndex = 0; outputIndex < outputs.size(); outputIndex++)
   1485        {
   1486            stream->writeInt(outputs[outputIndex]);
   1487        }
   1488 
   1489        size_t pixelShaderSize = pixelExecutable->shaderExecutable()->getLength();
   1490        stream->writeInt(pixelShaderSize);
   1491 
   1492        const uint8_t *pixelBlob = pixelExecutable->shaderExecutable()->getFunction();
   1493        stream->writeBytes(pixelBlob, pixelShaderSize);
   1494    }
   1495 
   1496    for (auto const &geometryExecutable : mGeometryExecutables)
   1497    {
   1498        if (!geometryExecutable)
   1499        {
   1500            stream->writeInt<size_t>(0);
   1501            continue;
   1502        }
   1503 
   1504        size_t geometryShaderSize = geometryExecutable->getLength();
   1505        stream->writeInt(geometryShaderSize);
   1506        stream->writeBytes(geometryExecutable->getFunction(), geometryShaderSize);
   1507    }
   1508 
   1509    stream->writeInt(mComputeExecutables.size());
   1510    for (size_t computeExecutableIndex = 0; computeExecutableIndex < mComputeExecutables.size();
   1511         computeExecutableIndex++)
   1512    {
   1513        ComputeExecutable *computeExecutable = mComputeExecutables[computeExecutableIndex].get();
   1514 
   1515        const gl::ImageUnitTextureTypeMap signatures = computeExecutable->signature();
   1516        stream->writeInt(signatures.size());
   1517        for (const auto &signature : signatures)
   1518        {
   1519            stream->writeInt(signature.first);
   1520            stream->writeEnum(signature.second);
   1521        }
   1522 
   1523        size_t computeShaderSize = computeExecutable->shaderExecutable()->getLength();
   1524        stream->writeInt(computeShaderSize);
   1525 
   1526        const uint8_t *computeBlob = computeExecutable->shaderExecutable()->getFunction();
   1527        stream->writeBytes(computeBlob, computeShaderSize);
   1528    }
   1529 
   1530    for (gl::ShaderType shaderType : {gl::ShaderType::Compute})
   1531    {
   1532        stream->writeInt(mImage2DBindLayoutCache[shaderType].size());
   1533        for (auto &image2DBindLayout : mImage2DBindLayoutCache[shaderType])
   1534        {
   1535            stream->writeInt(image2DBindLayout.first);
   1536        }
   1537    }
   1538 }
   1539 
   1540 void ProgramD3D::setBinaryRetrievableHint(bool /* retrievable */) {}
   1541 
   1542 void ProgramD3D::setSeparable(bool /* separable */) {}
   1543 
   1544 angle::Result ProgramD3D::getPixelExecutableForCachedOutputLayout(
   1545    d3d::Context *context,
   1546    ShaderExecutableD3D **outExecutable,
   1547    gl::InfoLog *infoLog)
   1548 {
   1549    if (mCachedPixelExecutableIndex.valid())
   1550    {
   1551        *outExecutable = mPixelExecutables[mCachedPixelExecutableIndex.value()]->shaderExecutable();
   1552        return angle::Result::Continue;
   1553    }
   1554 
   1555    std::string pixelHLSL = mDynamicHLSL->generatePixelShaderForOutputSignature(
   1556        mShaderHLSL[gl::ShaderType::Fragment], mPixelShaderKey, mUsesFragDepth,
   1557        mPixelShaderOutputLayoutCache, mShaderStorageBlocks[gl::ShaderType::Fragment],
   1558        mPixelShaderKey.size());
   1559 
   1560    std::string finalPixelHLSL = mDynamicHLSL->generateShaderForImage2DBindSignature(
   1561        *this, mState, gl::ShaderType::Fragment, pixelHLSL,
   1562        mImage2DUniforms[gl::ShaderType::Fragment],
   1563        mImage2DBindLayoutCache[gl::ShaderType::Fragment],
   1564        static_cast<unsigned int>(mPixelShaderKey.size()));
   1565 
   1566    // Generate new pixel executable
   1567    ShaderExecutableD3D *pixelExecutable = nullptr;
   1568 
   1569    gl::InfoLog tempInfoLog;
   1570    gl::InfoLog *currentInfoLog = infoLog ? infoLog : &tempInfoLog;
   1571 
   1572    ANGLE_TRY(mRenderer->compileToExecutable(
   1573        context, *currentInfoLog, finalPixelHLSL, gl::ShaderType::Fragment, mStreamOutVaryings,
   1574        (mState.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS),
   1575        mShaderWorkarounds[gl::ShaderType::Fragment], &pixelExecutable));
   1576 
   1577    if (pixelExecutable)
   1578    {
   1579        mPixelExecutables.push_back(std::unique_ptr<PixelExecutable>(
   1580            new PixelExecutable(mPixelShaderOutputLayoutCache, pixelExecutable)));
   1581        mCachedPixelExecutableIndex = mPixelExecutables.size() - 1;
   1582    }
   1583    else if (!infoLog)
   1584    {
   1585        ERR() << "Error compiling dynamic pixel executable:" << std::endl
   1586              << tempInfoLog.str() << std::endl;
   1587    }
   1588 
   1589    *outExecutable = pixelExecutable;
   1590    return angle::Result::Continue;
   1591 }
   1592 
   1593 angle::Result ProgramD3D::getVertexExecutableForCachedInputLayout(
   1594    d3d::Context *context,
   1595    ShaderExecutableD3D **outExectuable,
   1596    gl::InfoLog *infoLog)
   1597 {
   1598    if (mCachedVertexExecutableIndex.valid())
   1599    {
   1600        *outExectuable =
   1601            mVertexExecutables[mCachedVertexExecutableIndex.value()]->shaderExecutable();
   1602        return angle::Result::Continue;
   1603    }
   1604 
   1605    // Generate new dynamic layout with attribute conversions
   1606    std::string finalVertexHLSL = mDynamicHLSL->generateVertexShaderForInputLayout(
   1607        mShaderHLSL[gl::ShaderType::Vertex], mCachedInputLayout, mState.getProgramInputs(),
   1608        mShaderStorageBlocks[gl::ShaderType::Vertex], mPixelShaderKey.size());
   1609 
   1610    // Generate new vertex executable
   1611    ShaderExecutableD3D *vertexExecutable = nullptr;
   1612 
   1613    gl::InfoLog tempInfoLog;
   1614    gl::InfoLog *currentInfoLog = infoLog ? infoLog : &tempInfoLog;
   1615 
   1616    ANGLE_TRY(mRenderer->compileToExecutable(
   1617        context, *currentInfoLog, finalVertexHLSL, gl::ShaderType::Vertex, mStreamOutVaryings,
   1618        (mState.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS),
   1619        mShaderWorkarounds[gl::ShaderType::Vertex], &vertexExecutable));
   1620 
   1621    if (vertexExecutable)
   1622    {
   1623        mVertexExecutables.push_back(std::unique_ptr<VertexExecutable>(
   1624            new VertexExecutable(mCachedInputLayout, mCachedVertexSignature, vertexExecutable)));
   1625        mCachedVertexExecutableIndex = mVertexExecutables.size() - 1;
   1626    }
   1627    else if (!infoLog)
   1628    {
   1629        ERR() << "Error compiling dynamic vertex executable:" << std::endl
   1630              << tempInfoLog.str() << std::endl;
   1631    }
   1632 
   1633    *outExectuable = vertexExecutable;
   1634    return angle::Result::Continue;
   1635 }
   1636 
   1637 angle::Result ProgramD3D::getGeometryExecutableForPrimitiveType(d3d::Context *context,
   1638                                                                const gl::State &state,
   1639                                                                gl::PrimitiveMode drawMode,
   1640                                                                ShaderExecutableD3D **outExecutable,
   1641                                                                gl::InfoLog *infoLog)
   1642 {
   1643    if (outExecutable)
   1644    {
   1645        *outExecutable = nullptr;
   1646    }
   1647 
   1648    // Return a null shader if the current rendering doesn't use a geometry shader
   1649    if (!usesGeometryShader(state, drawMode))
   1650    {
   1651        return angle::Result::Continue;
   1652    }
   1653 
   1654    gl::PrimitiveMode geometryShaderType = GetGeometryShaderTypeFromDrawMode(drawMode);
   1655 
   1656    if (mGeometryExecutables[geometryShaderType])
   1657    {
   1658        if (outExecutable)
   1659        {
   1660            *outExecutable = mGeometryExecutables[geometryShaderType].get();
   1661        }
   1662        return angle::Result::Continue;
   1663    }
   1664    const gl::Caps &caps     = state.getCaps();
   1665    std::string geometryHLSL = mDynamicHLSL->generateGeometryShaderHLSL(
   1666        caps, geometryShaderType, mState, mRenderer->presentPathFastEnabled(),
   1667        mHasANGLEMultiviewEnabled, mRenderer->canSelectViewInVertexShader(),
   1668        usesGeometryShaderForPointSpriteEmulation(), mGeometryShaderPreamble);
   1669 
   1670    gl::InfoLog tempInfoLog;
   1671    gl::InfoLog *currentInfoLog = infoLog ? infoLog : &tempInfoLog;
   1672 
   1673    ShaderExecutableD3D *geometryExecutable = nullptr;
   1674    angle::Result result                    = mRenderer->compileToExecutable(
   1675                           context, *currentInfoLog, geometryHLSL, gl::ShaderType::Geometry, mStreamOutVaryings,
   1676                           (mState.getTransformFeedbackBufferMode() == GL_SEPARATE_ATTRIBS), CompilerWorkaroundsD3D(),
   1677                           &geometryExecutable);
   1678 
   1679    if (!infoLog && result == angle::Result::Stop)
   1680    {
   1681        ERR() << "Error compiling dynamic geometry executable:" << std::endl
   1682              << tempInfoLog.str() << std::endl;
   1683    }
   1684 
   1685    if (geometryExecutable != nullptr)
   1686    {
   1687        mGeometryExecutables[geometryShaderType].reset(geometryExecutable);
   1688    }
   1689 
   1690    if (outExecutable)
   1691    {
   1692        *outExecutable = mGeometryExecutables[geometryShaderType].get();
   1693    }
   1694    return result;
   1695 }
   1696 
   1697 class ProgramD3D::GetVertexExecutableTask : public ProgramD3D::GetExecutableTask
   1698 {
   1699  public:
   1700    GetVertexExecutableTask(const gl::Context *context, ProgramD3D *program)
   1701        : GetExecutableTask(context, program)
   1702    {}
   1703    angle::Result run() override
   1704    {
   1705        ANGLE_TRACE_EVENT0("gpu.angle", "ProgramD3D::GetVertexExecutableTask::run");
   1706 
   1707        ANGLE_TRY(mProgram->getVertexExecutableForCachedInputLayout(this, &mExecutable, &mInfoLog));
   1708 
   1709        return angle::Result::Continue;
   1710    }
   1711 };
   1712 
   1713 void ProgramD3D::updateCachedInputLayoutFromShader(const gl::Context *context)
   1714 {
   1715    GetDefaultInputLayoutFromShader(context, mState.getAttachedShader(gl::ShaderType::Vertex),
   1716                                    &mCachedInputLayout);
   1717    VertexExecutable::getSignature(mRenderer, mCachedInputLayout, &mCachedVertexSignature);
   1718    updateCachedVertexExecutableIndex();
   1719 }
   1720 
   1721 class ProgramD3D::GetPixelExecutableTask : public ProgramD3D::GetExecutableTask
   1722 {
   1723  public:
   1724    GetPixelExecutableTask(const gl::Context *context, ProgramD3D *program)
   1725        : GetExecutableTask(context, program)
   1726    {}
   1727    angle::Result run() override
   1728    {
   1729        ANGLE_TRACE_EVENT0("gpu.angle", "ProgramD3D::GetPixelExecutableTask::run");
   1730        if (!mProgram->mState.getAttachedShader(gl::ShaderType::Fragment))
   1731        {
   1732            return angle::Result::Continue;
   1733        }
   1734 
   1735        mProgram->updateCachedOutputLayoutFromShader();
   1736        mProgram->updateCachedImage2DBindLayoutFromShader(gl::ShaderType::Fragment);
   1737        ANGLE_TRY(mProgram->getPixelExecutableForCachedOutputLayout(this, &mExecutable, &mInfoLog));
   1738 
   1739        return angle::Result::Continue;
   1740    }
   1741 };
   1742 
   1743 void ProgramD3D::updateCachedOutputLayoutFromShader()
   1744 {
   1745    GetDefaultOutputLayoutFromShader(mPixelShaderKey, &mPixelShaderOutputLayoutCache);
   1746    updateCachedPixelExecutableIndex();
   1747 }
   1748 
   1749 void ProgramD3D::updateCachedImage2DBindLayoutFromShader(gl::ShaderType shaderType)
   1750 {
   1751    GetDefaultImage2DBindLayoutFromShader(mImage2DUniforms[shaderType],
   1752                                          &mImage2DBindLayoutCache[shaderType]);
   1753    switch (shaderType)
   1754    {
   1755        case gl::ShaderType::Compute:
   1756            updateCachedComputeExecutableIndex();
   1757            break;
   1758        case gl::ShaderType::Fragment:
   1759            updateCachedPixelExecutableIndex();
   1760            break;
   1761        case gl::ShaderType::Vertex:
   1762            updateCachedVertexExecutableIndex();
   1763            break;
   1764        default:
   1765            ASSERT(false);
   1766            break;
   1767    }
   1768 }
   1769 
   1770 class ProgramD3D::GetGeometryExecutableTask : public ProgramD3D::GetExecutableTask
   1771 {
   1772  public:
   1773    GetGeometryExecutableTask(const gl::Context *context,
   1774                              ProgramD3D *program,
   1775                              const gl::State &state)
   1776        : GetExecutableTask(context, program), mState(state)
   1777    {}
   1778 
   1779    angle::Result run() override
   1780    {
   1781        ANGLE_TRACE_EVENT0("gpu.angle", "ProgramD3D::GetGeometryExecutableTask::run");
   1782        // Auto-generate the geometry shader here, if we expect to be using point rendering in
   1783        // D3D11.
   1784        if (mProgram->usesGeometryShader(mState, gl::PrimitiveMode::Points))
   1785        {
   1786            ANGLE_TRY(mProgram->getGeometryExecutableForPrimitiveType(
   1787                this, mState, gl::PrimitiveMode::Points, &mExecutable, &mInfoLog));
   1788        }
   1789 
   1790        return angle::Result::Continue;
   1791    }
   1792 
   1793  private:
   1794    const gl::State &mState;
   1795 };
   1796 
   1797 class ProgramD3D::GetComputeExecutableTask : public ProgramD3D::GetExecutableTask
   1798 {
   1799  public:
   1800    GetComputeExecutableTask(const gl::Context *context, ProgramD3D *program)
   1801        : GetExecutableTask(context, program)
   1802    {}
   1803    angle::Result run() override
   1804    {
   1805        ANGLE_TRACE_EVENT0("gpu.angle", "ProgramD3D::GetComputeExecutableTask::run");
   1806        mProgram->updateCachedImage2DBindLayoutFromShader(gl::ShaderType::Compute);
   1807        ShaderExecutableD3D *computeExecutable = nullptr;
   1808        ANGLE_TRY(mProgram->getComputeExecutableForImage2DBindLayout(
   1809            mContext, this, &computeExecutable, &mInfoLog));
   1810 
   1811        return computeExecutable ? angle::Result::Continue : angle::Result::Incomplete;
   1812    }
   1813 };
   1814 
   1815 // The LinkEvent implementation for linking a rendering(VS, FS, GS) program.
   1816 class ProgramD3D::GraphicsProgramLinkEvent final : public LinkEvent
   1817 {
   1818  public:
   1819    GraphicsProgramLinkEvent(gl::InfoLog &infoLog,
   1820                             std::shared_ptr<WorkerThreadPool> workerPool,
   1821                             std::shared_ptr<ProgramD3D::GetVertexExecutableTask> vertexTask,
   1822                             std::shared_ptr<ProgramD3D::GetPixelExecutableTask> pixelTask,
   1823                             std::shared_ptr<ProgramD3D::GetGeometryExecutableTask> geometryTask,
   1824                             bool useGS,
   1825                             const ShaderD3D *vertexShader,
   1826                             const ShaderD3D *fragmentShader)
   1827        : mInfoLog(infoLog),
   1828          mVertexTask(vertexTask),
   1829          mPixelTask(pixelTask),
   1830          mGeometryTask(geometryTask),
   1831          mWaitEvents({{std::shared_ptr<WaitableEvent>(
   1832                            angle::WorkerThreadPool::PostWorkerTask(workerPool, mVertexTask)),
   1833                        std::shared_ptr<WaitableEvent>(
   1834                            angle::WorkerThreadPool::PostWorkerTask(workerPool, mPixelTask)),
   1835                        std::shared_ptr<WaitableEvent>(
   1836                            angle::WorkerThreadPool::PostWorkerTask(workerPool, mGeometryTask))}}),
   1837          mUseGS(useGS),
   1838          mVertexShader(vertexShader),
   1839          mFragmentShader(fragmentShader)
   1840    {}
   1841 
   1842    angle::Result wait(const gl::Context *context) override
   1843    {
   1844        ANGLE_TRACE_EVENT0("gpu.angle", "ProgramD3D::GraphicsProgramLinkEvent::wait");
   1845        WaitableEvent::WaitMany(&mWaitEvents);
   1846 
   1847        ANGLE_TRY(checkTask(context, mVertexTask.get()));
   1848        ANGLE_TRY(checkTask(context, mPixelTask.get()));
   1849        ANGLE_TRY(checkTask(context, mGeometryTask.get()));
   1850 
   1851        if (mVertexTask->getResult() == angle::Result::Incomplete ||
   1852            mPixelTask->getResult() == angle::Result::Incomplete ||
   1853            mGeometryTask->getResult() == angle::Result::Incomplete)
   1854        {
   1855            return angle::Result::Incomplete;
   1856        }
   1857 
   1858        ShaderExecutableD3D *defaultVertexExecutable = mVertexTask->getExecutable();
   1859        ShaderExecutableD3D *defaultPixelExecutable  = mPixelTask->getExecutable();
   1860        ShaderExecutableD3D *pointGS                 = mGeometryTask->getExecutable();
   1861 
   1862        if (mUseGS && pointGS)
   1863        {
   1864            // Geometry shaders are currently only used internally, so there is no corresponding
   1865            // shader object at the interface level. For now the geometry shader debug info is
   1866            // prepended to the vertex shader.
   1867            mVertexShader->appendDebugInfo("// GEOMETRY SHADER BEGIN\n\n");
   1868            mVertexShader->appendDebugInfo(pointGS->getDebugInfo());
   1869            mVertexShader->appendDebugInfo("\nGEOMETRY SHADER END\n\n\n");
   1870        }
   1871 
   1872        if (defaultVertexExecutable)
   1873        {
   1874            mVertexShader->appendDebugInfo(defaultVertexExecutable->getDebugInfo());
   1875        }
   1876 
   1877        if (defaultPixelExecutable)
   1878        {
   1879            mFragmentShader->appendDebugInfo(defaultPixelExecutable->getDebugInfo());
   1880        }
   1881 
   1882        bool isLinked = (defaultVertexExecutable && defaultPixelExecutable && (!mUseGS || pointGS));
   1883        if (!isLinked)
   1884        {
   1885            mInfoLog << "Failed to create D3D Shaders";
   1886        }
   1887        return isLinked ? angle::Result::Continue : angle::Result::Incomplete;
   1888    }
   1889 
   1890    bool isLinking() override
   1891    {
   1892        for (auto &event : mWaitEvents)
   1893        {
   1894            if (!event->isReady())
   1895            {
   1896                return true;
   1897            }
   1898        }
   1899        return false;
   1900    }
   1901 
   1902  private:
   1903    angle::Result checkTask(const gl::Context *context, ProgramD3D::GetExecutableTask *task)
   1904    {
   1905        if (!task->getInfoLog().empty())
   1906        {
   1907            mInfoLog << task->getInfoLog().str();
   1908        }
   1909 
   1910        // Continue and Incomplete are not errors. For Stop, pass the error to the ContextD3D.
   1911        if (task->getResult() != angle::Result::Stop)
   1912        {
   1913            return angle::Result::Continue;
   1914        }
   1915 
   1916        ContextD3D *contextD3D = GetImplAs<ContextD3D>(context);
   1917        task->popError(contextD3D);
   1918        return angle::Result::Stop;
   1919    }
   1920 
   1921    gl::InfoLog &mInfoLog;
   1922    std::shared_ptr<ProgramD3D::GetVertexExecutableTask> mVertexTask;
   1923    std::shared_ptr<ProgramD3D::GetPixelExecutableTask> mPixelTask;
   1924    std::shared_ptr<ProgramD3D::GetGeometryExecutableTask> mGeometryTask;
   1925    std::array<std::shared_ptr<WaitableEvent>, 3> mWaitEvents;
   1926    bool mUseGS;
   1927    const ShaderD3D *mVertexShader;
   1928    const ShaderD3D *mFragmentShader;
   1929 };
   1930 
   1931 // The LinkEvent implementation for linking a computing program.
   1932 class ProgramD3D::ComputeProgramLinkEvent final : public LinkEvent
   1933 {
   1934  public:
   1935    ComputeProgramLinkEvent(gl::InfoLog &infoLog,
   1936                            std::shared_ptr<ProgramD3D::GetComputeExecutableTask> computeTask,
   1937                            std::shared_ptr<WaitableEvent> event)
   1938        : mInfoLog(infoLog), mComputeTask(computeTask), mWaitEvent(event)
   1939    {}
   1940 
   1941    bool isLinking() override { return !mWaitEvent->isReady(); }
   1942 
   1943    angle::Result wait(const gl::Context *context) override
   1944    {
   1945        ANGLE_TRACE_EVENT0("gpu.angle", "ProgramD3D::ComputeProgramLinkEvent::wait");
   1946        mWaitEvent->wait();
   1947 
   1948        angle::Result result = mComputeTask->getResult();
   1949        if (result != angle::Result::Continue)
   1950        {
   1951            mInfoLog << "Failed to create D3D compute shader.";
   1952        }
   1953        return result;
   1954    }
   1955 
   1956  private:
   1957    gl::InfoLog &mInfoLog;
   1958    std::shared_ptr<ProgramD3D::GetComputeExecutableTask> mComputeTask;
   1959    std::shared_ptr<WaitableEvent> mWaitEvent;
   1960 };
   1961 
   1962 std::unique_ptr<LinkEvent> ProgramD3D::compileProgramExecutables(const gl::Context *context,
   1963                                                                 gl::InfoLog &infoLog)
   1964 {
   1965    ANGLE_TRACE_EVENT0("gpu.angle", "ProgramD3D::compileProgramExecutables");
   1966    // Ensure the compiler is initialized to avoid race conditions.
   1967    angle::Result result = mRenderer->ensureHLSLCompilerInitialized(GetImplAs<ContextD3D>(context));
   1968    if (result != angle::Result::Continue)
   1969    {
   1970        return std::make_unique<LinkEventDone>(result);
   1971    }
   1972 
   1973    auto vertexTask = std::make_shared<GetVertexExecutableTask>(context, this);
   1974    auto pixelTask  = std::make_shared<GetPixelExecutableTask>(context, this);
   1975    auto geometryTask =
   1976        std::make_shared<GetGeometryExecutableTask>(context, this, context->getState());
   1977    bool useGS                 = usesGeometryShader(context->getState(), gl::PrimitiveMode::Points);
   1978    gl::Shader *vertexShader   = mState.getAttachedShader(gl::ShaderType::Vertex);
   1979    gl::Shader *fragmentShader = mState.getAttachedShader(gl::ShaderType::Fragment);
   1980    const ShaderD3D *vertexShaderD3D = vertexShader ? GetImplAs<ShaderD3D>(vertexShader) : nullptr;
   1981    const ShaderD3D *fragmentShaderD3D =
   1982        fragmentShader ? GetImplAs<ShaderD3D>(fragmentShader) : nullptr;
   1983 
   1984    return std::make_unique<GraphicsProgramLinkEvent>(infoLog, context->getWorkerThreadPool(),
   1985                                                      vertexTask, pixelTask, geometryTask, useGS,
   1986                                                      vertexShaderD3D, fragmentShaderD3D);
   1987 }
   1988 
   1989 std::unique_ptr<LinkEvent> ProgramD3D::compileComputeExecutable(const gl::Context *context,
   1990                                                                gl::InfoLog &infoLog)
   1991 {
   1992    ANGLE_TRACE_EVENT0("gpu.angle", "ProgramD3D::compileComputeExecutable");
   1993    // Ensure the compiler is initialized to avoid race conditions.
   1994    angle::Result result = mRenderer->ensureHLSLCompilerInitialized(GetImplAs<ContextD3D>(context));
   1995    if (result != angle::Result::Continue)
   1996    {
   1997        return std::make_unique<LinkEventDone>(result);
   1998    }
   1999    auto computeTask = std::make_shared<GetComputeExecutableTask>(context, this);
   2000 
   2001    std::shared_ptr<WaitableEvent> waitableEvent;
   2002 
   2003    // TODO(jie.a.chen@intel.com): Fix the flaky bug.
   2004    // http://anglebug.com/3349
   2005    bool compileInParallel = false;
   2006    if (!compileInParallel)
   2007    {
   2008        (*computeTask)();
   2009        waitableEvent = std::make_shared<WaitableEventDone>();
   2010    }
   2011    else
   2012    {
   2013        waitableEvent =
   2014            WorkerThreadPool::PostWorkerTask(context->getWorkerThreadPool(), computeTask);
   2015    }
   2016 
   2017    return std::make_unique<ComputeProgramLinkEvent>(infoLog, computeTask, waitableEvent);
   2018 }
   2019 
   2020 angle::Result ProgramD3D::getComputeExecutableForImage2DBindLayout(
   2021    const gl::Context *glContext,
   2022    d3d::Context *context,
   2023    ShaderExecutableD3D **outExecutable,
   2024    gl::InfoLog *infoLog)
   2025 {
   2026    ANGLE_TRACE_EVENT0("gpu.angle", "ProgramD3D::getComputeExecutableForImage2DBindLayout");
   2027    if (mCachedComputeExecutableIndex.valid())
   2028    {
   2029        *outExecutable =
   2030            mComputeExecutables[mCachedComputeExecutableIndex.value()]->shaderExecutable();
   2031        return angle::Result::Continue;
   2032    }
   2033 
   2034    std::string computeHLSL =
   2035        mState.getAttachedShader(gl::ShaderType::Compute)->getTranslatedSource(glContext);
   2036 
   2037    std::string finalComputeHLSL = mDynamicHLSL->generateShaderForImage2DBindSignature(
   2038        *this, mState, gl::ShaderType::Compute, computeHLSL,
   2039        mImage2DUniforms[gl::ShaderType::Compute], mImage2DBindLayoutCache[gl::ShaderType::Compute],
   2040        0u);
   2041 
   2042    // Generate new compute executable
   2043    ShaderExecutableD3D *computeExecutable = nullptr;
   2044 
   2045    gl::InfoLog tempInfoLog;
   2046    gl::InfoLog *currentInfoLog = infoLog ? infoLog : &tempInfoLog;
   2047 
   2048    ANGLE_TRY(mRenderer->compileToExecutable(context, *currentInfoLog, finalComputeHLSL,
   2049                                             gl::ShaderType::Compute, std::vector<D3DVarying>(),
   2050                                             false, CompilerWorkaroundsD3D(), &computeExecutable));
   2051 
   2052    if (computeExecutable)
   2053    {
   2054        mComputeExecutables.push_back(std::unique_ptr<ComputeExecutable>(
   2055            new ComputeExecutable(mImage2DBindLayoutCache[gl::ShaderType::Compute],
   2056                                  std::unique_ptr<ShaderExecutableD3D>(computeExecutable))));
   2057        mCachedComputeExecutableIndex = mComputeExecutables.size() - 1;
   2058    }
   2059    else if (!infoLog)
   2060    {
   2061        ERR() << "Error compiling dynamic compute executable:" << std::endl
   2062              << tempInfoLog.str() << std::endl;
   2063    }
   2064    *outExecutable = computeExecutable;
   2065 
   2066    return angle::Result::Continue;
   2067 }
   2068 
   2069 std::unique_ptr<LinkEvent> ProgramD3D::link(const gl::Context *context,
   2070                                            const gl::ProgramLinkedResources &resources,
   2071                                            gl::InfoLog &infoLog,
   2072                                            const gl::ProgramMergedVaryings & /*mergedVaryings*/)
   2073 {
   2074    ANGLE_TRACE_EVENT0("gpu.angle", "ProgramD3D::link");
   2075    const auto &data = context->getState();
   2076 
   2077    reset();
   2078 
   2079    gl::Shader *computeShader = mState.getAttachedShader(gl::ShaderType::Compute);
   2080    if (computeShader)
   2081    {
   2082        mShaderSamplers[gl::ShaderType::Compute].resize(
   2083            data.getCaps().maxShaderTextureImageUnits[gl::ShaderType::Compute]);
   2084        mImages[gl::ShaderType::Compute].resize(data.getCaps().maxImageUnits);
   2085        mReadonlyImages[gl::ShaderType::Compute].resize(data.getCaps().maxImageUnits);
   2086 
   2087        mShaderUniformsDirty.set(gl::ShaderType::Compute);
   2088 
   2089        linkResources(context, resources);
   2090 
   2091        for (const sh::ShaderVariable &uniform : computeShader->getUniforms(context))
   2092        {
   2093            if (gl::IsImageType(uniform.type) && gl::IsImage2DType(uniform.type))
   2094            {
   2095                mImage2DUniforms[gl::ShaderType::Compute].push_back(uniform);
   2096            }
   2097        }
   2098 
   2099        defineUniformsAndAssignRegisters(context);
   2100 
   2101        return compileComputeExecutable(context, infoLog);
   2102    }
   2103    else
   2104    {
   2105        gl::ShaderMap<const ShaderD3D *> shadersD3D = {};
   2106        for (gl::ShaderType shaderType : gl::kAllGraphicsShaderTypes)
   2107        {
   2108            if (gl::Shader *shader = mState.getAttachedShader(shaderType))
   2109            {
   2110                shadersD3D[shaderType] = GetImplAs<ShaderD3D>(mState.getAttachedShader(shaderType));
   2111 
   2112                mShaderSamplers[shaderType].resize(
   2113                    data.getCaps().maxShaderTextureImageUnits[shaderType]);
   2114                mImages[shaderType].resize(data.getCaps().maxImageUnits);
   2115                mReadonlyImages[shaderType].resize(data.getCaps().maxImageUnits);
   2116 
   2117                shadersD3D[shaderType]->generateWorkarounds(&mShaderWorkarounds[shaderType]);
   2118 
   2119                mShaderUniformsDirty.set(shaderType);
   2120 
   2121                const std::set<std::string> &slowCompilingUniformBlockSet =
   2122                    shadersD3D[shaderType]->getSlowCompilingUniformBlockSet();
   2123                if (slowCompilingUniformBlockSet.size() > 0)
   2124                {
   2125                    std::ostringstream stream;
   2126                    stream << "You could get a better shader compiling performance if you re-write"
   2127                           << " the uniform block(s)\n[ ";
   2128                    for (const std::string &str : slowCompilingUniformBlockSet)
   2129                    {
   2130                        stream << str << " ";
   2131                    }
   2132                    stream << "]\nin the " << gl::GetShaderTypeString(shaderType) << " shader.\n";
   2133 
   2134                    stream << "You could get more details from "
   2135                              "https://chromium.googlesource.com/angle/angle/+/refs/heads/main/"
   2136                              "src/libANGLE/renderer/d3d/d3d11/"
   2137                              "UniformBlockToStructuredBufferTranslation.md\n";
   2138                    ANGLE_PERF_WARNING(context->getState().getDebug(), GL_DEBUG_SEVERITY_MEDIUM,
   2139                                       stream.str().c_str());
   2140                }
   2141 
   2142                for (const sh::ShaderVariable &uniform : shader->getUniforms(context))
   2143                {
   2144                    if (gl::IsImageType(uniform.type) && gl::IsImage2DType(uniform.type))
   2145                    {
   2146                        mImage2DUniforms[shaderType].push_back(uniform);
   2147                    }
   2148                }
   2149            }
   2150        }
   2151 
   2152        if (mRenderer->getNativeLimitations().noFrontFacingSupport)
   2153        {
   2154            const ShaderD3D *fragmentShader = shadersD3D[gl::ShaderType::Fragment];
   2155            if (fragmentShader && fragmentShader->usesFrontFacing())
   2156            {
   2157                infoLog << "The current renderer doesn't support gl_FrontFacing";
   2158                return std::make_unique<LinkEventDone>(angle::Result::Incomplete);
   2159            }
   2160        }
   2161 
   2162        const gl::VaryingPacking &varyingPacking =
   2163            resources.varyingPacking.getOutputPacking(gl::ShaderType::Vertex);
   2164 
   2165        ProgramD3DMetadata metadata(mRenderer, shadersD3D, context->getClientType());
   2166        BuiltinVaryingsD3D builtins(metadata, varyingPacking);
   2167 
   2168        mDynamicHLSL->generateShaderLinkHLSL(context, context->getCaps(), mState, metadata,
   2169                                             varyingPacking, builtins, &mShaderHLSL);
   2170 
   2171        const ShaderD3D *vertexShader = shadersD3D[gl::ShaderType::Vertex];
   2172        mUsesPointSize                = vertexShader && vertexShader->usesPointSize();
   2173        mDynamicHLSL->getPixelShaderOutputKey(data, mState, metadata, &mPixelShaderKey);
   2174        mUsesFragDepth            = metadata.usesFragDepth();
   2175        mUsesVertexID             = metadata.usesVertexID();
   2176        mUsesViewID               = metadata.usesViewID();
   2177        mHasANGLEMultiviewEnabled = metadata.hasANGLEMultiviewEnabled();
   2178 
   2179        // Cache if we use flat shading
   2180        mUsesFlatInterpolation = FindFlatInterpolationVarying(context, mState.getAttachedShaders());
   2181 
   2182        if (mRenderer->getMajorShaderModel() >= 4)
   2183        {
   2184            mGeometryShaderPreamble = mDynamicHLSL->generateGeometryShaderPreamble(
   2185                varyingPacking, builtins, mHasANGLEMultiviewEnabled,
   2186                metadata.canSelectViewInVertexShader());
   2187        }
   2188 
   2189        initAttribLocationsToD3DSemantic(context);
   2190 
   2191        defineUniformsAndAssignRegisters(context);
   2192 
   2193        gatherTransformFeedbackVaryings(varyingPacking, builtins[gl::ShaderType::Vertex]);
   2194 
   2195        linkResources(context, resources);
   2196 
   2197        if (mState.getAttachedShader(gl::ShaderType::Vertex))
   2198        {
   2199            updateCachedInputLayoutFromShader(context);
   2200        }
   2201 
   2202        return compileProgramExecutables(context, infoLog);
   2203    }
   2204 }
   2205 
   2206 GLboolean ProgramD3D::validate(const gl::Caps & /*caps*/, gl::InfoLog * /*infoLog*/)
   2207 {
   2208    // TODO(jmadill): Do something useful here?
   2209    return GL_TRUE;
   2210 }
   2211 
   2212 void ProgramD3D::initializeShaderStorageBlocks(const gl::Context *context)
   2213 {
   2214    if (mState.getShaderStorageBlocks().empty())
   2215    {
   2216        return;
   2217    }
   2218 
   2219    ASSERT(mD3DShaderStorageBlocks.empty());
   2220 
   2221    // Assign registers and update sizes.
   2222    gl::ShaderMap<const ShaderD3D *> shadersD3D = {};
   2223    for (gl::ShaderType shaderType : gl::AllShaderTypes())
   2224    {
   2225        shadersD3D[shaderType] = SafeGetImplAs<ShaderD3D>(mState.getAttachedShader(shaderType));
   2226    }
   2227    for (const gl::InterfaceBlock &shaderStorageBlock : mState.getShaderStorageBlocks())
   2228    {
   2229        unsigned int shaderStorageBlockElement =
   2230            shaderStorageBlock.isArray ? shaderStorageBlock.arrayElement : 0;
   2231        D3DInterfaceBlock d3dShaderStorageBlock;
   2232 
   2233        for (gl::ShaderType shaderType : gl::AllShaderTypes())
   2234        {
   2235            if (shaderStorageBlock.isActive(shaderType))
   2236            {
   2237                ASSERT(shadersD3D[shaderType]);
   2238                unsigned int baseRegister =
   2239                    shadersD3D[shaderType]->getShaderStorageBlockRegister(shaderStorageBlock.name);
   2240 
   2241                d3dShaderStorageBlock.mShaderRegisterIndexes[shaderType] =
   2242                    baseRegister + shaderStorageBlockElement;
   2243            }
   2244        }
   2245        mD3DShaderStorageBlocks.push_back(d3dShaderStorageBlock);
   2246    }
   2247 
   2248    for (gl::ShaderType shaderType : gl::AllShaderTypes())
   2249    {
   2250        gl::Shader *shader = mState.getAttachedShader(shaderType);
   2251        if (!shader)
   2252        {
   2253            continue;
   2254        }
   2255        ShaderD3D *shaderD3D = SafeGetImplAs<ShaderD3D>(shader);
   2256        for (const sh::InterfaceBlock &ssbo : shader->getShaderStorageBlocks(context))
   2257        {
   2258            if (!ssbo.active)
   2259            {
   2260                continue;
   2261            }
   2262            ShaderStorageBlock block;
   2263            block.name          = !ssbo.instanceName.empty() ? ssbo.instanceName : ssbo.name;
   2264            block.arraySize     = ssbo.isArray() ? ssbo.arraySize : 0;
   2265            block.registerIndex = shaderD3D->getShaderStorageBlockRegister(ssbo.name);
   2266            mShaderStorageBlocks[shaderType].push_back(block);
   2267        }
   2268    }
   2269 }
   2270 
   2271 void ProgramD3D::initializeUniformBlocks()
   2272 {
   2273    if (mState.getUniformBlocks().empty())
   2274    {
   2275        return;
   2276    }
   2277 
   2278    ASSERT(mD3DUniformBlocks.empty());
   2279 
   2280    // Assign registers and update sizes.
   2281    gl::ShaderMap<const ShaderD3D *> shadersD3D = {};
   2282    for (gl::ShaderType shaderType : gl::AllShaderTypes())
   2283    {
   2284        shadersD3D[shaderType] = SafeGetImplAs<ShaderD3D>(mState.getAttachedShader(shaderType));
   2285    }
   2286 
   2287    for (const gl::InterfaceBlock &uniformBlock : mState.getUniformBlocks())
   2288    {
   2289        unsigned int uniformBlockElement = uniformBlock.isArray ? uniformBlock.arrayElement : 0;
   2290 
   2291        D3DUniformBlock d3dUniformBlock;
   2292 
   2293        for (gl::ShaderType shaderType : gl::AllShaderTypes())
   2294        {
   2295            if (uniformBlock.isActive(shaderType))
   2296            {
   2297                ASSERT(shadersD3D[shaderType]);
   2298                unsigned int baseRegister =
   2299                    shadersD3D[shaderType]->getUniformBlockRegister(uniformBlock.name);
   2300                d3dUniformBlock.mShaderRegisterIndexes[shaderType] =
   2301                    baseRegister + uniformBlockElement;
   2302                bool useStructuredBuffer =
   2303                    shadersD3D[shaderType]->shouldUniformBlockUseStructuredBuffer(
   2304                        uniformBlock.name);
   2305                if (useStructuredBuffer)
   2306                {
   2307                    d3dUniformBlock.mUseStructuredBuffers[shaderType] = true;
   2308                    d3dUniformBlock.mByteWidths[shaderType]           = uniformBlock.dataSize;
   2309                    d3dUniformBlock.mStructureByteStrides[shaderType] =
   2310                        uniformBlock.firstFieldArraySize == 0u
   2311                            ? uniformBlock.dataSize
   2312                            : uniformBlock.dataSize / uniformBlock.firstFieldArraySize;
   2313                }
   2314            }
   2315        }
   2316 
   2317        mD3DUniformBlocks.push_back(d3dUniformBlock);
   2318    }
   2319 }
   2320 
   2321 void ProgramD3D::initializeUniformStorage(const gl::ShaderBitSet &availableShaderStages)
   2322 {
   2323    // Compute total default block size
   2324    gl::ShaderMap<unsigned int> shaderRegisters = {};
   2325    for (const D3DUniform *d3dUniform : mD3DUniforms)
   2326    {
   2327        if (d3dUniform->isSampler())
   2328        {
   2329            continue;
   2330        }
   2331 
   2332        for (gl::ShaderType shaderType : availableShaderStages)
   2333        {
   2334            if (d3dUniform->isReferencedByShader(shaderType))
   2335            {
   2336                shaderRegisters[shaderType] = std::max(
   2337                    shaderRegisters[shaderType],
   2338                    d3dUniform->mShaderRegisterIndexes[shaderType] + d3dUniform->registerCount);
   2339            }
   2340        }
   2341    }
   2342 
   2343    // We only reset uniform storages for the shader stages available in the program (attached
   2344    // shaders in ProgramD3D::link() and linkedShaderStages in ProgramD3D::load()).
   2345    for (gl::ShaderType shaderType : availableShaderStages)
   2346    {
   2347        mShaderUniformStorages[shaderType].reset(
   2348            mRenderer->createUniformStorage(shaderRegisters[shaderType] * 16u));
   2349    }
   2350 
   2351    // Iterate the uniforms again to assign data pointers to default block uniforms.
   2352    for (D3DUniform *d3dUniform : mD3DUniforms)
   2353    {
   2354        if (d3dUniform->isSampler())
   2355        {
   2356            d3dUniform->mSamplerData.resize(d3dUniform->getArraySizeProduct(), 0);
   2357            continue;
   2358        }
   2359 
   2360        for (gl::ShaderType shaderType : availableShaderStages)
   2361        {
   2362            if (d3dUniform->isReferencedByShader(shaderType))
   2363            {
   2364                d3dUniform->mShaderData[shaderType] =
   2365                    mShaderUniformStorages[shaderType]->getDataPointer(
   2366                        d3dUniform->mShaderRegisterIndexes[shaderType],
   2367                        d3dUniform->registerElement);
   2368            }
   2369        }
   2370    }
   2371 }
   2372 
   2373 void ProgramD3D::updateUniformBufferCache(const gl::Caps &caps)
   2374 {
   2375    if (mState.getUniformBlocks().empty())
   2376    {
   2377        return;
   2378    }
   2379 
   2380    for (gl::ShaderType shaderType : gl::AllShaderTypes())
   2381    {
   2382        mShaderUBOCaches[shaderType].clear();
   2383        mShaderUBOCachesUseSB[shaderType].clear();
   2384    }
   2385 
   2386    for (unsigned int uniformBlockIndex = 0; uniformBlockIndex < mD3DUniformBlocks.size();
   2387         uniformBlockIndex++)
   2388    {
   2389        const D3DUniformBlock &uniformBlock = mD3DUniformBlocks[uniformBlockIndex];
   2390        GLuint blockBinding                 = mState.getUniformBlockBinding(uniformBlockIndex);
   2391 
   2392        // Unnecessary to apply an unreferenced standard or shared UBO
   2393        for (gl::ShaderType shaderType : gl::AllShaderTypes())
   2394        {
   2395            if (!uniformBlock.activeInShader(shaderType))
   2396            {
   2397                continue;
   2398            }
   2399 
   2400            bool useStructuredBuffer   = uniformBlock.mUseStructuredBuffers[shaderType];
   2401            unsigned int registerIndex = uniformBlock.mShaderRegisterIndexes[shaderType];
   2402            if (useStructuredBuffer)
   2403            {
   2404                D3DUBOCacheUseSB cacheUseSB;
   2405                cacheUseSB.registerIndex       = registerIndex;
   2406                cacheUseSB.binding             = blockBinding;
   2407                cacheUseSB.byteWidth           = uniformBlock.mByteWidths[shaderType];
   2408                cacheUseSB.structureByteStride = uniformBlock.mStructureByteStrides[shaderType];
   2409                mShaderUBOCachesUseSB[shaderType].push_back(cacheUseSB);
   2410            }
   2411            else
   2412            {
   2413                ASSERT(registerIndex <
   2414                       static_cast<unsigned int>(caps.maxShaderUniformBlocks[shaderType]));
   2415                D3DUBOCache cache;
   2416                cache.registerIndex = registerIndex;
   2417                cache.binding       = blockBinding;
   2418                mShaderUBOCaches[shaderType].push_back(cache);
   2419            }
   2420        }
   2421    }
   2422 
   2423    for (gl::ShaderType shaderType : gl::AllShaderTypes())
   2424    {
   2425        GLuint uniformBlockCount = static_cast<GLuint>(mShaderUBOCaches[shaderType].size() +
   2426                                                       mShaderUBOCachesUseSB[shaderType].size());
   2427        ASSERT(uniformBlockCount <=
   2428               static_cast<unsigned int>(caps.maxShaderUniformBlocks[shaderType]));
   2429    }
   2430 }
   2431 
   2432 unsigned int ProgramD3D::getAtomicCounterBufferRegisterIndex(GLuint binding,
   2433                                                             gl::ShaderType shaderType) const
   2434 {
   2435    if (shaderType != gl::ShaderType::Compute)
   2436    {
   2437        // Implement atomic counters for non-compute shaders
   2438        // http://anglebug.com/1729
   2439        UNIMPLEMENTED();
   2440    }
   2441    return mComputeAtomicCounterBufferRegisterIndices[binding];
   2442 }
   2443 
   2444 unsigned int ProgramD3D::getShaderStorageBufferRegisterIndex(GLuint blockIndex,
   2445                                                             gl::ShaderType shaderType) const
   2446 {
   2447    return mD3DShaderStorageBlocks[blockIndex].mShaderRegisterIndexes[shaderType];
   2448 }
   2449 
   2450 const std::vector<D3DUBOCache> &ProgramD3D::getShaderUniformBufferCache(
   2451    gl::ShaderType shaderType) const
   2452 {
   2453    return mShaderUBOCaches[shaderType];
   2454 }
   2455 
   2456 const std::vector<D3DUBOCacheUseSB> &ProgramD3D::getShaderUniformBufferCacheUseSB(
   2457    gl::ShaderType shaderType) const
   2458 {
   2459    return mShaderUBOCachesUseSB[shaderType];
   2460 }
   2461 
   2462 void ProgramD3D::dirtyAllUniforms()
   2463 {
   2464    mShaderUniformsDirty = mState.getExecutable().getLinkedShaderStages();
   2465 }
   2466 
   2467 void ProgramD3D::markUniformsClean()
   2468 {
   2469    mShaderUniformsDirty.reset();
   2470 }
   2471 
   2472 void ProgramD3D::setUniform1fv(GLint location, GLsizei count, const GLfloat *v)
   2473 {
   2474    setUniformInternal(location, count, v, GL_FLOAT);
   2475 }
   2476 
   2477 void ProgramD3D::setUniform2fv(GLint location, GLsizei count, const GLfloat *v)
   2478 {
   2479    setUniformInternal(location, count, v, GL_FLOAT_VEC2);
   2480 }
   2481 
   2482 void ProgramD3D::setUniform3fv(GLint location, GLsizei count, const GLfloat *v)
   2483 {
   2484    setUniformInternal(location, count, v, GL_FLOAT_VEC3);
   2485 }
   2486 
   2487 void ProgramD3D::setUniform4fv(GLint location, GLsizei count, const GLfloat *v)
   2488 {
   2489    setUniformInternal(location, count, v, GL_FLOAT_VEC4);
   2490 }
   2491 
   2492 void ProgramD3D::setUniformMatrix2fv(GLint location,
   2493                                     GLsizei count,
   2494                                     GLboolean transpose,
   2495                                     const GLfloat *value)
   2496 {
   2497    setUniformMatrixfvInternal<2, 2>(location, count, transpose, value);
   2498 }
   2499 
   2500 void ProgramD3D::setUniformMatrix3fv(GLint location,
   2501                                     GLsizei count,
   2502                                     GLboolean transpose,
   2503                                     const GLfloat *value)
   2504 {
   2505    setUniformMatrixfvInternal<3, 3>(location, count, transpose, value);
   2506 }
   2507 
   2508 void ProgramD3D::setUniformMatrix4fv(GLint location,
   2509                                     GLsizei count,
   2510                                     GLboolean transpose,
   2511                                     const GLfloat *value)
   2512 {
   2513    setUniformMatrixfvInternal<4, 4>(location, count, transpose, value);
   2514 }
   2515 
   2516 void ProgramD3D::setUniformMatrix2x3fv(GLint location,
   2517                                       GLsizei count,
   2518                                       GLboolean transpose,
   2519                                       const GLfloat *value)
   2520 {
   2521    setUniformMatrixfvInternal<2, 3>(location, count, transpose, value);
   2522 }
   2523 
   2524 void ProgramD3D::setUniformMatrix3x2fv(GLint location,
   2525                                       GLsizei count,
   2526                                       GLboolean transpose,
   2527                                       const GLfloat *value)
   2528 {
   2529    setUniformMatrixfvInternal<3, 2>(location, count, transpose, value);
   2530 }
   2531 
   2532 void ProgramD3D::setUniformMatrix2x4fv(GLint location,
   2533                                       GLsizei count,
   2534                                       GLboolean transpose,
   2535                                       const GLfloat *value)
   2536 {
   2537    setUniformMatrixfvInternal<2, 4>(location, count, transpose, value);
   2538 }
   2539 
   2540 void ProgramD3D::setUniformMatrix4x2fv(GLint location,
   2541                                       GLsizei count,
   2542                                       GLboolean transpose,
   2543                                       const GLfloat *value)
   2544 {
   2545    setUniformMatrixfvInternal<4, 2>(location, count, transpose, value);
   2546 }
   2547 
   2548 void ProgramD3D::setUniformMatrix3x4fv(GLint location,
   2549                                       GLsizei count,
   2550                                       GLboolean transpose,
   2551                                       const GLfloat *value)
   2552 {
   2553    setUniformMatrixfvInternal<3, 4>(location, count, transpose, value);
   2554 }
   2555 
   2556 void ProgramD3D::setUniformMatrix4x3fv(GLint location,
   2557                                       GLsizei count,
   2558                                       GLboolean transpose,
   2559                                       const GLfloat *value)
   2560 {
   2561    setUniformMatrixfvInternal<4, 3>(location, count, transpose, value);
   2562 }
   2563 
   2564 void ProgramD3D::setUniform1iv(GLint location, GLsizei count, const GLint *v)
   2565 {
   2566    setUniformInternal(location, count, v, GL_INT);
   2567 }
   2568 
   2569 void ProgramD3D::setUniform2iv(GLint location, GLsizei count, const GLint *v)
   2570 {
   2571    setUniformInternal(location, count, v, GL_INT_VEC2);
   2572 }
   2573 
   2574 void ProgramD3D::setUniform3iv(GLint location, GLsizei count, const GLint *v)
   2575 {
   2576    setUniformInternal(location, count, v, GL_INT_VEC3);
   2577 }
   2578 
   2579 void ProgramD3D::setUniform4iv(GLint location, GLsizei count, const GLint *v)
   2580 {
   2581    setUniformInternal(location, count, v, GL_INT_VEC4);
   2582 }
   2583 
   2584 void ProgramD3D::setUniform1uiv(GLint location, GLsizei count, const GLuint *v)
   2585 {
   2586    setUniformInternal(location, count, v, GL_UNSIGNED_INT);
   2587 }
   2588 
   2589 void ProgramD3D::setUniform2uiv(GLint location, GLsizei count, const GLuint *v)
   2590 {
   2591    setUniformInternal(location, count, v, GL_UNSIGNED_INT_VEC2);
   2592 }
   2593 
   2594 void ProgramD3D::setUniform3uiv(GLint location, GLsizei count, const GLuint *v)
   2595 {
   2596    setUniformInternal(location, count, v, GL_UNSIGNED_INT_VEC3);
   2597 }
   2598 
   2599 void ProgramD3D::setUniform4uiv(GLint location, GLsizei count, const GLuint *v)
   2600 {
   2601    setUniformInternal(location, count, v, GL_UNSIGNED_INT_VEC4);
   2602 }
   2603 
   2604 void ProgramD3D::defineUniformsAndAssignRegisters(const gl::Context *context)
   2605 {
   2606    D3DUniformMap uniformMap;
   2607 
   2608    gl::ShaderBitSet attachedShaders;
   2609    for (gl::ShaderType shaderType : gl::AllShaderTypes())
   2610    {
   2611        gl::Shader *shader = mState.getAttachedShader(shaderType);
   2612        if (shader)
   2613        {
   2614            for (const sh::ShaderVariable &uniform : shader->getUniforms(context))
   2615            {
   2616                if (uniform.active)
   2617                {
   2618                    defineUniformBase(shader, uniform, &uniformMap);
   2619                }
   2620            }
   2621 
   2622            attachedShaders.set(shader->getType());
   2623        }
   2624    }
   2625 
   2626    // Initialize the D3DUniform list to mirror the indexing of the GL layer.
   2627    for (const gl::LinkedUniform &glUniform : mState.getUniforms())
   2628    {
   2629        if (!glUniform.isInDefaultBlock())
   2630            continue;
   2631 
   2632        std::string name = glUniform.name;
   2633        if (glUniform.isArray())
   2634        {
   2635            // In the program state, array uniform names include [0] as in the program resource
   2636            // spec. Here we don't include it.
   2637            // TODO(oetuaho@nvidia.com): consider using the same uniform naming here as in the GL
   2638            // layer.
   2639            ASSERT(angle::EndsWith(name, "[0]"));
   2640            name.resize(name.length() - 3);
   2641        }
   2642        auto mapEntry = uniformMap.find(name);
   2643        ASSERT(mapEntry != uniformMap.end());
   2644        mD3DUniforms.push_back(mapEntry->second);
   2645    }
   2646 
   2647    assignAllSamplerRegisters();
   2648    assignAllAtomicCounterRegisters();
   2649    // Samplers and readonly images share shader input resource slot, adjust low value of
   2650    // readonly image range.
   2651    for (gl::ShaderType shaderType : {gl::ShaderType::Compute, gl::ShaderType::Fragment})
   2652    {
   2653        mUsedReadonlyImageRange[shaderType] =
   2654            gl::RangeUI(mUsedShaderSamplerRanges[shaderType].high(),
   2655                        mUsedShaderSamplerRanges[shaderType].high());
   2656        // Atomic counter buffers and non-readonly images share input resource slots
   2657        mUsedImageRange[shaderType] = gl::RangeUI(mUsedAtomicCounterRange[shaderType].high(),
   2658                                                  mUsedAtomicCounterRange[shaderType].high());
   2659    }
   2660    assignAllImageRegisters();
   2661    initializeUniformStorage(attachedShaders);
   2662 }
   2663 
   2664 void ProgramD3D::defineUniformBase(const gl::Shader *shader,
   2665                                   const sh::ShaderVariable &uniform,
   2666                                   D3DUniformMap *uniformMap)
   2667 {
   2668    sh::StubBlockEncoder stubEncoder;
   2669 
   2670    // Samplers get their registers assigned in assignAllSamplerRegisters, and images get their
   2671    // registers assigned in assignAllImageRegisters.
   2672    if (gl::IsSamplerType(uniform.type))
   2673    {
   2674        UniformEncodingVisitorD3D visitor(shader->getType(), HLSLRegisterType::Texture,
   2675                                          &stubEncoder, uniformMap);
   2676        sh::TraverseShaderVariable(uniform, false, &visitor);
   2677        return;
   2678    }
   2679 
   2680    if (gl::IsImageType(uniform.type))
   2681    {
   2682        if (uniform.readonly)
   2683        {
   2684            UniformEncodingVisitorD3D visitor(shader->getType(), HLSLRegisterType::Texture,
   2685                                              &stubEncoder, uniformMap);
   2686            sh::TraverseShaderVariable(uniform, false, &visitor);
   2687        }
   2688        else
   2689        {
   2690            UniformEncodingVisitorD3D visitor(
   2691                shader->getType(), HLSLRegisterType::UnorderedAccessView, &stubEncoder, uniformMap);
   2692            sh::TraverseShaderVariable(uniform, false, &visitor);
   2693        }
   2694        mImageBindingMap[uniform.name] = uniform.binding;
   2695        return;
   2696    }
   2697 
   2698    if (uniform.isBuiltIn() && !uniform.isEmulatedBuiltIn())
   2699    {
   2700        UniformEncodingVisitorD3D visitor(shader->getType(), HLSLRegisterType::None, &stubEncoder,
   2701                                          uniformMap);
   2702        sh::TraverseShaderVariable(uniform, false, &visitor);
   2703        return;
   2704    }
   2705    else if (gl::IsAtomicCounterType(uniform.type))
   2706    {
   2707        UniformEncodingVisitorD3D visitor(shader->getType(), HLSLRegisterType::UnorderedAccessView,
   2708                                          &stubEncoder, uniformMap);
   2709        sh::TraverseShaderVariable(uniform, false, &visitor);
   2710        mAtomicBindingMap[uniform.name] = uniform.binding;
   2711        return;
   2712    }
   2713 
   2714    const ShaderD3D *shaderD3D = GetImplAs<ShaderD3D>(shader);
   2715    unsigned int startRegister = shaderD3D->getUniformRegister(uniform.name);
   2716    ShShaderOutput outputType  = shaderD3D->getCompilerOutputType();
   2717    sh::HLSLBlockEncoder encoder(sh::HLSLBlockEncoder::GetStrategyFor(outputType), true);
   2718    encoder.skipRegisters(startRegister);
   2719 
   2720    UniformEncodingVisitorD3D visitor(shader->getType(), HLSLRegisterType::None, &encoder,
   2721                                      uniformMap);
   2722    sh::TraverseShaderVariable(uniform, false, &visitor);
   2723 }
   2724 
   2725 bool ProgramD3D::hasNamedUniform(const std::string &name)
   2726 {
   2727    for (D3DUniform *d3dUniform : mD3DUniforms)
   2728    {
   2729        if (d3dUniform->name == name)
   2730        {
   2731            return true;
   2732        }
   2733    }
   2734 
   2735    return false;
   2736 }
   2737 
   2738 // Assume count is already clamped.
   2739 template <typename T>
   2740 void ProgramD3D::setUniformImpl(D3DUniform *targetUniform,
   2741                                const gl::VariableLocation &locationInfo,
   2742                                GLsizei count,
   2743                                const T *v,
   2744                                uint8_t *targetState,
   2745                                GLenum uniformType)
   2746 {
   2747    const int components                  = targetUniform->typeInfo.componentCount;
   2748    const unsigned int arrayElementOffset = locationInfo.arrayIndex;
   2749    const int blockSize                   = 4;
   2750 
   2751    if (targetUniform->typeInfo.type == uniformType)
   2752    {
   2753        T *dest         = reinterpret_cast<T *>(targetState) + arrayElementOffset * blockSize;
   2754        const T *source = v;
   2755 
   2756        // If the component is equal to the block size, we can optimize to a single memcpy.
   2757        // Otherwise, we have to do partial block writes.
   2758        if (components == blockSize)
   2759        {
   2760            memcpy(dest, source, components * count * sizeof(T));
   2761        }
   2762        else
   2763        {
   2764            for (GLint i = 0; i < count; i++, dest += blockSize, source += components)
   2765            {
   2766                memcpy(dest, source, components * sizeof(T));
   2767            }
   2768        }
   2769    }
   2770    else
   2771    {
   2772        ASSERT(targetUniform->typeInfo.type == gl::VariableBoolVectorType(uniformType));
   2773        GLint *boolParams = reinterpret_cast<GLint *>(targetState) + arrayElementOffset * 4;
   2774 
   2775        for (GLint i = 0; i < count; i++)
   2776        {
   2777            GLint *dest     = boolParams + (i * 4);
   2778            const T *source = v + (i * components);
   2779 
   2780            for (int c = 0; c < components; c++)
   2781            {
   2782                dest[c] = (source[c] == static_cast<T>(0)) ? GL_FALSE : GL_TRUE;
   2783            }
   2784        }
   2785    }
   2786 }
   2787 
   2788 template <typename T>
   2789 void ProgramD3D::setUniformInternal(GLint location, GLsizei count, const T *v, GLenum uniformType)
   2790 {
   2791    const gl::VariableLocation &locationInfo = mState.getUniformLocations()[location];
   2792    D3DUniform *targetUniform                = mD3DUniforms[locationInfo.index];
   2793 
   2794    if (targetUniform->typeInfo.isSampler)
   2795    {
   2796        ASSERT(uniformType == GL_INT);
   2797        size_t size = count * sizeof(T);
   2798        GLint *dest = &targetUniform->mSamplerData[locationInfo.arrayIndex];
   2799        if (memcmp(dest, v, size) != 0)
   2800        {
   2801            memcpy(dest, v, size);
   2802            mDirtySamplerMapping = true;
   2803        }
   2804        return;
   2805    }
   2806 
   2807    for (gl::ShaderType shaderType : gl::AllShaderTypes())
   2808    {
   2809        uint8_t *targetState = targetUniform->mShaderData[shaderType];
   2810        if (targetState)
   2811        {
   2812            setUniformImpl(targetUniform, locationInfo, count, v, targetState, uniformType);
   2813            mShaderUniformsDirty.set(shaderType);
   2814        }
   2815    }
   2816 }
   2817 
   2818 template <int cols, int rows>
   2819 void ProgramD3D::setUniformMatrixfvInternal(GLint location,
   2820                                            GLsizei countIn,
   2821                                            GLboolean transpose,
   2822                                            const GLfloat *value)
   2823 {
   2824    D3DUniform *targetUniform                   = getD3DUniformFromLocation(location);
   2825    const gl::VariableLocation &uniformLocation = mState.getUniformLocations()[location];
   2826    unsigned int arrayElementOffset             = uniformLocation.arrayIndex;
   2827    unsigned int elementCount                   = targetUniform->getArraySizeProduct();
   2828 
   2829    for (gl::ShaderType shaderType : gl::AllShaderTypes())
   2830    {
   2831        if (targetUniform->mShaderData[shaderType])
   2832        {
   2833            SetFloatUniformMatrixHLSL<cols, rows>::Run(arrayElementOffset, elementCount, countIn,
   2834                                                       transpose, value,
   2835                                                       targetUniform->mShaderData[shaderType]);
   2836            mShaderUniformsDirty.set(shaderType);
   2837        }
   2838    }
   2839 }
   2840 
   2841 void ProgramD3D::assignAllSamplerRegisters()
   2842 {
   2843    for (size_t uniformIndex = 0; uniformIndex < mD3DUniforms.size(); ++uniformIndex)
   2844    {
   2845        if (mD3DUniforms[uniformIndex]->isSampler())
   2846        {
   2847            assignSamplerRegisters(uniformIndex);
   2848        }
   2849    }
   2850 }
   2851 
   2852 void ProgramD3D::assignSamplerRegisters(size_t uniformIndex)
   2853 {
   2854    D3DUniform *d3dUniform = mD3DUniforms[uniformIndex];
   2855    ASSERT(d3dUniform->isSampler());
   2856    // If the uniform is an array of arrays, then we have separate entries for each inner array in
   2857    // mD3DUniforms. However, the sampler register info is stored in the shader only for the
   2858    // outermost array.
   2859    std::vector<unsigned int> subscripts;
   2860    const std::string baseName = gl::ParseResourceName(d3dUniform->name, &subscripts);
   2861    unsigned int registerOffset =
   2862        mState.getUniforms()[uniformIndex].parentArrayIndex() * d3dUniform->getArraySizeProduct();
   2863 
   2864    bool hasUniform = false;
   2865    for (gl::ShaderType shaderType : gl::AllShaderTypes())
   2866    {
   2867        if (!mState.getAttachedShader(shaderType))
   2868        {
   2869            continue;
   2870        }
   2871 
   2872        const ShaderD3D *shaderD3D = GetImplAs<ShaderD3D>(mState.getAttachedShader(shaderType));
   2873        if (shaderD3D->hasUniform(baseName))
   2874        {
   2875            d3dUniform->mShaderRegisterIndexes[shaderType] =
   2876                shaderD3D->getUniformRegister(baseName) + registerOffset;
   2877            ASSERT(d3dUniform->mShaderRegisterIndexes[shaderType] != GL_INVALID_VALUE);
   2878 
   2879            AssignSamplers(d3dUniform->mShaderRegisterIndexes[shaderType], d3dUniform->typeInfo,
   2880                           d3dUniform->getArraySizeProduct(), mShaderSamplers[shaderType],
   2881                           &mUsedShaderSamplerRanges[shaderType]);
   2882            hasUniform = true;
   2883        }
   2884    }
   2885 
   2886    ASSERT(hasUniform);
   2887 }
   2888 
   2889 // static
   2890 void ProgramD3D::AssignSamplers(unsigned int startSamplerIndex,
   2891                                const gl::UniformTypeInfo &typeInfo,
   2892                                unsigned int samplerCount,
   2893                                std::vector<Sampler> &outSamplers,
   2894                                gl::RangeUI *outUsedRange)
   2895 {
   2896    unsigned int samplerIndex = startSamplerIndex;
   2897 
   2898    do
   2899    {
   2900        ASSERT(samplerIndex < outSamplers.size());
   2901        Sampler *sampler            = &outSamplers[samplerIndex];
   2902        sampler->active             = true;
   2903        sampler->textureType        = gl::FromGLenum<gl::TextureType>(typeInfo.textureType);
   2904        sampler->logicalTextureUnit = 0;
   2905        outUsedRange->extend(samplerIndex);
   2906        samplerIndex++;
   2907    } while (samplerIndex < startSamplerIndex + samplerCount);
   2908 }
   2909 
   2910 void ProgramD3D::assignAllImageRegisters()
   2911 {
   2912    for (size_t uniformIndex = 0; uniformIndex < mD3DUniforms.size(); ++uniformIndex)
   2913    {
   2914        if (mD3DUniforms[uniformIndex]->isImage() && !mD3DUniforms[uniformIndex]->isImage2D())
   2915        {
   2916            assignImageRegisters(uniformIndex);
   2917        }
   2918    }
   2919 }
   2920 
   2921 void ProgramD3D::assignAllAtomicCounterRegisters()
   2922 {
   2923    if (mAtomicBindingMap.empty())
   2924    {
   2925        return;
   2926    }
   2927    gl::ShaderType shaderType       = gl::ShaderType::Compute;
   2928    const gl::Shader *computeShader = mState.getAttachedShader(shaderType);
   2929    if (computeShader)
   2930    {
   2931        const ShaderD3D *computeShaderD3D = GetImplAs<ShaderD3D>(computeShader);
   2932        auto &registerIndices             = mComputeAtomicCounterBufferRegisterIndices;
   2933        for (auto &atomicBinding : mAtomicBindingMap)
   2934        {
   2935            ASSERT(computeShaderD3D->hasUniform(atomicBinding.first));
   2936            unsigned int currentRegister =
   2937                computeShaderD3D->getUniformRegister(atomicBinding.first);
   2938            ASSERT(currentRegister != GL_INVALID_INDEX);
   2939            const int kBinding = atomicBinding.second;
   2940 
   2941            registerIndices[kBinding] = currentRegister;
   2942 
   2943            mUsedAtomicCounterRange[gl::ShaderType::Compute].extend(currentRegister);
   2944        }
   2945    }
   2946    else
   2947    {
   2948        // Implement atomic counters for non-compute shaders
   2949        // http://anglebug.com/1729
   2950        UNIMPLEMENTED();
   2951    }
   2952 }
   2953 
   2954 void ProgramD3D::assignImageRegisters(size_t uniformIndex)
   2955 {
   2956    D3DUniform *d3dUniform = mD3DUniforms[uniformIndex];
   2957    ASSERT(d3dUniform->isImage());
   2958    // If the uniform is an array of arrays, then we have separate entries for each inner array in
   2959    // mD3DUniforms. However, the image register info is stored in the shader only for the
   2960    // outermost array.
   2961    std::vector<unsigned int> subscripts;
   2962    const std::string baseName = gl::ParseResourceName(d3dUniform->name, &subscripts);
   2963    unsigned int registerOffset =
   2964        mState.getUniforms()[uniformIndex].parentArrayIndex() * d3dUniform->getArraySizeProduct();
   2965 
   2966    const gl::Shader *computeShader = mState.getAttachedShader(gl::ShaderType::Compute);
   2967    if (computeShader)
   2968    {
   2969        const ShaderD3D *computeShaderD3D =
   2970            GetImplAs<ShaderD3D>(mState.getAttachedShader(gl::ShaderType::Compute));
   2971        ASSERT(computeShaderD3D->hasUniform(baseName));
   2972        d3dUniform->mShaderRegisterIndexes[gl::ShaderType::Compute] =
   2973            computeShaderD3D->getUniformRegister(baseName) + registerOffset;
   2974        ASSERT(d3dUniform->mShaderRegisterIndexes[gl::ShaderType::Compute] != GL_INVALID_INDEX);
   2975        auto bindingIter = mImageBindingMap.find(baseName);
   2976        ASSERT(bindingIter != mImageBindingMap.end());
   2977        if (d3dUniform->regType == HLSLRegisterType::Texture)
   2978        {
   2979            AssignImages(d3dUniform->mShaderRegisterIndexes[gl::ShaderType::Compute],
   2980                         bindingIter->second, d3dUniform->getArraySizeProduct(),
   2981                         mReadonlyImages[gl::ShaderType::Compute],
   2982                         &mUsedReadonlyImageRange[gl::ShaderType::Compute]);
   2983        }
   2984        else if (d3dUniform->regType == HLSLRegisterType::UnorderedAccessView)
   2985        {
   2986            AssignImages(d3dUniform->mShaderRegisterIndexes[gl::ShaderType::Compute],
   2987                         bindingIter->second, d3dUniform->getArraySizeProduct(),
   2988                         mImages[gl::ShaderType::Compute],
   2989                         &mUsedImageRange[gl::ShaderType::Compute]);
   2990        }
   2991        else
   2992        {
   2993            UNREACHABLE();
   2994        }
   2995    }
   2996    else
   2997    {
   2998        // TODO(xinghua.cao@intel.com): Implement image variables in vertex shader and pixel shader.
   2999        UNIMPLEMENTED();
   3000    }
   3001 }
   3002 
   3003 // static
   3004 void ProgramD3D::AssignImages(unsigned int startImageIndex,
   3005                              int startLogicalImageUnit,
   3006                              unsigned int imageCount,
   3007                              std::vector<Image> &outImages,
   3008                              gl::RangeUI *outUsedRange)
   3009 {
   3010    unsigned int imageIndex = startImageIndex;
   3011 
   3012    // If declare without a binding qualifier, any uniform image variable (include all elements of
   3013    // unbound image array) shoud be bound to unit zero.
   3014    if (startLogicalImageUnit == -1)
   3015    {
   3016        ASSERT(imageIndex < outImages.size());
   3017        Image *image            = &outImages[imageIndex];
   3018        image->active           = true;
   3019        image->logicalImageUnit = 0;
   3020        outUsedRange->extend(imageIndex);
   3021        return;
   3022    }
   3023 
   3024    unsigned int logcalImageUnit = startLogicalImageUnit;
   3025    do
   3026    {
   3027        ASSERT(imageIndex < outImages.size());
   3028        Image *image            = &outImages[imageIndex];
   3029        image->active           = true;
   3030        image->logicalImageUnit = logcalImageUnit;
   3031        outUsedRange->extend(imageIndex);
   3032        imageIndex++;
   3033        logcalImageUnit++;
   3034    } while (imageIndex < startImageIndex + imageCount);
   3035 }
   3036 
   3037 void ProgramD3D::assignImage2DRegisters(gl::ShaderType shaderType,
   3038                                        unsigned int startImageIndex,
   3039                                        int startLogicalImageUnit,
   3040                                        bool readonly)
   3041 {
   3042    if (readonly)
   3043    {
   3044        AssignImages(startImageIndex, startLogicalImageUnit, 1, mReadonlyImages[shaderType],
   3045                     &mUsedReadonlyImageRange[shaderType]);
   3046    }
   3047    else
   3048    {
   3049        AssignImages(startImageIndex, startLogicalImageUnit, 1, mImages[shaderType],
   3050                     &mUsedImageRange[shaderType]);
   3051    }
   3052 }
   3053 
   3054 void ProgramD3D::reset()
   3055 {
   3056    mVertexExecutables.clear();
   3057    mPixelExecutables.clear();
   3058    mComputeExecutables.clear();
   3059 
   3060    for (auto &geometryExecutable : mGeometryExecutables)
   3061    {
   3062        geometryExecutable.reset(nullptr);
   3063    }
   3064 
   3065    for (gl::ShaderType shaderType : gl::AllShaderTypes())
   3066    {
   3067        mShaderHLSL[shaderType].clear();
   3068    }
   3069 
   3070    mUsesFragDepth            = false;
   3071    mHasANGLEMultiviewEnabled = false;
   3072    mUsesVertexID             = false;
   3073    mUsesViewID               = false;
   3074    mPixelShaderKey.clear();
   3075    mUsesPointSize         = false;
   3076    mUsesFlatInterpolation = false;
   3077 
   3078    SafeDeleteContainer(mD3DUniforms);
   3079    mD3DUniformBlocks.clear();
   3080    mD3DShaderStorageBlocks.clear();
   3081    mComputeAtomicCounterBufferRegisterIndices.fill({});
   3082 
   3083    for (gl::ShaderType shaderType : gl::AllShaderTypes())
   3084    {
   3085        mShaderUniformStorages[shaderType].reset();
   3086        mShaderSamplers[shaderType].clear();
   3087        mImages[shaderType].clear();
   3088        mReadonlyImages[shaderType].clear();
   3089    }
   3090 
   3091    mUsedShaderSamplerRanges.fill({0, 0});
   3092    mUsedAtomicCounterRange.fill({0, 0});
   3093    mDirtySamplerMapping = true;
   3094    mUsedImageRange.fill({0, 0});
   3095    mUsedReadonlyImageRange.fill({0, 0});
   3096 
   3097    mAttribLocationToD3DSemantic.fill(-1);
   3098 
   3099    mStreamOutVaryings.clear();
   3100 
   3101    mGeometryShaderPreamble.clear();
   3102 
   3103    markUniformsClean();
   3104 
   3105    mCachedPixelExecutableIndex.reset();
   3106    mCachedVertexExecutableIndex.reset();
   3107 }
   3108 
   3109 unsigned int ProgramD3D::getSerial() const
   3110 {
   3111    return mSerial;
   3112 }
   3113 
   3114 unsigned int ProgramD3D::issueSerial()
   3115 {
   3116    return mCurrentSerial++;
   3117 }
   3118 
   3119 void ProgramD3D::initAttribLocationsToD3DSemantic(const gl::Context *context)
   3120 {
   3121    gl::Shader *vertexShader = mState.getAttachedShader(gl::ShaderType::Vertex);
   3122    if (!vertexShader)
   3123    {
   3124        return;
   3125    }
   3126 
   3127    // Init semantic index
   3128    int semanticIndex = 0;
   3129    for (const sh::ShaderVariable &attribute : vertexShader->getActiveAttributes(context))
   3130    {
   3131        int regCount    = gl::VariableRegisterCount(attribute.type);
   3132        GLuint location = mState.getAttributeLocation(attribute.name);
   3133        ASSERT(location != std::numeric_limits<GLuint>::max());
   3134 
   3135        for (int reg = 0; reg < regCount; ++reg)
   3136        {
   3137            mAttribLocationToD3DSemantic[location + reg] = semanticIndex++;
   3138        }
   3139    }
   3140 }
   3141 
   3142 void ProgramD3D::updateCachedInputLayout(Serial associatedSerial, const gl::State &state)
   3143 {
   3144    if (mCurrentVertexArrayStateSerial == associatedSerial)
   3145    {
   3146        return;
   3147    }
   3148 
   3149    mCurrentVertexArrayStateSerial = associatedSerial;
   3150    mCachedInputLayout.clear();
   3151 
   3152    const auto &vertexAttributes = state.getVertexArray()->getVertexAttributes();
   3153    const gl::AttributesMask &attributesMask =
   3154        mState.getExecutable().getActiveAttribLocationsMask();
   3155 
   3156    for (size_t locationIndex : attributesMask)
   3157    {
   3158        int d3dSemantic = mAttribLocationToD3DSemantic[locationIndex];
   3159 
   3160        if (d3dSemantic != -1)
   3161        {
   3162            if (mCachedInputLayout.size() < static_cast<size_t>(d3dSemantic + 1))
   3163            {
   3164                mCachedInputLayout.resize(d3dSemantic + 1, angle::FormatID::NONE);
   3165            }
   3166            mCachedInputLayout[d3dSemantic] =
   3167                GetVertexFormatID(vertexAttributes[locationIndex],
   3168                                  state.getVertexAttribCurrentValue(locationIndex).Type);
   3169        }
   3170    }
   3171 
   3172    VertexExecutable::getSignature(mRenderer, mCachedInputLayout, &mCachedVertexSignature);
   3173 
   3174    updateCachedVertexExecutableIndex();
   3175 }
   3176 
   3177 void ProgramD3D::updateCachedOutputLayout(const gl::Context *context,
   3178                                          const gl::Framebuffer *framebuffer)
   3179 {
   3180    mPixelShaderOutputLayoutCache.clear();
   3181 
   3182    FramebufferD3D *fboD3D   = GetImplAs<FramebufferD3D>(framebuffer);
   3183    const auto &colorbuffers = fboD3D->getColorAttachmentsForRender(context);
   3184 
   3185    for (size_t colorAttachment = 0; colorAttachment < colorbuffers.size(); ++colorAttachment)
   3186    {
   3187        const gl::FramebufferAttachment *colorbuffer = colorbuffers[colorAttachment];
   3188 
   3189        if (colorbuffer)
   3190        {
   3191            auto binding    = colorbuffer->getBinding() == GL_BACK ? GL_COLOR_ATTACHMENT0
   3192                                                                   : colorbuffer->getBinding();
   3193            size_t maxIndex = binding != GL_NONE ? GetMaxOutputIndex(mPixelShaderKey,
   3194                                                                     binding - GL_COLOR_ATTACHMENT0)
   3195                                                 : 0;
   3196            mPixelShaderOutputLayoutCache.insert(mPixelShaderOutputLayoutCache.end(), maxIndex + 1,
   3197                                                 binding);
   3198        }
   3199        else
   3200        {
   3201            mPixelShaderOutputLayoutCache.push_back(GL_NONE);
   3202        }
   3203    }
   3204 
   3205    updateCachedPixelExecutableIndex();
   3206 }
   3207 
   3208 void ProgramD3D::updateCachedComputeImage2DBindLayout(const gl::Context *context)
   3209 {
   3210    const auto &glState = context->getState();
   3211    for (auto &image2DBindLayout : mImage2DBindLayoutCache[gl::ShaderType::Compute])
   3212    {
   3213        const gl::ImageUnit &imageUnit = glState.getImageUnit(image2DBindLayout.first);
   3214        if (imageUnit.texture.get())
   3215        {
   3216            image2DBindLayout.second = imageUnit.texture->getType();
   3217        }
   3218        else
   3219        {
   3220            image2DBindLayout.second = gl::TextureType::_2D;
   3221        }
   3222    }
   3223 
   3224    updateCachedComputeExecutableIndex();
   3225 }
   3226 
   3227 void ProgramD3D::gatherTransformFeedbackVaryings(const gl::VaryingPacking &varyingPacking,
   3228                                                 const BuiltinInfo &builtins)
   3229 {
   3230    const std::string &varyingSemantic =
   3231        GetVaryingSemantic(mRenderer->getMajorShaderModel(), usesPointSize());
   3232 
   3233    // Gather the linked varyings that are used for transform feedback, they should all exist.
   3234    mStreamOutVaryings.clear();
   3235 
   3236    const auto &tfVaryingNames = mState.getTransformFeedbackVaryingNames();
   3237    for (unsigned int outputSlot = 0; outputSlot < static_cast<unsigned int>(tfVaryingNames.size());
   3238         ++outputSlot)
   3239    {
   3240        const auto &tfVaryingName = tfVaryingNames[outputSlot];
   3241        if (tfVaryingName == "gl_Position")
   3242        {
   3243            if (builtins.glPosition.enabled)
   3244            {
   3245                mStreamOutVaryings.emplace_back(builtins.glPosition.semantic,
   3246                                                builtins.glPosition.index, 4, outputSlot);
   3247            }
   3248        }
   3249        else if (tfVaryingName == "gl_FragCoord")
   3250        {
   3251            if (builtins.glFragCoord.enabled)
   3252            {
   3253                mStreamOutVaryings.emplace_back(builtins.glFragCoord.semantic,
   3254                                                builtins.glFragCoord.index, 4, outputSlot);
   3255            }
   3256        }
   3257        else if (tfVaryingName == "gl_PointSize")
   3258        {
   3259            if (builtins.glPointSize.enabled)
   3260            {
   3261                mStreamOutVaryings.emplace_back("PSIZE", 0, 1, outputSlot);
   3262            }
   3263        }
   3264        else
   3265        {
   3266            const auto &registerInfos = varyingPacking.getRegisterList();
   3267            for (GLuint registerIndex = 0u; registerIndex < registerInfos.size(); ++registerIndex)
   3268            {
   3269                const auto &registerInfo = registerInfos[registerIndex];
   3270                const auto &varying      = registerInfo.packedVarying->varying();
   3271                GLenum transposedType    = gl::TransposeMatrixType(varying.type);
   3272                int componentCount       = gl::VariableColumnCount(transposedType);
   3273                ASSERT(!varying.isBuiltIn() && !varying.isStruct());
   3274 
   3275                // There can be more than one register assigned to a particular varying, and each
   3276                // register needs its own stream out entry.
   3277                if (registerInfo.tfVaryingName() == tfVaryingName)
   3278                {
   3279                    mStreamOutVaryings.emplace_back(varyingSemantic, registerIndex, componentCount,
   3280                                                    outputSlot);
   3281                }
   3282            }
   3283        }
   3284    }
   3285 }
   3286 
   3287 D3DUniform *ProgramD3D::getD3DUniformFromLocation(GLint location)
   3288 {
   3289    return mD3DUniforms[mState.getUniformLocations()[location].index];
   3290 }
   3291 
   3292 const D3DUniform *ProgramD3D::getD3DUniformFromLocation(GLint location) const
   3293 {
   3294    return mD3DUniforms[mState.getUniformLocations()[location].index];
   3295 }
   3296 
   3297 bool ProgramD3D::hasVertexExecutableForCachedInputLayout()
   3298 {
   3299    return mCachedVertexExecutableIndex.valid();
   3300 }
   3301 
   3302 bool ProgramD3D::hasGeometryExecutableForPrimitiveType(const gl::State &state,
   3303                                                       gl::PrimitiveMode drawMode)
   3304 {
   3305    if (!usesGeometryShader(state, drawMode))
   3306    {
   3307        // No shader necessary mean we have the required (null) executable.
   3308        return true;
   3309    }
   3310 
   3311    gl::PrimitiveMode geometryShaderType = GetGeometryShaderTypeFromDrawMode(drawMode);
   3312    return mGeometryExecutables[geometryShaderType].get() != nullptr;
   3313 }
   3314 
   3315 bool ProgramD3D::hasPixelExecutableForCachedOutputLayout()
   3316 {
   3317    return mCachedPixelExecutableIndex.valid();
   3318 }
   3319 
   3320 bool ProgramD3D::hasComputeExecutableForCachedImage2DBindLayout()
   3321 {
   3322    return mCachedComputeExecutableIndex.valid();
   3323 }
   3324 
   3325 template <typename DestT>
   3326 void ProgramD3D::getUniformInternal(GLint location, DestT *dataOut) const
   3327 {
   3328    const gl::VariableLocation &locationInfo = mState.getUniformLocations()[location];
   3329    const gl::LinkedUniform &uniform         = mState.getUniforms()[locationInfo.index];
   3330 
   3331    const D3DUniform *targetUniform = getD3DUniformFromLocation(location);
   3332    const uint8_t *srcPointer       = targetUniform->getDataPtrToElement(locationInfo.arrayIndex);
   3333 
   3334    if (gl::IsMatrixType(uniform.type))
   3335    {
   3336        GetMatrixUniform(uniform.type, dataOut, reinterpret_cast<const DestT *>(srcPointer), true);
   3337    }
   3338    else
   3339    {
   3340        memcpy(dataOut, srcPointer, uniform.getElementSize());
   3341    }
   3342 }
   3343 
   3344 void ProgramD3D::getUniformfv(const gl::Context *context, GLint location, GLfloat *params) const
   3345 {
   3346    getUniformInternal(location, params);
   3347 }
   3348 
   3349 void ProgramD3D::getUniformiv(const gl::Context *context, GLint location, GLint *params) const
   3350 {
   3351    getUniformInternal(location, params);
   3352 }
   3353 
   3354 void ProgramD3D::getUniformuiv(const gl::Context *context, GLint location, GLuint *params) const
   3355 {
   3356    getUniformInternal(location, params);
   3357 }
   3358 
   3359 void ProgramD3D::updateCachedVertexExecutableIndex()
   3360 {
   3361    mCachedVertexExecutableIndex.reset();
   3362    for (size_t executableIndex = 0; executableIndex < mVertexExecutables.size(); executableIndex++)
   3363    {
   3364        if (mVertexExecutables[executableIndex]->matchesSignature(mCachedVertexSignature))
   3365        {
   3366            mCachedVertexExecutableIndex = executableIndex;
   3367            break;
   3368        }
   3369    }
   3370 }
   3371 
   3372 void ProgramD3D::updateCachedPixelExecutableIndex()
   3373 {
   3374    mCachedPixelExecutableIndex.reset();
   3375    for (size_t executableIndex = 0; executableIndex < mPixelExecutables.size(); executableIndex++)
   3376    {
   3377        if (mPixelExecutables[executableIndex]->matchesSignature(mPixelShaderOutputLayoutCache))
   3378        {
   3379            mCachedPixelExecutableIndex = executableIndex;
   3380            break;
   3381        }
   3382    }
   3383 }
   3384 
   3385 void ProgramD3D::updateCachedComputeExecutableIndex()
   3386 {
   3387    mCachedComputeExecutableIndex.reset();
   3388    for (size_t executableIndex = 0; executableIndex < mComputeExecutables.size();
   3389         executableIndex++)
   3390    {
   3391        if (mComputeExecutables[executableIndex]->matchesSignature(
   3392                mImage2DBindLayoutCache[gl::ShaderType::Compute]))
   3393        {
   3394            mCachedComputeExecutableIndex = executableIndex;
   3395            break;
   3396        }
   3397    }
   3398 }
   3399 
   3400 void ProgramD3D::linkResources(const gl::Context *context,
   3401                               const gl::ProgramLinkedResources &resources)
   3402 {
   3403    HLSLBlockLayoutEncoderFactory hlslEncoderFactory;
   3404    gl::ProgramLinkedResourcesLinker linker(&hlslEncoderFactory);
   3405 
   3406    linker.linkResources(context, mState, resources);
   3407 
   3408    initializeUniformBlocks();
   3409    initializeShaderStorageBlocks(context);
   3410 }
   3411 
   3412 }  // namespace rx