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

// TextureStorage11.cpp: Implements the abstract rx::TextureStorage11 class and its concrete derived
// classes TextureStorage11_2D and TextureStorage11_Cube, which act as the interface to the D3D11
// texture.

#include "libANGLE/renderer/d3d/d3d11/TextureStorage11.h"

#include <tuple>

#include "common/MemoryBuffer.h"
#include "common/utilities.h"
#include "libANGLE/Context.h"
#include "libANGLE/ImageIndex.h"
#include "libANGLE/formatutils.h"
#include "libANGLE/renderer/d3d/EGLImageD3D.h"
#include "libANGLE/renderer/d3d/TextureD3D.h"
#include "libANGLE/renderer/d3d/d3d11/Blit11.h"
#include "libANGLE/renderer/d3d/d3d11/Context11.h"
#include "libANGLE/renderer/d3d/d3d11/Image11.h"
#include "libANGLE/renderer/d3d/d3d11/RenderTarget11.h"
#include "libANGLE/renderer/d3d/d3d11/Renderer11.h"
#include "libANGLE/renderer/d3d/d3d11/StreamProducerD3DTexture.h"
#include "libANGLE/renderer/d3d/d3d11/SwapChain11.h"
#include "libANGLE/renderer/d3d/d3d11/formatutils11.h"
#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
#include "libANGLE/renderer/d3d/d3d11/texture_format_table.h"

namespace rx
{
TextureStorage11::SamplerKey::SamplerKey()
    : baseLevel(0), mipLevels(0), swizzle(false), dropStencil(false)
{}

TextureStorage11::SamplerKey::SamplerKey(int baseLevel,
                                         int mipLevels,
                                         bool swizzle,
                                         bool dropStencil)
    : baseLevel(baseLevel), mipLevels(mipLevels), swizzle(swizzle), dropStencil(dropStencil)
{}

bool TextureStorage11::SamplerKey::operator<(const SamplerKey &rhs) const
{
    return std::tie(baseLevel, mipLevels, swizzle, dropStencil) <
           std::tie(rhs.baseLevel, rhs.mipLevels, rhs.swizzle, rhs.dropStencil);
}

TextureStorage11::ImageKey::ImageKey()
    : level(0), layered(false), layer(0), access(GL_READ_ONLY), format(GL_R32UI)
{}

TextureStorage11::ImageKey::ImageKey(int level,
                                     bool layered,
                                     int layer,
                                     GLenum access,
                                     GLenum format)
    : level(level), layered(layered), layer(layer), access(access), format(format)
{}

bool TextureStorage11::ImageKey::operator<(const ImageKey &rhs) const
{
    return std::tie(level, layered, layer, access, format) <
           std::tie(rhs.level, rhs.layered, rhs.layer, rhs.access, rhs.format);
}

MultisampledRenderToTextureInfo::MultisampledRenderToTextureInfo(const GLsizei samples,
                                                                 const gl::ImageIndex index)
    : samples(samples), index(index)
{}

MultisampledRenderToTextureInfo::~MultisampledRenderToTextureInfo() {}

TextureStorage11::TextureStorage11(Renderer11 *renderer,
                                   UINT bindFlags,
                                   UINT miscFlags,
                                   GLenum internalFormat)
    : mRenderer(renderer),
      mTopLevel(0),
      mMipLevels(0),
      mFormatInfo(d3d11::Format::Get(internalFormat, mRenderer->getRenderer11DeviceCaps())),
      mTextureWidth(0),
      mTextureHeight(0),
      mTextureDepth(0),
      mDropStencilTexture(),
      mBindFlags(bindFlags),
      mMiscFlags(miscFlags)
{}

TextureStorage11::~TextureStorage11()
{
    mSrvCacheForSampler.clear();
}

DWORD TextureStorage11::GetTextureBindFlags(GLenum internalFormat,
                                            const Renderer11DeviceCaps &renderer11DeviceCaps,
                                            bool renderTarget)
{
    UINT bindFlags = 0;

    const d3d11::Format &formatInfo = d3d11::Format::Get(internalFormat, renderer11DeviceCaps);
    if (formatInfo.srvFormat != DXGI_FORMAT_UNKNOWN)
    {
        bindFlags |= D3D11_BIND_SHADER_RESOURCE;
    }
    if (formatInfo.uavFormat != DXGI_FORMAT_UNKNOWN &&
        renderer11DeviceCaps.featureLevel >= d3d11_gl::GetMinimumFeatureLevelForES31())
    {
        // If we find performance issues later on some specific GPUs, this may be the cause.
        bindFlags |= D3D11_BIND_UNORDERED_ACCESS;
    }
    if (formatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN)
    {
        bindFlags |= D3D11_BIND_DEPTH_STENCIL;
    }
    if (formatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN && renderTarget)
    {
        bindFlags |= D3D11_BIND_RENDER_TARGET;
    }

    return bindFlags;
}

DWORD TextureStorage11::GetTextureMiscFlags(GLenum internalFormat,
                                            const Renderer11DeviceCaps &renderer11DeviceCaps,
                                            bool renderTarget,
                                            int levels)
{
    UINT miscFlags = 0;

    const d3d11::Format &formatInfo = d3d11::Format::Get(internalFormat, renderer11DeviceCaps);
    if (renderTarget && levels > 1)
    {
        if (d3d11::SupportsMipGen(formatInfo.texFormat, renderer11DeviceCaps.featureLevel))
        {
            miscFlags |= D3D11_RESOURCE_MISC_GENERATE_MIPS;
        }
    }

    return miscFlags;
}

UINT TextureStorage11::getBindFlags() const
{
    return mBindFlags;
}

UINT TextureStorage11::getMiscFlags() const
{
    return mMiscFlags;
}

int TextureStorage11::getTopLevel() const
{
    // Applying top level is meant to be encapsulated inside TextureStorage11.
    UNREACHABLE();
    return mTopLevel;
}

bool TextureStorage11::isRenderTarget() const
{
    return (mBindFlags & (D3D11_BIND_RENDER_TARGET | D3D11_BIND_DEPTH_STENCIL)) != 0;
}

bool TextureStorage11::isManaged() const
{
    return false;
}

bool TextureStorage11::supportsNativeMipmapFunction() const
{
    return (mMiscFlags & D3D11_RESOURCE_MISC_GENERATE_MIPS) != 0;
}

int TextureStorage11::getLevelCount() const
{
    return mMipLevels - mTopLevel;
}

int TextureStorage11::getLevelWidth(int mipLevel) const
{
    return std::max(static_cast<int>(mTextureWidth) >> mipLevel, 1);
}

int TextureStorage11::getLevelHeight(int mipLevel) const
{
    return std::max(static_cast<int>(mTextureHeight) >> mipLevel, 1);
}

int TextureStorage11::getLevelDepth(int mipLevel) const
{
    return std::max(static_cast<int>(mTextureDepth) >> mipLevel, 1);
}

angle::Result TextureStorage11::getMippedResource(const gl::Context *context,
                                                  const TextureHelper11 **outResource)
{
    return getResource(context, outResource);
}

angle::Result TextureStorage11::getSubresourceIndex(const gl::Context *context,
                                                    const gl::ImageIndex &index,
                                                    UINT *outSubresourceIndex) const
{
    UINT mipSlice    = static_cast<UINT>(index.getLevelIndex() + mTopLevel);
    UINT arraySlice  = static_cast<UINT>(index.hasLayer() ? index.getLayerIndex() : 0);
    UINT subresource = D3D11CalcSubresource(mipSlice, arraySlice, mMipLevels);
    ASSERT(subresource != std::numeric_limits<UINT>::max());
    *outSubresourceIndex = subresource;
    return angle::Result::Continue;
}

angle::Result TextureStorage11::getSRVForSampler(const gl::Context *context,
                                                 const gl::TextureState &textureState,
                                                 const gl::SamplerState &sampler,
                                                 const d3d11::SharedSRV **outSRV)
{
    // Make sure to add the level offset for our tiny compressed texture workaround
    const GLuint effectiveBaseLevel = textureState.getEffectiveBaseLevel();
    const bool swizzleRequired      = textureState.swizzleRequired();
    const bool mipmapping           = gl::IsMipmapFiltered(sampler);
    unsigned int mipLevels =
        mipmapping ? (textureState.getEffectiveMaxLevel() - effectiveBaseLevel + 1) : 1;

    // Make sure there's 'mipLevels' mipmap levels below the base level (offset by the top level,
    // which corresponds to GL level 0)
    mipLevels = std::min(mipLevels, mMipLevels - mTopLevel - effectiveBaseLevel);

    if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3)
    {
        ASSERT(!swizzleRequired);
        ASSERT(mipLevels == 1 || mipLevels == mMipLevels);
    }

    if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
    {
        // We must ensure that the level zero texture is in sync with mipped texture.
        ANGLE_TRY(useLevelZeroWorkaroundTexture(context, mipLevels == 1));
    }

    if (swizzleRequired)
    {
        verifySwizzleExists(textureState.getSwizzleState());
    }

    // We drop the stencil when sampling from the SRV if three conditions hold:
    // 1. the drop stencil workaround is enabled.
    const bool emulateTinyStencilTextures =
        mRenderer->getFeatures().emulateTinyStencilTextures.enabled;
    // 2. this is a stencil texture.
    const bool hasStencil = (mFormatInfo.format().stencilBits > 0);
    // 3. the texture has a 1x1 or 2x2 mip.
    const int effectiveTopLevel = effectiveBaseLevel + mipLevels - 1;
    const bool hasSmallMips =
        (getLevelWidth(effectiveTopLevel) <= 2 || getLevelHeight(effectiveTopLevel) <= 2);

    const bool useDropStencil = (emulateTinyStencilTextures && hasStencil && hasSmallMips);
    const SamplerKey key(effectiveBaseLevel, mipLevels, swizzleRequired, useDropStencil);
    if (useDropStencil)
    {
        // Ensure drop texture gets created.
        DropStencil result = DropStencil::CREATED;
        ANGLE_TRY(ensureDropStencilTexture(context, &result));

        // Clear the SRV cache if necessary.
        // TODO(jmadill): Re-use find query result.
        const auto srvEntry = mSrvCacheForSampler.find(key);
        if (result == DropStencil::CREATED && srvEntry != mSrvCacheForSampler.end())
        {
            mSrvCacheForSampler.erase(key);
        }
    }

    ANGLE_TRY(getCachedOrCreateSRVForSampler(context, key, outSRV));

    return angle::Result::Continue;
}

angle::Result TextureStorage11::getCachedOrCreateSRVForSampler(const gl::Context *context,
                                                               const SamplerKey &key,
                                                               const d3d11::SharedSRV **outSRV)
{
    auto iter = mSrvCacheForSampler.find(key);
    if (iter != mSrvCacheForSampler.end())
    {
        *outSRV = &iter->second;
        return angle::Result::Continue;
    }

    const TextureHelper11 *texture = nullptr;
    DXGI_FORMAT format             = DXGI_FORMAT_UNKNOWN;

    if (key.swizzle)
    {
        const auto &swizzleFormat =
            mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps());
        ASSERT(!key.dropStencil || swizzleFormat.format().stencilBits == 0);
        ANGLE_TRY(getSwizzleTexture(context, &texture));
        format = swizzleFormat.srvFormat;
    }
    else if (key.dropStencil)
    {
        ASSERT(mDropStencilTexture.valid());
        texture = &mDropStencilTexture;
        format  = DXGI_FORMAT_R32_FLOAT;
    }
    else
    {
        ANGLE_TRY(getResource(context, &texture));
        format = mFormatInfo.srvFormat;
    }

    d3d11::SharedSRV srv;

    ANGLE_TRY(createSRVForSampler(context, key.baseLevel, key.mipLevels, format, *texture, &srv));

    const auto &insertIt = mSrvCacheForSampler.insert(std::make_pair(key, std::move(srv)));
    *outSRV              = &insertIt.first->second;

    return angle::Result::Continue;
}

angle::Result TextureStorage11::getSRVLevel(const gl::Context *context,
                                            int mipLevel,
                                            bool blitSRV,
                                            const d3d11::SharedSRV **outSRV)
{
    ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());

    auto &levelSRVs      = (blitSRV) ? mLevelBlitSRVs : mLevelSRVs;
    auto &otherLevelSRVs = (blitSRV) ? mLevelSRVs : mLevelBlitSRVs;

    if (!levelSRVs[mipLevel].valid())
    {
        // Only create a different SRV for blit if blit format is different from regular srv format
        if (otherLevelSRVs[mipLevel].valid() && mFormatInfo.srvFormat == mFormatInfo.blitSRVFormat)
        {
            levelSRVs[mipLevel] = otherLevelSRVs[mipLevel].makeCopy();
        }
        else
        {
            const TextureHelper11 *resource = nullptr;
            ANGLE_TRY(getResource(context, &resource));

            DXGI_FORMAT resourceFormat =
                blitSRV ? mFormatInfo.blitSRVFormat : mFormatInfo.srvFormat;
            ANGLE_TRY(createSRVForSampler(context, mipLevel, 1, resourceFormat, *resource,
                                          &levelSRVs[mipLevel]));
        }
    }

    *outSRV = &levelSRVs[mipLevel];
    return angle::Result::Continue;
}

angle::Result TextureStorage11::getSRVLevels(const gl::Context *context,
                                             GLint baseLevel,
                                             GLint maxLevel,
                                             const d3d11::SharedSRV **outSRV)
{
    unsigned int mipLevels = maxLevel - baseLevel + 1;

    // Make sure there's 'mipLevels' mipmap levels below the base level (offset by the top level,
    // which corresponds to GL level 0)
    mipLevels = std::min(mipLevels, mMipLevels - mTopLevel - baseLevel);

    if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3)
    {
        ASSERT(mipLevels == 1 || mipLevels == mMipLevels);
    }

    if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
    {
        // We must ensure that the level zero texture is in sync with mipped texture.
        ANGLE_TRY(useLevelZeroWorkaroundTexture(context, mipLevels == 1));
    }

    // TODO(jmadill): Assert we don't need to drop stencil.

    SamplerKey key(baseLevel, mipLevels, false, false);
    ANGLE_TRY(getCachedOrCreateSRVForSampler(context, key, outSRV));

    return angle::Result::Continue;
}

angle::Result TextureStorage11::getSRVForImage(const gl::Context *context,
                                               const gl::ImageUnit &imageUnit,
                                               const d3d11::SharedSRV **outSRV)
{
    // TODO(Xinghua.cao@intel.com): Add solution to handle swizzle required.
    ImageKey key(imageUnit.level, (imageUnit.layered == GL_TRUE), imageUnit.layer, imageUnit.access,
                 imageUnit.format);
    ANGLE_TRY(getCachedOrCreateSRVForImage(context, key, outSRV));
    return angle::Result::Continue;
}

angle::Result TextureStorage11::getCachedOrCreateSRVForImage(const gl::Context *context,
                                                             const ImageKey &key,
                                                             const d3d11::SharedSRV **outSRV)
{
    auto iter = mSrvCacheForImage.find(key);
    if (iter != mSrvCacheForImage.end())
    {
        *outSRV = &iter->second;
        return angle::Result::Continue;
    }
    const TextureHelper11 *texture = nullptr;
    ANGLE_TRY(getResource(context, &texture));
    DXGI_FORMAT format =
        d3d11::Format::Get(key.format, mRenderer->getRenderer11DeviceCaps()).srvFormat;
    d3d11::SharedSRV srv;
    ANGLE_TRY(createSRVForImage(context, key.level, format, *texture, &srv));
    const auto &insertIt = mSrvCacheForImage.insert(std::make_pair(key, std::move(srv)));
    *outSRV              = &insertIt.first->second;
    return angle::Result::Continue;
}

angle::Result TextureStorage11::getUAVForImage(const gl::Context *context,
                                               const gl::ImageUnit &imageUnit,
                                               const d3d11::SharedUAV **outUAV)
{
    // TODO(Xinghua.cao@intel.com): Add solution to handle swizzle required.
    ImageKey key(imageUnit.level, (imageUnit.layered == GL_TRUE), imageUnit.layer, imageUnit.access,
                 imageUnit.format);
    ANGLE_TRY(getCachedOrCreateUAVForImage(context, key, outUAV));
    return angle::Result::Continue;
}

angle::Result TextureStorage11::getCachedOrCreateUAVForImage(const gl::Context *context,
                                                             const ImageKey &key,
                                                             const d3d11::SharedUAV **outUAV)
{
    auto iter = mUavCacheForImage.find(key);
    if (iter != mUavCacheForImage.end())
    {
        *outUAV = &iter->second;
        return angle::Result::Continue;
    }
    const TextureHelper11 *texture = nullptr;
    ANGLE_TRY(getResource(context, &texture));
    DXGI_FORMAT format =
        d3d11::Format::Get(key.format, mRenderer->getRenderer11DeviceCaps()).uavFormat;
    d3d11::SharedUAV uav;
    ANGLE_TRY(createUAVForImage(context, key.level, format, *texture, &uav));
    const auto &insertIt = mUavCacheForImage.insert(std::make_pair(key, std::move(uav)));
    *outUAV              = &insertIt.first->second;
    return angle::Result::Continue;
}

