tor-browser

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

StateManager11.cpp (158579B)


      1 //
      2 // Copyright 2015 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 // StateManager11.cpp: Defines a class for caching D3D11 state
      8 
      9 #include "libANGLE/renderer/d3d/d3d11/StateManager11.h"
     10 
     11 #include "common/angleutils.h"
     12 #include "common/bitset_utils.h"
     13 #include "common/mathutil.h"
     14 #include "common/utilities.h"
     15 #include "libANGLE/Context.h"
     16 #include "libANGLE/Query.h"
     17 #include "libANGLE/Surface.h"
     18 #include "libANGLE/VertexArray.h"
     19 #include "libANGLE/renderer/d3d/DisplayD3D.h"
     20 #include "libANGLE/renderer/d3d/TextureD3D.h"
     21 #include "libANGLE/renderer/d3d/d3d11/Buffer11.h"
     22 #include "libANGLE/renderer/d3d/d3d11/Context11.h"
     23 #include "libANGLE/renderer/d3d/d3d11/Framebuffer11.h"
     24 #include "libANGLE/renderer/d3d/d3d11/IndexBuffer11.h"
     25 #include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
     26 #include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
     27 #include "libANGLE/renderer/d3d/d3d11/ShaderExecutable11.h"
     28 #include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h"
     29 #include "libANGLE/renderer/d3d/d3d11/TransformFeedback11.h"
     30 #include "libANGLE/renderer/d3d/d3d11/VertexArray11.h"
     31 #include "libANGLE/renderer/d3d/d3d11/VertexBuffer11.h"
     32 
     33 namespace rx
     34 {
     35 
     36 namespace
     37 {
     38 bool ImageIndexConflictsWithSRV(const gl::ImageIndex &index, D3D11_SHADER_RESOURCE_VIEW_DESC desc)
     39 {
     40    unsigned mipLevel           = index.getLevelIndex();
     41    gl::TextureType textureType = index.getType();
     42 
     43    switch (desc.ViewDimension)
     44    {
     45        case D3D11_SRV_DIMENSION_TEXTURE2D:
     46        {
     47            bool allLevels         = (desc.Texture2D.MipLevels == std::numeric_limits<UINT>::max());
     48            unsigned int maxSrvMip = desc.Texture2D.MipLevels + desc.Texture2D.MostDetailedMip;
     49            maxSrvMip              = allLevels ? INT_MAX : maxSrvMip;
     50 
     51            unsigned mipMin = index.getLevelIndex();
     52            unsigned mipMax = INT_MAX;
     53 
     54            return textureType == gl::TextureType::_2D &&
     55                   gl::RangeUI(mipMin, mipMax)
     56                       .intersects(gl::RangeUI(desc.Texture2D.MostDetailedMip, maxSrvMip));
     57        }
     58 
     59        case D3D11_SRV_DIMENSION_TEXTURE2DARRAY:
     60        {
     61            GLint layerIndex = index.getLayerIndex();
     62 
     63            bool allLevels = (desc.Texture2DArray.MipLevels == std::numeric_limits<UINT>::max());
     64            unsigned int maxSrvMip =
     65                desc.Texture2DArray.MipLevels + desc.Texture2DArray.MostDetailedMip;
     66            maxSrvMip = allLevels ? INT_MAX : maxSrvMip;
     67 
     68            unsigned maxSlice = desc.Texture2DArray.FirstArraySlice + desc.Texture2DArray.ArraySize;
     69 
     70            // Cube maps can be mapped to Texture2DArray SRVs
     71            return (textureType == gl::TextureType::_2DArray ||
     72                    textureType == gl::TextureType::CubeMap) &&
     73                   desc.Texture2DArray.MostDetailedMip <= mipLevel && mipLevel < maxSrvMip &&
     74                   desc.Texture2DArray.FirstArraySlice <= static_cast<UINT>(layerIndex) &&
     75                   static_cast<UINT>(layerIndex) < maxSlice;
     76        }
     77 
     78        case D3D11_SRV_DIMENSION_TEXTURECUBE:
     79        {
     80            bool allLevels = (desc.TextureCube.MipLevels == std::numeric_limits<UINT>::max());
     81            unsigned int maxSrvMip = desc.TextureCube.MipLevels + desc.TextureCube.MostDetailedMip;
     82            maxSrvMip              = allLevels ? INT_MAX : maxSrvMip;
     83 
     84            return textureType == gl::TextureType::CubeMap &&
     85                   desc.TextureCube.MostDetailedMip <= mipLevel && mipLevel < maxSrvMip;
     86        }
     87 
     88        case D3D11_SRV_DIMENSION_TEXTURE3D:
     89        {
     90            bool allLevels         = (desc.Texture3D.MipLevels == std::numeric_limits<UINT>::max());
     91            unsigned int maxSrvMip = desc.Texture3D.MipLevels + desc.Texture3D.MostDetailedMip;
     92            maxSrvMip              = allLevels ? INT_MAX : maxSrvMip;
     93 
     94            return textureType == gl::TextureType::_3D &&
     95                   desc.Texture3D.MostDetailedMip <= mipLevel && mipLevel < maxSrvMip;
     96        }
     97        default:
     98            // We only handle the cases corresponding to valid image indexes
     99            UNIMPLEMENTED();
    100    }
    101 
    102    return false;
    103 }
    104 
    105 bool ImageIndexConflictsWithUAV(const gl::ImageIndex &index, D3D11_UNORDERED_ACCESS_VIEW_DESC desc)
    106 {
    107    unsigned mipLevel           = index.getLevelIndex();
    108    gl::TextureType textureType = index.getType();
    109 
    110    switch (desc.ViewDimension)
    111    {
    112        case D3D11_UAV_DIMENSION_TEXTURE2D:
    113        {
    114            return textureType == gl::TextureType::_2D && mipLevel == desc.Texture2D.MipSlice;
    115        }
    116 
    117        case D3D11_UAV_DIMENSION_TEXTURE2DARRAY:
    118        {
    119            GLint layerIndex         = index.getLayerIndex();
    120            unsigned mipSlice        = desc.Texture2DArray.MipSlice;
    121            unsigned firstArraySlice = desc.Texture2DArray.FirstArraySlice;
    122            unsigned lastArraySlice  = firstArraySlice + desc.Texture2DArray.ArraySize;
    123 
    124            return (textureType == gl::TextureType::_2DArray ||
    125                    textureType == gl::TextureType::CubeMap) &&
    126                   (mipLevel == mipSlice && gl::RangeUI(firstArraySlice, lastArraySlice)
    127                                                .contains(static_cast<UINT>(layerIndex)));
    128        }
    129 
    130        case D3D11_UAV_DIMENSION_TEXTURE3D:
    131        {
    132            GLint layerIndex     = index.getLayerIndex();
    133            unsigned mipSlice    = desc.Texture3D.MipSlice;
    134            unsigned firstWSlice = desc.Texture3D.FirstWSlice;
    135            unsigned lastWSlice  = firstWSlice + desc.Texture3D.WSize;
    136 
    137            return textureType == gl::TextureType::_3D &&
    138                   (mipLevel == mipSlice &&
    139                    gl::RangeUI(firstWSlice, lastWSlice).contains(static_cast<UINT>(layerIndex)));
    140        }
    141        default:
    142            return false;
    143    }
    144 }
    145 
    146 // Does *not* increment the resource ref count!!
    147 ID3D11Resource *GetViewResource(ID3D11View *view)
    148 {
    149    ID3D11Resource *resource = nullptr;
    150    ASSERT(view);
    151    view->GetResource(&resource);
    152    resource->Release();
    153    return resource;
    154 }
    155 
    156 int GetWrapBits(GLenum wrap)
    157 {
    158    switch (wrap)
    159    {
    160        case GL_CLAMP_TO_EDGE:
    161            return 0x0;
    162        case GL_REPEAT:
    163            return 0x1;
    164        case GL_MIRRORED_REPEAT:
    165            return 0x2;
    166        case GL_CLAMP_TO_BORDER:
    167            return 0x3;
    168        default:
    169            UNREACHABLE();
    170            return 0;
    171    }
    172 }
    173 
    174 Optional<size_t> FindFirstNonInstanced(
    175    const std::vector<const TranslatedAttribute *> &currentAttributes)
    176 {
    177    for (size_t index = 0; index < currentAttributes.size(); ++index)
    178    {
    179        if (currentAttributes[index]->divisor == 0)
    180        {
    181            return Optional<size_t>(index);
    182        }
    183    }
    184 
    185    return Optional<size_t>::Invalid();
    186 }
    187 
    188 void SortAttributesByLayout(const ProgramD3D &programD3D,
    189                            const std::vector<TranslatedAttribute> &vertexArrayAttribs,
    190                            const std::vector<TranslatedAttribute> &currentValueAttribs,
    191                            AttribIndexArray *sortedD3DSemanticsOut,
    192                            std::vector<const TranslatedAttribute *> *sortedAttributesOut)
    193 {
    194    sortedAttributesOut->clear();
    195 
    196    const AttribIndexArray &locationToSemantic = programD3D.getAttribLocationToD3DSemantics();
    197    const gl::ProgramExecutable &executable    = programD3D.getState().getExecutable();
    198 
    199    for (auto locationIndex : executable.getActiveAttribLocationsMask())
    200    {
    201        int d3dSemantic = locationToSemantic[locationIndex];
    202        if (sortedAttributesOut->size() <= static_cast<size_t>(d3dSemantic))
    203        {
    204            sortedAttributesOut->resize(d3dSemantic + 1);
    205        }
    206 
    207        (*sortedD3DSemanticsOut)[d3dSemantic] = d3dSemantic;
    208 
    209        const auto *arrayAttrib = &vertexArrayAttribs[locationIndex];
    210        if (arrayAttrib->attribute && arrayAttrib->attribute->enabled)
    211        {
    212            (*sortedAttributesOut)[d3dSemantic] = arrayAttrib;
    213        }
    214        else
    215        {
    216            ASSERT(currentValueAttribs[locationIndex].attribute);
    217            (*sortedAttributesOut)[d3dSemantic] = &currentValueAttribs[locationIndex];
    218        }
    219    }
    220 }
    221 
    222 void UpdateUniformBuffer(ID3D11DeviceContext *deviceContext,
    223                         UniformStorage11 *storage,
    224                         const d3d11::Buffer *buffer)
    225 {
    226    deviceContext->UpdateSubresource(buffer->get(), 0, nullptr, storage->getDataPointer(0, 0), 0,
    227                                     0);
    228 }
    229 
    230 size_t GetReservedBufferCount(bool usesPointSpriteEmulation)
    231 {
    232    return usesPointSpriteEmulation ? 1 : 0;
    233 }
    234 
    235 bool CullsEverything(const gl::State &glState)
    236 {
    237    return (glState.getRasterizerState().cullFace &&
    238            glState.getRasterizerState().cullMode == gl::CullFaceMode::FrontAndBack);
    239 }
    240 }  // anonymous namespace
    241 
    242 // StateManager11::ViewCache Implementation.
    243 template <typename ViewType, typename DescType>
    244 StateManager11::ViewCache<ViewType, DescType>::ViewCache() : mHighestUsedView(0)
    245 {}
    246 
    247 template <typename ViewType, typename DescType>
    248 StateManager11::ViewCache<ViewType, DescType>::~ViewCache()
    249 {}
    250 
    251 template <typename ViewType, typename DescType>
    252 void StateManager11::ViewCache<ViewType, DescType>::update(size_t resourceIndex, ViewType *view)
    253 {
    254    ASSERT(resourceIndex < mCurrentViews.size());
    255    ViewRecord<DescType> *record = &mCurrentViews[resourceIndex];
    256 
    257    record->view = reinterpret_cast<uintptr_t>(view);
    258    if (view)
    259    {
    260        record->resource = reinterpret_cast<uintptr_t>(GetViewResource(view));
    261        view->GetDesc(&record->desc);
    262        mHighestUsedView = std::max(resourceIndex + 1, mHighestUsedView);
    263    }
    264    else
    265    {
    266        record->resource = 0;
    267 
    268        if (resourceIndex + 1 == mHighestUsedView)
    269        {
    270            do
    271            {
    272                --mHighestUsedView;
    273            } while (mHighestUsedView > 0 && mCurrentViews[mHighestUsedView].view == 0);
    274        }
    275    }
    276 }
    277 
    278 template <typename ViewType, typename DescType>
    279 void StateManager11::ViewCache<ViewType, DescType>::clear()
    280 {
    281    if (mCurrentViews.empty())
    282    {
    283        return;
    284    }
    285 
    286    memset(&mCurrentViews[0], 0, sizeof(ViewRecord<DescType>) * mCurrentViews.size());
    287    mHighestUsedView = 0;
    288 }
    289 
    290 StateManager11::SRVCache *StateManager11::getSRVCache(gl::ShaderType shaderType)
    291 {
    292    ASSERT(shaderType != gl::ShaderType::InvalidEnum);
    293    return &mCurShaderSRVs[shaderType];
    294 }
    295 
    296 // ShaderConstants11 implementation
    297 ShaderConstants11::ShaderConstants11() : mNumActiveShaderSamplers({})
    298 {
    299    mShaderConstantsDirty.set();
    300 }
    301 
    302 ShaderConstants11::~ShaderConstants11() {}
    303 
    304 void ShaderConstants11::init(const gl::Caps &caps)
    305 {
    306    for (gl::ShaderType shaderType : gl::AllShaderTypes())
    307    {
    308        mShaderSamplerMetadata[shaderType].resize(caps.maxShaderTextureImageUnits[shaderType]);
    309        mShaderReadonlyImageMetadata[shaderType].resize(caps.maxShaderImageUniforms[shaderType]);
    310        mShaderImageMetadata[shaderType].resize(caps.maxShaderImageUniforms[shaderType]);
    311    }
    312 }
    313 
    314 size_t ShaderConstants11::GetShaderConstantsStructSize(gl::ShaderType shaderType)
    315 {
    316    switch (shaderType)
    317    {
    318        case gl::ShaderType::Vertex:
    319            return sizeof(Vertex);
    320        case gl::ShaderType::Fragment:
    321            return sizeof(Pixel);
    322        case gl::ShaderType::Compute:
    323            return sizeof(Compute);
    324 
    325        // TODO(jiawei.shao@intel.com): return geometry shader constant struct size
    326        case gl::ShaderType::Geometry:
    327            return 0u;
    328 
    329        default:
    330            UNREACHABLE();
    331            return 0u;
    332    }
    333 }
    334 
    335 size_t ShaderConstants11::getRequiredBufferSize(gl::ShaderType shaderType) const
    336 {
    337    ASSERT(shaderType != gl::ShaderType::InvalidEnum);
    338    return GetShaderConstantsStructSize(shaderType) +
    339           mShaderSamplerMetadata[shaderType].size() * sizeof(SamplerMetadata) +
    340           mShaderImageMetadata[shaderType].size() * sizeof(ImageMetadata) +
    341           mShaderReadonlyImageMetadata[shaderType].size() * sizeof(ImageMetadata);
    342 }
    343 
    344 void ShaderConstants11::markDirty()
    345 {
    346    mShaderConstantsDirty.set();
    347    mNumActiveShaderSamplers.fill(0);
    348 }
    349 
    350 bool ShaderConstants11::updateSamplerMetadata(SamplerMetadata *data,
    351                                              const gl::Texture &texture,
    352                                              const gl::SamplerState &samplerState)
    353 {
    354    bool dirty               = false;
    355    unsigned int baseLevel   = texture.getTextureState().getEffectiveBaseLevel();
    356    gl::TextureTarget target = (texture.getType() == gl::TextureType::CubeMap)
    357                                   ? gl::kCubeMapTextureTargetMin
    358                                   : gl::NonCubeTextureTypeToTarget(texture.getType());
    359    GLenum sizedFormat       = texture.getFormat(target, baseLevel).info->sizedInternalFormat;
    360    if (data->baseLevel != static_cast<int>(baseLevel))
    361    {
    362        data->baseLevel = static_cast<int>(baseLevel);
    363        dirty           = true;
    364    }
    365 
    366    // Some metadata is needed only for integer textures. We avoid updating the constant buffer
    367    // unnecessarily by changing the data only in case the texture is an integer texture and
    368    // the values have changed.
    369    bool needIntegerTextureMetadata = false;
    370    // internalFormatBits == 0 means a 32-bit texture in the case of integer textures.
    371    int internalFormatBits = 0;
    372    switch (sizedFormat)
    373    {
    374        case GL_RGBA32I:
    375        case GL_RGBA32UI:
    376        case GL_RGB32I:
    377        case GL_RGB32UI:
    378        case GL_RG32I:
    379        case GL_RG32UI:
    380        case GL_R32I:
    381        case GL_R32UI:
    382            needIntegerTextureMetadata = true;
    383            break;
    384        case GL_RGBA16I:
    385        case GL_RGBA16UI:
    386        case GL_RGB16I:
    387        case GL_RGB16UI:
    388        case GL_RG16I:
    389        case GL_RG16UI:
    390        case GL_R16I:
    391        case GL_R16UI:
    392            needIntegerTextureMetadata = true;
    393            internalFormatBits         = 16;
    394            break;
    395        case GL_RGBA8I:
    396        case GL_RGBA8UI:
    397        case GL_RGB8I:
    398        case GL_RGB8UI:
    399        case GL_RG8I:
    400        case GL_RG8UI:
    401        case GL_R8I:
    402        case GL_R8UI:
    403            needIntegerTextureMetadata = true;
    404            internalFormatBits         = 8;
    405            break;
    406        case GL_RGB10_A2UI:
    407            needIntegerTextureMetadata = true;
    408            internalFormatBits         = 10;
    409            break;
    410        default:
    411            break;
    412    }
    413    if (needIntegerTextureMetadata)
    414    {
    415        if (data->internalFormatBits != internalFormatBits)
    416        {
    417            data->internalFormatBits = internalFormatBits;
    418            dirty                    = true;
    419        }
    420        // Pack the wrap values into one integer so we can fit all the metadata in two 4-integer
    421        // vectors.
    422        GLenum wrapS  = samplerState.getWrapS();
    423        GLenum wrapT  = samplerState.getWrapT();
    424        GLenum wrapR  = samplerState.getWrapR();
    425        int wrapModes = GetWrapBits(wrapS) | (GetWrapBits(wrapT) << 2) | (GetWrapBits(wrapR) << 4);
    426        if (data->wrapModes != wrapModes)
    427        {
    428            data->wrapModes = wrapModes;
    429            dirty           = true;
    430        }
    431 
    432        const angle::ColorGeneric &borderColor(samplerState.getBorderColor());
    433        constexpr int kBlack[4]          = {};
    434        const void *const intBorderColor = (borderColor.type == angle::ColorGeneric::Type::Float)
    435                                               ? kBlack
    436                                               : borderColor.colorI.data();
    437        ASSERT(static_cast<const void *>(borderColor.colorI.data()) ==
    438               static_cast<const void *>(borderColor.colorUI.data()));
    439        if (memcmp(data->intBorderColor, intBorderColor, sizeof(data->intBorderColor)) != 0)
    440        {
    441            memcpy(data->intBorderColor, intBorderColor, sizeof(data->intBorderColor));
    442            dirty = true;
    443        }
    444    }
    445 
    446    return dirty;
    447 }
    448 
    449 bool ShaderConstants11::updateImageMetadata(ImageMetadata *data, const gl::ImageUnit &imageUnit)
    450 {
    451    bool dirty = false;
    452 
    453    if (data->layer != static_cast<int>(imageUnit.layer))
    454    {
    455        data->layer = static_cast<int>(imageUnit.layer);
    456        dirty       = true;
    457    }
    458 
    459    if (data->level != static_cast<unsigned int>(imageUnit.level))
    460    {
    461        data->level = static_cast<unsigned int>(imageUnit.level);
    462        dirty       = true;
    463    }
    464 
    465    return dirty;
    466 }
    467 
    468 void ShaderConstants11::setComputeWorkGroups(GLuint numGroupsX,
    469                                             GLuint numGroupsY,
    470                                             GLuint numGroupsZ)
    471 {
    472    mCompute.numWorkGroups[0] = numGroupsX;
    473    mCompute.numWorkGroups[1] = numGroupsY;
    474    mCompute.numWorkGroups[2] = numGroupsZ;
    475    mShaderConstantsDirty.set(gl::ShaderType::Compute);
    476 }
    477 
    478 void ShaderConstants11::setMultiviewWriteToViewportIndex(GLfloat index)
    479 {
    480    mVertex.multiviewWriteToViewportIndex = index;
    481    mPixel.multiviewWriteToViewportIndex  = index;
    482    mShaderConstantsDirty.set(gl::ShaderType::Vertex);
    483    mShaderConstantsDirty.set(gl::ShaderType::Fragment);
    484 }
    485 
    486 void ShaderConstants11::onViewportChange(const gl::Rectangle &glViewport,
    487                                         const D3D11_VIEWPORT &dxViewport,
    488                                         const gl::Offset &glFragCoordOffset,
    489                                         bool is9_3,
    490                                         bool presentPathFast)
    491 {
    492    mShaderConstantsDirty.set(gl::ShaderType::Vertex);
    493    mShaderConstantsDirty.set(gl::ShaderType::Fragment);
    494 
    495    // On Feature Level 9_*, we must emulate large and/or negative viewports in the shaders
    496    // using viewAdjust (like the D3D9 renderer).
    497    if (is9_3)
    498    {
    499        mVertex.viewAdjust[0] = static_cast<float>((glViewport.width - dxViewport.Width) +
    500                                                   2 * (glViewport.x - dxViewport.TopLeftX)) /
    501                                dxViewport.Width;
    502        mVertex.viewAdjust[1] = static_cast<float>((glViewport.height - dxViewport.Height) +
    503                                                   2 * (glViewport.y - dxViewport.TopLeftY)) /
    504                                dxViewport.Height;
    505        mVertex.viewAdjust[2] = static_cast<float>(glViewport.width) / dxViewport.Width;
    506        mVertex.viewAdjust[3] = static_cast<float>(glViewport.height) / dxViewport.Height;
    507    }
    508 
    509    mPixel.viewCoords[0] = glViewport.width * 0.5f;
    510    mPixel.viewCoords[1] = glViewport.height * 0.5f;
    511    mPixel.viewCoords[2] = glViewport.x + (glViewport.width * 0.5f);
    512    mPixel.viewCoords[3] = glViewport.y + (glViewport.height * 0.5f);
    513 
    514    // Instanced pointsprite emulation requires ViewCoords to be defined in the
    515    // the vertex shader.
    516    mVertex.viewCoords[0] = mPixel.viewCoords[0];
    517    mVertex.viewCoords[1] = mPixel.viewCoords[1];
    518    mVertex.viewCoords[2] = mPixel.viewCoords[2];
    519    mVertex.viewCoords[3] = mPixel.viewCoords[3];
    520 
    521    const float zNear = dxViewport.MinDepth;
    522    const float zFar  = dxViewport.MaxDepth;
    523 
    524    mPixel.depthFront[0] = (zFar - zNear) * 0.5f;
    525    mPixel.depthFront[1] = (zNear + zFar) * 0.5f;
    526 
    527    mVertex.depthRange[0] = zNear;
    528    mVertex.depthRange[1] = zFar;
    529    mVertex.depthRange[2] = zFar - zNear;
    530 
    531    mPixel.depthRange[0] = zNear;
    532    mPixel.depthRange[1] = zFar;
    533    mPixel.depthRange[2] = zFar - zNear;
    534 
    535    mPixel.viewScale[0] = 1.0f;
    536    mPixel.viewScale[1] = presentPathFast ? 1.0f : -1.0f;
    537    // Updates to the multiviewWriteToViewportIndex member are to be handled whenever the draw
    538    // framebuffer's layout is changed.
    539 
    540    mVertex.viewScale[0] = mPixel.viewScale[0];
    541    mVertex.viewScale[1] = mPixel.viewScale[1];
    542 
    543    mPixel.fragCoordOffset[0] = static_cast<float>(glFragCoordOffset.x);
    544    mPixel.fragCoordOffset[1] = static_cast<float>(glFragCoordOffset.y);
    545 }
    546 
    547 // Update the ShaderConstants with a new first vertex and return whether the update dirties them.
    548 ANGLE_INLINE bool ShaderConstants11::onFirstVertexChange(GLint firstVertex)
    549 {
    550    // firstVertex should already include baseVertex, if any.
    551    uint32_t newFirstVertex = static_cast<uint32_t>(firstVertex);
    552 
    553    bool firstVertexDirty = (mVertex.firstVertex != newFirstVertex);
    554    if (firstVertexDirty)
    555    {
    556        mVertex.firstVertex = newFirstVertex;
    557        mShaderConstantsDirty.set(gl::ShaderType::Vertex);
    558    }
    559    return firstVertexDirty;
    560 }
    561 
    562 void ShaderConstants11::onSamplerChange(gl::ShaderType shaderType,
    563                                        unsigned int samplerIndex,
    564                                        const gl::Texture &texture,
    565                                        const gl::SamplerState &samplerState)
    566 {
    567    ASSERT(shaderType != gl::ShaderType::InvalidEnum);
    568    if (updateSamplerMetadata(&mShaderSamplerMetadata[shaderType][samplerIndex], texture,
    569                              samplerState))
    570    {
    571        mNumActiveShaderSamplers[shaderType] = 0;
    572    }
    573 }
    574 
    575 bool ShaderConstants11::onImageChange(gl::ShaderType shaderType,
    576                                      unsigned int imageIndex,
    577                                      const gl::ImageUnit &imageUnit)
    578 {
    579    ASSERT(shaderType != gl::ShaderType::InvalidEnum);
    580    bool dirty = false;
    581    if (imageUnit.access == GL_READ_ONLY)
    582    {
    583        if (updateImageMetadata(&mShaderReadonlyImageMetadata[shaderType][imageIndex], imageUnit))
    584        {
    585            mNumActiveShaderReadonlyImages[shaderType] = 0;
    586            dirty                                      = true;
    587        }
    588    }
    589    else
    590    {
    591        if (updateImageMetadata(&mShaderImageMetadata[shaderType][imageIndex], imageUnit))
    592        {
    593            mNumActiveShaderImages[shaderType] = 0;
    594            dirty                              = true;
    595        }
    596    }
    597    return dirty;
    598 }
    599 
    600 void ShaderConstants11::onClipControlChange(bool lowerLeft, bool zeroToOne)
    601 {
    602    mVertex.clipControlOrigin    = lowerLeft ? -1.0f : 1.0f;
    603    mVertex.clipControlZeroToOne = zeroToOne ? 1.0f : 0.0f;
    604    mShaderConstantsDirty.set(gl::ShaderType::Vertex);
    605 }
    606 
    607 angle::Result ShaderConstants11::updateBuffer(const gl::Context *context,
    608                                              Renderer11 *renderer,
    609                                              gl::ShaderType shaderType,
    610                                              const ProgramD3D &programD3D,
    611                                              const d3d11::Buffer &driverConstantBuffer)
    612 {
    613    // Re-upload the sampler meta-data if the current program uses more samplers
    614    // than we previously uploaded.
    615    const int numSamplers       = programD3D.getUsedSamplerRange(shaderType).length();
    616    const int numReadonlyImages = programD3D.getUsedImageRange(shaderType, true).length();
    617    const int numImages         = programD3D.getUsedImageRange(shaderType, false).length();
    618 
    619    const bool dirty = mShaderConstantsDirty[shaderType] ||
    620                       (mNumActiveShaderSamplers[shaderType] < numSamplers) ||
    621                       (mNumActiveShaderReadonlyImages[shaderType] < numReadonlyImages) ||
    622                       (mNumActiveShaderImages[shaderType] < numImages);
    623 
    624    const size_t dataSize = GetShaderConstantsStructSize(shaderType);
    625    const uint8_t *samplerData =
    626        reinterpret_cast<const uint8_t *>(mShaderSamplerMetadata[shaderType].data());
    627    const size_t samplerDataSize = sizeof(SamplerMetadata) * numSamplers;
    628    const uint8_t *readonlyImageData =
    629        reinterpret_cast<const uint8_t *>(mShaderReadonlyImageMetadata[shaderType].data());
    630    const size_t readonlyImageDataSize = sizeof(ImageMetadata) * numReadonlyImages;
    631    const uint8_t *imageData =
    632        reinterpret_cast<const uint8_t *>(mShaderImageMetadata[shaderType].data());
    633    const size_t imageDataSize = sizeof(ImageMetadata) * numImages;
    634 
    635    mNumActiveShaderSamplers[shaderType]       = numSamplers;
    636    mNumActiveShaderReadonlyImages[shaderType] = numReadonlyImages;
    637    mNumActiveShaderImages[shaderType]         = numImages;
    638    mShaderConstantsDirty.set(shaderType, false);
    639 
    640    const uint8_t *data = nullptr;
    641    switch (shaderType)
    642    {
    643        case gl::ShaderType::Vertex:
    644            data = reinterpret_cast<const uint8_t *>(&mVertex);
    645            break;
    646        case gl::ShaderType::Fragment:
    647            data = reinterpret_cast<const uint8_t *>(&mPixel);
    648            break;
    649        case gl::ShaderType::Compute:
    650            data = reinterpret_cast<const uint8_t *>(&mCompute);
    651            break;
    652        default:
    653            UNREACHABLE();
    654            break;
    655    }
    656 
    657    ASSERT(driverConstantBuffer.valid());
    658 
    659    if (!dirty)
    660    {
    661        return angle::Result::Continue;
    662    }
    663 
    664    // Previous buffer contents are discarded, so we need to refresh the whole buffer.
    665    D3D11_MAPPED_SUBRESOURCE mapping = {};
    666    ANGLE_TRY(renderer->mapResource(context, driverConstantBuffer.get(), 0, D3D11_MAP_WRITE_DISCARD,
    667                                    0, &mapping));
    668 
    669    memcpy(mapping.pData, data, dataSize);
    670    memcpy(static_cast<uint8_t *>(mapping.pData) + dataSize, samplerData,
    671           sizeof(SamplerMetadata) * numSamplers);
    672 
    673    memcpy(static_cast<uint8_t *>(mapping.pData) + dataSize + samplerDataSize, readonlyImageData,
    674           readonlyImageDataSize);
    675    memcpy(
    676        static_cast<uint8_t *>(mapping.pData) + dataSize + samplerDataSize + readonlyImageDataSize,
    677        imageData, imageDataSize);
    678    renderer->getDeviceContext()->Unmap(driverConstantBuffer.get(), 0);
    679 
    680    return angle::Result::Continue;
    681 }
    682 
    683 StateManager11::StateManager11(Renderer11 *renderer)
    684    : mRenderer(renderer),
    685      mInternalDirtyBits(),
    686      mCurSampleAlphaToCoverage(false),
    687      mCurBlendStateExt(),
    688      mCurBlendColor(0, 0, 0, 0),
    689      mCurSampleMask(0),
    690      mCurStencilRef(0),
    691      mCurStencilBackRef(0),
    692      mCurStencilSize(0),
    693      mCurScissorEnabled(false),
    694      mCurScissorRect(),
    695      mCurViewport(),
    696      mCurNear(0.0f),
    697      mCurFar(0.0f),
    698      mViewportBounds(),
    699      mRenderTargetIsDirty(true),
    700      mCurPresentPathFastEnabled(false),
    701      mCurPresentPathFastColorBufferHeight(0),
    702      mDirtyCurrentValueAttribs(),
    703      mCurrentValueAttribs(),
    704      mCurrentInputLayout(),
    705      mDirtyVertexBufferRange(gl::MAX_VERTEX_ATTRIBS, 0),
    706      mCurrentPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_UNDEFINED),
    707      mLastAppliedDrawMode(gl::PrimitiveMode::InvalidEnum),
    708      mCullEverything(false),
    709      mDirtySwizzles(false),
    710      mAppliedIB(nullptr),
    711      mAppliedIBFormat(DXGI_FORMAT_UNKNOWN),
    712      mAppliedIBOffset(0),
    713      mIndexBufferIsDirty(false),
    714      mVertexDataManager(renderer),
    715      mIndexDataManager(renderer),
    716      mIsMultiviewEnabled(false),
    717      mIndependentBlendStates(false),
    718      mEmptySerial(mRenderer->generateSerial()),
    719      mProgramD3D(nullptr),
    720      mVertexArray11(nullptr),
    721      mFramebuffer11(nullptr)
    722 {
    723    mCurDepthStencilState.depthTest                = false;
    724    mCurDepthStencilState.depthFunc                = GL_LESS;
    725    mCurDepthStencilState.depthMask                = true;
    726    mCurDepthStencilState.stencilTest              = false;
    727    mCurDepthStencilState.stencilMask              = true;
    728    mCurDepthStencilState.stencilFail              = GL_KEEP;
    729    mCurDepthStencilState.stencilPassDepthFail     = GL_KEEP;
    730    mCurDepthStencilState.stencilPassDepthPass     = GL_KEEP;
    731    mCurDepthStencilState.stencilWritemask         = static_cast<GLuint>(-1);
    732    mCurDepthStencilState.stencilBackFunc          = GL_ALWAYS;
    733    mCurDepthStencilState.stencilBackMask          = static_cast<GLuint>(-1);
    734    mCurDepthStencilState.stencilBackFail          = GL_KEEP;
    735    mCurDepthStencilState.stencilBackPassDepthFail = GL_KEEP;
    736    mCurDepthStencilState.stencilBackPassDepthPass = GL_KEEP;
    737    mCurDepthStencilState.stencilBackWritemask     = static_cast<GLuint>(-1);
    738 
    739    mCurRasterState.rasterizerDiscard   = false;
    740    mCurRasterState.cullFace            = false;
    741    mCurRasterState.cullMode            = gl::CullFaceMode::Back;
    742    mCurRasterState.frontFace           = GL_CCW;
    743    mCurRasterState.polygonOffsetFill   = false;
    744    mCurRasterState.polygonOffsetFactor = 0.0f;
    745    mCurRasterState.polygonOffsetUnits  = 0.0f;
    746    mCurRasterState.pointDrawMode       = false;
    747    mCurRasterState.multiSample         = false;
    748    mCurRasterState.dither              = false;
    749 
    750    // Start with all internal dirty bits set except the SRV and UAV bits.
    751    mInternalDirtyBits.set();
    752    mInternalDirtyBits.reset(DIRTY_BIT_GRAPHICS_SRV_STATE);
    753    mInternalDirtyBits.reset(DIRTY_BIT_GRAPHICS_UAV_STATE);
    754    mInternalDirtyBits.reset(DIRTY_BIT_COMPUTE_SRV_STATE);
    755    mInternalDirtyBits.reset(DIRTY_BIT_COMPUTE_UAV_STATE);
    756 
    757    mGraphicsDirtyBitsMask.set();
    758    mGraphicsDirtyBitsMask.reset(DIRTY_BIT_COMPUTE_SRV_STATE);
    759    mGraphicsDirtyBitsMask.reset(DIRTY_BIT_COMPUTE_UAV_STATE);
    760    mComputeDirtyBitsMask.set(DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE);
    761    mComputeDirtyBitsMask.set(DIRTY_BIT_PROGRAM_UNIFORMS);
    762    mComputeDirtyBitsMask.set(DIRTY_BIT_DRIVER_UNIFORMS);
    763    mComputeDirtyBitsMask.set(DIRTY_BIT_PROGRAM_UNIFORM_BUFFERS);
    764    mComputeDirtyBitsMask.set(DIRTY_BIT_SHADERS);
    765    mComputeDirtyBitsMask.set(DIRTY_BIT_COMPUTE_SRV_STATE);
    766    mComputeDirtyBitsMask.set(DIRTY_BIT_COMPUTE_UAV_STATE);
    767 
    768    // Initially all current value attributes must be updated on first use.
    769    mDirtyCurrentValueAttribs.set();
    770 
    771    mCurrentVertexBuffers.fill(nullptr);
    772    mCurrentVertexStrides.fill(std::numeric_limits<UINT>::max());
    773    mCurrentVertexOffsets.fill(std::numeric_limits<UINT>::max());
    774 }
    775 
    776 StateManager11::~StateManager11() {}
    777 
    778 template <typename SRVType>
    779 void StateManager11::setShaderResourceInternal(gl::ShaderType shaderType,
    780                                               UINT resourceSlot,
    781                                               const SRVType *srv)
    782 {
    783    auto *currentSRVs = getSRVCache(shaderType);
    784    ASSERT(static_cast<size_t>(resourceSlot) < currentSRVs->size());
    785    const ViewRecord<D3D11_SHADER_RESOURCE_VIEW_DESC> &record = (*currentSRVs)[resourceSlot];
    786 
    787    if (record.view != reinterpret_cast<uintptr_t>(srv))
    788    {
    789        ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
    790        ID3D11ShaderResourceView *srvPtr   = srv ? srv->get() : nullptr;
    791        if (srvPtr)
    792        {
    793            uintptr_t resource = reinterpret_cast<uintptr_t>(GetViewResource(srvPtr));
    794            unsetConflictingUAVs(gl::PipelineType::GraphicsPipeline, gl::ShaderType::Compute,
    795                                 resource, nullptr);
    796        }
    797 
    798        switch (shaderType)
    799        {
    800            case gl::ShaderType::Vertex:
    801                deviceContext->VSSetShaderResources(resourceSlot, 1, &srvPtr);
    802                break;
    803            case gl::ShaderType::Fragment:
    804                deviceContext->PSSetShaderResources(resourceSlot, 1, &srvPtr);
    805                break;
    806            case gl::ShaderType::Compute:
    807            {
    808                if (srvPtr)
    809                {
    810                    uintptr_t resource = reinterpret_cast<uintptr_t>(GetViewResource(srvPtr));
    811                    unsetConflictingRTVs(resource);
    812                }
    813                deviceContext->CSSetShaderResources(resourceSlot, 1, &srvPtr);
    814                break;
    815            }
    816            default:
    817                UNREACHABLE();
    818        }
    819 
    820        currentSRVs->update(resourceSlot, srvPtr);
    821    }
    822 }
    823 
    824 template <typename UAVType>
    825 void StateManager11::setUnorderedAccessViewInternal(UINT resourceSlot,
    826                                                    const UAVType *uav,
    827                                                    UAVList *uavList)
    828 {
    829    ASSERT(static_cast<size_t>(resourceSlot) < mCurComputeUAVs.size());
    830    const ViewRecord<D3D11_UNORDERED_ACCESS_VIEW_DESC> &record = mCurComputeUAVs[resourceSlot];
    831 
    832    if (record.view != reinterpret_cast<uintptr_t>(uav))
    833    {
    834        ID3D11UnorderedAccessView *uavPtr = uav ? uav->get() : nullptr;
    835        // We need to make sure that resource being set to UnorderedAccessView slot |resourceSlot|
    836        // is not bound on SRV.
    837        if (uavPtr)
    838        {
    839            uintptr_t resource = reinterpret_cast<uintptr_t>(GetViewResource(uavPtr));
    840            unsetConflictingSRVs(gl::PipelineType::ComputePipeline, gl::ShaderType::Vertex,
    841                                 resource, nullptr, false);
    842            unsetConflictingSRVs(gl::PipelineType::ComputePipeline, gl::ShaderType::Fragment,
    843                                 resource, nullptr, false);
    844            unsetConflictingSRVs(gl::PipelineType::ComputePipeline, gl::ShaderType::Compute,
    845                                 resource, nullptr, false);
    846        }
    847        uavList->data[resourceSlot] = uavPtr;
    848        if (static_cast<int>(resourceSlot) > uavList->highestUsed)
    849        {
    850            uavList->highestUsed = resourceSlot;
    851        }
    852 
    853        mCurComputeUAVs.update(resourceSlot, uavPtr);
    854    }
    855 }
    856 
    857 void StateManager11::updateStencilSizeIfChanged(bool depthStencilInitialized,
    858                                                unsigned int stencilSize)
    859 {
    860    if (!depthStencilInitialized || stencilSize != mCurStencilSize)
    861    {
    862        mCurStencilSize = stencilSize;
    863        mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
    864    }
    865 }
    866 
    867 void StateManager11::checkPresentPath(const gl::Context *context)
    868 {
    869    const auto *framebuffer          = context->getState().getDrawFramebuffer();
    870    const auto *firstColorAttachment = framebuffer->getFirstColorAttachment();
    871    const bool clipSpaceOriginUpperLeft =
    872        context->getState().getClipSpaceOrigin() == gl::ClipSpaceOrigin::UpperLeft;
    873    const bool presentPathFastActive =
    874        UsePresentPathFast(mRenderer, firstColorAttachment) || clipSpaceOriginUpperLeft;
    875 
    876    const int colorBufferHeight = firstColorAttachment ? firstColorAttachment->getSize().height : 0;
    877 
    878    if ((mCurPresentPathFastEnabled != presentPathFastActive) ||
    879        (presentPathFastActive && (colorBufferHeight != mCurPresentPathFastColorBufferHeight)))
    880    {
    881        mCurPresentPathFastEnabled           = presentPathFastActive;
    882        mCurPresentPathFastColorBufferHeight = colorBufferHeight;
    883 
    884        // Scissor rect may need to be vertically inverted
    885        mInternalDirtyBits.set(DIRTY_BIT_SCISSOR_STATE);
    886 
    887        // Cull Mode may need to be inverted
    888        mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
    889 
    890        // Viewport may need to be vertically inverted
    891        invalidateViewport(context);
    892    }
    893 }
    894 
    895 angle::Result StateManager11::updateStateForCompute(const gl::Context *context,
    896                                                    GLuint numGroupsX,
    897                                                    GLuint numGroupsY,
    898                                                    GLuint numGroupsZ)
    899 {
    900    mShaderConstants.setComputeWorkGroups(numGroupsX, numGroupsY, numGroupsZ);
    901 
    902    if (mProgramD3D->updateSamplerMapping() == ProgramD3D::SamplerMapping::WasDirty)
    903    {
    904        invalidateTexturesAndSamplers();
    905    }
    906 
    907    if (mDirtySwizzles)
    908    {
    909        ANGLE_TRY(generateSwizzlesForShader(context, gl::ShaderType::Compute));
    910        mDirtySwizzles = false;
    911    }
    912 
    913    if (mProgramD3D->anyShaderUniformsDirty())
    914    {
    915        mInternalDirtyBits.set(DIRTY_BIT_PROGRAM_UNIFORMS);
    916    }
    917 
    918    auto dirtyBitsCopy = mInternalDirtyBits & mComputeDirtyBitsMask;
    919    mInternalDirtyBits &= ~mComputeDirtyBitsMask;
    920 
    921    for (auto iter = dirtyBitsCopy.begin(), end = dirtyBitsCopy.end(); iter != end; ++iter)
    922    {
    923        switch (*iter)
    924        {
    925            case DIRTY_BIT_COMPUTE_SRV_STATE:
    926                // Avoid to call syncTexturesForCompute function two times.
    927                iter.resetLaterBit(DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE);
    928                ANGLE_TRY(syncTexturesForCompute(context));
    929                break;
    930            case DIRTY_BIT_COMPUTE_UAV_STATE:
    931                ANGLE_TRY(syncUAVsForCompute(context));
    932                break;
    933            case DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE:
    934                ANGLE_TRY(syncTexturesForCompute(context));
    935                break;
    936            case DIRTY_BIT_PROGRAM_UNIFORMS:
    937            case DIRTY_BIT_DRIVER_UNIFORMS:
    938                ANGLE_TRY(applyComputeUniforms(context, mProgramD3D));
    939                break;
    940            case DIRTY_BIT_PROGRAM_UNIFORM_BUFFERS:
    941                ANGLE_TRY(syncUniformBuffers(context));
    942                break;
    943            case DIRTY_BIT_SHADERS:
    944                ANGLE_TRY(syncProgramForCompute(context));
    945                break;
    946            default:
    947                UNREACHABLE();
    948                break;
    949        }
    950    }
    951 
    952    return angle::Result::Continue;
    953 }
    954 
    955 void StateManager11::syncState(const gl::Context *context,
    956                               const gl::State::DirtyBits &dirtyBits,
    957                               gl::Command command)
    958 {
    959    if (!dirtyBits.any())
    960    {
    961        return;
    962    }
    963 
    964    const gl::State &state = context->getState();
    965 
    966    for (size_t dirtyBit : dirtyBits)
    967    {
    968        switch (dirtyBit)
    969        {
    970            case gl::State::DIRTY_BIT_BLEND_EQUATIONS:
    971            {
    972                const gl::BlendStateExt &blendStateExt = state.getBlendStateExt();
    973                ASSERT(mCurBlendStateExt.getDrawBufferCount() ==
    974                       blendStateExt.getDrawBufferCount());
    975                // Compare blend equations only for buffers with blending enabled because
    976                // subsequent sync stages enforce default values for buffers with blending disabled.
    977                if ((blendStateExt.getEnabledMask() &
    978                     mCurBlendStateExt.compareEquations(blendStateExt))
    979                        .any())
    980                {
    981                    mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
    982                }
    983                break;
    984            }
    985            case gl::State::DIRTY_BIT_BLEND_FUNCS:
    986            {
    987                const gl::BlendStateExt &blendStateExt = state.getBlendStateExt();
    988                ASSERT(mCurBlendStateExt.getDrawBufferCount() ==
    989                       blendStateExt.getDrawBufferCount());
    990                // Compare blend factors only for buffers with blending enabled because
    991                // subsequent sync stages enforce default values for buffers with blending disabled.
    992                if ((blendStateExt.getEnabledMask() &
    993                     mCurBlendStateExt.compareFactors(blendStateExt))
    994                        .any())
    995                {
    996                    mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
    997                }
    998                break;
    999            }
   1000            case gl::State::DIRTY_BIT_BLEND_ENABLED:
   1001            {
   1002                if (state.getBlendStateExt().getEnabledMask() != mCurBlendStateExt.getEnabledMask())
   1003                {
   1004                    mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
   1005                }
   1006                break;
   1007            }
   1008            case gl::State::DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED:
   1009                if (state.isSampleAlphaToCoverageEnabled() != mCurSampleAlphaToCoverage)
   1010                {
   1011                    mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
   1012                }
   1013                break;
   1014            case gl::State::DIRTY_BIT_DITHER_ENABLED:
   1015                if (state.getRasterizerState().dither != mCurRasterState.dither)
   1016                {
   1017                    mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
   1018                }
   1019                break;
   1020            case gl::State::DIRTY_BIT_COLOR_MASK:
   1021            {
   1022                if (state.getBlendStateExt().getColorMaskBits() !=
   1023                    mCurBlendStateExt.getColorMaskBits())
   1024                {
   1025                    mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
   1026                }
   1027                break;
   1028            }
   1029            case gl::State::DIRTY_BIT_BLEND_COLOR:
   1030                if (state.getBlendColor() != mCurBlendColor)
   1031                {
   1032                    mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
   1033                }
   1034                break;
   1035            // Depth and stencil redundant state changes are guarded in the
   1036            // frontend so for related cases here just set the dirty bit.
   1037            case gl::State::DIRTY_BIT_DEPTH_MASK:
   1038                mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
   1039                break;
   1040            case gl::State::DIRTY_BIT_DEPTH_TEST_ENABLED:
   1041                mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
   1042                break;
   1043            case gl::State::DIRTY_BIT_DEPTH_FUNC:
   1044                mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
   1045                break;
   1046            case gl::State::DIRTY_BIT_STENCIL_TEST_ENABLED:
   1047                mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
   1048                break;
   1049            case gl::State::DIRTY_BIT_STENCIL_FUNCS_FRONT:
   1050                mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
   1051                break;
   1052            case gl::State::DIRTY_BIT_STENCIL_FUNCS_BACK:
   1053                mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
   1054                break;
   1055            case gl::State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT:
   1056                mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
   1057                break;
   1058            case gl::State::DIRTY_BIT_STENCIL_WRITEMASK_BACK:
   1059                mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
   1060                break;
   1061            case gl::State::DIRTY_BIT_STENCIL_OPS_FRONT:
   1062                mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
   1063                break;
   1064            case gl::State::DIRTY_BIT_STENCIL_OPS_BACK:
   1065                mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
   1066                break;
   1067 
   1068            case gl::State::DIRTY_BIT_CULL_FACE_ENABLED:
   1069                if (state.getRasterizerState().cullFace != mCurRasterState.cullFace)
   1070                {
   1071                    mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
   1072                    mInternalDirtyBits.set(DIRTY_BIT_PRIMITIVE_TOPOLOGY);
   1073                }
   1074                break;
   1075            case gl::State::DIRTY_BIT_CULL_FACE:
   1076                if (state.getRasterizerState().cullMode != mCurRasterState.cullMode)
   1077                {
   1078                    mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
   1079                    mInternalDirtyBits.set(DIRTY_BIT_PRIMITIVE_TOPOLOGY);
   1080                }
   1081                break;
   1082            case gl::State::DIRTY_BIT_FRONT_FACE:
   1083                if (state.getRasterizerState().frontFace != mCurRasterState.frontFace)
   1084                {
   1085                    mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
   1086                    mInternalDirtyBits.set(DIRTY_BIT_PRIMITIVE_TOPOLOGY);
   1087                }
   1088                break;
   1089            case gl::State::DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED:
   1090                if (state.getRasterizerState().polygonOffsetFill !=
   1091                    mCurRasterState.polygonOffsetFill)
   1092                {
   1093                    mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
   1094                }
   1095                break;
   1096            case gl::State::DIRTY_BIT_POLYGON_OFFSET:
   1097            {
   1098                const gl::RasterizerState &rasterState = state.getRasterizerState();
   1099                if (rasterState.polygonOffsetFactor != mCurRasterState.polygonOffsetFactor ||
   1100                    rasterState.polygonOffsetUnits != mCurRasterState.polygonOffsetUnits)
   1101                {
   1102                    mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
   1103                }
   1104                break;
   1105            }
   1106            case gl::State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED:
   1107                if (state.getRasterizerState().rasterizerDiscard !=
   1108                    mCurRasterState.rasterizerDiscard)
   1109                {
   1110                    mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
   1111 
   1112                    // Enabling/disabling rasterizer discard affects the pixel shader.
   1113                    invalidateShaders();
   1114                }
   1115                break;
   1116            case gl::State::DIRTY_BIT_SCISSOR:
   1117                if (state.getScissor() != mCurScissorRect)
   1118                {
   1119                    mInternalDirtyBits.set(DIRTY_BIT_SCISSOR_STATE);
   1120                }
   1121                break;
   1122            case gl::State::DIRTY_BIT_SCISSOR_TEST_ENABLED:
   1123                if (state.isScissorTestEnabled() != mCurScissorEnabled)
   1124                {
   1125                    mInternalDirtyBits.set(DIRTY_BIT_SCISSOR_STATE);
   1126                    // Rasterizer state update needs mCurScissorsEnabled and updates when it changes
   1127                    mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
   1128                }
   1129                break;
   1130            case gl::State::DIRTY_BIT_DEPTH_RANGE:
   1131                invalidateViewport(context);
   1132                break;
   1133            case gl::State::DIRTY_BIT_VIEWPORT:
   1134                if (state.getViewport() != mCurViewport)
   1135                {
   1136                    invalidateViewport(context);
   1137                }
   1138                break;
   1139            case gl::State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING:
   1140                invalidateRenderTarget();
   1141                if (mIsMultiviewEnabled)
   1142                {
   1143                    handleMultiviewDrawFramebufferChange(context);
   1144                }
   1145                mFramebuffer11 = GetImplAs<Framebuffer11>(state.getDrawFramebuffer());
   1146                break;
   1147            case gl::State::DIRTY_BIT_VERTEX_ARRAY_BINDING:
   1148                invalidateVertexBuffer();
   1149                // Force invalidate the current value attributes, since the VertexArray11 keeps an
   1150                // internal cache of TranslatedAttributes, and they CurrentValue attributes are
   1151                // owned by the StateManager11/Context.
   1152                mDirtyCurrentValueAttribs.set();
   1153                // Invalidate the cached index buffer.
   1154                invalidateIndexBuffer();
   1155                mVertexArray11 = GetImplAs<VertexArray11>(state.getVertexArray());
   1156                break;
   1157            case gl::State::DIRTY_BIT_UNIFORM_BUFFER_BINDINGS:
   1158                invalidateProgramUniformBuffers();
   1159                break;
   1160            case gl::State::DIRTY_BIT_ATOMIC_COUNTER_BUFFER_BINDING:
   1161                invalidateProgramAtomicCounterBuffers();
   1162                break;
   1163            case gl::State::DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING:
   1164                invalidateProgramShaderStorageBuffers();
   1165                break;
   1166            case gl::State::DIRTY_BIT_TEXTURE_BINDINGS:
   1167                invalidateTexturesAndSamplers();
   1168                break;
   1169            case gl::State::DIRTY_BIT_SAMPLER_BINDINGS:
   1170                invalidateTexturesAndSamplers();
   1171                break;
   1172            case gl::State::DIRTY_BIT_IMAGE_BINDINGS:
   1173                invalidateImageBindings();
   1174                break;
   1175            case gl::State::DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING:
   1176                invalidateTransformFeedback();
   1177                break;
   1178            case gl::State::DIRTY_BIT_PROGRAM_BINDING:
   1179                mProgramD3D = GetImplAs<ProgramD3D>(state.getProgram());
   1180                break;
   1181            case gl::State::DIRTY_BIT_PROGRAM_EXECUTABLE:
   1182            {
   1183                invalidateShaders();
   1184                invalidateTexturesAndSamplers();
   1185                invalidateProgramUniforms();
   1186                invalidateProgramUniformBuffers();
   1187                invalidateProgramAtomicCounterBuffers();
   1188                invalidateProgramShaderStorageBuffers();
   1189                invalidateDriverUniforms();
   1190                const gl::ProgramExecutable *executable = state.getProgramExecutable();
   1191                if (!executable || command != gl::Command::Dispatch)
   1192                {
   1193                    mInternalDirtyBits.set(DIRTY_BIT_PRIMITIVE_TOPOLOGY);
   1194                    invalidateVertexBuffer();
   1195                    invalidateRenderTarget();
   1196                    // If OVR_multiview2 is enabled, the attribute divisor has to be updated for
   1197                    // each binding. When using compute, there could be no vertex array.
   1198                    if (mIsMultiviewEnabled && mVertexArray11)
   1199                    {
   1200                        ASSERT(mProgramD3D);
   1201                        ASSERT(mVertexArray11 == GetImplAs<VertexArray11>(state.getVertexArray()));
   1202                        const gl::ProgramState &programState = mProgramD3D->getState();
   1203                        int numViews =
   1204                            programState.usesMultiview() ? programState.getNumViews() : 1;
   1205                        mVertexArray11->markAllAttributeDivisorsForAdjustment(numViews);
   1206                    }
   1207                }
   1208                break;
   1209            }
   1210            case gl::State::DIRTY_BIT_CURRENT_VALUES:
   1211            {
   1212                for (auto attribIndex : state.getAndResetDirtyCurrentValues())
   1213                {
   1214                    invalidateCurrentValueAttrib(attribIndex);
   1215                }
   1216                break;
   1217            }
   1218            case gl::State::DIRTY_BIT_PROVOKING_VERTEX:
   1219                invalidateShaders();
   1220                break;
   1221            case gl::State::DIRTY_BIT_EXTENDED:
   1222            {
   1223                gl::State::ExtendedDirtyBits extendedDirtyBits =
   1224                    state.getAndResetExtendedDirtyBits();
   1225 
   1226                for (size_t extendedDirtyBit : extendedDirtyBits)
   1227                {
   1228                    switch (extendedDirtyBit)
   1229                    {
   1230                        case gl::State::EXTENDED_DIRTY_BIT_CLIP_CONTROL:
   1231                            checkPresentPath(context);
   1232                            break;
   1233                    }
   1234                }
   1235                break;
   1236            }
   1237            default:
   1238                break;
   1239        }
   1240    }
   1241 
   1242    // TODO(jmadill): Input layout and vertex buffer state.
   1243 }
   1244 
   1245 void StateManager11::handleMultiviewDrawFramebufferChange(const gl::Context *context)
   1246 {
   1247    const auto &glState                    = context->getState();
   1248    const gl::Framebuffer *drawFramebuffer = glState.getDrawFramebuffer();
   1249    ASSERT(drawFramebuffer != nullptr);
   1250 
   1251    if (drawFramebuffer->isMultiview())
   1252    {
   1253        // Because the base view index is applied as an offset to the 2D texture array when the
   1254        // RTV is created, we just have to pass a boolean to select which code path is to be
   1255        // used.
   1256        mShaderConstants.setMultiviewWriteToViewportIndex(0.0f);
   1257    }
   1258 }
   1259 
   1260 angle::Result StateManager11::syncBlendState(const gl::Context *context,
   1261                                             const gl::BlendStateExt &blendStateExt,
   1262                                             const gl::ColorF &blendColor,
   1263                                             unsigned int sampleMask,
   1264                                             bool sampleAlphaToCoverage,
   1265                                             bool emulateConstantAlpha)
   1266 {
   1267    const d3d11::BlendState *dxBlendState = nullptr;
   1268    const d3d11::BlendStateKey &key       = RenderStateCache::GetBlendStateKey(
   1269              context, mFramebuffer11, blendStateExt, sampleAlphaToCoverage);
   1270 
   1271    ANGLE_TRY(mRenderer->getBlendState(context, key, &dxBlendState));
   1272 
   1273    ASSERT(dxBlendState != nullptr);
   1274 
   1275    // D3D11 does not support CONSTANT_ALPHA as source or destination color factor, so ANGLE sets
   1276    // the factor to CONSTANT_COLOR and swizzles the color value to aaaa. For this reason, it's
   1277    // impossible to simultaneously use CONSTANT_ALPHA and CONSTANT_COLOR as source or destination
   1278    // color factors in the same blend state. This is enforced in the validation layer.
   1279    float blendColors[4] = {0.0f};
   1280    blendColors[0]       = emulateConstantAlpha ? blendColor.alpha : blendColor.red;
   1281    blendColors[1]       = emulateConstantAlpha ? blendColor.alpha : blendColor.green;
   1282    blendColors[2]       = emulateConstantAlpha ? blendColor.alpha : blendColor.blue;
   1283    blendColors[3]       = blendColor.alpha;
   1284 
   1285    mRenderer->getDeviceContext()->OMSetBlendState(dxBlendState->get(), blendColors, sampleMask);
   1286 
   1287    mCurBlendStateExt         = blendStateExt;
   1288    mCurBlendColor            = blendColor;
   1289    mCurSampleMask            = sampleMask;
   1290    mCurSampleAlphaToCoverage = sampleAlphaToCoverage;
   1291 
   1292    return angle::Result::Continue;
   1293 }
   1294 
   1295 angle::Result StateManager11::syncDepthStencilState(const gl::Context *context)
   1296 {
   1297    const gl::State &glState = context->getState();
   1298 
   1299    mCurDepthStencilState = glState.getDepthStencilState();
   1300    mCurStencilRef        = glState.getStencilRef();
   1301    mCurStencilBackRef    = glState.getStencilBackRef();
   1302 
   1303    // get the maximum size of the stencil ref
   1304    unsigned int maxStencil = 0;
   1305    if (mCurDepthStencilState.stencilTest && mCurStencilSize > 0)
   1306    {
   1307        maxStencil = (1 << mCurStencilSize) - 1;
   1308    }
   1309    ASSERT((mCurDepthStencilState.stencilWritemask & maxStencil) ==
   1310           (mCurDepthStencilState.stencilBackWritemask & maxStencil));
   1311    ASSERT(gl::clamp(mCurStencilRef, 0, static_cast<int>(maxStencil)) ==
   1312           gl::clamp(mCurStencilBackRef, 0, static_cast<int>(maxStencil)));
   1313    ASSERT((mCurDepthStencilState.stencilMask & maxStencil) ==
   1314           (mCurDepthStencilState.stencilBackMask & maxStencil));
   1315 
   1316    gl::DepthStencilState modifiedGLState = glState.getDepthStencilState();
   1317 
   1318    ASSERT(mCurDisableDepth.valid() && mCurDisableStencil.valid());
   1319 
   1320    if (mCurDisableDepth.value())
   1321    {
   1322        modifiedGLState.depthTest = false;
   1323        modifiedGLState.depthMask = false;
   1324    }
   1325 
   1326    if (mCurDisableStencil.value())
   1327    {
   1328        modifiedGLState.stencilTest = false;
   1329    }
   1330    if (!modifiedGLState.stencilTest)
   1331    {
   1332        modifiedGLState.stencilWritemask     = 0;
   1333        modifiedGLState.stencilBackWritemask = 0;
   1334    }
   1335 
   1336    // If STENCIL_TEST is disabled in glState, stencil testing and writing should be disabled.
   1337    // Verify that's true in the modifiedGLState so it is propagated to d3dState.
   1338    ASSERT(glState.getDepthStencilState().stencilTest ||
   1339           (!modifiedGLState.stencilTest && modifiedGLState.stencilWritemask == 0 &&
   1340            modifiedGLState.stencilBackWritemask == 0));
   1341 
   1342    const d3d11::DepthStencilState *d3dState = nullptr;
   1343    ANGLE_TRY(mRenderer->getDepthStencilState(context, modifiedGLState, &d3dState));
   1344    ASSERT(d3dState);
   1345 
   1346    // Max D3D11 stencil reference value is 0xFF,
   1347    // corresponding to the max 8 bits in a stencil buffer
   1348    // GL specifies we should clamp the ref value to the
   1349    // nearest bit depth when doing stencil ops
   1350    static_assert(D3D11_DEFAULT_STENCIL_READ_MASK == 0xFF,
   1351                  "Unexpected value of D3D11_DEFAULT_STENCIL_READ_MASK");
   1352    static_assert(D3D11_DEFAULT_STENCIL_WRITE_MASK == 0xFF,
   1353                  "Unexpected value of D3D11_DEFAULT_STENCIL_WRITE_MASK");
   1354    UINT dxStencilRef = static_cast<UINT>(gl::clamp(mCurStencilRef, 0, 0xFF));
   1355 
   1356    mRenderer->getDeviceContext()->OMSetDepthStencilState(d3dState->get(), dxStencilRef);
   1357 
   1358    return angle::Result::Continue;
   1359 }
   1360 
   1361 angle::Result StateManager11::syncRasterizerState(const gl::Context *context,
   1362                                                  gl::PrimitiveMode mode)
   1363 {
   1364    // TODO: Remove pointDrawMode and multiSample from gl::RasterizerState.
   1365    gl::RasterizerState rasterState = context->getState().getRasterizerState();
   1366    rasterState.pointDrawMode       = (mode == gl::PrimitiveMode::Points);
   1367    rasterState.multiSample         = mCurRasterState.multiSample;
   1368 
   1369    ID3D11RasterizerState *dxRasterState = nullptr;
   1370 
   1371    if (mCurPresentPathFastEnabled)
   1372    {
   1373        gl::RasterizerState modifiedRasterState = rasterState;
   1374 
   1375        // If prseent path fast is active then we need invert the front face state.
   1376        // This ensures that both gl_FrontFacing is correct, and front/back culling
   1377        // is performed correctly.
   1378        if (modifiedRasterState.frontFace == GL_CCW)
   1379        {
   1380            modifiedRasterState.frontFace = GL_CW;
   1381        }
   1382        else
   1383        {
   1384            ASSERT(modifiedRasterState.frontFace == GL_CW);
   1385            modifiedRasterState.frontFace = GL_CCW;
   1386        }
   1387 
   1388        ANGLE_TRY(mRenderer->getRasterizerState(context, modifiedRasterState, mCurScissorEnabled,
   1389                                                &dxRasterState));
   1390    }
   1391    else
   1392    {
   1393        ANGLE_TRY(mRenderer->getRasterizerState(context, rasterState, mCurScissorEnabled,
   1394                                                &dxRasterState));
   1395    }
   1396 
   1397    mRenderer->getDeviceContext()->RSSetState(dxRasterState);
   1398 
   1399    mCurRasterState = rasterState;
   1400 
   1401    return angle::Result::Continue;
   1402 }
   1403 
   1404 void StateManager11::syncScissorRectangle(const gl::Context *context)
   1405 {
   1406    const auto &glState          = context->getState();
   1407    gl::Framebuffer *framebuffer = glState.getDrawFramebuffer();
   1408    const gl::Rectangle &scissor = glState.getScissor();
   1409    const bool enabled           = glState.isScissorTestEnabled();
   1410 
   1411    mCurScissorOffset = framebuffer->getSurfaceTextureOffset();
   1412 
   1413    int scissorX = scissor.x + mCurScissorOffset.x;
   1414    int scissorY = scissor.y + mCurScissorOffset.y;
   1415 
   1416    if (mCurPresentPathFastEnabled)
   1417    {
   1418        scissorY = mCurPresentPathFastColorBufferHeight - scissor.height - scissor.y;
   1419    }
   1420 
   1421    if (enabled)
   1422    {
   1423        D3D11_RECT rect;
   1424        int x       = scissorX;
   1425        int y       = scissorY;
   1426        rect.left   = std::max(0, x);
   1427        rect.top    = std::max(0, y);
   1428        rect.right  = x + std::max(0, scissor.width);
   1429        rect.bottom = y + std::max(0, scissor.height);
   1430        mRenderer->getDeviceContext()->RSSetScissorRects(1, &rect);
   1431    }
   1432 
   1433    mCurScissorRect    = scissor;
   1434    mCurScissorEnabled = enabled;
   1435 }
   1436 
   1437 void StateManager11::syncViewport(const gl::Context *context)
   1438 {
   1439    const auto &glState          = context->getState();
   1440    gl::Framebuffer *framebuffer = glState.getDrawFramebuffer();
   1441    float actualZNear            = gl::clamp01(glState.getNearPlane());
   1442    float actualZFar             = gl::clamp01(glState.getFarPlane());
   1443 
   1444    const auto &caps         = context->getCaps();
   1445    int dxMaxViewportBoundsX = caps.maxViewportWidth;
   1446    int dxMaxViewportBoundsY = caps.maxViewportHeight;
   1447    int dxMinViewportBoundsX = -dxMaxViewportBoundsX;
   1448    int dxMinViewportBoundsY = -dxMaxViewportBoundsY;
   1449 
   1450    bool is9_3 = mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3;
   1451 
   1452    if (is9_3)
   1453    {
   1454        // Feature Level 9 viewports shouldn't exceed the dimensions of the rendertarget.
   1455        dxMaxViewportBoundsX = static_cast<int>(mViewportBounds.width);
   1456        dxMaxViewportBoundsY = static_cast<int>(mViewportBounds.height);
   1457        dxMinViewportBoundsX = 0;
   1458        dxMinViewportBoundsY = 0;
   1459    }
   1460 
   1461    bool clipSpaceOriginLowerLeft = glState.getClipSpaceOrigin() == gl::ClipSpaceOrigin::LowerLeft;
   1462    mShaderConstants.onClipControlChange(clipSpaceOriginLowerLeft,
   1463                                         glState.isClipControlDepthZeroToOne());
   1464 
   1465    const auto &viewport = glState.getViewport();
   1466 
   1467    int dxViewportTopLeftX = 0;
   1468    int dxViewportTopLeftY = 0;
   1469    int dxViewportWidth    = 0;
   1470    int dxViewportHeight   = 0;
   1471 
   1472    mCurViewportOffset = framebuffer->getSurfaceTextureOffset();
   1473 
   1474    dxViewportTopLeftX =
   1475        gl::clamp(viewport.x + mCurViewportOffset.x, dxMinViewportBoundsX, dxMaxViewportBoundsX);
   1476    dxViewportTopLeftY =
   1477        gl::clamp(viewport.y + mCurViewportOffset.y, dxMinViewportBoundsY, dxMaxViewportBoundsY);
   1478    dxViewportWidth  = gl::clamp(viewport.width, 0, dxMaxViewportBoundsX - dxViewportTopLeftX);
   1479    dxViewportHeight = gl::clamp(viewport.height, 0, dxMaxViewportBoundsY - dxViewportTopLeftY);
   1480 
   1481    D3D11_VIEWPORT dxViewport;
   1482    dxViewport.TopLeftX = static_cast<float>(dxViewportTopLeftX);
   1483    if (mCurPresentPathFastEnabled && clipSpaceOriginLowerLeft)
   1484    {
   1485        // When present path fast is active and we're rendering to framebuffer 0, we must invert
   1486        // the viewport in Y-axis.
   1487        // NOTE: We delay the inversion until right before the call to RSSetViewports, and leave
   1488        // dxViewportTopLeftY unchanged. This allows us to calculate viewAdjust below using the
   1489        // unaltered dxViewportTopLeftY value.
   1490        dxViewport.TopLeftY = static_cast<float>(mCurPresentPathFastColorBufferHeight -
   1491                                                 dxViewportTopLeftY - dxViewportHeight);
   1492    }
   1493    else
   1494    {
   1495        dxViewport.TopLeftY = static_cast<float>(dxViewportTopLeftY);
   1496    }
   1497 
   1498    // The es 3.1 spec section 9.2 states that, "If there are no attachments, rendering
   1499    // will be limited to a rectangle having a lower left of (0, 0) and an upper right of
   1500    // (width, height), where width and height are the framebuffer object's default width
   1501    // and height." See http://anglebug.com/1594
   1502    // If the Framebuffer has no color attachment and the default width or height is smaller
   1503    // than the current viewport, use the smaller of the two sizes.
   1504    // If framebuffer default width or height is 0, the params should not set.
   1505    if (!framebuffer->getFirstNonNullAttachment() &&
   1506        (framebuffer->getDefaultWidth() || framebuffer->getDefaultHeight()))
   1507    {
   1508        dxViewport.Width =
   1509            static_cast<GLfloat>(std::min(viewport.width, framebuffer->getDefaultWidth()));
   1510        dxViewport.Height =
   1511            static_cast<GLfloat>(std::min(viewport.height, framebuffer->getDefaultHeight()));
   1512    }
   1513    else
   1514    {
   1515        dxViewport.Width  = static_cast<float>(dxViewportWidth);
   1516        dxViewport.Height = static_cast<float>(dxViewportHeight);
   1517    }
   1518    dxViewport.MinDepth = actualZNear;
   1519    dxViewport.MaxDepth = actualZFar;
   1520 
   1521    mRenderer->getDeviceContext()->RSSetViewports(1, &dxViewport);
   1522 
   1523    mCurViewport = viewport;
   1524    mCurNear     = actualZNear;
   1525    mCurFar      = actualZFar;
   1526 
   1527    const D3D11_VIEWPORT adjustViewport = {static_cast<FLOAT>(dxViewportTopLeftX),
   1528                                           static_cast<FLOAT>(dxViewportTopLeftY),
   1529                                           static_cast<FLOAT>(dxViewportWidth),
   1530                                           static_cast<FLOAT>(dxViewportHeight),
   1531                                           actualZNear,
   1532                                           actualZFar};
   1533    mShaderConstants.onViewportChange(viewport, adjustViewport, mCurViewportOffset, is9_3,
   1534                                      mCurPresentPathFastEnabled);
   1535 }
   1536 
   1537 void StateManager11::invalidateRenderTarget()
   1538 {
   1539    mRenderTargetIsDirty = true;
   1540 }
   1541 
   1542 void StateManager11::processFramebufferInvalidation(const gl::Context *context)
   1543 {
   1544    ASSERT(mRenderTargetIsDirty);
   1545    ASSERT(context);
   1546 
   1547    mInternalDirtyBits.set(DIRTY_BIT_RENDER_TARGET);
   1548 
   1549    // The pixel shader is dependent on the output layout.
   1550    invalidateShaders();
   1551 
   1552    // The D3D11 blend state is heavily dependent on the current render target.
   1553    mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
   1554 
   1555    gl::Framebuffer *fbo = context->getState().getDrawFramebuffer();
   1556    ASSERT(fbo);
   1557 
   1558    // Dirty scissor and viewport because surface texture offset might have changed.
   1559    if (mCurViewportOffset != fbo->getSurfaceTextureOffset())
   1560    {
   1561        mInternalDirtyBits.set(DIRTY_BIT_VIEWPORT_STATE);
   1562    }
   1563    if (mCurScissorOffset != fbo->getSurfaceTextureOffset())
   1564    {
   1565        mInternalDirtyBits.set(DIRTY_BIT_SCISSOR_STATE);
   1566    }
   1567 
   1568    // Disable the depth test/depth write if we are using a stencil-only attachment.
   1569    // This is because ANGLE emulates stencil-only with D24S8 on D3D11 - we should neither read
   1570    // nor write to the unused depth part of this emulated texture.
   1571    bool disableDepth = (!fbo->hasDepth() && fbo->hasStencil());
   1572 
   1573    // Similarly we disable the stencil portion of the DS attachment if the app only binds depth.
   1574    bool disableStencil = (fbo->hasDepth() && !fbo->hasStencil());
   1575 
   1576    if (!mCurDisableDepth.valid() || disableDepth != mCurDisableDepth.value() ||
   1577        !mCurDisableStencil.valid() || disableStencil != mCurDisableStencil.value())
   1578    {
   1579        mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
   1580        mCurDisableDepth   = disableDepth;
   1581        mCurDisableStencil = disableStencil;
   1582    }
   1583 
   1584    bool multiSample = (fbo->getSamples(context) != 0);
   1585    if (multiSample != mCurRasterState.multiSample)
   1586    {
   1587        mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
   1588        mCurRasterState.multiSample = multiSample;
   1589    }
   1590 
   1591    checkPresentPath(context);
   1592 
   1593    if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3)
   1594    {
   1595        const auto *firstAttachment = fbo->getFirstNonNullAttachment();
   1596        if (firstAttachment)
   1597        {
   1598            const auto &size = firstAttachment->getSize();
   1599            if (mViewportBounds.width != size.width || mViewportBounds.height != size.height)
   1600            {
   1601                mViewportBounds = gl::Extents(size.width, size.height, 1);
   1602                invalidateViewport(context);
   1603            }
   1604        }
   1605    }
   1606 }
   1607 
   1608 void StateManager11::invalidateBoundViews()
   1609 {
   1610    for (SRVCache &curShaderSRV : mCurShaderSRVs)
   1611    {
   1612        curShaderSRV.clear();
   1613    }
   1614 
   1615    invalidateRenderTarget();
   1616 }
   1617 
   1618 void StateManager11::invalidateVertexBuffer()
   1619 {
   1620    unsigned int limit      = std::min<unsigned int>(mRenderer->getNativeCaps().maxVertexAttributes,
   1621                                                gl::MAX_VERTEX_ATTRIBS);
   1622    mDirtyVertexBufferRange = gl::RangeUI(0, limit);
   1623    invalidateInputLayout();
   1624    invalidateShaders();
   1625    mInternalDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_ATTRIBS);
   1626 }
   1627 
   1628 void StateManager11::invalidateViewport(const gl::Context *context)
   1629 {
   1630    mInternalDirtyBits.set(DIRTY_BIT_VIEWPORT_STATE);
   1631 
   1632    // Viewport affects the driver constants.
   1633    invalidateDriverUniforms();
   1634 }
   1635 
   1636 void StateManager11::invalidateTexturesAndSamplers()
   1637 {
   1638    mInternalDirtyBits.set(DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE);
   1639    invalidateSwizzles();
   1640 
   1641    // Texture state affects the driver uniforms (base level, etc).
   1642    invalidateDriverUniforms();
   1643 }
   1644 
   1645 void StateManager11::invalidateSwizzles()
   1646 {
   1647    mDirtySwizzles = true;
   1648 }
   1649 
   1650 void StateManager11::invalidateProgramUniforms()
   1651 {
   1652    mInternalDirtyBits.set(DIRTY_BIT_PROGRAM_UNIFORMS);
   1653 }
   1654 
   1655 void StateManager11::invalidateDriverUniforms()
   1656 {
   1657    mInternalDirtyBits.set(DIRTY_BIT_DRIVER_UNIFORMS);
   1658 }
   1659 
   1660 void StateManager11::invalidateProgramUniformBuffers()
   1661 {
   1662    mInternalDirtyBits.set(DIRTY_BIT_PROGRAM_UNIFORM_BUFFERS);
   1663 }
   1664 
   1665 void StateManager11::invalidateProgramAtomicCounterBuffers()
   1666 {
   1667    mInternalDirtyBits.set(DIRTY_BIT_GRAPHICS_UAV_STATE);
   1668    mInternalDirtyBits.set(DIRTY_BIT_COMPUTE_UAV_STATE);
   1669 }
   1670 
   1671 void StateManager11::invalidateProgramShaderStorageBuffers()
   1672 {
   1673    mInternalDirtyBits.set(DIRTY_BIT_GRAPHICS_UAV_STATE);
   1674    mInternalDirtyBits.set(DIRTY_BIT_COMPUTE_UAV_STATE);
   1675 }
   1676 
   1677 void StateManager11::invalidateImageBindings()
   1678 {
   1679    mInternalDirtyBits.set(DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE);
   1680    mInternalDirtyBits.set(DIRTY_BIT_GRAPHICS_SRV_STATE);
   1681    mInternalDirtyBits.set(DIRTY_BIT_GRAPHICS_UAV_STATE);
   1682    mInternalDirtyBits.set(DIRTY_BIT_COMPUTE_SRV_STATE);
   1683    mInternalDirtyBits.set(DIRTY_BIT_COMPUTE_UAV_STATE);
   1684 }
   1685 
   1686 void StateManager11::invalidateConstantBuffer(unsigned int slot)
   1687 {
   1688    if (slot == d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DRIVER)
   1689    {
   1690        invalidateDriverUniforms();
   1691    }
   1692    else if (slot == d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DEFAULT_UNIFORM_BLOCK)
   1693    {
   1694        invalidateProgramUniforms();
   1695    }
   1696    else
   1697    {
   1698        invalidateProgramUniformBuffers();
   1699    }
   1700 }
   1701 
   1702 void StateManager11::invalidateShaders()
   1703 {
   1704    mInternalDirtyBits.set(DIRTY_BIT_SHADERS);
   1705 }
   1706 
   1707 void StateManager11::invalidateTransformFeedback()
   1708 {
   1709    // Transform feedback affects the stream-out geometry shader.
   1710    invalidateShaders();
   1711    mInternalDirtyBits.set(DIRTY_BIT_TRANSFORM_FEEDBACK);
   1712    // syncPrimitiveTopology checks the transform feedback state.
   1713    mInternalDirtyBits.set(DIRTY_BIT_PRIMITIVE_TOPOLOGY);
   1714 }
   1715 
   1716 void StateManager11::invalidateInputLayout()
   1717 {
   1718    mInternalDirtyBits.set(DIRTY_BIT_VERTEX_BUFFERS_AND_INPUT_LAYOUT);
   1719 }
   1720 
   1721 void StateManager11::invalidateIndexBuffer()
   1722 {
   1723    mIndexBufferIsDirty = true;
   1724 }
   1725 
   1726 void StateManager11::setRenderTarget(ID3D11RenderTargetView *rtv, ID3D11DepthStencilView *dsv)
   1727 {
   1728    if (rtv)
   1729    {
   1730        unsetConflictingView(gl::PipelineType::GraphicsPipeline, rtv, true);
   1731    }
   1732 
   1733    if (dsv)
   1734    {
   1735        unsetConflictingView(gl::PipelineType::GraphicsPipeline, dsv, true);
   1736    }
   1737 
   1738    mRenderer->getDeviceContext()->OMSetRenderTargets(1, &rtv, dsv);
   1739    mCurRTVs.clear();
   1740    mCurRTVs.update(0, rtv);
   1741    mInternalDirtyBits.set(DIRTY_BIT_RENDER_TARGET);
   1742 }
   1743 
   1744 void StateManager11::setRenderTargets(ID3D11RenderTargetView **rtvs,
   1745                                      UINT numRTVs,
   1746                                      ID3D11DepthStencilView *dsv)
   1747 {
   1748    for (UINT rtvIndex = 0; rtvIndex < numRTVs; ++rtvIndex)
   1749    {
   1750        unsetConflictingView(gl::PipelineType::GraphicsPipeline, rtvs[rtvIndex], true);
   1751    }
   1752 
   1753    if (dsv)
   1754    {
   1755        unsetConflictingView(gl::PipelineType::GraphicsPipeline, dsv, true);
   1756    }
   1757 
   1758    mRenderer->getDeviceContext()->OMSetRenderTargets(numRTVs, (numRTVs > 0) ? rtvs : nullptr, dsv);
   1759    mCurRTVs.clear();
   1760    for (UINT i = 0; i < numRTVs; i++)
   1761    {
   1762        mCurRTVs.update(i, rtvs[i]);
   1763    }
   1764    mInternalDirtyBits.set(DIRTY_BIT_RENDER_TARGET);
   1765 }
   1766 
   1767 void StateManager11::onBeginQuery(Query11 *query)
   1768 {
   1769    mCurrentQueries.insert(query);
   1770 }
   1771 
   1772 void StateManager11::onDeleteQueryObject(Query11 *query)
   1773 {
   1774    mCurrentQueries.erase(query);
   1775 }
   1776 
   1777 angle::Result StateManager11::onMakeCurrent(const gl::Context *context)
   1778 {
   1779    ANGLE_TRY(ensureInitialized(context));
   1780 
   1781    const gl::State &state = context->getState();
   1782 
   1783    Context11 *context11 = GetImplAs<Context11>(context);
   1784 
   1785    for (Query11 *query : mCurrentQueries)
   1786    {
   1787        ANGLE_TRY(query->pause(context11));
   1788    }
   1789    mCurrentQueries.clear();
   1790 
   1791    for (gl::QueryType type : angle::AllEnums<gl::QueryType>())
   1792    {
   1793        gl::Query *query = state.getActiveQuery(type);
   1794        if (query != nullptr)
   1795        {
   1796            Query11 *query11 = GetImplAs<Query11>(query);
   1797            ANGLE_TRY(query11->resume(context11));
   1798            mCurrentQueries.insert(query11);
   1799        }
   1800    }
   1801 
   1802    // Reset the cache objects.
   1803    mProgramD3D    = nullptr;
   1804    mVertexArray11 = nullptr;
   1805    mFramebuffer11 = nullptr;
   1806 
   1807    return angle::Result::Continue;
   1808 }
   1809 
   1810 void StateManager11::unsetConflictingView(gl::PipelineType pipeline,
   1811                                          ID3D11View *view,
   1812                                          bool isRenderTarget)
   1813 {
   1814    uintptr_t resource = reinterpret_cast<uintptr_t>(GetViewResource(view));
   1815 
   1816    unsetConflictingSRVs(pipeline, gl::ShaderType::Vertex, resource, nullptr, isRenderTarget);
   1817    unsetConflictingSRVs(pipeline, gl::ShaderType::Fragment, resource, nullptr, isRenderTarget);
   1818    unsetConflictingSRVs(pipeline, gl::ShaderType::Compute, resource, nullptr, isRenderTarget);
   1819    unsetConflictingUAVs(pipeline, gl::ShaderType::Compute, resource, nullptr);
   1820 }
   1821 
   1822 void StateManager11::unsetConflictingSRVs(gl::PipelineType pipeline,
   1823                                          gl::ShaderType shaderType,
   1824                                          uintptr_t resource,
   1825                                          const gl::ImageIndex *index,
   1826                                          bool isRenderTarget)
   1827 {
   1828    auto *currentSRVs                 = getSRVCache(shaderType);
   1829    gl::PipelineType conflictPipeline = gl::GetPipelineType(shaderType);
   1830    bool foundOne                     = false;
   1831    size_t count                      = std::min(currentSRVs->size(), currentSRVs->highestUsed());
   1832    for (size_t resourceIndex = 0; resourceIndex < count; ++resourceIndex)
   1833    {
   1834        auto &record = (*currentSRVs)[resourceIndex];
   1835 
   1836        if (record.view && record.resource == resource &&
   1837            (!index || ImageIndexConflictsWithSRV(*index, record.desc)))
   1838        {
   1839            setShaderResourceInternal<d3d11::ShaderResourceView>(
   1840                shaderType, static_cast<UINT>(resourceIndex), nullptr);
   1841            foundOne = true;
   1842        }
   1843    }
   1844 
   1845    if (foundOne && (pipeline != conflictPipeline || isRenderTarget))
   1846    {
   1847        switch (conflictPipeline)
   1848        {
   1849            case gl::PipelineType::GraphicsPipeline:
   1850                mInternalDirtyBits.set(DIRTY_BIT_GRAPHICS_SRV_STATE);
   1851                break;
   1852            case gl::PipelineType::ComputePipeline:
   1853                mInternalDirtyBits.set(DIRTY_BIT_COMPUTE_SRV_STATE);
   1854                break;
   1855            default:
   1856                UNREACHABLE();
   1857        }
   1858    }
   1859 }
   1860 
   1861 void StateManager11::unsetConflictingUAVs(gl::PipelineType pipeline,
   1862                                          gl::ShaderType shaderType,
   1863                                          uintptr_t resource,
   1864                                          const gl::ImageIndex *index)
   1865 {
   1866    ASSERT(shaderType == gl::ShaderType::Compute);
   1867    bool foundOne = false;
   1868 
   1869    ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
   1870    size_t count = std::min(mCurComputeUAVs.size(), mCurComputeUAVs.highestUsed());
   1871    for (size_t resourceIndex = 0; resourceIndex < count; ++resourceIndex)
   1872    {
   1873        auto &record = mCurComputeUAVs[resourceIndex];
   1874 
   1875        if (record.view && record.resource == resource &&
   1876            (!index || ImageIndexConflictsWithUAV(*index, record.desc)))
   1877        {
   1878            deviceContext->CSSetUnorderedAccessViews(static_cast<UINT>(resourceIndex), 1,
   1879                                                     &mNullUAVs[0], nullptr);
   1880            mCurComputeUAVs.update(resourceIndex, nullptr);
   1881            foundOne = true;
   1882        }
   1883    }
   1884 
   1885    if (foundOne && pipeline == gl::PipelineType::GraphicsPipeline)
   1886    {
   1887        mInternalDirtyBits.set(DIRTY_BIT_COMPUTE_UAV_STATE);
   1888    }
   1889 }
   1890 
   1891 void StateManager11::unsetConflictingRTVs(uintptr_t resource)
   1892 {
   1893    ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
   1894    size_t count                       = std::min(mCurRTVs.size(), mCurRTVs.highestUsed());
   1895    for (size_t resourceIndex = 0; resourceIndex < count; ++resourceIndex)
   1896    {
   1897        auto &record = mCurRTVs[resourceIndex];
   1898 
   1899        if (record.view && record.resource == resource)
   1900        {
   1901            deviceContext->OMSetRenderTargets(0, nullptr, nullptr);
   1902            mCurRTVs.clear();
   1903            mInternalDirtyBits.set(DIRTY_BIT_RENDER_TARGET);
   1904            return;
   1905        }
   1906    }
   1907 }
   1908 
   1909 void StateManager11::unsetConflictingAttachmentResources(
   1910    const gl::FramebufferAttachment &attachment,
   1911    ID3D11Resource *resource)
   1912 {
   1913    // Unbind render target SRVs from the shader here to prevent D3D11 warnings.
   1914    if (attachment.type() == GL_TEXTURE)
   1915    {
   1916        uintptr_t resourcePtr       = reinterpret_cast<uintptr_t>(resource);
   1917        const gl::ImageIndex &index = attachment.getTextureImageIndex();
   1918        // The index doesn't need to be corrected for the small compressed texture workaround
   1919        // because a rendertarget is never compressed.
   1920        unsetConflictingSRVs(gl::PipelineType::GraphicsPipeline, gl::ShaderType::Vertex,
   1921                             resourcePtr, &index, false);
   1922        unsetConflictingSRVs(gl::PipelineType::GraphicsPipeline, gl::ShaderType::Fragment,
   1923                             resourcePtr, &index, false);
   1924        unsetConflictingSRVs(gl::PipelineType::GraphicsPipeline, gl::ShaderType::Compute,
   1925                             resourcePtr, &index, false);
   1926        unsetConflictingUAVs(gl::PipelineType::GraphicsPipeline, gl::ShaderType::Compute,
   1927                             resourcePtr, &index);
   1928    }
   1929    else if (attachment.type() == GL_FRAMEBUFFER_DEFAULT)
   1930    {
   1931        uintptr_t resourcePtr = reinterpret_cast<uintptr_t>(resource);
   1932        unsetConflictingSRVs(gl::PipelineType::GraphicsPipeline, gl::ShaderType::Vertex,
   1933                             resourcePtr, nullptr, false);
   1934        unsetConflictingSRVs(gl::PipelineType::GraphicsPipeline, gl::ShaderType::Fragment,
   1935                             resourcePtr, nullptr, false);
   1936        unsetConflictingSRVs(gl::PipelineType::GraphicsPipeline, gl::ShaderType::Compute,
   1937                             resourcePtr, nullptr, false);
   1938        unsetConflictingUAVs(gl::PipelineType::GraphicsPipeline, gl::ShaderType::Compute,
   1939                             resourcePtr, nullptr);
   1940    }
   1941 }
   1942 
   1943 angle::Result StateManager11::ensureInitialized(const gl::Context *context)
   1944 {
   1945    Renderer11 *renderer = GetImplAs<Context11>(context)->getRenderer();
   1946 
   1947    const gl::Caps &caps             = renderer->getNativeCaps();
   1948    const gl::Extensions &extensions = renderer->getNativeExtensions();
   1949 
   1950    for (gl::ShaderType shaderType : gl::AllShaderTypes())
   1951    {
   1952        const GLuint maxShaderTextureImageUnits =
   1953            static_cast<GLuint>(caps.maxShaderTextureImageUnits[shaderType]);
   1954 
   1955        mCurShaderSRVs[shaderType].initialize(maxShaderTextureImageUnits);
   1956        mForceSetShaderSamplerStates[shaderType].resize(maxShaderTextureImageUnits, true);
   1957        mCurShaderSamplerStates[shaderType].resize(maxShaderTextureImageUnits);
   1958    }
   1959    mCurRTVs.initialize(caps.maxColorAttachments);
   1960    mCurComputeUAVs.initialize(caps.maxImageUnits);
   1961 
   1962    // Initialize cached NULL SRV block
   1963    mNullSRVs.resize(caps.maxShaderTextureImageUnits[gl::ShaderType::Fragment], nullptr);
   1964 
   1965    mNullUAVs.resize(caps.maxImageUnits, nullptr);
   1966 
   1967    mCurrentValueAttribs.resize(caps.maxVertexAttributes);
   1968 
   1969    mShaderConstants.init(caps);
   1970 
   1971    mIsMultiviewEnabled = extensions.multiviewOVR || extensions.multiview2OVR;
   1972 
   1973    mIndependentBlendStates = extensions.drawBuffersIndexedAny();  // requires FL10_1
   1974 
   1975    // FL9_3 is limited to 4; ES3.1 context on FL11_0 is limited to 7
   1976    mCurBlendStateExt =
   1977        gl::BlendStateExt(GetImplAs<Context11>(context)->getNativeCaps().maxDrawBuffers);
   1978 
   1979    ANGLE_TRY(mVertexDataManager.initialize(context));
   1980 
   1981    mCurrentAttributes.reserve(gl::MAX_VERTEX_ATTRIBS);
   1982 
   1983    return angle::Result::Continue;
   1984 }
   1985 
   1986 void StateManager11::deinitialize()
   1987 {
   1988    mCurrentValueAttribs.clear();
   1989    mInputLayoutCache.clear();
   1990    mVertexDataManager.deinitialize();
   1991    mIndexDataManager.deinitialize();
   1992 
   1993    for (d3d11::Buffer &ShaderDriverConstantBuffer : mShaderDriverConstantBuffers)
   1994    {
   1995        ShaderDriverConstantBuffer.reset();
   1996    }
   1997 
   1998    mPointSpriteVertexBuffer.reset();
   1999    mPointSpriteIndexBuffer.reset();
   2000 }
   2001 
   2002 // Applies the render target surface, depth stencil surface, viewport rectangle and
   2003 // scissor rectangle to the renderer
   2004 angle::Result StateManager11::syncFramebuffer(const gl::Context *context)
   2005 {
   2006    // Check for zero-sized default framebuffer, which is a special case.
   2007    // in this case we do not wish to modify any state and just silently return false.
   2008    // this will not report any gl error but will cause the calling method to return.
   2009    if (mFramebuffer11->getState().isDefault())
   2010    {
   2011        RenderTarget11 *firstRT = mFramebuffer11->getFirstRenderTarget();
   2012        const gl::Extents &size = firstRT->getExtents();
   2013        if (size.empty())
   2014        {
   2015            return angle::Result::Continue;
   2016        }
   2017    }
   2018 
   2019    RTVArray framebufferRTVs = {{}};
   2020    const auto &colorRTs     = mFramebuffer11->getCachedColorRenderTargets();
   2021 
   2022    size_t appliedRTIndex  = 0;
   2023    bool skipInactiveRTs   = mRenderer->getFeatures().mrtPerfWorkaround.enabled;
   2024    const auto &drawStates = mFramebuffer11->getState().getDrawBufferStates();
   2025    gl::DrawBufferMask activeProgramOutputs =
   2026        mProgramD3D->getState().getExecutable().getActiveOutputVariablesMask();
   2027    UINT maxExistingRT           = 0;
   2028    const auto &colorAttachments = mFramebuffer11->getState().getColorAttachments();
   2029 
   2030    for (size_t rtIndex = 0; rtIndex < colorRTs.size(); ++rtIndex)
   2031    {
   2032        const RenderTarget11 *renderTarget = colorRTs[rtIndex];
   2033 
   2034        // Skip inactive rendertargets if the workaround is enabled.
   2035        if (skipInactiveRTs &&
   2036            (!renderTarget || drawStates[rtIndex] == GL_NONE || !activeProgramOutputs[rtIndex]))
   2037        {
   2038            continue;
   2039        }
   2040 
   2041        if (renderTarget)
   2042        {
   2043            framebufferRTVs[appliedRTIndex] = renderTarget->getRenderTargetView().get();
   2044            ASSERT(framebufferRTVs[appliedRTIndex]);
   2045            maxExistingRT = static_cast<UINT>(appliedRTIndex) + 1;
   2046 
   2047            // Unset conflicting texture SRVs
   2048            const gl::FramebufferAttachment &attachment = colorAttachments[rtIndex];
   2049            ASSERT(attachment.isAttached());
   2050            unsetConflictingAttachmentResources(attachment, renderTarget->getTexture().get());
   2051        }
   2052 
   2053        appliedRTIndex++;
   2054    }
   2055 
   2056    // Get the depth stencil buffers
   2057    ID3D11DepthStencilView *framebufferDSV = nullptr;
   2058    const auto *depthStencilRenderTarget   = mFramebuffer11->getCachedDepthStencilRenderTarget();
   2059    if (depthStencilRenderTarget)
   2060    {
   2061        framebufferDSV = depthStencilRenderTarget->getDepthStencilView().get();
   2062        ASSERT(framebufferDSV);
   2063 
   2064        // Unset conflicting texture SRVs
   2065        const gl::FramebufferAttachment *attachment =
   2066            mFramebuffer11->getState().getDepthOrStencilAttachment();
   2067        ASSERT(attachment);
   2068        unsetConflictingAttachmentResources(*attachment,
   2069                                            depthStencilRenderTarget->getTexture().get());
   2070    }
   2071 
   2072    ASSERT(maxExistingRT <= static_cast<UINT>(context->getCaps().maxDrawBuffers));
   2073 
   2074    // Apply the render target and depth stencil
   2075    mRenderer->getDeviceContext()->OMSetRenderTargets(maxExistingRT, framebufferRTVs.data(),
   2076                                                      framebufferDSV);
   2077    mCurRTVs.clear();
   2078    for (UINT i = 0; i < maxExistingRT; i++)
   2079    {
   2080        mCurRTVs.update(i, framebufferRTVs[i]);
   2081    }
   2082    return angle::Result::Continue;
   2083 }
   2084 
   2085 void StateManager11::invalidateCurrentValueAttrib(size_t attribIndex)
   2086 {
   2087    mDirtyCurrentValueAttribs.set(attribIndex);
   2088    mInternalDirtyBits.set(DIRTY_BIT_CURRENT_VALUE_ATTRIBS);
   2089    invalidateInputLayout();
   2090    invalidateShaders();
   2091 }
   2092 
   2093 angle::Result StateManager11::syncCurrentValueAttribs(
   2094    const gl::Context *context,
   2095    const std::vector<gl::VertexAttribCurrentValueData> &currentValues)
   2096 {
   2097    const gl::ProgramExecutable &executable = mProgramD3D->getState().getExecutable();
   2098    const auto &activeAttribsMask           = executable.getActiveAttribLocationsMask();
   2099    const auto &dirtyActiveAttribs          = (activeAttribsMask & mDirtyCurrentValueAttribs);
   2100 
   2101    if (!dirtyActiveAttribs.any())
   2102    {
   2103        return angle::Result::Continue;
   2104    }
   2105 
   2106    const auto &vertexAttributes = mVertexArray11->getState().getVertexAttributes();
   2107    const auto &vertexBindings   = mVertexArray11->getState().getVertexBindings();
   2108    mDirtyCurrentValueAttribs    = (mDirtyCurrentValueAttribs & ~dirtyActiveAttribs);
   2109 
   2110    for (auto attribIndex : dirtyActiveAttribs)
   2111    {
   2112        if (vertexAttributes[attribIndex].enabled)
   2113            continue;
   2114 
   2115        const auto *attrib                      = &vertexAttributes[attribIndex];
   2116        const auto &currentValue                = currentValues[attribIndex];
   2117        TranslatedAttribute *currentValueAttrib = &mCurrentValueAttribs[attribIndex];
   2118        currentValueAttrib->currentValueType    = currentValue.Type;
   2119        currentValueAttrib->attribute           = attrib;
   2120        currentValueAttrib->binding             = &vertexBindings[attrib->bindingIndex];
   2121 
   2122        mDirtyVertexBufferRange.extend(static_cast<unsigned int>(attribIndex));
   2123 
   2124        ANGLE_TRY(mVertexDataManager.storeCurrentValue(context, currentValue, currentValueAttrib,
   2125                                                       static_cast<size_t>(attribIndex)));
   2126    }
   2127 
   2128    return angle::Result::Continue;
   2129 }
   2130 
   2131 void StateManager11::setInputLayout(const d3d11::InputLayout *inputLayout)
   2132 {
   2133    if (setInputLayoutInternal(inputLayout))
   2134    {
   2135        invalidateInputLayout();
   2136    }
   2137 }
   2138 
   2139 bool StateManager11::setInputLayoutInternal(const d3d11::InputLayout *inputLayout)
   2140 {
   2141    ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
   2142    if (inputLayout == nullptr)
   2143    {
   2144        if (!mCurrentInputLayout.empty())
   2145        {
   2146            deviceContext->IASetInputLayout(nullptr);
   2147            mCurrentInputLayout.clear();
   2148            return true;
   2149        }
   2150    }
   2151    else if (inputLayout->getSerial() != mCurrentInputLayout)
   2152    {
   2153        deviceContext->IASetInputLayout(inputLayout->get());
   2154        mCurrentInputLayout = inputLayout->getSerial();
   2155        return true;
   2156    }
   2157 
   2158    return false;
   2159 }
   2160 
   2161 bool StateManager11::queueVertexBufferChange(size_t bufferIndex,
   2162                                             ID3D11Buffer *buffer,
   2163                                             UINT stride,
   2164                                             UINT offset)
   2165 {
   2166    if (buffer != mCurrentVertexBuffers[bufferIndex] ||
   2167        stride != mCurrentVertexStrides[bufferIndex] ||
   2168        offset != mCurrentVertexOffsets[bufferIndex])
   2169    {
   2170        mDirtyVertexBufferRange.extend(static_cast<unsigned int>(bufferIndex));
   2171 
   2172        mCurrentVertexBuffers[bufferIndex] = buffer;
   2173        mCurrentVertexStrides[bufferIndex] = stride;
   2174        mCurrentVertexOffsets[bufferIndex] = offset;
   2175        return true;
   2176    }
   2177 
   2178    return false;
   2179 }
   2180 
   2181 void StateManager11::applyVertexBufferChanges()
   2182 {
   2183    if (mDirtyVertexBufferRange.empty())
   2184    {
   2185        return;
   2186    }
   2187 
   2188    ASSERT(mDirtyVertexBufferRange.high() <= gl::MAX_VERTEX_ATTRIBS);
   2189 
   2190    UINT start = static_cast<UINT>(mDirtyVertexBufferRange.low());
   2191 
   2192    ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
   2193    deviceContext->IASetVertexBuffers(start, static_cast<UINT>(mDirtyVertexBufferRange.length()),
   2194                                      &mCurrentVertexBuffers[start], &mCurrentVertexStrides[start],
   2195                                      &mCurrentVertexOffsets[start]);
   2196 
   2197    mDirtyVertexBufferRange = gl::RangeUI(gl::MAX_VERTEX_ATTRIBS, 0);
   2198 }
   2199 
   2200 void StateManager11::setSingleVertexBuffer(const d3d11::Buffer *buffer, UINT stride, UINT offset)
   2201 {
   2202    ID3D11Buffer *native = buffer ? buffer->get() : nullptr;
   2203    if (queueVertexBufferChange(0, native, stride, offset))
   2204    {
   2205        invalidateInputLayout();
   2206        applyVertexBufferChanges();
   2207    }
   2208 }
   2209 
   2210 angle::Result StateManager11::updateState(const gl::Context *context,
   2211                                          gl::PrimitiveMode mode,
   2212                                          GLint firstVertex,
   2213                                          GLsizei vertexOrIndexCount,
   2214                                          gl::DrawElementsType indexTypeOrInvalid,
   2215                                          const void *indices,
   2216                                          GLsizei instanceCount,
   2217                                          GLint baseVertex,
   2218                                          GLuint baseInstance,
   2219                                          bool promoteDynamic)
   2220 {
   2221    const gl::State &glState = context->getState();
   2222 
   2223    // TODO(jmadill): Use dirty bits.
   2224    if (mRenderTargetIsDirty)
   2225    {
   2226        processFramebufferInvalidation(context);
   2227        mRenderTargetIsDirty = false;
   2228    }
   2229 
   2230    // TODO(jmadill): Use dirty bits.
   2231    if (mProgramD3D->updateSamplerMapping() == ProgramD3D::SamplerMapping::WasDirty)
   2232    {
   2233        invalidateTexturesAndSamplers();
   2234    }
   2235 
   2236    // TODO(jmadill): Use dirty bits.
   2237    if (mProgramD3D->anyShaderUniformsDirty())
   2238    {
   2239        mInternalDirtyBits.set(DIRTY_BIT_PROGRAM_UNIFORMS);
   2240    }
   2241 
   2242    // Swizzling can cause internal state changes with blit shaders.
   2243    if (mDirtySwizzles)
   2244    {
   2245        ANGLE_TRY(generateSwizzles(context));
   2246        mDirtySwizzles = false;
   2247    }
   2248 
   2249    ANGLE_TRY(mFramebuffer11->markAttachmentsDirty(context));
   2250 
   2251    // TODO(jiawei.shao@intel.com): This can be recomputed only on framebuffer or multisample mask
   2252    // state changes.
   2253    RenderTarget11 *firstRT = mFramebuffer11->getFirstRenderTarget();
   2254    int samples             = (firstRT ? firstRT->getSamples() : 0);
   2255    unsigned int sampleMask = GetBlendSampleMask(glState, samples);
   2256    if (sampleMask != mCurSampleMask)
   2257    {
   2258        mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
   2259    }
   2260 
   2261    ANGLE_TRY(mVertexArray11->syncStateForDraw(context, firstVertex, vertexOrIndexCount,
   2262                                               indexTypeOrInvalid, indices, instanceCount,
   2263                                               baseVertex, baseInstance, promoteDynamic));
   2264 
   2265    // Changes in the draw call can affect the vertex buffer translations.
   2266    if (!mLastFirstVertex.valid() || mLastFirstVertex.value() != firstVertex)
   2267    {
   2268        mLastFirstVertex = firstVertex;
   2269        invalidateInputLayout();
   2270    }
   2271 
   2272    // The ShaderConstants only need to be updated when the program uses vertexID
   2273    if (mProgramD3D->usesVertexID())
   2274    {
   2275        GLint firstVertexOnChange = firstVertex + baseVertex;
   2276        ASSERT(mVertexArray11);
   2277        if (mVertexArray11->hasActiveDynamicAttrib(context) &&
   2278            indexTypeOrInvalid != gl::DrawElementsType::InvalidEnum)
   2279        {
   2280            // drawElements with Dynamic attribute
   2281            // the firstVertex is already including baseVertex when
   2282            // doing ComputeStartVertex
   2283            firstVertexOnChange = firstVertex;
   2284        }
   2285 
   2286        if (mShaderConstants.onFirstVertexChange(firstVertexOnChange))
   2287        {
   2288            mInternalDirtyBits.set(DIRTY_BIT_DRIVER_UNIFORMS);
   2289        }
   2290    }
   2291 
   2292    if (indexTypeOrInvalid != gl::DrawElementsType::InvalidEnum)
   2293    {
   2294        ANGLE_TRY(applyIndexBuffer(context, vertexOrIndexCount, indexTypeOrInvalid, indices));
   2295    }
   2296 
   2297    if (mLastAppliedDrawMode != mode)
   2298    {
   2299        mLastAppliedDrawMode = mode;
   2300        mInternalDirtyBits.set(DIRTY_BIT_PRIMITIVE_TOPOLOGY);
   2301 
   2302        bool pointDrawMode = (mode == gl::PrimitiveMode::Points);
   2303        if (pointDrawMode != mCurRasterState.pointDrawMode)
   2304        {
   2305            mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
   2306 
   2307            // Changing from points to not points (or vice-versa) affects the geometry shader.
   2308            invalidateShaders();
   2309        }
   2310    }
   2311 
   2312    auto dirtyBitsCopy = mInternalDirtyBits & mGraphicsDirtyBitsMask;
   2313 
   2314    for (auto iter = dirtyBitsCopy.begin(), end = dirtyBitsCopy.end(); iter != end; ++iter)
   2315    {
   2316        mInternalDirtyBits.reset(*iter);
   2317        switch (*iter)
   2318        {
   2319            case DIRTY_BIT_RENDER_TARGET:
   2320                ANGLE_TRY(syncFramebuffer(context));
   2321                break;
   2322            case DIRTY_BIT_VIEWPORT_STATE:
   2323                syncViewport(context);
   2324                break;
   2325            case DIRTY_BIT_SCISSOR_STATE:
   2326                syncScissorRectangle(context);
   2327                break;
   2328            case DIRTY_BIT_RASTERIZER_STATE:
   2329                ANGLE_TRY(syncRasterizerState(context, mode));
   2330                break;
   2331            case DIRTY_BIT_BLEND_STATE:
   2332                ANGLE_TRY(syncBlendState(
   2333                    context, glState.getBlendStateExt(), glState.getBlendColor(), sampleMask,
   2334                    glState.isSampleAlphaToCoverageEnabled(), glState.hasConstantAlphaBlendFunc()));
   2335                break;
   2336            case DIRTY_BIT_DEPTH_STENCIL_STATE:
   2337                ANGLE_TRY(syncDepthStencilState(context));
   2338                break;
   2339            case DIRTY_BIT_GRAPHICS_SRV_STATE:
   2340                ANGLE_TRY(syncTextures(context));
   2341                break;
   2342            case DIRTY_BIT_GRAPHICS_UAV_STATE:
   2343                ANGLE_TRY(syncUAVsForGraphics(context));
   2344                break;
   2345            case DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE:
   2346                // TODO(jmadill): More fine-grained update.
   2347                ANGLE_TRY(syncTextures(context));
   2348                break;
   2349            case DIRTY_BIT_PROGRAM_UNIFORMS:
   2350                ANGLE_TRY(applyUniforms(context));
   2351                break;
   2352            case DIRTY_BIT_DRIVER_UNIFORMS:
   2353                // This must happen after viewport sync; the viewport affects builtin uniforms.
   2354                ANGLE_TRY(applyDriverUniforms(context));
   2355                break;
   2356            case DIRTY_BIT_PROGRAM_UNIFORM_BUFFERS:
   2357                ANGLE_TRY(syncUniformBuffers(context));
   2358                break;
   2359            case DIRTY_BIT_SHADERS:
   2360                ANGLE_TRY(syncProgram(context, mode));
   2361                break;
   2362            case DIRTY_BIT_CURRENT_VALUE_ATTRIBS:
   2363                ANGLE_TRY(syncCurrentValueAttribs(context, glState.getVertexAttribCurrentValues()));
   2364                break;
   2365            case DIRTY_BIT_TRANSFORM_FEEDBACK:
   2366                ANGLE_TRY(syncTransformFeedbackBuffers(context));
   2367                break;
   2368            case DIRTY_BIT_VERTEX_BUFFERS_AND_INPUT_LAYOUT:
   2369                ANGLE_TRY(syncVertexBuffersAndInputLayout(context, mode, firstVertex,
   2370                                                          vertexOrIndexCount, indexTypeOrInvalid,
   2371                                                          instanceCount));
   2372                break;
   2373            case DIRTY_BIT_PRIMITIVE_TOPOLOGY:
   2374                syncPrimitiveTopology(glState, mode);
   2375                break;
   2376            default:
   2377                UNREACHABLE();
   2378                break;
   2379        }
   2380    }
   2381 
   2382    // Check that we haven't set any dirty bits in the flushing of the dirty bits loop, except
   2383    // DIRTY_BIT_COMPUTE_SRVUAV_STATE dirty bit.
   2384    ASSERT((mInternalDirtyBits & mGraphicsDirtyBitsMask).none());
   2385 
   2386    return angle::Result::Continue;
   2387 }
   2388 
   2389 void StateManager11::setShaderResourceShared(gl::ShaderType shaderType,
   2390                                             UINT resourceSlot,
   2391                                             const d3d11::SharedSRV *srv)
   2392 {
   2393    setShaderResourceInternal(shaderType, resourceSlot, srv);
   2394 
   2395    // TODO(jmadill): Narrower dirty region.
   2396    mInternalDirtyBits.set(DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE);
   2397 }
   2398 
   2399 void StateManager11::setShaderResource(gl::ShaderType shaderType,
   2400                                       UINT resourceSlot,
   2401                                       const d3d11::ShaderResourceView *srv)
   2402 {
   2403    setShaderResourceInternal(shaderType, resourceSlot, srv);
   2404 
   2405    // TODO(jmadill): Narrower dirty region.
   2406    mInternalDirtyBits.set(DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE);
   2407 }
   2408 
   2409 void StateManager11::setPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY primitiveTopology)
   2410 {
   2411    if (setPrimitiveTopologyInternal(primitiveTopology))
   2412    {
   2413        mInternalDirtyBits.set(DIRTY_BIT_PRIMITIVE_TOPOLOGY);
   2414    }
   2415 }
   2416 
   2417 bool StateManager11::setPrimitiveTopologyInternal(D3D11_PRIMITIVE_TOPOLOGY primitiveTopology)
   2418 {
   2419    if (primitiveTopology != mCurrentPrimitiveTopology)
   2420    {
   2421        mRenderer->getDeviceContext()->IASetPrimitiveTopology(primitiveTopology);
   2422        mCurrentPrimitiveTopology = primitiveTopology;
   2423        return true;
   2424    }
   2425    else
   2426    {
   2427        return false;
   2428    }
   2429 }
   2430 
   2431 void StateManager11::setDrawShaders(const d3d11::VertexShader *vertexShader,
   2432                                    const d3d11::GeometryShader *geometryShader,
   2433                                    const d3d11::PixelShader *pixelShader)
   2434 {
   2435    setVertexShader(vertexShader);
   2436    setGeometryShader(geometryShader);
   2437    setPixelShader(pixelShader);
   2438 }
   2439 
   2440 void StateManager11::setVertexShader(const d3d11::VertexShader *shader)
   2441 {
   2442    ResourceSerial serial = shader ? shader->getSerial() : ResourceSerial(0);
   2443 
   2444    if (serial != mAppliedShaders[gl::ShaderType::Vertex])
   2445    {
   2446        ID3D11VertexShader *appliedShader = shader ? shader->get() : nullptr;
   2447        mRenderer->getDeviceContext()->VSSetShader(appliedShader, nullptr, 0);
   2448        mAppliedShaders[gl::ShaderType::Vertex] = serial;
   2449        invalidateShaders();
   2450    }
   2451 }
   2452 
   2453 void StateManager11::setGeometryShader(const d3d11::GeometryShader *shader)
   2454 {
   2455    ResourceSerial serial = shader ? shader->getSerial() : ResourceSerial(0);
   2456 
   2457    if (serial != mAppliedShaders[gl::ShaderType::Geometry])
   2458    {
   2459        ID3D11GeometryShader *appliedShader = shader ? shader->get() : nullptr;
   2460        mRenderer->getDeviceContext()->GSSetShader(appliedShader, nullptr, 0);
   2461        mAppliedShaders[gl::ShaderType::Geometry] = serial;
   2462        invalidateShaders();
   2463    }
   2464 }
   2465 
   2466 void StateManager11::setPixelShader(const d3d11::PixelShader *shader)
   2467 {
   2468    ResourceSerial serial = shader ? shader->getSerial() : ResourceSerial(0);
   2469 
   2470    if (serial != mAppliedShaders[gl::ShaderType::Fragment])
   2471    {
   2472        ID3D11PixelShader *appliedShader = shader ? shader->get() : nullptr;
   2473        mRenderer->getDeviceContext()->PSSetShader(appliedShader, nullptr, 0);
   2474        mAppliedShaders[gl::ShaderType::Fragment] = serial;
   2475        invalidateShaders();
   2476    }
   2477 }
   2478 
   2479 void StateManager11::setComputeShader(const d3d11::ComputeShader *shader)
   2480 {
   2481    ResourceSerial serial = shader ? shader->getSerial() : ResourceSerial(0);
   2482 
   2483    if (serial != mAppliedShaders[gl::ShaderType::Compute])
   2484    {
   2485        ID3D11ComputeShader *appliedShader = shader ? shader->get() : nullptr;
   2486        mRenderer->getDeviceContext()->CSSetShader(appliedShader, nullptr, 0);
   2487        mAppliedShaders[gl::ShaderType::Compute] = serial;
   2488        invalidateShaders();
   2489    }
   2490 }
   2491 
   2492 void StateManager11::setVertexConstantBuffer(unsigned int slot, const d3d11::Buffer *buffer)
   2493 {
   2494    ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
   2495    auto &currentSerial                = mCurrentConstantBufferVS[slot];
   2496 
   2497    mCurrentConstantBufferVSOffset[slot] = 0;
   2498    mCurrentConstantBufferVSSize[slot]   = 0;
   2499 
   2500    if (buffer)
   2501    {
   2502        if (currentSerial != buffer->getSerial())
   2503        {
   2504            deviceContext->VSSetConstantBuffers(slot, 1, buffer->getPointer());
   2505            currentSerial = buffer->getSerial();
   2506            invalidateConstantBuffer(slot);
   2507        }
   2508    }
   2509    else
   2510    {
   2511        if (!currentSerial.empty())
   2512        {
   2513            ID3D11Buffer *nullBuffer = nullptr;
   2514            deviceContext->VSSetConstantBuffers(slot, 1, &nullBuffer);
   2515            currentSerial.clear();
   2516            invalidateConstantBuffer(slot);
   2517        }
   2518    }
   2519 }
   2520 
   2521 void StateManager11::setPixelConstantBuffer(unsigned int slot, const d3d11::Buffer *buffer)
   2522 {
   2523    ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
   2524    auto &currentSerial                = mCurrentConstantBufferPS[slot];
   2525 
   2526    mCurrentConstantBufferPSOffset[slot] = 0;
   2527    mCurrentConstantBufferPSSize[slot]   = 0;
   2528 
   2529    if (buffer)
   2530    {
   2531        if (currentSerial != buffer->getSerial())
   2532        {
   2533            deviceContext->PSSetConstantBuffers(slot, 1, buffer->getPointer());
   2534            currentSerial = buffer->getSerial();
   2535            invalidateConstantBuffer(slot);
   2536        }
   2537    }
   2538    else
   2539    {
   2540        if (!currentSerial.empty())
   2541        {
   2542            ID3D11Buffer *nullBuffer = nullptr;
   2543            deviceContext->PSSetConstantBuffers(slot, 1, &nullBuffer);
   2544            currentSerial.clear();
   2545            invalidateConstantBuffer(slot);
   2546        }
   2547    }
   2548 }
   2549 
   2550 void StateManager11::setDepthStencilState(const d3d11::DepthStencilState *depthStencilState,
   2551                                          UINT stencilRef)
   2552 {
   2553    ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
   2554 
   2555    if (depthStencilState)
   2556    {
   2557        deviceContext->OMSetDepthStencilState(depthStencilState->get(), stencilRef);
   2558    }
   2559    else
   2560    {
   2561        deviceContext->OMSetDepthStencilState(nullptr, stencilRef);
   2562    }
   2563 
   2564    mInternalDirtyBits.set(DIRTY_BIT_DEPTH_STENCIL_STATE);
   2565 }
   2566 
   2567 void StateManager11::setSimpleBlendState(const d3d11::BlendState *blendState)
   2568 {
   2569    ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
   2570 
   2571    if (blendState)
   2572    {
   2573        deviceContext->OMSetBlendState(blendState->get(), nullptr, 0xFFFFFFFF);
   2574    }
   2575    else
   2576    {
   2577        deviceContext->OMSetBlendState(nullptr, nullptr, 0xFFFFFFFF);
   2578    }
   2579 
   2580    mInternalDirtyBits.set(DIRTY_BIT_BLEND_STATE);
   2581 }
   2582 
   2583 void StateManager11::setRasterizerState(const d3d11::RasterizerState *rasterizerState)
   2584 {
   2585    ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
   2586 
   2587    if (rasterizerState)
   2588    {
   2589        deviceContext->RSSetState(rasterizerState->get());
   2590    }
   2591    else
   2592    {
   2593        deviceContext->RSSetState(nullptr);
   2594    }
   2595 
   2596    mInternalDirtyBits.set(DIRTY_BIT_RASTERIZER_STATE);
   2597 }
   2598 
   2599 void StateManager11::setSimpleViewport(const gl::Extents &extents)
   2600 {
   2601    setSimpleViewport(extents.width, extents.height);
   2602 }
   2603 
   2604 void StateManager11::setSimpleViewport(int width, int height)
   2605 {
   2606    D3D11_VIEWPORT viewport;
   2607    viewport.TopLeftX = 0;
   2608    viewport.TopLeftY = 0;
   2609    viewport.Width    = static_cast<FLOAT>(width);
   2610    viewport.Height   = static_cast<FLOAT>(height);
   2611    viewport.MinDepth = 0.0f;
   2612    viewport.MaxDepth = 1.0f;
   2613 
   2614    mRenderer->getDeviceContext()->RSSetViewports(1, &viewport);
   2615    mInternalDirtyBits.set(DIRTY_BIT_VIEWPORT_STATE);
   2616 }
   2617 
   2618 void StateManager11::setSimplePixelTextureAndSampler(const d3d11::SharedSRV &srv,
   2619                                                     const d3d11::SamplerState &samplerState)
   2620 {
   2621    ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
   2622 
   2623    setShaderResourceInternal(gl::ShaderType::Fragment, 0, &srv);
   2624    deviceContext->PSSetSamplers(0, 1, samplerState.getPointer());
   2625 
   2626    mInternalDirtyBits.set(DIRTY_BIT_TEXTURE_AND_SAMPLER_STATE);
   2627    mForceSetShaderSamplerStates[gl::ShaderType::Fragment][0] = true;
   2628 }
   2629 
   2630 void StateManager11::setSimpleScissorRect(const gl::Rectangle &glRect)
   2631 {
   2632    D3D11_RECT scissorRect;
   2633    scissorRect.left   = glRect.x;
   2634    scissorRect.right  = glRect.x + glRect.width;
   2635    scissorRect.top    = glRect.y;
   2636    scissorRect.bottom = glRect.y + glRect.height;
   2637    setScissorRectD3D(scissorRect);
   2638 }
   2639 
   2640 void StateManager11::setScissorRectD3D(const D3D11_RECT &d3dRect)
   2641 {
   2642    mRenderer->getDeviceContext()->RSSetScissorRects(1, &d3dRect);
   2643    mInternalDirtyBits.set(DIRTY_BIT_SCISSOR_STATE);
   2644 }
   2645 
   2646 angle::Result StateManager11::syncTextures(const gl::Context *context)
   2647 {
   2648    ANGLE_TRY(applyTexturesForSRVs(context, gl::ShaderType::Vertex));
   2649    ANGLE_TRY(applyTexturesForSRVs(context, gl::ShaderType::Fragment));
   2650    if (mProgramD3D->hasShaderStage(gl::ShaderType::Geometry))
   2651    {
   2652        ANGLE_TRY(applyTexturesForSRVs(context, gl::ShaderType::Geometry));
   2653    }
   2654 
   2655    return angle::Result::Continue;
   2656 }
   2657 
   2658 angle::Result StateManager11::setSamplerState(const gl::Context *context,
   2659                                              gl::ShaderType type,
   2660                                              int index,
   2661                                              gl::Texture *texture,
   2662                                              const gl::SamplerState &samplerState)
   2663 {
   2664 #if !defined(NDEBUG)
   2665    // Storage should exist, texture should be complete. Only verified in Debug.
   2666    TextureD3D *textureD3D  = GetImplAs<TextureD3D>(texture);
   2667    TextureStorage *storage = nullptr;
   2668    ANGLE_TRY(textureD3D->getNativeTexture(context, &storage));
   2669    ASSERT(storage);
   2670 #endif  // !defined(NDEBUG)
   2671 
   2672    auto *deviceContext = mRenderer->getDeviceContext();
   2673 
   2674    ASSERT(index < mRenderer->getNativeCaps().maxShaderTextureImageUnits[type]);
   2675 
   2676    if (mForceSetShaderSamplerStates[type][index] ||
   2677        memcmp(&samplerState, &mCurShaderSamplerStates[type][index], sizeof(gl::SamplerState)) != 0)
   2678    {
   2679        ID3D11SamplerState *dxSamplerState = nullptr;
   2680        ANGLE_TRY(mRenderer->getSamplerState(context, samplerState, &dxSamplerState));
   2681 
   2682        ASSERT(dxSamplerState != nullptr);
   2683 
   2684        switch (type)
   2685        {
   2686            case gl::ShaderType::Vertex:
   2687                deviceContext->VSSetSamplers(index, 1, &dxSamplerState);
   2688                break;
   2689            case gl::ShaderType::Fragment:
   2690                deviceContext->PSSetSamplers(index, 1, &dxSamplerState);
   2691                break;
   2692            case gl::ShaderType::Compute:
   2693                deviceContext->CSSetSamplers(index, 1, &dxSamplerState);
   2694                break;
   2695            case gl::ShaderType::Geometry:
   2696                deviceContext->GSSetSamplers(index, 1, &dxSamplerState);
   2697                break;
   2698            default:
   2699                UNREACHABLE();
   2700                break;
   2701        }
   2702 
   2703        mCurShaderSamplerStates[type][index] = samplerState;
   2704    }
   2705 
   2706    mForceSetShaderSamplerStates[type][index] = false;
   2707 
   2708    // Sampler metadata that's passed to shaders in uniforms is stored separately from rest of the
   2709    // sampler state since having it in contiguous memory makes it possible to memcpy to a constant
   2710    // buffer, and it doesn't affect the state set by
   2711    // PSSetSamplers/VSSetSamplers/CSSetSamplers/GSSetSamplers.
   2712    mShaderConstants.onSamplerChange(type, index, *texture, samplerState);
   2713 
   2714    return angle::Result::Continue;
   2715 }
   2716 
   2717 angle::Result StateManager11::setTextureForSampler(const gl::Context *context,
   2718                                                   gl::ShaderType type,
   2719                                                   int index,
   2720                                                   gl::Texture *texture,
   2721                                                   const gl::SamplerState &sampler)
   2722 {
   2723    const d3d11::SharedSRV *textureSRV = nullptr;
   2724 
   2725    if (texture)
   2726    {
   2727        TextureD3D *textureImpl = GetImplAs<TextureD3D>(texture);
   2728 
   2729        TextureStorage *texStorage = nullptr;
   2730        ANGLE_TRY(textureImpl->getNativeTexture(context, &texStorage));
   2731 
   2732        // Texture should be complete and have a storage
   2733        ASSERT(texStorage);
   2734 
   2735        TextureStorage11 *storage11 = GetAs<TextureStorage11>(texStorage);
   2736 
   2737        ANGLE_TRY(
   2738            storage11->getSRVForSampler(context, texture->getTextureState(), sampler, &textureSRV));
   2739 
   2740        // If we get an invalid SRV here, something went wrong in the texture class and we're
   2741        // unexpectedly missing the shader resource view.
   2742        ASSERT(textureSRV->valid());
   2743 
   2744        textureImpl->resetDirty();
   2745    }
   2746 
   2747    ASSERT(
   2748        (type == gl::ShaderType::Fragment &&
   2749         index < mRenderer->getNativeCaps().maxShaderTextureImageUnits[gl::ShaderType::Fragment]) ||
   2750        (type == gl::ShaderType::Vertex &&
   2751         index < mRenderer->getNativeCaps().maxShaderTextureImageUnits[gl::ShaderType::Vertex]) ||
   2752        (type == gl::ShaderType::Compute &&
   2753         index < mRenderer->getNativeCaps().maxShaderTextureImageUnits[gl::ShaderType::Compute]));
   2754 
   2755    setShaderResourceInternal(type, index, textureSRV);
   2756    return angle::Result::Continue;
   2757 }
   2758 
   2759 angle::Result StateManager11::setImageState(const gl::Context *context,
   2760                                            gl::ShaderType type,
   2761                                            int index,
   2762                                            const gl::ImageUnit &imageUnit)
   2763 {
   2764    ASSERT(index < mRenderer->getNativeCaps().maxShaderImageUniforms[type]);
   2765 
   2766    if (mShaderConstants.onImageChange(type, index, imageUnit))
   2767    {
   2768        invalidateProgramUniforms();
   2769    }
   2770 
   2771    return angle::Result::Continue;
   2772 }
   2773 
   2774 // For each Direct3D sampler of either the pixel or vertex stage,
   2775 // looks up the corresponding OpenGL texture image unit and texture type,
   2776 // and sets the texture and its addressing/filtering state (or NULL when inactive).
   2777 // Sampler mapping needs to be up-to-date on the program object before this is called.
   2778 angle::Result StateManager11::applyTexturesForSRVs(const gl::Context *context,
   2779                                                   gl::ShaderType shaderType)
   2780 {
   2781    const auto &glState = context->getState();
   2782    const auto &caps    = context->getCaps();
   2783 
   2784    ASSERT(!mProgramD3D->isSamplerMappingDirty());
   2785 
   2786    // TODO(jmadill): Use the Program's sampler bindings.
   2787    const gl::ActiveTexturesCache &completeTextures = glState.getActiveTexturesCache();
   2788 
   2789    const gl::RangeUI samplerRange = mProgramD3D->getUsedSamplerRange(shaderType);
   2790    for (unsigned int samplerIndex = samplerRange.low(); samplerIndex < samplerRange.high();
   2791         samplerIndex++)
   2792    {
   2793        GLint textureUnit = mProgramD3D->getSamplerMapping(shaderType, samplerIndex, caps);
   2794        ASSERT(textureUnit != -1);
   2795        gl::Texture *texture = completeTextures[textureUnit];
   2796 
   2797        // A nullptr texture indicates incomplete.
   2798        if (texture)
   2799        {
   2800            gl::Sampler *samplerObject = glState.getSampler(textureUnit);
   2801 
   2802            const gl::SamplerState &samplerState =
   2803                samplerObject ? samplerObject->getSamplerState() : texture->getSamplerState();
   2804 
   2805            ANGLE_TRY(setSamplerState(context, shaderType, samplerIndex, texture, samplerState));
   2806            ANGLE_TRY(
   2807                setTextureForSampler(context, shaderType, samplerIndex, texture, samplerState));
   2808        }
   2809        else
   2810        {
   2811            gl::TextureType textureType =
   2812                mProgramD3D->getSamplerTextureType(shaderType, samplerIndex);
   2813 
   2814            // Texture is not sampler complete or it is in use by the framebuffer.  Bind the
   2815            // incomplete texture.
   2816            gl::Texture *incompleteTexture = nullptr;
   2817            ANGLE_TRY(mRenderer->getIncompleteTexture(context, textureType, &incompleteTexture));
   2818            ANGLE_TRY(setSamplerState(context, shaderType, samplerIndex, incompleteTexture,
   2819                                      incompleteTexture->getSamplerState()));
   2820            ANGLE_TRY(setTextureForSampler(context, shaderType, samplerIndex, incompleteTexture,
   2821                                           incompleteTexture->getSamplerState()));
   2822        }
   2823    }
   2824 
   2825    const gl::RangeUI readonlyImageRange = mProgramD3D->getUsedImageRange(shaderType, true);
   2826    for (unsigned int readonlyImageIndex = readonlyImageRange.low();
   2827         readonlyImageIndex < readonlyImageRange.high(); readonlyImageIndex++)
   2828    {
   2829        GLint imageUnitIndex =
   2830            mProgramD3D->getImageMapping(shaderType, readonlyImageIndex, true, caps);
   2831        ASSERT(imageUnitIndex != -1);
   2832        const gl::ImageUnit &imageUnit = glState.getImageUnit(imageUnitIndex);
   2833        if (!imageUnit.layered)
   2834        {
   2835            ANGLE_TRY(setImageState(context, gl::ShaderType::Compute,
   2836                                    readonlyImageIndex - readonlyImageRange.low(), imageUnit));
   2837        }
   2838        ANGLE_TRY(setTextureForImage(context, shaderType, readonlyImageIndex, imageUnit));
   2839    }
   2840 
   2841    return angle::Result::Continue;
   2842 }
   2843 
   2844 angle::Result StateManager11::getUAVsForRWImages(const gl::Context *context,
   2845                                                 gl::ShaderType shaderType,
   2846                                                 UAVList *uavList)
   2847 {
   2848    const auto &glState = context->getState();
   2849    const auto &caps    = context->getCaps();
   2850 
   2851    const gl::RangeUI imageRange = mProgramD3D->getUsedImageRange(shaderType, false);
   2852    for (unsigned int imageIndex = imageRange.low(); imageIndex < imageRange.high(); imageIndex++)
   2853    {
   2854        GLint imageUnitIndex = mProgramD3D->getImageMapping(shaderType, imageIndex, false, caps);
   2855        ASSERT(imageUnitIndex != -1);
   2856        const gl::ImageUnit &imageUnit = glState.getImageUnit(imageUnitIndex);
   2857        if (!imageUnit.layered)
   2858        {
   2859            ANGLE_TRY(setImageState(context, shaderType, imageIndex - imageRange.low(), imageUnit));
   2860        }
   2861        ANGLE_TRY(getUAVForRWImage(context, shaderType, imageIndex, imageUnit, uavList));
   2862    }
   2863 
   2864    return angle::Result::Continue;
   2865 }
   2866 
   2867 angle::Result StateManager11::syncTexturesForCompute(const gl::Context *context)
   2868 {
   2869    ANGLE_TRY(applyTexturesForSRVs(context, gl::ShaderType::Compute));
   2870    return angle::Result::Continue;
   2871 }
   2872 
   2873 angle::Result StateManager11::setTextureForImage(const gl::Context *context,
   2874                                                 gl::ShaderType type,
   2875                                                 int index,
   2876                                                 const gl::ImageUnit &imageUnit)
   2877 {
   2878    TextureD3D *textureImpl = nullptr;
   2879    if (!imageUnit.texture.get())
   2880    {
   2881        setShaderResourceInternal<d3d11::ShaderResourceView>(type, static_cast<UINT>(index),
   2882                                                             nullptr);
   2883        return angle::Result::Continue;
   2884    }
   2885 
   2886    textureImpl = GetImplAs<TextureD3D>(imageUnit.texture.get());
   2887 
   2888    // Ensure that texture has unordered access; convert it if not.
   2889    ANGLE_TRY(textureImpl->ensureUnorderedAccess(context));
   2890 
   2891    TextureStorage *texStorage = nullptr;
   2892    ANGLE_TRY(textureImpl->getNativeTexture(context, &texStorage));
   2893    // Texture should be complete and have a storage
   2894    ASSERT(texStorage);
   2895    TextureStorage11 *storage11 = GetAs<TextureStorage11>(texStorage);
   2896 
   2897    const d3d11::SharedSRV *textureSRV = nullptr;
   2898    ANGLE_TRY(storage11->getSRVForImage(context, imageUnit, &textureSRV));
   2899    // If we get an invalid SRV here, something went wrong in the texture class and we're
   2900    // unexpectedly missing the shader resource view.
   2901    ASSERT(textureSRV->valid());
   2902    ASSERT((index < mRenderer->getNativeCaps().maxImageUnits));
   2903    setShaderResourceInternal(type, index, textureSRV);
   2904 
   2905    textureImpl->resetDirty();
   2906    return angle::Result::Continue;
   2907 }
   2908 
   2909 angle::Result StateManager11::getUAVForRWImage(const gl::Context *context,
   2910                                               gl::ShaderType type,
   2911                                               int index,
   2912                                               const gl::ImageUnit &imageUnit,
   2913                                               UAVList *uavList)
   2914 {
   2915    TextureD3D *textureImpl = nullptr;
   2916    if (!imageUnit.texture.get())
   2917    {
   2918        setUnorderedAccessViewInternal<d3d11::UnorderedAccessView>(static_cast<UINT>(index),
   2919                                                                   nullptr, uavList);
   2920        return angle::Result::Continue;
   2921    }
   2922 
   2923    textureImpl = GetImplAs<TextureD3D>(imageUnit.texture.get());
   2924 
   2925    // Ensure that texture has unordered access; convert it if not.
   2926    ANGLE_TRY(textureImpl->ensureUnorderedAccess(context));
   2927 
   2928    TextureStorage *texStorage = nullptr;
   2929    ANGLE_TRY(textureImpl->getNativeTexture(context, &texStorage));
   2930    // Texture should be complete and have a storage
   2931    ASSERT(texStorage);
   2932    TextureStorage11 *storage11 = GetAs<TextureStorage11>(texStorage);
   2933 
   2934    const d3d11::SharedUAV *textureUAV = nullptr;
   2935    ANGLE_TRY(storage11->getUAVForImage(context, imageUnit, &textureUAV));
   2936    // If we get an invalid UAV here, something went wrong in the texture class and we're
   2937    // unexpectedly missing the unordered access view.
   2938    ASSERT(textureUAV->valid());
   2939    ASSERT((index < mRenderer->getNativeCaps().maxImageUnits));
   2940    setUnorderedAccessViewInternal(index, textureUAV, uavList);
   2941 
   2942    textureImpl->resetDirty();
   2943    return angle::Result::Continue;
   2944 }
   2945 
   2946 // Things that affect a program's dirtyness:
   2947 // 1. Directly changing the program executable -> triggered in StateManager11::syncState.
   2948 // 2. The vertex attribute layout              -> triggered in VertexArray11::syncState/signal.
   2949 // 3. The fragment shader's rendertargets      -> triggered in Framebuffer11::syncState/signal.
   2950 // 4. Enabling/disabling rasterizer discard.   -> triggered in StateManager11::syncState.
   2951 // 5. Enabling/disabling transform feedback.   -> checked in StateManager11::updateState.
   2952 // 6. An internal shader was used.             -> triggered in StateManager11::set*Shader.
   2953 // 7. Drawing with/without point sprites.      -> checked in StateManager11::updateState.
   2954 // TODO(jmadill): Use dirty bits for transform feedback.
   2955 angle::Result StateManager11::syncProgram(const gl::Context *context, gl::PrimitiveMode drawMode)
   2956 {
   2957    Context11 *context11 = GetImplAs<Context11>(context);
   2958    ANGLE_TRY(context11->triggerDrawCallProgramRecompilation(context, drawMode));
   2959 
   2960    const auto &glState = context->getState();
   2961 
   2962    mProgramD3D->updateCachedInputLayout(mVertexArray11->getCurrentStateSerial(), glState);
   2963 
   2964    // Binaries must be compiled before the sync.
   2965    ASSERT(mProgramD3D->hasVertexExecutableForCachedInputLayout());
   2966    ASSERT(mProgramD3D->hasGeometryExecutableForPrimitiveType(glState, drawMode));
   2967    ASSERT(mProgramD3D->hasPixelExecutableForCachedOutputLayout());
   2968 
   2969    ShaderExecutableD3D *vertexExe = nullptr;
   2970    ANGLE_TRY(mProgramD3D->getVertexExecutableForCachedInputLayout(context11, &vertexExe, nullptr));
   2971 
   2972    ShaderExecutableD3D *pixelExe = nullptr;
   2973    ANGLE_TRY(mProgramD3D->getPixelExecutableForCachedOutputLayout(context11, &pixelExe, nullptr));
   2974 
   2975    ShaderExecutableD3D *geometryExe = nullptr;
   2976    ANGLE_TRY(mProgramD3D->getGeometryExecutableForPrimitiveType(context11, glState, drawMode,
   2977                                                                 &geometryExe, nullptr));
   2978 
   2979    const d3d11::VertexShader *vertexShader =
   2980        (vertexExe ? &GetAs<ShaderExecutable11>(vertexExe)->getVertexShader() : nullptr);
   2981 
   2982    // Skip pixel shader if we're doing rasterizer discard.
   2983    const d3d11::PixelShader *pixelShader = nullptr;
   2984    if (!glState.getRasterizerState().rasterizerDiscard)
   2985    {
   2986        pixelShader = (pixelExe ? &GetAs<ShaderExecutable11>(pixelExe)->getPixelShader() : nullptr);
   2987    }
   2988 
   2989    const d3d11::GeometryShader *geometryShader = nullptr;
   2990    if (glState.isTransformFeedbackActiveUnpaused())
   2991    {
   2992        geometryShader =
   2993            (vertexExe ? &GetAs<ShaderExecutable11>(vertexExe)->getStreamOutShader() : nullptr);
   2994    }
   2995    else
   2996    {
   2997        geometryShader =
   2998            (geometryExe ? &GetAs<ShaderExecutable11>(geometryExe)->getGeometryShader() : nullptr);
   2999    }
   3000 
   3001    setDrawShaders(vertexShader, geometryShader, pixelShader);
   3002 
   3003    // Explicitly clear the shaders dirty bit.
   3004    mInternalDirtyBits.reset(DIRTY_BIT_SHADERS);
   3005 
   3006    return angle::Result::Continue;
   3007 }
   3008 
   3009 angle::Result StateManager11::syncProgramForCompute(const gl::Context *context)
   3010 {
   3011    Context11 *context11 = GetImplAs<Context11>(context);
   3012    ANGLE_TRY(context11->triggerDispatchCallProgramRecompilation(context));
   3013 
   3014    mProgramD3D->updateCachedComputeImage2DBindLayout(context);
   3015 
   3016    // Binaries must be compiled before the sync.
   3017    ASSERT(mProgramD3D->hasComputeExecutableForCachedImage2DBindLayout());
   3018 
   3019    ShaderExecutableD3D *computeExe = nullptr;
   3020    ANGLE_TRY(mProgramD3D->getComputeExecutableForImage2DBindLayout(context, context11, &computeExe,
   3021                                                                    nullptr));
   3022 
   3023    const d3d11::ComputeShader *computeShader =
   3024        (computeExe ? &GetAs<ShaderExecutable11>(computeExe)->getComputeShader() : nullptr);
   3025    setComputeShader(computeShader);
   3026    // Explicitly clear the shaders dirty bit.
   3027    mInternalDirtyBits.reset(DIRTY_BIT_SHADERS);
   3028 
   3029    return angle::Result::Continue;
   3030 }
   3031 
   3032 angle::Result StateManager11::syncVertexBuffersAndInputLayout(
   3033    const gl::Context *context,
   3034    gl::PrimitiveMode mode,
   3035    GLint firstVertex,
   3036    GLsizei vertexOrIndexCount,
   3037    gl::DrawElementsType indexTypeOrInvalid,
   3038    GLsizei instanceCount)
   3039 {
   3040    const auto &vertexArrayAttribs = mVertexArray11->getTranslatedAttribs();
   3041 
   3042    // Sort the attributes according to ensure we re-use similar input layouts.
   3043    AttribIndexArray sortedSemanticIndices;
   3044    SortAttributesByLayout(*mProgramD3D, vertexArrayAttribs, mCurrentValueAttribs,
   3045                           &sortedSemanticIndices, &mCurrentAttributes);
   3046 
   3047    D3D_FEATURE_LEVEL featureLevel = mRenderer->getRenderer11DeviceCaps().featureLevel;
   3048 
   3049    // If we are using FL 9_3, make sure the first attribute is not instanced
   3050    if (featureLevel <= D3D_FEATURE_LEVEL_9_3 && !mCurrentAttributes.empty())
   3051    {
   3052        if (mCurrentAttributes[0]->divisor > 0)
   3053        {
   3054            Optional<size_t> firstNonInstancedIndex = FindFirstNonInstanced(mCurrentAttributes);
   3055            if (firstNonInstancedIndex.valid())
   3056            {
   3057                size_t index = firstNonInstancedIndex.value();
   3058                std::swap(mCurrentAttributes[0], mCurrentAttributes[index]);
   3059                std::swap(sortedSemanticIndices[0], sortedSemanticIndices[index]);
   3060            }
   3061        }
   3062    }
   3063 
   3064    // Update the applied input layout by querying the cache.
   3065    const gl::State &state                = context->getState();
   3066    const d3d11::InputLayout *inputLayout = nullptr;
   3067    ANGLE_TRY(mInputLayoutCache.getInputLayout(GetImplAs<Context11>(context), state,
   3068                                               mCurrentAttributes, sortedSemanticIndices, mode,
   3069                                               vertexOrIndexCount, instanceCount, &inputLayout));
   3070    setInputLayoutInternal(inputLayout);
   3071 
   3072    // Update the applied vertex buffers.
   3073    ANGLE_TRY(applyVertexBuffers(context, mode, indexTypeOrInvalid, firstVertex));
   3074 
   3075    return angle::Result::Continue;
   3076 }
   3077 
   3078 angle::Result StateManager11::applyVertexBuffers(const gl::Context *context,
   3079                                                 gl::PrimitiveMode mode,
   3080                                                 gl::DrawElementsType indexTypeOrInvalid,
   3081                                                 GLint firstVertex)
   3082 {
   3083    bool programUsesInstancedPointSprites =
   3084        mProgramD3D->usesPointSize() && mProgramD3D->usesInstancedPointSpriteEmulation();
   3085    bool instancedPointSpritesActive =
   3086        programUsesInstancedPointSprites && (mode == gl::PrimitiveMode::Points);
   3087 
   3088    // Note that if we use instance emulation, we reserve the first buffer slot.
   3089    size_t reservedBuffers = GetReservedBufferCount(programUsesInstancedPointSprites);
   3090 
   3091    for (size_t attribIndex = 0; attribIndex < (gl::MAX_VERTEX_ATTRIBS - reservedBuffers);
   3092         ++attribIndex)
   3093    {
   3094        ID3D11Buffer *buffer = nullptr;
   3095        UINT vertexStride    = 0;
   3096        UINT vertexOffset    = 0;
   3097 
   3098        if (attribIndex < mCurrentAttributes.size())
   3099        {
   3100            const TranslatedAttribute &attrib = *mCurrentAttributes[attribIndex];
   3101            Buffer11 *bufferStorage = attrib.storage ? GetAs<Buffer11>(attrib.storage) : nullptr;
   3102 
   3103            // If indexed pointsprite emulation is active, then we need to take a less efficent code
   3104            // path. Emulated indexed pointsprite rendering requires that the vertex buffers match
   3105            // exactly to the indices passed by the caller.  This could expand or shrink the vertex
   3106            // buffer depending on the number of points indicated by the index list or how many
   3107            // duplicates are found on the index list.
   3108            if (bufferStorage == nullptr)
   3109            {
   3110                ASSERT(attrib.vertexBuffer.get());
   3111                buffer = GetAs<VertexBuffer11>(attrib.vertexBuffer.get())->getBuffer().get();
   3112            }
   3113            else if (instancedPointSpritesActive &&
   3114                     indexTypeOrInvalid != gl::DrawElementsType::InvalidEnum)
   3115            {
   3116                ASSERT(mVertexArray11->isCachedIndexInfoValid());
   3117                TranslatedIndexData indexInfo = mVertexArray11->getCachedIndexInfo();
   3118                if (indexInfo.srcIndexData.srcBuffer != nullptr)
   3119                {
   3120                    const uint8_t *bufferData = nullptr;
   3121                    ANGLE_TRY(indexInfo.srcIndexData.srcBuffer->getData(context, &bufferData));
   3122                    ASSERT(bufferData != nullptr);
   3123 
   3124                    ptrdiff_t offset =
   3125                        reinterpret_cast<ptrdiff_t>(indexInfo.srcIndexData.srcIndices);
   3126                    indexInfo.srcIndexData.srcBuffer  = nullptr;
   3127                    indexInfo.srcIndexData.srcIndices = bufferData + offset;
   3128                }
   3129 
   3130                ANGLE_TRY(bufferStorage->getEmulatedIndexedBuffer(context, &indexInfo.srcIndexData,
   3131                                                                  attrib, firstVertex, &buffer));
   3132 
   3133                mVertexArray11->updateCachedIndexInfo(indexInfo);
   3134            }
   3135            else
   3136            {
   3137                ANGLE_TRY(bufferStorage->getBuffer(
   3138                    context, BUFFER_USAGE_VERTEX_OR_TRANSFORM_FEEDBACK, &buffer));
   3139            }
   3140 
   3141            vertexStride = attrib.stride;
   3142            ANGLE_TRY(attrib.computeOffset(context, firstVertex, &vertexOffset));
   3143        }
   3144 
   3145        size_t bufferIndex = reservedBuffers + attribIndex;
   3146 
   3147        queueVertexBufferChange(bufferIndex, buffer, vertexStride, vertexOffset);
   3148    }
   3149 
   3150    Context11 *context11 = GetImplAs<Context11>(context);
   3151 
   3152    // Instanced PointSprite emulation requires two additional ID3D11Buffers. A vertex buffer needs
   3153    // to be created and added to the list of current buffers, strides and offsets collections.
   3154    // This buffer contains the vertices for a single PointSprite quad.
   3155    // An index buffer also needs to be created and applied because rendering instanced data on
   3156    // D3D11 FL9_3 requires DrawIndexedInstanced() to be used. Shaders that contain gl_PointSize and
   3157    // used without the GL_POINTS rendering mode require a vertex buffer because some drivers cannot
   3158    // handle missing vertex data and will TDR the system.
   3159    if (programUsesInstancedPointSprites)
   3160    {
   3161        constexpr UINT kPointSpriteVertexStride = sizeof(float) * 5;
   3162 
   3163        if (!mPointSpriteVertexBuffer.valid())
   3164        {
   3165            static constexpr float kPointSpriteVertices[] = {
   3166                // Position        | TexCoord
   3167                -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, /* v0 */
   3168                -1.0f, 1.0f,  0.0f, 0.0f, 0.0f, /* v1 */
   3169                1.0f,  1.0f,  0.0f, 1.0f, 0.0f, /* v2 */
   3170                1.0f,  -1.0f, 0.0f, 1.0f, 1.0f, /* v3 */
   3171                -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, /* v4 */
   3172                1.0f,  1.0f,  0.0f, 1.0f, 0.0f, /* v5 */
   3173            };
   3174 
   3175            D3D11_SUBRESOURCE_DATA vertexBufferData = {kPointSpriteVertices, 0, 0};
   3176            D3D11_BUFFER_DESC vertexBufferDesc;
   3177            vertexBufferDesc.ByteWidth           = sizeof(kPointSpriteVertices);
   3178            vertexBufferDesc.BindFlags           = D3D11_BIND_VERTEX_BUFFER;
   3179            vertexBufferDesc.Usage               = D3D11_USAGE_IMMUTABLE;
   3180            vertexBufferDesc.CPUAccessFlags      = 0;
   3181            vertexBufferDesc.MiscFlags           = 0;
   3182            vertexBufferDesc.StructureByteStride = 0;
   3183 
   3184            ANGLE_TRY(mRenderer->allocateResource(context11, vertexBufferDesc, &vertexBufferData,
   3185                                                  &mPointSpriteVertexBuffer));
   3186        }
   3187 
   3188        // Set the stride to 0 if GL_POINTS mode is not being used to instruct the driver to avoid
   3189        // indexing into the vertex buffer.
   3190        UINT stride = instancedPointSpritesActive ? kPointSpriteVertexStride : 0;
   3191        queueVertexBufferChange(0, mPointSpriteVertexBuffer.get(), stride, 0);
   3192 
   3193        if (!mPointSpriteIndexBuffer.valid())
   3194        {
   3195            // Create an index buffer and set it for pointsprite rendering
   3196            static constexpr unsigned short kPointSpriteIndices[] = {
   3197                0, 1, 2, 3, 4, 5,
   3198            };
   3199 
   3200            D3D11_SUBRESOURCE_DATA indexBufferData = {kPointSpriteIndices, 0, 0};
   3201            D3D11_BUFFER_DESC indexBufferDesc;
   3202            indexBufferDesc.ByteWidth           = sizeof(kPointSpriteIndices);
   3203            indexBufferDesc.BindFlags           = D3D11_BIND_INDEX_BUFFER;
   3204            indexBufferDesc.Usage               = D3D11_USAGE_IMMUTABLE;
   3205            indexBufferDesc.CPUAccessFlags      = 0;
   3206            indexBufferDesc.MiscFlags           = 0;
   3207            indexBufferDesc.StructureByteStride = 0;
   3208 
   3209            ANGLE_TRY(mRenderer->allocateResource(context11, indexBufferDesc, &indexBufferData,
   3210                                                  &mPointSpriteIndexBuffer));
   3211        }
   3212 
   3213        if (instancedPointSpritesActive)
   3214        {
   3215            // The index buffer is applied here because Instanced PointSprite emulation uses the a
   3216            // non-indexed rendering path in ANGLE (DrawArrays). This means that applyIndexBuffer()
   3217            // on the renderer will not be called and setting this buffer here ensures that the
   3218            // rendering path will contain the correct index buffers.
   3219            syncIndexBuffer(mPointSpriteIndexBuffer.get(), DXGI_FORMAT_R16_UINT, 0);
   3220        }
   3221    }
   3222 
   3223    applyVertexBufferChanges();
   3224    return angle::Result::Continue;
   3225 }
   3226 
   3227 angle::Result StateManager11::applyIndexBuffer(const gl::Context *context,
   3228                                               GLsizei indexCount,
   3229                                               gl::DrawElementsType indexType,
   3230                                               const void *indices)
   3231 {
   3232    if (!mIndexBufferIsDirty)
   3233    {
   3234        // No streaming or index buffer application necessary.
   3235        return angle::Result::Continue;
   3236    }
   3237 
   3238    gl::DrawElementsType destElementType = mVertexArray11->getCachedDestinationIndexType();
   3239    gl::Buffer *elementArrayBuffer       = mVertexArray11->getState().getElementArrayBuffer();
   3240 
   3241    TranslatedIndexData indexInfo;
   3242    ANGLE_TRY(mIndexDataManager.prepareIndexData(context, indexType, destElementType, indexCount,
   3243                                                 elementArrayBuffer, indices, &indexInfo));
   3244 
   3245    ID3D11Buffer *buffer     = nullptr;
   3246    DXGI_FORMAT bufferFormat = (indexInfo.indexType == gl::DrawElementsType::UnsignedInt)
   3247                                   ? DXGI_FORMAT_R32_UINT
   3248                                   : DXGI_FORMAT_R16_UINT;
   3249 
   3250    if (indexInfo.storage)
   3251    {
   3252        Buffer11 *storage = GetAs<Buffer11>(indexInfo.storage);
   3253        ANGLE_TRY(storage->getBuffer(context, BUFFER_USAGE_INDEX, &buffer));
   3254    }
   3255    else
   3256    {
   3257        IndexBuffer11 *indexBuffer = GetAs<IndexBuffer11>(indexInfo.indexBuffer);
   3258        buffer                     = indexBuffer->getBuffer().get();
   3259    }
   3260 
   3261    // Track dirty indices in the index range cache.
   3262    indexInfo.srcIndexData.srcIndicesChanged =
   3263        syncIndexBuffer(buffer, bufferFormat, indexInfo.startOffset);
   3264 
   3265    mIndexBufferIsDirty = false;
   3266 
   3267    mVertexArray11->updateCachedIndexInfo(indexInfo);
   3268    return angle::Result::Continue;
   3269 }
   3270 
   3271 void StateManager11::setIndexBuffer(ID3D11Buffer *buffer,
   3272                                    DXGI_FORMAT indexFormat,
   3273                                    unsigned int offset)
   3274 {
   3275    if (syncIndexBuffer(buffer, indexFormat, offset))
   3276    {
   3277        invalidateIndexBuffer();
   3278    }
   3279 }
   3280 
   3281 bool StateManager11::syncIndexBuffer(ID3D11Buffer *buffer,
   3282                                     DXGI_FORMAT indexFormat,
   3283                                     unsigned int offset)
   3284 {
   3285    if (buffer != mAppliedIB || indexFormat != mAppliedIBFormat || offset != mAppliedIBOffset)
   3286    {
   3287        mRenderer->getDeviceContext()->IASetIndexBuffer(buffer, indexFormat, offset);
   3288 
   3289        mAppliedIB       = buffer;
   3290        mAppliedIBFormat = indexFormat;
   3291        mAppliedIBOffset = offset;
   3292        return true;
   3293    }
   3294 
   3295    return false;
   3296 }
   3297 
   3298 // Vertex buffer is invalidated outside this function.
   3299 angle::Result StateManager11::updateVertexOffsetsForPointSpritesEmulation(
   3300    const gl::Context *context,
   3301    GLint startVertex,
   3302    GLsizei emulatedInstanceId)
   3303 {
   3304    size_t reservedBuffers = GetReservedBufferCount(true);
   3305    for (size_t attribIndex = 0; attribIndex < mCurrentAttributes.size(); ++attribIndex)
   3306    {
   3307        const auto &attrib = *mCurrentAttributes[attribIndex];
   3308        size_t bufferIndex = reservedBuffers + attribIndex;
   3309 
   3310        if (attrib.divisor > 0)
   3311        {
   3312            unsigned int offset = 0;
   3313            ANGLE_TRY(attrib.computeOffset(context, startVertex, &offset));
   3314            offset += (attrib.stride * (emulatedInstanceId / attrib.divisor));
   3315            if (offset != mCurrentVertexOffsets[bufferIndex])
   3316            {
   3317                invalidateInputLayout();
   3318                mDirtyVertexBufferRange.extend(static_cast<unsigned int>(bufferIndex));
   3319                mCurrentVertexOffsets[bufferIndex] = offset;
   3320            }
   3321        }
   3322    }
   3323 
   3324    applyVertexBufferChanges();
   3325    return angle::Result::Continue;
   3326 }
   3327 
   3328 angle::Result StateManager11::generateSwizzle(const gl::Context *context, gl::Texture *texture)
   3329 {
   3330    if (!texture)
   3331    {
   3332        return angle::Result::Continue;
   3333    }
   3334 
   3335    TextureD3D *textureD3D = GetImplAs<TextureD3D>(texture);
   3336    ASSERT(textureD3D);
   3337 
   3338    TextureStorage *texStorage = nullptr;
   3339    ANGLE_TRY(textureD3D->getNativeTexture(context, &texStorage));
   3340 
   3341    if (texStorage)
   3342    {
   3343        TextureStorage11 *storage11          = GetAs<TextureStorage11>(texStorage);
   3344        const gl::TextureState &textureState = texture->getTextureState();
   3345        ANGLE_TRY(storage11->generateSwizzles(context, textureState));
   3346    }
   3347 
   3348    return angle::Result::Continue;
   3349 }
   3350 
   3351 angle::Result StateManager11::generateSwizzlesForShader(const gl::Context *context,
   3352                                                        gl::ShaderType type)
   3353 {
   3354    const gl::State &glState       = context->getState();
   3355    const gl::RangeUI samplerRange = mProgramD3D->getUsedSamplerRange(type);
   3356 
   3357    for (unsigned int i = samplerRange.low(); i < samplerRange.high(); i++)
   3358    {
   3359        gl::TextureType textureType = mProgramD3D->getSamplerTextureType(type, i);
   3360        GLint textureUnit           = mProgramD3D->getSamplerMapping(type, i, context->getCaps());
   3361        if (textureUnit != -1)
   3362        {
   3363            gl::Texture *texture = glState.getSamplerTexture(textureUnit, textureType);
   3364            ASSERT(texture);
   3365            if (SwizzleRequired(texture->getTextureState()))
   3366            {
   3367                ANGLE_TRY(generateSwizzle(context, texture));
   3368            }
   3369        }
   3370    }
   3371 
   3372    return angle::Result::Continue;
   3373 }
   3374 
   3375 angle::Result StateManager11::generateSwizzles(const gl::Context *context)
   3376 {
   3377    ANGLE_TRY(generateSwizzlesForShader(context, gl::ShaderType::Vertex));
   3378    ANGLE_TRY(generateSwizzlesForShader(context, gl::ShaderType::Fragment));
   3379    return angle::Result::Continue;
   3380 }
   3381 
   3382 angle::Result StateManager11::applyUniformsForShader(const gl::Context *context,
   3383                                                     gl::ShaderType shaderType)
   3384 {
   3385    UniformStorage11 *shaderUniformStorage =
   3386        GetAs<UniformStorage11>(mProgramD3D->getShaderUniformStorage(shaderType));
   3387    ASSERT(shaderUniformStorage);
   3388 
   3389    ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
   3390 
   3391    const d3d11::Buffer *shaderConstantBuffer = nullptr;
   3392    ANGLE_TRY(shaderUniformStorage->getConstantBuffer(context, mRenderer, &shaderConstantBuffer));
   3393 
   3394    if (shaderUniformStorage->size() > 0 && mProgramD3D->areShaderUniformsDirty(shaderType))
   3395    {
   3396        UpdateUniformBuffer(deviceContext, shaderUniformStorage, shaderConstantBuffer);
   3397    }
   3398 
   3399    unsigned int slot = d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DEFAULT_UNIFORM_BLOCK;
   3400 
   3401    switch (shaderType)
   3402    {
   3403        case gl::ShaderType::Vertex:
   3404            if (mCurrentConstantBufferVS[slot] != shaderConstantBuffer->getSerial())
   3405            {
   3406                deviceContext->VSSetConstantBuffers(slot, 1, shaderConstantBuffer->getPointer());
   3407                mCurrentConstantBufferVS[slot]       = shaderConstantBuffer->getSerial();
   3408                mCurrentConstantBufferVSOffset[slot] = 0;
   3409                mCurrentConstantBufferVSSize[slot]   = 0;
   3410            }
   3411            break;
   3412 
   3413        case gl::ShaderType::Fragment:
   3414            if (mCurrentConstantBufferPS[slot] != shaderConstantBuffer->getSerial())
   3415            {
   3416                deviceContext->PSSetConstantBuffers(slot, 1, shaderConstantBuffer->getPointer());
   3417                mCurrentConstantBufferPS[slot]       = shaderConstantBuffer->getSerial();
   3418                mCurrentConstantBufferPSOffset[slot] = 0;
   3419                mCurrentConstantBufferPSSize[slot]   = 0;
   3420            }
   3421            break;
   3422 
   3423        // TODO(jiawei.shao@intel.com): apply geometry shader uniforms
   3424        case gl::ShaderType::Geometry:
   3425            UNIMPLEMENTED();
   3426            break;
   3427 
   3428        default:
   3429            UNREACHABLE();
   3430            break;
   3431    }
   3432 
   3433    return angle::Result::Continue;
   3434 }
   3435 
   3436 angle::Result StateManager11::applyUniforms(const gl::Context *context)
   3437 {
   3438    ANGLE_TRY(applyUniformsForShader(context, gl::ShaderType::Vertex));
   3439    ANGLE_TRY(applyUniformsForShader(context, gl::ShaderType::Fragment));
   3440    if (mProgramD3D->hasShaderStage(gl::ShaderType::Geometry))
   3441    {
   3442        ANGLE_TRY(applyUniformsForShader(context, gl::ShaderType::Geometry));
   3443    }
   3444 
   3445    mProgramD3D->markUniformsClean();
   3446 
   3447    return angle::Result::Continue;
   3448 }
   3449 
   3450 angle::Result StateManager11::applyDriverUniformsForShader(const gl::Context *context,
   3451                                                           gl::ShaderType shaderType)
   3452 {
   3453    ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
   3454 
   3455    d3d11::Buffer &shaderDriverConstantBuffer = mShaderDriverConstantBuffers[shaderType];
   3456    if (!shaderDriverConstantBuffer.valid())
   3457    {
   3458        size_t requiredSize = mShaderConstants.getRequiredBufferSize(shaderType);
   3459 
   3460        D3D11_BUFFER_DESC constantBufferDescription = {};
   3461        d3d11::InitConstantBufferDesc(&constantBufferDescription, requiredSize);
   3462        ANGLE_TRY(mRenderer->allocateResource(
   3463            GetImplAs<Context11>(context), constantBufferDescription, &shaderDriverConstantBuffer));
   3464 
   3465        ID3D11Buffer *driverConstants = shaderDriverConstantBuffer.get();
   3466        switch (shaderType)
   3467        {
   3468            case gl::ShaderType::Vertex:
   3469                deviceContext->VSSetConstantBuffers(d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DRIVER, 1,
   3470                                                    &driverConstants);
   3471                break;
   3472 
   3473            case gl::ShaderType::Fragment:
   3474                deviceContext->PSSetConstantBuffers(d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DRIVER, 1,
   3475                                                    &driverConstants);
   3476                break;
   3477 
   3478            case gl::ShaderType::Geometry:
   3479                deviceContext->GSSetConstantBuffers(d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DRIVER, 1,
   3480                                                    &driverConstants);
   3481                break;
   3482 
   3483            default:
   3484                UNREACHABLE();
   3485                return angle::Result::Continue;
   3486        }
   3487    }
   3488 
   3489    // Sampler metadata and driver constants need to coexist in the same constant buffer to
   3490    // conserve constant buffer slots. We update both in the constant buffer if needed.
   3491    ANGLE_TRY(mShaderConstants.updateBuffer(context, mRenderer, shaderType, *mProgramD3D,
   3492                                            shaderDriverConstantBuffer));
   3493 
   3494    return angle::Result::Continue;
   3495 }
   3496 
   3497 angle::Result StateManager11::applyDriverUniforms(const gl::Context *context)
   3498 {
   3499    ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
   3500 
   3501    ANGLE_TRY(applyDriverUniformsForShader(context, gl::ShaderType::Vertex));
   3502    ANGLE_TRY(applyDriverUniformsForShader(context, gl::ShaderType::Fragment));
   3503    if (mProgramD3D->hasShaderStage(gl::ShaderType::Geometry))
   3504    {
   3505        ANGLE_TRY(applyDriverUniformsForShader(context, gl::ShaderType::Geometry));
   3506    }
   3507 
   3508    // needed for the point sprite geometry shader
   3509    // GSSetConstantBuffers triggers device removal on 9_3, so we should only call it for ES3.
   3510    if (mRenderer->isES3Capable())
   3511    {
   3512        d3d11::Buffer &driverConstantBufferPS =
   3513            mShaderDriverConstantBuffers[gl::ShaderType::Fragment];
   3514        if (mCurrentGeometryConstantBuffer != driverConstantBufferPS.getSerial())
   3515        {
   3516            ASSERT(driverConstantBufferPS.valid());
   3517            deviceContext->GSSetConstantBuffers(0, 1, driverConstantBufferPS.getPointer());
   3518            mCurrentGeometryConstantBuffer = driverConstantBufferPS.getSerial();
   3519        }
   3520    }
   3521 
   3522    return angle::Result::Continue;
   3523 }
   3524 
   3525 angle::Result StateManager11::applyComputeUniforms(const gl::Context *context,
   3526                                                   ProgramD3D *programD3D)
   3527 {
   3528    UniformStorage11 *computeUniformStorage =
   3529        GetAs<UniformStorage11>(programD3D->getShaderUniformStorage(gl::ShaderType::Compute));
   3530    ASSERT(computeUniformStorage);
   3531 
   3532    const d3d11::Buffer *constantBuffer = nullptr;
   3533    ANGLE_TRY(computeUniformStorage->getConstantBuffer(context, mRenderer, &constantBuffer));
   3534 
   3535    ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
   3536 
   3537    if (computeUniformStorage->size() > 0 &&
   3538        programD3D->areShaderUniformsDirty(gl::ShaderType::Compute))
   3539    {
   3540        UpdateUniformBuffer(deviceContext, computeUniformStorage, constantBuffer);
   3541        programD3D->markUniformsClean();
   3542    }
   3543 
   3544    if (mCurrentComputeConstantBuffer != constantBuffer->getSerial())
   3545    {
   3546        deviceContext->CSSetConstantBuffers(
   3547            d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DEFAULT_UNIFORM_BLOCK, 1,
   3548            constantBuffer->getPointer());
   3549        mCurrentComputeConstantBuffer = constantBuffer->getSerial();
   3550    }
   3551 
   3552    if (!mShaderDriverConstantBuffers[gl::ShaderType::Compute].valid())
   3553    {
   3554        size_t requiredSize = mShaderConstants.getRequiredBufferSize(gl::ShaderType::Compute);
   3555 
   3556        D3D11_BUFFER_DESC constantBufferDescription = {};
   3557        d3d11::InitConstantBufferDesc(&constantBufferDescription, requiredSize);
   3558        ANGLE_TRY(
   3559            mRenderer->allocateResource(GetImplAs<Context11>(context), constantBufferDescription,
   3560                                        &mShaderDriverConstantBuffers[gl::ShaderType::Compute]));
   3561        ID3D11Buffer *buffer = mShaderDriverConstantBuffers[gl::ShaderType::Compute].get();
   3562        deviceContext->CSSetConstantBuffers(d3d11::RESERVED_CONSTANT_BUFFER_SLOT_DRIVER, 1,
   3563                                            &buffer);
   3564    }
   3565 
   3566    ANGLE_TRY(mShaderConstants.updateBuffer(context, mRenderer, gl::ShaderType::Compute,
   3567                                            *programD3D,
   3568                                            mShaderDriverConstantBuffers[gl::ShaderType::Compute]));
   3569 
   3570    return angle::Result::Continue;
   3571 }
   3572 
   3573 angle::Result StateManager11::syncUniformBuffersForShader(const gl::Context *context,
   3574                                                          gl::ShaderType shaderType)
   3575 {
   3576    const auto &glState                  = context->getState();
   3577    ID3D11DeviceContext *deviceContext   = mRenderer->getDeviceContext();
   3578    ID3D11DeviceContext1 *deviceContext1 = mRenderer->getDeviceContext1IfSupported();
   3579 
   3580    const auto &shaderUniformBuffers = mProgramD3D->getShaderUniformBufferCache(shaderType);
   3581 
   3582    for (size_t bufferIndex = 0; bufferIndex < shaderUniformBuffers.size(); ++bufferIndex)
   3583    {
   3584        const D3DUBOCache cache = shaderUniformBuffers[bufferIndex];
   3585        if (cache.binding == -1)
   3586        {
   3587            continue;
   3588        }
   3589 
   3590        const auto &uniformBuffer          = glState.getIndexedUniformBuffer(cache.binding);
   3591        const GLintptr uniformBufferOffset = uniformBuffer.getOffset();
   3592        const GLsizeiptr uniformBufferSize = uniformBuffer.getSize();
   3593 
   3594        if (uniformBuffer.get() == nullptr)
   3595        {
   3596            continue;
   3597        }
   3598 
   3599        Buffer11 *bufferStorage             = GetImplAs<Buffer11>(uniformBuffer.get());
   3600        const d3d11::Buffer *constantBuffer = nullptr;
   3601        UINT firstConstant                  = 0;
   3602        UINT numConstants                   = 0;
   3603 
   3604        ANGLE_TRY(bufferStorage->getConstantBufferRange(context, uniformBufferOffset,
   3605                                                        uniformBufferSize, &constantBuffer,
   3606                                                        &firstConstant, &numConstants));
   3607        ASSERT(constantBuffer);
   3608 
   3609        switch (shaderType)
   3610        {
   3611            case gl::ShaderType::Vertex:
   3612            {
   3613                if (mCurrentConstantBufferVS[cache.registerIndex] == constantBuffer->getSerial() &&
   3614                    mCurrentConstantBufferVSOffset[cache.registerIndex] == uniformBufferOffset &&
   3615                    mCurrentConstantBufferVSSize[cache.registerIndex] == uniformBufferSize)
   3616                {
   3617                    continue;
   3618                }
   3619 
   3620                if (firstConstant != 0 && uniformBufferSize != 0)
   3621                {
   3622                    ASSERT(numConstants != 0);
   3623                    deviceContext1->VSSetConstantBuffers1(cache.registerIndex, 1,
   3624                                                          constantBuffer->getPointer(),
   3625                                                          &firstConstant, &numConstants);
   3626                }
   3627                else
   3628                {
   3629                    deviceContext->VSSetConstantBuffers(cache.registerIndex, 1,
   3630                                                        constantBuffer->getPointer());
   3631                }
   3632 
   3633                mCurrentConstantBufferVS[cache.registerIndex]       = constantBuffer->getSerial();
   3634                mCurrentConstantBufferVSOffset[cache.registerIndex] = uniformBufferOffset;
   3635                mCurrentConstantBufferVSSize[cache.registerIndex]   = uniformBufferSize;
   3636                break;
   3637            }
   3638 
   3639            case gl::ShaderType::Fragment:
   3640            {
   3641                if (mCurrentConstantBufferPS[cache.registerIndex] == constantBuffer->getSerial() &&
   3642                    mCurrentConstantBufferPSOffset[cache.registerIndex] == uniformBufferOffset &&
   3643                    mCurrentConstantBufferPSSize[cache.registerIndex] == uniformBufferSize)
   3644                {
   3645                    continue;
   3646                }
   3647 
   3648                if (firstConstant != 0 && uniformBufferSize != 0)
   3649                {
   3650                    deviceContext1->PSSetConstantBuffers1(cache.registerIndex, 1,
   3651                                                          constantBuffer->getPointer(),
   3652                                                          &firstConstant, &numConstants);
   3653                }
   3654                else
   3655                {
   3656                    deviceContext->PSSetConstantBuffers(cache.registerIndex, 1,
   3657                                                        constantBuffer->getPointer());
   3658                }
   3659 
   3660                mCurrentConstantBufferPS[cache.registerIndex]       = constantBuffer->getSerial();
   3661                mCurrentConstantBufferPSOffset[cache.registerIndex] = uniformBufferOffset;
   3662                mCurrentConstantBufferPSSize[cache.registerIndex]   = uniformBufferSize;
   3663                break;
   3664            }
   3665 
   3666            case gl::ShaderType::Compute:
   3667            {
   3668                if (mCurrentConstantBufferCS[bufferIndex] == constantBuffer->getSerial() &&
   3669                    mCurrentConstantBufferCSOffset[bufferIndex] == uniformBufferOffset &&
   3670                    mCurrentConstantBufferCSSize[bufferIndex] == uniformBufferSize)
   3671                {
   3672                    continue;
   3673                }
   3674 
   3675                if (firstConstant != 0 && uniformBufferSize != 0)
   3676                {
   3677                    deviceContext1->CSSetConstantBuffers1(cache.registerIndex, 1,
   3678                                                          constantBuffer->getPointer(),
   3679                                                          &firstConstant, &numConstants);
   3680                }
   3681                else
   3682                {
   3683                    deviceContext->CSSetConstantBuffers(cache.registerIndex, 1,
   3684                                                        constantBuffer->getPointer());
   3685                }
   3686 
   3687                mCurrentConstantBufferCS[cache.registerIndex]       = constantBuffer->getSerial();
   3688                mCurrentConstantBufferCSOffset[cache.registerIndex] = uniformBufferOffset;
   3689                mCurrentConstantBufferCSSize[cache.registerIndex]   = uniformBufferSize;
   3690                break;
   3691            }
   3692 
   3693            // TODO(jiawei.shao@intel.com): update geometry shader uniform buffers.
   3694            case gl::ShaderType::Geometry:
   3695                UNIMPLEMENTED();
   3696                break;
   3697 
   3698            default:
   3699                UNREACHABLE();
   3700        }
   3701    }
   3702 
   3703    const auto &shaderUniformBuffersUseSB =
   3704        mProgramD3D->getShaderUniformBufferCacheUseSB(shaderType);
   3705    for (size_t bufferIndex = 0; bufferIndex < shaderUniformBuffersUseSB.size(); ++bufferIndex)
   3706    {
   3707        const D3DUBOCacheUseSB cache = shaderUniformBuffersUseSB[bufferIndex];
   3708        if (cache.binding == -1)
   3709        {
   3710            continue;
   3711        }
   3712 
   3713        const auto &uniformBuffer = glState.getIndexedUniformBuffer(cache.binding);
   3714        if (uniformBuffer.get() == nullptr)
   3715        {
   3716            continue;
   3717        }
   3718        const GLintptr uniformBufferOffset = uniformBuffer.getOffset();
   3719 
   3720        Buffer11 *bufferStorage                    = GetImplAs<Buffer11>(uniformBuffer.get());
   3721        const d3d11::ShaderResourceView *bufferSRV = nullptr;
   3722        ANGLE_TRY(bufferStorage->getStructuredBufferRangeSRV(
   3723            context, static_cast<unsigned int>(uniformBufferOffset), cache.byteWidth,
   3724            cache.structureByteStride, &bufferSRV));
   3725 
   3726        ASSERT(bufferSRV->valid());
   3727        setShaderResourceInternal(shaderType, cache.registerIndex, bufferSRV);
   3728    }
   3729 
   3730    return angle::Result::Continue;
   3731 }
   3732 
   3733 angle::Result StateManager11::getUAVsForShaderStorageBuffers(const gl::Context *context,
   3734                                                             gl::ShaderType shaderType,
   3735                                                             UAVList *uavList)
   3736 {
   3737    const gl::State &glState   = context->getState();
   3738    const gl::Program *program = glState.getProgram();
   3739    angle::FixedVector<Buffer11 *, gl::IMPLEMENTATION_MAX_SHADER_STORAGE_BUFFER_BINDINGS>
   3740        previouslyBound;
   3741    for (size_t blockIndex = 0; blockIndex < program->getActiveShaderStorageBlockCount();
   3742         blockIndex++)
   3743    {
   3744        GLuint binding = program->getShaderStorageBlockBinding(static_cast<GLuint>(blockIndex));
   3745        const unsigned int registerIndex = mProgramD3D->getShaderStorageBufferRegisterIndex(
   3746            static_cast<GLuint>(blockIndex), shaderType);
   3747        // It means this block is active but not statically used.
   3748        if (registerIndex == GL_INVALID_INDEX)
   3749        {
   3750            continue;
   3751        }
   3752        const auto &shaderStorageBuffer = glState.getIndexedShaderStorageBuffer(binding);
   3753        if (shaderStorageBuffer.get() == nullptr)
   3754        {
   3755            // We didn't see a driver error like atomic buffer did. But theoretically, the same
   3756            // thing should be done.
   3757            setUnorderedAccessViewInternal<d3d11::UnorderedAccessView>(registerIndex, nullptr,
   3758                                                                       uavList);
   3759            continue;
   3760        }
   3761 
   3762        Buffer11 *bufferStorage = GetImplAs<Buffer11>(shaderStorageBuffer.get());
   3763        if (std::find(previouslyBound.begin(), previouslyBound.end(), bufferStorage) !=
   3764            previouslyBound.end())
   3765        {
   3766            // D3D11 doesn't support binding a buffer multiple times
   3767            // http://anglebug.com/3032
   3768            ERR() << "Writing to multiple blocks on the same buffer is not allowed.";
   3769            return angle::Result::Stop;
   3770        }
   3771        previouslyBound.push_back(bufferStorage);
   3772 
   3773        d3d11::UnorderedAccessView *uavPtr = nullptr;
   3774        GLsizeiptr viewSize                = 0;
   3775        // Bindings only have a valid size if bound using glBindBufferRange
   3776        if (shaderStorageBuffer.getSize() > 0)
   3777        {
   3778            viewSize = shaderStorageBuffer.getSize();
   3779        }
   3780        // We use the buffer size for glBindBufferBase
   3781        else
   3782        {
   3783            viewSize = bufferStorage->getSize();
   3784        }
   3785        ANGLE_TRY(bufferStorage->getRawUAVRange(context, shaderStorageBuffer.getOffset(), viewSize,
   3786                                                &uavPtr));
   3787 
   3788        setUnorderedAccessViewInternal(registerIndex, uavPtr, uavList);
   3789    }
   3790 
   3791    return angle::Result::Continue;
   3792 }
   3793 
   3794 angle::Result StateManager11::syncUniformBuffers(const gl::Context *context)
   3795 {
   3796    mProgramD3D->updateUniformBufferCache(context->getCaps());
   3797 
   3798    if (mProgramD3D->hasShaderStage(gl::ShaderType::Compute))
   3799    {
   3800        ANGLE_TRY(syncUniformBuffersForShader(context, gl::ShaderType::Compute));
   3801    }
   3802    else
   3803    {
   3804        ANGLE_TRY(syncUniformBuffersForShader(context, gl::ShaderType::Vertex));
   3805        ANGLE_TRY(syncUniformBuffersForShader(context, gl::ShaderType::Fragment));
   3806        if (mProgramD3D->hasShaderStage(gl::ShaderType::Geometry))
   3807        {
   3808            ANGLE_TRY(syncUniformBuffersForShader(context, gl::ShaderType::Geometry));
   3809        }
   3810    }
   3811 
   3812    return angle::Result::Continue;
   3813 }
   3814 
   3815 angle::Result StateManager11::getUAVsForAtomicCounterBuffers(const gl::Context *context,
   3816                                                             gl::ShaderType shaderType,
   3817                                                             UAVList *uavList)
   3818 {
   3819    const gl::State &glState   = context->getState();
   3820    const gl::Program *program = glState.getProgram();
   3821    for (const auto &atomicCounterBuffer : program->getState().getAtomicCounterBuffers())
   3822    {
   3823        GLuint binding     = atomicCounterBuffer.binding;
   3824        const auto &buffer = glState.getIndexedAtomicCounterBuffer(binding);
   3825        const unsigned int registerIndex =
   3826            mProgramD3D->getAtomicCounterBufferRegisterIndex(binding, shaderType);
   3827        ASSERT(registerIndex != GL_INVALID_INDEX);
   3828        if (buffer.get() == nullptr)
   3829        {
   3830            // The atomic counter is used in shader. However, there is no buffer binding to it. We
   3831            // should clear the corresponding UAV in case the previous view type is a texture not a
   3832            // buffer. Otherwise, below error will be reported. The Unordered Access View dimension
   3833            // declared in the shader code (BUFFER) does not match the view type bound to slot 0
   3834            // of the Compute Shader unit (TEXTURE2D).
   3835            setUnorderedAccessViewInternal<d3d11::UnorderedAccessView>(registerIndex, nullptr,
   3836                                                                       uavList);
   3837            continue;
   3838        }
   3839 
   3840        Buffer11 *bufferStorage = GetImplAs<Buffer11>(buffer.get());
   3841        // TODO(enrico.galli@intel.com): Check to make sure that we aren't binding the same buffer
   3842        // multiple times, as this is unsupported by D3D11. http://anglebug.com/3141
   3843 
   3844        // Bindings only have a valid size if bound using glBindBufferRange. Therefore, we use the
   3845        // buffer size for glBindBufferBase
   3846        GLsizeiptr viewSize = (buffer.getSize() > 0) ? buffer.getSize() : bufferStorage->getSize();
   3847        d3d11::UnorderedAccessView *uavPtr = nullptr;
   3848        ANGLE_TRY(bufferStorage->getRawUAVRange(context, buffer.getOffset(), viewSize, &uavPtr));
   3849 
   3850        setUnorderedAccessViewInternal(registerIndex, uavPtr, uavList);
   3851    }
   3852 
   3853    return angle::Result::Continue;
   3854 }
   3855 
   3856 angle::Result StateManager11::getUAVsForShader(const gl::Context *context,
   3857                                               gl::ShaderType shaderType,
   3858                                               UAVList *uavList)
   3859 {
   3860    ANGLE_TRY(getUAVsForShaderStorageBuffers(context, shaderType, uavList));
   3861    ANGLE_TRY(getUAVsForRWImages(context, shaderType, uavList));
   3862    ANGLE_TRY(getUAVsForAtomicCounterBuffers(context, shaderType, uavList));
   3863 
   3864    return angle::Result::Continue;
   3865 }
   3866 
   3867 angle::Result StateManager11::syncUAVsForGraphics(const gl::Context *context)
   3868 {
   3869    UAVList uavList(mRenderer->getNativeCaps().maxImageUnits);
   3870 
   3871    ANGLE_TRY(getUAVsForShader(context, gl::ShaderType::Fragment, &uavList));
   3872    ANGLE_TRY(getUAVsForShader(context, gl::ShaderType::Vertex, &uavList));
   3873 
   3874    if (uavList.highestUsed >= 0)
   3875    {
   3876        ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
   3877        UINT baseUAVRegister = static_cast<UINT>(mProgramD3D->getPixelShaderKey().size());
   3878        deviceContext->OMSetRenderTargetsAndUnorderedAccessViews(
   3879            D3D11_KEEP_RENDER_TARGETS_AND_DEPTH_STENCIL, nullptr, nullptr, baseUAVRegister,
   3880            uavList.highestUsed + 1, uavList.data.data(), nullptr);
   3881    }
   3882 
   3883    return angle::Result::Continue;
   3884 }
   3885 
   3886 angle::Result StateManager11::syncUAVsForCompute(const gl::Context *context)
   3887 {
   3888    UAVList uavList(mRenderer->getNativeCaps().maxImageUnits);
   3889 
   3890    ANGLE_TRY(getUAVsForShader(context, gl::ShaderType::Compute, &uavList));
   3891 
   3892    if (uavList.highestUsed >= 0)
   3893    {
   3894        ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
   3895        deviceContext->CSSetUnorderedAccessViews(0, uavList.highestUsed + 1, uavList.data.data(),
   3896                                                 nullptr);
   3897    }
   3898 
   3899    return angle::Result::Continue;
   3900 }
   3901 
   3902 angle::Result StateManager11::syncTransformFeedbackBuffers(const gl::Context *context)
   3903 {
   3904    const auto &glState = context->getState();
   3905 
   3906    ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
   3907 
   3908    // If transform feedback is not active, unbind all buffers
   3909    if (!glState.isTransformFeedbackActiveUnpaused())
   3910    {
   3911        if (mAppliedTFSerial != mEmptySerial)
   3912        {
   3913            deviceContext->SOSetTargets(0, nullptr, nullptr);
   3914            mAppliedTFSerial = mEmptySerial;
   3915        }
   3916        return angle::Result::Continue;
   3917    }
   3918 
   3919    gl::TransformFeedback *transformFeedback = glState.getCurrentTransformFeedback();
   3920    TransformFeedback11 *tf11                = GetImplAs<TransformFeedback11>(transformFeedback);
   3921    if (mAppliedTFSerial == tf11->getSerial() && !tf11->isDirty())
   3922    {
   3923        return angle::Result::Continue;
   3924    }
   3925 
   3926    const std::vector<ID3D11Buffer *> *soBuffers = nullptr;
   3927    ANGLE_TRY(tf11->getSOBuffers(context, &soBuffers));
   3928    const std::vector<UINT> &soOffsets = tf11->getSOBufferOffsets();
   3929 
   3930    deviceContext->SOSetTargets(tf11->getNumSOBuffers(), soBuffers->data(), soOffsets.data());
   3931 
   3932    mAppliedTFSerial = tf11->getSerial();
   3933    tf11->onApply();
   3934 
   3935    return angle::Result::Continue;
   3936 }
   3937 
   3938 void StateManager11::syncPrimitiveTopology(const gl::State &glState,
   3939                                           gl::PrimitiveMode currentDrawMode)
   3940 {
   3941    D3D11_PRIMITIVE_TOPOLOGY primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_UNDEFINED;
   3942    // Don't cull everything by default, this also resets if we were previously culling
   3943    mCullEverything = false;
   3944 
   3945    switch (currentDrawMode)
   3946    {
   3947        case gl::PrimitiveMode::Points:
   3948        {
   3949            bool usesPointSize = mProgramD3D->usesPointSize();
   3950 
   3951            // ProgramBinary assumes non-point rendering if gl_PointSize isn't written,
   3952            // which affects varying interpolation. Since the value of gl_PointSize is
   3953            // undefined when not written, just skip drawing to avoid unexpected results.
   3954            if (!usesPointSize && !glState.isTransformFeedbackActiveUnpaused())
   3955            {
   3956                // Notify developers of risking undefined behavior.
   3957                WARN() << "Point rendering without writing to gl_PointSize.";
   3958                mCullEverything = true;
   3959                return;
   3960            }
   3961 
   3962            // If instanced pointsprites are enabled and the shader uses gl_PointSize, the topology
   3963            // must be D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST.
   3964            if (usesPointSize && mRenderer->getFeatures().useInstancedPointSpriteEmulation.enabled)
   3965            {
   3966                primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
   3967            }
   3968            else
   3969            {
   3970                primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_POINTLIST;
   3971            }
   3972            break;
   3973        }
   3974        case gl::PrimitiveMode::Lines:
   3975            primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINELIST;
   3976            break;
   3977        case gl::PrimitiveMode::LineLoop:
   3978            primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP;
   3979            break;
   3980        case gl::PrimitiveMode::LineStrip:
   3981            primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP;
   3982            break;
   3983        case gl::PrimitiveMode::Triangles:
   3984            primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
   3985            mCullEverything   = CullsEverything(glState);
   3986            break;
   3987        case gl::PrimitiveMode::TriangleStrip:
   3988            primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP;
   3989            mCullEverything   = CullsEverything(glState);
   3990            break;
   3991        // emulate fans via rewriting index buffer
   3992        case gl::PrimitiveMode::TriangleFan:
   3993            primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST;
   3994            mCullEverything   = CullsEverything(glState);
   3995            break;
   3996        default:
   3997            UNREACHABLE();
   3998            break;
   3999    }
   4000 
   4001    setPrimitiveTopologyInternal(primitiveTopology);
   4002 }
   4003 
   4004 }  // namespace rx