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

#include "src/dawn/native/d3d12/UtilsD3D12.h"

#include <stringapiset.h>

#include <utility>

#include "src/dawn/common/Range.h"
#include "src/dawn/native/CommandValidation.h"
#include "src/dawn/native/Format.h"
#include "src/dawn/native/d3d/D3DError.h"
#include "src/dawn/native/d3d12/BufferD3D12.h"
#include "src/dawn/native/d3d12/CommandRecordingContext.h"
#include "src/dawn/native/d3d12/DeviceD3D12.h"
#include "src/dawn/native/d3d12/TextureCopySplitter.h"
#include "src/utils/assert.h"

namespace dawn::native::d3d12 {

namespace {

uint64_t RequiredCopySizeByD3D12(const BlockCount blocksPerRow,
                                 const BlockCount rowsPerImage,
                                 const BlockExtent3D& copySize,
                                 const TypedTexelBlockInfo& blockInfo) {
    // WebGPU copy size for B2T/T2B computation is:
    // offset + bytesPerRow * rowsPerImage * (copySizeInBlocks.depthOrArrayLayers - 1)
    //   + bytesPerRow * (copySizeInBlocks.height - 1) + bytesPerBlock * copySizeInBlocks.width
    //
    // But D3D12 computes it differently, using 'rowsPerImage - 1' rather than
    // 'copySizeInBlocks.height - 1' for the last slice without the last row:
    //
    // offset + bytesPerRow * rowsPerImage * (copySizeInBlocks.depthOrArrayLayers - 1)
    //   + bytesPerRow * (rowsPerImage - 1) + bytesPerBlock * copySizeInBlocks.width
    //
    // D3D12 requires unnecessary buffer storage for the image padding row
    // (rowsPerImage - copySizeInBlocks.height) on the last image. It does respect
    // row padding (bytesPerRow) and doesn't require storage for it on the last row.
    // See crbug.com/41479503 for a more details.

    // Compute (block) size for the first images except the last.
    BlockCount allButLastImage =
        blocksPerRow * rowsPerImage * (copySize.depthOrArrayLayers - BlockCount{1u});
    // Compute (block) size of the last image as D3D12 does, which includes the size of whole last
    // row
    BlockCount lastRow = copySize.width;
    DAWN_ASSERT(rowsPerImage > copySize.height);
    BlockCount lastImageByD3D12 = blocksPerRow * (rowsPerImage - BlockCount{1u}) + lastRow;
    // Compute total (block) size as D3D12 does
    BlockCount requiredCopySizeByD3D12 = allButLastImage + lastImageByD3D12;
    return blockInfo.ToBytes(requiredCopySizeByD3D12);
}

// This function is used to access whether we need a workaround for D3D12's algorithm of
// calculating required buffer size for B2T/T2B copy. The workaround is needed only when
//   - It is a 3D texture.
//   - There are multiple depth images to be copied (copySize.depthOrArrayLayers > 1).
//   - It has rowsPerImage paddings (rowsPerImage > copySize.height).
//   - The buffer size doesn't meet D3D12's requirement.
bool NeedBufferSizeWorkaroundForBufferTextureCopyOnD3D12(const BufferCopy& bufferCopy,
                                                         const TextureCopy& textureCopy,
                                                         const BlockExtent3D& copySize) {
    TextureBase* texture = textureCopy.texture.Get();
    if (texture->GetDimension() != wgpu::TextureDimension::e3D ||
        copySize.depthOrArrayLayers <= BlockCount{1u} ||
        bufferCopy.rowsPerImage <= copySize.height) {
        return false;
    }

    const TypedTexelBlockInfo& blockInfo = GetBlockInfo(textureCopy);
    uint64_t requiredCopySizeByD3D12 = RequiredCopySizeByD3D12(
        bufferCopy.blocksPerRow, bufferCopy.rowsPerImage, copySize, blockInfo);
    return (bufferCopy.buffer->GetAllocatedSize() - bufferCopy.offset) < requiredCopySizeByD3D12;
}

D3D12_TEXTURE_COPY_LOCATION ComputeBufferLocationForCopyTextureRegion(
    const Texture* texture,
    ID3D12Resource* bufferResource,
    const TexelExtent3D& bufferSize,
    const uint64_t offset,
    const uint32_t rowPitch,
    Aspect aspect) {
    D3D12_TEXTURE_COPY_LOCATION bufferLocation;
    bufferLocation.pResource = bufferResource;
    bufferLocation.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
    bufferLocation.PlacedFootprint.Offset = offset;
    bufferLocation.PlacedFootprint.Footprint.Format =
        texture->GetD3D12CopyableSubresourceFormat(aspect);
    bufferLocation.PlacedFootprint.Footprint.Width = dchecked_cast<uint32_t>(bufferSize.width);
    bufferLocation.PlacedFootprint.Footprint.Height = dchecked_cast<uint32_t>(bufferSize.height);
    bufferLocation.PlacedFootprint.Footprint.Depth =
        dchecked_cast<uint32_t>(bufferSize.depthOrArrayLayers);
    bufferLocation.PlacedFootprint.Footprint.RowPitch = rowPitch;
    return bufferLocation;
}

}  // anonymous namespace

D3D12_COMPARISON_FUNC ToD3D12ComparisonFunc(wgpu::CompareFunction func) {
    switch (func) {
        case wgpu::CompareFunction::Never:
            return D3D12_COMPARISON_FUNC_NEVER;
        case wgpu::CompareFunction::Less:
            return D3D12_COMPARISON_FUNC_LESS;
        case wgpu::CompareFunction::LessEqual:
            return D3D12_COMPARISON_FUNC_LESS_EQUAL;
        case wgpu::CompareFunction::Greater:
            return D3D12_COMPARISON_FUNC_GREATER;
        case wgpu::CompareFunction::GreaterEqual:
            return D3D12_COMPARISON_FUNC_GREATER_EQUAL;
        case wgpu::CompareFunction::Equal:
            return D3D12_COMPARISON_FUNC_EQUAL;
        case wgpu::CompareFunction::NotEqual:
            return D3D12_COMPARISON_FUNC_NOT_EQUAL;
        case wgpu::CompareFunction::Always:
            return D3D12_COMPARISON_FUNC_ALWAYS;

        case wgpu::CompareFunction::Undefined:
        default:
            DAWN_UNREACHABLE();
    }
}

D3D12_SHADER_VISIBILITY ShaderVisibilityType(wgpu::ShaderStage visibility) {
    DAWN_ASSERT(visibility != wgpu::ShaderStage::None);

    if (visibility == wgpu::ShaderStage::Vertex) {
        return D3D12_SHADER_VISIBILITY_VERTEX;
    }

    if (visibility == wgpu::ShaderStage::Fragment) {
        return D3D12_SHADER_VISIBILITY_PIXEL;
    }

    // For compute or any two combination of stages, visibility must be ALL
    return D3D12_SHADER_VISIBILITY_ALL;
}

D3D12_TEXTURE_COPY_LOCATION ComputeTextureCopyLocationForTexture(const Texture* texture,
                                                                 uint32_t level,
                                                                 uint32_t layer,
                                                                 Aspect aspect) {
    D3D12_TEXTURE_COPY_LOCATION copyLocation;
    copyLocation.pResource = texture->GetD3D12Resource();
    copyLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
    copyLocation.SubresourceIndex = texture->GetSubresourceIndex(level, layer, aspect);

    return copyLocation;
}

D3D12_BOX ComputeD3D12BoxFromOffsetAndSize(const TexelOrigin3D& offset,
                                           const TexelExtent3D& copySize) {
    D3D12_BOX sourceRegion;
    sourceRegion.left = dchecked_cast<UINT>(offset.x);
    sourceRegion.top = dchecked_cast<UINT>(offset.y);
    sourceRegion.front = dchecked_cast<UINT>(offset.z);
    sourceRegion.right = dchecked_cast<UINT>(offset.x + copySize.width);
    sourceRegion.bottom = dchecked_cast<UINT>(offset.y + copySize.height);
    sourceRegion.back = dchecked_cast<UINT>(offset.z + copySize.depthOrArrayLayers);
    return sourceRegion;
}

void RecordBufferTextureCopyFromSplits(BufferTextureCopyDirection direction,
                                       ID3D12GraphicsCommandList* commandList,
                                       const TextureCopySubresource& baseCopySplit,
                                       ID3D12Resource* bufferResource,
                                       uint64_t baseOffset,
                                       BlockCount bufferBlocksPerRow,
                                       const TypedTexelBlockInfo& blockInfo,
                                       TextureBase* textureBase,
                                       uint32_t textureMiplevel,
                                       BlockCount textureLayer,
                                       Aspect aspect) {
    Texture* texture = ToBackend(textureBase);
    const D3D12_TEXTURE_COPY_LOCATION textureLocation = ComputeTextureCopyLocationForTexture(
        texture, textureMiplevel, dchecked_cast<uint32_t>(textureLayer), aspect);
    uint64_t bufferBytesPerRow = blockInfo.ToBytes(bufferBlocksPerRow);

    for (uint32_t i = 0; i < baseCopySplit.count; ++i) {
        const TextureCopySubresource::CopyInfo& info = baseCopySplit.copies[i];

        TexelOrigin3D textureOffset = blockInfo.ToTexel(info.textureOffset);
        TexelOrigin3D bufferOffset = blockInfo.ToTexel(info.bufferOffset);
        TexelExtent3D copySize = blockInfo.ToTexel(info.copySize);
        TexelExtent3D bufferSize = blockInfo.ToTexel(info.bufferSize);

        const uint64_t offsetBytes = info.alignedOffset + baseOffset;
        const D3D12_TEXTURE_COPY_LOCATION bufferLocation =
            ComputeBufferLocationForCopyTextureRegion(
                texture, bufferResource, bufferSize, offsetBytes,
                dchecked_cast<uint32_t>(bufferBytesPerRow), aspect);

        if (direction == BufferTextureCopyDirection::B2T) {
            const D3D12_BOX sourceRegion = ComputeD3D12BoxFromOffsetAndSize(bufferOffset, copySize);
            const Origin3D to = textureOffset.ToOrigin3D();
            commandList->CopyTextureRegion(&textureLocation, to.x, to.y, to.z, &bufferLocation,
                                           &sourceRegion);
        } else {
            DAWN_ASSERT(direction == BufferTextureCopyDirection::T2B);
            const D3D12_BOX sourceRegion =
                ComputeD3D12BoxFromOffsetAndSize(textureOffset, copySize);
            const Origin3D bo = bufferOffset.ToOrigin3D();
            commandList->CopyTextureRegion(&bufferLocation, bo.x, bo.y, bo.z, &textureLocation,
                                           &sourceRegion);
        }
    }
}

void Record2DBufferTextureCopyWithSplit(BufferTextureCopyDirection direction,
                                        ID3D12GraphicsCommandList* commandList,
                                        ID3D12Resource* bufferResource,
                                        uint64_t offset,
                                        BlockCount blocksPerRow,
                                        BlockCount rowsPerImage,
                                        const TextureCopy& textureCopy,
                                        const TypedTexelBlockInfo& blockInfo,
                                        const BlockExtent3D& copySize) {
    // See comments in Compute2DTextureCopySplits() for more details.
    const TextureCopySplits copySplits = Compute2DTextureCopySplits(
        blockInfo.ToBlock(textureCopy.origin), copySize, blockInfo.ToTexelBlockInfo(), offset,
        blocksPerRow, rowsPerImage);

    const uint64_t bytesPerLayer = blockInfo.ToBytes(blocksPerRow * rowsPerImage);

    // copySplits.copySubresources[1] is always calculated for the second copy layer with
    // extra "bytesPerLayer" copy offset compared with the first copy layer. So
    // here we use an array bufferOffsetsForNextLayer to record the extra offsets
    // for each copy layer: bufferOffsetsForNextLayer[0] is the extra offset for
    // the next copy layer that uses copySplits.copySubresources[0], and
    // bufferOffsetsForNextLayer[1] is the extra offset for the next copy layer
    // that uses copySplits.copySubresources[1].
    std::array<uint64_t, TextureCopySplits::kMaxTextureCopySubresources> bufferOffsetsForNextLayer =
        {{0u, 0u}};

    for (BlockCount copyLayer : Range(copySize.depthOrArrayLayers)) {
        const uint32_t splitIndex =
            dchecked_cast<uint32_t>(copyLayer) % copySplits.copySubresources.size();

        const TextureCopySubresource& copyResourcePerLayer =
            copySplits.copySubresources[splitIndex];
        const uint64_t bufferOffsetForNextLayer = bufferOffsetsForNextLayer[splitIndex];
        const BlockCount copyTextureLayer = copyLayer + blockInfo.ToBlock(textureCopy.origin).z;

        RecordBufferTextureCopyFromSplits(
            direction, commandList, copyResourcePerLayer, bufferResource, bufferOffsetForNextLayer,
            blocksPerRow, blockInfo, textureCopy.texture.Get(), textureCopy.mipLevel,
            copyTextureLayer, textureCopy.aspect);

        bufferOffsetsForNextLayer[splitIndex] += bytesPerLayer * copySplits.copySubresources.size();
    }
}

void Record2DBufferTextureCopyWithRelaxedOffsetAndPitch(BufferTextureCopyDirection direction,
                                                        ID3D12GraphicsCommandList* commandList,
                                                        ID3D12Resource* bufferResource,
                                                        const uint64_t offset,
                                                        BlockCount blocksPerRow,
                                                        BlockCount rowsPerImage,
                                                        const TextureCopy& textureCopy,
                                                        const TypedTexelBlockInfo& blockInfo,
                                                        const BlockExtent3D& copySize) {
    TextureCopySubresource copySubresource = Compute2DTextureCopySubresource(
        blockInfo.ToBlock(textureCopy.origin), copySize, blockInfo, offset, blocksPerRow, true);

    const uint64_t bytesPerLayer = blockInfo.ToBytes(blocksPerRow * rowsPerImage);
    uint64_t bufferOffsetForNextLayer = 0;
    for (BlockCount copyLayer : Range(copySize.depthOrArrayLayers)) {
        BlockCount copyTextureLayer = copyLayer + blockInfo.ToBlock(textureCopy.origin).z;
        RecordBufferTextureCopyFromSplits(direction, commandList, copySubresource, bufferResource,
                                          bufferOffsetForNextLayer, blocksPerRow, blockInfo,
                                          textureCopy.texture.Get(), textureCopy.mipLevel,
                                          copyTextureLayer, textureCopy.aspect);
        bufferOffsetForNextLayer += bytesPerLayer;
    }
}

void RecordBufferTextureCopyWithBufferHandle(BufferTextureCopyDirection direction,
                                             ID3D12GraphicsCommandList* commandList,
                                             ID3D12Resource* bufferResource,
                                             uint64_t offset,
                                             BlockCount blocksPerRow,
                                             BlockCount rowsPerImage,
                                             const TextureCopy& textureCopy,
                                             const BlockExtent3D& copySize) {
    DAWN_ASSERT(HasOneBit(textureCopy.aspect));

    TextureBase* texture = textureCopy.texture.Get();
    const TypedTexelBlockInfo& blockInfo = GetBlockInfo(textureCopy);
    BlockOrigin3D origin = blockInfo.ToBlock(textureCopy.origin);

    bool useRelaxedRowPitchAndOffset = texture->GetDevice()->IsToggleEnabled(
        Toggle::D3D12RelaxBufferTextureCopyPitchAndOffsetAlignment);

    switch (texture->GetDimension()) {
        case wgpu::TextureDimension::Undefined:
            DAWN_UNREACHABLE();

        case wgpu::TextureDimension::e1D: {
            // 1D textures copy splits are a subset of the single-layer 2D texture copy splits,
            // at least while 1D textures can only have a single array layer.
            DAWN_ASSERT(texture->GetArrayLayers() == 1);
            TextureCopySubresource copySubresource = Compute2DTextureCopySubresource(
                origin, copySize, blockInfo, offset, blocksPerRow, useRelaxedRowPitchAndOffset);
            RecordBufferTextureCopyFromSplits(
                direction, commandList, copySubresource, bufferResource, 0, blocksPerRow, blockInfo,
                texture, textureCopy.mipLevel, BlockCount{0u}, textureCopy.aspect);
            break;
        }

        // Record the CopyTextureRegion commands for 2D textures, with special handling of array
        // layers since each require their own set of copies.
        case wgpu::TextureDimension::e2D:
            if (useRelaxedRowPitchAndOffset) {
                // This function calls RecordBufferTextureCopyFromSplits
                Record2DBufferTextureCopyWithRelaxedOffsetAndPitch(
                    direction, commandList, bufferResource, offset, blocksPerRow, rowsPerImage,
                    textureCopy, blockInfo, copySize);
            } else {
                // This function calls RecordBufferTextureCopyFromSplits
                Record2DBufferTextureCopyWithSplit(direction, commandList, bufferResource, offset,
                                                   blocksPerRow, rowsPerImage, textureCopy,
                                                   blockInfo, copySize);
            }
            break;

        case wgpu::TextureDimension::e3D: {
            TextureCopySubresource copySubresource =
                Compute3DTextureCopySubresource(origin, copySize, blockInfo, offset, blocksPerRow,
                                                rowsPerImage, useRelaxedRowPitchAndOffset);
            RecordBufferTextureCopyFromSplits(
                direction, commandList, copySubresource, bufferResource, 0, blocksPerRow, blockInfo,
                texture, textureCopy.mipLevel, BlockCount{0u}, textureCopy.aspect);
            break;
        }
    }
}

void RecordBufferTextureCopy(BufferTextureCopyDirection direction,
                             ID3D12GraphicsCommandList* commandList,
                             const BufferCopy& bufferCopy,
                             const TextureCopy& textureCopy,
                             const BlockExtent3D& copySize) {
    const TypedTexelBlockInfo& blockInfo = GetBlockInfo(textureCopy);
    ID3D12Resource* bufferResource = ToBackend(bufferCopy.buffer)->GetD3D12Resource();

    if (NeedBufferSizeWorkaroundForBufferTextureCopyOnD3D12(bufferCopy, textureCopy, copySize)) {
        // Split the copy into two copies if the size of bufferCopy.buffer doesn't meet D3D12's
        // requirement and a workaround is needed:
        //   - The first copy will copy all depth images but the last depth image, including
        //     padding rows.
        //   - The second copy will copy the last depth image, skipping the padding rows between
        //     the second-to-last and last image.
        BlockExtent3D extentForAllButTheLastImage = copySize;
        extentForAllButTheLastImage.depthOrArrayLayers -= BlockCount{1u};
        RecordBufferTextureCopyWithBufferHandle(
            direction, commandList, bufferResource, bufferCopy.offset, bufferCopy.blocksPerRow,
            bufferCopy.rowsPerImage, textureCopy, extentForAllButTheLastImage);

        BlockExtent3D extentForTheLastImage = copySize;
        extentForTheLastImage.depthOrArrayLayers = BlockCount{1u};

        TextureCopy textureCopyForTheLastImage = textureCopy;
        textureCopyForTheLastImage.origin.z +=
            blockInfo.ToTexelDepth(copySize.depthOrArrayLayers) - TexelCount{1u};

        // We offset the copy so that we skip the padding rows. This way the footprint Height
        // will be computed without this padding.
        uint64_t copiedBytes = blockInfo.ToBytes(bufferCopy.blocksPerRow * bufferCopy.rowsPerImage *
                                                 (copySize.depthOrArrayLayers - BlockCount{1u}));
        RecordBufferTextureCopyWithBufferHandle(direction, commandList, bufferResource,
                                                bufferCopy.offset + copiedBytes,
                                                bufferCopy.blocksPerRow, bufferCopy.rowsPerImage,
                                                textureCopyForTheLastImage, extentForTheLastImage);
        return;
    }

    RecordBufferTextureCopyWithBufferHandle(direction, commandList, bufferResource,
                                            bufferCopy.offset, bufferCopy.blocksPerRow,
                                            bufferCopy.rowsPerImage, textureCopy, copySize);
}

void SetDebugName(Device* device, ID3D12Object* object, const char* prefix, std::string label) {
    if (!device->IsToggleEnabled(Toggle::UseUserDefinedLabelsInBackend)) {
        return;
    }

    if (!object) {
        return;
    }

    if (label.empty()) {
        object->SetPrivateData(WKPDID_D3DDebugObjectName, static_cast<uint32_t>(strlen(prefix)),
                               prefix);
        return;
    }

    std::string objectName = prefix;
    objectName += "_";
    objectName += label;
    object->SetPrivateData(WKPDID_D3DDebugObjectName, static_cast<uint32_t>(objectName.length()),
                           objectName.c_str());
}

D3D12_HEAP_TYPE GetD3D12HeapType(ResourceHeapKind resourceHeapKind) {
    switch (resourceHeapKind) {
        case ResourceHeapKind::Readback_OnlyBuffers:
        case ResourceHeapKind::Readback_AllBuffersAndTextures:
            return D3D12_HEAP_TYPE_READBACK;
        case ResourceHeapKind::Default_AllBuffersAndTextures:
        case ResourceHeapKind::Default_OnlyBuffers:
        case ResourceHeapKind::Default_OnlyNonRenderableOrDepthTextures:
        case ResourceHeapKind::Default_OnlyRenderableOrDepthTextures:
            return D3D12_HEAP_TYPE_DEFAULT;
        case ResourceHeapKind::Upload_OnlyBuffers:
        case ResourceHeapKind::Upload_AllBuffersAndTextures:
            return D3D12_HEAP_TYPE_UPLOAD;
        case ResourceHeapKind::Custom_WriteBack_OnlyBuffers:
            return D3D12_HEAP_TYPE_CUSTOM;
        case EnumCount:
        default:
            DAWN_UNREACHABLE();
    }
}

D3D12_HEAP_PROPERTIES GetD3D12HeapProperties(ResourceHeapKind resourceHeapKind) {
    D3D12_HEAP_PROPERTIES heapProperties = {};

    heapProperties.Type = GetD3D12HeapType(resourceHeapKind);

    // Now we only use `Custom_WriteBack_OnlyBuffers` resource heap on cache coherent UMA
    // architecture, where applications can more strongly entertain abandoning the attribution of
    // heaps and using the custom heap equivalent of upload heaps everywhere, and the upload heaps
    // are actually write-back on CacheCoherentUMA. See below link for more details:
    // https://learn.microsoft.com/en-us/windows/win32/api/d3d12/ns-d3d12-d3d12_feature_data_architecture
    if (resourceHeapKind == Custom_WriteBack_OnlyBuffers) {
        heapProperties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_WRITE_BACK;
        heapProperties.MemoryPoolPreference = D3D12_MEMORY_POOL_L0;
    } else {
        heapProperties.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
        heapProperties.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
    }

    heapProperties.CreationNodeMask = 0;
    heapProperties.VisibleNodeMask = 0;

    return heapProperties;
}

}  // namespace dawn::native::d3d12
