// 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/D3D12Info.h"

#include <array>
#include <utility>

#include "src/dawn/common/GPUInfo.h"
#include "src/dawn/native/d3d/D3DError.h"
#include "src/dawn/native/d3d12/BackendD3D12.h"
#include "src/dawn/native/d3d12/PhysicalDeviceD3D12.h"
#include "src/dawn/native/d3d12/PlatformFunctionsD3D12.h"

namespace dawn::native::d3d12 {

namespace {
#ifdef DAWN_USE_AGILITY_SDK
std::vector<D3D12DeviceInfo::LinAlgWMMSupport> GatherLinAlgWaveMatrixMultiplySupports(
    ComPtr<ID3D12Device> d3d12Device,
    uint32_t waveLaneCountMin) {
    std::vector<D3D12DeviceInfo::LinAlgWMMSupport> result;

    auto typesToQuery = std::array{
        D3D12_LINEAR_ALGEBRA_DATATYPE_SINT32,   //
        D3D12_LINEAR_ALGEBRA_DATATYPE_UINT32,   //
        D3D12_LINEAR_ALGEBRA_DATATYPE_FLOAT16,  //
        D3D12_LINEAR_ALGEBRA_DATATYPE_FLOAT32,  //
        D3D12_LINEAR_ALGEBRA_DATATYPE_SINT8,    //
        D3D12_LINEAR_ALGEBRA_DATATYPE_UINT8,    //
    };

    for (auto dataTypeAB : typesToQuery) {
        for (auto dataTypeAcc : typesToQuery) {
            D3D12_FEATURE_DATA_LINEAR_ALGEBRA_MATRIX_OPERATION_SUPPORT opSupport{};
            opSupport.OperationType = D3D12_LINEAR_ALGEBRA_OPERATION_TYPE_WAVE_MATRIX_MULTIPLY;
            opSupport.WaveMatrixMultiply = {};
            // Set WaveSize to waveLaneCountMin only. We assume if shapes are returned for this
            // size, they are supported for all supported wave sizes (waveLaneCountMin to
            // waveLaneCountMax).
            // TODO(crbug.com/527055544): We should be able to set this to '0' instead.
            DAWN_ASSERT(waveLaneCountMin != 0);
            opSupport.WaveMatrixMultiply.Inputs.WaveSize = waveLaneCountMin;
            opSupport.WaveMatrixMultiply.Inputs.MatrixAComponentType = dataTypeAB;
            opSupport.WaveMatrixMultiply.Inputs.MatrixBComponentType = dataTypeAB;
            opSupport.WaveMatrixMultiply.Inputs.AccumulatorComponentType = dataTypeAcc;

            // First call to get number of shapes
            opSupport.WaveMatrixMultiply.NumShapes = 0;
            opSupport.WaveMatrixMultiply.Shapes = nullptr;

            if (FAILED(d3d12Device->CheckFeatureSupport(
                    D3D12_FEATURE_LINEAR_ALGEBRA_LINEAR_ALGEBRA_MATRIX_OPERATION_SUPPORT,
                    &opSupport, sizeof(opSupport)))) {
                continue;
            }

            uint32_t numShapes = opSupport.WaveMatrixMultiply.NumShapes;
            if (numShapes == 0) {
                continue;
            }

            // Second call to populate shapes
            std::vector<D3D12_LINEAR_ALGEBRA_MATRIX_MULTIPLY_SHAPE> shapes(numShapes);
            opSupport.WaveMatrixMultiply.Shapes = shapes.data();

            if (FAILED(d3d12Device->CheckFeatureSupport(
                    D3D12_FEATURE_LINEAR_ALGEBRA_LINEAR_ALGEBRA_MATRIX_OPERATION_SUPPORT,
                    &opSupport, sizeof(opSupport)))) {
                continue;
            }

            // Add support entry
            auto wmm = opSupport.WaveMatrixMultiply;
            wmm.Shapes = nullptr;  // Clear so that we don't attempt to use this
            result.emplace_back(wmm.Inputs, wmm.SupportFlags, std::move(shapes));
        }
    }

    return result;
}
#endif  // DAWN_USE_AGILITY_SDK
}  // namespace

ResultOrError<D3D12DeviceInfo> GatherDeviceInfo(const PhysicalDevice& physicalDevice) {
    D3D12DeviceInfo info = {};

    ComPtr<ID3D12Device> d3d12Device = physicalDevice.GetDevice();

    // Newer builds replace D3D_FEATURE_DATA_ARCHITECTURE with
    // D3D_FEATURE_DATA_ARCHITECTURE1. However, D3D_FEATURE_DATA_ARCHITECTURE can be used
    // for backwards compat.
    // https://docs.microsoft.com/en-us/windows/desktop/api/d3d12/ne-d3d12-d3d12_feature
    D3D12_FEATURE_DATA_ARCHITECTURE arch = {};
    DAWN_TRY(CheckHRESULT(
        d3d12Device->CheckFeatureSupport(D3D12_FEATURE_ARCHITECTURE, &arch, sizeof(arch)),
        "ID3D12Device::CheckFeatureSupport"));

    info.isUMA = arch.UMA;
    info.isCacheCoherentUMA = arch.CacheCoherentUMA;

    D3D12_FEATURE_DATA_D3D12_OPTIONS featureOptions = {};
    DAWN_TRY(CheckHRESULT(d3d12Device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS,
                                                           &featureOptions, sizeof(featureOptions)),
                          "ID3D12Device::CheckFeatureSupport"));
    info.resourceHeapTier = featureOptions.ResourceHeapTier;
    info.resourceBindingTier = featureOptions.ResourceBindingTier;

