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

#include "dawn_native/vulkan/BackendVk.h"
#include "dawn_native/vulkan/DeviceVk.h"

#include "common/GPUInfo.h"

namespace dawn_native { namespace vulkan {

    Adapter::Adapter(Backend* backend, VkPhysicalDevice physicalDevice)
        : AdapterBase(backend->GetInstance(), wgpu::BackendType::Vulkan),
          mPhysicalDevice(physicalDevice),
          mBackend(backend) {
    }

    const VulkanDeviceInfo& Adapter::GetDeviceInfo() const {
        return mDeviceInfo;
    }

    VkPhysicalDevice Adapter::GetPhysicalDevice() const {
        return mPhysicalDevice;
    }

    Backend* Adapter::GetBackend() const {
        return mBackend;
    }

    MaybeError Adapter::Initialize() {
        DAWN_TRY_ASSIGN(mDeviceInfo, GatherDeviceInfo(*this));
        DAWN_TRY(CheckCoreWebGPUSupport());

        if (mDeviceInfo.HasExt(DeviceExt::DriverProperties)) {
            mDriverDescription = mDeviceInfo.driverProperties.driverName;
            if (mDeviceInfo.driverProperties.driverInfo[0] != '\0') {
                mDriverDescription += std::string(": ") + mDeviceInfo.driverProperties.driverInfo;
            }
        } else {
            mDriverDescription =
                "Vulkan driver version: " + std::to_string(mDeviceInfo.properties.driverVersion);
        }

        InitializeSupportedFeatures();

        mPCIInfo.deviceId = mDeviceInfo.properties.deviceID;
        mPCIInfo.vendorId = mDeviceInfo.properties.vendorID;
        mPCIInfo.name = mDeviceInfo.properties.deviceName;

        switch (mDeviceInfo.properties.deviceType) {
            case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU:
                mAdapterType = wgpu::AdapterType::IntegratedGPU;
                break;
            case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU:
                mAdapterType = wgpu::AdapterType::DiscreteGPU;
                break;
            case VK_PHYSICAL_DEVICE_TYPE_CPU:
                mAdapterType = wgpu::AdapterType::CPU;
                break;
            default:
                mAdapterType = wgpu::AdapterType::Unknown;
                break;
        }

        return {};
    }