const d3d11::Format &TextureStorage11::getFormatSet() const
{
    return mFormatInfo;
}

angle::Result TextureStorage11::generateSwizzles(const gl::Context *context,
                                                 const gl::SwizzleState &swizzleTarget)
{
    for (int level = 0; level < getLevelCount(); level++)
    {
        // Check if the swizzle for this level is out of date
        if (mSwizzleCache[level] != swizzleTarget)
        {
            // Need to re-render the swizzle for this level
            const d3d11::SharedSRV *sourceSRV = nullptr;
            ANGLE_TRY(getSRVLevel(context, level, true, &sourceSRV));

            const d3d11::RenderTargetView *destRTV;
            ANGLE_TRY(getSwizzleRenderTarget(context, level, &destRTV));

            gl::Extents size(getLevelWidth(level), getLevelHeight(level), getLevelDepth(level));

            Blit11 *blitter = mRenderer->getBlitter();

            ANGLE_TRY(blitter->swizzleTexture(context, *sourceSRV, *destRTV, size, swizzleTarget));

            mSwizzleCache[level] = swizzleTarget;
        }
    }

    return angle::Result::Continue;
}

void TextureStorage11::markLevelDirty(int mipLevel)
{
    if (mipLevel >= 0 && static_cast<size_t>(mipLevel) < mSwizzleCache.size())
    {
        // The default constructor of SwizzleState has GL_INVALID_INDEX for all channels which is
        // not a valid swizzle combination
        if (mSwizzleCache[mipLevel] != gl::SwizzleState())
        {
            // TODO(jmadill): Invalidate specific swizzle.
            mRenderer->getStateManager()->invalidateSwizzles();
            mSwizzleCache[mipLevel] = gl::SwizzleState();
        }
    }

    if (mDropStencilTexture.valid())
    {
        mDropStencilTexture.reset();
    }
}

void TextureStorage11::markDirty()
{
    for (size_t mipLevel = 0; mipLevel < mSwizzleCache.size(); ++mipLevel)
    {
        markLevelDirty(static_cast<int>(mipLevel));
    }
}

angle::Result TextureStorage11::updateSubresourceLevel(const gl::Context *context,
                                                       const TextureHelper11 &srcTexture,
                                                       unsigned int sourceSubresource,
                                                       const gl::ImageIndex &index,
                                                       const gl::Box &copyArea)
{
    ASSERT(srcTexture.valid());

    const GLint level = index.getLevelIndex();

    markLevelDirty(level);

    gl::Extents texSize(getLevelWidth(level), getLevelHeight(level), getLevelDepth(level));

    bool fullCopy = copyArea.x == 0 && copyArea.y == 0 && copyArea.z == 0 &&
                    copyArea.width == texSize.width && copyArea.height == texSize.height &&
                    copyArea.depth == texSize.depth;

    const TextureHelper11 *dstTexture = nullptr;

    // If the zero-LOD workaround is active and we want to update a level greater than zero, then we
    // should update the mipmapped texture, even if mapmaps are currently disabled.
    if (level > 0 && mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
    {
        ANGLE_TRY(getMippedResource(context, &dstTexture));
    }
    else
    {
        ANGLE_TRY(getResource(context, &dstTexture));
    }

    unsigned int dstSubresource = 0;
    ANGLE_TRY(getSubresourceIndex(context, index, &dstSubresource));

    ASSERT(dstTexture->valid());

    const d3d11::DXGIFormatSize &dxgiFormatSizeInfo =
        d3d11::GetDXGIFormatSizeInfo(mFormatInfo.texFormat);
    if (!fullCopy && mFormatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN)
    {
        // CopySubresourceRegion cannot copy partial depth stencils, use the blitter instead
        Blit11 *blitter = mRenderer->getBlitter();
        return blitter->copyDepthStencil(context, srcTexture, sourceSubresource, copyArea, texSize,
                                         *dstTexture, dstSubresource, copyArea, texSize, nullptr);
    }

    D3D11_BOX srcBox;
    srcBox.left = copyArea.x;
    srcBox.top  = copyArea.y;
    srcBox.right =
        copyArea.x + roundUp(static_cast<UINT>(copyArea.width), dxgiFormatSizeInfo.blockWidth);
    srcBox.bottom =
        copyArea.y + roundUp(static_cast<UINT>(copyArea.height), dxgiFormatSizeInfo.blockHeight);
    srcBox.front = copyArea.z;
    srcBox.back  = copyArea.z + copyArea.depth;

    ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();

    deviceContext->CopySubresourceRegion(dstTexture->get(), dstSubresource, copyArea.x, copyArea.y,
                                         copyArea.z, srcTexture.get(), sourceSubresource,
                                         fullCopy ? nullptr : &srcBox);
    return angle::Result::Continue;
}

angle::Result TextureStorage11::copySubresourceLevel(const gl::Context *context,
                                                     const TextureHelper11 &dstTexture,
                                                     unsigned int dstSubresource,
                                                     const gl::ImageIndex &index,
                                                     const gl::Box &region)
{
    ASSERT(dstTexture.valid());

    const TextureHelper11 *srcTexture = nullptr;

    // If the zero-LOD workaround is active and we want to update a level greater than zero, then we
    // should update the mipmapped texture, even if mapmaps are currently disabled.
    if (index.getLevelIndex() > 0 && mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
    {
        ANGLE_TRY(getMippedResource(context, &srcTexture));
    }
    else
    {
        ANGLE_TRY(getResource(context, &srcTexture));
    }

    ASSERT(srcTexture->valid());

    unsigned int srcSubresource = 0;
    ANGLE_TRY(getSubresourceIndex(context, index, &srcSubresource));

    ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();

    // D3D11 can't perform partial CopySubresourceRegion on depth/stencil textures, so pSrcBox
    // should be nullptr.
    D3D11_BOX srcBox;
    D3D11_BOX *pSrcBox = nullptr;
    if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3)
    {
        GLsizei width  = region.width;
        GLsizei height = region.height;
        d3d11::MakeValidSize(false, mFormatInfo.texFormat, &width, &height, nullptr);

        // Keep srcbox as nullptr if we're dealing with tiny mips of compressed textures.
        if (width == region.width && height == region.height)
        {
            // However, D3D10Level9 doesn't always perform CopySubresourceRegion correctly unless
            // the source box is specified. This is okay, since we don't perform
            // CopySubresourceRegion on depth/stencil textures on 9_3.
            ASSERT(mFormatInfo.dsvFormat == DXGI_FORMAT_UNKNOWN);
            srcBox.left   = region.x;
            srcBox.right  = region.x + region.width;
            srcBox.top    = region.y;
            srcBox.bottom = region.y + region.height;
            srcBox.front  = region.z;
            srcBox.back   = region.z + region.depth;
            pSrcBox       = &srcBox;
        }
    }

    deviceContext->CopySubresourceRegion(dstTexture.get(), dstSubresource, region.x, region.y,
                                         region.z, srcTexture->get(), srcSubresource, pSrcBox);

    return angle::Result::Continue;
}

angle::Result TextureStorage11::generateMipmap(const gl::Context *context,
                                               const gl::ImageIndex &sourceIndex,
                                               const gl::ImageIndex &destIndex)
{
    ASSERT(sourceIndex.getLayerIndex() == destIndex.getLayerIndex());

    markLevelDirty(destIndex.getLevelIndex());

    RenderTargetD3D *source = nullptr;
    ANGLE_TRY(getRenderTarget(context, sourceIndex, 0, &source));

    RenderTargetD3D *dest = nullptr;
    GLsizei destSamples   = 0;
    ANGLE_TRY(getRenderTarget(context, destIndex, destSamples, &dest));

    RenderTarget11 *rt11                   = GetAs<RenderTarget11>(source);
    const d3d11::SharedSRV &sourceSRV      = rt11->getBlitShaderResourceView(context);
    const d3d11::RenderTargetView &destRTV = rt11->getRenderTargetView();

    gl::Box sourceArea(0, 0, 0, source->getWidth(), source->getHeight(), source->getDepth());
    gl::Extents sourceSize(source->getWidth(), source->getHeight(), source->getDepth());

    gl::Box destArea(0, 0, 0, dest->getWidth(), dest->getHeight(), dest->getDepth());
    gl::Extents destSize(dest->getWidth(), dest->getHeight(), dest->getDepth());

    Blit11 *blitter = mRenderer->getBlitter();
    const gl::InternalFormat &sourceInternalFormat =
        gl::GetSizedInternalFormatInfo(source->getInternalFormat());
    GLenum format = sourceInternalFormat.format;
    GLenum type   = sourceInternalFormat.type;
    return blitter->copyTexture(context, sourceSRV, sourceArea, sourceSize, format, destRTV,
                                destArea, destSize, nullptr, format, type, GL_LINEAR, false, false,
                                false);
}

void TextureStorage11::verifySwizzleExists(const gl::SwizzleState &swizzleState)
{
    for (unsigned int level = 0; level < mMipLevels; level++)
    {
        ASSERT(mSwizzleCache[level] == swizzleState);
    }
}

void TextureStorage11::clearSRVCache()
{
    markDirty();
    mSrvCacheForSampler.clear();

    for (size_t level = 0; level < mLevelSRVs.size(); level++)
    {
        mLevelSRVs[level].reset();
        mLevelBlitSRVs[level].reset();
    }
}

angle::Result TextureStorage11::copyToStorage(const gl::Context *context,
                                              TextureStorage *destStorage)
{
    ASSERT(destStorage);

    const TextureHelper11 *sourceResouce = nullptr;
    ANGLE_TRY(getResource(context, &sourceResouce));

    TextureStorage11 *dest11            = GetAs<TextureStorage11>(destStorage);
    const TextureHelper11 *destResource = nullptr;
    ANGLE_TRY(dest11->getResource(context, &destResource));

    ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
    immediateContext->CopyResource(destResource->get(), sourceResouce->get());

    dest11->markDirty();

    return angle::Result::Continue;
}

void TextureStorage11::invalidateTextures()
{
    mRenderer->getStateManager()->invalidateTexturesAndSamplers();
}

angle::Result TextureStorage11::setData(const gl::Context *context,
                                        const gl::ImageIndex &index,
                                        ImageD3D *image,
                                        const gl::Box *destBox,
                                        GLenum type,
                                        const gl::PixelUnpackState &unpack,
                                        const uint8_t *pixelData)
{
    ASSERT(!image->isDirty());

    markLevelDirty(index.getLevelIndex());

    const TextureHelper11 *resource = nullptr;
    ANGLE_TRY(getResource(context, &resource));
    ASSERT(resource && resource->valid());

    UINT destSubresource = 0;
    ANGLE_TRY(getSubresourceIndex(context, index, &destSubresource));

    const gl::InternalFormat &internalFormatInfo =
        gl::GetInternalFormatInfo(image->getInternalFormat(), type);

    gl::Box levelBox(0, 0, 0, getLevelWidth(index.getLevelIndex()),
                     getLevelHeight(index.getLevelIndex()), getLevelDepth(index.getLevelIndex()));
    bool fullUpdate = (destBox == nullptr || *destBox == levelBox);
    ASSERT(internalFormatInfo.depthBits == 0 || fullUpdate);

    // TODO(jmadill): Handle compressed formats
    // Compressed formats have different load syntax, so we'll have to handle them with slightly
    // different logic. Will implemnent this in a follow-up patch, and ensure we do not use SetData
    // with compressed formats in the calling logic.
    ASSERT(!internalFormatInfo.compressed);

    Context11 *context11 = GetImplAs<Context11>(context);

    const int width    = destBox ? destBox->width : static_cast<int>(image->getWidth());
    const int height   = destBox ? destBox->height : static_cast<int>(image->getHeight());
    const int depth    = destBox ? destBox->depth : static_cast<int>(image->getDepth());
    GLuint srcRowPitch = 0;
    ANGLE_CHECK_GL_MATH(context11,
                        internalFormatInfo.computeRowPitch(type, width, unpack.alignment,
                                                           unpack.rowLength, &srcRowPitch));
    GLuint srcDepthPitch = 0;
    ANGLE_CHECK_GL_MATH(context11, internalFormatInfo.computeDepthPitch(
                                       height, unpack.imageHeight, srcRowPitch, &srcDepthPitch));
    GLuint srcSkipBytes = 0;
    ANGLE_CHECK_GL_MATH(
        context11, internalFormatInfo.computeSkipBytes(type, srcRowPitch, srcDepthPitch, unpack,
                                                       index.usesTex3D(), &srcSkipBytes));

    const d3d11::Format &d3d11Format =
        d3d11::Format::Get(image->getInternalFormat(), mRenderer->getRenderer11DeviceCaps());
    const d3d11::DXGIFormatSize &dxgiFormatInfo =
        d3d11::GetDXGIFormatSizeInfo(d3d11Format.texFormat);

    const size_t outputPixelSize = dxgiFormatInfo.pixelBytes;

    UINT bufferRowPitch   = static_cast<unsigned int>(outputPixelSize) * width;
    UINT bufferDepthPitch = bufferRowPitch * height;

    const size_t neededSize               = bufferDepthPitch * depth;
    angle::MemoryBuffer *conversionBuffer = nullptr;
    const uint8_t *data                   = nullptr;

    LoadImageFunctionInfo loadFunctionInfo = d3d11Format.getLoadFunctions()(type);
    if (loadFunctionInfo.requiresConversion)
    {
        ANGLE_TRY(mRenderer->getScratchMemoryBuffer(context11, neededSize, &conversionBuffer));
        loadFunctionInfo.loadFunction(width, height, depth, pixelData + srcSkipBytes, srcRowPitch,
                                      srcDepthPitch, conversionBuffer->data(), bufferRowPitch,
                                      bufferDepthPitch);
        data = conversionBuffer->data();
    }
    else
    {
        data             = pixelData + srcSkipBytes;
        bufferRowPitch   = srcRowPitch;
        bufferDepthPitch = srcDepthPitch;
    }

    ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();

    if (!fullUpdate)
    {
        ASSERT(destBox);

        D3D11_BOX destD3DBox;
        destD3DBox.left   = destBox->x;
        destD3DBox.right  = destBox->x + destBox->width;
        destD3DBox.top    = destBox->y;
        destD3DBox.bottom = destBox->y + destBox->height;
        destD3DBox.front  = destBox->z;
        destD3DBox.back   = destBox->z + destBox->depth;

        immediateContext->UpdateSubresource(resource->get(), destSubresource, &destD3DBox, data,
                                            bufferRowPitch, bufferDepthPitch);
    }
    else
    {
        immediateContext->UpdateSubresource(resource->get(), destSubresource, nullptr, data,
                                            bufferRowPitch, bufferDepthPitch);
    }

    return angle::Result::Continue;
}

angle::Result TextureStorage11::ensureDropStencilTexture(
    const gl::Context *context,
    TextureStorage11::DropStencil *dropStencilOut)
{
    ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
    return angle::Result::Stop;
}

angle::Result TextureStorage11::initDropStencilTexture(const gl::Context *context,
                                                       const gl::ImageIndexIterator &it)
{
    const TextureHelper11 *sourceTexture = nullptr;
    ANGLE_TRY(getResource(context, &sourceTexture));

    gl::ImageIndexIterator itCopy = it;

    while (itCopy.hasNext())
    {
        gl::ImageIndex index = itCopy.next();
        gl::Box wholeArea(0, 0, 0, getLevelWidth(index.getLevelIndex()),
                          getLevelHeight(index.getLevelIndex()), 1);
        gl::Extents wholeSize(wholeArea.width, wholeArea.height, 1);

        UINT subresource = 0;
        ANGLE_TRY(getSubresourceIndex(context, index, &subresource));

        ANGLE_TRY(mRenderer->getBlitter()->copyDepthStencil(
            context, *sourceTexture, subresource, wholeArea, wholeSize, mDropStencilTexture,
            subresource, wholeArea, wholeSize, nullptr));
    }

    return angle::Result::Continue;
}

GLsizei TextureStorage11::getRenderToTextureSamples() const
{
    if (mMSTexInfo)
    {
        return mMSTexInfo->samples;
    }
    return 0;
}

TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer, SwapChain11 *swapchain)
    : TextureStorage11(renderer,
                       D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE,
                       0,
                       swapchain->getRenderTargetInternalFormat()),
      mTexture(swapchain->getOffscreenTexture()),
      mLevelZeroTexture(),
      mLevelZeroRenderTarget(nullptr),
      mUseLevelZeroTexture(false),
      mSwizzleTexture()
{
    for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
    {
        mAssociatedImages[i] = nullptr;
        mRenderTarget[i]     = nullptr;
    }

    D3D11_TEXTURE2D_DESC texDesc;
    mTexture.getDesc(&texDesc);
    mMipLevels     = texDesc.MipLevels;
    mTextureWidth  = texDesc.Width;
    mTextureHeight = texDesc.Height;
    mTextureDepth  = 1;
    mHasKeyedMutex = (texDesc.MiscFlags & D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX) != 0;
}

