tor-browser

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

TextureStorage11.cpp (176339B)


      1 //
      2 // Copyright 2012 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 // TextureStorage11.cpp: Implements the abstract rx::TextureStorage11 class and its concrete derived
      8 // classes TextureStorage11_2D and TextureStorage11_Cube, which act as the interface to the D3D11
      9 // texture.
     10 
     11 #include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h"
     12 
     13 #include <tuple>
     14 
     15 #include "common/MemoryBuffer.h"
     16 #include "common/utilities.h"
     17 #include "libANGLE/Context.h"
     18 #include "libANGLE/ImageIndex.h"
     19 #include "libANGLE/formatutils.h"
     20 #include "libANGLE/renderer/d3d/EGLImageD3D.h"
     21 #include "libANGLE/renderer/d3d/TextureD3D.h"
     22 #include "libANGLE/renderer/d3d/d3d11/Blit11.h"
     23 #include "libANGLE/renderer/d3d/d3d11/Buffer11.h"
     24 #include "libANGLE/renderer/d3d/d3d11/Context11.h"
     25 #include "libANGLE/renderer/d3d/d3d11/Image11.h"
     26 #include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
     27 #include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
     28 #include "libANGLE/renderer/d3d/d3d11/StreamProducerD3DTexture.h"
     29 #include "libANGLE/renderer/d3d/d3d11/SwapChain11.h"
     30 #include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
     31 #include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
     32 #include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"
     33 
     34 namespace rx
     35 {
     36 TextureStorage11::SamplerKey::SamplerKey()
     37    : baseLevel(0), mipLevels(0), swizzle(false), dropStencil(false)
     38 {}
     39 
     40 TextureStorage11::SamplerKey::SamplerKey(int baseLevel,
     41                                         int mipLevels,
     42                                         bool swizzle,
     43                                         bool dropStencil)
     44    : baseLevel(baseLevel), mipLevels(mipLevels), swizzle(swizzle), dropStencil(dropStencil)
     45 {}
     46 
     47 bool TextureStorage11::SamplerKey::operator<(const SamplerKey &rhs) const
     48 {
     49    return std::tie(baseLevel, mipLevels, swizzle, dropStencil) <
     50           std::tie(rhs.baseLevel, rhs.mipLevels, rhs.swizzle, rhs.dropStencil);
     51 }
     52 
     53 TextureStorage11::ImageKey::ImageKey()
     54    : level(0), layered(false), layer(0), access(GL_READ_ONLY), format(GL_R32UI)
     55 {}
     56 
     57 TextureStorage11::ImageKey::ImageKey(int level,
     58                                     bool layered,
     59                                     int layer,
     60                                     GLenum access,
     61                                     GLenum format)
     62    : level(level), layered(layered), layer(layer), access(access), format(format)
     63 {}
     64 
     65 bool TextureStorage11::ImageKey::operator<(const ImageKey &rhs) const
     66 {
     67    return std::tie(level, layered, layer, access, format) <
     68           std::tie(rhs.level, rhs.layered, rhs.layer, rhs.access, rhs.format);
     69 }
     70 
     71 MultisampledRenderToTextureInfo::MultisampledRenderToTextureInfo(const GLsizei samples,
     72                                                                 const gl::ImageIndex &indexSS,
     73                                                                 const gl::ImageIndex &indexMS)
     74    : samples(samples), indexSS(indexSS), indexMS(indexMS), msTextureNeedsResolve(false)
     75 {}
     76 
     77 MultisampledRenderToTextureInfo::~MultisampledRenderToTextureInfo() {}
     78 
     79 TextureStorage11::TextureStorage11(Renderer11 *renderer,
     80                                   UINT bindFlags,
     81                                   UINT miscFlags,
     82                                   GLenum internalFormat,
     83                                   const std::string &label)
     84    : TextureStorage(label),
     85      mRenderer(renderer),
     86      mTopLevel(0),
     87      mMipLevels(0),
     88      mFormatInfo(d3d11::Format::Get(internalFormat, mRenderer->getRenderer11DeviceCaps())),
     89      mTextureWidth(0),
     90      mTextureHeight(0),
     91      mTextureDepth(0),
     92      mDropStencilTexture(),
     93      mBindFlags(bindFlags),
     94      mMiscFlags(miscFlags)
     95 {}
     96 
     97 TextureStorage11::~TextureStorage11()
     98 {
     99    mSrvCacheForSampler.clear();
    100 }
    101 
    102 DWORD TextureStorage11::GetTextureBindFlags(GLenum internalFormat,
    103                                            const Renderer11DeviceCaps &renderer11DeviceCaps,
    104                                            BindFlags flags)
    105 {
    106    UINT bindFlags = 0;
    107 
    108    const d3d11::Format &formatInfo = d3d11::Format::Get(internalFormat, renderer11DeviceCaps);
    109    if (formatInfo.srvFormat != DXGI_FORMAT_UNKNOWN)
    110    {
    111        bindFlags |= D3D11_BIND_SHADER_RESOURCE;
    112    }
    113    if (formatInfo.uavFormat != DXGI_FORMAT_UNKNOWN && flags.unorderedAccess)
    114    {
    115        bindFlags |= D3D11_BIND_UNORDERED_ACCESS;
    116    }
    117    if (formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN)
    118    {
    119        bindFlags |= D3D11_BIND_DEPTH_STENCIL;
    120    }
    121    if (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN && flags.renderTarget)
    122    {
    123        bindFlags |= D3D11_BIND_RENDER_TARGET;
    124    }
    125 
    126    return bindFlags;
    127 }
    128 
    129 DWORD TextureStorage11::GetTextureMiscFlags(GLenum internalFormat,
    130                                            const Renderer11DeviceCaps &renderer11DeviceCaps,
    131                                            BindFlags bindFlags,
    132                                            int levels)
    133 {
    134    UINT miscFlags = 0;
    135 
    136    const d3d11::Format &formatInfo = d3d11::Format::Get(internalFormat, renderer11DeviceCaps);
    137    if (bindFlags.renderTarget)
    138    {
    139        if (d3d11::SupportsMipGen(formatInfo.texFormat, renderer11DeviceCaps.featureLevel))
    140        {
    141            miscFlags |= D3D11_RESOURCE_MISC_GENERATE_MIPS;
    142        }
    143    }
    144 
    145    return miscFlags;
    146 }
    147 
    148 UINT TextureStorage11::getBindFlags() const
    149 {
    150    return mBindFlags;
    151 }
    152 
    153 UINT TextureStorage11::getMiscFlags() const
    154 {
    155    return mMiscFlags;
    156 }
    157 
    158 int TextureStorage11::getTopLevel() const
    159 {
    160    // Applying top level is meant to be encapsulated inside TextureStorage11.
    161    UNREACHABLE();
    162    return mTopLevel;
    163 }
    164 
    165 bool TextureStorage11::isRenderTarget() const
    166 {
    167    return (mBindFlags & (D3D11_BIND_RENDER_TARGET | D3D11_BIND_DEPTH_STENCIL)) != 0;
    168 }
    169 
    170 bool TextureStorage11::isManaged() const
    171 {
    172    return false;
    173 }
    174 
    175 bool TextureStorage11::supportsNativeMipmapFunction() const
    176 {
    177    return (mMiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS) != 0;
    178 }
    179 
    180 int TextureStorage11::getLevelCount() const
    181 {
    182    return mMipLevels - mTopLevel;
    183 }
    184 
    185 int TextureStorage11::getLevelWidth(int mipLevel) const
    186 {
    187    return std::max(static_cast<int>(mTextureWidth) >> mipLevel, 1);
    188 }
    189 
    190 int TextureStorage11::getLevelHeight(int mipLevel) const
    191 {
    192    return std::max(static_cast<int>(mTextureHeight) >> mipLevel, 1);
    193 }
    194 
    195 int TextureStorage11::getLevelDepth(int mipLevel) const
    196 {
    197    return std::max(static_cast<int>(mTextureDepth) >> mipLevel, 1);
    198 }
    199 
    200 angle::Result TextureStorage11::getMippedResource(const gl::Context *context,
    201                                                  const TextureHelper11 **outResource)
    202 {
    203    return getResource(context, outResource);
    204 }
    205 
    206 angle::Result TextureStorage11::getSubresourceIndex(const gl::Context *context,
    207                                                    const gl::ImageIndex &index,
    208                                                    UINT *outSubresourceIndex) const
    209 {
    210    UINT mipSlice    = static_cast<UINT>(index.getLevelIndex() + mTopLevel);
    211    UINT arraySlice  = static_cast<UINT>(index.hasLayer() ? index.getLayerIndex() : 0);
    212    UINT subresource = D3D11CalcSubresource(mipSlice, arraySlice, mMipLevels);
    213    ASSERT(subresource != std::numeric_limits<UINT>::max());
    214    *outSubresourceIndex = subresource;
    215    return angle::Result::Continue;
    216 }
    217 
    218 angle::Result TextureStorage11::getSRVForSampler(const gl::Context *context,
    219                                                 const gl::TextureState &textureState,
    220                                                 const gl::SamplerState &sampler,
    221                                                 const d3d11::SharedSRV **outSRV)
    222 {
    223    ANGLE_TRY(resolveTexture(context));
    224    // Make sure to add the level offset for our tiny compressed texture workaround
    225    const GLuint effectiveBaseLevel = textureState.getEffectiveBaseLevel();
    226    const bool swizzleRequired      = SwizzleRequired(textureState);
    227    const bool mipmapping           = gl::IsMipmapFiltered(sampler.getMinFilter());
    228    unsigned int mipLevels =
    229        mipmapping ? (textureState.getEffectiveMaxLevel() - effectiveBaseLevel + 1) : 1;
    230 
    231    // Make sure there's 'mipLevels' mipmap levels below the base level (offset by the top level,
    232    // which corresponds to GL level 0)
    233    mipLevels = std::min(mipLevels, mMipLevels - mTopLevel - effectiveBaseLevel);
    234 
    235    if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3)
    236    {
    237        ASSERT(!swizzleRequired);
    238        ASSERT(mipLevels == 1 || mipLevels == mMipLevels);
    239    }
    240 
    241    if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
    242    {
    243        // We must ensure that the level zero texture is in sync with mipped texture.
    244        ANGLE_TRY(useLevelZeroWorkaroundTexture(context, mipLevels == 1));
    245    }
    246 
    247    if (swizzleRequired)
    248    {
    249        verifySwizzleExists(GetEffectiveSwizzle(textureState));
    250    }
    251 
    252    // We drop the stencil when sampling from the SRV if three conditions hold:
    253    // 1. the drop stencil workaround is enabled.
    254    const bool emulateTinyStencilTextures =
    255        mRenderer->getFeatures().emulateTinyStencilTextures.enabled;
    256    // 2. this is a stencil texture.
    257    const bool hasStencil = (mFormatInfo.format().stencilBits > 0);
    258    // 3. the texture has a 1x1 or 2x2 mip.
    259    const int effectiveTopLevel = effectiveBaseLevel + mipLevels - 1;
    260    const bool hasSmallMips =
    261        (getLevelWidth(effectiveTopLevel) <= 2 || getLevelHeight(effectiveTopLevel) <= 2);
    262 
    263    const bool useDropStencil = (emulateTinyStencilTextures && hasStencil && hasSmallMips);
    264    const SamplerKey key(effectiveBaseLevel, mipLevels, swizzleRequired, useDropStencil);
    265    if (useDropStencil)
    266    {
    267        // Ensure drop texture gets created.
    268        DropStencil result = DropStencil::CREATED;
    269        ANGLE_TRY(ensureDropStencilTexture(context, &result));
    270 
    271        // Clear the SRV cache if necessary.
    272        // TODO(jmadill): Re-use find query result.
    273        const auto srvEntry = mSrvCacheForSampler.find(key);
    274        if (result == DropStencil::CREATED && srvEntry != mSrvCacheForSampler.end())
    275        {
    276            mSrvCacheForSampler.erase(key);
    277        }
    278    }
    279 
    280    ANGLE_TRY(getCachedOrCreateSRVForSampler(context, key, outSRV));
    281 
    282    return angle::Result::Continue;
    283 }
    284 
    285 angle::Result TextureStorage11::getCachedOrCreateSRVForSampler(const gl::Context *context,
    286                                                               const SamplerKey &key,
    287                                                               const d3d11::SharedSRV **outSRV)
    288 {
    289    auto iter = mSrvCacheForSampler.find(key);
    290    if (iter != mSrvCacheForSampler.end())
    291    {
    292        *outSRV = &iter->second;
    293        return angle::Result::Continue;
    294    }
    295 
    296    const TextureHelper11 *texture = nullptr;
    297    DXGI_FORMAT format             = DXGI_FORMAT_UNKNOWN;
    298 
    299    if (key.swizzle)
    300    {
    301        const auto &swizzleFormat =
    302            mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps());
    303        ASSERT(!key.dropStencil || swizzleFormat.format().stencilBits == 0);
    304        ANGLE_TRY(getSwizzleTexture(context, &texture));
    305        format = swizzleFormat.srvFormat;
    306    }
    307    else if (key.dropStencil)
    308    {
    309        ASSERT(mDropStencilTexture.valid());
    310        texture = &mDropStencilTexture;
    311        format  = DXGI_FORMAT_R32_FLOAT;
    312    }
    313    else
    314    {
    315        ANGLE_TRY(getResource(context, &texture));
    316        format = mFormatInfo.srvFormat;
    317    }
    318 
    319    d3d11::SharedSRV srv;
    320 
    321    ANGLE_TRY(createSRVForSampler(context, key.baseLevel, key.mipLevels, format, *texture, &srv));
    322 
    323    const auto &insertIt = mSrvCacheForSampler.insert(std::make_pair(key, std::move(srv)));
    324    *outSRV              = &insertIt.first->second;
    325 
    326    return angle::Result::Continue;
    327 }
    328 
    329 angle::Result TextureStorage11::getSRVLevel(const gl::Context *context,
    330                                            int mipLevel,
    331                                            SRVType srvType,
    332                                            const d3d11::SharedSRV **outSRV)
    333 {
    334    ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
    335 
    336    ANGLE_TRY(resolveTexture(context));
    337    if (srvType == SRVType::Stencil)
    338    {
    339        if (!mLevelStencilSRVs[mipLevel].valid())
    340        {
    341            const TextureHelper11 *resource = nullptr;
    342            ANGLE_TRY(getResource(context, &resource));
    343 
    344            ANGLE_TRY(createSRVForSampler(context, mipLevel, 1, mFormatInfo.stencilSRVFormat,
    345                                          *resource, &mLevelStencilSRVs[mipLevel]));
    346        }
    347        *outSRV = &mLevelStencilSRVs[mipLevel];
    348        return angle::Result::Continue;
    349    }
    350 
    351    auto &levelSRVs      = srvType == SRVType::Blit ? mLevelBlitSRVs : mLevelSRVs;
    352    auto &otherLevelSRVs = srvType == SRVType::Blit ? mLevelSRVs : mLevelBlitSRVs;
    353 
    354    if (!levelSRVs[mipLevel].valid())
    355    {
    356        // Only create a different SRV for blit if blit format is different from regular srv format
    357        if (otherLevelSRVs[mipLevel].valid() && mFormatInfo.srvFormat == mFormatInfo.blitSRVFormat)
    358        {
    359            levelSRVs[mipLevel] = otherLevelSRVs[mipLevel].makeCopy();
    360        }
    361        else
    362        {
    363            const TextureHelper11 *resource = nullptr;
    364            ANGLE_TRY(getResource(context, &resource));
    365 
    366            DXGI_FORMAT resourceFormat =
    367                srvType == SRVType::Blit ? mFormatInfo.blitSRVFormat : mFormatInfo.srvFormat;
    368            ANGLE_TRY(createSRVForSampler(context, mipLevel, 1, resourceFormat, *resource,
    369                                          &levelSRVs[mipLevel]));
    370        }
    371    }
    372 
    373    *outSRV = &levelSRVs[mipLevel];
    374    return angle::Result::Continue;
    375 }
    376 
    377 angle::Result TextureStorage11::getSRVLevels(const gl::Context *context,
    378                                             GLint baseLevel,
    379                                             GLint maxLevel,
    380                                             const d3d11::SharedSRV **outSRV)
    381 {
    382    ANGLE_TRY(resolveTexture(context));
    383    unsigned int mipLevels = maxLevel - baseLevel + 1;
    384 
    385    // Make sure there's 'mipLevels' mipmap levels below the base level (offset by the top level,
    386    // which corresponds to GL level 0)
    387    mipLevels = std::min(mipLevels, mMipLevels - mTopLevel - baseLevel);
    388 
    389    if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3)
    390    {
    391        ASSERT(mipLevels == 1 || mipLevels == mMipLevels);
    392    }
    393 
    394    if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
    395    {
    396        // We must ensure that the level zero texture is in sync with mipped texture.
    397        ANGLE_TRY(useLevelZeroWorkaroundTexture(context, mipLevels == 1));
    398    }
    399 
    400    // TODO(jmadill): Assert we don't need to drop stencil.
    401 
    402    SamplerKey key(baseLevel, mipLevels, false, false);
    403    ANGLE_TRY(getCachedOrCreateSRVForSampler(context, key, outSRV));
    404 
    405    return angle::Result::Continue;
    406 }
    407 
    408 angle::Result TextureStorage11::getSRVForImage(const gl::Context *context,
    409                                               const gl::ImageUnit &imageUnit,
    410                                               const d3d11::SharedSRV **outSRV)
    411 {
    412    ANGLE_TRY(resolveTexture(context));
    413    // TODO(Xinghua.cao@intel.com): Add solution to handle swizzle required.
    414    ImageKey key(imageUnit.level, (imageUnit.layered == GL_TRUE), imageUnit.layer, imageUnit.access,
    415                 imageUnit.format);
    416    ANGLE_TRY(getCachedOrCreateSRVForImage(context, key, outSRV));
    417    return angle::Result::Continue;
    418 }
    419 
    420 angle::Result TextureStorage11::getCachedOrCreateSRVForImage(const gl::Context *context,
    421                                                             const ImageKey &key,
    422                                                             const d3d11::SharedSRV **outSRV)
    423 {
    424    auto iter = mSrvCacheForImage.find(key);
    425    if (iter != mSrvCacheForImage.end())
    426    {
    427        *outSRV = &iter->second;
    428        return angle::Result::Continue;
    429    }
    430    const TextureHelper11 *texture = nullptr;
    431    ANGLE_TRY(getResource(context, &texture));
    432    DXGI_FORMAT format =
    433        d3d11::Format::Get(key.format, mRenderer->getRenderer11DeviceCaps()).srvFormat;
    434    d3d11::SharedSRV srv;
    435    ANGLE_TRY(createSRVForImage(context, key.level, format, *texture, &srv));
    436    const auto &insertIt = mSrvCacheForImage.insert(std::make_pair(key, std::move(srv)));
    437    *outSRV              = &insertIt.first->second;
    438    return angle::Result::Continue;
    439 }
    440 
    441 angle::Result TextureStorage11::getUAVForImage(const gl::Context *context,
    442                                               const gl::ImageUnit &imageUnit,
    443                                               const d3d11::SharedUAV **outUAV)
    444 {
    445    ANGLE_TRY(resolveTexture(context));
    446    // TODO(Xinghua.cao@intel.com): Add solution to handle swizzle required.
    447    ImageKey key(imageUnit.level, (imageUnit.layered == GL_TRUE), imageUnit.layer, imageUnit.access,
    448                 imageUnit.format);
    449    ANGLE_TRY(getCachedOrCreateUAVForImage(context, key, outUAV));
    450    return angle::Result::Continue;
    451 }
    452 
    453 angle::Result TextureStorage11::getCachedOrCreateUAVForImage(const gl::Context *context,
    454                                                             const ImageKey &key,
    455                                                             const d3d11::SharedUAV **outUAV)
    456 {
    457    auto iter = mUavCacheForImage.find(key);
    458    if (iter != mUavCacheForImage.end())
    459    {
    460        *outUAV = &iter->second;
    461        return angle::Result::Continue;
    462    }
    463    const TextureHelper11 *texture = nullptr;
    464    ANGLE_TRY(getResource(context, &texture));
    465    DXGI_FORMAT format =
    466        d3d11::Format::Get(key.format, mRenderer->getRenderer11DeviceCaps()).uavFormat;
    467    ASSERT(format != DXGI_FORMAT_UNKNOWN);
    468    d3d11::SharedUAV uav;
    469    ANGLE_TRY(createUAVForImage(context, key.level, format, *texture, &uav));
    470    const auto &insertIt = mUavCacheForImage.insert(std::make_pair(key, std::move(uav)));
    471    *outUAV              = &insertIt.first->second;
    472    return angle::Result::Continue;
    473 }
    474 
    475 const d3d11::Format &TextureStorage11::getFormatSet() const
    476 {
    477    return mFormatInfo;
    478 }
    479 
    480 angle::Result TextureStorage11::generateSwizzles(const gl::Context *context,
    481                                                 const gl::TextureState &textureState)
    482 {
    483    ANGLE_TRY(resolveTexture(context));
    484    gl::SwizzleState swizzleTarget = GetEffectiveSwizzle(textureState);
    485    for (int level = 0; level < getLevelCount(); level++)
    486    {
    487        // Check if the swizzle for this level is out of date
    488        if (mSwizzleCache[level] != swizzleTarget)
    489        {
    490            // Need to re-render the swizzle for this level
    491            const d3d11::SharedSRV *sourceSRV = nullptr;
    492            ANGLE_TRY(getSRVLevel(context, level,
    493                                  textureState.isStencilMode() ? SRVType::Stencil : SRVType::Blit,
    494                                  &sourceSRV));
    495 
    496            const d3d11::RenderTargetView *destRTV;
    497            ANGLE_TRY(getSwizzleRenderTarget(context, level, &destRTV));
    498 
    499            gl::Extents size(getLevelWidth(level), getLevelHeight(level), getLevelDepth(level));
    500 
    501            Blit11 *blitter = mRenderer->getBlitter();
    502 
    503            ANGLE_TRY(blitter->swizzleTexture(context, *sourceSRV, *destRTV, size, swizzleTarget));
    504 
    505            mSwizzleCache[level] = swizzleTarget;
    506        }
    507    }
    508 
    509    return angle::Result::Continue;
    510 }
    511 
    512 void TextureStorage11::markLevelDirty(int mipLevel)
    513 {
    514    if (mipLevel >= 0 && static_cast<size_t>(mipLevel) < mSwizzleCache.size())
    515    {
    516        // The default constructor of SwizzleState has GL_INVALID_INDEX for all channels which is
    517        // not a valid swizzle combination
    518        if (mSwizzleCache[mipLevel] != gl::SwizzleState())
    519        {
    520            // TODO(jmadill): Invalidate specific swizzle.
    521            mRenderer->getStateManager()->invalidateSwizzles();
    522            mSwizzleCache[mipLevel] = gl::SwizzleState();
    523        }
    524    }
    525 
    526    if (mDropStencilTexture.valid())
    527    {
    528        mDropStencilTexture.reset();
    529    }
    530 }
    531 
    532 void TextureStorage11::markDirty()
    533 {
    534    for (size_t mipLevel = 0; mipLevel < mSwizzleCache.size(); ++mipLevel)
    535    {
    536        markLevelDirty(static_cast<int>(mipLevel));
    537    }
    538 }
    539 
    540 angle::Result TextureStorage11::updateSubresourceLevel(const gl::Context *context,
    541                                                       const TextureHelper11 &srcTexture,
    542                                                       unsigned int sourceSubresource,
    543                                                       const gl::ImageIndex &index,
    544                                                       const gl::Box &copyArea)
    545 {
    546    ASSERT(srcTexture.valid());
    547 
    548    ANGLE_TRY(resolveTexture(context));
    549    const GLint level = index.getLevelIndex();
    550 
    551    markLevelDirty(level);
    552 
    553    gl::Extents texSize(getLevelWidth(level), getLevelHeight(level), getLevelDepth(level));
    554 
    555    bool fullCopy = copyArea.coversSameExtent(texSize);
    556 
    557    const TextureHelper11 *dstTexture = nullptr;
    558 
    559    // If the zero-LOD workaround is active and we want to update a level greater than zero, then we
    560    // should update the mipmapped texture, even if mapmaps are currently disabled.
    561    if (level > 0 && mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
    562    {
    563        ANGLE_TRY(getMippedResource(context, &dstTexture));
    564    }
    565    else
    566    {
    567        ANGLE_TRY(getResource(context, &dstTexture));
    568    }
    569 
    570    unsigned int dstSubresource = 0;
    571    ANGLE_TRY(getSubresourceIndex(context, index, &dstSubresource));
    572 
    573    ASSERT(dstTexture->valid());
    574 
    575    const d3d11::DXGIFormatSize &dxgiFormatSizeInfo =
    576        d3d11::GetDXGIFormatSizeInfo(mFormatInfo.texFormat);
    577    if (!fullCopy && mFormatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN)
    578    {
    579        // CopySubresourceRegion cannot copy partial depth stencils, use the blitter instead
    580        Blit11 *blitter = mRenderer->getBlitter();
    581        return blitter->copyDepthStencil(context, srcTexture, sourceSubresource, copyArea, texSize,
    582                                         *dstTexture, dstSubresource, copyArea, texSize, nullptr);
    583    }
    584 
    585    D3D11_BOX srcBox;
    586    srcBox.left = copyArea.x;
    587    srcBox.top  = copyArea.y;
    588    srcBox.right =
    589        copyArea.x + roundUp(static_cast<UINT>(copyArea.width), dxgiFormatSizeInfo.blockWidth);
    590    srcBox.bottom =
    591        copyArea.y + roundUp(static_cast<UINT>(copyArea.height), dxgiFormatSizeInfo.blockHeight);
    592    srcBox.front = copyArea.z;
    593    srcBox.back  = copyArea.z + copyArea.depth;
    594 
    595    ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
    596 
    597    deviceContext->CopySubresourceRegion(dstTexture->get(), dstSubresource, copyArea.x, copyArea.y,
    598                                         copyArea.z, srcTexture.get(), sourceSubresource,
    599                                         fullCopy ? nullptr : &srcBox);
    600    return angle::Result::Continue;
    601 }
    602 
    603 angle::Result TextureStorage11::copySubresourceLevel(const gl::Context *context,
    604                                                     const TextureHelper11 &dstTexture,
    605                                                     unsigned int dstSubresource,
    606                                                     const gl::ImageIndex &index,
    607                                                     const gl::Box &region)
    608 {
    609    ASSERT(dstTexture.valid());
    610 
    611    ANGLE_TRY(resolveTexture(context));
    612    const TextureHelper11 *srcTexture = nullptr;
    613 
    614    // If the zero-LOD workaround is active and we want to update a level greater than zero, then we
    615    // should update the mipmapped texture, even if mapmaps are currently disabled.
    616    if (index.getLevelIndex() > 0 && mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
    617    {
    618        ANGLE_TRY(getMippedResource(context, &srcTexture));
    619    }
    620    else
    621    {
    622        ANGLE_TRY(getResource(context, &srcTexture));
    623    }
    624 
    625    ASSERT(srcTexture->valid());
    626 
    627    unsigned int srcSubresource = 0;
    628    ANGLE_TRY(getSubresourceIndex(context, index, &srcSubresource));
    629 
    630    ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
    631 
    632    // D3D11 can't perform partial CopySubresourceRegion on depth/stencil textures, so pSrcBox
    633    // should be nullptr.
    634    D3D11_BOX srcBox;
    635    D3D11_BOX *pSrcBox = nullptr;
    636    if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3)
    637    {
    638        GLsizei width  = region.width;
    639        GLsizei height = region.height;
    640        d3d11::MakeValidSize(false, mFormatInfo.texFormat, &width, &height, nullptr);
    641 
    642        // Keep srcbox as nullptr if we're dealing with tiny mips of compressed textures.
    643        if (width == region.width && height == region.height)
    644        {
    645            // However, D3D10Level9 doesn't always perform CopySubresourceRegion correctly unless
    646            // the source box is specified. This is okay, since we don't perform
    647            // CopySubresourceRegion on depth/stencil textures on 9_3.
    648            ASSERT(mFormatInfo.dsvFormat == DXGI_FORMAT_UNKNOWN);
    649            srcBox.left   = region.x;
    650            srcBox.right  = region.x + region.width;
    651            srcBox.top    = region.y;
    652            srcBox.bottom = region.y + region.height;
    653            srcBox.front  = region.z;
    654            srcBox.back   = region.z + region.depth;
    655            pSrcBox       = &srcBox;
    656        }
    657    }
    658 
    659    deviceContext->CopySubresourceRegion(dstTexture.get(), dstSubresource, region.x, region.y,
    660                                         region.z, srcTexture->get(), srcSubresource, pSrcBox);
    661 
    662    return angle::Result::Continue;
    663 }
    664 
    665 angle::Result TextureStorage11::generateMipmap(const gl::Context *context,
    666                                               const gl::ImageIndex &sourceIndex,
    667                                               const gl::ImageIndex &destIndex)
    668 {
    669    ASSERT(sourceIndex.getLayerIndex() == destIndex.getLayerIndex());
    670 
    671    ANGLE_TRY(resolveTexture(context));
    672    markLevelDirty(destIndex.getLevelIndex());
    673 
    674    RenderTargetD3D *source = nullptr;
    675    ANGLE_TRY(getRenderTarget(context, sourceIndex, 0, &source));
    676 
    677    // dest will always have 0 since, we have just released the MS Texture struct
    678    RenderTargetD3D *dest = nullptr;
    679    ANGLE_TRY(getRenderTarget(context, destIndex, 0, &dest));
    680 
    681    RenderTarget11 *srcRT11                = GetAs<RenderTarget11>(source);
    682    RenderTarget11 *dstRT11                = GetAs<RenderTarget11>(dest);
    683    const d3d11::RenderTargetView &destRTV = dstRT11->getRenderTargetView();
    684    const d3d11::SharedSRV *sourceSRV;
    685    ANGLE_TRY(srcRT11->getBlitShaderResourceView(context, &sourceSRV));
    686 
    687    gl::Box sourceArea(0, 0, 0, source->getWidth(), source->getHeight(), source->getDepth());
    688    gl::Extents sourceSize(source->getWidth(), source->getHeight(), source->getDepth());
    689 
    690    gl::Box destArea(0, 0, 0, dest->getWidth(), dest->getHeight(), dest->getDepth());
    691    gl::Extents destSize(dest->getWidth(), dest->getHeight(), dest->getDepth());
    692 
    693    Blit11 *blitter = mRenderer->getBlitter();
    694    const gl::InternalFormat &sourceInternalFormat =
    695        gl::GetSizedInternalFormatInfo(source->getInternalFormat());
    696    GLenum format = sourceInternalFormat.format;
    697    GLenum type   = sourceInternalFormat.type;
    698    return blitter->copyTexture(context, *sourceSRV, sourceArea, sourceSize, format, destRTV,
    699                                destArea, destSize, nullptr, format, type, GL_LINEAR, false, false,
    700                                false);
    701 }
    702 
    703 void TextureStorage11::verifySwizzleExists(const gl::SwizzleState &swizzleState)
    704 {
    705    for (unsigned int level = 0; level < mMipLevels; level++)
    706    {
    707        ASSERT(mSwizzleCache[level] == swizzleState);
    708    }
    709 }
    710 
    711 void TextureStorage11::clearSRVCache()
    712 {
    713    markDirty();
    714    mSrvCacheForSampler.clear();
    715 
    716    for (size_t level = 0; level < mLevelSRVs.size(); level++)
    717    {
    718        mLevelSRVs[level].reset();
    719        mLevelBlitSRVs[level].reset();
    720    }
    721 }
    722 
    723 angle::Result TextureStorage11::copyToStorage(const gl::Context *context,
    724                                              TextureStorage *destStorage)
    725 {
    726    ASSERT(destStorage);
    727 
    728    ANGLE_TRY(resolveTexture(context));
    729    const TextureHelper11 *sourceResouce = nullptr;
    730    ANGLE_TRY(getResource(context, &sourceResouce));
    731 
    732    TextureStorage11 *dest11            = GetAs<TextureStorage11>(destStorage);
    733    const TextureHelper11 *destResource = nullptr;
    734    ANGLE_TRY(dest11->getResource(context, &destResource));
    735 
    736    ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
    737    immediateContext->CopyResource(destResource->get(), sourceResouce->get());
    738 
    739    dest11->markDirty();
    740 
    741    return angle::Result::Continue;
    742 }
    743 
    744 void TextureStorage11::invalidateTextures()
    745 {
    746    mRenderer->getStateManager()->invalidateTexturesAndSamplers();
    747 }
    748 
    749 angle::Result TextureStorage11::setData(const gl::Context *context,
    750                                        const gl::ImageIndex &index,
    751                                        ImageD3D *image,
    752                                        const gl::Box *destBox,
    753                                        GLenum type,
    754                                        const gl::PixelUnpackState &unpack,
    755                                        const uint8_t *pixelData)
    756 {
    757    ASSERT(!image->isDirty());
    758 
    759    ANGLE_TRY(resolveTexture(context));
    760    markLevelDirty(index.getLevelIndex());
    761 
    762    const TextureHelper11 *resource = nullptr;
    763    ANGLE_TRY(getResource(context, &resource));
    764    ASSERT(resource && resource->valid());
    765 
    766    UINT destSubresource = 0;
    767    ANGLE_TRY(getSubresourceIndex(context, index, &destSubresource));
    768 
    769    const gl::InternalFormat &internalFormatInfo =
    770        gl::GetInternalFormatInfo(image->getInternalFormat(), type);
    771 
    772    gl::Box levelBox(0, 0, 0, getLevelWidth(index.getLevelIndex()),
    773                     getLevelHeight(index.getLevelIndex()), getLevelDepth(index.getLevelIndex()));
    774    bool fullUpdate = (destBox == nullptr || *destBox == levelBox);
    775    ASSERT(internalFormatInfo.depthBits == 0 || fullUpdate);
    776 
    777    // TODO(jmadill): Handle compressed formats
    778    // Compressed formats have different load syntax, so we'll have to handle them with slightly
    779    // different logic. Will implemnent this in a follow-up patch, and ensure we do not use SetData
    780    // with compressed formats in the calling logic.
    781    ASSERT(!internalFormatInfo.compressed);
    782 
    783    Context11 *context11 = GetImplAs<Context11>(context);
    784 
    785    const int width    = destBox ? destBox->width : static_cast<int>(image->getWidth());
    786    const int height   = destBox ? destBox->height : static_cast<int>(image->getHeight());
    787    const int depth    = destBox ? destBox->depth : static_cast<int>(image->getDepth());
    788    GLuint srcRowPitch = 0;
    789    ANGLE_CHECK_GL_MATH(context11,
    790                        internalFormatInfo.computeRowPitch(type, width, unpack.alignment,
    791                                                           unpack.rowLength, &srcRowPitch));
    792    GLuint srcDepthPitch = 0;
    793    ANGLE_CHECK_GL_MATH(context11, internalFormatInfo.computeDepthPitch(
    794                                       height, unpack.imageHeight, srcRowPitch, &srcDepthPitch));
    795    GLuint srcSkipBytes = 0;
    796    ANGLE_CHECK_GL_MATH(
    797        context11, internalFormatInfo.computeSkipBytes(type, srcRowPitch, srcDepthPitch, unpack,
    798                                                       index.usesTex3D(), &srcSkipBytes));
    799 
    800    const d3d11::Format &d3d11Format =
    801        d3d11::Format::Get(image->getInternalFormat(), mRenderer->getRenderer11DeviceCaps());
    802    const d3d11::DXGIFormatSize &dxgiFormatInfo =
    803        d3d11::GetDXGIFormatSizeInfo(d3d11Format.texFormat);
    804 
    805    const size_t outputPixelSize = dxgiFormatInfo.pixelBytes;
    806 
    807    UINT bufferRowPitch   = static_cast<unsigned int>(outputPixelSize) * width;
    808    UINT bufferDepthPitch = bufferRowPitch * height;
    809 
    810    const size_t neededSize               = bufferDepthPitch * depth;
    811    angle::MemoryBuffer *conversionBuffer = nullptr;
    812    const uint8_t *data                   = nullptr;
    813 
    814    LoadImageFunctionInfo loadFunctionInfo = d3d11Format.getLoadFunctions()(type);
    815    if (loadFunctionInfo.requiresConversion)
    816    {
    817        ANGLE_TRY(mRenderer->getScratchMemoryBuffer(context11, neededSize, &conversionBuffer));
    818        loadFunctionInfo.loadFunction(width, height, depth, pixelData + srcSkipBytes, srcRowPitch,
    819                                      srcDepthPitch, conversionBuffer->data(), bufferRowPitch,
    820                                      bufferDepthPitch);
    821        data = conversionBuffer->data();
    822    }
    823    else
    824    {
    825        data             = pixelData + srcSkipBytes;
    826        bufferRowPitch   = srcRowPitch;
    827        bufferDepthPitch = srcDepthPitch;
    828    }
    829 
    830    ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
    831 
    832    if (!fullUpdate)
    833    {
    834        ASSERT(destBox);
    835 
    836        D3D11_BOX destD3DBox;
    837        destD3DBox.left   = destBox->x;
    838        destD3DBox.right  = destBox->x + destBox->width;
    839        destD3DBox.top    = destBox->y;
    840        destD3DBox.bottom = destBox->y + destBox->height;
    841        destD3DBox.front  = destBox->z;
    842        destD3DBox.back   = destBox->z + destBox->depth;
    843 
    844        immediateContext->UpdateSubresource(resource->get(), destSubresource, &destD3DBox, data,
    845                                            bufferRowPitch, bufferDepthPitch);
    846    }
    847    else
    848    {
    849        immediateContext->UpdateSubresource(resource->get(), destSubresource, nullptr, data,
    850                                            bufferRowPitch, bufferDepthPitch);
    851    }
    852 
    853    return angle::Result::Continue;
    854 }
    855 
    856 angle::Result TextureStorage11::ensureDropStencilTexture(
    857    const gl::Context *context,
    858    TextureStorage11::DropStencil *dropStencilOut)
    859 {
    860    ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
    861    return angle::Result::Stop;
    862 }
    863 
    864 angle::Result TextureStorage11::initDropStencilTexture(const gl::Context *context,
    865                                                       const gl::ImageIndexIterator &it)
    866 {
    867    const TextureHelper11 *sourceTexture = nullptr;
    868    ANGLE_TRY(getResource(context, &sourceTexture));
    869 
    870    gl::ImageIndexIterator itCopy = it;
    871 
    872    while (itCopy.hasNext())
    873    {
    874        gl::ImageIndex index = itCopy.next();
    875        gl::Box wholeArea(0, 0, 0, getLevelWidth(index.getLevelIndex()),
    876                          getLevelHeight(index.getLevelIndex()), 1);
    877        gl::Extents wholeSize(wholeArea.width, wholeArea.height, 1);
    878 
    879        UINT subresource = 0;
    880        ANGLE_TRY(getSubresourceIndex(context, index, &subresource));
    881 
    882        ANGLE_TRY(mRenderer->getBlitter()->copyDepthStencil(
    883            context, *sourceTexture, subresource, wholeArea, wholeSize, mDropStencilTexture,
    884            subresource, wholeArea, wholeSize, nullptr));
    885    }
    886 
    887    return angle::Result::Continue;
    888 }
    889 
    890 angle::Result TextureStorage11::resolveTextureHelper(const gl::Context *context,
    891                                                     const TextureHelper11 &texture)
    892 {
    893    UINT subresourceIndexSS;
    894    ANGLE_TRY(getSubresourceIndex(context, mMSTexInfo->indexSS, &subresourceIndexSS));
    895    UINT subresourceIndexMS;
    896    ANGLE_TRY(getSubresourceIndex(context, mMSTexInfo->indexMS, &subresourceIndexMS));
    897    ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
    898    const TextureHelper11 *resource    = nullptr;
    899    ANGLE_TRY(mMSTexInfo->msTex->getResource(context, &resource));
    900    deviceContext->ResolveSubresource(texture.get(), subresourceIndexSS, resource->get(),
    901                                      subresourceIndexMS, texture.getFormat());
    902    mMSTexInfo->msTextureNeedsResolve = false;
    903    return angle::Result::Continue;
    904 }
    905 
    906 angle::Result TextureStorage11::releaseMultisampledTexStorageForLevel(size_t level)
    907 {
    908    if (mMSTexInfo && mMSTexInfo->indexSS.getLevelIndex() == static_cast<int>(level))
    909    {
    910        mMSTexInfo->msTex.reset();
    911        onStateChange(angle::SubjectMessage::ContentsChanged);
    912    }
    913    return angle::Result::Continue;
    914 }
    915 
    916 GLsizei TextureStorage11::getRenderToTextureSamples() const
    917 {
    918    if (mMSTexInfo)
    919    {
    920        return mMSTexInfo->samples;
    921    }
    922    return 0;
    923 }
    924 
    925 angle::Result TextureStorage11::findMultisampledRenderTarget(const gl::Context *context,
    926                                                             const gl::ImageIndex &index,
    927                                                             GLsizei samples,
    928                                                             RenderTargetD3D **outRT) const
    929 {
    930    const int level = index.getLevelIndex();
    931    if (!mMSTexInfo || level != mMSTexInfo->indexSS.getLevelIndex() ||
    932        samples != mMSTexInfo->samples || !mMSTexInfo->msTex)
    933    {
    934        *outRT = nullptr;
    935        return angle::Result::Continue;
    936    }
    937    RenderTargetD3D *rt;
    938    ANGLE_TRY(mMSTexInfo->msTex->findRenderTarget(context, mMSTexInfo->indexMS, samples, &rt));
    939    *outRT = rt;
    940    return angle::Result::Continue;
    941 }
    942 
    943 angle::Result TextureStorage11::getMultisampledRenderTarget(const gl::Context *context,
    944                                                            const gl::ImageIndex &index,
    945                                                            GLsizei samples,
    946                                                            RenderTargetD3D **outRT)
    947 {
    948    const int level = index.getLevelIndex();
    949    if (!mMSTexInfo || level != mMSTexInfo->indexSS.getLevelIndex() ||
    950        samples != mMSTexInfo->samples || !mMSTexInfo->msTex)
    951    {
    952        // if mMSTexInfo already exists, then we want to resolve and release it
    953        // since the mMSTexInfo must be for a different sample count or level
    954        ANGLE_TRY(resolveTexture(context));
    955 
    956        // Now we can create a new object for the correct sample and level
    957        GLsizei width         = getLevelWidth(level);
    958        GLsizei height        = getLevelHeight(level);
    959        GLenum internalFormat = mFormatInfo.internalFormat;
    960        std::unique_ptr<TextureStorage11_2DMultisample> texMS(
    961            GetAs<TextureStorage11_2DMultisample>(mRenderer->createTextureStorage2DMultisample(
    962                internalFormat, width, height, level, samples, true, mKHRDebugLabel)));
    963 
    964        // make sure multisample object has the blitted information.
    965        gl::Rectangle area(0, 0, width, height);
    966        RenderTargetD3D *readRenderTarget = nullptr;
    967        // use incoming index here since the index will correspond to the single sampled texture
    968        ANGLE_TRY(getRenderTarget(context, index, 0, &readRenderTarget));
    969        gl::ImageIndex indexMS            = gl::ImageIndex::Make2DMultisample();
    970        RenderTargetD3D *drawRenderTarget = nullptr;
    971        ANGLE_TRY(texMS->getRenderTarget(context, indexMS, samples, &drawRenderTarget));
    972 
    973        // blit SS -> MS
    974        // mask: GL_COLOR_BUFFER_BIT, filter: GL_NEAREST
    975        ANGLE_TRY(mRenderer->blitRenderbufferRect(context, area, area, 0, 0, readRenderTarget,
    976                                                  drawRenderTarget, GL_NEAREST, nullptr, true,
    977                                                  false, false));
    978        mMSTexInfo = std::make_unique<MultisampledRenderToTextureInfo>(samples, index, indexMS);
    979        mMSTexInfo->msTex = std::move(texMS);
    980    }
    981    RenderTargetD3D *rt;
    982    ANGLE_TRY(mMSTexInfo->msTex->getRenderTarget(context, mMSTexInfo->indexMS, samples, &rt));
    983    // By returning the multisampled render target to the caller, the render target
    984    // is expected to be changed so we need to resolve to a single sampled texture
    985    // next time resolveTexture is called.
    986    mMSTexInfo->msTextureNeedsResolve = true;
    987    *outRT                            = rt;
    988    return angle::Result::Continue;
    989 }
    990 
    991 TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer,
    992                                         SwapChain11 *swapchain,
    993                                         const std::string &label)
    994    : TextureStorage11(renderer,
    995                       D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE,
    996                       0,
    997                       swapchain->getRenderTargetInternalFormat(),
    998                       label),
    999      mTexture(swapchain->getOffscreenTexture()),
   1000      mLevelZeroTexture(),
   1001      mLevelZeroRenderTarget(nullptr),
   1002      mUseLevelZeroTexture(false),
   1003      mSwizzleTexture()
   1004 {
   1005    for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
   1006    {
   1007        mAssociatedImages[i] = nullptr;
   1008        mRenderTarget[i]     = nullptr;
   1009    }
   1010 
   1011    D3D11_TEXTURE2D_DESC texDesc;
   1012    mTexture.getDesc(&texDesc);
   1013    mMipLevels     = texDesc.MipLevels;
   1014    mTextureWidth  = texDesc.Width;
   1015    mTextureHeight = texDesc.Height;
   1016    mTextureDepth  = 1;
   1017    mHasKeyedMutex = (texDesc.MiscFlags & D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX) != 0;
   1018 }
   1019 
   1020 TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer,
   1021                                         GLenum internalformat,
   1022                                         BindFlags bindFlags,
   1023                                         GLsizei width,
   1024                                         GLsizei height,
   1025                                         int levels,
   1026                                         const std::string &label,
   1027                                         bool hintLevelZeroOnly)
   1028    : TextureStorage11(
   1029          renderer,
   1030          GetTextureBindFlags(internalformat, renderer->getRenderer11DeviceCaps(), bindFlags),
   1031          GetTextureMiscFlags(internalformat,
   1032                              renderer->getRenderer11DeviceCaps(),
   1033                              bindFlags,
   1034                              levels),
   1035          internalformat,
   1036          label),
   1037      mTexture(),
   1038      mHasKeyedMutex(false),
   1039      mLevelZeroTexture(),
   1040      mLevelZeroRenderTarget(nullptr),
   1041      mUseLevelZeroTexture(hintLevelZeroOnly && levels > 1),
   1042      mSwizzleTexture()
   1043 {
   1044    for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
   1045    {
   1046        mAssociatedImages[i] = nullptr;
   1047        mRenderTarget[i]     = nullptr;
   1048    }
   1049 
   1050    d3d11::MakeValidSize(false, mFormatInfo.texFormat, &width, &height, &mTopLevel);
   1051    mMipLevels     = mTopLevel + levels;
   1052    mTextureWidth  = width;
   1053    mTextureHeight = height;
   1054    mTextureDepth  = 1;
   1055 
   1056    // The LevelZeroOnly hint should only be true if the zero max LOD workaround is active.
   1057    ASSERT(!mUseLevelZeroTexture || mRenderer->getFeatures().zeroMaxLodWorkaround.enabled);
   1058 }
   1059 
   1060 void TextureStorage11_2D::onLabelUpdate()
   1061 {
   1062    if (mTexture.valid())
   1063    {
   1064        mTexture.setKHRDebugLabel(&mKHRDebugLabel);
   1065    }
   1066    if (mLevelZeroTexture.valid())
   1067    {
   1068        mLevelZeroTexture.setKHRDebugLabel(&mKHRDebugLabel);
   1069    }
   1070    if (mSwizzleTexture.valid())
   1071    {
   1072        mSwizzleTexture.setKHRDebugLabel(&mKHRDebugLabel);
   1073    }
   1074 }
   1075 
   1076 angle::Result TextureStorage11_2D::onDestroy(const gl::Context *context)
   1077 {
   1078    for (unsigned i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
   1079    {
   1080        if (mAssociatedImages[i] != nullptr)
   1081        {
   1082            mAssociatedImages[i]->verifyAssociatedStorageValid(this);
   1083 
   1084            // We must let the Images recover their data before we delete it from the
   1085            // TextureStorage.
   1086            ANGLE_TRY(mAssociatedImages[i]->recoverFromAssociatedStorage(context));
   1087        }
   1088    }
   1089 
   1090    if (mHasKeyedMutex)
   1091    {
   1092        // If the keyed mutex is released that will unbind it and cause the state cache to become
   1093        // desynchronized.
   1094        mRenderer->getStateManager()->invalidateBoundViews();
   1095    }
   1096 
   1097    return angle::Result::Continue;
   1098 }
   1099 
   1100 TextureStorage11_2D::~TextureStorage11_2D() {}
   1101 
   1102 angle::Result TextureStorage11_2D::copyToStorage(const gl::Context *context,
   1103                                                 TextureStorage *destStorage)
   1104 {
   1105    ASSERT(destStorage);
   1106 
   1107    TextureStorage11_2D *dest11           = GetAs<TextureStorage11_2D>(destStorage);
   1108    ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
   1109 
   1110    if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
   1111    {
   1112        // If either mTexture or mLevelZeroTexture exist, then we need to copy them into the
   1113        // corresponding textures in destStorage.
   1114        if (mTexture.valid())
   1115        {
   1116            ANGLE_TRY(dest11->useLevelZeroWorkaroundTexture(context, false));
   1117 
   1118            const TextureHelper11 *destResource = nullptr;
   1119            ANGLE_TRY(dest11->getResource(context, &destResource));
   1120 
   1121            immediateContext->CopyResource(destResource->get(), mTexture.get());
   1122        }
   1123 
   1124        if (mLevelZeroTexture.valid())
   1125        {
   1126            ANGLE_TRY(dest11->useLevelZeroWorkaroundTexture(context, true));
   1127 
   1128            const TextureHelper11 *destResource = nullptr;
   1129            ANGLE_TRY(dest11->getResource(context, &destResource));
   1130 
   1131            immediateContext->CopyResource(destResource->get(), mLevelZeroTexture.get());
   1132        }
   1133 
   1134        return angle::Result::Continue;
   1135    }
   1136 
   1137    const TextureHelper11 *sourceResouce = nullptr;
   1138    ANGLE_TRY(getResource(context, &sourceResouce));
   1139 
   1140    const TextureHelper11 *destResource = nullptr;
   1141    ANGLE_TRY(dest11->getResource(context, &destResource));
   1142 
   1143    immediateContext->CopyResource(destResource->get(), sourceResouce->get());
   1144    dest11->markDirty();
   1145 
   1146    return angle::Result::Continue;
   1147 }
   1148 
   1149 angle::Result TextureStorage11_2D::useLevelZeroWorkaroundTexture(const gl::Context *context,
   1150                                                                 bool useLevelZeroTexture)
   1151 {
   1152    if (useLevelZeroTexture && mMipLevels > 1)
   1153    {
   1154        if (!mUseLevelZeroTexture && mTexture.valid())
   1155        {
   1156            ANGLE_TRY(ensureTextureExists(context, 1));
   1157 
   1158            // Pull data back from the mipped texture if necessary.
   1159            ASSERT(mLevelZeroTexture.valid());
   1160            ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
   1161            deviceContext->CopySubresourceRegion(mLevelZeroTexture.get(), 0, 0, 0, 0,
   1162                                                 mTexture.get(), 0, nullptr);
   1163        }
   1164 
   1165        mUseLevelZeroTexture = true;
   1166    }
   1167    else
   1168    {
   1169        if (mUseLevelZeroTexture && mLevelZeroTexture.valid())
   1170        {
   1171            ANGLE_TRY(ensureTextureExists(context, mMipLevels));
   1172 
   1173            // Pull data back from the level zero texture if necessary.
   1174            ASSERT(mTexture.valid());
   1175            ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
   1176            deviceContext->CopySubresourceRegion(mTexture.get(), 0, 0, 0, 0,
   1177                                                 mLevelZeroTexture.get(), 0, nullptr);
   1178        }
   1179 
   1180        mUseLevelZeroTexture = false;
   1181    }
   1182 
   1183    return angle::Result::Continue;
   1184 }
   1185 
   1186 void TextureStorage11_2D::associateImage(Image11 *image, const gl::ImageIndex &index)
   1187 {
   1188    const GLint level = index.getLevelIndex();
   1189 
   1190    ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
   1191    if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
   1192    {
   1193        mAssociatedImages[level] = image;
   1194    }
   1195 }
   1196 
   1197 void TextureStorage11_2D::verifyAssociatedImageValid(const gl::ImageIndex &index,
   1198                                                     Image11 *expectedImage)
   1199 {
   1200    const GLint level = index.getLevelIndex();
   1201 
   1202    ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
   1203    // This validation check should never return false. It means the Image/TextureStorage
   1204    // association is broken.
   1205    ASSERT(mAssociatedImages[level] == expectedImage);
   1206 }
   1207 
   1208 // disassociateImage allows an Image to end its association with a Storage.
   1209 void TextureStorage11_2D::disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage)
   1210 {
   1211    const GLint level = index.getLevelIndex();
   1212 
   1213    ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
   1214    ASSERT(mAssociatedImages[level] == expectedImage);
   1215    mAssociatedImages[level] = nullptr;
   1216 }
   1217 
   1218 // releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image
   1219 // recover its data before ending the association.
   1220 angle::Result TextureStorage11_2D::releaseAssociatedImage(const gl::Context *context,
   1221                                                          const gl::ImageIndex &index,
   1222                                                          Image11 *incomingImage)
   1223 {
   1224    const GLint level = index.getLevelIndex();
   1225 
   1226    ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
   1227 
   1228    if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
   1229    {
   1230        // No need to let the old Image recover its data, if it is also the incoming Image.
   1231        if (mAssociatedImages[level] != nullptr && mAssociatedImages[level] != incomingImage)
   1232        {
   1233            // Ensure that the Image is still associated with this TextureStorage.
   1234            mAssociatedImages[level]->verifyAssociatedStorageValid(this);
   1235 
   1236            // Force the image to recover from storage before its data is overwritten.
   1237            // This will reset mAssociatedImages[level] to nullptr too.
   1238            ANGLE_TRY(mAssociatedImages[level]->recoverFromAssociatedStorage(context));
   1239        }
   1240    }
   1241 
   1242    return angle::Result::Continue;
   1243 }
   1244 
   1245 angle::Result TextureStorage11_2D::getResource(const gl::Context *context,
   1246                                               const TextureHelper11 **outResource)
   1247 {
   1248    if (mUseLevelZeroTexture && mMipLevels > 1)
   1249    {
   1250        ANGLE_TRY(ensureTextureExists(context, 1));
   1251 
   1252        *outResource = &mLevelZeroTexture;
   1253        return angle::Result::Continue;
   1254    }
   1255 
   1256    ANGLE_TRY(ensureTextureExists(context, mMipLevels));
   1257 
   1258    *outResource = &mTexture;
   1259    return angle::Result::Continue;
   1260 }
   1261 
   1262 angle::Result TextureStorage11_2D::getMippedResource(const gl::Context *context,
   1263                                                     const TextureHelper11 **outResource)
   1264 {
   1265    // This shouldn't be called unless the zero max LOD workaround is active.
   1266    ASSERT(mRenderer->getFeatures().zeroMaxLodWorkaround.enabled);
   1267 
   1268    ANGLE_TRY(ensureTextureExists(context, mMipLevels));
   1269 
   1270    *outResource = &mTexture;
   1271    return angle::Result::Continue;
   1272 }
   1273 
   1274 angle::Result TextureStorage11_2D::ensureTextureExists(const gl::Context *context, int mipLevels)
   1275 {
   1276    // If mMipLevels = 1 then always use mTexture rather than mLevelZeroTexture.
   1277    ANGLE_TRY(resolveTexture(context));
   1278    bool useLevelZeroTexture       = mRenderer->getFeatures().zeroMaxLodWorkaround.enabled
   1279                                         ? (mipLevels == 1) && (mMipLevels > 1)
   1280                                         : false;
   1281    TextureHelper11 *outputTexture = useLevelZeroTexture ? &mLevelZeroTexture : &mTexture;
   1282 
   1283    // if the width or height is not positive this should be treated as an incomplete texture
   1284    // we handle that here by skipping the d3d texture creation
   1285    if (!outputTexture->valid() && mTextureWidth > 0 && mTextureHeight > 0)
   1286    {
   1287        ASSERT(mipLevels > 0);
   1288 
   1289        D3D11_TEXTURE2D_DESC desc;
   1290        desc.Width     = mTextureWidth;  // Compressed texture size constraints?
   1291        desc.Height    = mTextureHeight;
   1292        desc.MipLevels = mipLevels;
   1293        desc.ArraySize = 1;
   1294        desc.Format    = isUnorderedAccess() ? mFormatInfo.typelessFormat : mFormatInfo.texFormat;
   1295        desc.SampleDesc.Count   = 1;
   1296        desc.SampleDesc.Quality = 0;
   1297        desc.Usage              = D3D11_USAGE_DEFAULT;
   1298        desc.BindFlags          = getBindFlags();
   1299        desc.CPUAccessFlags     = 0;
   1300        desc.MiscFlags          = getMiscFlags();
   1301 
   1302        ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, mFormatInfo,
   1303                                             outputTexture));
   1304 
   1305        if (useLevelZeroTexture)
   1306        {
   1307            outputTexture->setLabels("TexStorage2D.Level0Texture", &mKHRDebugLabel);
   1308        }
   1309        else
   1310        {
   1311            outputTexture->setLabels("TexStorage2D.Texture", &mKHRDebugLabel);
   1312        }
   1313    }
   1314 
   1315    return angle::Result::Continue;
   1316 }
   1317 
   1318 angle::Result TextureStorage11_2D::findRenderTarget(const gl::Context *context,
   1319                                                    const gl::ImageIndex &index,
   1320                                                    GLsizei samples,
   1321                                                    RenderTargetD3D **outRT) const
   1322 {
   1323    ASSERT(!index.hasLayer());
   1324 
   1325    const int level = index.getLevelIndex();
   1326    ASSERT(level >= 0 && level < getLevelCount());
   1327 
   1328    bool needMS = samples > 0;
   1329    if (needMS)
   1330    {
   1331        return findMultisampledRenderTarget(context, index, samples, outRT);
   1332    }
   1333 
   1334    ASSERT(outRT);
   1335    if (mRenderTarget[level])
   1336    {
   1337        *outRT = mRenderTarget[level].get();
   1338        return angle::Result::Continue;
   1339    }
   1340 
   1341    if (mUseLevelZeroTexture)
   1342    {
   1343        ASSERT(level == 0);
   1344        *outRT = mLevelZeroRenderTarget.get();
   1345        return angle::Result::Continue;
   1346    }
   1347 
   1348    *outRT = nullptr;
   1349    return angle::Result::Continue;
   1350 }
   1351 
   1352 angle::Result TextureStorage11_2D::getRenderTarget(const gl::Context *context,
   1353                                                   const gl::ImageIndex &index,
   1354                                                   GLsizei samples,
   1355                                                   RenderTargetD3D **outRT)
   1356 {
   1357    ASSERT(!index.hasLayer());
   1358 
   1359    const int level = index.getLevelIndex();
   1360    ASSERT(level >= 0 && level < getLevelCount());
   1361 
   1362    bool needMS = samples > 0;
   1363    if (needMS)
   1364    {
   1365        return getMultisampledRenderTarget(context, index, samples, outRT);
   1366    }
   1367    else
   1368    {
   1369        ANGLE_TRY(resolveTexture(context));
   1370    }
   1371 
   1372    // In GL ES 2.0, the application can only render to level zero of the texture (Section 4.4.3 of
   1373    // the GLES 2.0 spec, page 113 of version 2.0.25). Other parts of TextureStorage11_2D could
   1374    // create RTVs on non-zero levels of the texture (e.g. generateMipmap).
   1375    // On Feature Level 9_3, this is unlikely to be useful. The renderer can't create SRVs on the
   1376    // individual levels of the texture, so methods like generateMipmap can't do anything useful
   1377    // with non-zero-level RTVs. Therefore if level > 0 on 9_3 then there's almost certainly
   1378    // something wrong.
   1379    ASSERT(
   1380        !(mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3 && level > 0));
   1381    ASSERT(outRT);
   1382    if (mRenderTarget[level])
   1383    {
   1384        *outRT = mRenderTarget[level].get();
   1385        return angle::Result::Continue;
   1386    }
   1387 
   1388    if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
   1389    {
   1390        ASSERT(level == 0);
   1391        ANGLE_TRY(useLevelZeroWorkaroundTexture(context, true));
   1392    }
   1393 
   1394    const TextureHelper11 *texture = nullptr;
   1395    ANGLE_TRY(getResource(context, &texture));
   1396 
   1397    const d3d11::SharedSRV *srv = nullptr;
   1398    ANGLE_TRY(getSRVLevel(context, level, SRVType::Sample, &srv));
   1399 
   1400    const d3d11::SharedSRV *blitSRV = nullptr;
   1401    ANGLE_TRY(getSRVLevel(context, level, SRVType::Blit, &blitSRV));
   1402 
   1403    Context11 *context11 = GetImplAs<Context11>(context);
   1404 
   1405    if (mUseLevelZeroTexture)
   1406    {
   1407        if (!mLevelZeroRenderTarget)
   1408        {
   1409            D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
   1410            rtvDesc.Format             = mFormatInfo.rtvFormat;
   1411            rtvDesc.ViewDimension      = D3D11_RTV_DIMENSION_TEXTURE2D;
   1412            rtvDesc.Texture2D.MipSlice = mTopLevel + level;
   1413 
   1414            d3d11::RenderTargetView rtv;
   1415            ANGLE_TRY(
   1416                mRenderer->allocateResource(context11, rtvDesc, mLevelZeroTexture.get(), &rtv));
   1417            rtv.setLabels("TexStorage2D.Level0RTV", &mKHRDebugLabel);
   1418 
   1419            mLevelZeroRenderTarget.reset(new TextureRenderTarget11(
   1420                std::move(rtv), mLevelZeroTexture, d3d11::SharedSRV(), d3d11::SharedSRV(),
   1421                mFormatInfo.internalFormat, getFormatSet(), getLevelWidth(level),
   1422                getLevelHeight(level), 1, 0));
   1423        }
   1424 
   1425        *outRT = mLevelZeroRenderTarget.get();
   1426        return angle::Result::Continue;
   1427    }
   1428 
   1429    if (mFormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN)
   1430    {
   1431        D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
   1432        rtvDesc.Format             = mFormatInfo.rtvFormat;
   1433        rtvDesc.ViewDimension      = D3D11_RTV_DIMENSION_TEXTURE2D;
   1434        rtvDesc.Texture2D.MipSlice = mTopLevel + level;
   1435 
   1436        d3d11::RenderTargetView rtv;
   1437        ANGLE_TRY(mRenderer->allocateResource(context11, rtvDesc, texture->get(), &rtv));
   1438        rtv.setLabels("TexStorage2D.RTV", &mKHRDebugLabel);
   1439 
   1440        mRenderTarget[level].reset(new TextureRenderTarget11(
   1441            std::move(rtv), *texture, *srv, *blitSRV, mFormatInfo.internalFormat, getFormatSet(),
   1442            getLevelWidth(level), getLevelHeight(level), 1, 0));
   1443 
   1444        *outRT = mRenderTarget[level].get();
   1445        return angle::Result::Continue;
   1446    }
   1447 
   1448    ASSERT(mFormatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN);
   1449 
   1450    D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
   1451    dsvDesc.Format             = mFormatInfo.dsvFormat;
   1452    dsvDesc.ViewDimension      = D3D11_DSV_DIMENSION_TEXTURE2D;
   1453    dsvDesc.Texture2D.MipSlice = mTopLevel + level;
   1454    dsvDesc.Flags              = 0;
   1455 
   1456    d3d11::DepthStencilView dsv;
   1457    ANGLE_TRY(mRenderer->allocateResource(context11, dsvDesc, texture->get(), &dsv));
   1458    dsv.setLabels("TexStorage2D.DSV", &mKHRDebugLabel);
   1459 
   1460    mRenderTarget[level].reset(new TextureRenderTarget11(
   1461        std::move(dsv), *texture, *srv, mFormatInfo.internalFormat, getFormatSet(),
   1462        getLevelWidth(level), getLevelHeight(level), 1, 0));
   1463 
   1464    *outRT = mRenderTarget[level].get();
   1465    return angle::Result::Continue;
   1466 }
   1467 
   1468 angle::Result TextureStorage11_2D::createSRVForSampler(const gl::Context *context,
   1469                                                       int baseLevel,
   1470                                                       int mipLevels,
   1471                                                       DXGI_FORMAT format,
   1472                                                       const TextureHelper11 &texture,
   1473                                                       d3d11::SharedSRV *outSRV)
   1474 {
   1475    ASSERT(outSRV);
   1476 
   1477    D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
   1478    srvDesc.Format                    = format;
   1479    srvDesc.ViewDimension             = D3D11_SRV_DIMENSION_TEXTURE2D;
   1480    srvDesc.Texture2D.MostDetailedMip = mTopLevel + baseLevel;
   1481    srvDesc.Texture2D.MipLevels       = mipLevels;
   1482 
   1483    const TextureHelper11 *srvTexture = &texture;
   1484 
   1485    if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
   1486    {
   1487        ASSERT(mTopLevel == 0);
   1488        ASSERT(baseLevel == 0);
   1489        // This code also assumes that the incoming texture equals either mLevelZeroTexture or
   1490        // mTexture.
   1491 
   1492        if (mipLevels == 1 && mMipLevels > 1)
   1493        {
   1494            // We must use a SRV on the level-zero-only texture.
   1495            ANGLE_TRY(ensureTextureExists(context, 1));
   1496            srvTexture = &mLevelZeroTexture;
   1497        }
   1498        else
   1499        {
   1500            ASSERT(mipLevels == static_cast<int>(mMipLevels));
   1501            ASSERT(mTexture.valid() && texture == mTexture);
   1502            srvTexture = &mTexture;
   1503        }
   1504    }
   1505 
   1506    ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, srvTexture->get(),
   1507                                          outSRV));
   1508    outSRV->setLabels("TexStorage2D.SRV", &mKHRDebugLabel);
   1509 
   1510    return angle::Result::Continue;
   1511 }
   1512 
   1513 angle::Result TextureStorage11_2D::createSRVForImage(const gl::Context *context,
   1514                                                     int level,
   1515                                                     DXGI_FORMAT format,
   1516                                                     const TextureHelper11 &texture,
   1517                                                     d3d11::SharedSRV *outSRV)
   1518 {
   1519    ASSERT(outSRV);
   1520    D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
   1521    srvDesc.Format                    = format;
   1522    srvDesc.ViewDimension             = D3D11_SRV_DIMENSION_TEXTURE2D;
   1523    srvDesc.Texture2D.MostDetailedMip = mTopLevel + level;
   1524    srvDesc.Texture2D.MipLevels       = 1;
   1525    ANGLE_TRY(
   1526        mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV));
   1527    outSRV->setLabels("TexStorage2D.SRVForImage", &mKHRDebugLabel);
   1528    return angle::Result::Continue;
   1529 }
   1530 
   1531 angle::Result TextureStorage11_2D::createUAVForImage(const gl::Context *context,
   1532                                                     int level,
   1533                                                     DXGI_FORMAT format,
   1534                                                     const TextureHelper11 &texture,
   1535                                                     d3d11::SharedUAV *outUAV)
   1536 {
   1537    ASSERT(outUAV);
   1538    D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
   1539    uavDesc.Format             = format;
   1540    uavDesc.ViewDimension      = D3D11_UAV_DIMENSION_TEXTURE2D;
   1541    uavDesc.Texture2D.MipSlice = mTopLevel + level;
   1542    ANGLE_TRY(
   1543        mRenderer->allocateResource(GetImplAs<Context11>(context), uavDesc, texture.get(), outUAV));
   1544    outUAV->setLabels("TexStorage2D.UAVForImage", &mKHRDebugLabel);
   1545    return angle::Result::Continue;
   1546 }
   1547 
   1548 angle::Result TextureStorage11_2D::getSwizzleTexture(const gl::Context *context,
   1549                                                     const TextureHelper11 **outTexture)
   1550 {
   1551    ASSERT(outTexture);
   1552 
   1553    if (!mSwizzleTexture.valid())
   1554    {
   1555        const auto &format = mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps());
   1556 
   1557        D3D11_TEXTURE2D_DESC desc;
   1558        desc.Width              = mTextureWidth;
   1559        desc.Height             = mTextureHeight;
   1560        desc.MipLevels          = mMipLevels;
   1561        desc.ArraySize          = 1;
   1562        desc.Format             = format.texFormat;
   1563        desc.SampleDesc.Count   = 1;
   1564        desc.SampleDesc.Quality = 0;
   1565        desc.Usage              = D3D11_USAGE_DEFAULT;
   1566        desc.BindFlags          = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
   1567        desc.CPUAccessFlags     = 0;
   1568        desc.MiscFlags          = 0;
   1569 
   1570        ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, format,
   1571                                             &mSwizzleTexture));
   1572        mSwizzleTexture.setLabels("TexStorage2D.SwizzleTexture", &mKHRDebugLabel);
   1573    }
   1574 
   1575    *outTexture = &mSwizzleTexture;
   1576    return angle::Result::Continue;
   1577 }
   1578 
   1579 angle::Result TextureStorage11_2D::getSwizzleRenderTarget(const gl::Context *context,
   1580                                                          int mipLevel,
   1581                                                          const d3d11::RenderTargetView **outRTV)
   1582 {
   1583    ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
   1584    ASSERT(outRTV);
   1585 
   1586    if (!mSwizzleRenderTargets[mipLevel].valid())
   1587    {
   1588        const TextureHelper11 *swizzleTexture = nullptr;
   1589        ANGLE_TRY(getSwizzleTexture(context, &swizzleTexture));
   1590 
   1591        D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
   1592        rtvDesc.Format =
   1593            mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()).rtvFormat;
   1594        rtvDesc.ViewDimension      = D3D11_RTV_DIMENSION_TEXTURE2D;
   1595        rtvDesc.Texture2D.MipSlice = mTopLevel + mipLevel;
   1596 
   1597        ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), rtvDesc,
   1598                                              mSwizzleTexture.get(),
   1599                                              &mSwizzleRenderTargets[mipLevel]));
   1600    }
   1601 
   1602    *outRTV = &mSwizzleRenderTargets[mipLevel];
   1603    return angle::Result::Continue;
   1604 }
   1605 
   1606 angle::Result TextureStorage11_2D::ensureDropStencilTexture(const gl::Context *context,
   1607                                                            DropStencil *dropStencilOut)
   1608 {
   1609    if (mDropStencilTexture.valid())
   1610    {
   1611        *dropStencilOut = DropStencil::ALREADY_EXISTS;
   1612        return angle::Result::Continue;
   1613    }
   1614 
   1615    D3D11_TEXTURE2D_DESC dropDesc = {};
   1616    dropDesc.ArraySize            = 1;
   1617    dropDesc.BindFlags            = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_DEPTH_STENCIL;
   1618    dropDesc.CPUAccessFlags       = 0;
   1619    dropDesc.Format               = DXGI_FORMAT_R32_TYPELESS;
   1620    dropDesc.Height               = mTextureHeight;
   1621    dropDesc.MipLevels            = mMipLevels;
   1622    dropDesc.MiscFlags            = 0;
   1623    dropDesc.SampleDesc.Count     = 1;
   1624    dropDesc.SampleDesc.Quality   = 0;
   1625    dropDesc.Usage                = D3D11_USAGE_DEFAULT;
   1626    dropDesc.Width                = mTextureWidth;
   1627 
   1628    const auto &format =
   1629        d3d11::Format::Get(GL_DEPTH_COMPONENT32F, mRenderer->getRenderer11DeviceCaps());
   1630    ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), dropDesc, format,
   1631                                         &mDropStencilTexture));
   1632    mDropStencilTexture.setLabels("TexStorage2D.DropStencil", &mKHRDebugLabel);
   1633 
   1634    ANGLE_TRY(initDropStencilTexture(context, gl::ImageIndexIterator::Make2D(0, mMipLevels)));
   1635 
   1636    *dropStencilOut = DropStencil::CREATED;
   1637    return angle::Result::Continue;
   1638 }
   1639 
   1640 angle::Result TextureStorage11_2D::resolveTexture(const gl::Context *context)
   1641 {
   1642    if (mMSTexInfo && mMSTexInfo->msTex && mMSTexInfo->msTextureNeedsResolve)
   1643    {
   1644        ANGLE_TRY(resolveTextureHelper(context, mTexture));
   1645        onStateChange(angle::SubjectMessage::ContentsChanged);
   1646    }
   1647    return angle::Result::Continue;
   1648 }
   1649 
   1650 TextureStorage11_External::TextureStorage11_External(
   1651    Renderer11 *renderer,
   1652    egl::Stream *stream,
   1653    const egl::Stream::GLTextureDescription &glDesc,
   1654    const std::string &label)
   1655    : TextureStorage11(renderer, D3D11_BIND_SHADER_RESOURCE, 0, glDesc.internalFormat, label)
   1656 {
   1657    ASSERT(stream->getProducerType() == egl::Stream::ProducerType::D3D11Texture);
   1658    auto *producer = static_cast<StreamProducerD3DTexture *>(stream->getImplementation());
   1659    mTexture.set(producer->getD3DTexture(), mFormatInfo);
   1660    mSubresourceIndex = producer->getArraySlice();
   1661    mTexture.get()->AddRef();
   1662    mMipLevels = 1;
   1663 
   1664    D3D11_TEXTURE2D_DESC desc;
   1665    mTexture.getDesc(&desc);
   1666    mTextureWidth  = desc.Width;
   1667    mTextureHeight = desc.Height;
   1668    mTextureDepth  = 1;
   1669    mHasKeyedMutex = (desc.MiscFlags & D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX) != 0;
   1670 }
   1671 
   1672 angle::Result TextureStorage11_External::onDestroy(const gl::Context *context)
   1673 {
   1674    if (mHasKeyedMutex)
   1675    {
   1676        // If the keyed mutex is released that will unbind it and cause the state cache to become
   1677        // desynchronized.
   1678        mRenderer->getStateManager()->invalidateBoundViews();
   1679    }
   1680 
   1681    return angle::Result::Continue;
   1682 }
   1683 
   1684 TextureStorage11_External::~TextureStorage11_External() {}
   1685 
   1686 angle::Result TextureStorage11_External::copyToStorage(const gl::Context *context,
   1687                                                       TextureStorage *destStorage)
   1688 {
   1689    UNIMPLEMENTED();
   1690    return angle::Result::Continue;
   1691 }
   1692 
   1693 void TextureStorage11_External::associateImage(Image11 *image, const gl::ImageIndex &index)
   1694 {
   1695    ASSERT(index.getLevelIndex() == 0);
   1696    mAssociatedImage = image;
   1697 }
   1698 
   1699 void TextureStorage11_External::verifyAssociatedImageValid(const gl::ImageIndex &index,
   1700                                                           Image11 *expectedImage)
   1701 {
   1702    ASSERT(index.getLevelIndex() == 0 && mAssociatedImage == expectedImage);
   1703 }
   1704 
   1705 void TextureStorage11_External::disassociateImage(const gl::ImageIndex &index,
   1706                                                  Image11 *expectedImage)
   1707 {
   1708    ASSERT(index.getLevelIndex() == 0);
   1709    ASSERT(mAssociatedImage == expectedImage);
   1710    mAssociatedImage = nullptr;
   1711 }
   1712 
   1713 angle::Result TextureStorage11_External::releaseAssociatedImage(const gl::Context *context,
   1714                                                                const gl::ImageIndex &index,
   1715                                                                Image11 *incomingImage)
   1716 {
   1717    ASSERT(index.getLevelIndex() == 0);
   1718 
   1719    if (mAssociatedImage != nullptr && mAssociatedImage != incomingImage)
   1720    {
   1721        mAssociatedImage->verifyAssociatedStorageValid(this);
   1722 
   1723        ANGLE_TRY(mAssociatedImage->recoverFromAssociatedStorage(context));
   1724    }
   1725 
   1726    return angle::Result::Continue;
   1727 }
   1728 
   1729 angle::Result TextureStorage11_External::getResource(const gl::Context *context,
   1730                                                     const TextureHelper11 **outResource)
   1731 {
   1732    *outResource = &mTexture;
   1733    return angle::Result::Continue;
   1734 }
   1735 
   1736 angle::Result TextureStorage11_External::getMippedResource(const gl::Context *context,
   1737                                                           const TextureHelper11 **outResource)
   1738 {
   1739    *outResource = &mTexture;
   1740    return angle::Result::Continue;
   1741 }
   1742 
   1743 angle::Result TextureStorage11_External::findRenderTarget(const gl::Context *context,
   1744                                                          const gl::ImageIndex &index,
   1745                                                          GLsizei samples,
   1746                                                          RenderTargetD3D **outRT) const
   1747 {
   1748    // Render targets are not supported for external textures
   1749    ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
   1750    return angle::Result::Stop;
   1751 }
   1752 
   1753 angle::Result TextureStorage11_External::getRenderTarget(const gl::Context *context,
   1754                                                         const gl::ImageIndex &index,
   1755                                                         GLsizei samples,
   1756                                                         RenderTargetD3D **outRT)
   1757 {
   1758    // Render targets are not supported for external textures
   1759    ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
   1760    return angle::Result::Stop;
   1761 }
   1762 
   1763 angle::Result TextureStorage11_External::createSRVForSampler(const gl::Context *context,
   1764                                                             int baseLevel,
   1765                                                             int mipLevels,
   1766                                                             DXGI_FORMAT format,
   1767                                                             const TextureHelper11 &texture,
   1768                                                             d3d11::SharedSRV *outSRV)
   1769 {
   1770    // Since external textures are treates as non-mipmapped textures, we ignore mipmap levels and
   1771    // use the specified subresource ID the storage was created with.
   1772    ASSERT(mipLevels == 1);
   1773    ASSERT(outSRV);
   1774 
   1775    D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
   1776    srvDesc.Format        = format;
   1777    srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
   1778    // subresource index is equal to the mip level for 2D textures
   1779    srvDesc.Texture2DArray.MostDetailedMip = 0;
   1780    srvDesc.Texture2DArray.MipLevels       = 1;
   1781    srvDesc.Texture2DArray.FirstArraySlice = mSubresourceIndex;
   1782    srvDesc.Texture2DArray.ArraySize       = 1;
   1783 
   1784    ANGLE_TRY(
   1785        mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV));
   1786    outSRV->setLabels("TexStorage2D.SRV", &mKHRDebugLabel);
   1787 
   1788    return angle::Result::Continue;
   1789 }
   1790 
   1791 angle::Result TextureStorage11_External::createSRVForImage(const gl::Context *context,
   1792                                                           int level,
   1793                                                           DXGI_FORMAT format,
   1794                                                           const TextureHelper11 &texture,
   1795                                                           d3d11::SharedSRV *outSRV)
   1796 {
   1797    ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
   1798    return angle::Result::Stop;
   1799 }
   1800 
   1801 angle::Result TextureStorage11_External::createUAVForImage(const gl::Context *context,
   1802                                                           int level,
   1803                                                           DXGI_FORMAT format,
   1804                                                           const TextureHelper11 &texture,
   1805                                                           d3d11::SharedUAV *outUAV)
   1806 {
   1807    ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
   1808    return angle::Result::Stop;
   1809 }
   1810 
   1811 angle::Result TextureStorage11_External::getSwizzleTexture(const gl::Context *context,
   1812                                                           const TextureHelper11 **outTexture)
   1813 {
   1814    ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
   1815    return angle::Result::Stop;
   1816 }
   1817 
   1818 angle::Result TextureStorage11_External::getSwizzleRenderTarget(
   1819    const gl::Context *context,
   1820    int mipLevel,
   1821    const d3d11::RenderTargetView **outRTV)
   1822 {
   1823    ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
   1824    return angle::Result::Stop;
   1825 }
   1826 
   1827 void TextureStorage11_External::onLabelUpdate()
   1828 {
   1829    if (mTexture.valid())
   1830    {
   1831        mTexture.setKHRDebugLabel(&mKHRDebugLabel);
   1832    }
   1833 }
   1834 
   1835 TextureStorage11ImmutableBase::TextureStorage11ImmutableBase(Renderer11 *renderer,
   1836                                                             UINT bindFlags,
   1837                                                             UINT miscFlags,
   1838                                                             GLenum internalFormat,
   1839                                                             const std::string &label)
   1840    : TextureStorage11(renderer, bindFlags, miscFlags, internalFormat, label)
   1841 {}
   1842 
   1843 void TextureStorage11ImmutableBase::associateImage(Image11 *, const gl::ImageIndex &) {}
   1844 
   1845 void TextureStorage11ImmutableBase::disassociateImage(const gl::ImageIndex &, Image11 *) {}
   1846 
   1847 void TextureStorage11ImmutableBase::verifyAssociatedImageValid(const gl::ImageIndex &, Image11 *) {}
   1848 
   1849 angle::Result TextureStorage11ImmutableBase::releaseAssociatedImage(const gl::Context *context,
   1850                                                                    const gl::ImageIndex &,
   1851                                                                    Image11 *)
   1852 {
   1853    return angle::Result::Continue;
   1854 }
   1855 
   1856 angle::Result TextureStorage11ImmutableBase::createSRVForImage(const gl::Context *context,
   1857                                                               int level,
   1858                                                               DXGI_FORMAT format,
   1859                                                               const TextureHelper11 &texture,
   1860                                                               d3d11::SharedSRV *outSRV)
   1861 {
   1862    ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
   1863    return angle::Result::Stop;
   1864 }
   1865 
   1866 angle::Result TextureStorage11ImmutableBase::createUAVForImage(const gl::Context *context,
   1867                                                               int level,
   1868                                                               DXGI_FORMAT format,
   1869                                                               const TextureHelper11 &texture,
   1870                                                               d3d11::SharedUAV *outUAV)
   1871 {
   1872    ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
   1873    return angle::Result::Stop;
   1874 }
   1875 
   1876 TextureStorage11_EGLImage::TextureStorage11_EGLImage(Renderer11 *renderer,
   1877                                                     EGLImageD3D *eglImage,
   1878                                                     RenderTarget11 *renderTarget11,
   1879                                                     const std::string &label)
   1880    : TextureStorage11ImmutableBase(renderer,
   1881                                    D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE,
   1882                                    0,
   1883                                    renderTarget11->getInternalFormat(),
   1884                                    label),
   1885      mImage(eglImage),
   1886      mCurrentRenderTarget(0),
   1887      mSwizzleTexture(),
   1888      mSwizzleRenderTargets(gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
   1889 {
   1890    mCurrentRenderTarget = reinterpret_cast<uintptr_t>(renderTarget11);
   1891 
   1892    mMipLevels     = 1;
   1893    mTextureWidth  = renderTarget11->getWidth();
   1894    mTextureHeight = renderTarget11->getHeight();
   1895    mTextureDepth  = 1;
   1896 }
   1897 
   1898 TextureStorage11_EGLImage::~TextureStorage11_EGLImage() {}
   1899 
   1900 angle::Result TextureStorage11_EGLImage::getSubresourceIndex(const gl::Context *context,
   1901                                                             const gl::ImageIndex &index,
   1902                                                             UINT *outSubresourceIndex) const
   1903 {
   1904    ASSERT(index.getType() == gl::TextureType::_2D);
   1905    ASSERT(index.getLevelIndex() == 0);
   1906 
   1907    RenderTarget11 *renderTarget11 = nullptr;
   1908    ANGLE_TRY(getImageRenderTarget(context, &renderTarget11));
   1909    *outSubresourceIndex = renderTarget11->getSubresourceIndex();
   1910    return angle::Result::Continue;
   1911 }
   1912 
   1913 angle::Result TextureStorage11_EGLImage::getResource(const gl::Context *context,
   1914                                                     const TextureHelper11 **outResource)
   1915 {
   1916    ANGLE_TRY(checkForUpdatedRenderTarget(context));
   1917 
   1918    RenderTarget11 *renderTarget11 = nullptr;
   1919    ANGLE_TRY(getImageRenderTarget(context, &renderTarget11));
   1920    *outResource = &renderTarget11->getTexture();
   1921    return angle::Result::Continue;
   1922 }
   1923 
   1924 angle::Result TextureStorage11_EGLImage::getSRVForSampler(const gl::Context *context,
   1925                                                          const gl::TextureState &textureState,
   1926                                                          const gl::SamplerState &sampler,
   1927                                                          const d3d11::SharedSRV **outSRV)
   1928 {
   1929    ANGLE_TRY(checkForUpdatedRenderTarget(context));
   1930    return TextureStorage11::getSRVForSampler(context, textureState, sampler, outSRV);
   1931 }
   1932 
   1933 angle::Result TextureStorage11_EGLImage::getMippedResource(const gl::Context *context,
   1934                                                           const TextureHelper11 **)
   1935 {
   1936    // This shouldn't be called unless the zero max LOD workaround is active.
   1937    // EGL images are unavailable in this configuration.
   1938    ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
   1939    return angle::Result::Stop;
   1940 }
   1941 
   1942 angle::Result TextureStorage11_EGLImage::findRenderTarget(const gl::Context *context,
   1943                                                          const gl::ImageIndex &index,
   1944                                                          GLsizei samples,
   1945                                                          RenderTargetD3D **outRT) const
   1946 {
   1947    // Since the render target of an EGL image will be updated when orphaning, trying to find a
   1948    // cache of it can be rarely useful.
   1949    ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
   1950    return angle::Result::Stop;
   1951 }
   1952 
   1953 angle::Result TextureStorage11_EGLImage::getRenderTarget(const gl::Context *context,
   1954                                                         const gl::ImageIndex &index,
   1955                                                         GLsizei samples,
   1956                                                         RenderTargetD3D **outRT)
   1957 {
   1958    ASSERT(!index.hasLayer());
   1959    ASSERT(index.getLevelIndex() == 0);
   1960 
   1961    ANGLE_TRY(checkForUpdatedRenderTarget(context));
   1962 
   1963    return mImage->getRenderTarget(context, outRT);
   1964 }
   1965 
   1966 angle::Result TextureStorage11_EGLImage::copyToStorage(const gl::Context *context,
   1967                                                       TextureStorage *destStorage)
   1968 {
   1969    const TextureHelper11 *sourceResouce = nullptr;
   1970    ANGLE_TRY(getResource(context, &sourceResouce));
   1971 
   1972    ASSERT(destStorage);
   1973    TextureStorage11_2D *dest11         = GetAs<TextureStorage11_2D>(destStorage);
   1974    const TextureHelper11 *destResource = nullptr;
   1975    ANGLE_TRY(dest11->getResource(context, &destResource));
   1976 
   1977    ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
   1978    immediateContext->CopyResource(destResource->get(), sourceResouce->get());
   1979 
   1980    dest11->markDirty();
   1981 
   1982    return angle::Result::Continue;
   1983 }
   1984 
   1985 angle::Result TextureStorage11_EGLImage::useLevelZeroWorkaroundTexture(const gl::Context *context,
   1986                                                                       bool)
   1987 {
   1988    ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
   1989    return angle::Result::Stop;
   1990 }
   1991 
   1992 angle::Result TextureStorage11_EGLImage::getSwizzleTexture(const gl::Context *context,
   1993                                                           const TextureHelper11 **outTexture)
   1994 {
   1995    ASSERT(outTexture);
   1996 
   1997    if (!mSwizzleTexture.valid())
   1998    {
   1999        const auto &format = mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps());
   2000 
   2001        D3D11_TEXTURE2D_DESC desc;
   2002        desc.Width              = mTextureWidth;
   2003        desc.Height             = mTextureHeight;
   2004        desc.MipLevels          = mMipLevels;
   2005        desc.ArraySize          = 1;
   2006        desc.Format             = format.texFormat;
   2007        desc.SampleDesc.Count   = 1;
   2008        desc.SampleDesc.Quality = 0;
   2009        desc.Usage              = D3D11_USAGE_DEFAULT;
   2010        desc.BindFlags          = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
   2011        desc.CPUAccessFlags     = 0;
   2012        desc.MiscFlags          = 0;
   2013 
   2014        ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, format,
   2015                                             &mSwizzleTexture));
   2016        mSwizzleTexture.setLabels("TexStorageEGLImage.SwizzleTexture", &mKHRDebugLabel);
   2017    }
   2018 
   2019    *outTexture = &mSwizzleTexture;
   2020    return angle::Result::Continue;
   2021 }
   2022 
   2023 angle::Result TextureStorage11_EGLImage::getSwizzleRenderTarget(
   2024    const gl::Context *context,
   2025    int mipLevel,
   2026    const d3d11::RenderTargetView **outRTV)
   2027 {
   2028    ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
   2029    ASSERT(outRTV);
   2030 
   2031    if (!mSwizzleRenderTargets[mipLevel].valid())
   2032    {
   2033        const TextureHelper11 *swizzleTexture = nullptr;
   2034        ANGLE_TRY(getSwizzleTexture(context, &swizzleTexture));
   2035 
   2036        D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
   2037        rtvDesc.Format =
   2038            mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()).rtvFormat;
   2039        rtvDesc.ViewDimension      = D3D11_RTV_DIMENSION_TEXTURE2D;
   2040        rtvDesc.Texture2D.MipSlice = mTopLevel + mipLevel;
   2041 
   2042        ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), rtvDesc,
   2043                                              mSwizzleTexture.get(),
   2044                                              &mSwizzleRenderTargets[mipLevel]));
   2045    }
   2046 
   2047    *outRTV = &mSwizzleRenderTargets[mipLevel];
   2048    return angle::Result::Continue;
   2049 }
   2050 
   2051 angle::Result TextureStorage11_EGLImage::checkForUpdatedRenderTarget(const gl::Context *context)
   2052 {
   2053    RenderTarget11 *renderTarget11 = nullptr;
   2054    ANGLE_TRY(getImageRenderTarget(context, &renderTarget11));
   2055 
   2056    if (mCurrentRenderTarget != reinterpret_cast<uintptr_t>(renderTarget11))
   2057    {
   2058        clearSRVCache();
   2059        mCurrentRenderTarget = reinterpret_cast<uintptr_t>(renderTarget11);
   2060    }
   2061 
   2062    return angle::Result::Continue;
   2063 }
   2064 
   2065 angle::Result TextureStorage11_EGLImage::createSRVForSampler(const gl::Context *context,
   2066                                                             int baseLevel,
   2067                                                             int mipLevels,
   2068                                                             DXGI_FORMAT format,
   2069                                                             const TextureHelper11 &texture,
   2070                                                             d3d11::SharedSRV *outSRV)
   2071 {
   2072    ASSERT(baseLevel == 0);
   2073    ASSERT(mipLevels == 1);
   2074    ASSERT(outSRV);
   2075 
   2076    // Create a new SRV only for the swizzle texture.  Otherwise just return the Image's
   2077    // RenderTarget's SRV.
   2078    if (texture == mSwizzleTexture)
   2079    {
   2080        D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
   2081        srvDesc.Format                    = format;
   2082        srvDesc.ViewDimension             = D3D11_SRV_DIMENSION_TEXTURE2D;
   2083        srvDesc.Texture2D.MostDetailedMip = mTopLevel + baseLevel;
   2084        srvDesc.Texture2D.MipLevels       = mipLevels;
   2085 
   2086        ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(),
   2087                                              outSRV));
   2088        outSRV->setLabels("TexStorageEGLImage.SRV", &mKHRDebugLabel);
   2089    }
   2090    else
   2091    {
   2092        RenderTarget11 *renderTarget = nullptr;
   2093        ANGLE_TRY(getImageRenderTarget(context, &renderTarget));
   2094 
   2095        ASSERT(texture == renderTarget->getTexture());
   2096 
   2097        const d3d11::SharedSRV *srv;
   2098        ANGLE_TRY(renderTarget->getShaderResourceView(context, &srv));
   2099 
   2100        *outSRV = srv->makeCopy();
   2101    }
   2102 
   2103    return angle::Result::Continue;
   2104 }
   2105 
   2106 angle::Result TextureStorage11_EGLImage::getImageRenderTarget(const gl::Context *context,
   2107                                                              RenderTarget11 **outRT) const
   2108 {
   2109    RenderTargetD3D *renderTargetD3D = nullptr;
   2110    ANGLE_TRY(mImage->getRenderTarget(context, &renderTargetD3D));
   2111    *outRT = GetAs<RenderTarget11>(renderTargetD3D);
   2112    return angle::Result::Continue;
   2113 }
   2114 
   2115 void TextureStorage11_EGLImage::onLabelUpdate()
   2116 {
   2117    if (mSwizzleTexture.valid())
   2118    {
   2119        mSwizzleTexture.setKHRDebugLabel(&mKHRDebugLabel);
   2120    }
   2121 }
   2122 
   2123 TextureStorage11_Cube::TextureStorage11_Cube(Renderer11 *renderer,
   2124                                             GLenum internalformat,
   2125                                             BindFlags bindFlags,
   2126                                             int size,
   2127                                             int levels,
   2128                                             bool hintLevelZeroOnly,
   2129                                             const std::string &label)
   2130    : TextureStorage11(
   2131          renderer,
   2132          GetTextureBindFlags(internalformat, renderer->getRenderer11DeviceCaps(), bindFlags),
   2133          GetTextureMiscFlags(internalformat,
   2134                              renderer->getRenderer11DeviceCaps(),
   2135                              bindFlags,
   2136                              levels),
   2137          internalformat,
   2138          label),
   2139      mTexture(),
   2140      mLevelZeroTexture(),
   2141      mUseLevelZeroTexture(hintLevelZeroOnly && levels > 1),
   2142      mSwizzleTexture()
   2143 {
   2144    for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
   2145    {
   2146        for (unsigned int face = 0; face < gl::kCubeFaceCount; face++)
   2147        {
   2148            mAssociatedImages[face][level] = nullptr;
   2149            mRenderTarget[face][level]     = nullptr;
   2150        }
   2151    }
   2152 
   2153    for (unsigned int face = 0; face < gl::kCubeFaceCount; face++)
   2154    {
   2155        mLevelZeroRenderTarget[face] = nullptr;
   2156    }
   2157 
   2158    // adjust size if needed for compressed textures
   2159    int height = size;
   2160    d3d11::MakeValidSize(false, mFormatInfo.texFormat, &size, &height, &mTopLevel);
   2161 
   2162    mMipLevels     = mTopLevel + levels;
   2163    mTextureWidth  = size;
   2164    mTextureHeight = size;
   2165    mTextureDepth  = 1;
   2166 
   2167    // The LevelZeroOnly hint should only be true if the zero max LOD workaround is active.
   2168    ASSERT(!mUseLevelZeroTexture || mRenderer->getFeatures().zeroMaxLodWorkaround.enabled);
   2169 }
   2170 
   2171 angle::Result TextureStorage11_Cube::onDestroy(const gl::Context *context)
   2172 {
   2173    for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
   2174    {
   2175        for (unsigned int face = 0; face < gl::kCubeFaceCount; face++)
   2176        {
   2177            if (mAssociatedImages[face][level] != nullptr)
   2178            {
   2179                mAssociatedImages[face][level]->verifyAssociatedStorageValid(this);
   2180 
   2181                // We must let the Images recover their data before we delete it from the
   2182                // TextureStorage.
   2183                ANGLE_TRY(mAssociatedImages[face][level]->recoverFromAssociatedStorage(context));
   2184            }
   2185        }
   2186    }
   2187 
   2188    return angle::Result::Continue;
   2189 }
   2190 
   2191 TextureStorage11_Cube::~TextureStorage11_Cube() {}
   2192 
   2193 angle::Result TextureStorage11_Cube::getSubresourceIndex(const gl::Context *context,
   2194                                                         const gl::ImageIndex &index,
   2195                                                         UINT *outSubresourceIndex) const
   2196 {
   2197    UINT arraySlice = index.cubeMapFaceIndex();
   2198    if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled && mUseLevelZeroTexture &&
   2199        index.getLevelIndex() == 0)
   2200    {
   2201        UINT subresource = D3D11CalcSubresource(0, arraySlice, 1);
   2202        ASSERT(subresource != std::numeric_limits<UINT>::max());
   2203        *outSubresourceIndex = subresource;
   2204    }
   2205    else
   2206    {
   2207        UINT mipSlice    = static_cast<UINT>(index.getLevelIndex() + mTopLevel);
   2208        UINT subresource = D3D11CalcSubresource(mipSlice, arraySlice, mMipLevels);
   2209        ASSERT(subresource != std::numeric_limits<UINT>::max());
   2210        *outSubresourceIndex = subresource;
   2211    }
   2212    return angle::Result::Continue;
   2213 }
   2214 
   2215 angle::Result TextureStorage11_Cube::copyToStorage(const gl::Context *context,
   2216                                                   TextureStorage *destStorage)
   2217 {
   2218    ASSERT(destStorage);
   2219 
   2220    TextureStorage11_Cube *dest11 = GetAs<TextureStorage11_Cube>(destStorage);
   2221 
   2222    if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
   2223    {
   2224        ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
   2225 
   2226        // If either mTexture or mLevelZeroTexture exist, then we need to copy them into the
   2227        // corresponding textures in destStorage.
   2228        if (mTexture.valid())
   2229        {
   2230            ANGLE_TRY(dest11->useLevelZeroWorkaroundTexture(context, false));
   2231 
   2232            const TextureHelper11 *destResource = nullptr;
   2233            ANGLE_TRY(dest11->getResource(context, &destResource));
   2234 
   2235            immediateContext->CopyResource(destResource->get(), mTexture.get());
   2236        }
   2237 
   2238        if (mLevelZeroTexture.valid())
   2239        {
   2240            ANGLE_TRY(dest11->useLevelZeroWorkaroundTexture(context, true));
   2241 
   2242            const TextureHelper11 *destResource = nullptr;
   2243            ANGLE_TRY(dest11->getResource(context, &destResource));
   2244 
   2245            immediateContext->CopyResource(destResource->get(), mLevelZeroTexture.get());
   2246        }
   2247    }
   2248    else
   2249    {
   2250        const TextureHelper11 *sourceResouce = nullptr;
   2251        ANGLE_TRY(getResource(context, &sourceResouce));
   2252 
   2253        const TextureHelper11 *destResource = nullptr;
   2254        ANGLE_TRY(dest11->getResource(context, &destResource));
   2255 
   2256        ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
   2257        immediateContext->CopyResource(destResource->get(), sourceResouce->get());
   2258    }
   2259 
   2260    dest11->markDirty();
   2261 
   2262    return angle::Result::Continue;
   2263 }
   2264 
   2265 angle::Result TextureStorage11_Cube::useLevelZeroWorkaroundTexture(const gl::Context *context,
   2266                                                                   bool useLevelZeroTexture)
   2267 {
   2268    if (useLevelZeroTexture && mMipLevels > 1)
   2269    {
   2270        if (!mUseLevelZeroTexture && mTexture.valid())
   2271        {
   2272            ANGLE_TRY(ensureTextureExists(context, 1));
   2273 
   2274            // Pull data back from the mipped texture if necessary.
   2275            ASSERT(mLevelZeroTexture.valid());
   2276            ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
   2277 
   2278            for (int face = 0; face < 6; face++)
   2279            {
   2280                deviceContext->CopySubresourceRegion(mLevelZeroTexture.get(),
   2281                                                     D3D11CalcSubresource(0, face, 1), 0, 0, 0,
   2282                                                     mTexture.get(), face * mMipLevels, nullptr);
   2283            }
   2284        }
   2285 
   2286        mUseLevelZeroTexture = true;
   2287    }
   2288    else
   2289    {
   2290        if (mUseLevelZeroTexture && mLevelZeroTexture.valid())
   2291        {
   2292            ANGLE_TRY(ensureTextureExists(context, mMipLevels));
   2293 
   2294            // Pull data back from the level zero texture if necessary.
   2295            ASSERT(mTexture.valid());
   2296            ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
   2297 
   2298            for (int face = 0; face < 6; face++)
   2299            {
   2300                deviceContext->CopySubresourceRegion(mTexture.get(),
   2301                                                     D3D11CalcSubresource(0, face, mMipLevels), 0,
   2302                                                     0, 0, mLevelZeroTexture.get(), face, nullptr);
   2303            }
   2304        }
   2305 
   2306        mUseLevelZeroTexture = false;
   2307    }
   2308 
   2309    return angle::Result::Continue;
   2310 }
   2311 
   2312 void TextureStorage11_Cube::associateImage(Image11 *image, const gl::ImageIndex &index)
   2313 {
   2314    const GLint level       = index.getLevelIndex();
   2315    const GLint layerTarget = index.cubeMapFaceIndex();
   2316 
   2317    ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
   2318    ASSERT(0 <= layerTarget && layerTarget < static_cast<GLint>(gl::kCubeFaceCount));
   2319 
   2320    if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
   2321    {
   2322        if (0 <= layerTarget && layerTarget < static_cast<GLint>(gl::kCubeFaceCount))
   2323        {
   2324            mAssociatedImages[layerTarget][level] = image;
   2325        }
   2326    }
   2327 }
   2328 
   2329 void TextureStorage11_Cube::verifyAssociatedImageValid(const gl::ImageIndex &index,
   2330                                                       Image11 *expectedImage)
   2331 {
   2332    const GLint level       = index.getLevelIndex();
   2333    const GLint layerTarget = index.cubeMapFaceIndex();
   2334 
   2335    ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
   2336    ASSERT(0 <= layerTarget && layerTarget < static_cast<GLint>(gl::kCubeFaceCount));
   2337    // This validation check should never return false. It means the Image/TextureStorage
   2338    // association is broken.
   2339    ASSERT(mAssociatedImages[layerTarget][level] == expectedImage);
   2340 }
   2341 
   2342 // disassociateImage allows an Image to end its association with a Storage.
   2343 void TextureStorage11_Cube::disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage)
   2344 {
   2345    const GLint level       = index.getLevelIndex();
   2346    const GLint layerTarget = index.cubeMapFaceIndex();
   2347 
   2348    ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
   2349    ASSERT(0 <= layerTarget && layerTarget < static_cast<GLint>(gl::kCubeFaceCount));
   2350    ASSERT(mAssociatedImages[layerTarget][level] == expectedImage);
   2351    mAssociatedImages[layerTarget][level] = nullptr;
   2352 }
   2353 
   2354 // releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image
   2355 // recover its data before ending the association.
   2356 angle::Result TextureStorage11_Cube::releaseAssociatedImage(const gl::Context *context,
   2357                                                            const gl::ImageIndex &index,
   2358                                                            Image11 *incomingImage)
   2359 {
   2360    const GLint level       = index.getLevelIndex();
   2361    const GLint layerTarget = index.cubeMapFaceIndex();
   2362 
   2363    ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
   2364    ASSERT(0 <= layerTarget && layerTarget < static_cast<GLint>(gl::kCubeFaceCount));
   2365 
   2366    if ((0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
   2367    {
   2368        if (0 <= layerTarget && layerTarget < static_cast<GLint>(gl::kCubeFaceCount))
   2369        {
   2370            // No need to let the old Image recover its data, if it is also the incoming Image.
   2371            if (mAssociatedImages[layerTarget][level] != nullptr &&
   2372                mAssociatedImages[layerTarget][level] != incomingImage)
   2373            {
   2374                // Ensure that the Image is still associated with this TextureStorage.
   2375                mAssociatedImages[layerTarget][level]->verifyAssociatedStorageValid(this);
   2376 
   2377                // Force the image to recover from storage before its data is overwritten.
   2378                // This will reset mAssociatedImages[level] to nullptr too.
   2379                ANGLE_TRY(
   2380                    mAssociatedImages[layerTarget][level]->recoverFromAssociatedStorage(context));
   2381            }
   2382        }
   2383    }
   2384 
   2385    return angle::Result::Continue;
   2386 }
   2387 
   2388 angle::Result TextureStorage11_Cube::getResource(const gl::Context *context,
   2389                                                 const TextureHelper11 **outResource)
   2390 {
   2391    if (mUseLevelZeroTexture && mMipLevels > 1)
   2392    {
   2393        ANGLE_TRY(ensureTextureExists(context, 1));
   2394        *outResource = &mLevelZeroTexture;
   2395    }
   2396    else
   2397    {
   2398        ANGLE_TRY(ensureTextureExists(context, mMipLevels));
   2399        *outResource = &mTexture;
   2400    }
   2401    return angle::Result::Continue;
   2402 }
   2403 
   2404 angle::Result TextureStorage11_Cube::getMippedResource(const gl::Context *context,
   2405                                                       const TextureHelper11 **outResource)
   2406 {
   2407    // This shouldn't be called unless the zero max LOD workaround is active.
   2408    ASSERT(mRenderer->getFeatures().zeroMaxLodWorkaround.enabled);
   2409 
   2410    ANGLE_TRY(ensureTextureExists(context, mMipLevels));
   2411    *outResource = &mTexture;
   2412    return angle::Result::Continue;
   2413 }
   2414 
   2415 angle::Result TextureStorage11_Cube::ensureTextureExists(const gl::Context *context, int mipLevels)
   2416 {
   2417    // If mMipLevels = 1 then always use mTexture rather than mLevelZeroTexture.
   2418    ANGLE_TRY(resolveTexture(context));
   2419    bool useLevelZeroTexture       = mRenderer->getFeatures().zeroMaxLodWorkaround.enabled
   2420                                         ? (mipLevels == 1) && (mMipLevels > 1)
   2421                                         : false;
   2422    TextureHelper11 *outputTexture = useLevelZeroTexture ? &mLevelZeroTexture : &mTexture;
   2423 
   2424    // if the size is not positive this should be treated as an incomplete texture
   2425    // we handle that here by skipping the d3d texture creation
   2426    if (!outputTexture->valid() && mTextureWidth > 0 && mTextureHeight > 0)
   2427    {
   2428        ASSERT(mMipLevels > 0);
   2429 
   2430        D3D11_TEXTURE2D_DESC desc;
   2431        desc.Width     = mTextureWidth;
   2432        desc.Height    = mTextureHeight;
   2433        desc.MipLevels = mipLevels;
   2434        desc.ArraySize = gl::kCubeFaceCount;
   2435        desc.Format    = isUnorderedAccess() ? mFormatInfo.typelessFormat : mFormatInfo.texFormat;
   2436        desc.SampleDesc.Count   = 1;
   2437        desc.SampleDesc.Quality = 0;
   2438        desc.Usage              = D3D11_USAGE_DEFAULT;
   2439        desc.BindFlags          = getBindFlags();
   2440        desc.CPUAccessFlags     = 0;
   2441        desc.MiscFlags          = D3D11_RESOURCE_MISC_TEXTURECUBE | getMiscFlags();
   2442 
   2443        ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, mFormatInfo,
   2444                                             outputTexture));
   2445        outputTexture->setLabels("TexStorageCube.Texture", &mKHRDebugLabel);
   2446    }
   2447 
   2448    return angle::Result::Continue;
   2449 }
   2450 
   2451 angle::Result TextureStorage11_Cube::findRenderTarget(const gl::Context *context,
   2452                                                      const gl::ImageIndex &index,
   2453                                                      GLsizei samples,
   2454                                                      RenderTargetD3D **outRT) const
   2455 {
   2456    const int faceIndex = index.cubeMapFaceIndex();
   2457    const int level     = index.getLevelIndex();
   2458 
   2459    ASSERT(level >= 0 && level < getLevelCount());
   2460    ASSERT(faceIndex >= 0 && faceIndex < static_cast<GLint>(gl::kCubeFaceCount));
   2461 
   2462    bool needMS = samples > 0;
   2463    if (needMS)
   2464    {
   2465        return findMultisampledRenderTarget(context, index, samples, outRT);
   2466    }
   2467 
   2468    if (!mRenderTarget[faceIndex][level])
   2469    {
   2470        if (mUseLevelZeroTexture)
   2471        {
   2472            ASSERT(index.getLevelIndex() == 0);
   2473            ASSERT(outRT);
   2474            *outRT = mLevelZeroRenderTarget[faceIndex].get();
   2475            return angle::Result::Continue;
   2476        }
   2477    }
   2478 
   2479    ASSERT(outRT);
   2480    *outRT = mRenderTarget[faceIndex][level].get();
   2481    return angle::Result::Continue;
   2482 }
   2483 
   2484 angle::Result TextureStorage11_Cube::createRenderTargetSRV(const gl::Context *context,
   2485                                                           const TextureHelper11 &texture,
   2486                                                           const gl::ImageIndex &index,
   2487                                                           DXGI_FORMAT resourceFormat,
   2488                                                           d3d11::SharedSRV *srv) const
   2489 {
   2490    D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
   2491    srvDesc.Format                         = resourceFormat;
   2492    srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + index.getLevelIndex();
   2493    srvDesc.Texture2DArray.MipLevels       = 1;
   2494    srvDesc.Texture2DArray.FirstArraySlice = index.cubeMapFaceIndex();
   2495    srvDesc.Texture2DArray.ArraySize       = 1;
   2496 
   2497    if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_10_0)
   2498    {
   2499        srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
   2500    }
   2501    else
   2502    {
   2503        // Will be used with Texture2D sampler, not TextureCube
   2504        srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
   2505    }
   2506 
   2507    ANGLE_TRY(
   2508        mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), srv));
   2509    return angle::Result::Continue;
   2510 }
   2511 
   2512 angle::Result TextureStorage11_Cube::getRenderTarget(const gl::Context *context,
   2513                                                     const gl::ImageIndex &index,
   2514                                                     GLsizei samples,
   2515                                                     RenderTargetD3D **outRT)
   2516 {
   2517    const int faceIndex = index.cubeMapFaceIndex();
   2518    const int level     = index.getLevelIndex();
   2519 
   2520    ASSERT(level >= 0 && level < getLevelCount());
   2521    ASSERT(faceIndex >= 0 && faceIndex < static_cast<GLint>(gl::kCubeFaceCount));
   2522 
   2523    bool needMS = samples > 0;
   2524    if (needMS)
   2525    {
   2526        return getMultisampledRenderTarget(context, index, samples, outRT);
   2527    }
   2528    else
   2529    {
   2530        ANGLE_TRY(resolveTexture(context));
   2531    }
   2532 
   2533    Context11 *context11 = GetImplAs<Context11>(context);
   2534 
   2535    if (!mRenderTarget[faceIndex][level])
   2536    {
   2537        if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
   2538        {
   2539            ASSERT(index.getLevelIndex() == 0);
   2540            ANGLE_TRY(useLevelZeroWorkaroundTexture(context, true));
   2541        }
   2542 
   2543        const TextureHelper11 *texture = nullptr;
   2544        ANGLE_TRY(getResource(context, &texture));
   2545 
   2546        if (mUseLevelZeroTexture)
   2547        {
   2548            if (!mLevelZeroRenderTarget[faceIndex])
   2549            {
   2550                D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
   2551                rtvDesc.Format                         = mFormatInfo.rtvFormat;
   2552                rtvDesc.ViewDimension                  = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
   2553                rtvDesc.Texture2DArray.MipSlice        = mTopLevel + level;
   2554                rtvDesc.Texture2DArray.FirstArraySlice = faceIndex;
   2555                rtvDesc.Texture2DArray.ArraySize       = 1;
   2556 
   2557                d3d11::RenderTargetView rtv;
   2558                ANGLE_TRY(
   2559                    mRenderer->allocateResource(context11, rtvDesc, mLevelZeroTexture.get(), &rtv));
   2560 
   2561                mLevelZeroRenderTarget[faceIndex].reset(new TextureRenderTarget11(
   2562                    std::move(rtv), mLevelZeroTexture, d3d11::SharedSRV(), d3d11::SharedSRV(),
   2563                    mFormatInfo.internalFormat, getFormatSet(), getLevelWidth(level),
   2564                    getLevelHeight(level), 1, 0));
   2565            }
   2566 
   2567            ASSERT(outRT);
   2568            *outRT = mLevelZeroRenderTarget[faceIndex].get();
   2569            return angle::Result::Continue;
   2570        }
   2571 
   2572        d3d11::SharedSRV srv;
   2573        ANGLE_TRY(createRenderTargetSRV(context, *texture, index, mFormatInfo.srvFormat, &srv));
   2574        d3d11::SharedSRV blitSRV;
   2575        if (mFormatInfo.blitSRVFormat != mFormatInfo.srvFormat)
   2576        {
   2577            ANGLE_TRY(createRenderTargetSRV(context, *texture, index, mFormatInfo.blitSRVFormat,
   2578                                            &blitSRV));
   2579        }
   2580        else
   2581        {
   2582            blitSRV = srv.makeCopy();
   2583        }
   2584 
   2585        srv.setLabels("TexStorageCube.RenderTargetSRV", &mKHRDebugLabel);
   2586 
   2587        if (mFormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN)
   2588        {
   2589            D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
   2590            rtvDesc.Format                         = mFormatInfo.rtvFormat;
   2591            rtvDesc.ViewDimension                  = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
   2592            rtvDesc.Texture2DArray.MipSlice        = mTopLevel + level;
   2593            rtvDesc.Texture2DArray.FirstArraySlice = faceIndex;
   2594            rtvDesc.Texture2DArray.ArraySize       = 1;
   2595 
   2596            d3d11::RenderTargetView rtv;
   2597            ANGLE_TRY(mRenderer->allocateResource(context11, rtvDesc, texture->get(), &rtv));
   2598            rtv.setLabels("TexStorageCube.RenderTargetRTV", &mKHRDebugLabel);
   2599 
   2600            mRenderTarget[faceIndex][level].reset(new TextureRenderTarget11(
   2601                std::move(rtv), *texture, srv, blitSRV, mFormatInfo.internalFormat, getFormatSet(),
   2602                getLevelWidth(level), getLevelHeight(level), 1, 0));
   2603        }
   2604        else if (mFormatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN)
   2605        {
   2606            D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
   2607            dsvDesc.Format                         = mFormatInfo.dsvFormat;
   2608            dsvDesc.ViewDimension                  = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
   2609            dsvDesc.Flags                          = 0;
   2610            dsvDesc.Texture2DArray.MipSlice        = mTopLevel + level;
   2611            dsvDesc.Texture2DArray.FirstArraySlice = faceIndex;
   2612            dsvDesc.Texture2DArray.ArraySize       = 1;
   2613 
   2614            d3d11::DepthStencilView dsv;
   2615            ANGLE_TRY(mRenderer->allocateResource(context11, dsvDesc, texture->get(), &dsv));
   2616            dsv.setLabels("TexStorageCube.RenderTargetDSV", &mKHRDebugLabel);
   2617 
   2618            mRenderTarget[faceIndex][level].reset(new TextureRenderTarget11(
   2619                std::move(dsv), *texture, srv, mFormatInfo.internalFormat, getFormatSet(),
   2620                getLevelWidth(level), getLevelHeight(level), 1, 0));
   2621        }
   2622        else
   2623        {
   2624            UNREACHABLE();
   2625        }
   2626    }
   2627 
   2628    ASSERT(outRT);
   2629    *outRT = mRenderTarget[faceIndex][level].get();
   2630    return angle::Result::Continue;
   2631 }
   2632 
   2633 angle::Result TextureStorage11_Cube::createSRVForSampler(const gl::Context *context,
   2634                                                         int baseLevel,
   2635                                                         int mipLevels,
   2636                                                         DXGI_FORMAT format,
   2637                                                         const TextureHelper11 &texture,
   2638                                                         d3d11::SharedSRV *outSRV)
   2639 {
   2640    ASSERT(outSRV);
   2641 
   2642    D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
   2643    srvDesc.Format = format;
   2644 
   2645    // Unnormalized integer cube maps are not supported by DX11; we emulate them as an array of six
   2646    // 2D textures
   2647    const GLenum componentType = d3d11::GetComponentType(format);
   2648    if (componentType == GL_INT || componentType == GL_UNSIGNED_INT)
   2649    {
   2650        srvDesc.ViewDimension                  = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
   2651        srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + baseLevel;
   2652        srvDesc.Texture2DArray.MipLevels       = mipLevels;
   2653        srvDesc.Texture2DArray.FirstArraySlice = 0;
   2654        srvDesc.Texture2DArray.ArraySize       = gl::kCubeFaceCount;
   2655    }
   2656    else
   2657    {
   2658        srvDesc.ViewDimension               = D3D11_SRV_DIMENSION_TEXTURECUBE;
   2659        srvDesc.TextureCube.MipLevels       = mipLevels;
   2660        srvDesc.TextureCube.MostDetailedMip = mTopLevel + baseLevel;
   2661    }
   2662 
   2663    const TextureHelper11 *srvTexture = &texture;
   2664 
   2665    if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
   2666    {
   2667        ASSERT(mTopLevel == 0);
   2668        ASSERT(baseLevel == 0);
   2669        // This code also assumes that the incoming texture equals either mLevelZeroTexture or
   2670        // mTexture.
   2671 
   2672        if (mipLevels == 1 && mMipLevels > 1)
   2673        {
   2674            // We must use a SRV on the level-zero-only texture.
   2675            ANGLE_TRY(ensureTextureExists(context, 1));
   2676            srvTexture = &mLevelZeroTexture;
   2677        }
   2678        else
   2679        {
   2680            ASSERT(mipLevels == static_cast<int>(mMipLevels));
   2681            ASSERT(mTexture.valid() && texture == mTexture);
   2682            srvTexture = &mTexture;
   2683        }
   2684    }
   2685 
   2686    ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, srvTexture->get(),
   2687                                          outSRV));
   2688    outSRV->setLabels("TexStorageCube.SRV", &mKHRDebugLabel);
   2689 
   2690    return angle::Result::Continue;
   2691 }
   2692 
   2693 angle::Result TextureStorage11_Cube::createSRVForImage(const gl::Context *context,
   2694                                                       int level,
   2695                                                       DXGI_FORMAT format,
   2696                                                       const TextureHelper11 &texture,
   2697                                                       d3d11::SharedSRV *outSRV)
   2698 {
   2699    ASSERT(outSRV);
   2700    D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
   2701    srvDesc.Format                         = format;
   2702    srvDesc.ViewDimension                  = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
   2703    srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + level;
   2704    srvDesc.Texture2DArray.MipLevels       = 1;
   2705    srvDesc.Texture2DArray.FirstArraySlice = 0;
   2706    srvDesc.Texture2DArray.ArraySize       = gl::kCubeFaceCount;
   2707    ANGLE_TRY(
   2708        mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV));
   2709    outSRV->setLabels("TexStorageCube.SRVForImage", &mKHRDebugLabel);
   2710    return angle::Result::Continue;
   2711 }
   2712 
   2713 angle::Result TextureStorage11_Cube::createUAVForImage(const gl::Context *context,
   2714                                                       int level,
   2715                                                       DXGI_FORMAT format,
   2716                                                       const TextureHelper11 &texture,
   2717                                                       d3d11::SharedUAV *outUAV)
   2718 {
   2719    ASSERT(outUAV);
   2720    D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
   2721    uavDesc.Format                         = format;
   2722    uavDesc.ViewDimension                  = D3D11_UAV_DIMENSION_TEXTURE2DARRAY;
   2723    uavDesc.Texture2DArray.MipSlice        = mTopLevel + level;
   2724    uavDesc.Texture2DArray.FirstArraySlice = 0;
   2725    uavDesc.Texture2DArray.ArraySize       = gl::kCubeFaceCount;
   2726    ANGLE_TRY(
   2727        mRenderer->allocateResource(GetImplAs<Context11>(context), uavDesc, texture.get(), outUAV));
   2728    outUAV->setLabels("TexStorageCube.UAVForImage", &mKHRDebugLabel);
   2729    return angle::Result::Continue;
   2730 }
   2731 
   2732 angle::Result TextureStorage11_Cube::getSwizzleTexture(const gl::Context *context,
   2733                                                       const TextureHelper11 **outTexture)
   2734 {
   2735    ASSERT(outTexture);
   2736 
   2737    if (!mSwizzleTexture.valid())
   2738    {
   2739        const auto &format = mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps());
   2740 
   2741        D3D11_TEXTURE2D_DESC desc;
   2742        desc.Width              = mTextureWidth;
   2743        desc.Height             = mTextureHeight;
   2744        desc.MipLevels          = mMipLevels;
   2745        desc.ArraySize          = gl::kCubeFaceCount;
   2746        desc.Format             = format.texFormat;
   2747        desc.SampleDesc.Count   = 1;
   2748        desc.SampleDesc.Quality = 0;
   2749        desc.Usage              = D3D11_USAGE_DEFAULT;
   2750        desc.BindFlags          = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
   2751        desc.CPUAccessFlags     = 0;
   2752        desc.MiscFlags          = D3D11_RESOURCE_MISC_TEXTURECUBE;
   2753 
   2754        ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, format,
   2755                                             &mSwizzleTexture));
   2756        mSwizzleTexture.setLabels("TexStorageCube.SwizzleTexture", &mKHRDebugLabel);
   2757    }
   2758 
   2759    *outTexture = &mSwizzleTexture;
   2760    return angle::Result::Continue;
   2761 }
   2762 
   2763 angle::Result TextureStorage11_Cube::getSwizzleRenderTarget(const gl::Context *context,
   2764                                                            int mipLevel,
   2765                                                            const d3d11::RenderTargetView **outRTV)
   2766 {
   2767    ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
   2768    ASSERT(outRTV);
   2769 
   2770    if (!mSwizzleRenderTargets[mipLevel].valid())
   2771    {
   2772        const TextureHelper11 *swizzleTexture = nullptr;
   2773        ANGLE_TRY(getSwizzleTexture(context, &swizzleTexture));
   2774 
   2775        D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
   2776        rtvDesc.Format =
   2777            mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()).rtvFormat;
   2778        rtvDesc.ViewDimension                  = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
   2779        rtvDesc.Texture2DArray.MipSlice        = mTopLevel + mipLevel;
   2780        rtvDesc.Texture2DArray.FirstArraySlice = 0;
   2781        rtvDesc.Texture2DArray.ArraySize       = gl::kCubeFaceCount;
   2782 
   2783        ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), rtvDesc,
   2784                                              mSwizzleTexture.get(),
   2785                                              &mSwizzleRenderTargets[mipLevel]));
   2786    }
   2787 
   2788    *outRTV = &mSwizzleRenderTargets[mipLevel];
   2789    return angle::Result::Continue;
   2790 }
   2791 
   2792 angle::Result TextureStorage11_Cube::ensureDropStencilTexture(const gl::Context *context,
   2793                                                              DropStencil *dropStencilOut)
   2794 {
   2795    if (mDropStencilTexture.valid())
   2796    {
   2797        *dropStencilOut = DropStencil::ALREADY_EXISTS;
   2798        return angle::Result::Continue;
   2799    }
   2800 
   2801    D3D11_TEXTURE2D_DESC dropDesc = {};
   2802    dropDesc.ArraySize            = 6;
   2803    dropDesc.BindFlags            = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_DEPTH_STENCIL;
   2804    dropDesc.CPUAccessFlags       = 0;
   2805    dropDesc.Format               = DXGI_FORMAT_R32_TYPELESS;
   2806    dropDesc.Height               = mTextureHeight;
   2807    dropDesc.MipLevels            = mMipLevels;
   2808    dropDesc.MiscFlags            = D3D11_RESOURCE_MISC_TEXTURECUBE;
   2809    dropDesc.SampleDesc.Count     = 1;
   2810    dropDesc.SampleDesc.Quality   = 0;
   2811    dropDesc.Usage                = D3D11_USAGE_DEFAULT;
   2812    dropDesc.Width                = mTextureWidth;
   2813 
   2814    const auto &format =
   2815        d3d11::Format::Get(GL_DEPTH_COMPONENT32F, mRenderer->getRenderer11DeviceCaps());
   2816    ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), dropDesc, format,
   2817                                         &mDropStencilTexture));
   2818    mDropStencilTexture.setLabels("TexStorageCube.DropStencil", &mKHRDebugLabel);
   2819 
   2820    ANGLE_TRY(initDropStencilTexture(context, gl::ImageIndexIterator::MakeCube(0, mMipLevels)));
   2821 
   2822    *dropStencilOut = DropStencil::CREATED;
   2823    return angle::Result::Continue;
   2824 }
   2825 
   2826 angle::Result TextureStorage11_Cube::resolveTexture(const gl::Context *context)
   2827 {
   2828    if (mMSTexInfo && mMSTexInfo->msTex && mMSTexInfo->msTextureNeedsResolve)
   2829    {
   2830        ANGLE_TRY(resolveTextureHelper(context, mTexture));
   2831        onStateChange(angle::SubjectMessage::ContentsChanged);
   2832    }
   2833    return angle::Result::Continue;
   2834 }
   2835 
   2836 void TextureStorage11_Cube::onLabelUpdate()
   2837 {
   2838    if (mTexture.valid())
   2839    {
   2840        mTexture.setKHRDebugLabel(&mKHRDebugLabel);
   2841    }
   2842    if (mLevelZeroTexture.valid())
   2843    {
   2844        mLevelZeroTexture.setKHRDebugLabel(&mKHRDebugLabel);
   2845    }
   2846    if (mSwizzleTexture.valid())
   2847    {
   2848        mSwizzleTexture.setKHRDebugLabel(&mKHRDebugLabel);
   2849    }
   2850 }
   2851 
   2852 TextureStorage11_3D::TextureStorage11_3D(Renderer11 *renderer,
   2853                                         GLenum internalformat,
   2854                                         BindFlags bindFlags,
   2855                                         GLsizei width,
   2856                                         GLsizei height,
   2857                                         GLsizei depth,
   2858                                         int levels,
   2859                                         const std::string &label)
   2860    : TextureStorage11(
   2861          renderer,
   2862          GetTextureBindFlags(internalformat, renderer->getRenderer11DeviceCaps(), bindFlags),
   2863          GetTextureMiscFlags(internalformat,
   2864                              renderer->getRenderer11DeviceCaps(),
   2865                              bindFlags,
   2866                              levels),
   2867          internalformat,
   2868          label)
   2869 {
   2870    for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
   2871    {
   2872        mAssociatedImages[i]   = nullptr;
   2873        mLevelRenderTargets[i] = nullptr;
   2874    }
   2875 
   2876    // adjust size if needed for compressed textures
   2877    d3d11::MakeValidSize(false, mFormatInfo.texFormat, &width, &height, &mTopLevel);
   2878 
   2879    mMipLevels     = mTopLevel + levels;
   2880    mTextureWidth  = width;
   2881    mTextureHeight = height;
   2882    mTextureDepth  = depth;
   2883 }
   2884 
   2885 angle::Result TextureStorage11_3D::onDestroy(const gl::Context *context)
   2886 {
   2887    for (unsigned i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
   2888    {
   2889        if (mAssociatedImages[i] != nullptr)
   2890        {
   2891            mAssociatedImages[i]->verifyAssociatedStorageValid(this);
   2892 
   2893            // We must let the Images recover their data before we delete it from the
   2894            // TextureStorage.
   2895            ANGLE_TRY(mAssociatedImages[i]->recoverFromAssociatedStorage(context));
   2896        }
   2897    }
   2898 
   2899    return angle::Result::Continue;
   2900 }
   2901 
   2902 TextureStorage11_3D::~TextureStorage11_3D() {}
   2903 
   2904 void TextureStorage11_3D::associateImage(Image11 *image, const gl::ImageIndex &index)
   2905 {
   2906    const GLint level = index.getLevelIndex();
   2907 
   2908    ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
   2909 
   2910    if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
   2911    {
   2912        mAssociatedImages[level] = image;
   2913    }
   2914 }
   2915 
   2916 void TextureStorage11_3D::verifyAssociatedImageValid(const gl::ImageIndex &index,
   2917                                                     Image11 *expectedImage)
   2918 {
   2919    const GLint level = index.getLevelIndex();
   2920 
   2921    ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
   2922    // This validation check should never return false. It means the Image/TextureStorage
   2923    // association is broken.
   2924    ASSERT(mAssociatedImages[level] == expectedImage);
   2925 }
   2926 
   2927 // disassociateImage allows an Image to end its association with a Storage.
   2928 void TextureStorage11_3D::disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage)
   2929 {
   2930    const GLint level = index.getLevelIndex();
   2931 
   2932    ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
   2933    ASSERT(mAssociatedImages[level] == expectedImage);
   2934    mAssociatedImages[level] = nullptr;
   2935 }
   2936 
   2937 // releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image
   2938 // recover its data before ending the association.
   2939 angle::Result TextureStorage11_3D::releaseAssociatedImage(const gl::Context *context,
   2940                                                          const gl::ImageIndex &index,
   2941                                                          Image11 *incomingImage)
   2942 {
   2943    const GLint level = index.getLevelIndex();
   2944 
   2945    ASSERT((0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS));
   2946 
   2947    if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
   2948    {
   2949        // No need to let the old Image recover its data, if it is also the incoming Image.
   2950        if (mAssociatedImages[level] != nullptr && mAssociatedImages[level] != incomingImage)
   2951        {
   2952            // Ensure that the Image is still associated with this TextureStorage.
   2953            mAssociatedImages[level]->verifyAssociatedStorageValid(this);
   2954 
   2955            // Force the image to recover from storage before its data is overwritten.
   2956            // This will reset mAssociatedImages[level] to nullptr too.
   2957            ANGLE_TRY(mAssociatedImages[level]->recoverFromAssociatedStorage(context));
   2958        }
   2959    }
   2960 
   2961    return angle::Result::Continue;
   2962 }
   2963 
   2964 angle::Result TextureStorage11_3D::getResource(const gl::Context *context,
   2965                                               const TextureHelper11 **outResource)
   2966 {
   2967    // If the width, height or depth are not positive this should be treated as an incomplete
   2968    // texture. We handle that here by skipping the d3d texture creation.
   2969    if (!mTexture.valid() && mTextureWidth > 0 && mTextureHeight > 0 && mTextureDepth > 0)
   2970    {
   2971        ASSERT(mMipLevels > 0);
   2972 
   2973        D3D11_TEXTURE3D_DESC desc;
   2974        desc.Width     = mTextureWidth;
   2975        desc.Height    = mTextureHeight;
   2976        desc.Depth     = mTextureDepth;
   2977        desc.MipLevels = mMipLevels;
   2978        desc.Format    = isUnorderedAccess() ? mFormatInfo.typelessFormat : mFormatInfo.texFormat;
   2979        desc.Usage     = D3D11_USAGE_DEFAULT;
   2980        desc.BindFlags = getBindFlags();
   2981        desc.CPUAccessFlags = 0;
   2982        desc.MiscFlags      = getMiscFlags();
   2983 
   2984        ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, mFormatInfo,
   2985                                             &mTexture));
   2986        mTexture.setLabels("TexStorage3D.Texture", &mKHRDebugLabel);
   2987    }
   2988 
   2989    *outResource = &mTexture;
   2990    return angle::Result::Continue;
   2991 }
   2992 
   2993 angle::Result TextureStorage11_3D::createSRVForSampler(const gl::Context *context,
   2994                                                       int baseLevel,
   2995                                                       int mipLevels,
   2996                                                       DXGI_FORMAT format,
   2997                                                       const TextureHelper11 &texture,
   2998                                                       d3d11::SharedSRV *outSRV)
   2999 {
   3000    ASSERT(outSRV);
   3001 
   3002    D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
   3003    srvDesc.Format                    = format;
   3004    srvDesc.ViewDimension             = D3D11_SRV_DIMENSION_TEXTURE3D;
   3005    srvDesc.Texture3D.MostDetailedMip = baseLevel;
   3006    srvDesc.Texture3D.MipLevels       = mipLevels;
   3007 
   3008    ANGLE_TRY(
   3009        mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV));
   3010    outSRV->setLabels("TexStorage3D.SRV", &mKHRDebugLabel);
   3011 
   3012    return angle::Result::Continue;
   3013 }
   3014 
   3015 angle::Result TextureStorage11_3D::createSRVForImage(const gl::Context *context,
   3016                                                     int level,
   3017                                                     DXGI_FORMAT format,
   3018                                                     const TextureHelper11 &texture,
   3019                                                     d3d11::SharedSRV *outSRV)
   3020 {
   3021    ASSERT(outSRV);
   3022    D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
   3023    srvDesc.Format                    = format;
   3024    srvDesc.ViewDimension             = D3D11_SRV_DIMENSION_TEXTURE3D;
   3025    srvDesc.Texture3D.MostDetailedMip = mTopLevel + level;
   3026    srvDesc.Texture3D.MipLevels       = 1;
   3027    ANGLE_TRY(
   3028        mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV));
   3029    outSRV->setLabels("TexStorage3D.SRVForImage", &mKHRDebugLabel);
   3030    return angle::Result::Continue;
   3031 }
   3032 
   3033 angle::Result TextureStorage11_3D::createUAVForImage(const gl::Context *context,
   3034                                                     int level,
   3035                                                     DXGI_FORMAT format,
   3036                                                     const TextureHelper11 &texture,
   3037                                                     d3d11::SharedUAV *outUAV)
   3038 {
   3039    ASSERT(outUAV);
   3040    D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
   3041    uavDesc.Format                = format;
   3042    uavDesc.ViewDimension         = D3D11_UAV_DIMENSION_TEXTURE3D;
   3043    uavDesc.Texture3D.MipSlice    = mTopLevel + level;
   3044    uavDesc.Texture3D.FirstWSlice = 0;
   3045    uavDesc.Texture3D.WSize       = mTextureDepth;
   3046    ANGLE_TRY(
   3047        mRenderer->allocateResource(GetImplAs<Context11>(context), uavDesc, texture.get(), outUAV));
   3048    outUAV->setLabels("TexStorage3D.UAVForImage", &mKHRDebugLabel);
   3049    return angle::Result::Continue;
   3050 }
   3051 
   3052 angle::Result TextureStorage11_3D::findRenderTarget(const gl::Context *context,
   3053                                                    const gl::ImageIndex &index,
   3054                                                    GLsizei samples,
   3055                                                    RenderTargetD3D **outRT) const
   3056 {
   3057    const int mipLevel = index.getLevelIndex();
   3058    ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
   3059 
   3060    if (!index.hasLayer())
   3061    {
   3062        ASSERT(outRT);
   3063        *outRT = mLevelRenderTargets[mipLevel].get();
   3064        return angle::Result::Continue;
   3065    }
   3066 
   3067    const int layer = index.getLayerIndex();
   3068 
   3069    LevelLayerKey key(mipLevel, layer);
   3070    if (mLevelLayerRenderTargets.find(key) == mLevelLayerRenderTargets.end())
   3071    {
   3072        ASSERT(outRT);
   3073        *outRT = nullptr;
   3074        return angle::Result::Continue;
   3075    }
   3076 
   3077    ASSERT(outRT);
   3078    *outRT = mLevelLayerRenderTargets.at(key).get();
   3079    return angle::Result::Continue;
   3080 }
   3081 
   3082 angle::Result TextureStorage11_3D::getRenderTarget(const gl::Context *context,
   3083                                                   const gl::ImageIndex &index,
   3084                                                   GLsizei samples,
   3085                                                   RenderTargetD3D **outRT)
   3086 {
   3087    const int mipLevel = index.getLevelIndex();
   3088    ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
   3089 
   3090    ASSERT(mFormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN);
   3091 
   3092    Context11 *context11 = GetImplAs<Context11>(context);
   3093 
   3094    if (!index.hasLayer())
   3095    {
   3096        if (!mLevelRenderTargets[mipLevel])
   3097        {
   3098            const TextureHelper11 *texture = nullptr;
   3099            ANGLE_TRY(getResource(context, &texture));
   3100 
   3101            const d3d11::SharedSRV *srv = nullptr;
   3102            ANGLE_TRY(getSRVLevel(context, mipLevel, SRVType::Sample, &srv));
   3103 
   3104            const d3d11::SharedSRV *blitSRV = nullptr;
   3105            ANGLE_TRY(getSRVLevel(context, mipLevel, SRVType::Blit, &blitSRV));
   3106 
   3107            D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
   3108            rtvDesc.Format                = mFormatInfo.rtvFormat;
   3109            rtvDesc.ViewDimension         = D3D11_RTV_DIMENSION_TEXTURE3D;
   3110            rtvDesc.Texture3D.MipSlice    = mTopLevel + mipLevel;
   3111            rtvDesc.Texture3D.FirstWSlice = 0;
   3112            rtvDesc.Texture3D.WSize       = static_cast<UINT>(-1);
   3113 
   3114            d3d11::RenderTargetView rtv;
   3115            ANGLE_TRY(mRenderer->allocateResource(context11, rtvDesc, texture->get(), &rtv));
   3116            rtv.setLabels("TexStorage3D.RTV", &mKHRDebugLabel);
   3117 
   3118            mLevelRenderTargets[mipLevel].reset(new TextureRenderTarget11(
   3119                std::move(rtv), *texture, *srv, *blitSRV, mFormatInfo.internalFormat,
   3120                getFormatSet(), getLevelWidth(mipLevel), getLevelHeight(mipLevel),
   3121                getLevelDepth(mipLevel), 0));
   3122        }
   3123 
   3124        ASSERT(outRT);
   3125        *outRT = mLevelRenderTargets[mipLevel].get();
   3126        return angle::Result::Continue;
   3127    }
   3128 
   3129    const int layer = index.getLayerIndex();
   3130 
   3131    LevelLayerKey key(mipLevel, layer);
   3132    if (mLevelLayerRenderTargets.find(key) == mLevelLayerRenderTargets.end())
   3133    {
   3134        const TextureHelper11 *texture = nullptr;
   3135        ANGLE_TRY(getResource(context, &texture));
   3136 
   3137        D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
   3138        rtvDesc.Format                = mFormatInfo.rtvFormat;
   3139        rtvDesc.ViewDimension         = D3D11_RTV_DIMENSION_TEXTURE3D;
   3140        rtvDesc.Texture3D.MipSlice    = mTopLevel + mipLevel;
   3141        rtvDesc.Texture3D.FirstWSlice = layer;
   3142        rtvDesc.Texture3D.WSize       = 1;
   3143 
   3144        const d3d11::SharedSRV *srv = nullptr;
   3145        ANGLE_TRY(getSRVLevel(context, mipLevel, SRVType::Sample, &srv));
   3146 
   3147        const d3d11::SharedSRV *blitSRV = nullptr;
   3148        ANGLE_TRY(getSRVLevel(context, mipLevel, SRVType::Blit, &blitSRV));
   3149 
   3150        d3d11::RenderTargetView rtv;
   3151        ANGLE_TRY(mRenderer->allocateResource(context11, rtvDesc, texture->get(), &rtv));
   3152        rtv.setLabels("TexStorage3D.LayerRTV", &mKHRDebugLabel);
   3153 
   3154        mLevelLayerRenderTargets[key].reset(new TextureRenderTarget11(
   3155            std::move(rtv), *texture, *srv, *blitSRV, mFormatInfo.internalFormat, getFormatSet(),
   3156            getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, 0));
   3157    }
   3158 
   3159    ASSERT(outRT);
   3160    *outRT = mLevelLayerRenderTargets[key].get();
   3161    return angle::Result::Continue;
   3162 }
   3163 
   3164 angle::Result TextureStorage11_3D::getSwizzleTexture(const gl::Context *context,
   3165                                                     const TextureHelper11 **outTexture)
   3166 {
   3167    ASSERT(outTexture);
   3168 
   3169    if (!mSwizzleTexture.valid())
   3170    {
   3171        const auto &format = mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps());
   3172 
   3173        D3D11_TEXTURE3D_DESC desc;
   3174        desc.Width          = mTextureWidth;
   3175        desc.Height         = mTextureHeight;
   3176        desc.Depth          = mTextureDepth;
   3177        desc.MipLevels      = mMipLevels;
   3178        desc.Format         = format.texFormat;
   3179        desc.Usage          = D3D11_USAGE_DEFAULT;
   3180        desc.BindFlags      = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
   3181        desc.CPUAccessFlags = 0;
   3182        desc.MiscFlags      = 0;
   3183 
   3184        ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, format,
   3185                                             &mSwizzleTexture));
   3186        mSwizzleTexture.setLabels("TexStorage3D.SwizzleTexture", &mKHRDebugLabel);
   3187    }
   3188 
   3189    *outTexture = &mSwizzleTexture;
   3190    return angle::Result::Continue;
   3191 }
   3192 
   3193 angle::Result TextureStorage11_3D::getSwizzleRenderTarget(const gl::Context *context,
   3194                                                          int mipLevel,
   3195                                                          const d3d11::RenderTargetView **outRTV)
   3196 {
   3197    ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
   3198    ASSERT(outRTV);
   3199 
   3200    if (!mSwizzleRenderTargets[mipLevel].valid())
   3201    {
   3202        const TextureHelper11 *swizzleTexture = nullptr;
   3203        ANGLE_TRY(getSwizzleTexture(context, &swizzleTexture));
   3204 
   3205        D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
   3206        rtvDesc.Format =
   3207            mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()).rtvFormat;
   3208        rtvDesc.ViewDimension         = D3D11_RTV_DIMENSION_TEXTURE3D;
   3209        rtvDesc.Texture3D.MipSlice    = mTopLevel + mipLevel;
   3210        rtvDesc.Texture3D.FirstWSlice = 0;
   3211        rtvDesc.Texture3D.WSize       = static_cast<UINT>(-1);
   3212 
   3213        ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), rtvDesc,
   3214                                              mSwizzleTexture.get(),
   3215                                              &mSwizzleRenderTargets[mipLevel]));
   3216        mSwizzleRenderTargets[mipLevel].setLabels("TexStorage3D.SwizzleRTV", &mKHRDebugLabel);
   3217    }
   3218 
   3219    *outRTV = &mSwizzleRenderTargets[mipLevel];
   3220    return angle::Result::Continue;
   3221 }
   3222 
   3223 void TextureStorage11_3D::onLabelUpdate()
   3224 {
   3225    if (mTexture.valid())
   3226    {
   3227        mTexture.setKHRDebugLabel(&mKHRDebugLabel);
   3228    }
   3229    if (mSwizzleTexture.valid())
   3230    {
   3231        mSwizzleTexture.setKHRDebugLabel(&mKHRDebugLabel);
   3232    }
   3233 }
   3234 
   3235 TextureStorage11_2DArray::TextureStorage11_2DArray(Renderer11 *renderer,
   3236                                                   GLenum internalformat,
   3237                                                   BindFlags bindFlags,
   3238                                                   GLsizei width,
   3239                                                   GLsizei height,
   3240                                                   GLsizei depth,
   3241                                                   int levels,
   3242                                                   const std::string &label)
   3243    : TextureStorage11(
   3244          renderer,
   3245          GetTextureBindFlags(internalformat, renderer->getRenderer11DeviceCaps(), bindFlags),
   3246          GetTextureMiscFlags(internalformat,
   3247                              renderer->getRenderer11DeviceCaps(),
   3248                              bindFlags,
   3249                              levels),
   3250          internalformat,
   3251          label)
   3252 {
   3253    // adjust size if needed for compressed textures
   3254    d3d11::MakeValidSize(false, mFormatInfo.texFormat, &width, &height, &mTopLevel);
   3255 
   3256    mMipLevels     = mTopLevel + levels;
   3257    mTextureWidth  = width;
   3258    mTextureHeight = height;
   3259    mTextureDepth  = depth;
   3260 }
   3261 
   3262 angle::Result TextureStorage11_2DArray::onDestroy(const gl::Context *context)
   3263 {
   3264    for (auto iter : mAssociatedImages)
   3265    {
   3266        if (iter.second)
   3267        {
   3268            iter.second->verifyAssociatedStorageValid(this);
   3269 
   3270            // We must let the Images recover their data before we delete it from the
   3271            // TextureStorage.
   3272            ANGLE_TRY(iter.second->recoverFromAssociatedStorage(context));
   3273        }
   3274    }
   3275    mAssociatedImages.clear();
   3276 
   3277    return angle::Result::Continue;
   3278 }
   3279 
   3280 TextureStorage11_2DArray::~TextureStorage11_2DArray() {}
   3281 
   3282 void TextureStorage11_2DArray::associateImage(Image11 *image, const gl::ImageIndex &index)
   3283 {
   3284    const GLint level       = index.getLevelIndex();
   3285    const GLint layerTarget = index.getLayerIndex();
   3286    const GLint numLayers   = index.getLayerCount();
   3287 
   3288    ASSERT(0 <= level && level < getLevelCount());
   3289 
   3290    if (0 <= level && level < getLevelCount())
   3291    {
   3292        LevelLayerRangeKey key(level, layerTarget, numLayers);
   3293        mAssociatedImages[key] = image;
   3294    }
   3295 }
   3296 
   3297 void TextureStorage11_2DArray::verifyAssociatedImageValid(const gl::ImageIndex &index,
   3298                                                          Image11 *expectedImage)
   3299 {
   3300    const GLint level       = index.getLevelIndex();
   3301    const GLint layerTarget = index.getLayerIndex();
   3302    const GLint numLayers   = index.getLayerCount();
   3303 
   3304    LevelLayerRangeKey key(level, layerTarget, numLayers);
   3305 
   3306    // This validation check should never return false. It means the Image/TextureStorage
   3307    // association is broken.
   3308    bool retValue = (mAssociatedImages.find(key) != mAssociatedImages.end() &&
   3309                     (mAssociatedImages[key] == expectedImage));
   3310    ASSERT(retValue);
   3311 }
   3312 
   3313 // disassociateImage allows an Image to end its association with a Storage.
   3314 void TextureStorage11_2DArray::disassociateImage(const gl::ImageIndex &index,
   3315                                                 Image11 *expectedImage)
   3316 {
   3317    const GLint level       = index.getLevelIndex();
   3318    const GLint layerTarget = index.getLayerIndex();
   3319    const GLint numLayers   = index.getLayerCount();
   3320 
   3321    LevelLayerRangeKey key(level, layerTarget, numLayers);
   3322 
   3323    bool imageAssociationCorrect = (mAssociatedImages.find(key) != mAssociatedImages.end() &&
   3324                                    (mAssociatedImages[key] == expectedImage));
   3325    ASSERT(imageAssociationCorrect);
   3326    mAssociatedImages[key] = nullptr;
   3327 }
   3328 
   3329 // releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image
   3330 // recover its data before ending the association.
   3331 angle::Result TextureStorage11_2DArray::releaseAssociatedImage(const gl::Context *context,
   3332                                                               const gl::ImageIndex &index,
   3333                                                               Image11 *incomingImage)
   3334 {
   3335    const GLint level       = index.getLevelIndex();
   3336    const GLint layerTarget = index.getLayerIndex();
   3337    const GLint numLayers   = index.getLayerCount();
   3338 
   3339    LevelLayerRangeKey key(level, layerTarget, numLayers);
   3340 
   3341    if (mAssociatedImages.find(key) != mAssociatedImages.end())
   3342    {
   3343        if (mAssociatedImages[key] != nullptr && mAssociatedImages[key] != incomingImage)
   3344        {
   3345            // Ensure that the Image is still associated with this TextureStorage.
   3346            mAssociatedImages[key]->verifyAssociatedStorageValid(this);
   3347 
   3348            // Force the image to recover from storage before its data is overwritten.
   3349            // This will reset mAssociatedImages[level] to nullptr too.
   3350            ANGLE_TRY(mAssociatedImages[key]->recoverFromAssociatedStorage(context));
   3351        }
   3352    }
   3353 
   3354    return angle::Result::Continue;
   3355 }
   3356 
   3357 angle::Result TextureStorage11_2DArray::getResource(const gl::Context *context,
   3358                                                    const TextureHelper11 **outResource)
   3359 {
   3360    // if the width, height or depth is not positive this should be treated as an incomplete texture
   3361    // we handle that here by skipping the d3d texture creation
   3362    if (!mTexture.valid() && mTextureWidth > 0 && mTextureHeight > 0 && mTextureDepth > 0)
   3363    {
   3364        ASSERT(mMipLevels > 0);
   3365 
   3366        D3D11_TEXTURE2D_DESC desc;
   3367        desc.Width     = mTextureWidth;
   3368        desc.Height    = mTextureHeight;
   3369        desc.MipLevels = mMipLevels;
   3370        desc.ArraySize = mTextureDepth;
   3371        desc.Format    = isUnorderedAccess() ? mFormatInfo.typelessFormat : mFormatInfo.texFormat;
   3372        desc.SampleDesc.Count   = 1;
   3373        desc.SampleDesc.Quality = 0;
   3374        desc.Usage              = D3D11_USAGE_DEFAULT;
   3375        desc.BindFlags          = getBindFlags();
   3376        desc.CPUAccessFlags     = 0;
   3377        desc.MiscFlags          = getMiscFlags();
   3378 
   3379        ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, mFormatInfo,
   3380                                             &mTexture));
   3381        mTexture.setLabels("TexStorage2DArray.Texture", &mKHRDebugLabel);
   3382    }
   3383 
   3384    *outResource = &mTexture;
   3385    return angle::Result::Continue;
   3386 }
   3387 
   3388 angle::Result TextureStorage11_2DArray::createSRVForSampler(const gl::Context *context,
   3389                                                            int baseLevel,
   3390                                                            int mipLevels,
   3391                                                            DXGI_FORMAT format,
   3392                                                            const TextureHelper11 &texture,
   3393                                                            d3d11::SharedSRV *outSRV)
   3394 {
   3395    D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
   3396    srvDesc.Format                         = format;
   3397    srvDesc.ViewDimension                  = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
   3398    srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + baseLevel;
   3399    srvDesc.Texture2DArray.MipLevels       = mipLevels;
   3400    srvDesc.Texture2DArray.FirstArraySlice = 0;
   3401    srvDesc.Texture2DArray.ArraySize       = mTextureDepth;
   3402 
   3403    ANGLE_TRY(
   3404        mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV));
   3405    outSRV->setLabels("TexStorage2DArray.SRV", &mKHRDebugLabel);
   3406 
   3407    return angle::Result::Continue;
   3408 }
   3409 
   3410 angle::Result TextureStorage11_2DArray::createSRVForImage(const gl::Context *context,
   3411                                                          int level,
   3412                                                          DXGI_FORMAT format,
   3413                                                          const TextureHelper11 &texture,
   3414                                                          d3d11::SharedSRV *outSRV)
   3415 {
   3416    ASSERT(outSRV);
   3417    D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
   3418    srvDesc.Format                         = format;
   3419    srvDesc.ViewDimension                  = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
   3420    srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + level;
   3421    srvDesc.Texture2DArray.MipLevels       = 1;
   3422    srvDesc.Texture2DArray.FirstArraySlice = 0;
   3423    srvDesc.Texture2DArray.ArraySize       = mTextureDepth;
   3424    ANGLE_TRY(
   3425        mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV));
   3426    outSRV->setLabels("TexStorage2DArray.SRVForImage", &mKHRDebugLabel);
   3427    return angle::Result::Continue;
   3428 }
   3429 
   3430 angle::Result TextureStorage11_2DArray::createUAVForImage(const gl::Context *context,
   3431                                                          int level,
   3432                                                          DXGI_FORMAT format,
   3433                                                          const TextureHelper11 &texture,
   3434                                                          d3d11::SharedUAV *outUAV)
   3435 {
   3436    ASSERT(outUAV);
   3437    D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
   3438    uavDesc.Format                         = format;
   3439    uavDesc.ViewDimension                  = D3D11_UAV_DIMENSION_TEXTURE2DARRAY;
   3440    uavDesc.Texture2DArray.MipSlice        = mTopLevel + level;
   3441    uavDesc.Texture2DArray.FirstArraySlice = 0;
   3442    uavDesc.Texture2DArray.ArraySize       = mTextureDepth;
   3443    ANGLE_TRY(
   3444        mRenderer->allocateResource(GetImplAs<Context11>(context), uavDesc, texture.get(), outUAV));
   3445    outUAV->setLabels("TexStorage2DArray.UAVForImage", &mKHRDebugLabel);
   3446    return angle::Result::Continue;
   3447 }
   3448 
   3449 angle::Result TextureStorage11_2DArray::findRenderTarget(const gl::Context *context,
   3450                                                         const gl::ImageIndex &index,
   3451                                                         GLsizei samples,
   3452                                                         RenderTargetD3D **outRT) const
   3453 {
   3454    ASSERT(index.hasLayer());
   3455 
   3456    const int mipLevel  = index.getLevelIndex();
   3457    const int layer     = index.getLayerIndex();
   3458    const int numLayers = index.getLayerCount();
   3459 
   3460    ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
   3461 
   3462    LevelLayerRangeKey key(mipLevel, layer, numLayers);
   3463    if (mRenderTargets.find(key) == mRenderTargets.end())
   3464    {
   3465        ASSERT(outRT);
   3466        *outRT = nullptr;
   3467        return angle::Result::Continue;
   3468    }
   3469 
   3470    ASSERT(outRT);
   3471    *outRT = mRenderTargets.at(key).get();
   3472    return angle::Result::Continue;
   3473 }
   3474 
   3475 angle::Result TextureStorage11_2DArray::createRenderTargetSRV(const gl::Context *context,
   3476                                                              const TextureHelper11 &texture,
   3477                                                              const gl::ImageIndex &index,
   3478                                                              DXGI_FORMAT resourceFormat,
   3479                                                              d3d11::SharedSRV *srv) const
   3480 {
   3481    D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
   3482    srvDesc.Format                         = resourceFormat;
   3483    srvDesc.ViewDimension                  = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
   3484    srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + index.getLevelIndex();
   3485    srvDesc.Texture2DArray.MipLevels       = 1;
   3486    srvDesc.Texture2DArray.FirstArraySlice = index.getLayerIndex();
   3487    srvDesc.Texture2DArray.ArraySize       = index.getLayerCount();
   3488 
   3489    ANGLE_TRY(
   3490        mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), srv));
   3491 
   3492    return angle::Result::Continue;
   3493 }
   3494 
   3495 angle::Result TextureStorage11_2DArray::getRenderTarget(const gl::Context *context,
   3496                                                        const gl::ImageIndex &index,
   3497                                                        GLsizei samples,
   3498                                                        RenderTargetD3D **outRT)
   3499 {
   3500    ASSERT(index.hasLayer());
   3501 
   3502    const int mipLevel  = index.getLevelIndex();
   3503    const int layer     = index.getLayerIndex();
   3504    const int numLayers = index.getLayerCount();
   3505 
   3506    ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
   3507 
   3508    LevelLayerRangeKey key(mipLevel, layer, numLayers);
   3509    if (mRenderTargets.find(key) == mRenderTargets.end())
   3510    {
   3511        const TextureHelper11 *texture = nullptr;
   3512        ANGLE_TRY(getResource(context, &texture));
   3513        d3d11::SharedSRV srv;
   3514        ANGLE_TRY(createRenderTargetSRV(context, *texture, index, mFormatInfo.srvFormat, &srv));
   3515        d3d11::SharedSRV blitSRV;
   3516        if (mFormatInfo.blitSRVFormat != mFormatInfo.srvFormat)
   3517        {
   3518            ANGLE_TRY(createRenderTargetSRV(context, *texture, index, mFormatInfo.blitSRVFormat,
   3519                                            &blitSRV));
   3520        }
   3521        else
   3522        {
   3523            blitSRV = srv.makeCopy();
   3524        }
   3525 
   3526        srv.setLabels("TexStorage2DArray.RenderTargetSRV", &mKHRDebugLabel);
   3527 
   3528        if (mFormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN)
   3529        {
   3530            D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
   3531            rtvDesc.Format                         = mFormatInfo.rtvFormat;
   3532            rtvDesc.ViewDimension                  = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
   3533            rtvDesc.Texture2DArray.MipSlice        = mTopLevel + mipLevel;
   3534            rtvDesc.Texture2DArray.FirstArraySlice = layer;
   3535            rtvDesc.Texture2DArray.ArraySize       = numLayers;
   3536 
   3537            d3d11::RenderTargetView rtv;
   3538            ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), rtvDesc,
   3539                                                  texture->get(), &rtv));
   3540            rtv.setLabels("TexStorage2DArray.RenderTargetRTV", &mKHRDebugLabel);
   3541 
   3542            mRenderTargets[key].reset(new TextureRenderTarget11(
   3543                std::move(rtv), *texture, srv, blitSRV, mFormatInfo.internalFormat, getFormatSet(),
   3544                getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, 0));
   3545        }
   3546        else
   3547        {
   3548            ASSERT(mFormatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN);
   3549 
   3550            D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
   3551            dsvDesc.Format                         = mFormatInfo.dsvFormat;
   3552            dsvDesc.ViewDimension                  = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
   3553            dsvDesc.Texture2DArray.MipSlice        = mTopLevel + mipLevel;
   3554            dsvDesc.Texture2DArray.FirstArraySlice = layer;
   3555            dsvDesc.Texture2DArray.ArraySize       = numLayers;
   3556            dsvDesc.Flags                          = 0;
   3557 
   3558            d3d11::DepthStencilView dsv;
   3559            ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), dsvDesc,
   3560                                                  texture->get(), &dsv));
   3561            dsv.setLabels("TexStorage2DArray.RenderTargetDSV", &mKHRDebugLabel);
   3562 
   3563            mRenderTargets[key].reset(new TextureRenderTarget11(
   3564                std::move(dsv), *texture, srv, mFormatInfo.internalFormat, getFormatSet(),
   3565                getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, 0));
   3566        }
   3567    }
   3568 
   3569    ASSERT(outRT);
   3570    *outRT = mRenderTargets[key].get();
   3571    return angle::Result::Continue;
   3572 }
   3573 
   3574 angle::Result TextureStorage11_2DArray::getSwizzleTexture(const gl::Context *context,
   3575                                                          const TextureHelper11 **outTexture)
   3576 {
   3577    if (!mSwizzleTexture.valid())
   3578    {
   3579        const auto &format = mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps());
   3580 
   3581        D3D11_TEXTURE2D_DESC desc;
   3582        desc.Width              = mTextureWidth;
   3583        desc.Height             = mTextureHeight;
   3584        desc.MipLevels          = mMipLevels;
   3585        desc.ArraySize          = mTextureDepth;
   3586        desc.Format             = format.texFormat;
   3587        desc.SampleDesc.Count   = 1;
   3588        desc.SampleDesc.Quality = 0;
   3589        desc.Usage              = D3D11_USAGE_DEFAULT;
   3590        desc.BindFlags          = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
   3591        desc.CPUAccessFlags     = 0;
   3592        desc.MiscFlags          = 0;
   3593 
   3594        ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, format,
   3595                                             &mSwizzleTexture));
   3596        mSwizzleTexture.setLabels("TexStorage2DArray.SwizzleTexture", &mKHRDebugLabel);
   3597    }
   3598 
   3599    *outTexture = &mSwizzleTexture;
   3600    return angle::Result::Continue;
   3601 }
   3602 
   3603 angle::Result TextureStorage11_2DArray::getSwizzleRenderTarget(
   3604    const gl::Context *context,
   3605    int mipLevel,
   3606    const d3d11::RenderTargetView **outRTV)
   3607 {
   3608    ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
   3609    ASSERT(outRTV);
   3610 
   3611    if (!mSwizzleRenderTargets[mipLevel].valid())
   3612    {
   3613        const TextureHelper11 *swizzleTexture = nullptr;
   3614        ANGLE_TRY(getSwizzleTexture(context, &swizzleTexture));
   3615 
   3616        D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
   3617        rtvDesc.Format =
   3618            mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()).rtvFormat;
   3619        rtvDesc.ViewDimension                  = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
   3620        rtvDesc.Texture2DArray.MipSlice        = mTopLevel + mipLevel;
   3621        rtvDesc.Texture2DArray.FirstArraySlice = 0;
   3622        rtvDesc.Texture2DArray.ArraySize       = mTextureDepth;
   3623 
   3624        ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), rtvDesc,
   3625                                              mSwizzleTexture.get(),
   3626                                              &mSwizzleRenderTargets[mipLevel]));
   3627    }
   3628 
   3629    *outRTV = &mSwizzleRenderTargets[mipLevel];
   3630    return angle::Result::Continue;
   3631 }
   3632 
   3633 angle::Result TextureStorage11_2DArray::ensureDropStencilTexture(const gl::Context *context,
   3634                                                                 DropStencil *dropStencilOut)
   3635 {
   3636    if (mDropStencilTexture.valid())
   3637    {
   3638        *dropStencilOut = DropStencil::ALREADY_EXISTS;
   3639        return angle::Result::Continue;
   3640    }
   3641 
   3642    D3D11_TEXTURE2D_DESC dropDesc = {};
   3643    dropDesc.ArraySize            = mTextureDepth;
   3644    dropDesc.BindFlags            = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_DEPTH_STENCIL;
   3645    dropDesc.CPUAccessFlags       = 0;
   3646    dropDesc.Format               = DXGI_FORMAT_R32_TYPELESS;
   3647    dropDesc.Height               = mTextureHeight;
   3648    dropDesc.MipLevels            = mMipLevels;
   3649    dropDesc.MiscFlags            = 0;
   3650    dropDesc.SampleDesc.Count     = 1;
   3651    dropDesc.SampleDesc.Quality   = 0;
   3652    dropDesc.Usage                = D3D11_USAGE_DEFAULT;
   3653    dropDesc.Width                = mTextureWidth;
   3654 
   3655    const auto &format =
   3656        d3d11::Format::Get(GL_DEPTH_COMPONENT32F, mRenderer->getRenderer11DeviceCaps());
   3657    ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), dropDesc, format,
   3658                                         &mDropStencilTexture));
   3659    mDropStencilTexture.setLabels("TexStorage2DArray.DropStencil", &mKHRDebugLabel);
   3660 
   3661    std::vector<GLsizei> layerCounts(mMipLevels, mTextureDepth);
   3662 
   3663    ANGLE_TRY(initDropStencilTexture(
   3664        context, gl::ImageIndexIterator::Make2DArray(0, mMipLevels, layerCounts.data())));
   3665 
   3666    *dropStencilOut = DropStencil::CREATED;
   3667    return angle::Result::Continue;
   3668 }
   3669 
   3670 void TextureStorage11_2DArray::onLabelUpdate()
   3671 {
   3672    if (mTexture.valid())
   3673    {
   3674        mTexture.setKHRDebugLabel(&mKHRDebugLabel);
   3675    }
   3676    if (mSwizzleTexture.valid())
   3677    {
   3678        mSwizzleTexture.setKHRDebugLabel(&mKHRDebugLabel);
   3679    }
   3680 }
   3681 
   3682 TextureStorage11_2DMultisample::TextureStorage11_2DMultisample(Renderer11 *renderer,
   3683                                                               GLenum internalformat,
   3684                                                               GLsizei width,
   3685                                                               GLsizei height,
   3686                                                               int levels,
   3687                                                               int samples,
   3688                                                               bool fixedSampleLocations,
   3689                                                               const std::string &label)
   3690    : TextureStorage11ImmutableBase(renderer,
   3691                                    GetTextureBindFlags(internalformat,
   3692                                                        renderer->getRenderer11DeviceCaps(),
   3693                                                        BindFlags::RenderTarget()),
   3694                                    GetTextureMiscFlags(internalformat,
   3695                                                        renderer->getRenderer11DeviceCaps(),
   3696                                                        BindFlags::RenderTarget(),
   3697                                                        levels),
   3698                                    internalformat,
   3699                                    label),
   3700      mTexture(),
   3701      mRenderTarget(nullptr)
   3702 {
   3703    // There are no multisampled compressed formats, so there's no need to adjust texture size
   3704    // according to block size.
   3705    ASSERT(d3d11::GetDXGIFormatSizeInfo(mFormatInfo.texFormat).blockWidth <= 1);
   3706    ASSERT(d3d11::GetDXGIFormatSizeInfo(mFormatInfo.texFormat).blockHeight <= 1);
   3707 
   3708    mMipLevels            = 1;
   3709    mTextureWidth         = width;
   3710    mTextureHeight        = height;
   3711    mTextureDepth         = 1;
   3712    mSamples              = samples;
   3713    mFixedSampleLocations = fixedSampleLocations;
   3714 }
   3715 
   3716 angle::Result TextureStorage11_2DMultisample::onDestroy(const gl::Context *context)
   3717 {
   3718    mRenderTarget.reset();
   3719    return angle::Result::Continue;
   3720 }
   3721 
   3722 TextureStorage11_2DMultisample::~TextureStorage11_2DMultisample() {}
   3723 
   3724 angle::Result TextureStorage11_2DMultisample::copyToStorage(const gl::Context *context,
   3725                                                            TextureStorage *destStorage)
   3726 {
   3727    ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
   3728    return angle::Result::Stop;
   3729 }
   3730 
   3731 angle::Result TextureStorage11_2DMultisample::getResource(const gl::Context *context,
   3732                                                          const TextureHelper11 **outResource)
   3733 {
   3734    ANGLE_TRY(ensureTextureExists(context, 1));
   3735 
   3736    *outResource = &mTexture;
   3737    return angle::Result::Continue;
   3738 }
   3739 
   3740 angle::Result TextureStorage11_2DMultisample::ensureTextureExists(const gl::Context *context,
   3741                                                                  int mipLevels)
   3742 {
   3743    // For Multisampled textures, mipLevels always equals 1.
   3744    ASSERT(mipLevels == 1);
   3745 
   3746    // if the width or height is not positive this should be treated as an incomplete texture
   3747    // we handle that here by skipping the d3d texture creation
   3748    if (!mTexture.valid() && mTextureWidth > 0 && mTextureHeight > 0)
   3749    {
   3750        D3D11_TEXTURE2D_DESC desc;
   3751        ZeroMemory(&desc, sizeof(desc));
   3752        desc.Width          = mTextureWidth;  // Compressed texture size constraints?
   3753        desc.Height         = mTextureHeight;
   3754        desc.MipLevels      = mipLevels;
   3755        desc.ArraySize      = 1;
   3756        desc.Format         = mFormatInfo.texFormat;
   3757        desc.Usage          = D3D11_USAGE_DEFAULT;
   3758        desc.BindFlags      = getBindFlags() & ~D3D11_BIND_UNORDERED_ACCESS;
   3759        desc.CPUAccessFlags = 0;
   3760        desc.MiscFlags      = getMiscFlags();
   3761 
   3762        const gl::TextureCaps &textureCaps =
   3763            mRenderer->getNativeTextureCaps().get(mFormatInfo.internalFormat);
   3764        GLuint supportedSamples = textureCaps.getNearestSamples(mSamples);
   3765        desc.SampleDesc.Count   = (supportedSamples == 0) ? 1 : supportedSamples;
   3766        desc.SampleDesc.Quality = mRenderer->getSampleDescQuality(supportedSamples);
   3767 
   3768        ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, mFormatInfo,
   3769                                             &mTexture));
   3770        mTexture.setLabels("TexStorage2DMS.Texture", &mKHRDebugLabel);
   3771    }
   3772 
   3773    return angle::Result::Continue;
   3774 }
   3775 
   3776 angle::Result TextureStorage11_2DMultisample::findRenderTarget(const gl::Context *context,
   3777                                                               const gl::ImageIndex &index,
   3778                                                               GLsizei samples,
   3779                                                               RenderTargetD3D **outRT) const
   3780 {
   3781    ASSERT(!index.hasLayer());
   3782 
   3783    const int level = index.getLevelIndex();
   3784    ASSERT(level == 0);
   3785 
   3786    ASSERT(outRT);
   3787    *outRT = mRenderTarget.get();
   3788    return angle::Result::Continue;
   3789 }
   3790 
   3791 angle::Result TextureStorage11_2DMultisample::getRenderTarget(const gl::Context *context,
   3792                                                              const gl::ImageIndex &index,
   3793                                                              GLsizei samples,
   3794                                                              RenderTargetD3D **outRT)
   3795 {
   3796    ASSERT(!index.hasLayer());
   3797 
   3798    const int level = index.getLevelIndex();
   3799    ASSERT(level == 0);
   3800 
   3801    ASSERT(outRT);
   3802    if (mRenderTarget)
   3803    {
   3804        *outRT = mRenderTarget.get();
   3805        return angle::Result::Continue;
   3806    }
   3807 
   3808    const TextureHelper11 *texture = nullptr;
   3809    ANGLE_TRY(getResource(context, &texture));
   3810 
   3811    const d3d11::SharedSRV *srv = nullptr;
   3812    ANGLE_TRY(getSRVLevel(context, level, SRVType::Sample, &srv));
   3813 
   3814    const d3d11::SharedSRV *blitSRV = nullptr;
   3815    ANGLE_TRY(getSRVLevel(context, level, SRVType::Blit, &blitSRV));
   3816 
   3817    Context11 *context11 = GetImplAs<Context11>(context);
   3818 
   3819    if (mFormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN)
   3820    {
   3821        D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
   3822        rtvDesc.Format        = mFormatInfo.rtvFormat;
   3823        rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS;
   3824 
   3825        d3d11::RenderTargetView rtv;
   3826        ANGLE_TRY(mRenderer->allocateResource(context11, rtvDesc, texture->get(), &rtv));
   3827 
   3828        mRenderTarget.reset(new TextureRenderTarget11(
   3829            std::move(rtv), *texture, *srv, *blitSRV, mFormatInfo.internalFormat, getFormatSet(),
   3830            getLevelWidth(level), getLevelHeight(level), 1, mSamples));
   3831 
   3832        *outRT = mRenderTarget.get();
   3833        return angle::Result::Continue;
   3834    }
   3835 
   3836    ASSERT(mFormatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN);
   3837 
   3838    D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
   3839    dsvDesc.Format        = mFormatInfo.dsvFormat;
   3840    dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS;
   3841    dsvDesc.Flags         = 0;
   3842 
   3843    d3d11::DepthStencilView dsv;
   3844    ANGLE_TRY(mRenderer->allocateResource(context11, dsvDesc, texture->get(), &dsv));
   3845 
   3846    mRenderTarget.reset(new TextureRenderTarget11(
   3847        std::move(dsv), *texture, *srv, mFormatInfo.internalFormat, getFormatSet(),
   3848        getLevelWidth(level), getLevelHeight(level), 1, mSamples));
   3849 
   3850    *outRT = mRenderTarget.get();
   3851    return angle::Result::Continue;
   3852 }
   3853 
   3854 angle::Result TextureStorage11_2DMultisample::createSRVForSampler(const gl::Context *context,
   3855                                                                  int baseLevel,
   3856                                                                  int mipLevels,
   3857                                                                  DXGI_FORMAT format,
   3858                                                                  const TextureHelper11 &texture,
   3859                                                                  d3d11::SharedSRV *outSRV)
   3860 {
   3861    ASSERT(outSRV);
   3862 
   3863    D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
   3864    srvDesc.Format        = format;
   3865    srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS;
   3866 
   3867    ANGLE_TRY(
   3868        mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV));
   3869    outSRV->setLabels("TexStorage2DMS.SRV", &mKHRDebugLabel);
   3870    return angle::Result::Continue;
   3871 }
   3872 
   3873 angle::Result TextureStorage11_2DMultisample::getSwizzleTexture(const gl::Context *context,
   3874                                                                const TextureHelper11 **outTexture)
   3875 {
   3876    ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
   3877    return angle::Result::Stop;
   3878 }
   3879 
   3880 angle::Result TextureStorage11_2DMultisample::getSwizzleRenderTarget(
   3881    const gl::Context *context,
   3882    int mipLevel,
   3883    const d3d11::RenderTargetView **outRTV)
   3884 {
   3885    ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
   3886    return angle::Result::Stop;
   3887 }
   3888 
   3889 angle::Result TextureStorage11_2DMultisample::ensureDropStencilTexture(const gl::Context *context,
   3890                                                                       DropStencil *dropStencilOut)
   3891 {
   3892    ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
   3893    return angle::Result::Stop;
   3894 }
   3895 
   3896 void TextureStorage11_2DMultisample::onLabelUpdate()
   3897 {
   3898    if (mTexture.valid())
   3899    {
   3900        mTexture.setKHRDebugLabel(&mKHRDebugLabel);
   3901    }
   3902 }
   3903 
   3904 TextureStorage11_2DMultisampleArray::TextureStorage11_2DMultisampleArray(Renderer11 *renderer,
   3905                                                                         GLenum internalformat,
   3906                                                                         GLsizei width,
   3907                                                                         GLsizei height,
   3908                                                                         GLsizei depth,
   3909                                                                         int levels,
   3910                                                                         int samples,
   3911                                                                         bool fixedSampleLocations,
   3912                                                                         const std::string &label)
   3913    : TextureStorage11ImmutableBase(renderer,
   3914                                    GetTextureBindFlags(internalformat,
   3915                                                        renderer->getRenderer11DeviceCaps(),
   3916                                                        BindFlags::RenderTarget()),
   3917                                    GetTextureMiscFlags(internalformat,
   3918                                                        renderer->getRenderer11DeviceCaps(),
   3919                                                        BindFlags::RenderTarget(),
   3920                                                        levels),
   3921                                    internalformat,
   3922                                    label),
   3923      mTexture()
   3924 {
   3925    // There are no multisampled compressed formats, so there's no need to adjust texture size
   3926    // according to block size.
   3927    ASSERT(d3d11::GetDXGIFormatSizeInfo(mFormatInfo.texFormat).blockWidth <= 1);
   3928    ASSERT(d3d11::GetDXGIFormatSizeInfo(mFormatInfo.texFormat).blockHeight <= 1);
   3929 
   3930    mMipLevels            = 1;
   3931    mTextureWidth         = width;
   3932    mTextureHeight        = height;
   3933    mTextureDepth         = depth;
   3934    mSamples              = samples;
   3935    mFixedSampleLocations = fixedSampleLocations;
   3936 }
   3937 
   3938 angle::Result TextureStorage11_2DMultisampleArray::onDestroy(const gl::Context *context)
   3939 {
   3940    return angle::Result::Continue;
   3941 }
   3942 
   3943 TextureStorage11_2DMultisampleArray::~TextureStorage11_2DMultisampleArray() {}
   3944 
   3945 angle::Result TextureStorage11_2DMultisampleArray::copyToStorage(const gl::Context *context,
   3946                                                                 TextureStorage *destStorage)
   3947 {
   3948    ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
   3949    return angle::Result::Stop;
   3950 }
   3951 
   3952 angle::Result TextureStorage11_2DMultisampleArray::getResource(const gl::Context *context,
   3953                                                               const TextureHelper11 **outResource)
   3954 {
   3955    ANGLE_TRY(ensureTextureExists(context, 1));
   3956 
   3957    *outResource = &mTexture;
   3958    return angle::Result::Continue;
   3959 }
   3960 
   3961 angle::Result TextureStorage11_2DMultisampleArray::ensureTextureExists(const gl::Context *context,
   3962                                                                       int mipLevels)
   3963 {
   3964    // For multisampled textures, mipLevels always equals 1.
   3965    ASSERT(mipLevels == 1);
   3966 
   3967    // if the width or height is not positive this should be treated as an incomplete texture
   3968    // we handle that here by skipping the d3d texture creation
   3969    if (!mTexture.valid() && mTextureWidth > 0 && mTextureHeight > 0)
   3970    {
   3971        D3D11_TEXTURE2D_DESC desc;
   3972        ZeroMemory(&desc, sizeof(desc));
   3973        desc.Width          = mTextureWidth;
   3974        desc.Height         = mTextureHeight;
   3975        desc.MipLevels      = mipLevels;
   3976        desc.ArraySize      = mTextureDepth;
   3977        desc.Format         = mFormatInfo.texFormat;
   3978        desc.Usage          = D3D11_USAGE_DEFAULT;
   3979        desc.BindFlags      = getBindFlags() & ~D3D11_BIND_UNORDERED_ACCESS;
   3980        desc.CPUAccessFlags = 0;
   3981        desc.MiscFlags      = getMiscFlags();
   3982 
   3983        const gl::TextureCaps &textureCaps =
   3984            mRenderer->getNativeTextureCaps().get(mFormatInfo.internalFormat);
   3985        GLuint supportedSamples = textureCaps.getNearestSamples(mSamples);
   3986        desc.SampleDesc.Count   = (supportedSamples == 0) ? 1 : supportedSamples;
   3987        desc.SampleDesc.Quality = mRenderer->getSampleDescQuality(supportedSamples);
   3988 
   3989        ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, mFormatInfo,
   3990                                             &mTexture));
   3991        mTexture.setLabels("TexStorage2DMSArray.Texture", &mKHRDebugLabel);
   3992    }
   3993 
   3994    return angle::Result::Continue;
   3995 }
   3996 
   3997 angle::Result TextureStorage11_2DMultisampleArray::findRenderTarget(const gl::Context *context,
   3998                                                                    const gl::ImageIndex &index,
   3999                                                                    GLsizei samples,
   4000                                                                    RenderTargetD3D **outRT) const
   4001 {
   4002    ASSERT(index.hasLayer());
   4003 
   4004    const int mipLevel = index.getLevelIndex();
   4005    ASSERT(mipLevel == 0);
   4006    const int layer     = index.getLayerIndex();
   4007    const int numLayers = index.getLayerCount();
   4008 
   4009    ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
   4010 
   4011    TextureStorage11_2DArray::LevelLayerRangeKey key(mipLevel, layer, numLayers);
   4012    if (mRenderTargets.find(key) == mRenderTargets.end())
   4013    {
   4014        ASSERT(outRT);
   4015        *outRT = nullptr;
   4016        return angle::Result::Continue;
   4017    }
   4018 
   4019    ASSERT(outRT);
   4020    *outRT = mRenderTargets.at(key).get();
   4021    return angle::Result::Continue;
   4022 }
   4023 
   4024 angle::Result TextureStorage11_2DMultisampleArray::createRenderTargetSRV(
   4025    const gl::Context *context,
   4026    const TextureHelper11 &texture,
   4027    const gl::ImageIndex &index,
   4028    DXGI_FORMAT resourceFormat,
   4029    d3d11::SharedSRV *srv) const
   4030 {
   4031    D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
   4032    srvDesc.Format                           = resourceFormat;
   4033    srvDesc.ViewDimension                    = D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY;
   4034    srvDesc.Texture2DMSArray.FirstArraySlice = index.getLayerIndex();
   4035    srvDesc.Texture2DMSArray.ArraySize       = index.getLayerCount();
   4036 
   4037    ANGLE_TRY(
   4038        mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), srv));
   4039 
   4040    return angle::Result::Continue;
   4041 }
   4042 
   4043 angle::Result TextureStorage11_2DMultisampleArray::getRenderTarget(const gl::Context *context,
   4044                                                                   const gl::ImageIndex &index,
   4045                                                                   GLsizei samples,
   4046                                                                   RenderTargetD3D **outRT)
   4047 {
   4048    ASSERT(index.hasLayer());
   4049 
   4050    const int mipLevel = index.getLevelIndex();
   4051    ASSERT(mipLevel == 0);
   4052    const int layer     = index.getLayerIndex();
   4053    const int numLayers = index.getLayerCount();
   4054 
   4055    ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
   4056 
   4057    TextureStorage11_2DArray::LevelLayerRangeKey key(mipLevel, layer, numLayers);
   4058    if (mRenderTargets.find(key) == mRenderTargets.end())
   4059    {
   4060        const TextureHelper11 *texture = nullptr;
   4061        ANGLE_TRY(getResource(context, &texture));
   4062        d3d11::SharedSRV srv;
   4063        ANGLE_TRY(createRenderTargetSRV(context, *texture, index, mFormatInfo.srvFormat, &srv));
   4064        d3d11::SharedSRV blitSRV;
   4065        if (mFormatInfo.blitSRVFormat != mFormatInfo.srvFormat)
   4066        {
   4067            ANGLE_TRY(createRenderTargetSRV(context, *texture, index, mFormatInfo.blitSRVFormat,
   4068                                            &blitSRV));
   4069        }
   4070        else
   4071        {
   4072            blitSRV = srv.makeCopy();
   4073        }
   4074 
   4075        srv.setLabels("TexStorage2DMSArray.RenderTargetSRV", &mKHRDebugLabel);
   4076 
   4077        if (mFormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN)
   4078        {
   4079            D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
   4080            rtvDesc.Format                           = mFormatInfo.rtvFormat;
   4081            rtvDesc.ViewDimension                    = D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY;
   4082            rtvDesc.Texture2DMSArray.FirstArraySlice = layer;
   4083            rtvDesc.Texture2DMSArray.ArraySize       = numLayers;
   4084 
   4085            d3d11::RenderTargetView rtv;
   4086            ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), rtvDesc,
   4087                                                  texture->get(), &rtv));
   4088            rtv.setLabels("TexStorage2DMSArray.RenderTargetRTV", &mKHRDebugLabel);
   4089 
   4090            mRenderTargets[key].reset(new TextureRenderTarget11(
   4091                std::move(rtv), *texture, srv, blitSRV, mFormatInfo.internalFormat, getFormatSet(),
   4092                getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, mSamples));
   4093        }
   4094        else
   4095        {
   4096            ASSERT(mFormatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN);
   4097 
   4098            D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
   4099            dsvDesc.Format                           = mFormatInfo.dsvFormat;
   4100            dsvDesc.ViewDimension                    = D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY;
   4101            dsvDesc.Texture2DMSArray.FirstArraySlice = layer;
   4102            dsvDesc.Texture2DMSArray.ArraySize       = numLayers;
   4103            dsvDesc.Flags                            = 0;
   4104 
   4105            d3d11::DepthStencilView dsv;
   4106            ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), dsvDesc,
   4107                                                  texture->get(), &dsv));
   4108            dsv.setLabels("TexStorage2DMSArray.RenderTargetDSV", &mKHRDebugLabel);
   4109 
   4110            mRenderTargets[key].reset(new TextureRenderTarget11(
   4111                std::move(dsv), *texture, srv, mFormatInfo.internalFormat, getFormatSet(),
   4112                getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, mSamples));
   4113        }
   4114    }
   4115 
   4116    ASSERT(outRT);
   4117    *outRT = mRenderTargets[key].get();
   4118    return angle::Result::Continue;
   4119 }
   4120 
   4121 angle::Result TextureStorage11_2DMultisampleArray::createSRVForSampler(
   4122    const gl::Context *context,
   4123    int baseLevel,
   4124    int mipLevels,
   4125    DXGI_FORMAT format,
   4126    const TextureHelper11 &texture,
   4127    d3d11::SharedSRV *outSRV)
   4128 {
   4129    ASSERT(outSRV);
   4130 
   4131    D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
   4132    srvDesc.Format                           = format;
   4133    srvDesc.ViewDimension                    = D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY;
   4134    srvDesc.Texture2DMSArray.FirstArraySlice = 0;
   4135    srvDesc.Texture2DMSArray.ArraySize       = mTextureDepth;
   4136 
   4137    ANGLE_TRY(
   4138        mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV));
   4139    outSRV->setLabels("TexStorage2DMSArray.SRV", &mKHRDebugLabel);
   4140    return angle::Result::Continue;
   4141 }
   4142 
   4143 angle::Result TextureStorage11_2DMultisampleArray::getSwizzleTexture(
   4144    const gl::Context *context,
   4145    const TextureHelper11 **outTexture)
   4146 {
   4147    ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
   4148    return angle::Result::Stop;
   4149 }
   4150 
   4151 angle::Result TextureStorage11_2DMultisampleArray::getSwizzleRenderTarget(
   4152    const gl::Context *context,
   4153    int mipLevel,
   4154    const d3d11::RenderTargetView **outRTV)
   4155 {
   4156    ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
   4157    return angle::Result::Stop;
   4158 }
   4159 
   4160 angle::Result TextureStorage11_2DMultisampleArray::ensureDropStencilTexture(
   4161    const gl::Context *context,
   4162    DropStencil *dropStencilOut)
   4163 {
   4164    ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
   4165    return angle::Result::Stop;
   4166 }
   4167 
   4168 void TextureStorage11_2DMultisampleArray::onLabelUpdate()
   4169 {
   4170    if (mTexture.valid())
   4171    {
   4172        mTexture.setKHRDebugLabel(&mKHRDebugLabel);
   4173    }
   4174 }
   4175 
   4176 TextureStorage11_Buffer::TextureStorage11_Buffer(Renderer11 *renderer,
   4177                                                 const gl::OffsetBindingPointer<gl::Buffer> &buffer,
   4178                                                 GLenum internalFormat,
   4179                                                 const std::string &label)
   4180    : TextureStorage11(renderer,
   4181                       D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE,
   4182                       0,
   4183                       internalFormat,
   4184                       label),
   4185      mTexture(),
   4186      mBuffer(buffer),
   4187      mDataSize(GetBoundBufferAvailableSize(buffer))
   4188 {
   4189    unsigned int bytesPerPixel =
   4190        static_cast<unsigned int>(d3d11::GetDXGIFormatSizeInfo(mFormatInfo.srvFormat).pixelBytes);
   4191    mMipLevels     = 1;
   4192    mTextureWidth  = static_cast<unsigned int>(mDataSize / bytesPerPixel);
   4193    mTextureHeight = 1;
   4194    mTextureDepth  = 1;
   4195 }
   4196 
   4197 TextureStorage11_Buffer::~TextureStorage11_Buffer() {}
   4198 
   4199 angle::Result TextureStorage11_Buffer::initTexture(const gl::Context *context)
   4200 {
   4201    if (!mTexture.valid())
   4202    {
   4203        ID3D11Buffer *buffer = nullptr;
   4204        Buffer11 *buffer11   = GetImplAs<Buffer11>(mBuffer.get());
   4205        ANGLE_TRY(buffer11->getBuffer(context, rx::BufferUsage::BUFFER_USAGE_TYPED_UAV, &buffer));
   4206        mTexture.set(buffer, mFormatInfo);
   4207        mTexture.get()->AddRef();
   4208    }
   4209    return angle::Result::Continue;
   4210 }
   4211 
   4212 angle::Result TextureStorage11_Buffer::getResource(const gl::Context *context,
   4213                                                   const TextureHelper11 **outResource)
   4214 {
   4215    ANGLE_TRY(initTexture(context));
   4216    *outResource = &mTexture;
   4217    return angle::Result::Continue;
   4218 }
   4219 
   4220 angle::Result TextureStorage11_Buffer::getMippedResource(const gl::Context *context,
   4221                                                         const TextureHelper11 **)
   4222 {
   4223    ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
   4224    return angle::Result::Stop;
   4225 }
   4226 
   4227 angle::Result TextureStorage11_Buffer::findRenderTarget(const gl::Context *context,
   4228                                                        const gl::ImageIndex &index,
   4229                                                        GLsizei samples,
   4230                                                        RenderTargetD3D **outRT) const
   4231 {
   4232    ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
   4233    return angle::Result::Stop;
   4234 }
   4235 
   4236 angle::Result TextureStorage11_Buffer::getRenderTarget(const gl::Context *context,
   4237                                                       const gl::ImageIndex &index,
   4238                                                       GLsizei samples,
   4239                                                       RenderTargetD3D **outRT)
   4240 {
   4241    ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
   4242    return angle::Result::Stop;
   4243 }
   4244 
   4245 angle::Result TextureStorage11_Buffer::getSwizzleTexture(const gl::Context *context,
   4246                                                         const TextureHelper11 **outTexture)
   4247 {
   4248    ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
   4249    return angle::Result::Stop;
   4250 }
   4251 
   4252 angle::Result TextureStorage11_Buffer::getSwizzleRenderTarget(
   4253    const gl::Context *context,
   4254    int mipLevel,
   4255    const d3d11::RenderTargetView **outRTV)
   4256 {
   4257    ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
   4258    return angle::Result::Stop;
   4259 }
   4260 
   4261 angle::Result TextureStorage11_Buffer::createSRVForSampler(const gl::Context *context,
   4262                                                           int baseLevel,
   4263                                                           int mipLevels,
   4264                                                           DXGI_FORMAT format,
   4265                                                           const TextureHelper11 &texture,
   4266                                                           d3d11::SharedSRV *outSRV)
   4267 {
   4268    ASSERT(baseLevel == 0);
   4269    ASSERT(mipLevels == 1);
   4270    ASSERT(outSRV);
   4271    ANGLE_TRY(initTexture(context));
   4272    UINT bytesPerPixel = static_cast<UINT>(d3d11::GetDXGIFormatSizeInfo(format).pixelBytes);
   4273    D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
   4274    srvDesc.Format        = format;
   4275    srvDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
   4276    ASSERT(mBuffer.getOffset() % bytesPerPixel == 0);
   4277    srvDesc.Buffer.FirstElement = static_cast<UINT>(mBuffer.getOffset() / bytesPerPixel);
   4278    srvDesc.Buffer.NumElements  = static_cast<UINT>(mDataSize / bytesPerPixel);
   4279 
   4280    ANGLE_TRY(
   4281        mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV));
   4282    outSRV->setLabels("TexBuffer.SRV", &mKHRDebugLabel);
   4283 
   4284    return angle::Result::Continue;
   4285 }
   4286 
   4287 angle::Result TextureStorage11_Buffer::createSRVForImage(const gl::Context *context,
   4288                                                         int level,
   4289                                                         DXGI_FORMAT format,
   4290                                                         const TextureHelper11 &texture,
   4291                                                         d3d11::SharedSRV *outSRV)
   4292 {
   4293    ANGLE_TRY(initTexture(context));
   4294    UINT bytesPerPixel = static_cast<UINT>(d3d11::GetDXGIFormatSizeInfo(format).pixelBytes);
   4295    D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
   4296    srvDesc.Format        = format;
   4297    srvDesc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
   4298    ASSERT(mBuffer.getOffset() % bytesPerPixel == 0);
   4299    srvDesc.Buffer.FirstElement = static_cast<UINT>(mBuffer.getOffset() / bytesPerPixel);
   4300    srvDesc.Buffer.NumElements  = static_cast<UINT>(mDataSize / bytesPerPixel);
   4301 
   4302    ANGLE_TRY(
   4303        mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV));
   4304    outSRV->setLabels("TexBuffer.SRVForImage", &mKHRDebugLabel);
   4305 
   4306    return angle::Result::Continue;
   4307 }
   4308 angle::Result TextureStorage11_Buffer::createUAVForImage(const gl::Context *context,
   4309                                                         int level,
   4310                                                         DXGI_FORMAT format,
   4311                                                         const TextureHelper11 &texture,
   4312                                                         d3d11::SharedUAV *outUAV)
   4313 {
   4314    ANGLE_TRY(initTexture(context));
   4315    unsigned bytesPerPixel = d3d11::GetDXGIFormatSizeInfo(format).pixelBytes;
   4316    D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
   4317    uavDesc.Format        = format;
   4318    uavDesc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
   4319    ASSERT(mBuffer.getOffset() % bytesPerPixel == 0);
   4320    uavDesc.Buffer.FirstElement = static_cast<UINT>(mBuffer.getOffset() / bytesPerPixel);
   4321    uavDesc.Buffer.NumElements  = static_cast<UINT>(mDataSize / bytesPerPixel);
   4322    uavDesc.Buffer.Flags        = 0;
   4323 
   4324    ANGLE_TRY(
   4325        mRenderer->allocateResource(GetImplAs<Context11>(context), uavDesc, texture.get(), outUAV));
   4326    outUAV->setLabels("TexBuffer.UAVForImage", &mKHRDebugLabel);
   4327 
   4328    return angle::Result::Continue;
   4329 }
   4330 
   4331 void TextureStorage11_Buffer::associateImage(Image11 *image, const gl::ImageIndex &index) {}
   4332 void TextureStorage11_Buffer::disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage)
   4333 {}
   4334 void TextureStorage11_Buffer::verifyAssociatedImageValid(const gl::ImageIndex &index,
   4335                                                         Image11 *expectedImage)
   4336 {}
   4337 angle::Result TextureStorage11_Buffer::releaseAssociatedImage(const gl::Context *context,
   4338                                                              const gl::ImageIndex &index,
   4339                                                              Image11 *incomingImage)
   4340 {
   4341    return angle::Result::Continue;
   4342 }
   4343 
   4344 void TextureStorage11_Buffer::onLabelUpdate()
   4345 {
   4346    if (mTexture.valid())
   4347    {
   4348        mTexture.setKHRDebugLabel(&mKHRDebugLabel);
   4349    }
   4350 }
   4351 
   4352 }  // namespace rx