fix(agc): name the reason when /dev/udmabuf cannot be opened

On Linux, shared direct memory is imported through /dev/udmabuf (#943).
Many distributions create it as root:kvm 0660, so a user outside the
kvm group cannot open it. The ranges are then copied instead of
imported, and GPU stores through FLAT/GLOBAL addresses to them fail
with "BDA access failed": DOOM PPSA99666's compute presenter falls back
to its CPU scaler. The only trace was "failed at open /dev/udmabuf
(-1000072003)", a Vulkan result that hides errno.

Print the open error once, with the fix for EACCES, and document the
requirement in USAGE.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
john.maia 2026-10-08 17:27:02 +01:00
parent 464203cea8
commit f70d2bdf87
2 changed files with 12 additions and 1 deletions

View File

@ -29,6 +29,7 @@
#include <set>
#include <thread>
#include <stop_token>
#include <cerrno>
#include <cstdlib>
#include <cstdio>
#include <chrono>
@ -239,7 +240,15 @@ const char* createHostPointerImport(const Context& context, HostImport& entry, V
#ifndef _WIN32
int udmabufDevice() {
static const int device = open("/dev/udmabuf", O_RDWR | O_CLOEXEC);
static const int device = [] {
const int result = open("/dev/udmabuf", O_RDWR | O_CLOEXEC);
if (result < 0) {
const int error = errno;
std::fprintf(stderr, "[gpu] open /dev/udmabuf: %s; shared direct memory is copied instead of imported, and GPU stores through FLAT/GLOBAL addresses do not reach it%s\n",
std::strerror(error), error == EACCES ? " (give the user read-write access to /dev/udmabuf, for example through the kvm group)" : "");
}
return result;
}();
return device;
}

View File

@ -76,6 +76,8 @@ On Windows, a self-built `libs/` also needs `libgcc_s_seh-1.dll`, `libstdc++-6.d
On Windows, direct memory (`sceKernelAllocateDirectMemory`, up to 13824 MiB per title) is committed in full when the title allocates it, not when its pages are first used. The system commit limit (installed memory plus page file size, the second value of Committed in Task Manager) must cover it together with all other committed memory. Otherwise the allocation throws `create direct memory backing of 0x<n> bytes (<m> MiB)` with the Windows error; enlarge the page file or close other applications.
On Linux, when the Vulkan driver imports dma-buf memory (not the NVIDIA proprietary driver), shared direct memory is imported through `/dev/udmabuf`, and the user who runs the game needs read-write access to it. Many distributions create it as `root:kvm` with mode `0660`: add the user to the `kvm` group and log in again (an ACL such as `setfacl -m u:$USER:rw /dev/udmabuf` lasts until the next reboot). Without access, startup prints `[gpu] open /dev/udmabuf: Permission denied`, these ranges are copied instead of imported, and GPU stores to them through FLAT/GLOBAL addresses fail with `BDA access failed`. Ranges above udmabuf's `size_limit_mb` (64 MiB by default) are copied as well.
Linux:
```sh