Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/jp7677/dxvk-nvapi.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Peters <jp7677@gmail.com>2021-12-05 10:19:17 +0300
committerJens Peters <jp7677@gmail.com>2021-12-05 15:51:17 +0300
commitca6c35bfc48d452a42d099e9f43d2cdace290738 (patch)
treefa29cc418b3bd1adb8c492695d1b677f14a22d39
parentfe232dcf2c0bc5d8e1de93c1c490320630d21ee7 (diff)
nvapi: Report GPUs with NVIDIAs proprietary driver only
This matches Windows behavior and may avoid reports about version number mismatch when using other vendors. Introduce 'DXVK_NVAPI_ALLOW_OTHER_DRIVERS' environment variable to enable the old behavior.
-rw-r--r--README.md7
-rw-r--r--src/sysinfo/nvapi_adapter.cpp10
-rw-r--r--tests/nvapi_d3d12.cpp4
-rw-r--r--tests/nvapi_sysinfo.cpp51
4 files changed, 54 insertions, 18 deletions
diff --git a/README.md b/README.md
index acaaf26..f02e713 100644
--- a/README.md
+++ b/README.md
@@ -15,7 +15,7 @@ While originally being developed for usage with Unreal Engine 4, most notably fo
## Requirements
-This implementation is supposed to be used on Linux using Wine or derivatives like Proton. Usage on Windows is discouraged. Please do not replace `nvapi.dll`/`nvapi64.dll` on Windows from NVIDIA's driver package with this version. DXVK-NVAPI uses several DXVK and VKD3D-Proton extension points, thus using DXVK (D3D11 and DXGI) is a requirement. Using Wine's D3D11 or DXGI will fail. Usage of DXVK-NVAPI is not restricted to NVIDIA GPUs, but some entry points offer no functionality when a different GPU vendor is detected.
+This implementation is supposed to be used on Linux using Wine or derivatives like Proton. Usage on Windows is discouraged. Please do not replace `nvapi.dll`/`nvapi64.dll` on Windows from NVIDIA's driver package with this version. DXVK-NVAPI uses several DXVK and VKD3D-Proton extension points, thus using DXVK (D3D11 and DXGI) is a requirement. Using Wine's D3D11 or DXGI will fail. Usage of DXVK-NVAPI is not restricted to NVIDIA GPUs, though the default behavior is to report only NVIDIA GPUs. Some entry points offer no functionality when a different GPU vendor is detected.
When available, DXVK-NVAPI uses NVIDIA's NVML management library to query temperature, utilization and others for NVIDIA GPUs. See [wine-nvml](https://github.com/Saancreed/wine-nvml) how to add NVML support to Wine/Proton.
@@ -62,17 +62,18 @@ Wine does not includes DXVK-NVAPI.
- Ensure that Wine uses DXVK's `dxgi.dll`, e.g. with `WINEDLLOVERRIDES=dxgi=n`.
- Disable the `nvapiHack` in DXVK with `dxgi.nvapiHack = False` set in a DXVK configuration file, see [dxvk.conf](https://github.com/doitsujin/dxvk/blob/master/dxvk.conf#L51).
-## Debugging and troubleshooting
+## Tweaks, debugging and troubleshooting
See [Quirks-for-usage-with-DXVK-NVAPI](https://github.com/jp7677/dxvk-nvapi/wiki/Quirks-for-usage-with-DXVK-NVAPI) for any known quirks or work arounds.
The following environment variables tweak DXVK-NVAPI's runtime behavior:
- `DXVK_NVAPI_DRIVER_VERSION` lets you override the reported driver version. Valid values are numbers between 100 and 99999. Use e.g. `DXVK_NVAPI_DRIVER_VERSION=47141` to report driver version `471.41`.
+- `DXVK_NVAPI_ALLOW_OTHER_DRIVERS` - lets you use DXVK-NVAPI without running an NVIDIA card on NVIDIAs proprietary driver when set, e.g. `DXVK_NVAPI_ALLOW_OTHER_DRIVERS=1`. Useful for using e.g. D3D11 extension on a non-NVIDIA GPU.
- `DXVK_NVAPI_LOG_LEVEL` set to `info` prints log statements. The default behavior omits any logging. Please fill an issue if using log servery `info` creates log spam. There are no other log levels.
- `DXVK_NVAPI_LOG_PATH` enables file logging additionally to console output and sets the path where the log file `dxvk-nvapi.log` should be written to. Log statements are appended to an existing file. Please remove this file once in a while to prevent excessive grow. This requires `DXVK_NVAPI_LOG_LEVEL` set to `info`.
-This project provides a test suite. Run the package script with `--enable-tests` (see above) to build `nvapi64-tests.exe`. Running the tests executable without arguments queries the local system and provides system information about visible GPU's:
+This project provides a test suite. Run the package script with `--enable-tests` (see above) to build `nvapi64-tests.exe`. Running the tests executable without arguments queries the local system and provides system information about visible GPUs:
```bash
DXVK_LOG_LEVEL=none WINEDEBUG=-all WINEDLLOVERRIDES=dxgi,nvapi64=n wine nvapi64-tests.exe
diff --git a/src/sysinfo/nvapi_adapter.cpp b/src/sysinfo/nvapi_adapter.cpp
index d41c796..9c9f4cf 100644
--- a/src/sysinfo/nvapi_adapter.cpp
+++ b/src/sysinfo/nvapi_adapter.cpp
@@ -12,6 +12,7 @@ namespace dxvk {
bool NvapiAdapter::Initialize(Com<IDXGIAdapter1>& dxgiAdapter, std::vector<NvapiOutput*>& outputs) {
constexpr auto driverVersionEnvName = "DXVK_NVAPI_DRIVER_VERSION";
+ constexpr auto allowOtherDriversEnvName = "DXVK_NVAPI_ALLOW_OTHER_DRIVERS";
// Get the Vulkan handle from the DXGI adapter to get access to Vulkan device properties which has some information we want.
Com<IDXGIVkInteropAdapter> dxgiVkInteropAdapter;
@@ -68,6 +69,13 @@ namespace dxvk {
m_vulkan.GetPhysicalDeviceMemoryProperties2(vkInstance, vkDevice, &memoryProperties2);
m_memoryProperties = memoryProperties2.memoryProperties;
+ auto allowOtherDrivers = env::getEnvVariable(allowOtherDriversEnvName);
+ if (!allowOtherDrivers.empty())
+ log::write(str::format(allowOtherDrivers, " is set, reporting also GPUs with non-NVIDIA proprietary driver."));
+
+ if (GetDriverId() != VK_DRIVER_ID_NVIDIA_PROPRIETARY && allowOtherDrivers.empty())
+ return false;
+
if (GetDriverId() == VK_DRIVER_ID_NVIDIA_PROPRIETARY)
// Handle NVIDIA version notation
m_vkDriverVersion = VK_MAKE_VERSION(
@@ -114,7 +122,7 @@ namespace dxvk {
if (std::string(end).empty() && driverVersionOverride >= 100 && driverVersionOverride <= 99999) {
std::stringstream stream;
stream << (driverVersionOverride / 100) << "." << std::setfill('0') << std::setw(2) << (driverVersionOverride % 100);
- log::write(str::format(driverVersionEnvName, " is set to '", driverVersion, "', reporting driver version ", stream.str()));
+ log::write(str::format(driverVersionEnvName, " is set to '", driverVersion, "', reporting driver version ", stream.str(), "."));
m_driverVersionOverride = driverVersionOverride;
}
else
diff --git a/tests/nvapi_d3d12.cpp b/tests/nvapi_d3d12.cpp
index 872b9aa..b344f04 100644
--- a/tests/nvapi_d3d12.cpp
+++ b/tests/nvapi_d3d12.cpp
@@ -159,6 +159,8 @@ TEST_CASE("D3D12 methods succeed", "[.d3d12]") {
Data{VK_DRIVER_ID_AMD_OPEN_SOURCE, VK_KHR_FRAGMENT_SHADING_RATE_EXTENSION_NAME, 0, 0},
Data{VK_DRIVER_ID_NVIDIA_PROPRIETARY, "ext", 0, 0});
+ ::SetEnvironmentVariableA("DXVK_NVAPI_ALLOW_OTHER_DRIVERS", "1");
+
luid->HighPart = 0x00000002;
luid->LowPart = 0x00000001;
@@ -185,6 +187,8 @@ TEST_CASE("D3D12 methods succeed", "[.d3d12]") {
REQUIRE(graphicsCaps.majorSMVersion == args.expectedMajorSMVersion);
REQUIRE(graphicsCaps.minorSMVersion == args.expectedMinorSMVersion);
REQUIRE(deviceRefCount == 0);
+
+ ::SetEnvironmentVariableA("DXVK_NVAPI_ALLOW_OTHER_DRIVERS", "");
}
}
diff --git a/tests/nvapi_sysinfo.cpp b/tests/nvapi_sysinfo.cpp
index 1e21085..d1f062c 100644
--- a/tests/nvapi_sysinfo.cpp
+++ b/tests/nvapi_sysinfo.cpp
@@ -12,27 +12,42 @@ TEST_CASE("GetErrorMessage returns OK", "[.sysinfo]") {
REQUIRE(strcmp(desc, "NVAPI_NVIDIA_DEVICE_NOT_FOUND") == 0);
}
-TEST_CASE("Initialize returns device-not-found when DXVK reports no adapters", "[.sysinfo]") {
+TEST_CASE("Initialize succeed", "[.sysinfo]") {
auto dxgiFactory = std::make_unique<DXGIFactory1Mock>();
auto vulkan = std::make_unique<VulkanMock>();
auto nvml = std::make_unique<NvmlMock>();
+ DXGIDxvkAdapterMock adapter;
+ DXGIOutputMock output;
+
+ auto e = ConfigureDefaultTestEnvironment(*dxgiFactory, *vulkan, *nvml, adapter, output);
- ALLOW_CALL(*dxgiFactory, AddRef())
- .RETURN(1);
- ALLOW_CALL(*dxgiFactory, Release())
- .RETURN(0);
- ALLOW_CALL(*dxgiFactory, EnumAdapters1(_, _))
- .RETURN(DXGI_ERROR_NOT_FOUND);
+ SECTION("Initialize returns OK") {
+ SetupResourceFactory(std::move(dxgiFactory), std::move(vulkan), std::move(nvml));
+ REQUIRE(NvAPI_Initialize() == NVAPI_OK);
+ REQUIRE(NvAPI_Unload() == NVAPI_OK);
+ }
- ALLOW_CALL(*vulkan, IsAvailable())
- .RETURN(true);
+ SECTION("Initialize returns device-not-found when DXVK reports no adapters") {
+ ALLOW_CALL(*dxgiFactory, EnumAdapters1(_, _)) // NOLINT(bugprone-use-after-move)
+ .RETURN(DXGI_ERROR_NOT_FOUND);
- ALLOW_CALL(*nvml, IsAvailable())
- .RETURN(false);
+ SetupResourceFactory(std::move(dxgiFactory), std::move(vulkan), std::move(nvml));
+ REQUIRE(NvAPI_Initialize() == NVAPI_NVIDIA_DEVICE_NOT_FOUND);
+ REQUIRE(NvAPI_Unload() == NVAPI_API_NOT_INITIALIZED);
+ }
- SetupResourceFactory(std::move(dxgiFactory), std::move(vulkan), std::move(nvml));
- REQUIRE(NvAPI_Initialize() == NVAPI_NVIDIA_DEVICE_NOT_FOUND);
- REQUIRE(NvAPI_Unload() == NVAPI_API_NOT_INITIALIZED);
+ SECTION("Initialize returns device-not-found when adapter with non NVIDIA driver ID has been found") {
+ ALLOW_CALL(*vulkan, GetPhysicalDeviceProperties2(_, _, _)) // NOLINT(bugprone-use-after-move)
+ .SIDE_EFFECT(
+ ConfigureGetPhysicalDeviceProperties2(_3,
+ [](auto props, auto idProps, auto pciBusInfoProps, auto driverProps, auto fragmentShadingRateProps) {
+ driverProps->driverID = VK_DRIVER_ID_MESA_RADV;
+ }));
+
+ SetupResourceFactory(std::move(dxgiFactory), std::move(vulkan), std::move(nvml));
+ REQUIRE(NvAPI_Initialize() == NVAPI_NVIDIA_DEVICE_NOT_FOUND);
+ REQUIRE(NvAPI_Unload() == NVAPI_API_NOT_INITIALIZED);
+ }
}
TEST_CASE("Topology methods succeed", "[.sysinfo]") {
@@ -251,6 +266,8 @@ TEST_CASE("Sysinfo methods succeed", "[.sysinfo]") {
Data{VK_DRIVER_ID_NVIDIA_PROPRIETARY, 470, 101, 1, 47099},
Data{VK_DRIVER_ID_AMD_OPEN_SOURCE, 21, 2, 3, 2102});
+ ::SetEnvironmentVariableA("DXVK_NVAPI_ALLOW_OTHER_DRIVERS", "1");
+
ALLOW_CALL(*vulkan, GetPhysicalDeviceProperties2(_, _, _)) // NOLINT(bugprone-use-after-move)
.SIDE_EFFECT(
ConfigureGetPhysicalDeviceProperties2(_3,
@@ -275,6 +292,8 @@ TEST_CASE("Sysinfo methods succeed", "[.sysinfo]") {
REQUIRE(version.drvVersion == args.expectedVersion);
REQUIRE(strcmp(version.szAdapterString, "GPU0") == 0);
REQUIRE(std::string(version.szBuildBranchString).length() > 0);
+
+ ::SetEnvironmentVariableA("DXVK_NVAPI_ALLOW_OTHER_DRIVERS", "0");
}
SECTION("GetDisplayDriverVersion with version override returns OK") {
@@ -480,6 +499,8 @@ TEST_CASE("Sysinfo methods succeed", "[.sysinfo]") {
}
SECTION("GetArchInfo returns device-not-found when no NVIDIA device is present") {
+ ::SetEnvironmentVariableA("DXVK_NVAPI_ALLOW_OTHER_DRIVERS", "1");
+
ALLOW_CALL(*vulkan, GetPhysicalDeviceProperties2(_, _, _)) // NOLINT(bugprone-use-after-move)
.SIDE_EFFECT(
ConfigureGetPhysicalDeviceProperties2(_3,
@@ -496,6 +517,8 @@ TEST_CASE("Sysinfo methods succeed", "[.sysinfo]") {
NV_GPU_ARCH_INFO archInfo;
archInfo.version = NV_GPU_ARCH_INFO_VER_2;
REQUIRE(NvAPI_GPU_GetArchInfo(handle, &archInfo) == NVAPI_NVIDIA_DEVICE_NOT_FOUND);
+
+ ::SetEnvironmentVariableA("DXVK_NVAPI_ALLOW_OTHER_DRIVERS", "0");
}
SECTION("NVML depending methods succeed when NVML is available") {