TextureStorage11_2D::TextureStorage11_2D(Renderer11 *renderer,
                                         GLenum internalformat,
                                         bool renderTarget,
                                         GLsizei width,
                                         GLsizei height,
                                         int levels,
                                         bool hintLevelZeroOnly)
    : TextureStorage11(
          renderer,
          GetTextureBindFlags(internalformat, renderer->getRenderer11DeviceCaps(), renderTarget),
          GetTextureMiscFlags(internalformat,
                              renderer->getRenderer11DeviceCaps(),
                              renderTarget,
                              levels),
          internalformat),
      mTexture(),
      mHasKeyedMutex(false),
      mLevelZeroTexture(),
      mLevelZeroRenderTarget(nullptr),
      mUseLevelZeroTexture(hintLevelZeroOnly && levels > 1),
      mSwizzleTexture()
{
    for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
    {
        mAssociatedImages[i] = nullptr;
        mRenderTarget[i]     = nullptr;
    }

    d3d11::MakeValidSize(false, mFormatInfo.texFormat, &width, &height, &mTopLevel);
    mMipLevels     = mTopLevel + levels;
    mTextureWidth  = width;
    mTextureHeight = height;
    mTextureDepth  = 1;

    // The LevelZeroOnly hint should only be true if the zero max LOD workaround is active.
    ASSERT(!mUseLevelZeroTexture || mRenderer->getFeatures().zeroMaxLodWorkaround.enabled);
}

angle::Result TextureStorage11_2D::onDestroy(const gl::Context *context)
{
    for (unsigned i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
    {
        if (mAssociatedImages[i] != nullptr)
        {
            mAssociatedImages[i]->verifyAssociatedStorageValid(this);

            // We must let the Images recover their data before we delete it from the
            // TextureStorage.
            ANGLE_TRY(mAssociatedImages[i]->recoverFromAssociatedStorage(context));
        }
    }

    if (mHasKeyedMutex)
    {
        // If the keyed mutex is released that will unbind it and cause the state cache to become
        // desynchronized.
        mRenderer->getStateManager()->invalidateBoundViews();
    }

    return angle::Result::Continue;
}

TextureStorage11_2D::~TextureStorage11_2D() {}

angle::Result TextureStorage11_2D::copyToStorage(const gl::Context *context,
                                                 TextureStorage *destStorage)
{
    ASSERT(destStorage);

    TextureStorage11_2D *dest11           = GetAs<TextureStorage11_2D>(destStorage);
    ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();

    if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
    {
        // If either mTexture or mLevelZeroTexture exist, then we need to copy them into the
        // corresponding textures in destStorage.
        if (mTexture.valid())
        {
            ANGLE_TRY(dest11->useLevelZeroWorkaroundTexture(context, false));

            const TextureHelper11 *destResource = nullptr;
            ANGLE_TRY(dest11->getResource(context, &destResource));

            immediateContext->CopyResource(destResource->get(), mTexture.get());
        }

        if (mLevelZeroTexture.valid())
        {
            ANGLE_TRY(dest11->useLevelZeroWorkaroundTexture(context, true));

            const TextureHelper11 *destResource = nullptr;
            ANGLE_TRY(dest11->getResource(context, &destResource));

            immediateContext->CopyResource(destResource->get(), mLevelZeroTexture.get());
        }

        return angle::Result::Continue;
    }

    const TextureHelper11 *sourceResouce = nullptr;
    ANGLE_TRY(getResource(context, &sourceResouce));

    const TextureHelper11 *destResource = nullptr;
    ANGLE_TRY(dest11->getResource(context, &destResource));

    immediateContext->CopyResource(destResource->get(), sourceResouce->get());
    dest11->markDirty();

    return angle::Result::Continue;
}

angle::Result TextureStorage11_2D::useLevelZeroWorkaroundTexture(const gl::Context *context,
                                                                 bool useLevelZeroTexture)
{
    if (useLevelZeroTexture && mMipLevels > 1)
    {
        if (!mUseLevelZeroTexture && mTexture.valid())
        {
            ANGLE_TRY(ensureTextureExists(context, 1));

            // Pull data back from the mipped texture if necessary.
            ASSERT(mLevelZeroTexture.valid());
            ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
            deviceContext->CopySubresourceRegion(mLevelZeroTexture.get(), 0, 0, 0, 0,
                                                 mTexture.get(), 0, nullptr);
        }

        mUseLevelZeroTexture = true;
    }
    else
    {
        if (mUseLevelZeroTexture && mLevelZeroTexture.valid())
        {
            ANGLE_TRY(ensureTextureExists(context, mMipLevels));

            // Pull data back from the level zero texture if necessary.
            ASSERT(mTexture.valid());
            ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();
            deviceContext->CopySubresourceRegion(mTexture.get(), 0, 0, 0, 0,
                                                 mLevelZeroTexture.get(), 0, nullptr);
        }

        mUseLevelZeroTexture = false;
    }

    return angle::Result::Continue;
}

void TextureStorage11_2D::associateImage(Image11 *image, const gl::ImageIndex &index)
{
    const GLint level = index.getLevelIndex();

    ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
    if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
    {
        mAssociatedImages[level] = image;
    }
}

void TextureStorage11_2D::verifyAssociatedImageValid(const gl::ImageIndex &index,
                                                     Image11 *expectedImage)
{
    const GLint level = index.getLevelIndex();

    ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
    // This validation check should never return false. It means the Image/TextureStorage
    // association is broken.
    ASSERT(mAssociatedImages[level] == expectedImage);
}

// disassociateImage allows an Image to end its association with a Storage.
void TextureStorage11_2D::disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage)
{
    const GLint level = index.getLevelIndex();

    ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
    ASSERT(mAssociatedImages[level] == expectedImage);
    mAssociatedImages[level] = nullptr;
}

// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image
// recover its data before ending the association.
angle::Result TextureStorage11_2D::releaseAssociatedImage(const gl::Context *context,
                                                          const gl::ImageIndex &index,
                                                          Image11 *incomingImage)
{
    const GLint level = index.getLevelIndex();

    ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);

    if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
    {
        // No need to let the old Image recover its data, if it is also the incoming Image.
        if (mAssociatedImages[level] != nullptr && mAssociatedImages[level] != incomingImage)
        {
            // Ensure that the Image is still associated with this TextureStorage.
            mAssociatedImages[level]->verifyAssociatedStorageValid(this);

            // Force the image to recover from storage before its data is overwritten.
            // This will reset mAssociatedImages[level] to nullptr too.
            ANGLE_TRY(mAssociatedImages[level]->recoverFromAssociatedStorage(context));
        }
    }

    return angle::Result::Continue;
}

angle::Result TextureStorage11_2D::getResource(const gl::Context *context,
                                               const TextureHelper11 **outResource)
{
    if (mUseLevelZeroTexture && mMipLevels > 1)
    {
        ANGLE_TRY(ensureTextureExists(context, 1));

        *outResource = &mLevelZeroTexture;
        return angle::Result::Continue;
    }

    ANGLE_TRY(ensureTextureExists(context, mMipLevels));

    *outResource = &mTexture;
    return angle::Result::Continue;
}

angle::Result TextureStorage11_2D::getMippedResource(const gl::Context *context,
                                                     const TextureHelper11 **outResource)
{
    // This shouldn't be called unless the zero max LOD workaround is active.
    ASSERT(mRenderer->getFeatures().zeroMaxLodWorkaround.enabled);

    ANGLE_TRY(ensureTextureExists(context, mMipLevels));

    *outResource = &mTexture;
    return angle::Result::Continue;
}

angle::Result TextureStorage11_2D::ensureTextureExists(const gl::Context *context, int mipLevels)
{
    // If mMipLevels = 1 then always use mTexture rather than mLevelZeroTexture.
    bool useLevelZeroTexture = mRenderer->getFeatures().zeroMaxLodWorkaround.enabled
                                   ? (mipLevels == 1) && (mMipLevels > 1)
                                   : false;
    TextureHelper11 *outputTexture = useLevelZeroTexture ? &mLevelZeroTexture : &mTexture;

    // if the width or height is not positive this should be treated as an incomplete texture
    // we handle that here by skipping the d3d texture creation
    if (!outputTexture->valid() && mTextureWidth > 0 && mTextureHeight > 0)
    {
        ASSERT(mipLevels > 0);

        D3D11_TEXTURE2D_DESC desc;
        desc.Width              = mTextureWidth;  // Compressed texture size constraints?
        desc.Height             = mTextureHeight;
        desc.MipLevels          = mipLevels;
        desc.ArraySize          = 1;
        desc.Format             = mFormatInfo.texFormat;
        desc.SampleDesc.Count   = 1;
        desc.SampleDesc.Quality = 0;
        desc.Usage              = D3D11_USAGE_DEFAULT;
        desc.BindFlags          = getBindFlags();
        desc.CPUAccessFlags     = 0;
        desc.MiscFlags          = getMiscFlags();

        ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, mFormatInfo,
                                             outputTexture));

        if (useLevelZeroTexture)
        {
            outputTexture->setDebugName("TexStorage2D.Level0Texture");
        }
        else
        {
            outputTexture->setDebugName("TexStorage2D.Texture");
        }
    }

    return angle::Result::Continue;
}

angle::Result TextureStorage11_2D::getRenderTarget(const gl::Context *context,
                                                   const gl::ImageIndex &index,
                                                   GLsizei samples,
                                                   RenderTargetD3D **outRT)
{
    ASSERT(!index.hasLayer());

    const int level = index.getLevelIndex();
    ASSERT(level >= 0 && level < getLevelCount());

    // In GL ES 2.0, the application can only render to level zero of the texture (Section 4.4.3 of
    // the GLES 2.0 spec, page 113 of version 2.0.25). Other parts of TextureStorage11_2D could
    // create RTVs on non-zero levels of the texture (e.g. generateMipmap).
    // On Feature Level 9_3, this is unlikely to be useful. The renderer can't create SRVs on the
    // individual levels of the texture, so methods like generateMipmap can't do anything useful
    // with non-zero-level RTVs. Therefore if level > 0 on 9_3 then there's almost certainly
    // something wrong.
    ASSERT(
        !(mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_9_3 && level > 0));
    ASSERT(outRT);
    if (mRenderTarget[level])
    {
        *outRT = mRenderTarget[level].get();
        return angle::Result::Continue;
    }

    if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
    {
        ASSERT(level == 0);
        ANGLE_TRY(useLevelZeroWorkaroundTexture(context, true));
    }

    const TextureHelper11 *texture = nullptr;
    ANGLE_TRY(getResource(context, &texture));

    const d3d11::SharedSRV *srv = nullptr;
    ANGLE_TRY(getSRVLevel(context, level, false, &srv));

    const d3d11::SharedSRV *blitSRV = nullptr;
    ANGLE_TRY(getSRVLevel(context, level, true, &blitSRV));

    Context11 *context11 = GetImplAs<Context11>(context);

    if (mUseLevelZeroTexture)
    {
        if (!mLevelZeroRenderTarget)
        {
            D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
            rtvDesc.Format             = mFormatInfo.rtvFormat;
            rtvDesc.ViewDimension      = D3D11_RTV_DIMENSION_TEXTURE2D;
            rtvDesc.Texture2D.MipSlice = mTopLevel + level;

            d3d11::RenderTargetView rtv;
            ANGLE_TRY(
                mRenderer->allocateResource(context11, rtvDesc, mLevelZeroTexture.get(), &rtv));
            rtv.setDebugName("TexStorage2D.Level0RTV");

            mLevelZeroRenderTarget.reset(new TextureRenderTarget11(
                std::move(rtv), mLevelZeroTexture, d3d11::SharedSRV(), d3d11::SharedSRV(),
                mFormatInfo.internalFormat, getFormatSet(), getLevelWidth(level),
                getLevelHeight(level), 1, 0));
        }

        *outRT = mLevelZeroRenderTarget.get();
        return angle::Result::Continue;
    }

    if (mFormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN)
    {
        D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
        rtvDesc.Format             = mFormatInfo.rtvFormat;
        rtvDesc.ViewDimension      = D3D11_RTV_DIMENSION_TEXTURE2D;
        rtvDesc.Texture2D.MipSlice = mTopLevel + level;

        d3d11::RenderTargetView rtv;
        ANGLE_TRY(mRenderer->allocateResource(context11, rtvDesc, texture->get(), &rtv));
        rtv.setDebugName("TexStorage2D.RTV");

        mRenderTarget[level].reset(new TextureRenderTarget11(
            std::move(rtv), *texture, *srv, *blitSRV, mFormatInfo.internalFormat, getFormatSet(),
            getLevelWidth(level), getLevelHeight(level), 1, 0));

        *outRT = mRenderTarget[level].get();
        return angle::Result::Continue;
    }

    ASSERT(mFormatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN);

    D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
    dsvDesc.Format             = mFormatInfo.dsvFormat;
    dsvDesc.ViewDimension      = D3D11_DSV_DIMENSION_TEXTURE2D;
    dsvDesc.Texture2D.MipSlice = mTopLevel + level;
    dsvDesc.Flags              = 0;

    d3d11::DepthStencilView dsv;
    ANGLE_TRY(mRenderer->allocateResource(context11, dsvDesc, texture->get(), &dsv));
    dsv.setDebugName("TexStorage2D.DSV");

    mRenderTarget[level].reset(new TextureRenderTarget11(
        std::move(dsv), *texture, *srv, mFormatInfo.internalFormat, getFormatSet(),
        getLevelWidth(level), getLevelHeight(level), 1, 0));

    *outRT = mRenderTarget[level].get();
    return angle::Result::Continue;
}

angle::Result TextureStorage11_2D::createSRVForSampler(const gl::Context *context,
                                                       int baseLevel,
                                                       int mipLevels,
                                                       DXGI_FORMAT format,
                                                       const TextureHelper11 &texture,
                                                       d3d11::SharedSRV *outSRV)
{
    ASSERT(outSRV);

    D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
    srvDesc.Format                    = format;
    srvDesc.ViewDimension             = D3D11_SRV_DIMENSION_TEXTURE2D;
    srvDesc.Texture2D.MostDetailedMip = mTopLevel + baseLevel;
    srvDesc.Texture2D.MipLevels       = mipLevels;

    const TextureHelper11 *srvTexture = &texture;

    if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
    {
        ASSERT(mTopLevel == 0);
        ASSERT(baseLevel == 0);
        // This code also assumes that the incoming texture equals either mLevelZeroTexture or
        // mTexture.

        if (mipLevels == 1 && mMipLevels > 1)
        {
            // We must use a SRV on the level-zero-only texture.
            ANGLE_TRY(ensureTextureExists(context, 1));
            srvTexture = &mLevelZeroTexture;
        }
        else
        {
            ASSERT(mipLevels == static_cast<int>(mMipLevels));
            ASSERT(mTexture.valid() && texture == mTexture);
            srvTexture = &mTexture;
        }
    }

    ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, srvTexture->get(),
                                          outSRV));
    outSRV->setDebugName("TexStorage2D.SRV");

    return angle::Result::Continue;
}

angle::Result TextureStorage11_2D::createSRVForImage(const gl::Context *context,
                                                     int level,
                                                     DXGI_FORMAT format,
                                                     const TextureHelper11 &texture,
                                                     d3d11::SharedSRV *outSRV)
{
    ASSERT(outSRV);
    D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
    srvDesc.Format                    = format;
    srvDesc.ViewDimension             = D3D11_SRV_DIMENSION_TEXTURE2D;
    srvDesc.Texture2D.MostDetailedMip = mTopLevel + level;
    srvDesc.Texture2D.MipLevels       = 1;
    ANGLE_TRY(
        mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV));
    outSRV->setDebugName("TexStorage2D.SRVForImage");
    return angle::Result::Continue;
}

angle::Result TextureStorage11_2D::createUAVForImage(const gl::Context *context,
                                                     int level,
                                                     DXGI_FORMAT format,
                                                     const TextureHelper11 &texture,
                                                     d3d11::SharedUAV *outUAV)
{
    ASSERT(outUAV);
    D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
    uavDesc.Format             = format;
    uavDesc.ViewDimension      = D3D11_UAV_DIMENSION_TEXTURE2D;
    uavDesc.Texture2D.MipSlice = mTopLevel + level;
    ANGLE_TRY(
        mRenderer->allocateResource(GetImplAs<Context11>(context), uavDesc, texture.get(), outUAV));
    outUAV->setDebugName("TexStorage2D.UAVForImage");
    return angle::Result::Continue;
}

angle::Result TextureStorage11_2D::getSwizzleTexture(const gl::Context *context,
                                                     const TextureHelper11 **outTexture)
{
    ASSERT(outTexture);

    if (!mSwizzleTexture.valid())
    {
        const auto &format = mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps());

        D3D11_TEXTURE2D_DESC desc;
        desc.Width              = mTextureWidth;
        desc.Height             = mTextureHeight;
        desc.MipLevels          = mMipLevels;
        desc.ArraySize          = 1;
        desc.Format             = format.texFormat;
        desc.SampleDesc.Count   = 1;
        desc.SampleDesc.Quality = 0;
        desc.Usage              = D3D11_USAGE_DEFAULT;
        desc.BindFlags          = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
        desc.CPUAccessFlags     = 0;
        desc.MiscFlags          = 0;

        ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, format,
                                             &mSwizzleTexture));
        mSwizzleTexture.setDebugName("TexStorage2D.SwizzleTexture");
    }

    *outTexture = &mSwizzleTexture;
    return angle::Result::Continue;
}

