// Copyright 2023 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "dawn/native/d3d11/TextureD3D11.h"

#include <algorithm>
#include <string>
#include <utility>

#include "dawn/common/Constants.h"
#include "dawn/common/Math.h"
#include "dawn/native/ChainUtils.h"
#include "dawn/native/CommandBuffer.h"
#include "dawn/native/CommandValidation.h"
#include "dawn/native/DynamicUploader.h"
#include "dawn/native/EnumMaskIterator.h"
#include "dawn/native/IntegerTypes.h"
#include "dawn/native/Queue.h"
#include "dawn/native/ToBackend.h"
#include "dawn/native/d3d/D3DError.h"
#include "dawn/native/d3d/UtilsD3D.h"
#include "dawn/native/d3d11/CommandRecordingContextD3D11.h"
#include "dawn/native/d3d11/DeviceD3D11.h"
#include "dawn/native/d3d11/Forward.h"
#include "dawn/native/d3d11/QueueD3D11.h"
#include "dawn/native/d3d11/SharedFenceD3D11.h"
#include "dawn/native/d3d11/SharedTextureMemoryD3D11.h"
#include "dawn/native/d3d11/UtilsD3D11.h"

namespace dawn::native::d3d11 {
namespace {

UINT D3D11TextureBindFlags(wgpu::TextureUsage usage, const Format& format) {
    bool isDepthOrStencilFormat = format.HasDepthOrStencil();
    UINT bindFlags = 0;
    if (usage & wgpu::TextureUsage::TextureBinding) {
        bindFlags |= D3D11_BIND_SHADER_RESOURCE;
    }
    if (usage & wgpu::TextureUsage::StorageBinding) {
        bindFlags |= D3D11_BIND_UNORDERED_ACCESS | D3D11_BIND_SHADER_RESOURCE;
    }
    if (usage & wgpu::TextureUsage::RenderAttachment) {
        bindFlags |= isDepthOrStencilFormat ? D3D11_BIND_DEPTH_STENCIL : D3D11_BIND_RENDER_TARGET;
    }
    if (usage & wgpu::TextureUsage::StorageAttachment) {
        bindFlags |= D3D11_BIND_UNORDERED_ACCESS;
    }
    return bindFlags;
}

Aspect D3D11Aspect(Aspect aspect) {
    // https://learn.microsoft.com/en-us/windows/win32/direct3d12/subresources
    // Planar formats existed in Direct3D 11, but individual planes could not be addressed
    // individually, so squash stencil into depth.
    if (aspect & Aspect::Stencil) {
        DAWN_ASSERT(IsSubset(aspect, Aspect::Depth | Aspect::Stencil));
        return Aspect::Depth;
    }

    DAWN_ASSERT(HasOneBit(aspect));
    return aspect;
}

// Gets the uncompressed texture format for reinterpretation conversion.
wgpu::TextureFormat UncompressedTextureFormat(wgpu::TextureFormat compressedFormat) {
    // https://learn.microsoft.com/en-us/windows/win32/direct3d10/d3d10-graphics-programming-guide-resources-block-compression
    switch (compressedFormat) {
        case wgpu::TextureFormat::BC1RGBAUnorm:
        case wgpu::TextureFormat::BC1RGBAUnormSrgb:
        case wgpu::TextureFormat::BC4RSnorm:
        case wgpu::TextureFormat::BC4RUnorm:
            return wgpu::TextureFormat::RGBA16Uint;

        case wgpu::TextureFormat::BC2RGBAUnorm:
        case wgpu::TextureFormat::BC2RGBAUnormSrgb:
        case wgpu::TextureFormat::BC3RGBAUnorm:
        case wgpu::TextureFormat::BC3RGBAUnormSrgb:
        case wgpu::TextureFormat::BC5RGSnorm:
        case wgpu::TextureFormat::BC5RGUnorm:
        case wgpu::TextureFormat::BC6HRGBFloat:
        case wgpu::TextureFormat::BC6HRGBUfloat:
        case wgpu::TextureFormat::BC7RGBAUnorm:
        case wgpu::TextureFormat::BC7RGBAUnormSrgb:
            return wgpu::TextureFormat::RGBA32Uint;
        default:
            DAWN_UNREACHABLE();
    }
}

// The memory layout of depth or stencil component inside a texel of depth-stencil format.
struct DepthStencilAspectLayout {
    // Texel size of a depth/stencil DXGI format in bytes.
    uint32_t texelSize = 0u;
    // Depth/Stencil component offset inside the texel in bytes.
    uint32_t componentOffset = 0u;
    // Depth/Stencil component size in bytes.
    uint32_t componentSize = 0u;
};

DepthStencilAspectLayout DepthStencilAspectLayout(DXGI_FORMAT format, Aspect aspect) {
    DAWN_ASSERT(aspect == Aspect::Depth || aspect == Aspect::Stencil);
    uint32_t texelSize = 0u;
    uint32_t componentOffset = 0u;
    uint32_t componentSize = 0u;

    switch (format) {
        case DXGI_FORMAT_D24_UNORM_S8_UINT:
            componentOffset = aspect == Aspect::Stencil ? 3u : 0u;
            componentSize = aspect == Aspect::Stencil ? 1u : 3u;
            texelSize = 4u;
            break;
        case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
            componentOffset = aspect == Aspect::Stencil ? 4u : 0u;
            componentSize = aspect == Aspect::Stencil ? 1u : 4u;
            texelSize = 8u;
            break;
        default:
            DAWN_UNREACHABLE();
    }
    return {texelSize, componentOffset, componentSize};
}

}  // namespace

// static
ResultOrError<Ref<Texture>> Texture::Create(Device* device,
                                            const UnpackedPtr<TextureDescriptor>& descriptor) {
    Ref<Texture> texture = AcquireRef(new Texture(device, descriptor, Kind::Normal));
    DAWN_TRY(texture->InitializeAsInternalTexture());
    return std::move(texture);
}

// static
ResultOrError<Ref<Texture>> Texture::Create(Device* device,
                                            const UnpackedPtr<TextureDescriptor>& descriptor,
                                            ComPtr<ID3D11Resource> d3d11Texture) {
    Ref<Texture> dawnTexture = AcquireRef(new Texture(device, descriptor, Kind::Normal));
    DAWN_TRY(dawnTexture->InitializeAsSwapChainTexture(std::move(d3d11Texture)));
    return std::move(dawnTexture);
}

ResultOrError<Ref<Texture>> Texture::CreateInternal(
    Device* device,
    const UnpackedPtr<TextureDescriptor>& descriptor,
    Kind kind) {
    Ref<Texture> texture = AcquireRef(new Texture(device, descriptor, kind));
    DAWN_TRY(texture->InitializeAsInternalTexture());
    return std::move(texture);
}

// static
ResultOrError<Ref<Texture>> Texture::CreateFromSharedTextureMemory(
    SharedTextureMemory* memory,
    const UnpackedPtr<TextureDescriptor>& descriptor) {
    Device* device = ToBackend(memory->GetDevice());
    Ref<Texture> texture = AcquireRef(new Texture(device, descriptor, Kind::Normal));
    DAWN_TRY(
        texture->InitializeAsExternalTexture(memory->GetD3DResource(), memory->GetKeyedMutex()));
    texture->mSharedResourceMemoryContents = memory->GetContents();
    return texture;
}

template <typename T>
T Texture::GetD3D11TextureDesc() const {
    T desc;

    if constexpr (std::is_same<T, D3D11_TEXTURE1D_DESC>::value) {
        desc.Width = GetBaseSize().width;
        desc.ArraySize = GetArrayLayers();
        desc.MiscFlags = 0;
    } else if constexpr (std::is_same<T, D3D11_TEXTURE2D_DESC>::value) {
        desc.Width = GetBaseSize().width;
        desc.Height = GetBaseSize().height;
        desc.ArraySize = GetArrayLayers();
        desc.SampleDesc.Count = GetSampleCount();
        desc.SampleDesc.Quality = 0;
        desc.MiscFlags = 0;
        if (GetArrayLayers() >= 6 && desc.Width == desc.Height) {
            // Texture layers are more than 6. It can be used as a cube map.
            desc.MiscFlags |= D3D11_RESOURCE_MISC_TEXTURECUBE;
        }
    } else if constexpr (std::is_same<T, D3D11_TEXTURE3D_DESC>::value) {
        desc.Width = GetBaseSize().width;
        desc.Height = GetBaseSize().height;
        desc.Depth = GetBaseSize().depthOrArrayLayers;
        desc.MiscFlags = 0;
    }

    desc.MipLevels = static_cast<UINT16>(GetNumMipLevels());
    // To sample from a depth or stencil texture, we need to create a typeless texture.
    bool needsTypelessFormat = GetFormat().HasDepthOrStencil() &&
                               (GetInternalUsage() & wgpu::TextureUsage::TextureBinding);
    // We need to use the typeless format if view format reinterpretation is required.
    needsTypelessFormat |= GetViewFormats().any();
    // We need to use the typeless format if it's a staging texture for writting to depth-stencil
    // textures.
    needsTypelessFormat |=
        d3d::IsDepthStencil(d3d::DXGITextureFormat(GetDevice(), GetFormat().format)) &&
        mKind == Kind::Staging;
    desc.Format = needsTypelessFormat
                      ? d3d::DXGITypelessTextureFormat(GetDevice(), GetFormat().format)
                      : d3d::DXGITextureFormat(GetDevice(), GetFormat().format);
    desc.Usage = mKind == Kind::Staging ? D3D11_USAGE_STAGING : D3D11_USAGE_DEFAULT;
    desc.BindFlags = D3D11TextureBindFlags(GetInternalUsage(), GetFormat());
    constexpr UINT kCPUReadWriteFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE;
    desc.CPUAccessFlags = mKind == Kind::Staging ? kCPUReadWriteFlags : 0;

    return desc;
}

MaybeError Texture::InitializeAsInternalTexture() {
    Device* device = ToBackend(GetDevice());

    if (GetFormat().IsRenderable() && mKind != Kind::Staging) {
        // If the texture format is renderable, we need to add the render attachment usage
        // internally, so the texture can be cleared with GPU.
        AddInternalUsage(wgpu::TextureUsage::RenderAttachment);
    }

    switch (GetDimension()) {
        case wgpu::TextureDimension::Undefined:
            DAWN_UNREACHABLE();
        case wgpu::TextureDimension::e1D: {
            D3D11_TEXTURE1D_DESC desc = GetD3D11TextureDesc<D3D11_TEXTURE1D_DESC>();
            ComPtr<ID3D11Texture1D> d3d11Texture1D;
            DAWN_TRY(CheckOutOfMemoryHRESULT(
                device->GetD3D11Device()->CreateTexture1D(&desc, nullptr, &d3d11Texture1D),
                "D3D11 create texture1d"));
            mD3d11Resource = std::move(d3d11Texture1D);
            break;
        }
        case wgpu::TextureDimension::e2D: {
            D3D11_TEXTURE2D_DESC desc = GetD3D11TextureDesc<D3D11_TEXTURE2D_DESC>();
            ComPtr<ID3D11Texture2D> d3d11Texture2D;
            DAWN_TRY(CheckOutOfMemoryHRESULT(
                device->GetD3D11Device()->CreateTexture2D(&desc, nullptr, &d3d11Texture2D),
                "D3D11 create texture2d"));
            mD3d11Resource = std::move(d3d11Texture2D);
            break;
        }
        case wgpu::TextureDimension::e3D: {
            D3D11_TEXTURE3D_DESC desc = GetD3D11TextureDesc<D3D11_TEXTURE3D_DESC>();
            ComPtr<ID3D11Texture3D> d3d11Texture3D;
            DAWN_TRY(CheckOutOfMemoryHRESULT(
                device->GetD3D11Device()->CreateTexture3D(&desc, nullptr, &d3d11Texture3D),
                "D3D11 create texture3d"));
            mD3d11Resource = std::move(d3d11Texture3D);
            break;
        }
    }

    // Staging texture is used internally, so we don't need to clear it.
    if (device->IsToggleEnabled(Toggle::NonzeroClearResourcesOnCreationForTesting) &&
        mKind == Kind::Normal) {
        auto commandContext = ToBackend(device->GetQueue())
                                  ->GetScopedPendingCommandContext(QueueBase::SubmitMode::Normal);
        DAWN_TRY(Clear(&commandContext, GetAllSubresources(), TextureBase::ClearValue::NonZero));
    }

    SetLabelImpl();

    return {};
}

MaybeError Texture::InitializeAsSwapChainTexture(ComPtr<ID3D11Resource> d3d11Texture) {
    mD3d11Resource = std::move(d3d11Texture);
    SetLabelHelper("Dawn_SwapChainTexture");

    return {};
}

MaybeError Texture::InitializeAsExternalTexture(ComPtr<IUnknown> d3dTexture,
                                                Ref<d3d::KeyedMutex> keyedMutex) {
    ComPtr<ID3D11Resource> d3d11Texture;
    DAWN_TRY(CheckHRESULT(d3dTexture.As(&d3d11Texture), "Query ID3D11Resource from IUnknown"));
    mD3d11Resource = std::move(d3d11Texture);
    mKeyedMutex = std::move(keyedMutex);
    SetLabelHelper("Dawn_ExternalTexture");
    return {};
}

Texture::Texture(Device* device, const UnpackedPtr<TextureDescriptor>& descriptor, Kind kind)
    : Base(device, descriptor), mKind(kind) {}

Texture::~Texture() = default;

void Texture::DestroyImpl(DestroyReason reason) {
    // TODO(crbug.com/dawn/831): DestroyImpl is called from two places.
    // - It may be called if the texture is explicitly destroyed with APIDestroy.
    //   This case is NOT thread-safe and needs proper synchronization with other
    //   simultaneous uses of the texture.
    // - It may be called when the last ref to the texture is dropped and the texture
    //   is implicitly destroyed. This case is thread-safe because there are no
    //   other threads using the texture since there are no other live refs.
    TextureBase::DestroyImpl(reason);
    mD3d11Resource = nullptr;
    mKeyedMutex = nullptr;
    mTextureForStencilSampling = nullptr;
}

std::optional<DeviceGuard> Texture::UseDeviceGuardForDestroy() {
    // TODO(crbug.com/481211676): DestroyImpl() is mostly thread-safe without the device lock.
    // However, concurrent calls to texture.Destroy() and Queue::Submit() can still race.
    // We rely on users to properly synchronize Destroy() with other queue operations.
    // In the future, we should implement validation to prevent such concurrent usage.
    return std::nullopt;
}

ID3D11Resource* Texture::GetD3D11Resource() const {
    return mD3d11Resource.Get();
}

ResultOrError<ComPtr<ID3D11RenderTargetView1>> Texture::CreateD3D11RenderTargetView(
    wgpu::TextureFormat viewFormat,
    uint32_t mipLevel,
    uint32_t baseSlice,
    uint32_t sliceCount,
    uint32_t planeSlice) {
    D3D11_RENDER_TARGET_VIEW_DESC1 rtvDesc;
    rtvDesc.Format = d3d::DXGITextureFormat(GetDevice(), viewFormat);
    if (IsMultisampledTexture()) {
        DAWN_ASSERT(GetDimension() == wgpu::TextureDimension::e2D);
        DAWN_ASSERT(GetNumMipLevels() == 1);
        DAWN_ASSERT(mipLevel == 0);
        DAWN_ASSERT(baseSlice == 0);
        DAWN_ASSERT(sliceCount == 1);
        DAWN_ASSERT(planeSlice == 0);
        rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DMS;
    } else {
        switch (GetDimension()) {
            case wgpu::TextureDimension::Undefined:
                DAWN_UNREACHABLE();
            case wgpu::TextureDimension::e2D:
                // Currently we always use D3D11_TEX2D_ARRAY_RTV because we cannot specify base
                // array layer and layer count in D3D11_TEX2D_RTV. For 2D texture views, we treat
                // them as 1-layer 2D array textures. (Just like how we treat SRVs)
                // https://docs.microsoft.com/en-us/windows/desktop/api/d3d11/ns-d3d11-d3d11_tex2d_rtv
                // https://docs.microsoft.com/en-us/windows/desktop/api/d3d11/ns-d3d11-d3d11_tex2d_array
                // _rtv
                rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY;
                rtvDesc.Texture2DArray.MipSlice = mipLevel;
                rtvDesc.Texture2DArray.FirstArraySlice = baseSlice;
                rtvDesc.Texture2DArray.ArraySize = sliceCount;
                rtvDesc.Texture2DArray.PlaneSlice = planeSlice;
                break;
            case wgpu::TextureDimension::e3D:
                rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE3D;
                rtvDesc.Texture3D.MipSlice = mipLevel;
                rtvDesc.Texture3D.FirstWSlice = baseSlice;
                rtvDesc.Texture3D.WSize = sliceCount;
                break;
            case wgpu::TextureDimension::e1D:
                rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE1D;
                rtvDesc.Texture1D.MipSlice = mipLevel;
                break;
        }
    }

    ComPtr<ID3D11RenderTargetView1> rtv;
    DAWN_TRY(CheckHRESULT(ToBackend(GetDevice())
                              ->GetD3D11Device3()
                              ->CreateRenderTargetView1(GetD3D11Resource(), &rtvDesc, &rtv),
                          "CreateRenderTargetView"));

    return std::move(rtv);
}

ResultOrError<ComPtr<ID3D11DepthStencilView>> Texture::CreateD3D11DepthStencilView(
    const SubresourceRange& singleLevelRange,
    bool depthReadOnly,
    bool stencilReadOnly) const {
    D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
    DAWN_ASSERT(singleLevelRange.levelCount == 1);
    dsvDesc.Format = d3d::DXGITextureFormat(GetDevice(), GetFormat().format);
    dsvDesc.Flags = 0;
    if (depthReadOnly && singleLevelRange.aspects & Aspect::Depth) {
        dsvDesc.Flags |= D3D11_DSV_READ_ONLY_DEPTH;
    }
    if (stencilReadOnly && singleLevelRange.aspects & Aspect::Stencil) {
        dsvDesc.Flags |= D3D11_DSV_READ_ONLY_STENCIL;
    }

    if (IsMultisampledTexture()) {
        DAWN_ASSERT(GetNumMipLevels() == 1);
        DAWN_ASSERT(singleLevelRange.baseMipLevel == 0);
        DAWN_ASSERT(singleLevelRange.baseArrayLayer == 0);
        DAWN_ASSERT(singleLevelRange.layerCount == 1);
        dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DMS;
    } else {
        dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY;
        dsvDesc.Texture2DArray.MipSlice = singleLevelRange.baseMipLevel;
        dsvDesc.Texture2DArray.FirstArraySlice = singleLevelRange.baseArrayLayer;
        dsvDesc.Texture2DArray.ArraySize = singleLevelRange.layerCount;
    }

    ComPtr<ID3D11DepthStencilView> dsv;
    DAWN_TRY(CheckHRESULT(ToBackend(GetDevice())
                              ->GetD3D11Device()
                              ->CreateDepthStencilView(GetD3D11Resource(), &dsvDesc, &dsv),
                          "CreateDepthStencilView"));
    return dsv;
}

MaybeError Texture::SynchronizeTextureBeforeUse(
    const ScopedCommandRecordingContext* commandContext) {
    if (auto* contents =
            static_cast<SharedTextureMemoryContentsD3D11*>(GetSharedResourceMemoryContents())) {
        const auto* device = ToBackend(GetDevice());
        const auto& queueFence = ToBackend(device->GetQueue())->GetSharedFence();

        SharedTextureMemoryBase::PendingFenceList fences;
        contents->AcquirePendingFences(&fences);
        for (const auto& fence : fences) {
            auto d3dFence = ToBackend(fence.object);
            if (d3dFence.Get() == queueFence.Get()) {
                // We don't need to wait on the fence that we signaled (self-wait).
                DAWN_ASSERT(ExecutionSerial(fence.signaledValue) <=
                            GetDevice()->GetQueue()->GetLastSubmittedCommandSerial());
                continue;
            }
            DAWN_TRY(
                CheckHRESULT(commandContext->Wait(d3dFence->GetD3DFence(), fence.signaledValue),
                             "ID3D11DeviceContext4::Wait"));
        }

        const bool requiresFenceSignal = contents->RequiresFenceSignal();
        if (requiresFenceSignal && !device->IsToggleEnabled(Toggle::D3D11DisableFence)) {
            commandContext->SetNeedsFence();
        }
    }
    if (mKeyedMutex != nullptr) {
        DAWN_TRY(commandContext->AcquireKeyedMutex(mKeyedMutex));
    }
    mLastSharedTextureMemoryUsageSerial = GetDevice()->GetQueue()->GetPendingCommandSerial();
    return {};
}

MaybeError Texture::Clear(const ScopedCommandRecordingContext* commandContext,
                          const SubresourceRange& range,
                          TextureBase::ClearValue clearValue) {
    bool isRenderable = GetInternalUsage() & wgpu::TextureUsage::RenderAttachment;

    if (isRenderable) {
        float color = clearValue == ClearValue::Zero ? 0.0f : 1.0f;
        float depth = clearValue == ClearValue::Zero ? 0.0f : 1.0f;
        uint8_t stencil = clearValue == ClearValue::Zero ? 0u : 1u;
        D3D11ClearValue d3d11ClearValue = {{color, color, color, color}, depth, stencil};
        DAWN_TRY(ClearRenderable(commandContext, range, clearValue, d3d11ClearValue));
    } else if (GetFormat().isCompressed) {
        DAWN_TRY(ClearCompressed(commandContext, range, clearValue));
    } else {
        DAWN_TRY(ClearNonRenderable(commandContext, range, clearValue));
    }

    if (clearValue == TextureBase::ClearValue::Zero && mKind == Kind::Normal) {
        SetIsSubresourceContentInitialized(true, range);
        GetDevice()->IncrementLazyClearCountForTesting();
    }

    return {};
}

MaybeError Texture::ClearRenderable(const ScopedCommandRecordingContext* commandContext,
                                    const SubresourceRange& range,
                                    TextureBase::ClearValue clearValue,
                                    const D3D11ClearValue& d3d11ClearValue) {
    UINT clearFlags = 0;
    if (GetFormat().HasDepth() && range.aspects & Aspect::Depth) {
        clearFlags |= D3D11_CLEAR_DEPTH;
    }
    if (GetFormat().HasStencil() && range.aspects & Aspect::Stencil) {
        clearFlags |= D3D11_CLEAR_STENCIL;
    }

    SubresourceRange clearRange;
    clearRange.aspects = range.aspects;
    clearRange.layerCount = 1u;
    clearRange.levelCount = 1u;
    for (clearRange.baseArrayLayer = range.baseArrayLayer;
         clearRange.baseArrayLayer < range.baseArrayLayer + range.layerCount;
         ++clearRange.baseArrayLayer) {
        for (clearRange.baseMipLevel = range.baseMipLevel;
             clearRange.baseMipLevel < range.baseMipLevel + range.levelCount;
             ++clearRange.baseMipLevel) {
            if (clearValue == TextureBase::ClearValue::Zero &&
                IsSubresourceContentInitialized(clearRange)) {
                // Skip lazy clears if already initialized.
                continue;
            }
            if (GetFormat().HasDepthOrStencil()) {
                ComPtr<ID3D11DepthStencilView> d3d11DSV;
                DAWN_TRY_ASSIGN(d3d11DSV, CreateD3D11DepthStencilView(clearRange,
                                                                      /*depthReadOnly=*/false,
                                                                      /*stencilReadOnly=*/false));
                commandContext->ClearDepthStencilView(
                    d3d11DSV.Get(), clearFlags, d3d11ClearValue.depth, d3d11ClearValue.stencil);
            } else {
                for (auto aspect : IterateEnumMask(clearRange.aspects)) {
                    wgpu::TextureFormat format = GetFormat().IsMultiPlanar()
                                                     ? GetFormat().GetAspectInfo(aspect).format
                                                     : GetFormat().format;
                    ComPtr<ID3D11RenderTargetView> d3d11RTV;
                    // For the subresources of 3d textures, clearRange.baseArrayLayer must be 0 and
                    // clearRange.layerCount must be 1, the sliceCount is the depthOrArrayLayers of
                    // the subresource virtual size, which must be 1 for 2d textures. When clearing
                    // RTV, we can use the 'layer' as baseSlice and the 'depthOrArrayLayers' as
                    // sliceCount to create RTV without checking the dimension.
                    DAWN_TRY_ASSIGN(d3d11RTV,
                                    CreateD3D11RenderTargetView(
                                        format, clearRange.baseMipLevel, clearRange.baseArrayLayer,
                                        GetMipLevelSingleSubresourceVirtualSize(
                                            clearRange.baseMipLevel, clearRange.aspects)
                                            .depthOrArrayLayers,
                                        GetAspectIndex(aspect)));
                    commandContext->ClearRenderTargetView(d3d11RTV.Get(), d3d11ClearValue.color);
                }
            }
        }
    }

    return {};
}

MaybeError Texture::ClearNonRenderable(const ScopedCommandRecordingContext* commandContext,
                                       const SubresourceRange& range,
                                       TextureBase::ClearValue clearValue) {
    const TexelBlockInfo& blockInfo = GetFormat().GetAspectInfo(range.aspects).block;
    // TODO(dawn:1705): Use interim texture clear-and-copy as compressed textures do to
    // avoid CPU-to-GPU write.
    for (Aspect aspect : IterateEnumMask(range.aspects)) {
        Extent3D writeSize = GetMipLevelSubresourceVirtualSize(range.baseMipLevel, aspect);
        uint32_t bytesPerRow = blockInfo.byteSize * writeSize.width;

        uint32_t rowsPerImage = writeSize.height;
        uint64_t byteLength;
        // TODO(crbug.com/424536624): Call non-validating overload of ComputeRequiredBytesInCopy
        DAWN_TRY_ASSIGN(byteLength, ComputeRequiredBytesInCopy(blockInfo, writeSize, bytesPerRow,
                                                               rowsPerImage));

        std::vector<uint8_t> clearData(byteLength, clearValue == ClearValue::Zero ? 0 : 1);
        SubresourceRange writeRange = range;
        writeRange.layerCount = 1;
        writeRange.levelCount = 1;
        for (uint32_t layer = range.baseArrayLayer; layer < range.baseArrayLayer + range.layerCount;
             ++layer) {
            for (uint32_t level = range.baseMipLevel; level < range.baseMipLevel + range.levelCount;
                 ++level) {
                if (clearValue == TextureBase::ClearValue::Zero &&
                    IsSubresourceContentInitialized(
                        SubresourceRange::SingleMipAndLayer(level, layer, aspect))) {
                    // Skip lazy clears if already initialized.
                    continue;
                }
                writeRange.baseArrayLayer = layer;
                writeRange.baseMipLevel = level;
                writeSize = GetMipLevelSubresourceVirtualSize(level, aspect);
                bytesPerRow = blockInfo.byteSize * writeSize.width;
                rowsPerImage = writeSize.height;
                DAWN_TRY(WriteInternal(commandContext, writeRange, {0, 0, 0}, writeSize,
                                       clearData.data(), bytesPerRow, rowsPerImage));
            }
        }
    }

    return {};
}

MaybeError Texture::ClearCompressed(const ScopedCommandRecordingContext* commandContext,
                                    const SubresourceRange& range,
                                    TextureBase::ClearValue clearValue) {
    DAWN_ASSERT(range.aspects == Aspect::Color);
    const TexelBlockInfo& blockInfo = GetFormat().GetAspectInfo(range.aspects).block;
    // Create an interim texture of renderable format for reinterpretation conversion.
    TextureDescriptor desc = {};
    desc.label = "CopyUncompressedTextureToCompressedTexureInterim";
    desc.dimension = GetDimension();
    DAWN_ASSERT(desc.dimension == wgpu::TextureDimension::e2D);
    desc.size = {GetWidth(Aspect::Color), GetHeight(Aspect::Color), 1};
    desc.format = UncompressedTextureFormat(GetFormat().format);
    desc.mipLevelCount = 1;
    desc.sampleCount = 1;

    Ref<Texture> interimTexture;
    DAWN_TRY_ASSIGN(interimTexture,
                    CreateInternal(ToBackend(GetDevice()), Unpack(&desc), Kind::Interim));

    float color = 0.0f;
    if (clearValue == ClearValue::NonZero) {
        // Ensure value 1 per byte rather than per component. This is required in this test case:
        // https://source.chromium.org/chromium/chromium/src/+/refs/heads/main:third_party/dawn/src/dawn/tests/end2end/NonzeroTextureCreationTests.cpp;drc=7a6604d0564b56cce77b72ae759b3773a756423c;l=244
        double valueOnePerByte;
        switch (desc.format) {
            case wgpu::TextureFormat::RGBA16Uint:
                valueOnePerByte = 0x0101;
                break;
            case wgpu::TextureFormat::RGBA32Uint:
                valueOnePerByte = 0x01010101;
                break;
            default:
                DAWN_UNREACHABLE();
        }
        color = valueOnePerByte;
    }
    float depth = clearValue == ClearValue::Zero ? 0.0f : 1.0f;
    uint8_t stencil = clearValue == ClearValue::Zero ? 0u : 1u;
    D3D11ClearValue d3d11ClearValue = {{color, color, color, color}, depth, stencil};
    DAWN_TRY(interimTexture->ClearRenderable(commandContext,
                                             SubresourceRange::MakeFull(Aspect::Color, 1, 1),
                                             clearValue, d3d11ClearValue));

    D3D11_BOX srcBox;
    srcBox.left = 0;
    srcBox.top = 0;
    srcBox.front = 0;
    srcBox.back = 1;
    uint32_t srcSubresource = interimTexture->GetSubresourceIndex(0, 0, Aspect::Color);
    // Copy from the interim texture to the dest texture.
    for (uint32_t layer = range.baseArrayLayer; layer < range.baseArrayLayer + range.layerCount;
         ++layer) {
        for (uint32_t level = range.baseMipLevel; level < range.baseMipLevel + range.levelCount;
             ++level) {
            if (clearValue == TextureBase::ClearValue::Zero &&
                IsSubresourceContentInitialized(
                    SubresourceRange::SingleMipAndLayer(level, layer, range.aspects))) {
                // Skip lazy clears if already initialized.
                continue;
            }
            uint32_t dstSubresource = GetSubresourceIndex(level, layer, Aspect::Color);
            auto physicalSize = GetMipLevelSingleSubresourcePhysicalSize(level, Aspect::Color);
            // The documentation says D3D11_BOX's coordinates should be in texels for
            // textures. However the validation layer seemingly assumes them to be in
            // blocks. Otherwise it would complain like this:
            //     ID3D11DeviceContext::CopySubresourceRegion: When offset by the
            //     destination coordinates and converted to block dimensions, pSrcBox does
            //     not fit on the destination subresource. OffsetSrcBox = { left:0, top:0,
            //     front:0, right:128, bottom:128, back:1 } (in blocks). DstSubresource = {
            //     left:0, top:0, front:0, right:32, bottom:32, back:1 } (in blocks). [
            //     RESOURCE_MANIPULATION ERROR #280:COPYSUBRESOURCEREGION_INVALIDSOURCEBOX]
            srcBox.right = physicalSize.width / blockInfo.width;
            srcBox.bottom = physicalSize.height / blockInfo.height;
            commandContext->CopySubresourceRegion(GetD3D11Resource(), dstSubresource, 0, 0, 0,
                                                  interimTexture->GetD3D11Resource(),
                                                  srcSubresource, &srcBox);
        }
    }

    return {};
}

void Texture::SetLabelHelper(const char* prefix) {
    SetDebugName(ToBackend(GetDevice()), mD3d11Resource.Get(), prefix, GetLabel());
}

void Texture::SetLabelImpl() {
    SetLabelHelper("Dawn_InternalTexture");
}

MaybeError Texture::EnsureSubresourceContentInitialized(
    const ScopedCommandRecordingContext* commandContext,
    const SubresourceRange& range) {
    if (!ToBackend(GetDevice())->IsToggleEnabled(Toggle::LazyClearResourceOnFirstUse)) {
        return {};
    }
    if (!IsSubresourceContentInitialized(range)) {
        // If subresource has not been initialized, clear it to black as it could contain
        // dirty bits from recycled memory
        DAWN_TRY(Clear(commandContext, range, TextureBase::ClearValue::Zero));
    }
    return {};
}

MaybeError Texture::Write(const ScopedCommandRecordingContext* commandContext,
                          const SubresourceRange& subresources,
                          const Origin3D& origin,
                          const Extent3D& size,
                          const uint8_t* data,
                          uint32_t bytesPerRow,
                          uint32_t rowsPerImage) {
    if (IsCompleteSubresourceCopiedTo(this, size, subresources.baseMipLevel,
                                      subresources.aspects)) {
        SetIsSubresourceContentInitialized(true, subresources);
    } else {
        // Dawn validation should have ensured that full subresources write for depth/stencil
        // textures.
        DAWN_ASSERT(!GetFormat().HasDepthOrStencil());
        DAWN_TRY(EnsureSubresourceContentInitialized(commandContext, subresources));
    }
    DAWN_TRY(
        WriteInternal(commandContext, subresources, origin, size, data, bytesPerRow, rowsPerImage));

    return {};
}

MaybeError Texture::WriteInternal(const ScopedCommandRecordingContext* commandContext,
                                  const SubresourceRange& subresources,
                                  const Origin3D& origin,
                                  const Extent3D& size,
                                  const uint8_t* data,
                                  uint32_t bytesPerRow,
                                  uint32_t rowsPerImage) {
    DAWN_ASSERT(size.width != 0 && size.height != 0 && size.depthOrArrayLayers != 0);
    DAWN_ASSERT(subresources.levelCount == 1);

    if (d3d::IsDepthStencil(d3d::DXGITextureFormat(GetDevice(), GetFormat().format))) {
        DAWN_TRY(WriteDepthStencilInternal(commandContext, subresources, origin, size, data,
                                           bytesPerRow, rowsPerImage));
        return {};
    }

    D3D11_BOX dstBox;
    dstBox.left = origin.x;
    dstBox.right = origin.x + size.width;
    dstBox.top = origin.y;
    dstBox.bottom = origin.y + size.height;

    bool isCompleteSubresourceCopiedTo =
        IsCompleteSubresourceCopiedTo(this, size, subresources.baseMipLevel, subresources.aspects);
    DAWN_ASSERT(subresources.levelCount == 1);
    bool writeCompleteTexture = isCompleteSubresourceCopiedTo && GetNumMipLevels() == 1 &&
                                GetArrayLayers() == subresources.layerCount;

    if (GetDimension() == wgpu::TextureDimension::e3D) {
        dstBox.front = origin.z;
        dstBox.back = origin.z + size.depthOrArrayLayers;
        uint32_t subresource =
            GetSubresourceIndex(subresources.baseMipLevel, 0, D3D11Aspect(subresources.aspects));
        UINT copyFlag = writeCompleteTexture ? D3D11_COPY_DISCARD : 0;
        commandContext->UpdateSubresource1(GetD3D11Resource(), subresource, &dstBox, data,
                                           bytesPerRow, bytesPerRow * rowsPerImage, copyFlag);
    } else {
        dstBox.front = 0;
        dstBox.back = 1;
        for (uint32_t layer = 0; layer < subresources.layerCount; ++layer) {
            uint32_t subresource =
                GetSubresourceIndex(subresources.baseMipLevel, subresources.baseArrayLayer + layer,
                                    D3D11Aspect(subresources.aspects));
            D3D11_BOX* pDstBox = GetFormat().HasDepthOrStencil() ? nullptr : &dstBox;
            UINT copyFlag = (writeCompleteTexture && layer == 0) ? D3D11_COPY_DISCARD : 0;
            commandContext->UpdateSubresource1(GetD3D11Resource(), subresource, pDstBox, data,
                                               bytesPerRow, 0, copyFlag);
            data += rowsPerImage * bytesPerRow;
        }
    }

    return {};
}

MaybeError Texture::WriteDepthStencilInternal(const ScopedCommandRecordingContext* commandContext,
                                              const SubresourceRange& subresources,
                                              const Origin3D& origin,
                                              const Extent3D& size,
                                              const uint8_t* data,
                                              uint32_t bytesPerRow,
                                              uint32_t rowsPerImage) {
    TextureDescriptor desc = {};
    desc.label = "WriteStencilTextureStaging";
    desc.dimension = GetDimension();
    desc.size = size;
    desc.format = GetFormat().format;
    desc.mipLevelCount = 1;
    desc.sampleCount = GetSampleCount();

    Ref<Texture> stagingTexture;
    DAWN_TRY_ASSIGN(stagingTexture,
                    CreateInternal(ToBackend(GetDevice()), Unpack(&desc), Kind::Staging));

    // Depth-stencil subresources can only be written to completely and not partially.
    DAWN_ASSERT(
        IsCompleteSubresourceCopiedTo(this, size, subresources.baseMipLevel, subresources.aspects));

    SubresourceRange otherRange = subresources;
    Aspect otherAspects = GetFormat().aspects & ~subresources.aspects;
    DAWN_ASSERT(HasZeroOrOneBits(otherAspects));
    otherRange.aspects = otherAspects;
    // We need to copy the texture over if the other aspect is present and initialized so that it is
    // preserved during the write.
    bool shouldCopyExistingDataFirst =
        HasOneBit(otherAspects) && IsSubresourceContentInitialized(otherRange);

    if (shouldCopyExistingDataFirst) {
        // Copy the dest texture to a staging texture.
        CopyTextureToTextureCmd copyCmd;
        copyCmd.source.texture = this;
        copyCmd.source.origin = origin;
        copyCmd.source.mipLevel = subresources.baseMipLevel;
        copyCmd.source.aspect = otherAspects;
        copyCmd.destination.texture = stagingTexture.Get();
        copyCmd.destination.origin = {TexelCount{0}, TexelCount{0}, TexelCount{0}};
        copyCmd.destination.mipLevel = 0;
        copyCmd.destination.aspect = otherAspects;
        copyCmd.copySize = size;
        DAWN_TRY(Texture::CopyInternal(commandContext, &copyCmd));
    }

    const auto aspectLayout = DepthStencilAspectLayout(
        d3d::DXGITextureFormat(GetDevice(), GetFormat().format), subresources.aspects);

    // Map and write to the staging texture.
    D3D11_MAPPED_SUBRESOURCE mappedResource;
    const uint8_t* pSrcData = data;
    for (uint32_t layer = 0; layer < size.depthOrArrayLayers; ++layer) {
        DAWN_TRY(CheckHRESULT(commandContext->Map(stagingTexture->GetD3D11Resource(), layer,
                                                  D3D11_MAP_READ, 0, &mappedResource),
                              "D3D11 map staging texture"));
        uint8_t* pDstData = static_cast<uint8_t*>(mappedResource.pData);
        for (uint32_t y = 0; y < size.height; ++y) {
            const uint8_t* pSrcRow = pSrcData;
            uint8_t* pDstRow = pDstData;
            pDstRow += aspectLayout.componentOffset;
            for (uint32_t x = 0; x < size.width; ++x) {
                std::memcpy(pDstRow, pSrcRow, aspectLayout.componentSize);
                pDstRow += aspectLayout.texelSize;
                pSrcRow += aspectLayout.componentSize;
            }
            pDstData += mappedResource.RowPitch;
            pSrcData += bytesPerRow;
        }
        commandContext->Unmap(stagingTexture->GetD3D11Resource(), layer);
        DAWN_ASSERT(size.height <= rowsPerImage);
        // Skip the padding rows.
        pSrcData += (rowsPerImage - size.height) * bytesPerRow;
    }

    // Copy to the dest texture from the staging texture.
    CopyTextureToTextureCmd copyCmd;
    copyCmd.source.texture = stagingTexture.Get();
    copyCmd.source.origin = {TexelCount{0}, TexelCount{0}, TexelCount{0}};
    copyCmd.source.mipLevel = 0;
    copyCmd.source.aspect = GetFormat().aspects;
    copyCmd.destination.texture = this;
    copyCmd.destination.origin = origin;
    copyCmd.destination.mipLevel = subresources.baseMipLevel;
    copyCmd.destination.aspect = GetFormat().aspects;
    copyCmd.copySize = size;
    DAWN_TRY(Texture::CopyInternal(commandContext, &copyCmd));

    return {};
}

MaybeError Texture::ReadStaging(const ScopedCommandRecordingContext* commandContext,
                                const SubresourceRange& subresources,
                                const Origin3D& origin,
                                Extent3D size,
                                uint32_t dstBytesPerRow,
                                uint32_t dstRowsPerImage,
                                Texture::ReadCallback callback) {
    DAWN_ASSERT(size.width != 0 && size.height != 0 && size.depthOrArrayLayers != 0);
    DAWN_ASSERT(mKind == Kind::Staging);
    DAWN_ASSERT(subresources.baseArrayLayer == 0);
    DAWN_ASSERT(origin.z == 0);

    const TexelBlockInfo& blockInfo = GetFormat().GetAspectInfo(subresources.aspects).block;
    const bool hasStencil = GetFormat().HasStencil();
    DAWN_ASSERT(size.width % blockInfo.width == 0);
    DAWN_ASSERT(size.height % blockInfo.height == 0);
    const uint32_t bytesPerRow = blockInfo.byteSize * (size.width / blockInfo.width);
    const uint32_t rowsPerImage = size.height / blockInfo.height;

    if (GetDimension() == wgpu::TextureDimension::e2D) {
        for (uint32_t layer = 0; layer < subresources.layerCount; ++layer) {
            // Copy the staging texture to the buffer.
            // The Map() will block until the GPU is done with the texture.
            // TODO(dawn:1705): avoid blocking the CPU.
            D3D11_MAPPED_SUBRESOURCE mappedResource;
            DAWN_TRY(CheckHRESULT(
                commandContext->Map(GetD3D11Resource(), layer, D3D11_MAP_READ, 0, &mappedResource),
                "D3D11 map staging texture"));

            uint8_t* pSrcData = static_cast<uint8_t*>(mappedResource.pData);
            uint64_t dstOffset = dstBytesPerRow * dstRowsPerImage * layer;
            if (dstBytesPerRow == bytesPerRow && mappedResource.RowPitch == bytesPerRow) {
                // If there is no padding in the rows, we can upload the whole image
                // in one read.
                DAWN_TRY(callback(pSrcData, dstOffset, dstBytesPerRow * rowsPerImage));
            } else if (hasStencil) {
                // We need to read texel by texel for depth-stencil formats.
                std::vector<uint8_t> depthOrStencilData(size.width * blockInfo.byteSize);
                const auto aspectLayout = DepthStencilAspectLayout(
                    d3d::DXGITextureFormat(GetDevice(), GetFormat().format), subresources.aspects);
                DAWN_ASSERT(blockInfo.byteSize == aspectLayout.componentSize);
                for (uint32_t y = 0; y < rowsPerImage; ++y) {
                    // Filter the depth/stencil data out.
                    uint8_t* src = pSrcData;
                    uint8_t* dst = depthOrStencilData.data();
                    src += aspectLayout.componentOffset;
                    for (uint32_t x = 0; x < size.width; ++x) {
                        std::memcpy(dst, src, aspectLayout.componentSize);
                        src += aspectLayout.texelSize;
                        dst += aspectLayout.componentSize;
                    }
                    DAWN_TRY(callback(depthOrStencilData.data(), dstOffset, bytesPerRow));
                    dstOffset += dstBytesPerRow;
                    pSrcData += mappedResource.RowPitch;
                }
            } else {
                // Otherwise, we need to read each row separately.
                for (uint32_t y = 0; y < rowsPerImage; ++y) {
                    DAWN_TRY(callback(pSrcData, dstOffset, bytesPerRow));
                    dstOffset += dstBytesPerRow;
                    pSrcData += mappedResource.RowPitch;
                }
            }
            commandContext->Unmap(GetD3D11Resource(), layer);
        }
        return {};
    }

    // 3D textures are copied one slice at a time.
    // Copy the staging texture to the buffer.
    // The Map() will block until the GPU is done with the texture.
    // TODO(dawn:1705): avoid blocking the CPU.
    D3D11_MAPPED_SUBRESOURCE mappedResource;
    DAWN_TRY(
        CheckHRESULT(commandContext->Map(GetD3D11Resource(), 0, D3D11_MAP_READ, 0, &mappedResource),
                     "D3D11 map staging texture"));

    for (uint32_t z = 0; z < size.depthOrArrayLayers; ++z) {
        uint64_t dstOffset = dstBytesPerRow * dstRowsPerImage * z;
        uint8_t* pSrcData =
            static_cast<uint8_t*>(mappedResource.pData) + z * mappedResource.DepthPitch;
        if (dstBytesPerRow == bytesPerRow && mappedResource.RowPitch == bytesPerRow) {
            // If there is no padding in the rows, we can upload the whole image
            // in one read.
            DAWN_TRY(callback(pSrcData, dstOffset, bytesPerRow * size.height));
        } else {
            // Otherwise, we need to read each row separately.
            for (uint32_t y = 0; y < size.height; ++y) {
                DAWN_TRY(callback(pSrcData, dstOffset, bytesPerRow));
                dstOffset += dstBytesPerRow;
                pSrcData += mappedResource.RowPitch;
            }
        }
    }
    commandContext->Unmap(GetD3D11Resource(), 0);

    return {};
}

MaybeError Texture::Read(const ScopedCommandRecordingContext* commandContext,
                         const SubresourceRange& subresources,
                         const Origin3D& origin,
                         Extent3D size,
                         uint32_t dstBytesPerRow,
                         uint32_t dstRowsPerImage,
                         Texture::ReadCallback callback) {
    DAWN_ASSERT(size.width != 0 && size.height != 0 && size.depthOrArrayLayers != 0);
    DAWN_ASSERT(mKind != Kind::Staging);

    DAWN_TRY(EnsureSubresourceContentInitialized(commandContext, subresources));
    TextureDescriptor desc = {};
    desc.label = "CopyTextureToBufferStaging";
    desc.dimension = GetDimension();
    desc.size = size;
    desc.format = GetFormat().format;
    desc.mipLevelCount = subresources.levelCount;
    desc.sampleCount = GetSampleCount();

    Ref<Texture> stagingTexture;
    DAWN_TRY_ASSIGN(stagingTexture,
                    CreateInternal(ToBackend(GetDevice()), Unpack(&desc), Kind::Staging));

    CopyTextureToTextureCmd copyCmd;
    copyCmd.source.texture = this;
    copyCmd.source.origin = origin;
    copyCmd.source.mipLevel = subresources.baseMipLevel;
    copyCmd.source.aspect = subresources.aspects;
    copyCmd.destination.texture = stagingTexture.Get();
    copyCmd.destination.origin = {TexelCount{0}, TexelCount{0}, TexelCount{0}};
    copyCmd.destination.mipLevel = 0;
    copyCmd.destination.aspect = subresources.aspects;
    copyCmd.copySize = size;

    DAWN_TRY(Texture::Copy(commandContext, &copyCmd));
    SubresourceRange stagingSubresources = SubresourceRange::MakeFull(
        subresources.aspects, subresources.layerCount, subresources.levelCount);

    return stagingTexture->ReadStaging(commandContext, stagingSubresources, {0, 0, 0}, size,
                                       dstBytesPerRow, dstRowsPerImage, callback);
}

// static
MaybeError Texture::Copy(const ScopedCommandRecordingContext* commandContext,
                         CopyTextureToTextureCmd* copy) {
    DAWN_ASSERT(!copy->copySize.IsEmpty());

    auto& src = copy->source;
    auto& dst = copy->destination;

    DAWN_ASSERT(src.aspect == dst.aspect);

    // TODO(dawn:1705): support copy between textures with different dimensions.
    if (src.texture->GetDimension() != dst.texture->GetDimension()) {
        return DAWN_UNIMPLEMENTED_ERROR("Copy between textures with different dimensions");
    }

    SubresourceRange srcSubresources = GetSubresourcesAffectedByCopy(src, copy->copySize);
    DAWN_TRY(ToBackend(src.texture)
                 ->EnsureSubresourceContentInitialized(commandContext, srcSubresources));

    SubresourceRange dstSubresources = GetSubresourcesAffectedByCopy(dst, copy->copySize);
    if (IsCompleteSubresourceCopiedTo(dst.texture.Get(), copy->copySize, dst.mipLevel,
                                      dst.aspect)) {
        dst.texture->SetIsSubresourceContentInitialized(true, dstSubresources);
    } else {
        // Partial update subresource of a depth/stencil texture is not allowed.
        DAWN_ASSERT(!dst.texture->GetFormat().HasDepthOrStencil());
        DAWN_TRY(ToBackend(dst.texture)
                     ->EnsureSubresourceContentInitialized(commandContext, dstSubresources));
    }

    DAWN_TRY(CopyInternal(commandContext, copy));

    return {};
}

// static
MaybeError Texture::CopyInternal(const ScopedCommandRecordingContext* commandContext,
                                 CopyTextureToTextureCmd* copy) {
    auto& src = copy->source;
    auto& dst = copy->destination;

    SubresourceRange srcSubresources = GetSubresourcesAffectedByCopy(src, copy->copySize);
    SubresourceRange dstSubresources = GetSubresourcesAffectedByCopy(dst, copy->copySize);

    D3D11_BOX srcBox;
    srcBox.left = static_cast<uint32_t>(src.origin.x);
    srcBox.right = static_cast<uint32_t>(src.origin.x + copy->copySize.width);
    srcBox.top = static_cast<uint32_t>(src.origin.y);
    srcBox.bottom = static_cast<uint32_t>(src.origin.y + copy->copySize.height);
    switch (src.texture->GetDimension()) {
        case wgpu::TextureDimension::Undefined:
            DAWN_UNREACHABLE();
        case wgpu::TextureDimension::e1D:
        case wgpu::TextureDimension::e2D:
            srcBox.front = 0;
            srcBox.back = 1;
            break;
        case wgpu::TextureDimension::e3D:
            srcBox.front = static_cast<uint32_t>(src.origin.z);
            srcBox.back = static_cast<uint32_t>(src.origin.z + copy->copySize.depthOrArrayLayers);
            break;
    }

    bool isWholeSubresource =
        src.texture->CoversFullSubresource(src.mipLevel, src.aspect, copy->copySize) &&
        dst.texture->CoversFullSubresource(dst.mipLevel, dst.aspect, copy->copySize);
    // Partial update subresource of a depth/stencil texture is not allowed.
    DAWN_ASSERT(isWholeSubresource || !src.texture->GetFormat().HasDepthOrStencil());

    for (uint32_t layer = 0; layer < srcSubresources.layerCount; ++layer) {
        uint32_t srcSubresource =
            src.texture->GetSubresourceIndex(src.mipLevel, srcSubresources.baseArrayLayer + layer,
                                             D3D11Aspect(srcSubresources.aspects));
        uint32_t dstSubresource =
            dst.texture->GetSubresourceIndex(dst.mipLevel, dstSubresources.baseArrayLayer + layer,
                                             D3D11Aspect(dstSubresources.aspects));
        commandContext->CopySubresourceRegion(
            ToBackend(dst.texture)->GetD3D11Resource(), dstSubresource,
            static_cast<uint32_t>(dst.origin.x), static_cast<uint32_t>(dst.origin.y),
            dst.texture->GetDimension() == wgpu::TextureDimension::e3D
                ? static_cast<uint32_t>(dst.origin.z)
                : 0,
            ToBackend(src.texture)->GetD3D11Resource(), srcSubresource,
            isWholeSubresource ? nullptr : &srcBox);
    }

    return {};
}

ResultOrError<ComPtr<ID3D11ShaderResourceView>> Texture::GetStencilSRV(
    const ScopedCommandRecordingContext* commandContext,
    const TextureView* view) {
    DAWN_ASSERT(GetFormat().HasStencil());

    if (!mTextureForStencilSampling.Get()) {
        // Create an interim texture of R8Uint format.
        TextureDescriptor desc = {};
        desc.label = "InterimStencilTexture";
        desc.dimension = GetDimension();
        desc.size = GetSize(Aspect::Stencil);
        desc.format = wgpu::TextureFormat::R8Uint;
        desc.mipLevelCount = GetNumMipLevels();
        desc.sampleCount = GetSampleCount();
        desc.usage = wgpu::TextureUsage::TextureBinding;

        DAWN_TRY_ASSIGN(mTextureForStencilSampling,
                        CreateInternal(ToBackend(GetDevice()), Unpack(&desc), Kind::Interim));
    }

    // Sync the stencil data of this texture to the interim stencil-view texture.
    // TODO(dawn:1705): Improve to only sync as few as possible.
    const auto range = view->GetSubresourceRange();
    const TexelBlockInfo& blockInfo = GetFormat().GetAspectInfo(range.aspects).block;
    Extent3D size = GetMipLevelSubresourceVirtualSize(range.baseMipLevel, range.aspects);
    uint32_t bytesPerRow = blockInfo.byteSize * size.width;
    uint32_t rowsPerImage = size.height;
    uint64_t byteLength;
    // TODO(crbug.com/424536624): Call non-validating overload of ComputeRequiredBytesInCopy
    DAWN_TRY_ASSIGN(byteLength,
                    ComputeRequiredBytesInCopy(blockInfo, size, bytesPerRow, rowsPerImage));

    std::vector<uint8_t> stagingData(byteLength);
    for (uint32_t level = range.baseMipLevel; level < range.baseMipLevel + range.levelCount;
         ++level) {
        size = GetMipLevelSubresourceVirtualSize(level, range.aspects);
        bytesPerRow = blockInfo.byteSize * size.width;
        rowsPerImage = size.height;
        auto singleRange = SubresourceRange(range.aspects, {0, range.layerCount}, {level, 1});

        Texture::ReadCallback callback = [&](const uint8_t* data, uint64_t offset,
                                             uint64_t length) -> MaybeError {
            std::memcpy(static_cast<uint8_t*>(stagingData.data()) + offset, data, length);
            return {};
        };

        // TODO(383779503): Work out a way of GPU-GPU copy, rather than the CPU-GPU round trip.
        GetDevice()->EmitWarningOnce("Sampling the stencil component is rather slow now.");
        DAWN_TRY(Read(commandContext, singleRange, {0, 0, 0}, size, bytesPerRow, rowsPerImage,
                      callback));

        DAWN_TRY(mTextureForStencilSampling->WriteInternal(commandContext, singleRange, {0, 0, 0},
                                                           size, stagingData.data(), bytesPerRow,
                                                           rowsPerImage));
    }

    Ref<TextureViewBase> textureView;
    TextureViewDescriptor viewDesc = {};
    viewDesc.label = "InterimStencilTextureView";
    viewDesc.format = wgpu::TextureFormat::R8Uint;
    viewDesc.dimension = view->GetDimension();
    viewDesc.baseArrayLayer = view->GetBaseArrayLayer();
    viewDesc.arrayLayerCount = view->GetLayerCount();
    viewDesc.baseMipLevel = view->GetBaseMipLevel();
    viewDesc.mipLevelCount = view->GetLevelCount();
    DAWN_TRY_ASSIGN(textureView, mTextureForStencilSampling->CreateView(&viewDesc));

    ComPtr<ID3D11ShaderResourceView> srv;
    DAWN_TRY_ASSIGN(srv, ToBackend(textureView)->GetOrCreateD3D11ShaderResourceView());
    return srv;
}

ResultOrError<ComPtr<ID3D11ShaderResourceView1>> Texture::CreateD3D11ShaderResourceView(
    wgpu::TextureViewDimension viewDimension,
    wgpu::TextureFormat viewFormat,
    Aspect aspects,
    uint32_t mipLevel,
    uint32_t levelCount,
    uint32_t baseSlice,
    uint32_t sliceCount) {
    D3D11_SHADER_RESOURCE_VIEW_DESC1 srvDesc;
    srvDesc.Format = d3d::D3DShaderResourceViewFormat(
        GetDevice(), GetFormat(), GetDevice()->GetValidInternalFormat(viewFormat), aspects);

    // Currently we always use D3D11_TEX2D_ARRAY_SRV because we cannot specify base array
    // layer and layer count in D3D11_TEX2D_SRV. For 2D texture views, we treat them as
    // 1-layer 2D array textures. Multisampled textures may only be one array layer, so we
    // use D3D11_SRV_DIMENSION_TEXTURE2DMS.
    // https://docs.microsoft.com/en-us/windows/desktop/api/d3d11/ns-d3d11-d3d11_tex2d_srv
    // https://docs.microsoft.com/en-us/windows/desktop/api/d3d11/ns-d3d11-d3d11_tex2d_array_srv
    if (IsMultisampledTexture()) {
        switch (viewDimension) {
            case wgpu::TextureViewDimension::e2DArray:
                DAWN_ASSERT(GetArrayLayers() == 1);
                [[fallthrough]];
            case wgpu::TextureViewDimension::e2D:
                DAWN_ASSERT(GetDimension() == wgpu::TextureDimension::e2D);
                srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DMS;
                break;

            default:
                DAWN_UNREACHABLE();
        }
    } else {
        switch (viewDimension) {
            case wgpu::TextureViewDimension::e1D:
                srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1D;
                srvDesc.Texture1D.MipLevels = levelCount;
                srvDesc.Texture1D.MostDetailedMip = mipLevel;
                break;

            case wgpu::TextureViewDimension::e2D:
            case wgpu::TextureViewDimension::e2DArray:
                DAWN_ASSERT(GetDimension() == wgpu::TextureDimension::e2D);
                srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY;
                srvDesc.Texture2DArray.ArraySize = sliceCount;
                srvDesc.Texture2DArray.FirstArraySlice = baseSlice;
                srvDesc.Texture2DArray.MipLevels = levelCount;
                srvDesc.Texture2DArray.MostDetailedMip = mipLevel;
                srvDesc.Texture2DArray.PlaneSlice = GetAspectIndex(aspects);
                break;
            case wgpu::TextureViewDimension::Cube:
            case wgpu::TextureViewDimension::CubeArray:
                DAWN_ASSERT(GetDimension() == wgpu::TextureDimension::e2D);
                DAWN_ASSERT(sliceCount % 6 == 0);
                srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBEARRAY;
                srvDesc.TextureCubeArray.First2DArrayFace = baseSlice;
                srvDesc.TextureCubeArray.NumCubes = sliceCount / 6;
                srvDesc.TextureCubeArray.MipLevels = levelCount;
                srvDesc.TextureCubeArray.MostDetailedMip = mipLevel;
                break;
            case wgpu::TextureViewDimension::e3D:
                DAWN_ASSERT(GetDimension() == wgpu::TextureDimension::e3D);
                srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D;
                srvDesc.Texture3D.MostDetailedMip = mipLevel;
                srvDesc.Texture3D.MipLevels = levelCount;
                break;

            case wgpu::TextureViewDimension::Undefined:
                DAWN_UNREACHABLE();
        }
    }

    ComPtr<ID3D11ShaderResourceView1> srv;
    DAWN_TRY_CONTEXT(
        CheckHRESULT(ToBackend(GetDevice())
                         ->GetD3D11Device3()
                         ->CreateShaderResourceView1(GetD3D11Resource(), &srvDesc, &srv),
                     "CreateShaderResourceView1"),
        "%s", SRVCreationStr(GetD3D11Resource(), srvDesc));

    return std::move(srv);
}

// static
Ref<TextureView> TextureView::Create(TextureBase* texture,
                                     const UnpackedPtr<TextureViewDescriptor>& descriptor) {
    return AcquireRef(new TextureView(texture, descriptor));
}

TextureView::~TextureView() = default;

void TextureView::DestroyImpl(DestroyReason reason) {
    TextureViewBase::DestroyImpl(reason);
    mD3d11SharedResourceView = nullptr;
    mD3d11RenderTargetViews.clear();
    mD3d11DepthStencilView = nullptr;
    mD3d11UnorderedAccessView = nullptr;
}

ResultOrError<ID3D11ShaderResourceView*> TextureView::GetOrCreateD3D11ShaderResourceView() {
    if (mD3d11SharedResourceView) {
        return mD3d11SharedResourceView.Get();
    }

    DAWN_TRY_ASSIGN(mD3d11SharedResourceView,
                    ToBackend(GetTexture())
                        ->CreateD3D11ShaderResourceView(
                            GetDimension(), GetFormat().format, GetAspects(), GetBaseMipLevel(),
                            GetLevelCount(), GetBaseArrayLayer(), GetLayerCount()));
    return mD3d11SharedResourceView.Get();
}

ResultOrError<ID3D11RenderTargetView*> TextureView::GetOrCreateD3D11RenderTargetView(
    uint32_t depthSlice) {
    DAWN_ASSERT(depthSlice < GetSingleSubresourceVirtualSize().depthOrArrayLayers);

    if (mD3d11RenderTargetViews.empty()) {
        mD3d11RenderTargetViews.resize(GetSingleSubresourceVirtualSize().depthOrArrayLayers);
    }

    if (mD3d11RenderTargetViews[depthSlice]) {
        return mD3d11RenderTargetViews[depthSlice].Get();
    }

    // We have validated that the depthSlice in render pass's colorAttachments must be undefined for
    // 2d RTVs, which value is set to 0. For 3d RTVs, the baseArrayLayer must be 0. So here we can
    // simply use baseArrayLayer + depthSlice to specify the slice in RTVs without checking the
    // view's dimension.
    DAWN_TRY_ASSIGN(mD3d11RenderTargetViews[depthSlice],
                    ToBackend(GetTexture())
                        ->CreateD3D11RenderTargetView(
                            GetFormat().format, GetBaseMipLevel(), GetBaseArrayLayer() + depthSlice,
                            GetLayerCount(), GetAspectIndex(GetAspects())));
    return mD3d11RenderTargetViews[depthSlice].Get();
}

ResultOrError<ID3D11DepthStencilView*> TextureView::GetOrCreateD3D11DepthStencilView(
    bool depthReadOnly,
    bool stencilReadOnly) {
    // TODO: figure out if it is necessary to cache DSV for different properties.
    if (mD3d11DepthStencilView && mD3d11DepthStencilViewDepthReadOnly == depthReadOnly &&
        mD3d11DepthStencilViewStencilReadOnly == stencilReadOnly) {
        return mD3d11DepthStencilView.Get();
    }

    mD3d11DepthStencilView.Reset();
    DAWN_TRY_ASSIGN(
        mD3d11DepthStencilView,
        ToBackend(GetTexture())
            ->CreateD3D11DepthStencilView(GetSubresourceRange(), depthReadOnly, stencilReadOnly));
    mD3d11DepthStencilViewDepthReadOnly = depthReadOnly;
    mD3d11DepthStencilViewStencilReadOnly = stencilReadOnly;
    return mD3d11DepthStencilView.Get();
}

ResultOrError<ID3D11UnorderedAccessView*> TextureView::GetOrCreateD3D11UnorderedAccessView() {
    if (mD3d11UnorderedAccessView) {
        return mD3d11UnorderedAccessView.Get();
    }

    D3D11_UNORDERED_ACCESS_VIEW_DESC uavDesc;
    uavDesc.Format = d3d::DXGITextureFormat(GetDevice(), GetFormat().format);

    DAWN_ASSERT(!GetTexture()->IsMultisampledTexture());
    switch (GetDimension()) {
        case wgpu::TextureViewDimension::e1D:
            uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE1D;
            uavDesc.Texture1D.MipSlice = GetBaseMipLevel();
            break;
        case wgpu::TextureViewDimension::e2D:
            uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2D;
            uavDesc.Texture2D.MipSlice = GetBaseMipLevel();
            break;
        case wgpu::TextureViewDimension::e2DArray:
            uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE2DARRAY;
            uavDesc.Texture2DArray.FirstArraySlice = GetBaseArrayLayer();
            uavDesc.Texture2DArray.ArraySize = GetLayerCount();
            uavDesc.Texture2DArray.MipSlice = GetBaseMipLevel();
            break;
        case wgpu::TextureViewDimension::e3D:
            uavDesc.ViewDimension = D3D11_UAV_DIMENSION_TEXTURE3D;
            uavDesc.Texture3D.FirstWSlice = 0;
            uavDesc.Texture3D.WSize =
                std::max(1u, GetSingleSubresourceVirtualSize().depthOrArrayLayers);
            uavDesc.Texture3D.MipSlice = GetBaseMipLevel();
            break;
        // Cube and Cubemap can't be used as storage texture. So there is no need to create UAV
        // descriptor for them.
        case wgpu::TextureViewDimension::Cube:
        case wgpu::TextureViewDimension::CubeArray:
        case wgpu::TextureViewDimension::Undefined:
            DAWN_UNREACHABLE();
    }

    DAWN_TRY(
        CheckHRESULT(ToBackend(GetDevice())
                         ->GetD3D11Device()
                         ->CreateUnorderedAccessView(ToBackend(GetTexture())->GetD3D11Resource(),
                                                     &uavDesc, &mD3d11UnorderedAccessView),
                     "CreateUnorderedAccessView"));

    SetDebugName(ToBackend(GetDevice()), mD3d11UnorderedAccessView.Get(), "Dawn_TextureView",
                 GetLabel());

    return mD3d11UnorderedAccessView.Get();
}

}  // namespace dawn::native::d3d11
