// Copyright 2019 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/UtilsD3D12.h"

#include "common/Assert.h"
#include "dawn_native/Format.h"
#include "dawn_native/d3d12/BufferD3D12.h"
#include "dawn_native/d3d12/CommandRecordingContext.h"
#include "dawn_native/d3d12/D3D12Error.h"
#include "dawn_native/d3d12/DeviceD3D12.h"

#include <stringapiset.h>

namespace dawn::native::d3d12 {

    ResultOrError<std::wstring> ConvertStringToWstring(const char* str) {
        size_t len = strlen(str);
        if (len == 0) {
            return std::wstring();
        }
        int numChars = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, str, len, nullptr, 0);
        if (numChars == 0) {
            return DAWN_INTERNAL_ERROR("Failed to convert string to wide string");
        }
        std::wstring result;
        result.resize(numChars);
        int numConvertedChars =
            MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, str, len, &result[0], numChars);
        if (numConvertedChars != numChars) {
            return DAWN_INTERNAL_ERROR("Failed to convert string to wide string");
        }
        return std::move(result);
    }

    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:
                UNREACHABLE();
        }
    }

    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_TEXTURE_COPY_LOCATION ComputeBufferLocationForCopyTextureRegion(
        const Texture* texture,
        ID3D12Resource* bufferResource,
        const Extent3D& 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 = bufferSize.width;
        bufferLocation.PlacedFootprint.Footprint.Height = bufferSize.height;
        bufferLocation.PlacedFootprint.Footprint.Depth = bufferSize.depthOrArrayLayers;
        bufferLocation.PlacedFootprint.Footprint.RowPitch = rowPitch;
        return bufferLocation;
    }

    D3D12_BOX ComputeD3D12BoxFromOffsetAndSize(const Origin3D& offset, const Extent3D& copySize) {
        D3D12_BOX sourceRegion;
        sourceRegion.left = offset.x;
        sourceRegion.top = offset.y;
        sourceRegion.front = offset.z;
        sourceRegion.right = offset.x + copySize.width;
        sourceRegion.bottom = offset.y + copySize.height;
        sourceRegion.back = offset.z + copySize.depthOrArrayLayers;
        return sourceRegion;
    }

    bool IsTypeless(DXGI_FORMAT format) {
        // List generated from <dxgiformat.h>
        switch (format) {
            case DXGI_FORMAT_R32G32B32A32_TYPELESS:
            case DXGI_FORMAT_R32G32B32_TYPELESS:
            case DXGI_FORMAT_R16G16B16A16_TYPELESS:
            case DXGI_FORMAT_R32G32_TYPELESS:
            case DXGI_FORMAT_R32G8X24_TYPELESS:
            case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
            case DXGI_FORMAT_R10G10B10A2_TYPELESS:
            case DXGI_FORMAT_R8G8B8A8_TYPELESS:
            case DXGI_FORMAT_R16G16_TYPELESS:
            case DXGI_FORMAT_R32_TYPELESS:
            case DXGI_FORMAT_R24G8_TYPELESS:
            case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
            case DXGI_FORMAT_R8G8_TYPELESS:
            case DXGI_FORMAT_R16_TYPELESS:
            case DXGI_FORMAT_R8_TYPELESS:
            case DXGI_FORMAT_BC1_TYPELESS:
            case DXGI_FORMAT_BC2_TYPELESS:
            case DXGI_FORMAT_BC3_TYPELESS:
            case DXGI_FORMAT_BC4_TYPELESS:
            case DXGI_FORMAT_BC5_TYPELESS:
            case DXGI_FORMAT_B8G8R8A8_TYPELESS:
            case DXGI_FORMAT_B8G8R8X8_TYPELESS:
            case DXGI_FORMAT_BC6H_TYPELESS:
            case DXGI_FORMAT_BC7_TYPELESS:
                return true;
            default:
                return false;
        }
    }

    void RecordCopyBufferToTextureFromTextureCopySplit(ID3D12GraphicsCommandList* commandList,
                                                       const TextureCopySubresource& baseCopySplit,
                                                       ID3D12Resource* bufferResource,
                                                       uint64_t baseOffset,
                                                       uint64_t bufferBytesPerRow,
                                                       Texture* texture,
                                                       uint32_t textureMiplevel,
                                                       uint32_t textureLayer,
                                                       Aspect aspect) {
        ASSERT(HasOneBit(aspect));
        const D3D12_TEXTURE_COPY_LOCATION textureLocation =
            ComputeTextureCopyLocationForTexture(texture, textureMiplevel, textureLayer, aspect);

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

            // TODO(jiawei.shao@intel.com): pre-compute bufferLocation and sourceRegion as
            // members in TextureCopySubresource::CopyInfo.
            const uint64_t offsetBytes = info.alignedOffset + baseOffset;
            const D3D12_TEXTURE_COPY_LOCATION bufferLocation =
                ComputeBufferLocationForCopyTextureRegion(texture, bufferResource, info.bufferSize,
                                                          offsetBytes, bufferBytesPerRow, aspect);
            const D3D12_BOX sourceRegion =
                ComputeD3D12BoxFromOffsetAndSize(info.bufferOffset, info.copySize);

            commandList->CopyTextureRegion(&textureLocation, info.textureOffset.x,
                                           info.textureOffset.y, info.textureOffset.z,
                                           &bufferLocation, &sourceRegion);
        }
    }

    void CopyBufferTo2DTextureWithCopySplit(CommandRecordingContext* commandContext,
                                            const TextureCopy& textureCopy,
                                            ID3D12Resource* bufferResource,
                                            const uint64_t offset,
                                            const uint32_t bytesPerRow,
                                            const uint32_t rowsPerImage,
                                            const Extent3D& copySize,
                                            Texture* texture,
                                            Aspect aspect) {
        ASSERT(HasOneBit(aspect));
        // See comments in Compute2DTextureCopySplits() for more details.
        const TexelBlockInfo& blockInfo = texture->GetFormat().GetAspectInfo(aspect).block;
        const TextureCopySplits copySplits = Compute2DTextureCopySplits(
            textureCopy.origin, copySize, blockInfo, offset, bytesPerRow, rowsPerImage);

        const uint64_t bytesPerLayer = bytesPerRow * 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 (uint32_t copyLayer = 0; copyLayer < copySize.depthOrArrayLayers; ++copyLayer) {
            const uint32_t splitIndex = copyLayer % copySplits.copySubresources.size();

            const TextureCopySubresource& copySplitPerLayerBase =
                copySplits.copySubresources[splitIndex];
            const uint64_t bufferOffsetForNextLayer = bufferOffsetsForNextLayer[splitIndex];
            const uint32_t copyTextureLayer = copyLayer + textureCopy.origin.z;

            RecordCopyBufferToTextureFromTextureCopySplit(
                commandContext->GetCommandList(), copySplitPerLayerBase, bufferResource,
                bufferOffsetForNextLayer, bytesPerRow, texture, textureCopy.mipLevel,
                copyTextureLayer, aspect);

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

    void CopyBufferTo3DTexture(CommandRecordingContext* commandContext,
                               const TextureCopy& textureCopy,
                               ID3D12Resource* bufferResource,
                               const uint64_t offset,
                               const uint32_t bytesPerRow,
                               const uint32_t rowsPerImage,
                               const Extent3D& copySize,
                               Texture* texture,
                               Aspect aspect) {
        ASSERT(HasOneBit(aspect));
        // See comments in Compute3DTextureCopySplits() for more details.
        const TexelBlockInfo& blockInfo = texture->GetFormat().GetAspectInfo(aspect).block;
        const TextureCopySubresource copyRegions = Compute3DTextureCopySplits(
            textureCopy.origin, copySize, blockInfo, offset, bytesPerRow, rowsPerImage);

        RecordCopyBufferToTextureFromTextureCopySplit(commandContext->GetCommandList(), copyRegions,
                                                      bufferResource, 0, bytesPerRow, texture,
                                                      textureCopy.mipLevel, 0, aspect);
    }

    void RecordCopyBufferToTexture(CommandRecordingContext* commandContext,
                                   const TextureCopy& textureCopy,
                                   ID3D12Resource* bufferResource,
                                   const uint64_t offset,
                                   const uint32_t bytesPerRow,
                                   const uint32_t rowsPerImage,
                                   const Extent3D& copySize,
                                   Texture* texture,
                                   Aspect aspect) {
        // Record the CopyTextureRegion commands for 3D textures. Multiple depths of 3D
        // textures can be copied in one shot and copySplits are not needed.
        if (texture->GetDimension() == wgpu::TextureDimension::e3D) {
            CopyBufferTo3DTexture(commandContext, textureCopy, bufferResource, offset, bytesPerRow,
                                  rowsPerImage, copySize, texture, aspect);
        } else {
            // Compute the copySplits and record the CopyTextureRegion commands for 2D
            // textures.
            CopyBufferTo2DTextureWithCopySplit(commandContext, textureCopy, bufferResource, offset,
                                               bytesPerRow, rowsPerImage, copySize, texture,
                                               aspect);
        }
    }

    void RecordCopyTextureToBufferFromTextureCopySplit(ID3D12GraphicsCommandList* commandList,
                                                       const TextureCopySubresource& baseCopySplit,
                                                       Buffer* buffer,
                                                       uint64_t baseOffset,
                                                       uint64_t bufferBytesPerRow,
                                                       Texture* texture,
                                                       uint32_t textureMiplevel,
                                                       uint32_t textureLayer,
                                                       Aspect aspect) {
        const D3D12_TEXTURE_COPY_LOCATION textureLocation =
            ComputeTextureCopyLocationForTexture(texture, textureMiplevel, textureLayer, aspect);

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

            // TODO(jiawei.shao@intel.com): pre-compute bufferLocation and sourceRegion as
            // members in TextureCopySubresource::CopyInfo.
            const uint64_t offsetBytes = info.alignedOffset + baseOffset;
            const D3D12_TEXTURE_COPY_LOCATION bufferLocation =
                ComputeBufferLocationForCopyTextureRegion(texture, buffer->GetD3D12Resource(),
                                                          info.bufferSize, offsetBytes,
                                                          bufferBytesPerRow, aspect);
            const D3D12_BOX sourceRegion =
                ComputeD3D12BoxFromOffsetAndSize(info.textureOffset, info.copySize);

            commandList->CopyTextureRegion(&bufferLocation, info.bufferOffset.x,
                                           info.bufferOffset.y, info.bufferOffset.z,
                                           &textureLocation, &sourceRegion);
        }
    }

    void Copy2DTextureToBufferWithCopySplit(ID3D12GraphicsCommandList* commandList,
                                            const TextureCopy& textureCopy,
                                            const BufferCopy& bufferCopy,
                                            Texture* texture,
                                            Buffer* buffer,
                                            const Extent3D& copySize) {
        ASSERT(HasOneBit(textureCopy.aspect));
        const TexelBlockInfo& blockInfo =
            texture->GetFormat().GetAspectInfo(textureCopy.aspect).block;

        // See comments around Compute2DTextureCopySplits() for more details.
        const TextureCopySplits copySplits =
            Compute2DTextureCopySplits(textureCopy.origin, copySize, blockInfo, bufferCopy.offset,
                                       bufferCopy.bytesPerRow, bufferCopy.rowsPerImage);

        const uint64_t bytesPerLayer = bufferCopy.bytesPerRow * bufferCopy.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 (uint32_t copyLayer = 0; copyLayer < copySize.depthOrArrayLayers; ++copyLayer) {
            const uint32_t splitIndex = copyLayer % copySplits.copySubresources.size();

            const TextureCopySubresource& copySplitPerLayerBase =
                copySplits.copySubresources[splitIndex];
            const uint64_t bufferOffsetForNextLayer = bufferOffsetsForNextLayer[splitIndex];
            const uint32_t copyTextureLayer = copyLayer + textureCopy.origin.z;

            RecordCopyTextureToBufferFromTextureCopySplit(
                commandList, copySplitPerLayerBase, buffer, bufferOffsetForNextLayer,
                bufferCopy.bytesPerRow, texture, textureCopy.mipLevel, copyTextureLayer,
                textureCopy.aspect);

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

    void Copy3DTextureToBuffer(ID3D12GraphicsCommandList* commandList,
                               const TextureCopy& textureCopy,
                               const BufferCopy& bufferCopy,
                               Texture* texture,
                               Buffer* buffer,
                               const Extent3D& copySize) {
        ASSERT(HasOneBit(textureCopy.aspect));
        const TexelBlockInfo& blockInfo =
            texture->GetFormat().GetAspectInfo(textureCopy.aspect).block;

        // See comments around Compute3DTextureCopySplits() for more details.
        const TextureCopySubresource copyRegions =
            Compute3DTextureCopySplits(textureCopy.origin, copySize, blockInfo, bufferCopy.offset,
                                       bufferCopy.bytesPerRow, bufferCopy.rowsPerImage);

        RecordCopyTextureToBufferFromTextureCopySplit(commandList, copyRegions, buffer, 0,
                                                      bufferCopy.bytesPerRow, texture,
                                                      textureCopy.mipLevel, 0, textureCopy.aspect);
    }

    void RecordCopyTextureToBuffer(ID3D12GraphicsCommandList* commandList,
                                   const TextureCopy& textureCopy,
                                   const BufferCopy& bufferCopy,
                                   Texture* texture,
                                   Buffer* buffer,
                                   const Extent3D& copySize) {
        if (texture->GetDimension() == wgpu::TextureDimension::e3D) {
            Copy3DTextureToBuffer(commandList, textureCopy, bufferCopy, texture, buffer, copySize);
        } else {
            Copy2DTextureToBufferWithCopySplit(commandList, textureCopy, bufferCopy, texture,
                                               buffer, copySize);
        }
    }

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

        if (label.empty() || !device->IsToggleEnabled(Toggle::UseUserDefinedLabelsInBackend)) {
            object->SetPrivateData(WKPDID_D3DDebugObjectName, strlen(prefix), prefix);
            return;
        }

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

}  // namespace dawn::native::d3d12