angle::Result TextureStorage11_2D::getSwizzleRenderTarget(const gl::Context *context,
                                                          int mipLevel,
                                                          const d3d11::RenderTargetView **outRTV)
{
    ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
    ASSERT(outRTV);

    if (!mSwizzleRenderTargets[mipLevel].valid())
    {
        const TextureHelper11 *swizzleTexture = nullptr;
        ANGLE_TRY(getSwizzleTexture(context, &swizzleTexture));

        D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
        rtvDesc.Format =
            mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()).rtvFormat;
        rtvDesc.ViewDimension      = D3D11_RTV_DIMENSION_TEXTURE2D;
        rtvDesc.Texture2D.MipSlice = mTopLevel + mipLevel;

        ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), rtvDesc,
                                              mSwizzleTexture.get(),
                                              &mSwizzleRenderTargets[mipLevel]));
    }

    *outRTV = &mSwizzleRenderTargets[mipLevel];
    return angle::Result::Continue;
}

angle::Result TextureStorage11_2D::ensureDropStencilTexture(const gl::Context *context,
                                                            DropStencil *dropStencilOut)
{
    if (mDropStencilTexture.valid())
    {
        *dropStencilOut = DropStencil::ALREADY_EXISTS;
        return angle::Result::Continue;
    }

    D3D11_TEXTURE2D_DESC dropDesc = {};
    dropDesc.ArraySize            = 1;
    dropDesc.BindFlags            = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_DEPTH_STENCIL;
    dropDesc.CPUAccessFlags       = 0;
    dropDesc.Format               = DXGI_FORMAT_R32_TYPELESS;
    dropDesc.Height               = mTextureHeight;
    dropDesc.MipLevels            = mMipLevels;
    dropDesc.MiscFlags            = 0;
    dropDesc.SampleDesc.Count     = 1;
    dropDesc.SampleDesc.Quality   = 0;
    dropDesc.Usage                = D3D11_USAGE_DEFAULT;
    dropDesc.Width                = mTextureWidth;

    const auto &format =
        d3d11::Format::Get(GL_DEPTH_COMPONENT32F, mRenderer->getRenderer11DeviceCaps());
    ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), dropDesc, format,
                                         &mDropStencilTexture));
    mDropStencilTexture.setDebugName("TexStorage2D.DropStencil");

    ANGLE_TRY(initDropStencilTexture(context, gl::ImageIndexIterator::Make2D(0, mMipLevels)));

    *dropStencilOut = DropStencil::CREATED;
    return angle::Result::Continue;
}

TextureStorage11_External::TextureStorage11_External(
    Renderer11 *renderer,
    egl::Stream *stream,
    const egl::Stream::GLTextureDescription &glDesc)
    : TextureStorage11(renderer, D3D11_BIND_SHADER_RESOURCE, 0, glDesc.internalFormat)
{
    ASSERT(stream->getProducerType() == egl::Stream::ProducerType::D3D11Texture);
    auto *producer = static_cast<StreamProducerD3DTexture *>(stream->getImplementation());
    mTexture.set(producer->getD3DTexture(), mFormatInfo);
    mSubresourceIndex = producer->getArraySlice();
    mTexture.get()->AddRef();
    mMipLevels = 1;

    D3D11_TEXTURE2D_DESC desc;
    mTexture.getDesc(&desc);
    mTextureWidth  = desc.Width;
    mTextureHeight = desc.Height;
    mTextureDepth  = 1;
    mHasKeyedMutex = (desc.MiscFlags & D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX) != 0;
}

angle::Result TextureStorage11_External::onDestroy(const gl::Context *context)
{
    if (mHasKeyedMutex)
    {
        // If the keyed mutex is released that will unbind it and cause the state cache to become
        // desynchronized.
        mRenderer->getStateManager()->invalidateBoundViews();
    }

    return angle::Result::Continue;
}

TextureStorage11_External::~TextureStorage11_External() {}

angle::Result TextureStorage11_External::copyToStorage(const gl::Context *context,
                                                       TextureStorage *destStorage)
{
    UNIMPLEMENTED();
    return angle::Result::Continue;
}

void TextureStorage11_External::associateImage(Image11 *image, const gl::ImageIndex &index)
{
    ASSERT(index.getLevelIndex() == 0);
    mAssociatedImage = image;
}

void TextureStorage11_External::verifyAssociatedImageValid(const gl::ImageIndex &index,
                                                           Image11 *expectedImage)
{
    ASSERT(index.getLevelIndex() == 0 && mAssociatedImage == expectedImage);
}

void TextureStorage11_External::disassociateImage(const gl::ImageIndex &index,
                                                  Image11 *expectedImage)
{
    ASSERT(index.getLevelIndex() == 0);
    ASSERT(mAssociatedImage == expectedImage);
    mAssociatedImage = nullptr;
}

angle::Result TextureStorage11_External::releaseAssociatedImage(const gl::Context *context,
                                                                const gl::ImageIndex &index,
                                                                Image11 *incomingImage)
{
    ASSERT(index.getLevelIndex() == 0);

    if (mAssociatedImage != nullptr && mAssociatedImage != incomingImage)
    {
        mAssociatedImage->verifyAssociatedStorageValid(this);

        ANGLE_TRY(mAssociatedImage->recoverFromAssociatedStorage(context));
    }

    return angle::Result::Continue;
}

angle::Result TextureStorage11_External::getResource(const gl::Context *context,
                                                     const TextureHelper11 **outResource)
{
    *outResource = &mTexture;
    return angle::Result::Continue;
}

angle::Result TextureStorage11_External::getMippedResource(const gl::Context *context,
                                                           const TextureHelper11 **outResource)
{
    *outResource = &mTexture;
    return angle::Result::Continue;
}

angle::Result TextureStorage11_External::getRenderTarget(const gl::Context *context,
                                                         const gl::ImageIndex &index,
                                                         GLsizei samples,
                                                         RenderTargetD3D **outRT)
{
    // Render targets are not supported for external textures
    ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
    return angle::Result::Stop;
}

angle::Result TextureStorage11_External::createSRVForSampler(const gl::Context *context,
                                                             int baseLevel,
                                                             int mipLevels,
                                                             DXGI_FORMAT format,
                                                             const TextureHelper11 &texture,
                                                             d3d11::SharedSRV *outSRV)
{
    // Since external textures are treates as non-mipmapped textures, we ignore mipmap levels and
    // use the specified subresource ID the storage was created with.
    ASSERT(mipLevels == 1);
    ASSERT(outSRV);

    D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
    srvDesc.Format        = format;
    srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
    // subresource index is equal to the mip level for 2D textures
    srvDesc.Texture2DArray.MostDetailedMip = 0;
    srvDesc.Texture2DArray.MipLevels       = 1;
    srvDesc.Texture2DArray.FirstArraySlice = mSubresourceIndex;
    srvDesc.Texture2DArray.ArraySize       = 1;

    ANGLE_TRY(
        mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV));
    outSRV->setDebugName("TexStorage2D.SRV");

    return angle::Result::Continue;
}

angle::Result TextureStorage11_External::createSRVForImage(const gl::Context *context,
                                                           int level,
                                                           DXGI_FORMAT format,
                                                           const TextureHelper11 &texture,
                                                           d3d11::SharedSRV *outSRV)
{
    ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
    return angle::Result::Stop;
}

angle::Result TextureStorage11_External::createUAVForImage(const gl::Context *context,
                                                           int level,
                                                           DXGI_FORMAT format,
                                                           const TextureHelper11 &texture,
                                                           d3d11::SharedUAV *outUAV)
{
    ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
    return angle::Result::Stop;
}

angle::Result TextureStorage11_External::getSwizzleTexture(const gl::Context *context,
                                                           const TextureHelper11 **outTexture)
{
    ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
    return angle::Result::Stop;
}

angle::Result TextureStorage11_External::getSwizzleRenderTarget(
    const gl::Context *context,
    int mipLevel,
    const d3d11::RenderTargetView **outRTV)
{
    ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
    return angle::Result::Stop;
}

TextureStorage11ImmutableBase::TextureStorage11ImmutableBase(Renderer11 *renderer,
                                                             UINT bindFlags,
                                                             UINT miscFlags,
                                                             GLenum internalFormat)
    : TextureStorage11(renderer, bindFlags, miscFlags, internalFormat)
{}

void TextureStorage11ImmutableBase::associateImage(Image11 *, const gl::ImageIndex &) {}

void TextureStorage11ImmutableBase::disassociateImage(const gl::ImageIndex &, Image11 *) {}

void TextureStorage11ImmutableBase::verifyAssociatedImageValid(const gl::ImageIndex &, Image11 *) {}

angle::Result TextureStorage11ImmutableBase::releaseAssociatedImage(const gl::Context *context,
                                                                    const gl::ImageIndex &,
                                                                    Image11 *)
{
    return angle::Result::Continue;
}

angle::Result TextureStorage11ImmutableBase::createSRVForImage(const gl::Context *context,
                                                               int level,
                                                               DXGI_FORMAT format,
                                                               const TextureHelper11 &texture,
                                                               d3d11::SharedSRV *outSRV)
{
    ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
    return angle::Result::Stop;
}

angle::Result TextureStorage11ImmutableBase::createUAVForImage(const gl::Context *context,
                                                               int level,
                                                               DXGI_FORMAT format,
                                                               const TextureHelper11 &texture,
                                                               d3d11::SharedUAV *outUAV)
{
    ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
    return angle::Result::Stop;
}

TextureStorage11_EGLImage::TextureStorage11_EGLImage(Renderer11 *renderer,
                                                     EGLImageD3D *eglImage,
                                                     RenderTarget11 *renderTarget11)
    : TextureStorage11ImmutableBase(renderer,
                                    D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE,
                                    0,
                                    renderTarget11->getInternalFormat()),
      mImage(eglImage),
      mCurrentRenderTarget(0),
      mSwizzleTexture(),
      mSwizzleRenderTargets(gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
{
    mCurrentRenderTarget = reinterpret_cast<uintptr_t>(renderTarget11);

    mMipLevels     = 1;
    mTextureWidth  = renderTarget11->getWidth();
    mTextureHeight = renderTarget11->getHeight();
    mTextureDepth  = 1;
}

TextureStorage11_EGLImage::~TextureStorage11_EGLImage() {}

angle::Result TextureStorage11_EGLImage::getSubresourceIndex(const gl::Context *context,
                                                             const gl::ImageIndex &index,
                                                             UINT *outSubresourceIndex) const
{
    ASSERT(index.getType() == gl::TextureType::_2D);
    ASSERT(index.getLevelIndex() == 0);

    RenderTarget11 *renderTarget11 = nullptr;
    ANGLE_TRY(getImageRenderTarget(context, &renderTarget11));
    *outSubresourceIndex = renderTarget11->getSubresourceIndex();
    return angle::Result::Continue;
}

angle::Result TextureStorage11_EGLImage::getResource(const gl::Context *context,
                                                     const TextureHelper11 **outResource)
{
    ANGLE_TRY(checkForUpdatedRenderTarget(context));

    RenderTarget11 *renderTarget11 = nullptr;
    ANGLE_TRY(getImageRenderTarget(context, &renderTarget11));
    *outResource = &renderTarget11->getTexture();
    return angle::Result::Continue;
}

angle::Result TextureStorage11_EGLImage::getSRVForSampler(const gl::Context *context,
                                                          const gl::TextureState &textureState,
                                                          const gl::SamplerState &sampler,
                                                          const d3d11::SharedSRV **outSRV)
{
    ANGLE_TRY(checkForUpdatedRenderTarget(context));
    return TextureStorage11::getSRVForSampler(context, textureState, sampler, outSRV);
}

angle::Result TextureStorage11_EGLImage::getMippedResource(const gl::Context *context,
                                                           const TextureHelper11 **)
{
    // This shouldn't be called unless the zero max LOD workaround is active.
    // EGL images are unavailable in this configuration.
    ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
    return angle::Result::Stop;
}

angle::Result TextureStorage11_EGLImage::getRenderTarget(const gl::Context *context,
                                                         const gl::ImageIndex &index,
                                                         GLsizei samples,
                                                         RenderTargetD3D **outRT)
{
    ASSERT(!index.hasLayer());
    ASSERT(index.getLevelIndex() == 0);

    ANGLE_TRY(checkForUpdatedRenderTarget(context));

    return mImage->getRenderTarget(context, outRT);
}

angle::Result TextureStorage11_EGLImage::copyToStorage(const gl::Context *context,
                                                       TextureStorage *destStorage)
{
    const TextureHelper11 *sourceResouce = nullptr;
    ANGLE_TRY(getResource(context, &sourceResouce));

    ASSERT(destStorage);
    TextureStorage11_2D *dest11         = GetAs<TextureStorage11_2D>(destStorage);
    const TextureHelper11 *destResource = nullptr;
    ANGLE_TRY(dest11->getResource(context, &destResource));

    ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
    immediateContext->CopyResource(destResource->get(), sourceResouce->get());

    dest11->markDirty();

    return angle::Result::Continue;
}

angle::Result TextureStorage11_EGLImage::useLevelZeroWorkaroundTexture(const gl::Context *context,
                                                                       bool)
{
    ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
    return angle::Result::Stop;
}

angle::Result TextureStorage11_EGLImage::getSwizzleTexture(const gl::Context *context,
                                                           const TextureHelper11 **outTexture)
{
    ASSERT(outTexture);

    if (!mSwizzleTexture.valid())
    {
        const auto &format = mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps());

        D3D11_TEXTURE2D_DESC desc;
        desc.Width              = mTextureWidth;
        desc.Height             = mTextureHeight;
        desc.MipLevels          = mMipLevels;
        desc.ArraySize          = 1;
        desc.Format             = format.texFormat;
        desc.SampleDesc.Count   = 1;
        desc.SampleDesc.Quality = 0;
        desc.Usage              = D3D11_USAGE_DEFAULT;
        desc.BindFlags          = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
        desc.CPUAccessFlags     = 0;
        desc.MiscFlags          = 0;

        ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, format,
                                             &mSwizzleTexture));
        mSwizzleTexture.setDebugName("TexStorageEGLImage.SwizzleTexture");
    }

    *outTexture = &mSwizzleTexture;
    return angle::Result::Continue;
}

angle::Result TextureStorage11_EGLImage::getSwizzleRenderTarget(
    const gl::Context *context,
    int mipLevel,
    const d3d11::RenderTargetView **outRTV)
{
    ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
    ASSERT(outRTV);

    if (!mSwizzleRenderTargets[mipLevel].valid())
    {
        const TextureHelper11 *swizzleTexture = nullptr;
        ANGLE_TRY(getSwizzleTexture(context, &swizzleTexture));

        D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
        rtvDesc.Format =
            mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()).rtvFormat;
        rtvDesc.ViewDimension      = D3D11_RTV_DIMENSION_TEXTURE2D;
        rtvDesc.Texture2D.MipSlice = mTopLevel + mipLevel;

        ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), rtvDesc,
                                              mSwizzleTexture.get(),
                                              &mSwizzleRenderTargets[mipLevel]));
    }

    *outRTV = &mSwizzleRenderTargets[mipLevel];
    return angle::Result::Continue;
}

angle::Result TextureStorage11_EGLImage::checkForUpdatedRenderTarget(const gl::Context *context)
{
    RenderTarget11 *renderTarget11 = nullptr;
    ANGLE_TRY(getImageRenderTarget(context, &renderTarget11));

    if (mCurrentRenderTarget != reinterpret_cast<uintptr_t>(renderTarget11))
    {
        clearSRVCache();
        mCurrentRenderTarget = reinterpret_cast<uintptr_t>(renderTarget11);
    }

    return angle::Result::Continue;
}

angle::Result TextureStorage11_EGLImage::createSRVForSampler(const gl::Context *context,
                                                             int baseLevel,
                                                             int mipLevels,
                                                             DXGI_FORMAT format,
                                                             const TextureHelper11 &texture,
                                                             d3d11::SharedSRV *outSRV)
{
    ASSERT(baseLevel == 0);
    ASSERT(mipLevels == 1);
    ASSERT(outSRV);

    // Create a new SRV only for the swizzle texture.  Otherwise just return the Image's
    // RenderTarget's SRV.
    if (texture == mSwizzleTexture)
    {
        D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
        srvDesc.Format                    = format;
        srvDesc.ViewDimension             = D3D11_SRV_DIMENSION_TEXTURE2D;
        srvDesc.Texture2D.MostDetailedMip = mTopLevel + baseLevel;
        srvDesc.Texture2D.MipLevels       = mipLevels;

        ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(),
                                              outSRV));
        outSRV->setDebugName("TexStorageEGLImage.SRV");
    }
    else
    {
        RenderTarget11 *renderTarget = nullptr;
        ANGLE_TRY(getImageRenderTarget(context, &renderTarget));

        ASSERT(texture == renderTarget->getTexture());

        *outSRV = renderTarget->getShaderResourceView(context).makeCopy();
    }

    return angle::Result::Continue;
}

angle::Result TextureStorage11_EGLImage::getImageRenderTarget(const gl::Context *context,
                                                              RenderTarget11 **outRT) const
{
    RenderTargetD3D *renderTargetD3D = nullptr;
    ANGLE_TRY(mImage->getRenderTarget(context, &renderTargetD3D));
    *outRT = GetAs<RenderTarget11>(renderTargetD3D);
    return angle::Result::Continue;
}

