Hi there, as Nvidia shut down 32bit PhysX-Support for the rtx50-series, I was struggling with this, too. I have an rtx A400, that does the PhysX in Windows, but there was no solution for Linux. I am using CachyOS btw. Today I thought, I'd let the new Opus5.5 dwell another round on that problem. And it got to a solution. It compiled a new dxvk/nvapi.dll based on SveSop's branch. And it works. A400 is showing activity and frames keep steady at 62, as the game is horrible at holding its own fps limit. The dll needs to replace the CachyOS's own dll, as Proton copies it over at every game start.
This is the patch it implemented:
From 53a41dca7eb9f4098f384c742d2b9d77b97d8f29 Mon Sep 17 00:00:00 2001
From: build <x@x>
Date: Wed, 23 Sep 2026 09:18:32 +0000
Subject: [PATCH] nvapi_gpu: treat CudaEnumComputeCapableGpus V2 computeGpus as
output pointer
---
src/nvapi_gpu.cpp | 39 +++++++++++++++++++--------------------
1 file changed, 19 insertions(+), 20 deletions(-)
diff --git a/src/nvapi_gpu.cpp b/src/nvapi_gpu.cpp
index e4be425..bce3909 100644
--- a/src/nvapi_gpu.cpp
+++ b/src/nvapi_gpu.cpp
@@ -1,3 +1,6 @@
+#include <algorithm>
+#include <array>
+#include <mutex>
#include "nvapi_private.h"
#include "nvapi_globals.h"
#include "util/util_statuscode.h"
@@ -703,29 +706,25 @@ NVAPI_FUNCTION NvAPI_GPU_CudaEnumComputeCapableGpus(NV_COMPUTE_GPU_TOPOLOGY* pCo
case NV_COMPUTE_GPU_TOPOLOGY_VER: {
auto pComputeTopoV2 = reinterpret_cast<NV_COMPUTE_GPU_TOPOLOGY_V2*>(pComputeTopo);
- // If caller only wants to check gpuCount, but has not allocated memory for computeGpus
- if (!pComputeTopoV2->gpuCount) {
- pComputeTopoV2->gpuCount = cudaCapableGpus.size();
- return Ok(n);
- }
- // Safeguard in case caller has not allocated memory for computeGpus struct
- if (!pComputeTopoV2->computeGpus)
- return InvalidArgument(n);
-
- // Write required adapter info - Assume caller has only allocated size gpuCount to the array
- // Compare possible size given in the array vs. adapters available
- auto count = pComputeTopoV2->gpuCount < cudaCapableGpus.size()
- ? pComputeTopoV2->gpuCount
- : cudaCapableGpus.size();
-
- // Fill in physical info in the array
+ // In V2, computeGpus is an OUTPUT pointer owned by NVAPI, not a caller-provided buffer.
+ // Evidence: PhysX System Software 9.x (PhysXDevice.dll) calls this function with only
+ // `version` initialized (gpuCount/computeGpus left as uninitialized stack data), or with
+ // gpuCount=0 and computeGpus=NULL, and afterwards reads gpuCount entries through the
+ // returned computeGpus pointer. Writing through the caller's pointer therefore crashes
+ // (e.g. Batman: Arkham Asylum, APEX titles), and rejecting V2 disables GPU PhysX.
+ // So: ignore input values, hand out a pointer to storage that lives as long as the DLL.
+ static std::mutex computeGpusMutex;
+ static std::array<NV_COMPUTE_GPU, NVAPI_MAX_PHYSICAL_GPUS> computeGpus{};
+
+ std::scoped_lock lock(computeGpusMutex);
+ auto count = std::min<size_t>(cudaCapableGpus.size(), computeGpus.size());
for (auto i = 0U; i < count; i++) {
- pComputeTopoV2->computeGpus[i].hPhysicalGpu = cudaCapableGpus[i];
- pComputeTopoV2->computeGpus[i].flags = flags;
+ computeGpus[i].hPhysicalGpu = cudaCapableGpus[i];
+ computeGpus[i].flags = flags;
}
- // Return total number of adapters in gpuCount
- pComputeTopoV2->gpuCount = cudaCapableGpus.size();
+ pComputeTopoV2->gpuCount = static_cast<NvU32>(count);
+ pComputeTopoV2->computeGpus = computeGpus.data();
break;
}
default:
--
2.43.0
nvapi.dllx1 2026-09physxdevice.dllx1 2026-09
There is a problem with older 32-Bit games with PhysX
in Linux 20.04.4 requires Legacy GL drivers LibGL1
but those drivers are Not compatible with all Nvidia proprietary drivers,
so far: driver 470 works ok,
with GPUs around 2016, like GTX 1050Ti, Quadro M & Quadro P
Driver detects Dual GPU installed...
but does Not have the PhysX option to force PhysX to CPU or GPU, like Windows Nvidia driver,
Batman Arkham Asylum GOTY v1.1
PhysX High setting works only with 1x GPU,
PhysX 9.14
does Not work with Dual GPU,
second GPU has 0% load, small ram usage.
at the beginning, there is steam falling, in a corridor,
that part drops fps to 15,
tested single channel RAM vs. Dual Channel,
fps drops, severe affected by single-channel DDR5-5600 XMP1.
Faster single core helps.
just curious to know what are your opinions.