    MaybeError Adapter::CheckCoreWebGPUSupport() {
        // Needed for viewport Y-flip.
        if (!mDeviceInfo.HasExt(DeviceExt::Maintenance1)) {
            return DAWN_INTERNAL_ERROR("Vulkan 1.1 or Vulkan 1.0 with KHR_Maintenance1 required.");
        }

        // Needed for security
        if (!mDeviceInfo.features.robustBufferAccess) {
            return DAWN_INTERNAL_ERROR("Vulkan robustBufferAccess feature required.");
        }

        if (!mDeviceInfo.features.textureCompressionBC &&
            !(mDeviceInfo.features.textureCompressionETC2 &&
              mDeviceInfo.features.textureCompressionASTC_LDR)) {
            return DAWN_INTERNAL_ERROR(
                "Vulkan textureCompressionBC feature required or both textureCompressionETC2 and "
                "textureCompressionASTC required.");
        }

        // Needed for the respective WebGPU features.
        if (!mDeviceInfo.features.depthBiasClamp) {
            return DAWN_INTERNAL_ERROR("Vulkan depthBiasClamp feature required.");
        }
        if (!mDeviceInfo.features.fragmentStoresAndAtomics) {
            return DAWN_INTERNAL_ERROR("Vulkan fragmentStoresAndAtomics feature required.");
        }
        if (!mDeviceInfo.features.fullDrawIndexUint32) {
            return DAWN_INTERNAL_ERROR("Vulkan fullDrawIndexUint32 feature required.");
        }
        if (!mDeviceInfo.features.imageCubeArray) {
            return DAWN_INTERNAL_ERROR("Vulkan imageCubeArray feature required.");
        }
        if (!mDeviceInfo.features.independentBlend) {
            return DAWN_INTERNAL_ERROR("Vulkan independentBlend feature required.");
        }
        if (!mDeviceInfo.features.sampleRateShading) {
            return DAWN_INTERNAL_ERROR("Vulkan sampleRateShading feature required.");
        }

        // Check base WebGPU limits are supported.
        const VkPhysicalDeviceLimits& limits = mDeviceInfo.properties.limits;
        if (limits.maxImageDimension1D < kMaxTextureDimension1D) {
            return DAWN_INTERNAL_ERROR("Insufficient Vulkan limits for maxTextureDimension1D");
        }
        if (limits.maxImageDimension2D < kMaxTextureDimension2D ||
            limits.maxImageDimensionCube < kMaxTextureDimension2D ||
            limits.maxFramebufferWidth < kMaxTextureDimension2D ||
            limits.maxFramebufferHeight < kMaxTextureDimension2D ||
            limits.maxViewportDimensions[0] < kMaxTextureDimension2D ||
            limits.maxViewportDimensions[1] < kMaxTextureDimension2D ||
            limits.viewportBoundsRange[1] < kMaxTextureDimension2D) {
            return DAWN_INTERNAL_ERROR("Insufficient Vulkan limits for maxTextureDimension2D");
        }
        if (limits.maxImageDimension3D < kMaxTextureDimension3D) {
            return DAWN_INTERNAL_ERROR("Insufficient Vulkan limits for maxTextureDimension3D");
        }
        if (limits.maxImageArrayLayers < kMaxTextureArrayLayers) {
            return DAWN_INTERNAL_ERROR("Insufficient Vulkan limits for maxTextureArrayLayers");
        }
        if (limits.maxBoundDescriptorSets < kMaxBindGroups) {
            return DAWN_INTERNAL_ERROR("Insufficient Vulkan limits for maxBindGroups");
        }
        if (limits.maxDescriptorSetUniformBuffersDynamic <
            kMaxDynamicUniformBuffersPerPipelineLayout) {
            return DAWN_INTERNAL_ERROR(
                "Insufficient Vulkan limits for maxDynamicUniformBuffersPerPipelineLayout");
        }
        if (limits.maxDescriptorSetStorageBuffersDynamic <
            kMaxDynamicStorageBuffersPerPipelineLayout) {
            return DAWN_INTERNAL_ERROR(
                "Insufficient Vulkan limits for maxDynamicStorageBuffersPerPipelineLayout");
        }
        if (limits.maxPerStageDescriptorSampledImages < kMaxSampledTexturesPerShaderStage) {
            return DAWN_INTERNAL_ERROR(
                "Insufficient Vulkan limits for maxSampledTexturesPerShaderStage");
        }
        if (limits.maxPerStageDescriptorSamplers < kMaxSamplersPerShaderStage) {
            return DAWN_INTERNAL_ERROR("Insufficient Vulkan limits for maxSamplersPerShaderStage");
        }
        if (limits.maxPerStageDescriptorStorageBuffers < kMaxStorageBuffersPerShaderStage) {
            return DAWN_INTERNAL_ERROR(
                "Insufficient Vulkan limits for maxStorageBuffersPerShaderStage");
        }
        if (limits.maxPerStageDescriptorStorageImages < kMaxStorageTexturesPerShaderStage) {
            return DAWN_INTERNAL_ERROR(
                "Insufficient Vulkan limits for maxStorageTexturesPerShaderStage");
        }
        if (limits.maxPerStageDescriptorUniformBuffers < kMaxUniformBuffersPerShaderStage) {
            return DAWN_INTERNAL_ERROR(
                "Insufficient Vulkan limits for maxUniformBuffersPerShaderStage");
        }
        if (limits.maxUniformBufferRange < kMaxUniformBufferBindingSize) {
            return DAWN_INTERNAL_ERROR(
                "Insufficient Vulkan limits for maxUniformBufferBindingSize");
        }
        if (limits.maxStorageBufferRange < kMaxStorageBufferBindingSize) {
            return DAWN_INTERNAL_ERROR(
                "Insufficient Vulkan limits for maxStorageBufferBindingSize");
        }
        if (limits.minUniformBufferOffsetAlignment > kMinUniformBufferOffsetAlignment) {
            return DAWN_INTERNAL_ERROR(
                "Insufficient Vulkan limits for minUniformBufferOffsetAlignment");
        }
        if (limits.minStorageBufferOffsetAlignment > kMinStorageBufferOffsetAlignment) {
            return DAWN_INTERNAL_ERROR(
                "Insufficient Vulkan limits for minStorageBufferOffsetAlignment");
        }
        if (limits.maxVertexInputBindings < kMaxVertexBuffers) {
            return DAWN_INTERNAL_ERROR("Insufficient Vulkan limits for maxVertexBuffers");
        }
        if (limits.maxVertexInputAttributes < kMaxVertexAttributes) {
            return DAWN_INTERNAL_ERROR("Insufficient Vulkan limits for maxVertexAttributes");
        }
        if (limits.maxVertexInputBindingStride < kMaxVertexBufferArrayStride ||
            limits.maxVertexInputAttributeOffset < kMaxVertexBufferArrayStride - 1) {
            return DAWN_INTERNAL_ERROR("Insufficient Vulkan limits for maxVertexBufferArrayStride");
        }
        if (limits.maxVertexOutputComponents < kMaxInterStageShaderComponents ||
            limits.maxFragmentInputComponents < kMaxInterStageShaderComponents) {
            return DAWN_INTERNAL_ERROR(
                "Insufficient Vulkan limits for maxInterStageShaderComponents");
        }
        if (limits.maxComputeSharedMemorySize < kMaxComputeWorkgroupStorageSize) {
            return DAWN_INTERNAL_ERROR(
                "Insufficient Vulkan limits for maxComputeWorkgroupStorageSize");
        }
        if (limits.maxComputeWorkGroupInvocations < kMaxComputeWorkgroupInvocations) {
            return DAWN_INTERNAL_ERROR(
                "Insufficient Vulkan limits for maxComputeWorkgroupInvocations");
        }
        if (limits.maxComputeWorkGroupSize[0] < kMaxComputeWorkgroupSizeX ||
            limits.maxComputeWorkGroupSize[1] < kMaxComputeWorkgroupSizeY ||
            limits.maxComputeWorkGroupSize[2] < kMaxComputeWorkgroupSizeZ) {
            return DAWN_INTERNAL_ERROR(
                "Insufficient Vulkan limits for maxComputeWorkgroupSize");
        }
        if (limits.maxComputeWorkGroupCount[0] < kMaxComputePerDimensionDispatchSize ||
            limits.maxComputeWorkGroupCount[1] < kMaxComputePerDimensionDispatchSize ||
            limits.maxComputeWorkGroupCount[2] < kMaxComputePerDimensionDispatchSize) {
            return DAWN_INTERNAL_ERROR(
                "Insufficient Vulkan limits for maxComputePerDimensionDispatchSize");
        }
        if (limits.maxColorAttachments < kMaxColorAttachments) {
            return DAWN_INTERNAL_ERROR("Insufficient Vulkan limits for maxColorAttachments");
        }
        if (!IsSubset(VkSampleCountFlags(VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT),
                      limits.framebufferColorSampleCounts)) {
            return DAWN_INTERNAL_ERROR(
                "Insufficient Vulkan limits for framebufferColorSampleCounts");
        }
        if (!IsSubset(VkSampleCountFlags(VK_SAMPLE_COUNT_1_BIT | VK_SAMPLE_COUNT_4_BIT),
                      limits.framebufferDepthSampleCounts)) {
            return DAWN_INTERNAL_ERROR(
                "Insufficient Vulkan limits for framebufferDepthSampleCounts");
        }

        // Only check maxFragmentCombinedOutputResources on mobile GPUs. Desktop GPUs drivers seem
        // to put incorrect values for this limit with things like 8 or 16 when they can do bindless
        // storage buffers.
        uint32_t vendorId = mDeviceInfo.properties.vendorID;
        if (!gpu_info::IsAMD(vendorId) && !gpu_info::IsIntel(vendorId) &&
            !gpu_info::IsNvidia(vendorId)) {
            if (limits.maxFragmentCombinedOutputResources < kMaxColorAttachments +
                                                                kMaxStorageTexturesPerShaderStage +
                                                                kMaxStorageBuffersPerShaderStage) {
                return DAWN_INTERNAL_ERROR(
                    "Insufficient Vulkan maxFragmentCombinedOutputResources limit");
            }
        }

        return {};
    }

