// Copyright 2023 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 "dawn/native/d3d11/PhysicalDeviceD3D11.h"

#include <algorithm>
#include <string>
#include <utility>

#include "dawn/common/Constants.h"
#include "dawn/native/ChainUtils.h"
#include "dawn/native/Instance.h"
#include "dawn/native/d3d/D3DError.h"
#include "dawn/native/d3d11/BackendD3D11.h"
#include "dawn/native/d3d11/DeviceD3D11.h"
#include "dawn/native/d3d11/PlatformFunctionsD3D11.h"
#include "dawn/native/d3d11/UtilsD3D11.h"

namespace dawn::native::d3d11 {

PhysicalDevice::PhysicalDevice(Backend* backend,
                               ComPtr<IDXGIAdapter4> hardwareAdapter,
                               ComPtr<ID3D11Device> d3d11Device)
    : Base(backend, std::move(hardwareAdapter), wgpu::BackendType::D3D11),
      mIsSharedD3D11Device(!!d3d11Device),
      mD3D11Device(std::move(d3d11Device)) {}

PhysicalDevice::~PhysicalDevice() = default;

bool PhysicalDevice::SupportsExternalImages() const {
    return true;
}

bool PhysicalDevice::SupportsFeatureLevel(FeatureLevel featureLevel) const {
    // TODO(dawn:1820): compare D3D11 feature levels with Dawn feature levels.
    switch (featureLevel) {
        case FeatureLevel::Core: {
            return mFeatureLevel >= D3D_FEATURE_LEVEL_11_1;
        }
        case FeatureLevel::Compatibility: {
            return true;
        }
    }
}

const DeviceInfo& PhysicalDevice::GetDeviceInfo() const {
    return mDeviceInfo;
}

ResultOrError<ComPtr<ID3D11Device>> PhysicalDevice::CreateD3D11Device(bool enableDebugLayer) {
    if (mIsSharedD3D11Device) {
        DAWN_ASSERT(mD3D11Device);
        return ComPtr<ID3D11Device>(mD3D11Device);
    }

    // If there mD3D11Device which is used for collecting GPU info is not null, try to use it.
    if (mD3D11Device) {
        // Backend validation level doesn't match, recreate the d3d11 device.
        if (enableDebugLayer == IsDebugLayerEnabled(mD3D11Device)) {
            return std::move(mD3D11Device);
        }
        mD3D11Device = nullptr;
    }

    const PlatformFunctions* functions = static_cast<Backend*>(GetBackend())->GetFunctions();
    const D3D_FEATURE_LEVEL featureLevels[] = {D3D_FEATURE_LEVEL_11_1, D3D_FEATURE_LEVEL_11_0};

    ComPtr<ID3D11Device> d3d11Device;

    if (enableDebugLayer) {
        // Try create d3d11 device with debug layer.
        HRESULT hr = functions->d3d11CreateDevice(
            GetHardwareAdapter(), D3D_DRIVER_TYPE_UNKNOWN,
            /*Software=*/nullptr, D3D11_CREATE_DEVICE_DEBUG, featureLevels,
            std::size(featureLevels), D3D11_SDK_VERSION, &d3d11Device,
            /*pFeatureLevel=*/nullptr, /*[out] ppImmediateContext=*/nullptr);

        if (SUCCEEDED(hr)) {
            DAWN_ASSERT(IsDebugLayerEnabled(d3d11Device));
            return d3d11Device;
        }
    }

    DAWN_TRY(CheckHRESULT(functions->d3d11CreateDevice(
                              GetHardwareAdapter(), D3D_DRIVER_TYPE_UNKNOWN,
                              /*Software=*/nullptr, /*Flags=*/0, featureLevels,
                              std::size(featureLevels), D3D11_SDK_VERSION, &d3d11Device,
                              /*pFeatureLevel=*/nullptr, /*[out] ppImmediateContext=*/nullptr),
                          "D3D11CreateDevice failed"));

    return d3d11Device;
}

MaybeError PhysicalDevice::InitializeImpl() {
    DAWN_TRY(Base::InitializeImpl());
    // D3D11 cannot check for feature support without a device.
    // Create the device to populate the adapter properties then reuse it when needed for actual
    // rendering.
    if (!mIsSharedD3D11Device) {
        DAWN_TRY_ASSIGN(mD3D11Device, CreateD3D11Device(/*enableDebugLayers=*/false));
    }

    mFeatureLevel = mD3D11Device->GetFeatureLevel();
    DAWN_TRY_ASSIGN(mDeviceInfo, GatherDeviceInfo(GetHardwareAdapter(), mD3D11Device));

    // Base::InitializeImpl() cannot distinguish between discrete and integrated GPUs, so we need to
    // overwrite it.
    if (mAdapterType == wgpu::AdapterType::DiscreteGPU && mDeviceInfo.isUMA) {
        mAdapterType = wgpu::AdapterType::IntegratedGPU;
    }

    return {};
}

void PhysicalDevice::InitializeSupportedFeaturesImpl() {
    EnableFeature(Feature::Depth32FloatStencil8);
    EnableFeature(Feature::DepthClipControl);
    EnableFeature(Feature::TextureCompressionBC);
    EnableFeature(Feature::SurfaceCapabilities);
    EnableFeature(Feature::D3D11MultithreadProtected);
    EnableFeature(Feature::DualSourceBlending);
    EnableFeature(Feature::Unorm16TextureFormats);
    EnableFeature(Feature::Snorm16TextureFormats);
    EnableFeature(Feature::Norm16TextureFormats);
    EnableFeature(Feature::AdapterPropertiesMemoryHeaps);
    EnableFeature(Feature::AdapterPropertiesD3D);
    EnableFeature(Feature::R8UnormStorage);
    EnableFeature(Feature::ShaderModuleCompilationOptions);
    EnableFeature(Feature::DawnLoadResolveTexture);
    if (mDeviceInfo.isUMA && mDeviceInfo.supportsMapNoOverwriteDynamicBuffers) {
        // With UMA we should allow mapping usages on more type of buffers.
        EnableFeature(Feature::BufferMapExtendedUsages);
    }

    // Multi planar formats are always supported since Feature Level 11.0
    // https://learn.microsoft.com/en-us/windows/win32/direct3ddxgi/format-support-for-direct3d-11-0-feature-level-hardware
    EnableFeature(Feature::DawnMultiPlanarFormats);
    EnableFeature(Feature::MultiPlanarFormatP010);
    EnableFeature(Feature::MultiPlanarRenderTargets);

    if (mDeviceInfo.supportsROV) {
        EnableFeature(Feature::PixelLocalStorageCoherent);
    }

    EnableFeature(Feature::SharedTextureMemoryD3D11Texture2D);
    if (mDeviceInfo.supportsSharedResourceCapabilityTier2) {
        EnableFeature(Feature::SharedTextureMemoryDXGISharedHandle);
    }
    if (mDeviceInfo.supportsMonitoredFence || mDeviceInfo.supportsNonMonitoredFence) {
        EnableFeature(Feature::SharedFenceDXGISharedHandle);
    }

    UINT formatSupport = 0;
    HRESULT hr = mD3D11Device->CheckFormatSupport(DXGI_FORMAT_B8G8R8A8_UNORM, &formatSupport);
    DAWN_ASSERT(SUCCEEDED(hr));
    if (formatSupport & D3D11_FORMAT_SUPPORT_TYPED_UNORDERED_ACCESS_VIEW) {
        EnableFeature(Feature::BGRA8UnormStorage);
    }
}

MaybeError PhysicalDevice::InitializeSupportedLimitsImpl(CombinedLimits* limits) {
    GetDefaultLimitsForSupportedFeatureLevel(&limits->v1);

    // // https://docs.microsoft.com/en-us/windows/win32/direct3d12/hardware-feature-levels

    // Limits that are the same across D3D feature levels
    limits->v1.maxTextureDimension1D = D3D11_REQ_TEXTURE1D_U_DIMENSION;
    limits->v1.maxTextureDimension2D = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;
    limits->v1.maxTextureDimension3D = D3D11_REQ_TEXTURE3D_U_V_OR_W_DIMENSION;
    limits->v1.maxTextureArrayLayers = D3D11_REQ_TEXTURE2D_ARRAY_AXIS_DIMENSION;
    // Slot values can be 0-15, inclusive:
    // https://docs.microsoft.com/en-ca/windows/win32/api/d3d11/ns-d3d11-d3d11_input_element_desc
    limits->v1.maxVertexBuffers = 16;
    // Both SV_VertexID and SV_InstanceID will consume vertex input slots.
    limits->v1.maxVertexAttributes = D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT - 2;

    uint32_t maxUAVsAllStages = mFeatureLevel == D3D_FEATURE_LEVEL_11_1
                                    ? D3D11_1_UAV_SLOT_COUNT
                                    : D3D11_PS_CS_UAV_REGISTER_COUNT;
    mUAVSlotCount = maxUAVsAllStages;
    uint32_t maxUAVsPerStage = maxUAVsAllStages / 2;

    // Reserve one slot for builtin constants.
    constexpr uint32_t kReservedCBVSlots = 1;
    limits->v1.maxUniformBuffersPerShaderStage =
        D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT - kReservedCBVSlots;

    // Allocate half of the UAVs to storage buffers, and half to storage textures.
    limits->v1.maxStorageTexturesPerShaderStage = maxUAVsPerStage / 2;
    limits->v1.maxStorageBuffersPerShaderStage = maxUAVsPerStage / 2;
    limits->v1.maxSampledTexturesPerShaderStage = D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT;
    limits->v1.maxSamplersPerShaderStage = D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT;
    limits->v1.maxColorAttachments = D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT;
    // This is maxColorAttachments times 16, the color format with the largest cost.
    limits->v1.maxColorAttachmentBytesPerSample = D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT * 16;

    limits->v1.maxDynamicUniformBuffersPerPipelineLayout =
        limits->v1.maxUniformBuffersPerShaderStage;
    limits->v1.maxDynamicStorageBuffersPerPipelineLayout =
        limits->v1.maxStorageBuffersPerShaderStage;

    // https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/sm5-attributes-numthreads
    limits->v1.maxComputeWorkgroupSizeX = D3D11_CS_THREAD_GROUP_MAX_X;
    limits->v1.maxComputeWorkgroupSizeY = D3D11_CS_THREAD_GROUP_MAX_Y;
    limits->v1.maxComputeWorkgroupSizeZ = D3D11_CS_THREAD_GROUP_MAX_Z;
    limits->v1.maxComputeInvocationsPerWorkgroup = D3D11_CS_THREAD_GROUP_MAX_THREADS_PER_GROUP;

    // https://learn.microsoft.com/en-us/windows/win32/api/d3d11/nf-d3d11-id3d11devicecontext-dispatch
    limits->v1.maxComputeWorkgroupsPerDimension = D3D11_CS_DISPATCH_MAX_THREAD_GROUPS_PER_DIMENSION;

    // https://docs.microsoft.com/en-us/windows/win32/direct3d11/overviews-direct3d-11-devices-downlevel-compute-shaders
    // Thread Group Shared Memory is limited to 16Kb on downlevel hardware. This is less than
    // the 32Kb that is available to Direct3D 11 hardware. D3D12 is also 32kb.
    limits->v1.maxComputeWorkgroupStorageSize = 32768;

    // Max number of "constants" where each constant is a 16-byte float4
    limits->v1.maxUniformBufferBindingSize = D3D11_REQ_CONSTANT_BUFFER_ELEMENT_COUNT * 16;

    if (gpu_info::IsQualcomm(GetVendorId())) {
        // limit of number of texels in a buffer == (1 << 27)
        // D3D11_REQ_BUFFER_RESOURCE_TEXEL_COUNT_2_TO_EXP
        // This limit doesn't apply to a raw buffer, but only applies to
        // typed, or structured buffer. so this could be a QC driver bug.
        limits->v1.maxStorageBufferBindingSize = uint64_t(1)
                                                 << D3D11_REQ_BUFFER_RESOURCE_TEXEL_COUNT_2_TO_EXP;
    } else {
        limits->v1.maxStorageBufferBindingSize = kAssumedMaxBufferSize;
    }

    // D3D11 has no documented limit on the buffer size.
    limits->v1.maxBufferSize = kAssumedMaxBufferSize;

    // 1 for SV_Position and 1 for (SV_IsFrontFace OR SV_SampleIndex).
    // See the discussions in https://github.com/gpuweb/gpuweb/issues/1962 for more details.
    limits->v1.maxInterStageShaderVariables = D3D11_PS_INPUT_REGISTER_COUNT - 2;
    limits->v1.maxInterStageShaderComponents =
        limits->v1.maxInterStageShaderVariables * D3D11_PS_INPUT_REGISTER_COMPONENTS;

    return {};
}

FeatureValidationResult PhysicalDevice::ValidateFeatureSupportedWithTogglesImpl(
    wgpu::FeatureName feature,
    const TogglesState& toggles) const {
    return {};
}

void PhysicalDevice::SetupBackendAdapterToggles(dawn::platform::Platform* platform,
                                                TogglesState* adapterToggles) const {
    // D3D11 must use FXC, not DXC.
    adapterToggles->ForceSet(Toggle::UseDXC, false);
}

void PhysicalDevice::SetupBackendDeviceToggles(dawn::platform::Platform* platform,
                                               TogglesState* deviceToggles) const {
    // D3D11 can only clear RTV with float values.
    deviceToggles->Default(Toggle::ApplyClearBigIntegerColorValueWithDraw, true);
    deviceToggles->Default(Toggle::UseBlitForBufferToStencilTextureCopy, true);
    deviceToggles->Default(Toggle::D3D11UseUnmonitoredFence, !mDeviceInfo.supportsMonitoredFence);
    deviceToggles->Default(Toggle::UseBlitForT2B, true);
}

ResultOrError<Ref<DeviceBase>> PhysicalDevice::CreateDeviceImpl(
    AdapterBase* adapter,
    const UnpackedPtr<DeviceDescriptor>& descriptor,
    const TogglesState& deviceToggles,
    Ref<DeviceBase::DeviceLostEvent>&& lostEvent) {
    return Device::Create(adapter, descriptor, deviceToggles, std::move(lostEvent));
}

// Resets the backend device and creates a new one. If any D3D11 objects belonging to the
// current ID3D11Device have not been destroyed, a non-zero value will be returned upon Reset()
// and the subequent call to CreateDevice will return a handle the existing device instead of
// creating a new one.
MaybeError PhysicalDevice::ResetInternalDeviceForTestingImpl() {
    [[maybe_unused]] auto refCount = mD3D11Device.Reset();
    DAWN_ASSERT(refCount == 0);
    DAWN_TRY(Initialize());

    return {};
}

void PhysicalDevice::PopulateBackendProperties(UnpackedPtr<AdapterProperties>& properties) const {
    if (auto* memoryHeapProperties = properties.Get<AdapterPropertiesMemoryHeaps>()) {
        // https://microsoft.github.io/DirectX-Specs/d3d/D3D12GPUUploadHeaps.html describes
        // the properties of D3D12 Default/Upload/Readback heaps. The assumption is that these are
        // roughly how D3D11 allocates memory has well.
        if (mDeviceInfo.isUMA) {
            auto* heapInfo = new MemoryHeapInfo[1];
            memoryHeapProperties->heapCount = 1;
            memoryHeapProperties->heapInfo = heapInfo;

            heapInfo[0].size =
                std::max(mDeviceInfo.dedicatedVideoMemory, mDeviceInfo.sharedSystemMemory);
            heapInfo[0].properties =
                wgpu::HeapProperty::DeviceLocal | wgpu::HeapProperty::HostVisible |
                wgpu::HeapProperty::HostUncached | wgpu::HeapProperty::HostCached;
        } else {
            auto* heapInfo = new MemoryHeapInfo[2];
            memoryHeapProperties->heapCount = 2;
            memoryHeapProperties->heapInfo = heapInfo;

            heapInfo[0].size = mDeviceInfo.dedicatedVideoMemory;
            heapInfo[0].properties = wgpu::HeapProperty::DeviceLocal;

            heapInfo[1].size = mDeviceInfo.sharedSystemMemory;
            heapInfo[1].properties =
                wgpu::HeapProperty::HostVisible | wgpu::HeapProperty::HostCoherent |
                wgpu::HeapProperty::HostUncached | wgpu::HeapProperty::HostCached;
        }
    }
    if (auto* d3dProperties = properties.Get<AdapterPropertiesD3D>()) {
        d3dProperties->shaderModel = GetDeviceInfo().shaderModel;
    }
}

}  // namespace dawn::native::d3d11