    D3D12_FEATURE_DATA_D3D12_OPTIONS2 featureOptions2 = {};
    if (SUCCEEDED(d3d12Device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS2, &featureOptions2,
                                                   sizeof(featureOptions2)))) {
        info.programmableSamplePositionsTier = featureOptions2.ProgrammableSamplePositionsTier;
    }

    D3D12_FEATURE_DATA_D3D12_OPTIONS3 featureOptions3 = {};
    if (SUCCEEDED(d3d12Device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS3, &featureOptions3,
                                                   sizeof(featureOptions3)))) {
        info.supportsCastingFullyTypedFormat = featureOptions3.CastingFullyTypedFormatSupported;
    }

    // Used to share resources cross-API. If we query CheckFeatureSupport for
    // D3D12_FEATURE_D3D12_OPTIONS4 successfully, then we can use cross-API sharing.
    info.supportsSharedResourceCapabilityTier1 = false;
    D3D12_FEATURE_DATA_D3D12_OPTIONS4 featureOptions4 = {};
    if (SUCCEEDED(d3d12Device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS4, &featureOptions4,
                                                   sizeof(featureOptions4)))) {
        // Tier 1 support additionally enables the NV12 format. Since only the NV12 format
        // is used by Dawn, check for Tier 1.
        if (featureOptions4.SharedResourceCompatibilityTier >=
            D3D12_SHARED_RESOURCE_COMPATIBILITY_TIER_1) {
            info.supportsSharedResourceCapabilityTier1 = true;
        }

        // featureOptions4.MSAA64KBAlignedTextureSupported indicates whether 64KB-aligned MSAA
        // textures are supported.
        info.use64KBAlignedMSAATexture = featureOptions4.MSAA64KBAlignedTextureSupported;

        // To support shader f16 feature, both featureOptions4.Native16BitShaderOpsSupported and
        // using shader model version >= 6.2 are required.
        info.supportsNative16BitShaderOps = featureOptions4.Native16BitShaderOpsSupported;
    }

    // D3D12_HEAP_FLAG_CREATE_NOT_ZEROED is available anytime that ID3D12Device8 is exposed, or a
    // check for D3D12_FEATURE_D3D12_OPTIONS7 succeeds.
    D3D12_FEATURE_DATA_D3D12_OPTIONS7 featureOptions7 = {};
    if (SUCCEEDED(d3d12Device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS7, &featureOptions7,
                                                   sizeof(featureOptions7)))) {
        info.supportsHeapFlagCreateNotZeroed = true;
    }

    D3D12_FEATURE_DATA_D3D12_OPTIONS8 featureOptions8 = {};
    if (SUCCEEDED(d3d12Device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS8, &featureOptions8,
                                                   sizeof(featureOptions8)))) {
        info.supportsTextureCompressionUnaligned = featureOptions8.UnalignedBlockTexturesSupported;
    }

    D3D12_FEATURE_DATA_D3D12_OPTIONS13 featureOptions13 = {};
    if (SUCCEEDED(d3d12Device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS13, &featureOptions13,
                                                   sizeof(featureOptions13)))) {
        info.supportsTextureCopyBetweenDimensions =
            featureOptions13.TextureCopyBetweenDimensionsSupported;
        info.supportsUnrestrictedBufferTextureCopyPitch =
            featureOptions13.UnrestrictedBufferTextureCopyPitchSupported;
    }

#if D3D12_SDK_VERSION >= 612
    D3D12_FEATURE_DATA_D3D12_OPTIONS18 featureOptions18 = {};
    if (SUCCEEDED(d3d12Device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS18, &featureOptions18,
                                                   sizeof(featureOptions18)))) {
        info.supportsRenderPass = featureOptions18.RenderPassesValid;
    }
