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

#include "common/GPUInfo.h"
#include "dawn_native/d3d12/AdapterD3D12.h"
#include "dawn_native/d3d12/BackendD3D12.h"
#include "dawn_native/d3d12/D3D12Error.h"
#include "dawn_native/d3d12/PlatformFunctions.h"

namespace dawn::native::d3d12 {

    ResultOrError<D3D12DeviceInfo> GatherDeviceInfo(const Adapter& adapter) {
        D3D12DeviceInfo info = {};

        // 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(adapter.GetDevice()->CheckFeatureSupport(D3D12_FEATURE_ARCHITECTURE,
                                                                       &arch, sizeof(arch)),
                              "ID3D12Device::CheckFeatureSupport"));

        info.isUMA = arch.UMA;

        D3D12_FEATURE_DATA_D3D12_OPTIONS options = {};
        DAWN_TRY(CheckHRESULT(adapter.GetDevice()->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS,
                                                                       &options, sizeof(options)),
                              "ID3D12Device::CheckFeatureSupport"));

        info.resourceHeapTier = options.ResourceHeapTier;

        // Windows builds 1809 and above can use the D3D12 render pass API. If we query
        // CheckFeatureSupport for D3D12_FEATURE_D3D12_OPTIONS5 successfully, then we can use
        // the render pass API.
        info.supportsRenderPass = false;
        D3D12_FEATURE_DATA_D3D12_OPTIONS5 featureOptions5 = {};
        if (SUCCEEDED(adapter.GetDevice()->CheckFeatureSupport(
                D3D12_FEATURE_D3D12_OPTIONS5, &featureOptions5, sizeof(featureOptions5)))) {
            // Performance regressions been observed when using a render pass on Intel graphics
            // with RENDER_PASS_TIER_1 available, so fall back to a software emulated render
            // pass on these platforms.
            if (featureOptions5.RenderPassesTier < D3D12_RENDER_PASS_TIER_1 ||
                !gpu_info::IsIntel(adapter.GetVendorId())) {
                info.supportsRenderPass = true;
            }
        }

        // 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(adapter.GetDevice()->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;
            }
        }

        D3D12_FEATURE_DATA_SHADER_MODEL knownShaderModels[] = {{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(adapter.GetDevice()->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
        ASSERT(driverShaderModel <= 0xFF);
        uint32_t shaderModelMajor = (driverShaderModel & 0xF0) >> 4;
        uint32_t shaderModelMinor = (driverShaderModel & 0xF);

        ASSERT(shaderModelMajor < 10);
        ASSERT(shaderModelMinor < 10);
        info.shaderModel = 10 * shaderModelMajor + shaderModelMinor;

        // Profiles are always <stage>s_<minor>_<major> so we build the s_<minor>_major and add
        // it to each of the stage's suffix.
        std::wstring profileSuffix = L"s_M_n";
        profileSuffix[2] = wchar_t('0' + shaderModelMajor);
        profileSuffix[4] = wchar_t('0' + shaderModelMinor);

        info.shaderProfiles[SingleShaderStage::Vertex] = L"v" + profileSuffix;
        info.shaderProfiles[SingleShaderStage::Fragment] = L"p" + profileSuffix;
        info.shaderProfiles[SingleShaderStage::Compute] = L"c" + profileSuffix;

        D3D12_FEATURE_DATA_D3D12_OPTIONS4 featureData4 = {};
        if (SUCCEEDED(adapter.GetDevice()->CheckFeatureSupport(
                D3D12_FEATURE_D3D12_OPTIONS4, &featureData4, sizeof(featureData4)))) {
            info.supportsShaderFloat16 = driverShaderModel >= D3D_SHADER_MODEL_6_2 &&
                                         featureData4.Native16BitShaderOpsSupported;
        }

        return std::move(info);
    }

}  // namespace dawn::native::d3d12
