// 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) {
    D3D12_RESOURCE_FLAGS flags = D3D12_RESOURCE_FLAG_NONE;

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

    if (usage & wgpu::TextureUsage::RenderAttachment) {
        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;

        // DXGI_FORMAT_D24_UNORM_S8_UINT is the smallest format supported on D3D12 that has stencil,
        // for which the typeless equivalent is DXGI_FORMAT_R24G8_TYPELESS.
        case wgpu::TextureFormat::Stencil8:
            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;
        // DXGI_FORMAT_D24_UNORM_S8_UINT is the smallest format supported on D3D12 that has stencil.
        case wgpu::TextureFormat::Stencil8:
            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,
    ComPtr<ID3D12Fence> d3d12Fence,
    Ref<D3D11on12ResourceCacheEntry> d3d11on12Resource,
    uint64_t fenceWaitValue,
    uint64_t fenceSignalValue,
    bool isSwapChainTexture,
    bool isInitialized) {
    Ref<Texture> dawnTexture =
        AcquireRef(new Texture(device, descriptor, TextureState::OwnedExternal));
    DAWN_TRY(dawnTexture->InitializeAsExternalTexture(
        std::move(d3d12Texture), std::move(d3d12Fence), std::move(d3d11on12Resource),
        fenceWaitValue, fenceSignalValue, 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(ComPtr<ID3D12Resource> d3d12Texture,
                                                ComPtr<ID3D12Fence> d3d12Fence,
                                                Ref<D3D11on12ResourceCacheEntry> d3d11on12Resource,
                                                uint64_t fenceWaitValue,
                                                uint64_t fenceSignalValue,
                                                bool 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};

    mD3D12Fence = std::move(d3d12Fence);
    mD3D11on12Resource = std::move(d3d11on12Resource);
    mFenceWaitValue = fenceWaitValue;
    mFenceSignalValue = fenceSignalValue;
    mSwapChainTexture = isSwapChainTexture;

    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());
    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;

    // Signal the fence on destroy after all uses of the texture.
    if (mD3D12Fence != nullptr && mFenceSignalValue != 0) {
        device->GetCommandQueue()->Signal(mD3D12Fence.Get(), mFenceSignalValue);
    }

    // Now that the texture has been destroyed. It should release the refptr of the d3d11on12
    // resource and the fence.
    mD3D11on12Resource = nullptr;
    mD3D12Fence = 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::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::SynchronizeImportedTextureBeforeUse() {
    if (mD3D11on12Resource != nullptr) {
        DAWN_TRY(mD3D11on12Resource->AcquireKeyedMutex());
    }
    // Perform the wait only on the first call. We can use UINT64_MAX as a sentinel value since it's
    // also used by the D3D runtime to indicate device removed according to:
    // https://docs.microsoft.com/en-us/windows/win32/api/d3d12/nf-d3d12-id3d12fence-getcompletedvalue#return-value
    if (mD3D12Fence != nullptr && mFenceWaitValue != UINT64_MAX) {
        DAWN_TRY(CheckHRESULT(
            ToBackend(GetDevice())->GetCommandQueue()->Wait(mD3D12Fence.Get(), mFenceWaitValue),
            "D3D12 fence wait"));
        mFenceWaitValue = UINT64_MAX;
    }
    return {};
}

void Texture::SynchronizeImportedTextureAfterUse() {
    if (mD3D11on12Resource != nullptr) {
        mD3D11on12Resource->ReleaseKeyedMutex();
    }
    // Defer signaling the fence until destroy after all uses of the fence.
}

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) {
    // Externally allocated textures 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 CommandRecordingContext::ExecuteCommandList.
    if (mResourceAllocation.GetInfo().mMethod == AllocationMethod::kExternal) {
        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 {
        ASSERT(!IsMultisampledTexture());

        // 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 = GetMipLevelSingleSubresourcePhysicalSize(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 = GetMipLevelSingleSubresourcePhysicalSize(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, largestMipSize.height, 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: {
                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
