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

MaybeError InitializeDebugLayerFilters(ComPtr<ID3D11Device> d3d11Device) {
    ComPtr<ID3D11InfoQueue> infoQueue;
    DAWN_TRY(CheckHRESULT(d3d11Device.As(&infoQueue),
                          "D3D11 querying device for ID3D11InfoQueue interface"));

    static D3D11_MESSAGE_ID kDenyIds[] = {
        // D3D11 Debug layer warns no RTV set, however it is allowed.
        D3D11_MESSAGE_ID_DEVICE_DRAW_RENDERTARGETVIEW_NOT_SET,
        // D3D11 Debug layer warns SetPrivateData() with same name more than once.
        D3D11_MESSAGE_ID_SETPRIVATEDATA_CHANGINGPARAMS,
    };

    // Filter out info/message and only create errors from warnings or worse.
    static D3D11_MESSAGE_SEVERITY kDenySeverities[] = {
        D3D11_MESSAGE_SEVERITY_INFO,
        D3D11_MESSAGE_SEVERITY_MESSAGE,
    };

    static D3D11_INFO_QUEUE_FILTER filter = {
        {},  // AllowList
        {
            0,                           // NumCategories
            nullptr,                     // pCategoryList
            std::size(kDenySeverities),  // NumSeverities
            kDenySeverities,             // pSeverityList
            std::size(kDenyIds),         // NumIDs
            kDenyIds,                    // pIDList
        },                               // DenyList
    };

    return CheckHRESULT(infoQueue->PushStorageFilter(&filter),
                        "D3D11 InfoQueue pushing storage filter");
}

}  // namespace

PhysicalDevice::PhysicalDevice(Backend* backend,
                               ComPtr<IDXGIAdapter3> 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() {
    if (mIsSharedD3D11Device) {
        DAWN_ASSERT(mD3D11Device);
        // If the shared d3d11 device was created with debug layer, we have to initialize debug
        // layer filters to avoid some unwanted warnings.
        if (IsDebugLayerEnabled(mD3D11Device)) {
            DAWN_TRY(InitializeDebugLayerFilters(mD3D11Device));
        }
        return ComPtr<ID3D11Device>(mD3D11Device);
    }

    // If there mD3D11Device which is used for collecting GPU info is not null, try to use it.
    if (mD3D11Device) {
        bool isDebugLayerEnabled = IsDebugLayerEnabled(mD3D11Device);
        // Backend validation level doesn't match, recreate the d3d11 device.
        if (GetInstance()->IsBackendValidationEnabled() == isDebugLayerEnabled) {
            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 (GetInstance()->IsBackendValidationEnabled()) {
        // 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));
            DAWN_TRY(InitializeDebugLayerFilters(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());
    }

    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);

    // 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);
    }

    // Always expose SharedTextureMemoryDXGISharedHandle, since the d3d11 should be able to
    // import shared handles which are exported from d3d device.
    EnableFeature(Feature::SharedTextureMemoryDXGISharedHandle);
    EnableFeature(Feature::SharedTextureMemoryD3D11Texture2D);
    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(TogglesState* adpterToggles) const {
    // D3D11 must use FXC, not DXC.
    adpterToggles->ForceSet(Toggle::UseDXC, false);
}

void PhysicalDevice::SetupBackendDeviceToggles(TogglesState* deviceToggles) const {
    // D3D11 can only clear RTV with float values.
    deviceToggles->Default(Toggle::ApplyClearBigIntegerColorValueWithDraw, true);
    deviceToggles->Default(Toggle::UseBlitForBufferToStencilTextureCopy, 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
