// 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
