jp7677 / dxvk-nvapi

Alternative NVAPI implementation on top of DXVK.
MIT License
375 stars 37 forks source link

NVAPI libnvidia-api.so.1 relevance #100

Open jp7677 opened 2 years ago

jp7677 commented 2 years ago

The NVIDIA Linux driver ships libnvidia-api.so.1 since driver version 525. This library seems to be the Linux counterpart of nvapi64.dll from Windows. Lets use this issue to discuss ideas and its relevance to this project.

The version from the 525 driver contains the following methods (based on the function pointers described in the 520 NVAPI Open Source SDK) (thanks @Saancreed )

NvAPI_Initialize
NvAPI_Unload
NvAPI_GetErrorMessage
NvAPI_EnumPhysicalGPUs
NvAPI_GPU_GetShaderSubPipeCount
NvAPI_GPU_GetGpuCoreCount
NvAPI_GPU_GetFullName
NvAPI_GPU_GetPCIIdentifiers
NvAPI_GPU_GetBusType
NvAPI_GPU_GetBusId
NvAPI_GPU_GetVbiosRevision
NvAPI_GPU_GetVbiosOEMRevision
NvAPI_GPU_GetVbiosVersionString
NvAPI_GPU_GetCurrentPCIEDownstreamWidth
NvAPI_GPU_GetPhysicalFrameBufferSize
NvAPI_GPU_GetVirtualFrameBufferSize
NvAPI_GPU_GetBoardInfo
NvAPI_GPU_GetArchInfo
NvAPI_GPU_GetHDCPSupportStatus
NvAPI_GPU_GetTachReading
NvAPI_GPU_GetECCStatusInfo
NvAPI_GPU_GetECCConfigurationInfo
NvAPI_GPU_GetVirtualizationInfo
NvAPI_GPU_GetLicensableFeatures
NvAPI_GPU_GetVRReadyData
NvAPI_GPU_GetPstatesInfoEx
NvAPI_GPU_GetPstates20
NvAPI_GPU_GetCurrentPstate
NvAPI_GPU_GetDynamicPstatesInfoEx
NvAPI_GPU_GetThermalSettings
NvAPI_GPU_GetAllClockFrequencies
NvAPI_GPU_QueryIlluminationSupport
NvAPI_GPU_GetIllumination
NvAPI_GPU_SetIllumination
NvAPI_GPU_ClientIllumDevicesGetInfo
NvAPI_GPU_ClientIllumDevicesGetControl
NvAPI_GPU_ClientIllumDevicesSetControl
NvAPI_GPU_ClientIllumZonesGetInfo
NvAPI_GPU_ClientIllumZonesGetControl
NvAPI_GPU_ClientIllumZonesSetControl
Saancreed commented 2 years ago

Small correction: the library file is called libnvidia-api.so.1 and it was introduced in 525 series.

We only know about functions that are included in https://download.nvidia.com/XFree86/nvapi-open-source-sdk/R520-OpenSource.tar SDK which hasn't been updated to 525 release yet.

The program I used to check which functions are available is this:

#include "./nvapi.h"
#include "./nvapi_interface.h"

#include <dlfcn.h>
#include <iostream>
#include <memory>

int main()
{
    auto nvapi = std::unique_ptr<void, decltype(&dlclose)>{dlopen("libnvidia-api.so.1", RTLD_NOW), dlclose};
    auto nvapi_QueryInterface = reinterpret_cast<void *(*)(NvU32)>(dlsym(nvapi.get(), "nvapi_QueryInterface"));

    for (auto &i : nvapi_interface_table)
    {
        if (nvapi_QueryInterface(i.id))
            std::cout << "    Found: " << i.func << std::endl;
        else
            std::cerr << "NOT Found: " << i.func << std::endl;
    }
}

Might be useful to check again once NVIDIA releases R525 NVAPI SDK (build with -ldl).

jp7677 commented 2 years ago

Small correction: the library file is called libnvidia-api.so.1 and it was introduced in 525 series.

Ah, thanks, corrected, that was a genuine typo ;).

Etaash-mathamsetty commented 2 years ago

I am going to check which functions are exported on windows out of curiosity, maybe linux only has a small number of them edit: looking at nvapi.h it's already clear linux has only a small number (that we know of right now, they haven't released the R525 sdk yet)

Saancreed commented 2 years ago

Nvidia released R525 SDK sometime earlier this week and the only new function that can be found in libnvidia-api.so is NvAPI_GPU_GetRamBusWidth. There's also a bunch of new functions related to HDR but they seem to be Windows-only, at least in the latest driver release.

jp7677 commented 2 years ago

Thanks for the heads up! Hopefully we can merge Liam's PR soon. After that I'll also update to the new headers and then it is time for a new release.

jp7677 commented 2 years ago

Regarding libnvidia-api.so, in its current state it could serve as a perfect nvml replacement because, well obviously, all those GPU_ related methods match exactly and no translation is needed like we have to do for nvml.

That said, we cannot unfortunately throw out the existing DXVK/Vulkan based sysinfo things and replace it with enumerating physical GPU's using libnvidia-api.so. The major showstopper (next to a few others, like honoring DXVK_DEVICE_FILTER, missing display related methods) is NvAPI_GPU_GetAdapterIdFromPhysicalGpu which returns the adapter LUID (needed for DLSS). libnvidia-api.so doesn't has this method, but even if i had an implementation, the LUID is generated by wine/wine-vulkan and thus not known to libnvidia-api.so. Doing the LUID magic in a wine-nvidia-api project would imho essentially just mirror the current sysinfo mechanics.

Saancreed commented 2 years ago

Another thing to look out for is how to properly correlate DXGI adapters / VkPhysicalDevices returned by DXVK and physical GPU handles returned by native libnvidia-api.so. NVML has the nice property of being able to find devices by PCI bus ID for which Vulkan gives us a tuple of (Domain, Bus, Device, Function) we can easily use. It can even find them by UUIDs if we were inclined to go that path. But with native NvPhysicalGpuHandles we are limited to what NVAPI can tell us about each handle it returns, which appears to be… not much.

Assuming that we have a PC with, let's say, four RTX 4090 GPUs (and a private power plant for them, of course), each one with the same full name, vendorId and deviceId but with distinct UUIDs and PCI bus IDs, how do we associate a VkPhysicalDevice with correct NvPhysicalGpuHandle?

(We'd also lose NvAPI_GPU_GetIrq if we were to dump NVML completely but that's not a big loss.)

jp7677 commented 2 years ago

Yeah, that's indeed a blocking issue for now. I had hoped we can correlate by NvAPI_GPU_GetBusId and NvAPI_GPU_GetBusSlotId, which is the same as PCI bus ID/device ID. But unfortunately NvAPI_GPU_GetBusSlotId is currently not implemented by libnvidia-api.