// Copyright 2017 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "dawn/native/d3d12/TextureD3D12.h"

#include <algorithm>
#include <utility>

#include "dawn/common/Constants.h"
#include "dawn/common/Math.h"
#include "dawn/native/DynamicUploader.h"
#include "dawn/native/EnumMaskIterator.h"
#include "dawn/native/Error.h"
#include "dawn/native/d3d12/BufferD3D12.h"
#include "dawn/native/d3d12/CommandRecordingContext.h"
#include "dawn/native/d3d12/D3D11on12Util.h"
#include "dawn/native/d3d12/D3D12Error.h"
#include "dawn/native/d3d12/DeviceD3D12.h"
#include "dawn/native/d3d12/HeapD3D12.h"
#include "dawn/native/d3d12/ResourceAllocatorManagerD3D12.h"
#include "dawn/native/d3d12/StagingBufferD3D12.h"
#include "dawn/native/d3d12/StagingDescriptorAllocatorD3D12.h"
#include "dawn/native/d3d12/TextureCopySplitter.h"
#include "dawn/native/d3d12/UtilsD3D12.h"

namespace dawn::native::d3d12 {

namespace {

D3D12_RESOURCE_STATES D3D12TextureUsage(wgpu::TextureUsage usage, const Format& format) {
    D3D12_RESOURCE_STATES resourceState = D3D12_RESOURCE_STATE_COMMON;

    if (usage & kPresentTextureUsage) {
        // The present usage is only used internally by the swapchain and is never used in
        // combination with other usages.
        ASSERT(usage == kPresentTextureUsage);
        return D3D12_RESOURCE_STATE_PRESENT;
    }

    if (usage & wgpu::TextureUsage::CopySrc) {
        resourceState |= D3D12_RESOURCE_STATE_COPY_SOURCE;
    }
    if (usage & wgpu::TextureUsage::CopyDst) {
        resourceState |= D3D12_RESOURCE_STATE_COPY_DEST;
    }
    if (usage & (wgpu::TextureUsage::TextureBinding)) {
        resourceState |= (D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE |
                          D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE);
    }
    if (usage & wgpu::TextureUsage::StorageBinding) {
        resourceState |= D3D12_RESOURCE_STATE_UNORDERED_ACCESS;
    }
    if (usage & wgpu::TextureUsage::RenderAttachment) {
        if (format.HasDepthOrStencil()) {
            resourceState |= D3D12_RESOURCE_STATE_DEPTH_WRITE;
        } else {
            resourceState |= D3D12_RESOURCE_STATE_RENDER_TARGET;
        }
    }

    if (usage & kReadOnlyRenderAttachment) {
        // There is no STENCIL_READ state. Readonly for stencil is bundled with DEPTH_READ.
        resourceState |= D3D12_RESOURCE_STATE_DEPTH_READ;
    }

    return resourceState;
}

D3D12_RESOURCE_FLAGS D3D12ResourceFlags(wgpu::TextureUsage usage,
                                        const Format& format,
                                        bool isMultisampledTexture) {
    D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE;

    if (usage & wgpu::TextureUsage::StorageBinding) {
        flags |= D3D12_RESOURCE_FLAG_ALLOW_UNORDERED_ACCESS;
    }

    // A multisampled resource must have either D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET or
    // D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL set in D3D12_RESOURCE_DESC::Flags.
    // https://docs.microsoft.com/en-us/windows/desktop/api/d3d12/ns-d3d12-d3d12_resource_desc
    if ((usage & wgpu::TextureUsage::RenderAttachment) != 0 || isMultisampledTexture) {
        if (format.HasDepthOrStencil()) {
            flags |= D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL;
        } else {
            flags |= D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET;
        }
    }

    ASSERT(!(flags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) ||
           flags == D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL);
    return flags;
}

D3D12_RESOURCE_DIMENSION D3D12TextureDimension(wgpu::TextureDimension dimension) {
    switch (dimension) {
        case wgpu::TextureDimension::e1D:
            return D3D12_RESOURCE_DIMENSION_TEXTURE1D;
        case wgpu::TextureDimension::e2D:
            return D3D12_RESOURCE_DIMENSION_TEXTURE2D;
        case wgpu::TextureDimension::e3D:
            return D3D12_RESOURCE_DIMENSION_TEXTURE3D;
    }
}

DXGI_FORMAT D3D12TypelessTextureFormat(wgpu::TextureFormat format) {
    switch (format) {
        case wgpu::TextureFormat::R8Unorm:
        case wgpu::TextureFormat::R8Snorm:
        case wgpu::TextureFormat::R8Uint:
        case wgpu::TextureFormat::R8Sint:
            return DXGI_FORMAT_R8_TYPELESS;

        case wgpu::TextureFormat::R16Uint:
        case wgpu::TextureFormat::R16Sint:
        case wgpu::TextureFormat::R16Float:
        case wgpu::TextureFormat::Depth16Unorm:
            return DXGI_FORMAT_R16_TYPELESS;

        case wgpu::TextureFormat::RG8Unorm:
        case wgpu::TextureFormat::RG8Snorm:
        case wgpu::TextureFormat::RG8Uint:
        case wgpu::TextureFormat::RG8Sint:
            return DXGI_FORMAT_R8G8_TYPELESS;

        case wgpu::TextureFormat::R32Uint:
        case wgpu::TextureFormat::R32Sint:
        case wgpu::TextureFormat::R32Float:
            return DXGI_FORMAT_R32_TYPELESS;

        case wgpu::TextureFormat::RG16Uint:
        case wgpu::TextureFormat::RG16Sint:
        case wgpu::TextureFormat::RG16Float:
            return DXGI_FORMAT_R16G16_TYPELESS;

        case wgpu::TextureFormat::RGBA8Unorm:
        case wgpu::TextureFormat::RGBA8UnormSrgb:
        case wgpu::TextureFormat::RGBA8Snorm:
        case wgpu::TextureFormat::RGBA8Uint:
        case wgpu::TextureFormat::RGBA8Sint:
            return DXGI_FORMAT_R8G8B8A8_TYPELESS;

        case wgpu::TextureFormat::BGRA8Unorm:
        case wgpu::TextureFormat::BGRA8UnormSrgb:
            return DXGI_FORMAT_B8G8R8A8_TYPELESS;

        case wgpu::TextureFormat::RGB10A2Unorm:
            return DXGI_FORMAT_R10G10B10A2_TYPELESS;

        case wgpu::TextureFormat::RG11B10Ufloat:
            return DXGI_FORMAT_R11G11B10_FLOAT;
        case wgpu::TextureFormat::RGB9E5Ufloat:
            return DXGI_FORMAT_R9G9B9E5_SHAREDEXP;

        case wgpu::TextureFormat::RG32Uint:
        case wgpu::TextureFormat::RG32Sint:
        case wgpu::TextureFormat::RG32Float:
            return DXGI_FORMAT_R32G32_TYPELESS;

        case wgpu::TextureFormat::RGBA16Uint:
        case wgpu::TextureFormat::RGBA16Sint:
        case wgpu::TextureFormat::RGBA16Float:
            return DXGI_FORMAT_R16G16B16A16_TYPELESS;

        case wgpu::TextureFormat::RGBA32Uint:
        case wgpu::TextureFormat::RGBA32Sint:
        case wgpu::TextureFormat::RGBA32Float:
            return DXGI_FORMAT_R32G32B32A32_TYPELESS;

        case wgpu::TextureFormat::Depth32Float:
        case wgpu::TextureFormat::Depth24Plus:
            return DXGI_FORMAT_R32_TYPELESS;

        // Depth24UnormStencil8 is the smallest format supported on D3D12 that has stencil.
        case wgpu::TextureFormat::Stencil8:
        case wgpu::TextureFormat::Depth24UnormStencil8:
            return DXGI_FORMAT_R24G8_TYPELESS;
        case wgpu::TextureFormat::Depth24PlusStencil8:
        case wgpu::TextureFormat::Depth32FloatStencil8:
            return DXGI_FORMAT_R32G8X24_TYPELESS;

        case wgpu::TextureFormat::BC1RGBAUnorm:
        case wgpu::TextureFormat::BC1RGBAUnormSrgb:
            return DXGI_FORMAT_BC1_TYPELESS;

        case wgpu::TextureFormat::BC2RGBAUnorm:
        case wgpu::TextureFormat::BC2RGBAUnormSrgb:
            return DXGI_FORMAT_BC2_TYPELESS;

        case wgpu::TextureFormat::BC3RGBAUnorm:
        case wgpu::TextureFormat::BC3RGBAUnormSrgb:
            return DXGI_FORMAT_BC3_TYPELESS;

        case wgpu::TextureFormat::BC4RSnorm:
        case wgpu::TextureFormat::BC4RUnorm:
            return DXGI_FORMAT_BC4_TYPELESS;

        case wgpu::TextureFormat::BC5RGSnorm:
        case wgpu::TextureFormat::BC5RGUnorm:
            return DXGI_FORMAT_BC5_TYPELESS;

        case wgpu::TextureFormat::BC6HRGBFloat:
        case wgpu::TextureFormat::BC6HRGBUfloat:
            return DXGI_FORMAT_BC6H_TYPELESS;

        case wgpu::TextureFormat::BC7RGBAUnorm:
        case wgpu::TextureFormat::BC7RGBAUnormSrgb:
            return DXGI_FORMAT_BC7_TYPELESS;

        case wgpu::TextureFormat::ETC2RGB8Unorm:
        case wgpu::TextureFormat::ETC2RGB8UnormSrgb:
        case wgpu::TextureFormat::ETC2RGB8A1Unorm:
        case wgpu::TextureFormat::ETC2RGB8A1UnormSrgb:
        case wgpu::TextureFormat::ETC2RGBA8Unorm:
        case wgpu::TextureFormat::ETC2RGBA8UnormSrgb:
        case wgpu::TextureFormat::EACR11Unorm:
        case wgpu::TextureFormat::EACR11Snorm:
        case wgpu::TextureFormat::EACRG11Unorm:
        case wgpu::TextureFormat::EACRG11Snorm:

        case wgpu::TextureFormat::ASTC4x4Unorm:
        case wgpu::TextureFormat::ASTC4x4UnormSrgb:
        case wgpu::TextureFormat::ASTC5x4Unorm:
        case wgpu::TextureFormat::ASTC5x4UnormSrgb:
        case wgpu::TextureFormat::ASTC5x5Unorm:
        case wgpu::TextureFormat::ASTC5x5UnormSrgb:
        case wgpu::TextureFormat::ASTC6x5Unorm:
        case wgpu::TextureFormat::ASTC6x5UnormSrgb:
        case wgpu::TextureFormat::ASTC6x6Unorm:
        case wgpu::TextureFormat::ASTC6x6UnormSrgb:
        case wgpu::TextureFormat::ASTC8x5Unorm:
        case wgpu::TextureFormat::ASTC8x5UnormSrgb:
        case wgpu::TextureFormat::ASTC8x6Unorm:
        case wgpu::TextureFormat::ASTC8x6UnormSrgb:
        case wgpu::TextureFormat::ASTC8x8Unorm:
        case wgpu::TextureFormat::ASTC8x8UnormSrgb:
        case wgpu::TextureFormat::ASTC10x5Unorm:
        case wgpu::TextureFormat::ASTC10x5UnormSrgb:
        case wgpu::TextureFormat::ASTC10x6Unorm:
        case wgpu::TextureFormat::ASTC10x6UnormSrgb:
        case wgpu::TextureFormat::ASTC10x8Unorm:
        case wgpu::TextureFormat::ASTC10x8UnormSrgb:
        case wgpu::TextureFormat::ASTC10x10Unorm:
        case wgpu::TextureFormat::ASTC10x10UnormSrgb:
        case wgpu::TextureFormat::ASTC12x10Unorm:
        case wgpu::TextureFormat::ASTC12x10UnormSrgb:
        case wgpu::TextureFormat::ASTC12x12Unorm:
        case wgpu::TextureFormat::ASTC12x12UnormSrgb:

        case wgpu::TextureFormat::R8BG8Biplanar420Unorm:
        case wgpu::TextureFormat::Undefined:
            UNREACHABLE();
    }
}

}  // namespace

DXGI_FORMAT D3D12TextureFormat(wgpu::TextureFormat format) {
    switch (format) {
        case wgpu::TextureFormat::R8Unorm:
            return DXGI_FORMAT_R8_UNORM;
        case wgpu::TextureFormat::R8Snorm:
            return DXGI_FORMAT_R8_SNORM;
        case wgpu::TextureFormat::R8Uint:
            return DXGI_FORMAT_R8_UINT;
        case wgpu::TextureFormat::R8Sint:
            return DXGI_FORMAT_R8_SINT;

        case wgpu::TextureFormat::R16Uint:
            return DXGI_FORMAT_R16_UINT;
        case wgpu::TextureFormat::R16Sint:
            return DXGI_FORMAT_R16_SINT;
        case wgpu::TextureFormat::R16Float:
            return DXGI_FORMAT_R16_FLOAT;
        case wgpu::TextureFormat::RG8Unorm:
            return DXGI_FORMAT_R8G8_UNORM;
        case wgpu::TextureFormat::RG8Snorm:
            return DXGI_FORMAT_R8G8_SNORM;
        case wgpu::TextureFormat::RG8Uint:
            return DXGI_FORMAT_R8G8_UINT;
        case wgpu::TextureFormat::RG8Sint:
            return DXGI_FORMAT_R8G8_SINT;

        case wgpu::TextureFormat::R32Uint:
            return DXGI_FORMAT_R32_UINT;
        case wgpu::TextureFormat::R32Sint:
            return DXGI_FORMAT_R32_SINT;
        case wgpu::TextureFormat::R32Float:
            return DXGI_FORMAT_R32_FLOAT;
        case wgpu::TextureFormat::RG16Uint:
            return DXGI_FORMAT_R16G16_UINT;
        case wgpu::TextureFormat::RG16Sint:
            return DXGI_FORMAT_R16G16_SINT;
        case wgpu::TextureFormat::RG16Float:
            return DXGI_FORMAT_R16G16_FLOAT;
        case wgpu::TextureFormat::RGBA8Unorm:
            return DXGI_FORMAT_R8G8B8A8_UNORM;
        case wgpu::TextureFormat::RGBA8UnormSrgb:
            return DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
        case wgpu::TextureFormat::RGBA8Snorm:
            return DXGI_FORMAT_R8G8B8A8_SNORM;
        case wgpu::TextureFormat::RGBA8Uint:
            return DXGI_FORMAT_R8G8B8A8_UINT;
        case wgpu::TextureFormat::RGBA8Sint:
            return DXGI_FORMAT_R8G8B8A8_SINT;
        case wgpu::TextureFormat::BGRA8Unorm:
            return DXGI_FORMAT_B8G8R8A8_UNORM;
        case wgpu::TextureFormat::BGRA8UnormSrgb:
            return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
        case wgpu::TextureFormat::RGB10A2Unorm:
            return DXGI_FORMAT_R10G10B10A2_UNORM;
        case wgpu::TextureFormat::RG11B10Ufloat:
            return DXGI_FORMAT_R11G11B10_FLOAT;
        case wgpu::TextureFormat::RGB9E5Ufloat:
            return DXGI_FORMAT_R9G9B9E5_SHAREDEXP;

        case wgpu::TextureFormat::RG32Uint:
            return DXGI_FORMAT_R32G32_UINT;
        case wgpu::TextureFormat::RG32Sint:
            return DXGI_FORMAT_R32G32_SINT;
        case wgpu::TextureFormat::RG32Float:
            return DXGI_FORMAT_R32G32_FLOAT;
        case wgpu::TextureFormat::RGBA16Uint:
            return DXGI_FORMAT_R16G16B16A16_UINT;
        case wgpu::TextureFormat::RGBA16Sint:
            return DXGI_FORMAT_R16G16B16A16_SINT;
        case wgpu::TextureFormat::RGBA16Float:
            return DXGI_FORMAT_R16G16B16A16_FLOAT;

        case wgpu::TextureFormat::RGBA32Uint:
            return DXGI_FORMAT_R32G32B32A32_UINT;
        case wgpu::TextureFormat::RGBA32Sint:
            return DXGI_FORMAT_R32G32B32A32_SINT;
        case wgpu::TextureFormat::RGBA32Float:
            return DXGI_FORMAT_R32G32B32A32_FLOAT;

        case wgpu::TextureFormat::Depth16Unorm:
            return DXGI_FORMAT_D16_UNORM;
        case wgpu::TextureFormat::Depth32Float:
        case wgpu::TextureFormat::Depth24Plus:
            return DXGI_FORMAT_D32_FLOAT;
        // Depth24UnormStencil8 is the smallest format supported on D3D12 that has stencil.
        case wgpu::TextureFormat::Stencil8:
        case wgpu::TextureFormat::Depth24UnormStencil8:
            return DXGI_FORMAT_D24_UNORM_S8_UINT;
        case wgpu::TextureFormat::Depth24PlusStencil8:
        case wgpu::TextureFormat::Depth32FloatStencil8:
            return DXGI_FORMAT_D32_FLOAT_S8X24_UINT;

        case wgpu::TextureFormat::BC1RGBAUnorm:
            return DXGI_FORMAT_BC1_UNORM;
        case wgpu::TextureFormat::BC1RGBAUnormSrgb:
            return DXGI_FORMAT_BC1_UNORM_SRGB;
        case wgpu::TextureFormat::BC2RGBAUnorm:
            return DXGI_FORMAT_BC2_UNORM;
        case wgpu::TextureFormat::BC2RGBAUnormSrgb:
            return DXGI_FORMAT_BC2_UNORM_SRGB;
        case wgpu::TextureFormat::BC3RGBAUnorm:
            return DXGI_FORMAT_BC3_UNORM;
        case wgpu::TextureFormat::BC3RGBAUnormSrgb:
            return DXGI_FORMAT_BC3_UNORM_SRGB;
        case wgpu::TextureFormat::BC4RSnorm:
            return DXGI_FORMAT_BC4_SNORM;
        case wgpu::TextureFormat::BC4RUnorm:
            return DXGI_FORMAT_BC4_UNORM;
        case wgpu::TextureFormat::BC5RGSnorm:
            return DXGI_FORMAT_BC5_SNORM;
        case wgpu::TextureFormat::BC5RGUnorm:
            return DXGI_FORMAT_BC5_UNORM;
        case wgpu::TextureFormat::BC6HRGBFloat:
            return DXGI_FORMAT_BC6H_SF16;
        case wgpu::TextureFormat::BC6HRGBUfloat:
            return DXGI_FORMAT_BC6H_UF16;
        case wgpu::TextureFormat::BC7RGBAUnorm:
            return DXGI_FORMAT_BC7_UNORM;
        case wgpu::TextureFormat::BC7RGBAUnormSrgb:
            return DXGI_FORMAT_BC7_UNORM_SRGB;

        case wgpu::TextureFormat::R8BG8Biplanar420Unorm:
            return DXGI_FORMAT_NV12;

        case wgpu::TextureFormat::ETC2RGB8Unorm:
        case wgpu::TextureFormat::ETC2RGB8UnormSrgb:
        case wgpu::TextureFormat::ETC2RGB8A1Unorm:
        case wgpu::TextureFormat::ETC2RGB8A1UnormSrgb:
        case wgpu::TextureFormat::ETC2RGBA8Unorm:
        case wgpu::TextureFormat::ETC2RGBA8UnormSrgb:
        case wgpu::TextureFormat::EACR11Unorm:
        case wgpu::TextureFormat::EACR11Snorm:
        case wgpu::TextureFormat::EACRG11Unorm:
        case wgpu::TextureFormat::EACRG11Snorm:

        case wgpu::TextureFormat::ASTC4x4Unorm:
        case wgpu::TextureFormat::ASTC4x4UnormSrgb:
        case wgpu::TextureFormat::ASTC5x4Unorm:
        case wgpu::TextureFormat::ASTC5x4UnormSrgb:
        case wgpu::TextureFormat::ASTC5x5Unorm:
        case wgpu::TextureFormat::ASTC5x5UnormSrgb:
        case wgpu::TextureFormat::ASTC6x5Unorm:
        case wgpu::TextureFormat::ASTC6x5UnormSrgb:
        case wgpu::TextureFormat::ASTC6x6Unorm:
        case wgpu::TextureFormat::ASTC6x6UnormSrgb:
        case wgpu::TextureFormat::ASTC8x5Unorm:
        case wgpu::TextureFormat::ASTC8x5UnormSrgb:
        case wgpu::TextureFormat::ASTC8x6Unorm:
        case wgpu::TextureFormat::ASTC8x6UnormSrgb:
        case wgpu::TextureFormat::ASTC8x8Unorm:
        case wgpu::TextureFormat::ASTC8x8UnormSrgb:
        case wgpu::TextureFormat::ASTC10x5Unorm:
        case wgpu::TextureFormat::ASTC10x5UnormSrgb:
        case wgpu::TextureFormat::ASTC10x6Unorm:
        case wgpu::TextureFormat::ASTC10x6UnormSrgb:
        case wgpu::TextureFormat::ASTC10x8Unorm:
        case wgpu::TextureFormat::ASTC10x8UnormSrgb:
        case wgpu::TextureFormat::ASTC10x10Unorm:
        case wgpu::TextureFormat::ASTC10x10UnormSrgb:
        case wgpu::TextureFormat::ASTC12x10Unorm:
        case wgpu::TextureFormat::ASTC12x10UnormSrgb:
        case wgpu::TextureFormat::ASTC12x12Unorm:
        case wgpu::TextureFormat::ASTC12x12UnormSrgb:

        case wgpu::TextureFormat::Undefined:
            UNREACHABLE();
    }
}

MaybeError ValidateTextureDescriptorCanBeWrapped(const TextureDescriptor* descriptor) {
    DAWN_INVALID_IF(descriptor->dimension != wgpu::TextureDimension::e2D,
                    "Texture dimension (%s) is not %s.", descriptor->dimension,
                    wgpu::TextureDimension::e2D);

    DAWN_INVALID_IF(descriptor->mipLevelCount != 1, "Mip level count (%u) is not 1.",
                    descriptor->mipLevelCount);

    DAWN_INVALID_IF(descriptor->size.depthOrArrayLayers != 1, "Array layer count (%u) is not 1.",
                    descriptor->size.depthOrArrayLayers);

    DAWN_INVALID_IF(descriptor->sampleCount != 1, "Sample count (%u) is not 1.",
                    descriptor->sampleCount);

    return {};
}

MaybeError ValidateD3D12TextureCanBeWrapped(ID3D12Resource* d3d12Resource,
                                            const TextureDescriptor* dawnDescriptor) {
    const D3D12_RESOURCE_DESC d3dDescriptor = d3d12Resource->GetDesc();
    DAWN_INVALID_IF(
        (dawnDescriptor->size.width != d3dDescriptor.Width) ||
            (dawnDescriptor->size.height != d3dDescriptor.Height) ||
            (dawnDescriptor->size.depthOrArrayLayers != 1),
        "D3D12 texture size (Width: %u, Height: %u, DepthOrArraySize: 1) doesn't match Dawn "
        "descriptor size (width: %u, height: %u, depthOrArrayLayers: %u).",
        d3dDescriptor.Width, d3dDescriptor.Height, dawnDescriptor->size.width,
        dawnDescriptor->size.height, dawnDescriptor->size.depthOrArrayLayers);

    const DXGI_FORMAT dxgiFormatFromDescriptor = D3D12TextureFormat(dawnDescriptor->format);
    DAWN_INVALID_IF(dxgiFormatFromDescriptor != d3dDescriptor.Format,
                    "D3D12 texture format (%x) is not compatible with Dawn descriptor format (%s).",
                    d3dDescriptor.Format, dawnDescriptor->format);

    DAWN_INVALID_IF(d3dDescriptor.MipLevels != 1,
                    "D3D12 texture number of miplevels (%u) is not 1.", d3dDescriptor.MipLevels);

    DAWN_INVALID_IF(d3dDescriptor.DepthOrArraySize != 1, "D3D12 texture array size (%u) is not 1.",
                    d3dDescriptor.DepthOrArraySize);

    // Shared textures cannot be multi-sample so no need to check those.
    ASSERT(d3dDescriptor.SampleDesc.Count == 1);
    ASSERT(d3dDescriptor.SampleDesc.Quality == 0);

    return {};
}

// https://docs.microsoft.com/en-us/windows/win32/api/d3d12/ne-d3d12-d3d12_shared_resource_compatibility_tier
MaybeError ValidateD3D12VideoTextureCanBeShared(Device* device, DXGI_FORMAT textureFormat) {
    const bool supportsSharedResourceCapabilityTier1 =
        device->GetDeviceInfo().supportsSharedResourceCapabilityTier1;
    switch (textureFormat) {
        // MSDN docs are not correct, NV12 requires at-least tier 1.
        case DXGI_FORMAT_NV12:
            if (supportsSharedResourceCapabilityTier1) {
                return {};
            }
            break;
        default:
            break;
    }

    return DAWN_FORMAT_VALIDATION_ERROR("DXGI format does not support cross-API sharing.");
}

// static
ResultOrError<Ref<Texture>> Texture::Create(Device* device, const TextureDescriptor* descriptor) {
    Ref<Texture> dawnTexture =
        AcquireRef(new Texture(device, descriptor, TextureState::OwnedInternal));

    DAWN_INVALID_IF(dawnTexture->GetFormat().IsMultiPlanar(),
                    "Cannot create a multi-planar formatted texture directly");

    DAWN_TRY(dawnTexture->InitializeAsInternalTexture());
    return std::move(dawnTexture);
}

// static
ResultOrError<Ref<Texture>> Texture::CreateExternalImage(
    Device* device,
    const TextureDescriptor* descriptor,
    ComPtr<ID3D12Resource> d3d12Texture,
    Ref<D3D11on12ResourceCacheEntry> d3d11on12Resource,
    bool isSwapChainTexture,
    bool isInitialized) {
    Ref<Texture> dawnTexture =
        AcquireRef(new Texture(device, descriptor, TextureState::OwnedExternal));
    DAWN_TRY(dawnTexture->InitializeAsExternalTexture(
        descriptor, std::move(d3d12Texture), std::move(d3d11on12Resource), isSwapChainTexture));

    // Importing a multi-planar format must be initialized. This is required because
    // a shared multi-planar format cannot be initialized by Dawn.
    DAWN_INVALID_IF(
        !isInitialized && dawnTexture->GetFormat().IsMultiPlanar(),
        "Cannot create a texture with a multi-planar format (%s) with uninitialized data.",
        dawnTexture->GetFormat().format);

    dawnTexture->SetIsSubresourceContentInitialized(isInitialized,
                                                    dawnTexture->GetAllSubresources());
    return std::move(dawnTexture);
}

// static
ResultOrError<Ref<Texture>> Texture::Create(Device* device,
                                            const TextureDescriptor* descriptor,
                                            ComPtr<ID3D12Resource> d3d12Texture) {
    Ref<Texture> dawnTexture =
        AcquireRef(new Texture(device, descriptor, TextureState::OwnedExternal));
    DAWN_TRY(dawnTexture->InitializeAsSwapChainTexture(std::move(d3d12Texture)));
    return std::move(dawnTexture);
}

MaybeError Texture::InitializeAsExternalTexture(const TextureDescriptor* descriptor,
                                                ComPtr<ID3D12Resource> d3d12Texture,
                                                Ref<D3D11on12ResourceCacheEntry> d3d11on12Resource,
                                                bool isSwapChainTexture) {
    mD3D11on12Resource = std::move(d3d11on12Resource);
    mSwapChainTexture = isSwapChainTexture;

    D3D12_RESOURCE_DESC desc = d3d12Texture->GetDesc();
    mD3D12ResourceFlags = desc.Flags;

    AllocationInfo info;
    info.mMethod = AllocationMethod::kExternal;
    // When creating the ResourceHeapAllocation, the resource heap is set to nullptr because the
    // texture is owned externally. The texture's owning entity must remain responsible for
    // memory management.
    mResourceAllocation = {info, 0, std::move(d3d12Texture), nullptr};

    SetLabelHelper("Dawn_ExternalTexture");

    return {};
}

MaybeError Texture::InitializeAsInternalTexture() {
    D3D12_RESOURCE_DESC resourceDescriptor;
    resourceDescriptor.Dimension = D3D12TextureDimension(GetDimension());
    resourceDescriptor.Alignment = 0;

    const Extent3D& size = GetSize();
    resourceDescriptor.Width = size.width;
    resourceDescriptor.Height = size.height;
    resourceDescriptor.DepthOrArraySize = size.depthOrArrayLayers;

    // This will need to be much more nuanced when WebGPU has
    // texture view compatibility rules.
    const bool needsTypelessFormat = GetFormat().HasDepthOrStencil() &&
                                     (GetInternalUsage() & wgpu::TextureUsage::TextureBinding) != 0;

    DXGI_FORMAT dxgiFormat = needsTypelessFormat ? D3D12TypelessTextureFormat(GetFormat().format)
                                                 : D3D12TextureFormat(GetFormat().format);

    resourceDescriptor.MipLevels = static_cast<UINT16>(GetNumMipLevels());
    resourceDescriptor.Format = dxgiFormat;
    resourceDescriptor.SampleDesc.Count = GetSampleCount();
    resourceDescriptor.SampleDesc.Quality = 0;
    resourceDescriptor.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN;
    resourceDescriptor.Flags =
        D3D12ResourceFlags(GetInternalUsage(), GetFormat(), IsMultisampledTexture());
    mD3D12ResourceFlags = resourceDescriptor.Flags;

    DAWN_TRY_ASSIGN(mResourceAllocation,
                    ToBackend(GetDevice())
                        ->AllocateMemory(D3D12_HEAP_TYPE_DEFAULT, resourceDescriptor,
                                         D3D12_RESOURCE_STATE_COMMON));

    SetLabelImpl();

    Device* device = ToBackend(GetDevice());

    if (device->IsToggleEnabled(Toggle::NonzeroClearResourcesOnCreationForTesting)) {
        CommandRecordingContext* commandContext;
        DAWN_TRY_ASSIGN(commandContext, device->GetPendingCommandContext());

        DAWN_TRY(
            ClearTexture(commandContext, GetAllSubresources(), TextureBase::ClearValue::NonZero));
    }

    return {};
}

MaybeError Texture::InitializeAsSwapChainTexture(ComPtr<ID3D12Resource> d3d12Texture) {
    AllocationInfo info;
    info.mMethod = AllocationMethod::kExternal;
    // When creating the ResourceHeapAllocation, the resource heap is set to nullptr because the
    // texture is owned externally. The texture's owning entity must remain responsible for
    // memory management.
    mResourceAllocation = {info, 0, std::move(d3d12Texture), nullptr};

    SetLabelHelper("Dawn_SwapChainTexture");

    return {};
}

Texture::Texture(Device* device, const TextureDescriptor* descriptor, TextureState state)
    : TextureBase(device, descriptor, state),
      mSubresourceStateAndDecay(
          GetFormat().aspects,
          GetArrayLayers(),
          GetNumMipLevels(),
          {D3D12_RESOURCE_STATES::D3D12_RESOURCE_STATE_COMMON, kMaxExecutionSerial, false}) {}

Texture::~Texture() {}

void Texture::DestroyImpl() {
    TextureBase::DestroyImpl();

    Device* device = ToBackend(GetDevice());

    // In PIX's D3D12-only mode, there is no way to determine frame boundaries
    // for WebGPU since Dawn does not manage DXGI swap chains. Without assistance,
    // PIX will wait forever for a present that never happens.
    // If we know we're dealing with a swapbuffer texture, inform PIX we've
    // "presented" the texture so it can determine frame boundaries and use its
    // contents for the UI.
    if (mSwapChainTexture) {
        ID3D12SharingContract* d3dSharingContract = device->GetSharingContract();
        if (d3dSharingContract != nullptr) {
            d3dSharingContract->Present(mResourceAllocation.GetD3D12Resource(), 0, 0);
        }
    }

    device->DeallocateMemory(mResourceAllocation);

    // Now that we've deallocated the memory, the texture is no longer a swap chain texture.
    // We can set mSwapChainTexture to false to avoid passing a nullptr to
    // ID3D12SharingContract::Present.
    mSwapChainTexture = false;

    // Now that the texture has been destroyed. It should release the refptr
    // of the d3d11on12 resource.
    mD3D11on12Resource = nullptr;
}

DXGI_FORMAT Texture::GetD3D12Format() const {
    return D3D12TextureFormat(GetFormat().format);
}

ID3D12Resource* Texture::GetD3D12Resource() const {
    return mResourceAllocation.GetD3D12Resource();
}

DXGI_FORMAT Texture::GetD3D12CopyableSubresourceFormat(Aspect aspect) const {
    ASSERT(GetFormat().aspects & aspect);

    switch (GetFormat().format) {
        case wgpu::TextureFormat::Depth24UnormStencil8:
        case wgpu::TextureFormat::Depth24PlusStencil8:
        case wgpu::TextureFormat::Depth32FloatStencil8:
        case wgpu::TextureFormat::Stencil8:
            switch (aspect) {
                case Aspect::Depth:
                    return DXGI_FORMAT_R32_FLOAT;
                case Aspect::Stencil:
                    return DXGI_FORMAT_R8_UINT;
                default:
                    UNREACHABLE();
            }
        default:
            ASSERT(HasOneBit(GetFormat().aspects));
            return GetD3D12Format();
    }
}

MaybeError Texture::AcquireKeyedMutex() {
    ASSERT(mD3D11on12Resource != nullptr);
    return mD3D11on12Resource->AcquireKeyedMutex();
}

void Texture::ReleaseKeyedMutex() {
    ASSERT(mD3D11on12Resource != nullptr);
    mD3D11on12Resource->ReleaseKeyedMutex();
}

void Texture::TrackUsageAndTransitionNow(CommandRecordingContext* commandContext,
                                         wgpu::TextureUsage usage,
                                         const SubresourceRange& range) {
    TrackUsageAndTransitionNow(commandContext, D3D12TextureUsage(usage, GetFormat()), range);
}

void Texture::TrackAllUsageAndTransitionNow(CommandRecordingContext* commandContext,
                                            wgpu::TextureUsage usage) {
    TrackUsageAndTransitionNow(commandContext, D3D12TextureUsage(usage, GetFormat()),
                               GetAllSubresources());
}

void Texture::TrackAllUsageAndTransitionNow(CommandRecordingContext* commandContext,
                                            D3D12_RESOURCE_STATES newState) {
    TrackUsageAndTransitionNow(commandContext, newState, GetAllSubresources());
}

void Texture::TrackUsageAndTransitionNow(CommandRecordingContext* commandContext,
                                         D3D12_RESOURCE_STATES newState,
                                         const SubresourceRange& range) {
    if (mResourceAllocation.GetInfo().mMethod != AllocationMethod::kExternal) {
        // Track the underlying heap to ensure residency.
        Heap* heap = ToBackend(mResourceAllocation.GetResourceHeap());
        commandContext->TrackHeapUsage(heap, GetDevice()->GetPendingCommandSerial());
    }

    std::vector<D3D12_RESOURCE_BARRIER> barriers;

    // TODO(enga): Consider adding a Count helper.
    uint32_t aspectCount = 0;
    for (Aspect aspect : IterateEnumMask(range.aspects)) {
        aspectCount++;
        DAWN_UNUSED(aspect);
    }

    barriers.reserve(range.levelCount * range.layerCount * aspectCount);

    TransitionUsageAndGetResourceBarrier(commandContext, &barriers, newState, range);
    if (barriers.size()) {
        commandContext->GetCommandList()->ResourceBarrier(barriers.size(), barriers.data());
    }
}

void Texture::TransitionSubresourceRange(std::vector<D3D12_RESOURCE_BARRIER>* barriers,
                                         const SubresourceRange& range,
                                         StateAndDecay* state,
                                         D3D12_RESOURCE_STATES newState,
                                         ExecutionSerial pendingCommandSerial) const {
    D3D12_RESOURCE_STATES lastState = state->lastState;

    // If the transition is from-UAV-to-UAV, then a UAV barrier is needed.
    // If one of the usages isn't UAV, then other barriers are used.
    bool needsUAVBarrier = lastState == D3D12_RESOURCE_STATE_UNORDERED_ACCESS &&
                           newState == D3D12_RESOURCE_STATE_UNORDERED_ACCESS;

    if (needsUAVBarrier) {
        D3D12_RESOURCE_BARRIER barrier;
        barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV;
        barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
        barrier.UAV.pResource = GetD3D12Resource();
        barriers->push_back(barrier);
        return;
    }

    // Reuse the subresource(s) directly and avoid transition when it isn't needed, and
    // return false.
    if (lastState == newState) {
        return;
    }

    // The COMMON state represents a state where no write operations can be pending, and
    // where all pixels are uncompressed. This makes it possible to transition to and
    // from some states without synchronization (i.e. without an explicit
    // ResourceBarrier call). Textures can be implicitly promoted to 1) a single write
    // state, or 2) multiple read states. Textures will implicitly decay to the COMMON
    // state when all of the following are true: 1) the texture is accessed on a command
    // list, 2) the ExecuteCommandLists call that uses that command list has ended, and
    // 3) the texture was promoted implicitly to a read-only state and is still in that
    // state.
    // https://docs.microsoft.com/en-us/windows/desktop/direct3d12/using-resource-barriers-to-synchronize-resource-states-in-direct3d-12#implicit-state-transitions

    // To track implicit decays, we must record the pending serial on which that
    // transition will occur. When that texture is used again, the previously recorded
    // serial must be compared to the last completed serial to determine if the texture
    // has implicity decayed to the common state.
    if (state->isValidToDecay && pendingCommandSerial > state->lastDecaySerial) {
        lastState = D3D12_RESOURCE_STATE_COMMON;
    }

    // Update the tracked state.
    state->lastState = newState;

    // Destination states that qualify for an implicit promotion for a
    // non-simultaneous-access texture: NON_PIXEL_SHADER_RESOURCE,
    // PIXEL_SHADER_RESOURCE, COPY_SRC, COPY_DEST.
    {
        static constexpr D3D12_RESOURCE_STATES kD3D12PromotableReadOnlyStates =
            D3D12_RESOURCE_STATE_COPY_SOURCE | D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE |
            D3D12_RESOURCE_STATE_NON_PIXEL_SHADER_RESOURCE;

        if (lastState == D3D12_RESOURCE_STATE_COMMON) {
            if (IsSubset(newState, kD3D12PromotableReadOnlyStates)) {
                // Implicit texture state decays can only occur when the texture was implicitly
                // transitioned to a read-only state. isValidToDecay is needed to differentiate
                // between resources that were implictly or explicitly transitioned to a
                // read-only state.
                state->isValidToDecay = true;
                state->lastDecaySerial = pendingCommandSerial;
                return;
            } else if (newState == D3D12_RESOURCE_STATE_COPY_DEST) {
                state->isValidToDecay = false;
                return;
            }
        }
    }

    D3D12_RESOURCE_BARRIER barrier;
    barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
    barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
    barrier.Transition.pResource = GetD3D12Resource();
    barrier.Transition.StateBefore = lastState;
    barrier.Transition.StateAfter = newState;

    bool isFullRange = range.baseArrayLayer == 0 && range.baseMipLevel == 0 &&
                       range.layerCount == GetArrayLayers() &&
                       range.levelCount == GetNumMipLevels() &&
                       range.aspects == GetFormat().aspects;

    // Use a single transition for all subresources if possible.
    if (isFullRange) {
        barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
        barriers->push_back(barrier);
    } else {
        for (Aspect aspect : IterateEnumMask(range.aspects)) {
            for (uint32_t arrayLayer = 0; arrayLayer < range.layerCount; ++arrayLayer) {
                for (uint32_t mipLevel = 0; mipLevel < range.levelCount; ++mipLevel) {
                    barrier.Transition.Subresource = GetSubresourceIndex(
                        range.baseMipLevel + mipLevel, range.baseArrayLayer + arrayLayer, aspect);
                    barriers->push_back(barrier);
                }
            }
        }
    }

    state->isValidToDecay = false;
}

void Texture::HandleTransitionSpecialCases(CommandRecordingContext* commandContext) {
    // Textures with keyed mutexes can be written from other graphics queues. Hence, they
    // must be acquired before command list submission to ensure work from the other queues
    // has finished. See Device::ExecuteCommandContext.
    if (mD3D11on12Resource != nullptr) {
        commandContext->AddToSharedTextureList(this);
    }
}

void Texture::TransitionUsageAndGetResourceBarrier(CommandRecordingContext* commandContext,
                                                   std::vector<D3D12_RESOURCE_BARRIER>* barrier,
                                                   wgpu::TextureUsage usage,
                                                   const SubresourceRange& range) {
    TransitionUsageAndGetResourceBarrier(commandContext, barrier,
                                         D3D12TextureUsage(usage, GetFormat()), range);
}

void Texture::TransitionUsageAndGetResourceBarrier(CommandRecordingContext* commandContext,
                                                   std::vector<D3D12_RESOURCE_BARRIER>* barriers,
                                                   D3D12_RESOURCE_STATES newState,
                                                   const SubresourceRange& range) {
    HandleTransitionSpecialCases(commandContext);

    const ExecutionSerial pendingCommandSerial = ToBackend(GetDevice())->GetPendingCommandSerial();

    mSubresourceStateAndDecay.Update(range, [&](const SubresourceRange& updateRange,
                                                StateAndDecay* state) {
        TransitionSubresourceRange(barriers, updateRange, state, newState, pendingCommandSerial);
    });
}

void Texture::TrackUsageAndGetResourceBarrierForPass(CommandRecordingContext* commandContext,
                                                     std::vector<D3D12_RESOURCE_BARRIER>* barriers,
                                                     const TextureSubresourceUsage& textureUsages) {
    if (mResourceAllocation.GetInfo().mMethod != AllocationMethod::kExternal) {
        // Track the underlying heap to ensure residency.
        Heap* heap = ToBackend(mResourceAllocation.GetResourceHeap());
        commandContext->TrackHeapUsage(heap, GetDevice()->GetPendingCommandSerial());
    }

    HandleTransitionSpecialCases(commandContext);

    const ExecutionSerial pendingCommandSerial = ToBackend(GetDevice())->GetPendingCommandSerial();

    mSubresourceStateAndDecay.Merge(
        textureUsages,
        [&](const SubresourceRange& mergeRange, StateAndDecay* state, wgpu::TextureUsage usage) {
            // Skip if this subresource is not used during the current pass
            if (usage == wgpu::TextureUsage::None) {
                return;
            }

            D3D12_RESOURCE_STATES newState = D3D12TextureUsage(usage, GetFormat());
            TransitionSubresourceRange(barriers, mergeRange, state, newState, pendingCommandSerial);
        });
}

D3D12_RENDER_TARGET_VIEW_DESC Texture::GetRTVDescriptor(const Format& format,
                                                        uint32_t mipLevel,
                                                        uint32_t baseSlice,
                                                        uint32_t sliceCount) const {
    D3D12_RENDER_TARGET_VIEW_DESC rtvDesc;
    rtvDesc.Format = D3D12TextureFormat(format.format);
    if (IsMultisampledTexture()) {
        ASSERT(GetDimension() == wgpu::TextureDimension::e2D);
        ASSERT(GetNumMipLevels() == 1);
        ASSERT(sliceCount == 1);
        ASSERT(baseSlice == 0);
        ASSERT(mipLevel == 0);
        rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2DMS;
        return rtvDesc;
    }
    switch (GetDimension()) {
        case wgpu::TextureDimension::e2D:
            // Currently we always use D3D12_TEX2D_ARRAY_RTV because we cannot specify base
            // array layer and layer count in D3D12_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/d3d12/ns-d3d12-d3d12_tex2d_rtv
            // https://docs.microsoft.com/en-us/windows/desktop/api/d3d12/ns-d3d12-d3d12_tex2d_array
            // _rtv
            rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2DARRAY;
            rtvDesc.Texture2DArray.FirstArraySlice = baseSlice;
            rtvDesc.Texture2DArray.ArraySize = sliceCount;
            rtvDesc.Texture2DArray.MipSlice = mipLevel;
            rtvDesc.Texture2DArray.PlaneSlice = 0;
            break;
        case wgpu::TextureDimension::e3D:
            rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE3D;
            rtvDesc.Texture3D.MipSlice = mipLevel;
            rtvDesc.Texture3D.FirstWSlice = baseSlice;
            rtvDesc.Texture3D.WSize = sliceCount;
            break;
        case wgpu::TextureDimension::e1D:
            UNREACHABLE();
            break;
    }
    return rtvDesc;
}

D3D12_DEPTH_STENCIL_VIEW_DESC Texture::GetDSVDescriptor(uint32_t mipLevel,
                                                        uint32_t baseArrayLayer,
                                                        uint32_t layerCount,
                                                        Aspect aspects,
                                                        bool depthReadOnly,
                                                        bool stencilReadOnly) const {
    D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc;
    dsvDesc.Format = GetD3D12Format();
    dsvDesc.Flags = D3D12_DSV_FLAG_NONE;
    if (depthReadOnly && aspects & Aspect::Depth) {
        dsvDesc.Flags |= D3D12_DSV_FLAG_READ_ONLY_DEPTH;
    }
    if (stencilReadOnly && aspects & Aspect::Stencil) {
        dsvDesc.Flags |= D3D12_DSV_FLAG_READ_ONLY_STENCIL;
    }

    if (IsMultisampledTexture()) {
        ASSERT(GetNumMipLevels() == 1);
        ASSERT(layerCount == 1);
        ASSERT(baseArrayLayer == 0);
        ASSERT(mipLevel == 0);
        dsvDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2DMS;
    } else {
        dsvDesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2DARRAY;
        dsvDesc.Texture2DArray.FirstArraySlice = baseArrayLayer;
        dsvDesc.Texture2DArray.ArraySize = layerCount;
        dsvDesc.Texture2DArray.MipSlice = mipLevel;
    }

    return dsvDesc;
}

MaybeError Texture::ClearTexture(CommandRecordingContext* commandContext,
                                 const SubresourceRange& range,
                                 TextureBase::ClearValue clearValue) {
    ID3D12GraphicsCommandList* commandList = commandContext->GetCommandList();

    Device* device = ToBackend(GetDevice());

    uint8_t clearColor = (clearValue == TextureBase::ClearValue::Zero) ? 0 : 1;
    float fClearColor = (clearValue == TextureBase::ClearValue::Zero) ? 0.f : 1.f;

    if ((mD3D12ResourceFlags & D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL) != 0) {
        TrackUsageAndTransitionNow(commandContext, D3D12_RESOURCE_STATE_DEPTH_WRITE, range);

        for (uint32_t level = range.baseMipLevel; level < range.baseMipLevel + range.levelCount;
             ++level) {
            for (uint32_t layer = range.baseArrayLayer;
                 layer < range.baseArrayLayer + range.layerCount; ++layer) {
                // Iterate the aspects individually to determine which clear flags to use.
                D3D12_CLEAR_FLAGS clearFlags = {};
                for (Aspect aspect : IterateEnumMask(range.aspects)) {
                    if (clearValue == TextureBase::ClearValue::Zero &&
                        IsSubresourceContentInitialized(
                            SubresourceRange::SingleMipAndLayer(level, layer, aspect))) {
                        // Skip lazy clears if already initialized.
                        continue;
                    }

                    switch (aspect) {
                        case Aspect::Depth:
                            clearFlags |= D3D12_CLEAR_FLAG_DEPTH;
                            break;
                        case Aspect::Stencil:
                            clearFlags |= D3D12_CLEAR_FLAG_STENCIL;
                            break;
                        default:
                            UNREACHABLE();
                    }
                }

                if (clearFlags == 0) {
                    continue;
                }

                CPUDescriptorHeapAllocation dsvHandle;
                DAWN_TRY_ASSIGN(
                    dsvHandle,
                    device->GetDepthStencilViewAllocator()->AllocateTransientCPUDescriptors());
                const D3D12_CPU_DESCRIPTOR_HANDLE baseDescriptor = dsvHandle.GetBaseDescriptor();
                D3D12_DEPTH_STENCIL_VIEW_DESC dsvDesc =
                    GetDSVDescriptor(level, layer, 1, range.aspects, false, false);
                device->GetD3D12Device()->CreateDepthStencilView(GetD3D12Resource(), &dsvDesc,
                                                                 baseDescriptor);

                commandList->ClearDepthStencilView(baseDescriptor, clearFlags, fClearColor,
                                                   clearColor, 0, nullptr);
            }
        }
    } else if ((mD3D12ResourceFlags & D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET) != 0) {
        TrackUsageAndTransitionNow(commandContext, D3D12_RESOURCE_STATE_RENDER_TARGET, range);

        const float clearColorRGBA[4] = {fClearColor, fClearColor, fClearColor, fClearColor};

        ASSERT(range.aspects == Aspect::Color);
        for (uint32_t level = range.baseMipLevel; level < range.baseMipLevel + range.levelCount;
             ++level) {
            for (uint32_t layer = range.baseArrayLayer;
                 layer < range.baseArrayLayer + range.layerCount; ++layer) {
                if (clearValue == TextureBase::ClearValue::Zero &&
                    IsSubresourceContentInitialized(
                        SubresourceRange::SingleMipAndLayer(level, layer, Aspect::Color))) {
                    // Skip lazy clears if already initialized.
                    continue;
                }

                CPUDescriptorHeapAllocation rtvHeap;
                DAWN_TRY_ASSIGN(
                    rtvHeap,
                    device->GetRenderTargetViewAllocator()->AllocateTransientCPUDescriptors());
                const D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = rtvHeap.GetBaseDescriptor();

                uint32_t baseSlice = layer;
                uint32_t sliceCount = 1;
                if (GetDimension() == wgpu::TextureDimension::e3D) {
                    baseSlice = 0;
                    sliceCount = std::max(GetDepth() >> level, 1u);
                }
                D3D12_RENDER_TARGET_VIEW_DESC rtvDesc =
                    GetRTVDescriptor(GetFormat(), level, baseSlice, sliceCount);
                device->GetD3D12Device()->CreateRenderTargetView(GetD3D12Resource(), &rtvDesc,
                                                                 rtvHandle);
                commandList->ClearRenderTargetView(rtvHandle, clearColorRGBA, 0, nullptr);
            }
        }
    } else {
        // create temp buffer with clear color to copy to the texture image
        TrackUsageAndTransitionNow(commandContext, D3D12_RESOURCE_STATE_COPY_DEST, range);

        for (Aspect aspect : IterateEnumMask(range.aspects)) {
            const TexelBlockInfo& blockInfo = GetFormat().GetAspectInfo(aspect).block;

            Extent3D largestMipSize = GetMipLevelPhysicalSize(range.baseMipLevel);

            uint32_t bytesPerRow =
                Align((largestMipSize.width / blockInfo.width) * blockInfo.byteSize,
                      kTextureBytesPerRowAlignment);
            uint64_t bufferSize = bytesPerRow * (largestMipSize.height / blockInfo.height) *
                                  largestMipSize.depthOrArrayLayers;
            DynamicUploader* uploader = device->GetDynamicUploader();
            UploadHandle uploadHandle;
            DAWN_TRY_ASSIGN(uploadHandle,
                            uploader->Allocate(bufferSize, device->GetPendingCommandSerial(),
                                               blockInfo.byteSize));
            memset(uploadHandle.mappedBuffer, clearColor, bufferSize);

            for (uint32_t level = range.baseMipLevel; level < range.baseMipLevel + range.levelCount;
                 ++level) {
                // compute d3d12 texture copy locations for texture and buffer
                Extent3D copySize = GetMipLevelPhysicalSize(level);

                for (uint32_t layer = range.baseArrayLayer;
                     layer < range.baseArrayLayer + range.layerCount; ++layer) {
                    if (clearValue == TextureBase::ClearValue::Zero &&
                        IsSubresourceContentInitialized(
                            SubresourceRange::SingleMipAndLayer(level, layer, aspect))) {
                        // Skip lazy clears if already initialized.
                        continue;
                    }

                    TextureCopy textureCopy;
                    textureCopy.texture = this;
                    textureCopy.origin = {0, 0, layer};
                    textureCopy.mipLevel = level;
                    textureCopy.aspect = aspect;
                    RecordBufferTextureCopyWithBufferHandle(
                        BufferTextureCopyDirection::B2T, commandList,
                        ToBackend(uploadHandle.stagingBuffer)->GetResource(),
                        uploadHandle.startOffset, bytesPerRow, GetHeight(), textureCopy, copySize);
                }
            }
        }
    }
    if (clearValue == TextureBase::ClearValue::Zero) {
        SetIsSubresourceContentInitialized(true, range);
        GetDevice()->IncrementLazyClearCountForTesting();
    }
    return {};
}

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

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

void Texture::EnsureSubresourceContentInitialized(CommandRecordingContext* 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
        GetDevice()->ConsumedError(
            ClearTexture(commandContext, range, TextureBase::ClearValue::Zero));
    }
}

