// 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 "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 {
        // Reuse the subresource(s) directly and avoid transition when it isn't needed, and
        // return false.
        if (state->lastState == newState) {
            return;
        }

        D3D12_RESOURCE_STATES lastState = state->lastState;

        // 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(uint32_t mipLevel,
                                                            uint32_t baseSlice,
                                                            uint32_t sliceCount) const {
        D3D12_RENDER_TARGET_VIEW_DESC rtvDesc;
        rtvDesc.Format = GetD3D12Format();
        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(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(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