    bool Adapter::SupportsExternalImages() const {
        // Via dawn_native::vulkan::WrapVulkanImage
        return external_memory::Service::CheckSupport(mDeviceInfo) &&
               external_semaphore::Service::CheckSupport(mDeviceInfo, mPhysicalDevice,
                                                         mBackend->GetFunctions());
    }

    void Adapter::InitializeSupportedFeatures() {
        if (mDeviceInfo.features.textureCompressionBC == VK_TRUE) {
            mSupportedFeatures.EnableFeature(Feature::TextureCompressionBC);
        }

        if (mDeviceInfo.features.textureCompressionETC2 == VK_TRUE) {
            mSupportedFeatures.EnableFeature(Feature::TextureCompressionETC2);
        }

        if (mDeviceInfo.features.textureCompressionASTC_LDR == VK_TRUE) {
            mSupportedFeatures.EnableFeature(Feature::TextureCompressionASTC);
        }

        if (mDeviceInfo.features.pipelineStatisticsQuery == VK_TRUE) {
            mSupportedFeatures.EnableFeature(Feature::PipelineStatisticsQuery);
        }

        if (mDeviceInfo.features.depthClamp == VK_TRUE) {
            mSupportedFeatures.EnableFeature(Feature::DepthClamping);
        }

        if (mDeviceInfo.properties.limits.timestampComputeAndGraphics == VK_TRUE) {
            mSupportedFeatures.EnableFeature(Feature::TimestampQuery);
        }
    }

    ResultOrError<DeviceBase*> Adapter::CreateDeviceImpl(const DeviceDescriptor* descriptor) {
        return Device::Create(this, descriptor);
    }

}}  // namespace dawn_native::vulkan