bool Texture::StateAndDecay::operator==(const Texture::StateAndDecay& other) const {
    return lastState == other.lastState && lastDecaySerial == other.lastDecaySerial &&
           isValidToDecay == other.isValidToDecay;
}

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

TextureView::TextureView(TextureBase* texture, const TextureViewDescriptor* descriptor)
    : TextureViewBase(texture, descriptor) {
    mSrvDesc.Format = D3D12TextureFormat(descriptor->format);
    mSrvDesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;

    UINT planeSlice = 0;
    const Format& textureFormat = texture->GetFormat();
    if (textureFormat.HasDepthOrStencil()) {
        // Configure the SRV descriptor to reinterpret the texture allocated as
        // TYPELESS as a single-plane shader-accessible view.
        switch (textureFormat.format) {
            case wgpu::TextureFormat::Depth32Float:
            case wgpu::TextureFormat::Depth24Plus:
                mSrvDesc.Format = DXGI_FORMAT_R32_FLOAT;
                break;
            case wgpu::TextureFormat::Depth16Unorm:
                mSrvDesc.Format = DXGI_FORMAT_R16_UNORM;
                break;
            case wgpu::TextureFormat::Stencil8:
            case wgpu::TextureFormat::Depth24UnormStencil8: {
                Aspect aspects = SelectFormatAspects(textureFormat, descriptor->aspect);
                ASSERT(aspects != Aspect::None);
                if (!HasZeroOrOneBits(aspects)) {
                    // A single aspect is not selected. The texture view must not be
                    // sampled.
                    mSrvDesc.Format = DXGI_FORMAT_UNKNOWN;
                    break;
                }
                switch (aspects) {
                    case Aspect::Depth:
                        planeSlice = 0;
                        mSrvDesc.Format = DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
                        break;
                    case Aspect::Stencil:
                        planeSlice = 1;
                        mSrvDesc.Format = DXGI_FORMAT_X24_TYPELESS_G8_UINT;
                        // Stencil is accessed using the .g component in the shader.
                        // Map it to the zeroth component to match other APIs.
                        mSrvDesc.Shader4ComponentMapping = D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING(
                            D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_1,
                            D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0,
                            D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0,
                            D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_1);
                        break;
                    default:
                        UNREACHABLE();
                        break;
                }
                break;
            }
            case wgpu::TextureFormat::Depth24PlusStencil8:
            case wgpu::TextureFormat::Depth32FloatStencil8: {
                Aspect aspects = SelectFormatAspects(textureFormat, descriptor->aspect);
                ASSERT(aspects != Aspect::None);
                if (!HasZeroOrOneBits(aspects)) {
                    // A single aspect is not selected. The texture view must not be
                    // sampled.
                    mSrvDesc.Format = DXGI_FORMAT_UNKNOWN;
                    break;
                }
                switch (aspects) {
                    case Aspect::Depth:
                        planeSlice = 0;
                        mSrvDesc.Format = DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS;
                        break;
                    case Aspect::Stencil:
                        planeSlice = 1;
                        mSrvDesc.Format = DXGI_FORMAT_X32_TYPELESS_G8X24_UINT;
                        // Stencil is accessed using the .g component in the shader.
                        // Map it to the zeroth component to match other APIs.
                        mSrvDesc.Shader4ComponentMapping = D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING(
                            D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_1,
                            D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0,
                            D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0,
                            D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_1);
                        break;
                    default:
                        UNREACHABLE();
                        break;
                }
                break;
            }
            default:
                UNREACHABLE();
                break;
        }
    }

    // Per plane view formats must have the plane slice number be the index of the plane in the
    // array of textures.
    if (texture->GetFormat().IsMultiPlanar()) {
        const Aspect planeAspect = ConvertViewAspect(GetFormat(), descriptor->aspect);
        planeSlice = GetAspectIndex(planeAspect);
        mSrvDesc.Format =
            D3D12TextureFormat(texture->GetFormat().GetAspectInfo(planeAspect).format);
    }

    // Currently we always use D3D12_TEX2D_ARRAY_SRV because we cannot specify base array layer
    // and layer count in D3D12_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
    // D3D12_SRV_DIMENSION_TEXTURE2DMS.
    // https://docs.microsoft.com/en-us/windows/desktop/api/d3d12/ns-d3d12-d3d12_tex2d_srv
    // https://docs.microsoft.com/en-us/windows/desktop/api/d3d12/ns-d3d12-d3d12_tex2d_array_srv
    if (GetTexture()->IsMultisampledTexture()) {
        switch (descriptor->dimension) {
            case wgpu::TextureViewDimension::e2DArray:
                ASSERT(texture->GetArrayLayers() == 1);
                [[fallthrough]];
            case wgpu::TextureViewDimension::e2D:
                ASSERT(texture->GetDimension() == wgpu::TextureDimension::e2D);
                mSrvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2DMS;
                break;

            default:
                UNREACHABLE();
        }
    } else {
        switch (descriptor->dimension) {
            case wgpu::TextureViewDimension::e1D:
                mSrvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE1D;
                mSrvDesc.Texture1D.MipLevels = descriptor->mipLevelCount;
                mSrvDesc.Texture1D.MostDetailedMip = descriptor->baseMipLevel;
                mSrvDesc.Texture1D.ResourceMinLODClamp = 0;
                break;

            case wgpu::TextureViewDimension::e2D:
            case wgpu::TextureViewDimension::e2DArray:
                ASSERT(texture->GetDimension() == wgpu::TextureDimension::e2D);
                mSrvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2DARRAY;
                mSrvDesc.Texture2DArray.ArraySize = descriptor->arrayLayerCount;
                mSrvDesc.Texture2DArray.FirstArraySlice = descriptor->baseArrayLayer;
                mSrvDesc.Texture2DArray.MipLevels = descriptor->mipLevelCount;
                mSrvDesc.Texture2DArray.MostDetailedMip = descriptor->baseMipLevel;
                mSrvDesc.Texture2DArray.PlaneSlice = planeSlice;
                mSrvDesc.Texture2DArray.ResourceMinLODClamp = 0;
                break;
            case wgpu::TextureViewDimension::Cube:
            case wgpu::TextureViewDimension::CubeArray:
                ASSERT(texture->GetDimension() == wgpu::TextureDimension::e2D);
                ASSERT(descriptor->arrayLayerCount % 6 == 0);
                mSrvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURECUBEARRAY;
                mSrvDesc.TextureCubeArray.First2DArrayFace = descriptor->baseArrayLayer;
                mSrvDesc.TextureCubeArray.NumCubes = descriptor->arrayLayerCount / 6;
                mSrvDesc.TextureCubeArray.MostDetailedMip = descriptor->baseMipLevel;
                mSrvDesc.TextureCubeArray.MipLevels = descriptor->mipLevelCount;
                mSrvDesc.TextureCubeArray.ResourceMinLODClamp = 0;
                break;
            case wgpu::TextureViewDimension::e3D:
                ASSERT(texture->GetDimension() == wgpu::TextureDimension::e3D);
                mSrvDesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE3D;
                mSrvDesc.Texture3D.MostDetailedMip = descriptor->baseMipLevel;
                mSrvDesc.Texture3D.MipLevels = descriptor->mipLevelCount;
                mSrvDesc.Texture3D.ResourceMinLODClamp = 0;
                break;

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

DXGI_FORMAT TextureView::GetD3D12Format() const {
    return D3D12TextureFormat(GetFormat().format);
}

const D3D12_SHADER_RESOURCE_VIEW_DESC& TextureView::GetSRVDescriptor() const {
    ASSERT(mSrvDesc.Format != DXGI_FORMAT_UNKNOWN);
    return mSrvDesc;
}

D3D12_RENDER_TARGET_VIEW_DESC TextureView::GetRTVDescriptor() const {
    return ToBackend(GetTexture())
        ->GetRTVDescriptor(GetFormat(), GetBaseMipLevel(), GetBaseArrayLayer(), GetLayerCount());
}

D3D12_DEPTH_STENCIL_VIEW_DESC TextureView::GetDSVDescriptor(bool depthReadOnly,
                                                            bool stencilReadOnly) const {
    ASSERT(GetLevelCount() == 1);
    return ToBackend(GetTexture())
        ->GetDSVDescriptor(GetBaseMipLevel(), GetBaseArrayLayer(), GetLayerCount(), GetAspects(),
                           depthReadOnly, stencilReadOnly);
}

D3D12_UNORDERED_ACCESS_VIEW_DESC TextureView::GetUAVDescriptor() const {
    D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc;
    uavDesc.Format = GetD3D12Format();

    ASSERT(!GetTexture()->IsMultisampledTexture());
    switch (GetDimension()) {
        case wgpu::TextureViewDimension::e1D:
            uavDesc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE1D;
            uavDesc.Texture1D.MipSlice = GetBaseMipLevel();
            break;
        case wgpu::TextureViewDimension::e2D:
        case wgpu::TextureViewDimension::e2DArray:
            uavDesc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2DARRAY;
            uavDesc.Texture2DArray.FirstArraySlice = GetBaseArrayLayer();
            uavDesc.Texture2DArray.ArraySize = GetLayerCount();
            uavDesc.Texture2DArray.MipSlice = GetBaseMipLevel();
            uavDesc.Texture2DArray.PlaneSlice = 0;
            break;
        case wgpu::TextureViewDimension::e3D:
            uavDesc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE3D;
            uavDesc.Texture3D.FirstWSlice = 0;
            uavDesc.Texture3D.WSize = GetTexture()->GetDepth() >> GetBaseMipLevel();
            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:
            UNREACHABLE();
    }
    return uavDesc;
}

}  // namespace dawn::native::d3d12