TextureStorage11_Cube::TextureStorage11_Cube(Renderer11 *renderer,
                                             GLenum internalformat,
                                             bool renderTarget,
                                             int size,
                                             int levels,
                                             bool hintLevelZeroOnly)
    : TextureStorage11(
          renderer,
          GetTextureBindFlags(internalformat, renderer->getRenderer11DeviceCaps(), renderTarget),
          GetTextureMiscFlags(internalformat,
                              renderer->getRenderer11DeviceCaps(),
                              renderTarget,
                              levels),
          internalformat),
      mTexture(),
      mLevelZeroTexture(),
      mUseLevelZeroTexture(hintLevelZeroOnly && levels > 1),
      mSwizzleTexture()
{
    for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
    {
        for (unsigned int face = 0; face < gl::kCubeFaceCount; face++)
        {
            mAssociatedImages[face][level] = nullptr;
            mRenderTarget[face][level]     = nullptr;
        }
    }

    for (unsigned int face = 0; face < gl::kCubeFaceCount; face++)
    {
        mLevelZeroRenderTarget[face] = nullptr;
    }

    // adjust size if needed for compressed textures
    int height = size;
    d3d11::MakeValidSize(false, mFormatInfo.texFormat, &size, &height, &mTopLevel);

    mMipLevels     = mTopLevel + levels;
    mTextureWidth  = size;
    mTextureHeight = size;
    mTextureDepth  = 1;

    // The LevelZeroOnly hint should only be true if the zero max LOD workaround is active.
    ASSERT(!mUseLevelZeroTexture || mRenderer->getFeatures().zeroMaxLodWorkaround.enabled);
}

angle::Result TextureStorage11_Cube::onDestroy(const gl::Context *context)
{
    for (unsigned int level = 0; level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
    {
        for (unsigned int face = 0; face < gl::kCubeFaceCount; face++)
        {
            if (mAssociatedImages[face][level] != nullptr)
            {
                mAssociatedImages[face][level]->verifyAssociatedStorageValid(this);

                // We must let the Images recover their data before we delete it from the
                // TextureStorage.
                ANGLE_TRY(mAssociatedImages[face][level]->recoverFromAssociatedStorage(context));
            }
        }
    }

    return angle::Result::Continue;
}

TextureStorage11_Cube::~TextureStorage11_Cube() {}

angle::Result TextureStorage11_Cube::getSubresourceIndex(const gl::Context *context,
                                                         const gl::ImageIndex &index,
                                                         UINT *outSubresourceIndex) const
{
    UINT arraySlice = index.cubeMapFaceIndex();
    if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled && mUseLevelZeroTexture &&
        index.getLevelIndex() == 0)
    {
        UINT subresource = D3D11CalcSubresource(0, arraySlice, 1);
        ASSERT(subresource != std::numeric_limits<UINT>::max());
        *outSubresourceIndex = subresource;
    }
    else
    {
        UINT mipSlice    = static_cast<UINT>(index.getLevelIndex() + mTopLevel);
        UINT subresource = D3D11CalcSubresource(mipSlice, arraySlice, mMipLevels);
        ASSERT(subresource != std::numeric_limits<UINT>::max());
        *outSubresourceIndex = subresource;
    }
    return angle::Result::Continue;
}

angle::Result TextureStorage11_Cube::copyToStorage(const gl::Context *context,
                                                   TextureStorage *destStorage)
{
    ASSERT(destStorage);

    TextureStorage11_Cube *dest11 = GetAs<TextureStorage11_Cube>(destStorage);

    if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
    {
        ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();

        // If either mTexture or mLevelZeroTexture exist, then we need to copy them into the
        // corresponding textures in destStorage.
        if (mTexture.valid())
        {
            ANGLE_TRY(dest11->useLevelZeroWorkaroundTexture(context, false));

            const TextureHelper11 *destResource = nullptr;
            ANGLE_TRY(dest11->getResource(context, &destResource));

            immediateContext->CopyResource(destResource->get(), mTexture.get());
        }

        if (mLevelZeroTexture.valid())
        {
            ANGLE_TRY(dest11->useLevelZeroWorkaroundTexture(context, true));

            const TextureHelper11 *destResource = nullptr;
            ANGLE_TRY(dest11->getResource(context, &destResource));

            immediateContext->CopyResource(destResource->get(), mLevelZeroTexture.get());
        }
    }
    else
    {
        const TextureHelper11 *sourceResouce = nullptr;
        ANGLE_TRY(getResource(context, &sourceResouce));

        const TextureHelper11 *destResource = nullptr;
        ANGLE_TRY(dest11->getResource(context, &destResource));

        ID3D11DeviceContext *immediateContext = mRenderer->getDeviceContext();
        immediateContext->CopyResource(destResource->get(), sourceResouce->get());
    }

    dest11->markDirty();

    return angle::Result::Continue;
}

angle::Result TextureStorage11_Cube::useLevelZeroWorkaroundTexture(const gl::Context *context,
                                                                   bool useLevelZeroTexture)
{
    if (useLevelZeroTexture && mMipLevels > 1)
    {
        if (!mUseLevelZeroTexture && mTexture.valid())
        {
            ANGLE_TRY(ensureTextureExists(context, 1));

            // Pull data back from the mipped texture if necessary.
            ASSERT(mLevelZeroTexture.valid());
            ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();

            for (int face = 0; face < 6; face++)
            {
                deviceContext->CopySubresourceRegion(mLevelZeroTexture.get(),
                                                     D3D11CalcSubresource(0, face, 1), 0, 0, 0,
                                                     mTexture.get(), face * mMipLevels, nullptr);
            }
        }

        mUseLevelZeroTexture = true;
    }
    else
    {
        if (mUseLevelZeroTexture && mLevelZeroTexture.valid())
        {
            ANGLE_TRY(ensureTextureExists(context, mMipLevels));

            // Pull data back from the level zero texture if necessary.
            ASSERT(mTexture.valid());
            ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext();

            for (int face = 0; face < 6; face++)
            {
                deviceContext->CopySubresourceRegion(mTexture.get(),
                                                     D3D11CalcSubresource(0, face, mMipLevels), 0,
                                                     0, 0, mLevelZeroTexture.get(), face, nullptr);
            }
        }

        mUseLevelZeroTexture = false;
    }

    return angle::Result::Continue;
}

void TextureStorage11_Cube::associateImage(Image11 *image, const gl::ImageIndex &index)
{
    const GLint level       = index.getLevelIndex();
    const GLint layerTarget = index.cubeMapFaceIndex();

    ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
    ASSERT(0 <= layerTarget && layerTarget < static_cast<GLint>(gl::kCubeFaceCount));

    if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
    {
        if (0 <= layerTarget && layerTarget < static_cast<GLint>(gl::kCubeFaceCount))
        {
            mAssociatedImages[layerTarget][level] = image;
        }
    }
}

void TextureStorage11_Cube::verifyAssociatedImageValid(const gl::ImageIndex &index,
                                                       Image11 *expectedImage)
{
    const GLint level       = index.getLevelIndex();
    const GLint layerTarget = index.cubeMapFaceIndex();

    ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
    ASSERT(0 <= layerTarget && layerTarget < static_cast<GLint>(gl::kCubeFaceCount));
    // This validation check should never return false. It means the Image/TextureStorage
    // association is broken.
    ASSERT(mAssociatedImages[layerTarget][level] == expectedImage);
}

// disassociateImage allows an Image to end its association with a Storage.
void TextureStorage11_Cube::disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage)
{
    const GLint level       = index.getLevelIndex();
    const GLint layerTarget = index.cubeMapFaceIndex();

    ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
    ASSERT(0 <= layerTarget && layerTarget < static_cast<GLint>(gl::kCubeFaceCount));
    ASSERT(mAssociatedImages[layerTarget][level] == expectedImage);
    mAssociatedImages[layerTarget][level] = nullptr;
}

// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image
// recover its data before ending the association.
angle::Result TextureStorage11_Cube::releaseAssociatedImage(const gl::Context *context,
                                                            const gl::ImageIndex &index,
                                                            Image11 *incomingImage)
{
    const GLint level       = index.getLevelIndex();
    const GLint layerTarget = index.cubeMapFaceIndex();

    ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
    ASSERT(0 <= layerTarget && layerTarget < static_cast<GLint>(gl::kCubeFaceCount));

    if ((0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
    {
        if (0 <= layerTarget && layerTarget < static_cast<GLint>(gl::kCubeFaceCount))
        {
            // No need to let the old Image recover its data, if it is also the incoming Image.
            if (mAssociatedImages[layerTarget][level] != nullptr &&
                mAssociatedImages[layerTarget][level] != incomingImage)
            {
                // Ensure that the Image is still associated with this TextureStorage.
                mAssociatedImages[layerTarget][level]->verifyAssociatedStorageValid(this);

                // Force the image to recover from storage before its data is overwritten.
                // This will reset mAssociatedImages[level] to nullptr too.
                ANGLE_TRY(
                    mAssociatedImages[layerTarget][level]->recoverFromAssociatedStorage(context));
            }
        }
    }

    return angle::Result::Continue;
}

angle::Result TextureStorage11_Cube::getResource(const gl::Context *context,
                                                 const TextureHelper11 **outResource)
{
    if (mUseLevelZeroTexture && mMipLevels > 1)
    {
        ANGLE_TRY(ensureTextureExists(context, 1));
        *outResource = &mLevelZeroTexture;
    }
    else
    {
        ANGLE_TRY(ensureTextureExists(context, mMipLevels));
        *outResource = &mTexture;
    }
    return angle::Result::Continue;
}

angle::Result TextureStorage11_Cube::getMippedResource(const gl::Context *context,
                                                       const TextureHelper11 **outResource)
{
    // This shouldn't be called unless the zero max LOD workaround is active.
    ASSERT(mRenderer->getFeatures().zeroMaxLodWorkaround.enabled);

    ANGLE_TRY(ensureTextureExists(context, mMipLevels));
    *outResource = &mTexture;
    return angle::Result::Continue;
}

angle::Result TextureStorage11_Cube::ensureTextureExists(const gl::Context *context, int mipLevels)
{
    // If mMipLevels = 1 then always use mTexture rather than mLevelZeroTexture.
    bool useLevelZeroTexture = mRenderer->getFeatures().zeroMaxLodWorkaround.enabled
                                   ? (mipLevels == 1) && (mMipLevels > 1)
                                   : false;
    TextureHelper11 *outputTexture = useLevelZeroTexture ? &mLevelZeroTexture : &mTexture;

    // if the size is not positive this should be treated as an incomplete texture
    // we handle that here by skipping the d3d texture creation
    if (!outputTexture->valid() && mTextureWidth > 0 && mTextureHeight > 0)
    {
        ASSERT(mMipLevels > 0);

        D3D11_TEXTURE2D_DESC desc;
        desc.Width              = mTextureWidth;
        desc.Height             = mTextureHeight;
        desc.MipLevels          = mipLevels;
        desc.ArraySize          = gl::kCubeFaceCount;
        desc.Format             = mFormatInfo.texFormat;
        desc.SampleDesc.Count   = 1;
        desc.SampleDesc.Quality = 0;
        desc.Usage              = D3D11_USAGE_DEFAULT;
        desc.BindFlags          = getBindFlags();
        desc.CPUAccessFlags     = 0;
        desc.MiscFlags          = D3D11_RESOURCE_MISC_TEXTURECUBE | getMiscFlags();

        ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, mFormatInfo,
                                             outputTexture));
        outputTexture->setDebugName("TexStorageCube.Texture");
    }

    return angle::Result::Continue;
}

angle::Result TextureStorage11_Cube::createRenderTargetSRV(const gl::Context *context,
                                                           const TextureHelper11 &texture,
                                                           const gl::ImageIndex &index,
                                                           DXGI_FORMAT resourceFormat,
                                                           d3d11::SharedSRV *srv) const
{
    D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
    srvDesc.Format                         = resourceFormat;
    srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + index.getLevelIndex();
    srvDesc.Texture2DArray.MipLevels       = 1;
    srvDesc.Texture2DArray.FirstArraySlice = index.cubeMapFaceIndex();
    srvDesc.Texture2DArray.ArraySize       = 1;

    if (mRenderer->getRenderer11DeviceCaps().featureLevel <= D3D_FEATURE_LEVEL_10_0)
    {
        srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE;
    }
    else
    {
        // Will be used with Texture2D sampler, not TextureCube
        srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
    }

    ANGLE_TRY(
        mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), srv));
    return angle::Result::Continue;
}

angle::Result TextureStorage11_Cube::getRenderTarget(const gl::Context *context,
                                                     const gl::ImageIndex &index,
                                                     GLsizei samples,
                                                     RenderTargetD3D **outRT)
{
    const int faceIndex = index.cubeMapFaceIndex();
    const int level     = index.getLevelIndex();

    ASSERT(level >= 0 && level < getLevelCount());
    ASSERT(faceIndex >= 0 && faceIndex < static_cast<GLint>(gl::kCubeFaceCount));

    Context11 *context11 = GetImplAs<Context11>(context);

    if (!mRenderTarget[faceIndex][level])
    {
        if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
        {
            ASSERT(index.getLevelIndex() == 0);
            ANGLE_TRY(useLevelZeroWorkaroundTexture(context, true));
        }

        const TextureHelper11 *texture = nullptr;
        ANGLE_TRY(getResource(context, &texture));

        if (mUseLevelZeroTexture)
        {
            if (!mLevelZeroRenderTarget[faceIndex])
            {
                D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
                rtvDesc.Format                         = mFormatInfo.rtvFormat;
                rtvDesc.ViewDimension                  = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
                rtvDesc.Texture2DArray.MipSlice        = mTopLevel + level;
                rtvDesc.Texture2DArray.FirstArraySlice = faceIndex;
                rtvDesc.Texture2DArray.ArraySize       = 1;

                d3d11::RenderTargetView rtv;
                ANGLE_TRY(
                    mRenderer->allocateResource(context11, rtvDesc, mLevelZeroTexture.get(), &rtv));

                mLevelZeroRenderTarget[faceIndex].reset(new TextureRenderTarget11(
                    std::move(rtv), mLevelZeroTexture, d3d11::SharedSRV(), d3d11::SharedSRV(),
                    mFormatInfo.internalFormat, getFormatSet(), getLevelWidth(level),
                    getLevelHeight(level), 1, 0));
            }

            ASSERT(outRT);
            *outRT = mLevelZeroRenderTarget[faceIndex].get();
            return angle::Result::Continue;
        }

        d3d11::SharedSRV srv;
        ANGLE_TRY(createRenderTargetSRV(context, *texture, index, mFormatInfo.srvFormat, &srv));
        d3d11::SharedSRV blitSRV;
        if (mFormatInfo.blitSRVFormat != mFormatInfo.srvFormat)
        {
            ANGLE_TRY(createRenderTargetSRV(context, *texture, index, mFormatInfo.blitSRVFormat,
                                            &blitSRV));
        }
        else
        {
            blitSRV = srv.makeCopy();
        }

        srv.setDebugName("TexStorageCube.RenderTargetSRV");

        if (mFormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN)
        {
            D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
            rtvDesc.Format                         = mFormatInfo.rtvFormat;
            rtvDesc.ViewDimension                  = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
            rtvDesc.Texture2DArray.MipSlice        = mTopLevel + level;
            rtvDesc.Texture2DArray.FirstArraySlice = faceIndex;
            rtvDesc.Texture2DArray.ArraySize       = 1;

            d3d11::RenderTargetView rtv;
            ANGLE_TRY(mRenderer->allocateResource(context11, rtvDesc, texture->get(), &rtv));
            rtv.setDebugName("TexStorageCube.RenderTargetRTV");

            mRenderTarget[faceIndex][level].reset(new TextureRenderTarget11(
                std::move(rtv), *texture, srv, blitSRV, mFormatInfo.internalFormat, getFormatSet(),
                getLevelWidth(level), getLevelHeight(level), 1, 0));
        }
        else if (mFormatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN)
        {
            D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
            dsvDesc.Format                         = mFormatInfo.dsvFormat;
            dsvDesc.ViewDimension                  = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
            dsvDesc.Flags                          = 0;
            dsvDesc.Texture2DArray.MipSlice        = mTopLevel + level;
            dsvDesc.Texture2DArray.FirstArraySlice = faceIndex;
            dsvDesc.Texture2DArray.ArraySize       = 1;

            d3d11::DepthStencilView dsv;
            ANGLE_TRY(mRenderer->allocateResource(context11, dsvDesc, texture->get(), &dsv));
            dsv.setDebugName("TexStorageCube.RenderTargetDSV");

            mRenderTarget[faceIndex][level].reset(new TextureRenderTarget11(
                std::move(dsv), *texture, srv, mFormatInfo.internalFormat, getFormatSet(),
                getLevelWidth(level), getLevelHeight(level), 1, 0));
        }
        else
        {
            UNREACHABLE();
        }
    }

    ASSERT(outRT);
    *outRT = mRenderTarget[faceIndex][level].get();
    return angle::Result::Continue;
}