#endif

    info.supportsRootSignatureVersion1_1 = false;
    D3D12_FEATURE_DATA_ROOT_SIGNATURE featureDataRootSignature = {};
    featureDataRootSignature.HighestVersion = D3D_ROOT_SIGNATURE_VERSION_1_1;
    if (SUCCEEDED(d3d12Device->CheckFeatureSupport(D3D12_FEATURE_ROOT_SIGNATURE,
                                                   &featureDataRootSignature,
                                                   sizeof(featureDataRootSignature)))) {
        info.supportsRootSignatureVersion1_1 =
            featureDataRootSignature.HighestVersion >= D3D_ROOT_SIGNATURE_VERSION_1_1;
    }

    D3D12_FEATURE_DATA_EXISTING_HEAPS existingHeapInfo = {};
    if (SUCCEEDED(d3d12Device->CheckFeatureSupport(D3D12_FEATURE_EXISTING_HEAPS, &existingHeapInfo,
                                                   sizeof(existingHeapInfo)))) {
        info.supportsExistingHeap = existingHeapInfo.Supported;
    }

    // D3D_SHADER_MODEL_6_10 is only defined in the Agility SDK headers; guard it
    // so builds that fall back to the Windows SDK header still compile.
    D3D12_FEATURE_DATA_SHADER_MODEL knownShaderModels[] = {
#ifdef DAWN_USE_AGILITY_SDK
        {D3D_SHADER_MODEL_6_10},
#endif
        {D3D_SHADER_MODEL_6_9},  {D3D_SHADER_MODEL_6_8}, {D3D_SHADER_MODEL_6_7},
        {D3D_SHADER_MODEL_6_6},  {D3D_SHADER_MODEL_6_5}, {D3D_SHADER_MODEL_6_4},
        {D3D_SHADER_MODEL_6_3},  {D3D_SHADER_MODEL_6_2}, {D3D_SHADER_MODEL_6_1},
        {D3D_SHADER_MODEL_6_0},  {D3D_SHADER_MODEL_5_1}};

    uint32_t driverShaderModel = 0;
    for (D3D12_FEATURE_DATA_SHADER_MODEL shaderModel : knownShaderModels) {
        if (SUCCEEDED(d3d12Device->CheckFeatureSupport(D3D12_FEATURE_SHADER_MODEL, &shaderModel,
                                                       sizeof(shaderModel)))) {
            driverShaderModel = shaderModel.HighestShaderModel;
            break;
        }
    }

    if (driverShaderModel < D3D_SHADER_MODEL_5_1) {
        return DAWN_INTERNAL_ERROR("Driver doesn't support Shader Model 5.1 or higher");
    }

    // D3D_SHADER_MODEL is encoded as 0xMm with M the major version and m the minor version

    DAWN_ASSERT(driverShaderModel <= 0xFF);
    uint32_t shaderModelMajor = (driverShaderModel & 0xF0) >> 4;
    uint32_t shaderModelMinor = (driverShaderModel & 0xF);

    DAWN_ASSERT(shaderModelMajor < 10);
    DAWN_ASSERT(shaderModelMinor < 16);
    // TODO(crbug.com/513251803): Don't use shader model as decimal value
    info.highestSupportedShaderModel = 10 * shaderModelMajor + shaderModelMinor;

    // Device support wave intrinsics if shader model >= SM6.0 and capabilities flag WaveOps is set.
    // https://github.com/Microsoft/DirectXShaderCompiler/wiki/Wave-Intrinsics
    if (driverShaderModel >= D3D_SHADER_MODEL_6_0) {
        D3D12_FEATURE_DATA_D3D12_OPTIONS1 featureOptions1 = {};
        if (SUCCEEDED(d3d12Device->CheckFeatureSupport(
                D3D12_FEATURE_D3D12_OPTIONS1, &featureOptions1, sizeof(featureOptions1)))) {
            info.supportsWaveOps = featureOptions1.WaveOps;
            info.waveLaneCountMin = featureOptions1.WaveLaneCountMin;
            // Currently the WaveLaneCountMax queried from D3D12 API is not reliable and the meaning
            // is unclear. The result is recorded into D3D12DeviceInfo, but is not intended to be
            // used now.
            info.waveLaneCountMax = featureOptions1.WaveLaneCountMax;

            if (driverShaderModel >= D3D_SHADER_MODEL_6_6 && featureOptions1.Int64ShaderOps) {
                D3D12_FEATURE_DATA_D3D12_OPTIONS9 featureOptions9 = {};
                if (SUCCEEDED(d3d12Device->CheckFeatureSupport(
                        D3D12_FEATURE_D3D12_OPTIONS9, &featureOptions9, sizeof(featureOptions9)))) {
                    info.supportsInt64Atomics = featureOptions9.AtomicInt64OnTypedResourceSupported;
                }
            }
        }
    }
    {
        DXGI_ADAPTER_DESC adapterDesc;
        DAWN_TRY(CheckHRESULT(physicalDevice.GetHardwareAdapter()->GetDesc(&adapterDesc),
                              "IDXGIAdapter3::GetDesc"));
        info.dedicatedVideoMemory = adapterDesc.DedicatedVideoMemory;
        info.sharedSystemMemory = adapterDesc.SharedSystemMemory;
    }

#ifdef DAWN_USE_AGILITY_SDK
    info.linAlgWaveMatrixMultiplySupports =
        GatherLinAlgWaveMatrixMultiplySupports(d3d12Device, info.waveLaneCountMin);
#endif

    return std::move(info);
}

}  // namespace dawn::native::d3d12