angle::Result TextureStorage11_Cube::createSRVForSampler(const gl::Context *context,
                                                         int baseLevel,
                                                         int mipLevels,
                                                         DXGI_FORMAT format,
                                                         const TextureHelper11 &texture,
                                                         d3d11::SharedSRV *outSRV)
{
    ASSERT(outSRV);

    D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
    srvDesc.Format = format;

    // Unnormalized integer cube maps are not supported by DX11; we emulate them as an array of six
    // 2D textures
    const GLenum componentType = d3d11::GetComponentType(format);
    if (componentType == GL_INT || componentType == GL_UNSIGNED_INT)
    {
        srvDesc.ViewDimension                  = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
        srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + baseLevel;
        srvDesc.Texture2DArray.MipLevels       = mipLevels;
        srvDesc.Texture2DArray.FirstArraySlice = 0;
        srvDesc.Texture2DArray.ArraySize       = gl::kCubeFaceCount;
    }
    else
    {
        srvDesc.ViewDimension               = D3D11_SRV_DIMENSION_TEXTURECUBE;
        srvDesc.TextureCube.MipLevels       = mipLevels;
        srvDesc.TextureCube.MostDetailedMip = mTopLevel + baseLevel;
    }

    const TextureHelper11 *srvTexture = &texture;

    if (mRenderer->getFeatures().zeroMaxLodWorkaround.enabled)
    {
        ASSERT(mTopLevel == 0);
        ASSERT(baseLevel == 0);
        // This code also assumes that the incoming texture equals either mLevelZeroTexture or
        // mTexture.

        if (mipLevels == 1 && mMipLevels > 1)
        {
            // We must use a SRV on the level-zero-only texture.
            ANGLE_TRY(ensureTextureExists(context, 1));
            srvTexture = &mLevelZeroTexture;
        }
        else
        {
            ASSERT(mipLevels == static_cast<int>(mMipLevels));
            ASSERT(mTexture.valid() && texture == mTexture);
            srvTexture = &mTexture;
        }
    }

    ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, srvTexture->get(),
                                          outSRV));
    outSRV->setDebugName("TexStorageCube.SRV");

    return angle::Result::Continue;
}

angle::Result TextureStorage11_Cube::createSRVForImage(const gl::Context *context,
                                                       int level,
                                                       DXGI_FORMAT format,
                                                       const TextureHelper11 &texture,
                                                       d3d11::SharedSRV *outSRV)
{
    ASSERT(outSRV);
    D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
    srvDesc.Format                         = format;
    srvDesc.ViewDimension                  = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
    srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + level;
    srvDesc.Texture2DArray.MipLevels       = 1;
    srvDesc.Texture2DArray.FirstArraySlice = 0;
    srvDesc.Texture2DArray.ArraySize       = gl::kCubeFaceCount;
    ANGLE_TRY(
        mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV));
    outSRV->setDebugName("TexStorageCube.SRVForImage");
    return angle::Result::Continue;
}

angle::Result TextureStorage11_Cube::createUAVForImage(const gl::Context *context,
                                                       int level,
                                                       DXGI_FORMAT format,
                                                       const TextureHelper11 &texture,
                                                       d3d11::SharedUAV *outUAV)
{
    ASSERT(outUAV);
    D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
    uavDesc.Format                         = format;
    uavDesc.ViewDimension                  = D3D11_UAV_DIMENSION_TEXTURE2DARRAY;
    uavDesc.Texture2DArray.MipSlice        = mTopLevel + level;
    uavDesc.Texture2DArray.FirstArraySlice = 0;
    uavDesc.Texture2DArray.ArraySize       = gl::kCubeFaceCount;
    ANGLE_TRY(
        mRenderer->allocateResource(GetImplAs<Context11>(context), uavDesc, texture.get(), outUAV));
    outUAV->setDebugName("TexStorageCube.UAVForImage");
    return angle::Result::Continue;
}

angle::Result TextureStorage11_Cube::getSwizzleTexture(const gl::Context *context,
                                                       const TextureHelper11 **outTexture)
{
    ASSERT(outTexture);

    if (!mSwizzleTexture.valid())
    {
        const auto &format = mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps());

        D3D11_TEXTURE2D_DESC desc;
        desc.Width              = mTextureWidth;
        desc.Height             = mTextureHeight;
        desc.MipLevels          = mMipLevels;
        desc.ArraySize          = gl::kCubeFaceCount;
        desc.Format             = format.texFormat;
        desc.SampleDesc.Count   = 1;
        desc.SampleDesc.Quality = 0;
        desc.Usage              = D3D11_USAGE_DEFAULT;
        desc.BindFlags          = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
        desc.CPUAccessFlags     = 0;
        desc.MiscFlags          = D3D11_RESOURCE_MISC_TEXTURECUBE;

        ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, format,
                                             &mSwizzleTexture));
        mSwizzleTexture.setDebugName("TexStorageCube.SwizzleTexture");
    }

    *outTexture = &mSwizzleTexture;
    return angle::Result::Continue;
}

angle::Result TextureStorage11_Cube::getSwizzleRenderTarget(const gl::Context *context,
                                                            int mipLevel,
                                                            const d3d11::RenderTargetView **outRTV)
{
    ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
    ASSERT(outRTV);

    if (!mSwizzleRenderTargets[mipLevel].valid())
    {
        const TextureHelper11 *swizzleTexture = nullptr;
        ANGLE_TRY(getSwizzleTexture(context, &swizzleTexture));

        D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
        rtvDesc.Format =
            mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()).rtvFormat;
        rtvDesc.ViewDimension                  = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
        rtvDesc.Texture2DArray.MipSlice        = mTopLevel + mipLevel;
        rtvDesc.Texture2DArray.FirstArraySlice = 0;
        rtvDesc.Texture2DArray.ArraySize       = gl::kCubeFaceCount;

        ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), rtvDesc,
                                              mSwizzleTexture.get(),
                                              &mSwizzleRenderTargets[mipLevel]));
    }

    *outRTV = &mSwizzleRenderTargets[mipLevel];
    return angle::Result::Continue;
}

angle::Result TextureStorage11_Cube::ensureDropStencilTexture(const gl::Context *context,
                                                              DropStencil *dropStencilOut)
{
    if (mDropStencilTexture.valid())
    {
        *dropStencilOut = DropStencil::ALREADY_EXISTS;
        return angle::Result::Continue;
    }

    D3D11_TEXTURE2D_DESC dropDesc = {};
    dropDesc.ArraySize            = 6;
    dropDesc.BindFlags            = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_DEPTH_STENCIL;
    dropDesc.CPUAccessFlags       = 0;
    dropDesc.Format               = DXGI_FORMAT_R32_TYPELESS;
    dropDesc.Height               = mTextureHeight;
    dropDesc.MipLevels            = mMipLevels;
    dropDesc.MiscFlags            = D3D11_RESOURCE_MISC_TEXTURECUBE;
    dropDesc.SampleDesc.Count     = 1;
    dropDesc.SampleDesc.Quality   = 0;
    dropDesc.Usage                = D3D11_USAGE_DEFAULT;
    dropDesc.Width                = mTextureWidth;

    const auto &format =
        d3d11::Format::Get(GL_DEPTH_COMPONENT32F, mRenderer->getRenderer11DeviceCaps());
    ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), dropDesc, format,
                                         &mDropStencilTexture));
    mDropStencilTexture.setDebugName("TexStorageCube.DropStencil");

    ANGLE_TRY(initDropStencilTexture(context, gl::ImageIndexIterator::MakeCube(0, mMipLevels)));

    *dropStencilOut = DropStencil::CREATED;
    return angle::Result::Continue;
}

TextureStorage11_3D::TextureStorage11_3D(Renderer11 *renderer,
                                         GLenum internalformat,
                                         bool renderTarget,
                                         GLsizei width,
                                         GLsizei height,
                                         GLsizei depth,
                                         int levels)
    : TextureStorage11(
          renderer,
          GetTextureBindFlags(internalformat, renderer->getRenderer11DeviceCaps(), renderTarget),
          GetTextureMiscFlags(internalformat,
                              renderer->getRenderer11DeviceCaps(),
                              renderTarget,
                              levels),
          internalformat)
{
    for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
    {
        mAssociatedImages[i]   = nullptr;
        mLevelRenderTargets[i] = nullptr;
    }

    // adjust size if needed for compressed textures
    d3d11::MakeValidSize(false, mFormatInfo.texFormat, &width, &height, &mTopLevel);

    mMipLevels     = mTopLevel + levels;
    mTextureWidth  = width;
    mTextureHeight = height;
    mTextureDepth  = depth;
}

angle::Result TextureStorage11_3D::onDestroy(const gl::Context *context)
{
    for (unsigned i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++)
    {
        if (mAssociatedImages[i] != nullptr)
        {
            mAssociatedImages[i]->verifyAssociatedStorageValid(this);

            // We must let the Images recover their data before we delete it from the
            // TextureStorage.
            ANGLE_TRY(mAssociatedImages[i]->recoverFromAssociatedStorage(context));
        }
    }

    return angle::Result::Continue;
}

TextureStorage11_3D::~TextureStorage11_3D() {}

void TextureStorage11_3D::associateImage(Image11 *image, const gl::ImageIndex &index)
{
    const GLint level = index.getLevelIndex();

    ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);

    if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
    {
        mAssociatedImages[level] = image;
    }
}

void TextureStorage11_3D::verifyAssociatedImageValid(const gl::ImageIndex &index,
                                                     Image11 *expectedImage)
{
    const GLint level = index.getLevelIndex();

    ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
    // This validation check should never return false. It means the Image/TextureStorage
    // association is broken.
    ASSERT(mAssociatedImages[level] == expectedImage);
}

// disassociateImage allows an Image to end its association with a Storage.
void TextureStorage11_3D::disassociateImage(const gl::ImageIndex &index, Image11 *expectedImage)
{
    const GLint level = index.getLevelIndex();

    ASSERT(0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS);
    ASSERT(mAssociatedImages[level] == expectedImage);
    mAssociatedImages[level] = nullptr;
}

// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image
// recover its data before ending the association.
angle::Result TextureStorage11_3D::releaseAssociatedImage(const gl::Context *context,
                                                          const gl::ImageIndex &index,
                                                          Image11 *incomingImage)
{
    const GLint level = index.getLevelIndex();

    ASSERT((0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS));

    if (0 <= level && level < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
    {
        // No need to let the old Image recover its data, if it is also the incoming Image.
        if (mAssociatedImages[level] != nullptr && mAssociatedImages[level] != incomingImage)
        {
            // Ensure that the Image is still associated with this TextureStorage.
            mAssociatedImages[level]->verifyAssociatedStorageValid(this);

            // Force the image to recover from storage before its data is overwritten.
            // This will reset mAssociatedImages[level] to nullptr too.
            ANGLE_TRY(mAssociatedImages[level]->recoverFromAssociatedStorage(context));
        }
    }

    return angle::Result::Continue;
}

angle::Result TextureStorage11_3D::getResource(const gl::Context *context,
                                               const TextureHelper11 **outResource)
{
    // If the width, height or depth are not positive this should be treated as an incomplete
    // texture. We handle that here by skipping the d3d texture creation.
    if (!mTexture.valid() && mTextureWidth > 0 && mTextureHeight > 0 && mTextureDepth > 0)
    {
        ASSERT(mMipLevels > 0);

        D3D11_TEXTURE3D_DESC desc;
        desc.Width          = mTextureWidth;
        desc.Height         = mTextureHeight;
        desc.Depth          = mTextureDepth;
        desc.MipLevels      = mMipLevels;
        desc.Format         = mFormatInfo.texFormat;
        desc.Usage          = D3D11_USAGE_DEFAULT;
        desc.BindFlags      = getBindFlags();
        desc.CPUAccessFlags = 0;
        desc.MiscFlags      = getMiscFlags();

        ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, mFormatInfo,
                                             &mTexture));
        mTexture.setDebugName("TexStorage3D.Texture");
    }

    *outResource = &mTexture;
    return angle::Result::Continue;
}

angle::Result TextureStorage11_3D::createSRVForSampler(const gl::Context *context,
                                                       int baseLevel,
                                                       int mipLevels,
                                                       DXGI_FORMAT format,
                                                       const TextureHelper11 &texture,
                                                       d3d11::SharedSRV *outSRV)
{
    ASSERT(outSRV);

    D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
    srvDesc.Format                    = format;
    srvDesc.ViewDimension             = D3D11_SRV_DIMENSION_TEXTURE3D;
    srvDesc.Texture3D.MostDetailedMip = baseLevel;
    srvDesc.Texture3D.MipLevels       = mipLevels;

    ANGLE_TRY(
        mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV));
    outSRV->setDebugName("TexStorage3D.SRV");

    return angle::Result::Continue;
}

angle::Result TextureStorage11_3D::createSRVForImage(const gl::Context *context,
                                                     int level,
                                                     DXGI_FORMAT format,
                                                     const TextureHelper11 &texture,
                                                     d3d11::SharedSRV *outSRV)
{
    ASSERT(outSRV);
    D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
    srvDesc.Format                    = format;
    srvDesc.ViewDimension             = D3D11_SRV_DIMENSION_TEXTURE3D;
    srvDesc.Texture3D.MostDetailedMip = mTopLevel + level;
    srvDesc.Texture3D.MipLevels       = 1;
    ANGLE_TRY(
        mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV));
    outSRV->setDebugName("TexStorage3D.SRVForImage");
    return angle::Result::Continue;
}

angle::Result TextureStorage11_3D::createUAVForImage(const gl::Context *context,
                                                     int level,
                                                     DXGI_FORMAT format,
                                                     const TextureHelper11 &texture,
                                                     d3d11::SharedUAV *outUAV)
{
    ASSERT(outUAV);
    D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
    uavDesc.Format                = format;
    uavDesc.ViewDimension         = D3D11_UAV_DIMENSION_TEXTURE3D;
    uavDesc.Texture3D.MipSlice    = mTopLevel + level;
    uavDesc.Texture3D.FirstWSlice = 0;
    uavDesc.Texture3D.WSize       = mTextureDepth;
    ANGLE_TRY(
        mRenderer->allocateResource(GetImplAs<Context11>(context), uavDesc, texture.get(), outUAV));
    outUAV->setDebugName("TexStorage3D.UAVForImage");
    return angle::Result::Continue;
}

angle::Result TextureStorage11_3D::getRenderTarget(const gl::Context *context,
                                                   const gl::ImageIndex &index,
                                                   GLsizei samples,
                                                   RenderTargetD3D **outRT)
{
    const int mipLevel = index.getLevelIndex();
    ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());

    ASSERT(mFormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN);

    Context11 *context11 = GetImplAs<Context11>(context);

    if (!index.hasLayer())
    {
        if (!mLevelRenderTargets[mipLevel])
        {
            const TextureHelper11 *texture = nullptr;
            ANGLE_TRY(getResource(context, &texture));

            const d3d11::SharedSRV *srv = nullptr;
            ANGLE_TRY(getSRVLevel(context, mipLevel, false, &srv));

            const d3d11::SharedSRV *blitSRV = nullptr;
            ANGLE_TRY(getSRVLevel(context, mipLevel, true, &blitSRV));

            D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
            rtvDesc.Format                = mFormatInfo.rtvFormat;
            rtvDesc.ViewDimension         = D3D11_RTV_DIMENSION_TEXTURE3D;
            rtvDesc.Texture3D.MipSlice    = mTopLevel + mipLevel;
            rtvDesc.Texture3D.FirstWSlice = 0;
            rtvDesc.Texture3D.WSize       = static_cast<UINT>(-1);

            d3d11::RenderTargetView rtv;
            ANGLE_TRY(mRenderer->allocateResource(context11, rtvDesc, texture->get(), &rtv));
            rtv.setDebugName("TexStorage3D.RTV");

            mLevelRenderTargets[mipLevel].reset(new TextureRenderTarget11(
                std::move(rtv), *texture, *srv, *blitSRV, mFormatInfo.internalFormat,
                getFormatSet(), getLevelWidth(mipLevel), getLevelHeight(mipLevel),
                getLevelDepth(mipLevel), 0));
        }

        ASSERT(outRT);
        *outRT = mLevelRenderTargets[mipLevel].get();
        return angle::Result::Continue;
    }

    const int layer = index.getLayerIndex();

    LevelLayerKey key(mipLevel, layer);
    if (mLevelLayerRenderTargets.find(key) == mLevelLayerRenderTargets.end())
    {
        const TextureHelper11 *texture = nullptr;
        ANGLE_TRY(getResource(context, &texture));

        // TODO, what kind of SRV is expected here?
        const d3d11::SharedSRV srv;
        const d3d11::SharedSRV blitSRV;

        D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
        rtvDesc.Format                = mFormatInfo.rtvFormat;
        rtvDesc.ViewDimension         = D3D11_RTV_DIMENSION_TEXTURE3D;
        rtvDesc.Texture3D.MipSlice    = mTopLevel + mipLevel;
        rtvDesc.Texture3D.FirstWSlice = layer;
        rtvDesc.Texture3D.WSize       = 1;

        d3d11::RenderTargetView rtv;
        ANGLE_TRY(mRenderer->allocateResource(context11, rtvDesc, texture->get(), &rtv));
        rtv.setDebugName("TexStorage3D.LayerRTV");

        mLevelLayerRenderTargets[key].reset(new TextureRenderTarget11(
            std::move(rtv), *texture, srv, blitSRV, mFormatInfo.internalFormat, getFormatSet(),
            getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, 0));
    }

    ASSERT(outRT);
    *outRT = mLevelLayerRenderTargets[key].get();
    return angle::Result::Continue;
}

angle::Result TextureStorage11_3D::getSwizzleTexture(const gl::Context *context,
                                                     const TextureHelper11 **outTexture)
{
    ASSERT(outTexture);

    if (!mSwizzleTexture.valid())
    {
        const auto &format = mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps());

        D3D11_TEXTURE3D_DESC desc;
        desc.Width          = mTextureWidth;
        desc.Height         = mTextureHeight;
        desc.Depth          = mTextureDepth;
        desc.MipLevels      = mMipLevels;
        desc.Format         = format.texFormat;
        desc.Usage          = D3D11_USAGE_DEFAULT;
        desc.BindFlags      = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
        desc.CPUAccessFlags = 0;
        desc.MiscFlags      = 0;

        ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, format,
                                             &mSwizzleTexture));
        mSwizzleTexture.setDebugName("TexStorage3D.SwizzleTexture");
    }

    *outTexture = &mSwizzleTexture;
    return angle::Result::Continue;
}

angle::Result TextureStorage11_3D::getSwizzleRenderTarget(const gl::Context *context,
                                                          int mipLevel,
                                                          const d3d11::RenderTargetView **outRTV)
{
    ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
    ASSERT(outRTV);

    if (!mSwizzleRenderTargets[mipLevel].valid())
    {
        const TextureHelper11 *swizzleTexture = nullptr;
        ANGLE_TRY(getSwizzleTexture(context, &swizzleTexture));

        D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
        rtvDesc.Format =
            mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()).rtvFormat;
        rtvDesc.ViewDimension         = D3D11_RTV_DIMENSION_TEXTURE3D;
        rtvDesc.Texture3D.MipSlice    = mTopLevel + mipLevel;
        rtvDesc.Texture3D.FirstWSlice = 0;
        rtvDesc.Texture3D.WSize       = static_cast<UINT>(-1);

        ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), rtvDesc,
                                              mSwizzleTexture.get(),
                                              &mSwizzleRenderTargets[mipLevel]));
        mSwizzleRenderTargets[mipLevel].setDebugName("TexStorage3D.SwizzleRTV");
    }

    *outRTV = &mSwizzleRenderTargets[mipLevel];
    return angle::Result::Continue;
}

TextureStorage11_2DArray::TextureStorage11_2DArray(Renderer11 *renderer,
                                                   GLenum internalformat,
                                                   bool renderTarget,
                                                   GLsizei width,
                                                   GLsizei height,
                                                   GLsizei depth,
                                                   int levels)
    : TextureStorage11(
          renderer,
          GetTextureBindFlags(internalformat, renderer->getRenderer11DeviceCaps(), renderTarget),
          GetTextureMiscFlags(internalformat,
                              renderer->getRenderer11DeviceCaps(),
                              renderTarget,
                              levels),
          internalformat)
{
    // adjust size if needed for compressed textures
    d3d11::MakeValidSize(false, mFormatInfo.texFormat, &width, &height, &mTopLevel);

    mMipLevels     = mTopLevel + levels;
    mTextureWidth  = width;
    mTextureHeight = height;
    mTextureDepth  = depth;
}

angle::Result TextureStorage11_2DArray::onDestroy(const gl::Context *context)
{
    for (auto iter : mAssociatedImages)
    {
        if (iter.second)
        {
            iter.second->verifyAssociatedStorageValid(this);

            // We must let the Images recover their data before we delete it from the
            // TextureStorage.
            ANGLE_TRY(iter.second->recoverFromAssociatedStorage(context));
        }
    }
    mAssociatedImages.clear();

    return angle::Result::Continue;
}

TextureStorage11_2DArray::~TextureStorage11_2DArray() {}

void TextureStorage11_2DArray::associateImage(Image11 *image, const gl::ImageIndex &index)
{
    const GLint level       = index.getLevelIndex();
    const GLint layerTarget = index.getLayerIndex();
    const GLint numLayers   = index.getLayerCount();

    ASSERT(0 <= level && level < getLevelCount());

    if (0 <= level && level < getLevelCount())
    {
        LevelLayerRangeKey key(level, layerTarget, numLayers);
        mAssociatedImages[key] = image;
    }
}

void TextureStorage11_2DArray::verifyAssociatedImageValid(const gl::ImageIndex &index,
                                                          Image11 *expectedImage)
{
    const GLint level       = index.getLevelIndex();
    const GLint layerTarget = index.getLayerIndex();
    const GLint numLayers   = index.getLayerCount();

    LevelLayerRangeKey key(level, layerTarget, numLayers);

    // This validation check should never return false. It means the Image/TextureStorage
    // association is broken.
    bool retValue = (mAssociatedImages.find(key) != mAssociatedImages.end() &&
                     (mAssociatedImages[key] == expectedImage));
    ASSERT(retValue);
}

// disassociateImage allows an Image to end its association with a Storage.
void TextureStorage11_2DArray::disassociateImage(const gl::ImageIndex &index,
                                                 Image11 *expectedImage)
{
    const GLint level       = index.getLevelIndex();
    const GLint layerTarget = index.getLayerIndex();
    const GLint numLayers   = index.getLayerCount();

    LevelLayerRangeKey key(level, layerTarget, numLayers);

    bool imageAssociationCorrect = (mAssociatedImages.find(key) != mAssociatedImages.end() &&
                                    (mAssociatedImages[key] == expectedImage));
    ASSERT(imageAssociationCorrect);
    mAssociatedImages[key] = nullptr;
}

// releaseAssociatedImage prepares the Storage for a new Image association. It lets the old Image
// recover its data before ending the association.
angle::Result TextureStorage11_2DArray::releaseAssociatedImage(const gl::Context *context,
                                                               const gl::ImageIndex &index,
                                                               Image11 *incomingImage)
{
    const GLint level       = index.getLevelIndex();
    const GLint layerTarget = index.getLayerIndex();
    const GLint numLayers   = index.getLayerCount();

    LevelLayerRangeKey key(level, layerTarget, numLayers);

    if (mAssociatedImages.find(key) != mAssociatedImages.end())
    {
        if (mAssociatedImages[key] != nullptr && mAssociatedImages[key] != incomingImage)
        {
            // Ensure that the Image is still associated with this TextureStorage.
            mAssociatedImages[key]->verifyAssociatedStorageValid(this);

            // Force the image to recover from storage before its data is overwritten.
            // This will reset mAssociatedImages[level] to nullptr too.
            ANGLE_TRY(mAssociatedImages[key]->recoverFromAssociatedStorage(context));
        }
    }

    return angle::Result::Continue;
}

angle::Result TextureStorage11_2DArray::getResource(const gl::Context *context,
                                                    const TextureHelper11 **outResource)
{
    // if the width, height or depth is not positive this should be treated as an incomplete texture
    // we handle that here by skipping the d3d texture creation
    if (!mTexture.valid() && mTextureWidth > 0 && mTextureHeight > 0 && mTextureDepth > 0)
    {
        ASSERT(mMipLevels > 0);

        D3D11_TEXTURE2D_DESC desc;
        desc.Width              = mTextureWidth;
        desc.Height             = mTextureHeight;
        desc.MipLevels          = mMipLevels;
        desc.ArraySize          = mTextureDepth;
        desc.Format             = mFormatInfo.texFormat;
        desc.SampleDesc.Count   = 1;
        desc.SampleDesc.Quality = 0;
        desc.Usage              = D3D11_USAGE_DEFAULT;
        desc.BindFlags          = getBindFlags();
        desc.CPUAccessFlags     = 0;
        desc.MiscFlags          = getMiscFlags();

        ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, mFormatInfo,
                                             &mTexture));
        mTexture.setDebugName("TexStorage2DArray.Texture");
    }

    *outResource = &mTexture;
    return angle::Result::Continue;
}

angle::Result TextureStorage11_2DArray::createSRVForSampler(const gl::Context *context,
                                                            int baseLevel,
                                                            int mipLevels,
                                                            DXGI_FORMAT format,
                                                            const TextureHelper11 &texture,
                                                            d3d11::SharedSRV *outSRV)
{
    D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
    srvDesc.Format                         = format;
    srvDesc.ViewDimension                  = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
    srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + baseLevel;
    srvDesc.Texture2DArray.MipLevels       = mipLevels;
    srvDesc.Texture2DArray.FirstArraySlice = 0;
    srvDesc.Texture2DArray.ArraySize       = mTextureDepth;

    ANGLE_TRY(
        mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV));
    outSRV->setDebugName("TexStorage2DArray.SRV");

    return angle::Result::Continue;
}

angle::Result TextureStorage11_2DArray::createSRVForImage(const gl::Context *context,
                                                          int level,
                                                          DXGI_FORMAT format,
                                                          const TextureHelper11 &texture,
                                                          d3d11::SharedSRV *outSRV)
{
    ASSERT(outSRV);
    D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
    srvDesc.Format                         = format;
    srvDesc.ViewDimension                  = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
    srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + level;
    srvDesc.Texture2DArray.MipLevels       = 1;
    srvDesc.Texture2DArray.FirstArraySlice = 0;
    srvDesc.Texture2DArray.ArraySize       = mTextureDepth;
    ANGLE_TRY(
        mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV));
    outSRV->setDebugName("TexStorage2DArray.SRVForImage");
    return angle::Result::Continue;
}

angle::Result TextureStorage11_2DArray::createUAVForImage(const gl::Context *context,
                                                          int level,
                                                          DXGI_FORMAT format,
                                                          const TextureHelper11 &texture,
                                                          d3d11::SharedUAV *outUAV)
{
    ASSERT(outUAV);
    D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
    uavDesc.Format                         = format;
    uavDesc.ViewDimension                  = D3D11_UAV_DIMENSION_TEXTURE2DARRAY;
    uavDesc.Texture2DArray.MipSlice        = mTopLevel + level;
    uavDesc.Texture2DArray.FirstArraySlice = 0;
    uavDesc.Texture2DArray.ArraySize       = mTextureDepth;
    ANGLE_TRY(
        mRenderer->allocateResource(GetImplAs<Context11>(context), uavDesc, texture.get(), outUAV));
    outUAV->setDebugName("TexStorage2DArray.UAVForImage");
    return angle::Result::Continue;
}

angle::Result TextureStorage11_2DArray::createRenderTargetSRV(const gl::Context *context,
                                                              const TextureHelper11 &texture,
                                                              const gl::ImageIndex &index,
                                                              DXGI_FORMAT resourceFormat,
                                                              d3d11::SharedSRV *srv) const
{
    D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
    srvDesc.Format                         = resourceFormat;
    srvDesc.ViewDimension                  = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
    srvDesc.Texture2DArray.MostDetailedMip = mTopLevel + index.getLevelIndex();
    srvDesc.Texture2DArray.MipLevels       = 1;
    srvDesc.Texture2DArray.FirstArraySlice = index.getLayerIndex();
    srvDesc.Texture2DArray.ArraySize       = index.getLayerCount();

    ANGLE_TRY(
        mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), srv));

    return angle::Result::Continue;
}

angle::Result TextureStorage11_2DArray::getRenderTarget(const gl::Context *context,
                                                        const gl::ImageIndex &index,
                                                        GLsizei samples,
                                                        RenderTargetD3D **outRT)
{
    ASSERT(index.hasLayer());

    const int mipLevel  = index.getLevelIndex();
    const int layer     = index.getLayerIndex();
    const int numLayers = index.getLayerCount();

    ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());

    LevelLayerRangeKey key(mipLevel, layer, numLayers);
    if (mRenderTargets.find(key) == mRenderTargets.end())
    {
        const TextureHelper11 *texture = nullptr;
        ANGLE_TRY(getResource(context, &texture));
        d3d11::SharedSRV srv;
        ANGLE_TRY(createRenderTargetSRV(context, *texture, index, mFormatInfo.srvFormat, &srv));
        d3d11::SharedSRV blitSRV;
        if (mFormatInfo.blitSRVFormat != mFormatInfo.srvFormat)
        {
            ANGLE_TRY(createRenderTargetSRV(context, *texture, index, mFormatInfo.blitSRVFormat,
                                            &blitSRV));
        }
        else
        {
            blitSRV = srv.makeCopy();
        }

        srv.setDebugName("TexStorage2DArray.RenderTargetSRV");

        if (mFormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN)
        {
            D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
            rtvDesc.Format                         = mFormatInfo.rtvFormat;
            rtvDesc.ViewDimension                  = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
            rtvDesc.Texture2DArray.MipSlice        = mTopLevel + mipLevel;
            rtvDesc.Texture2DArray.FirstArraySlice = layer;
            rtvDesc.Texture2DArray.ArraySize       = numLayers;

            d3d11::RenderTargetView rtv;
            ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), rtvDesc,
                                                  texture->get(), &rtv));
            rtv.setDebugName("TexStorage2DArray.RenderTargetRTV");

            mRenderTargets[key].reset(new TextureRenderTarget11(
                std::move(rtv), *texture, srv, blitSRV, mFormatInfo.internalFormat, getFormatSet(),
                getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, 0));
        }
        else
        {
            ASSERT(mFormatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN);

            D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
            dsvDesc.Format                         = mFormatInfo.dsvFormat;
            dsvDesc.ViewDimension                  = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
            dsvDesc.Texture2DArray.MipSlice        = mTopLevel + mipLevel;
            dsvDesc.Texture2DArray.FirstArraySlice = layer;
            dsvDesc.Texture2DArray.ArraySize       = numLayers;
            dsvDesc.Flags                          = 0;

            d3d11::DepthStencilView dsv;
            ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), dsvDesc,
                                                  texture->get(), &dsv));
            dsv.setDebugName("TexStorage2DArray.RenderTargetDSV");

            mRenderTargets[key].reset(new TextureRenderTarget11(
                std::move(dsv), *texture, srv, mFormatInfo.internalFormat, getFormatSet(),
                getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, 0));
        }
    }

    ASSERT(outRT);
    *outRT = mRenderTargets[key].get();
    return angle::Result::Continue;
}

angle::Result TextureStorage11_2DArray::getSwizzleTexture(const gl::Context *context,
                                                          const TextureHelper11 **outTexture)
{
    if (!mSwizzleTexture.valid())
    {
        const auto &format = mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps());

        D3D11_TEXTURE2D_DESC desc;
        desc.Width              = mTextureWidth;
        desc.Height             = mTextureHeight;
        desc.MipLevels          = mMipLevels;
        desc.ArraySize          = mTextureDepth;
        desc.Format             = format.texFormat;
        desc.SampleDesc.Count   = 1;
        desc.SampleDesc.Quality = 0;
        desc.Usage              = D3D11_USAGE_DEFAULT;
        desc.BindFlags          = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
        desc.CPUAccessFlags     = 0;
        desc.MiscFlags          = 0;

        ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, format,
                                             &mSwizzleTexture));
        mSwizzleTexture.setDebugName("TexStorage2DArray.SwizzleTexture");
    }

    *outTexture = &mSwizzleTexture;
    return angle::Result::Continue;
}

angle::Result TextureStorage11_2DArray::getSwizzleRenderTarget(
    const gl::Context *context,
    int mipLevel,
    const d3d11::RenderTargetView **outRTV)
{
    ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());
    ASSERT(outRTV);

    if (!mSwizzleRenderTargets[mipLevel].valid())
    {
        const TextureHelper11 *swizzleTexture = nullptr;
        ANGLE_TRY(getSwizzleTexture(context, &swizzleTexture));

        D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
        rtvDesc.Format =
            mFormatInfo.getSwizzleFormat(mRenderer->getRenderer11DeviceCaps()).rtvFormat;
        rtvDesc.ViewDimension                  = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
        rtvDesc.Texture2DArray.MipSlice        = mTopLevel + mipLevel;
        rtvDesc.Texture2DArray.FirstArraySlice = 0;
        rtvDesc.Texture2DArray.ArraySize       = mTextureDepth;

        ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), rtvDesc,
                                              mSwizzleTexture.get(),
                                              &mSwizzleRenderTargets[mipLevel]));
    }

    *outRTV = &mSwizzleRenderTargets[mipLevel];
    return angle::Result::Continue;
}

angle::Result TextureStorage11_2DArray::ensureDropStencilTexture(const gl::Context *context,
                                                                 DropStencil *dropStencilOut)
{
    if (mDropStencilTexture.valid())
    {
        *dropStencilOut = DropStencil::ALREADY_EXISTS;
        return angle::Result::Continue;
    }

    D3D11_TEXTURE2D_DESC dropDesc = {};
    dropDesc.ArraySize            = mTextureDepth;
    dropDesc.BindFlags            = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_DEPTH_STENCIL;
    dropDesc.CPUAccessFlags       = 0;
    dropDesc.Format               = DXGI_FORMAT_R32_TYPELESS;
    dropDesc.Height               = mTextureHeight;
    dropDesc.MipLevels            = mMipLevels;
    dropDesc.MiscFlags            = 0;
    dropDesc.SampleDesc.Count     = 1;
    dropDesc.SampleDesc.Quality   = 0;
    dropDesc.Usage                = D3D11_USAGE_DEFAULT;
    dropDesc.Width                = mTextureWidth;

    const auto &format =
        d3d11::Format::Get(GL_DEPTH_COMPONENT32F, mRenderer->getRenderer11DeviceCaps());
    ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), dropDesc, format,
                                         &mDropStencilTexture));
    mDropStencilTexture.setDebugName("TexStorage2DArray.DropStencil");

    std::vector<GLsizei> layerCounts(mMipLevels, mTextureDepth);

    ANGLE_TRY(initDropStencilTexture(
        context, gl::ImageIndexIterator::Make2DArray(0, mMipLevels, layerCounts.data())));

    *dropStencilOut = DropStencil::CREATED;
    return angle::Result::Continue;
}

TextureStorage11_2DMultisample::TextureStorage11_2DMultisample(Renderer11 *renderer,
                                                               GLenum internalformat,
                                                               GLsizei width,
                                                               GLsizei height,
                                                               int levels,
                                                               int samples,
                                                               bool fixedSampleLocations)
    : TextureStorage11ImmutableBase(
          renderer,
          GetTextureBindFlags(internalformat, renderer->getRenderer11DeviceCaps(), true),
          GetTextureMiscFlags(internalformat, renderer->getRenderer11DeviceCaps(), true, levels),
          internalformat),
      mTexture(),
      mRenderTarget(nullptr)
{
    // There are no multisampled compressed formats, so there's no need to adjust texture size
    // according to block size.
    ASSERT(d3d11::GetDXGIFormatSizeInfo(mFormatInfo.texFormat).blockWidth <= 1);
    ASSERT(d3d11::GetDXGIFormatSizeInfo(mFormatInfo.texFormat).blockHeight <= 1);

    mMipLevels            = 1;
    mTextureWidth         = width;
    mTextureHeight        = height;
    mTextureDepth         = 1;
    mSamples              = samples;
    mFixedSampleLocations = fixedSampleLocations;
}

angle::Result TextureStorage11_2DMultisample::onDestroy(const gl::Context *context)
{
    mRenderTarget.reset();
    return angle::Result::Continue;
}

TextureStorage11_2DMultisample::~TextureStorage11_2DMultisample() {}

angle::Result TextureStorage11_2DMultisample::copyToStorage(const gl::Context *context,
                                                            TextureStorage *destStorage)
{
    ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
    return angle::Result::Stop;
}

angle::Result TextureStorage11_2DMultisample::getResource(const gl::Context *context,
                                                          const TextureHelper11 **outResource)
{
    ANGLE_TRY(ensureTextureExists(context, 1));

    *outResource = &mTexture;
    return angle::Result::Continue;
}

angle::Result TextureStorage11_2DMultisample::ensureTextureExists(const gl::Context *context,
                                                                  int mipLevels)
{
    // For Multisampled textures, mipLevels always equals 1.
    ASSERT(mipLevels == 1);

    // if the width or height is not positive this should be treated as an incomplete texture
    // we handle that here by skipping the d3d texture creation
    if (!mTexture.valid() && mTextureWidth > 0 && mTextureHeight > 0)
    {
        D3D11_TEXTURE2D_DESC desc;
        ZeroMemory(&desc, sizeof(desc));
        desc.Width          = mTextureWidth;  // Compressed texture size constraints?
        desc.Height         = mTextureHeight;
        desc.MipLevels      = mipLevels;
        desc.ArraySize      = 1;
        desc.Format         = mFormatInfo.texFormat;
        desc.Usage          = D3D11_USAGE_DEFAULT;
        desc.BindFlags      = getBindFlags() & ~D3D11_BIND_UNORDERED_ACCESS;
        desc.CPUAccessFlags = 0;
        desc.MiscFlags      = getMiscFlags();

        const gl::TextureCaps &textureCaps =
            mRenderer->getNativeTextureCaps().get(mFormatInfo.internalFormat);
        GLuint supportedSamples = textureCaps.getNearestSamples(mSamples);
        desc.SampleDesc.Count   = (supportedSamples == 0) ? 1 : supportedSamples;
        desc.SampleDesc.Quality = static_cast<UINT>(D3D11_STANDARD_MULTISAMPLE_PATTERN);

        ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, mFormatInfo,
                                             &mTexture));
        mTexture.setDebugName("TexStorage2DMS.Texture");
    }

    return angle::Result::Continue;
}

angle::Result TextureStorage11_2DMultisample::getRenderTarget(const gl::Context *context,
                                                              const gl::ImageIndex &index,
                                                              GLsizei samples,
                                                              RenderTargetD3D **outRT)
{
    ASSERT(!index.hasLayer());

    const int level = index.getLevelIndex();
    ASSERT(level == 0);

    ASSERT(outRT);
    if (mRenderTarget)
    {
        *outRT = mRenderTarget.get();
        return angle::Result::Continue;
    }

    const TextureHelper11 *texture = nullptr;
    ANGLE_TRY(getResource(context, &texture));

    const d3d11::SharedSRV *srv = nullptr;
    ANGLE_TRY(getSRVLevel(context, level, false, &srv));

    const d3d11::SharedSRV *blitSRV = nullptr;
    ANGLE_TRY(getSRVLevel(context, level, true, &blitSRV));

    Context11 *context11 = GetImplAs<Context11>(context);

    if (mFormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN)
    {
        D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
        rtvDesc.Format        = mFormatInfo.rtvFormat;
        rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS;

        d3d11::RenderTargetView rtv;
        ANGLE_TRY(mRenderer->allocateResource(context11, rtvDesc, texture->get(), &rtv));

        mRenderTarget.reset(new TextureRenderTarget11(
            std::move(rtv), *texture, *srv, *blitSRV, mFormatInfo.internalFormat, getFormatSet(),
            getLevelWidth(level), getLevelHeight(level), 1, mSamples));

        *outRT = mRenderTarget.get();
        return angle::Result::Continue;
    }

    ASSERT(mFormatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN);

    D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
    dsvDesc.Format        = mFormatInfo.dsvFormat;
    dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS;
    dsvDesc.Flags         = 0;

    d3d11::DepthStencilView dsv;
    ANGLE_TRY(mRenderer->allocateResource(context11, dsvDesc, texture->get(), &dsv));

    mRenderTarget.reset(new TextureRenderTarget11(
        std::move(dsv), *texture, *srv, mFormatInfo.internalFormat, getFormatSet(),
        getLevelWidth(level), getLevelHeight(level), 1, mSamples));

    *outRT = mRenderTarget.get();
    return angle::Result::Continue;
}

angle::Result TextureStorage11_2DMultisample::createSRVForSampler(const gl::Context *context,
                                                                  int baseLevel,
                                                                  int mipLevels,
                                                                  DXGI_FORMAT format,
                                                                  const TextureHelper11 &texture,
                                                                  d3d11::SharedSRV *outSRV)
{
    ASSERT(outSRV);

    D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
    srvDesc.Format        = format;
    srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS;

    ANGLE_TRY(
        mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV));
    outSRV->setDebugName("TexStorage2DMS.SRV");
    return angle::Result::Continue;
}

angle::Result TextureStorage11_2DMultisample::getSwizzleTexture(const gl::Context *context,
                                                                const TextureHelper11 **outTexture)
{
    ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
    return angle::Result::Stop;
}

angle::Result TextureStorage11_2DMultisample::getSwizzleRenderTarget(
    const gl::Context *context,
    int mipLevel,
    const d3d11::RenderTargetView **outRTV)
{
    ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
    return angle::Result::Stop;
}

angle::Result TextureStorage11_2DMultisample::ensureDropStencilTexture(const gl::Context *context,
                                                                       DropStencil *dropStencilOut)
{
    ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
    return angle::Result::Stop;
}

TextureStorage11_2DMultisampleArray::TextureStorage11_2DMultisampleArray(Renderer11 *renderer,
                                                                         GLenum internalformat,
                                                                         GLsizei width,
                                                                         GLsizei height,
                                                                         GLsizei depth,
                                                                         int levels,
                                                                         int samples,
                                                                         bool fixedSampleLocations)
    : TextureStorage11ImmutableBase(
          renderer,
          GetTextureBindFlags(internalformat, renderer->getRenderer11DeviceCaps(), true),
          GetTextureMiscFlags(internalformat, renderer->getRenderer11DeviceCaps(), true, levels),
          internalformat),
      mTexture()
{
    // There are no multisampled compressed formats, so there's no need to adjust texture size
    // according to block size.
    ASSERT(d3d11::GetDXGIFormatSizeInfo(mFormatInfo.texFormat).blockWidth <= 1);
    ASSERT(d3d11::GetDXGIFormatSizeInfo(mFormatInfo.texFormat).blockHeight <= 1);

    mMipLevels            = 1;
    mTextureWidth         = width;
    mTextureHeight        = height;
    mTextureDepth         = depth;
    mSamples              = samples;
    mFixedSampleLocations = fixedSampleLocations;
}

angle::Result TextureStorage11_2DMultisampleArray::onDestroy(const gl::Context *context)
{
    return angle::Result::Continue;
}

TextureStorage11_2DMultisampleArray::~TextureStorage11_2DMultisampleArray() {}

angle::Result TextureStorage11_2DMultisampleArray::copyToStorage(const gl::Context *context,
                                                                 TextureStorage *destStorage)
{
    ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
    return angle::Result::Stop;
}

angle::Result TextureStorage11_2DMultisampleArray::getResource(const gl::Context *context,
                                                               const TextureHelper11 **outResource)
{
    ANGLE_TRY(ensureTextureExists(context, 1));

    *outResource = &mTexture;
    return angle::Result::Continue;
}

angle::Result TextureStorage11_2DMultisampleArray::ensureTextureExists(const gl::Context *context,
                                                                       int mipLevels)
{
    // For multisampled textures, mipLevels always equals 1.
    ASSERT(mipLevels == 1);

    // if the width or height is not positive this should be treated as an incomplete texture
    // we handle that here by skipping the d3d texture creation
    if (!mTexture.valid() && mTextureWidth > 0 && mTextureHeight > 0)
    {
        D3D11_TEXTURE2D_DESC desc;
        ZeroMemory(&desc, sizeof(desc));
        desc.Width          = mTextureWidth;
        desc.Height         = mTextureHeight;
        desc.MipLevels      = mipLevels;
        desc.ArraySize      = mTextureDepth;
        desc.Format         = mFormatInfo.texFormat;
        desc.Usage          = D3D11_USAGE_DEFAULT;
        desc.BindFlags      = getBindFlags() & ~D3D11_BIND_UNORDERED_ACCESS;
        desc.CPUAccessFlags = 0;
        desc.MiscFlags      = getMiscFlags();

        const gl::TextureCaps &textureCaps =
            mRenderer->getNativeTextureCaps().get(mFormatInfo.internalFormat);
        GLuint supportedSamples = textureCaps.getNearestSamples(mSamples);
        desc.SampleDesc.Count   = (supportedSamples == 0) ? 1 : supportedSamples;
        desc.SampleDesc.Quality = static_cast<UINT>(D3D11_STANDARD_MULTISAMPLE_PATTERN);

        ANGLE_TRY(mRenderer->allocateTexture(GetImplAs<Context11>(context), desc, mFormatInfo,
                                             &mTexture));
        mTexture.setDebugName("TexStorage2DMSArray.Texture");
    }

    return angle::Result::Continue;
}

angle::Result TextureStorage11_2DMultisampleArray::createRenderTargetSRV(
    const gl::Context *context,
    const TextureHelper11 &texture,
    const gl::ImageIndex &index,
    DXGI_FORMAT resourceFormat,
    d3d11::SharedSRV *srv) const
{
    D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
    srvDesc.Format                           = resourceFormat;
    srvDesc.ViewDimension                    = D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY;
    srvDesc.Texture2DMSArray.FirstArraySlice = index.getLayerIndex();
    srvDesc.Texture2DMSArray.ArraySize       = index.getLayerCount();

    ANGLE_TRY(
        mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), srv));

    return angle::Result::Continue;
}

angle::Result TextureStorage11_2DMultisampleArray::getRenderTarget(const gl::Context *context,
                                                                   const gl::ImageIndex &index,
                                                                   GLsizei samples,
                                                                   RenderTargetD3D **outRT)
{
    ASSERT(index.hasLayer());

    const int mipLevel = index.getLevelIndex();
    ASSERT(mipLevel == 0);
    const int layer     = index.getLayerIndex();
    const int numLayers = index.getLayerCount();

    ASSERT(mipLevel >= 0 && mipLevel < getLevelCount());

    TextureStorage11_2DArray::LevelLayerRangeKey key(mipLevel, layer, numLayers);
    if (mRenderTargets.find(key) == mRenderTargets.end())
    {
        const TextureHelper11 *texture = nullptr;
        ANGLE_TRY(getResource(context, &texture));
        d3d11::SharedSRV srv;
        ANGLE_TRY(createRenderTargetSRV(context, *texture, index, mFormatInfo.srvFormat, &srv));
        d3d11::SharedSRV blitSRV;
        if (mFormatInfo.blitSRVFormat != mFormatInfo.srvFormat)
        {
            ANGLE_TRY(createRenderTargetSRV(context, *texture, index, mFormatInfo.blitSRVFormat,
                                            &blitSRV));
        }
        else
        {
            blitSRV = srv.makeCopy();
        }

        srv.setDebugName("TexStorage2DMSArray.RenderTargetSRV");

        if (mFormatInfo.rtvFormat != DXGI_FORMAT_UNKNOWN)
        {
            D3D11_RENDER_TARGET_VIEW_DESC rtvDesc;
            rtvDesc.Format                           = mFormatInfo.rtvFormat;
            rtvDesc.ViewDimension                    = D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY;
            rtvDesc.Texture2DMSArray.FirstArraySlice = layer;
            rtvDesc.Texture2DMSArray.ArraySize       = numLayers;

            d3d11::RenderTargetView rtv;
            ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), rtvDesc,
                                                  texture->get(), &rtv));
            rtv.setDebugName("TexStorage2DMSArray.RenderTargetRTV");

            mRenderTargets[key].reset(new TextureRenderTarget11(
                std::move(rtv), *texture, srv, blitSRV, mFormatInfo.internalFormat, getFormatSet(),
                getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, mSamples));
        }
        else
        {
            ASSERT(mFormatInfo.dsvFormat != DXGI_FORMAT_UNKNOWN);

            D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
            dsvDesc.Format                           = mFormatInfo.dsvFormat;
            dsvDesc.ViewDimension                    = D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY;
            dsvDesc.Texture2DMSArray.FirstArraySlice = layer;
            dsvDesc.Texture2DMSArray.ArraySize       = numLayers;
            dsvDesc.Flags                            = 0;

            d3d11::DepthStencilView dsv;
            ANGLE_TRY(mRenderer->allocateResource(GetImplAs<Context11>(context), dsvDesc,
                                                  texture->get(), &dsv));
            dsv.setDebugName("TexStorage2DMSArray.RenderTargetDSV");

            mRenderTargets[key].reset(new TextureRenderTarget11(
                std::move(dsv), *texture, srv, mFormatInfo.internalFormat, getFormatSet(),
                getLevelWidth(mipLevel), getLevelHeight(mipLevel), 1, mSamples));
        }
    }

    ASSERT(outRT);
    *outRT = mRenderTargets[key].get();
    return angle::Result::Continue;
}

angle::Result TextureStorage11_2DMultisampleArray::createSRVForSampler(
    const gl::Context *context,
    int baseLevel,
    int mipLevels,
    DXGI_FORMAT format,
    const TextureHelper11 &texture,
    d3d11::SharedSRV *outSRV)
{
    ASSERT(outSRV);

    D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
    srvDesc.Format                           = format;
    srvDesc.ViewDimension                    = D3D11_SRV_DIMENSION_TEXTURE2DMSARRAY;
    srvDesc.Texture2DMSArray.FirstArraySlice = 0;
    srvDesc.Texture2DMSArray.ArraySize       = mTextureDepth;

    ANGLE_TRY(
        mRenderer->allocateResource(GetImplAs<Context11>(context), srvDesc, texture.get(), outSRV));
    outSRV->setDebugName("TexStorage2DMSArray.SRV");
    return angle::Result::Continue;
}

angle::Result TextureStorage11_2DMultisampleArray::getSwizzleTexture(
    const gl::Context *context,
    const TextureHelper11 **outTexture)
{
    ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
    return angle::Result::Stop;
}

angle::Result TextureStorage11_2DMultisampleArray::getSwizzleRenderTarget(
    const gl::Context *context,
    int mipLevel,
    const d3d11::RenderTargetView **outRTV)
{
    ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
    return angle::Result::Stop;
}

angle::Result TextureStorage11_2DMultisampleArray::ensureDropStencilTexture(
    const gl::Context *context,
    DropStencil *dropStencilOut)
{
    ANGLE_HR_UNREACHABLE(GetImplAs<Context11>(context));
    return angle::Result::Stop;
}

}  // namespace rx
