Kitty and alacritty cannot launch in vmware workstation pro, 3d accel is enabled #12966
Replies: 3 comments 10 replies
|
I stumbled upon this patch. It allows hyprland to work together with the vmwgfx driver in VMWare Fusion. |
|
Hihi, I recently ran into this issue too and it dove me down a little rabbit hole of figuring out why the bug even occurs. I, like OP, had an issue with Kitty not wanting to open. The patch by Andrew Bastin offers a way to somewhat ignore why the issue is occurring but I don't think it fully tackles why this is happening. In Short, Why is it CrashingI can go into more detail but on VMWare guests using So the flow ends up being if a Mesa/svga client buffer has an associated guest-backed surface, This inevitably needs to be a kernel fix, but we can still perform a proper deallocation in userspace through libdrm and sending the command A FixHere is my patch atleast for the Hyprland code. I also included the one for Wlroots but that probably won't be something fixed here, just more for completion sake. Hyprland --- a/src/protocols/LinuxDMABUF.cpp
+++ b/src/protocols/LinuxDMABUF.cpp
@@ -4,6 +4,7 @@
#include <tuple>
#include "../helpers/MiscFunctions.hpp"
#include <sys/mman.h>
+#include <cstring>
#include <xf86drm.h>
#include <fcntl.h>
#include <sys/stat.h>
@@ -261,6 +262,30 @@
m_createdBuffer = buf;
}
+#define DRM_VMW_UNREF_SURFACE 10
+
+struct drmVmwSurfaceArg {
+ int32_t sid;
+ uint32_t handleType;
+};
+
+// vmwgfx prime-imports surface-backed dmabufs as TTM handles, not GEM, so
+// GEM_CLOSE fails with EINVAL; close them via DRM_VMW_UNREF_SURFACE instead.
+static int closeVmwGFXHandle(int fd, uint32_t handle) {
+ bool isVmwgfx;
+ drmVersionPtr version;
+
+ version = drmGetVersion(fd);
+ isVmwgfx = version && version->name && strncmp(version->name, "vmwgfx", version->name_len) == 0;
+ if (version)
+ drmFreeVersion(version);
+ if (!isVmwgfx)
+ return -1;
+
+ struct drmVmwSurfaceArg arg = {(int32_t)handle, 0};
+ return drmCommandWrite(fd, DRM_VMW_UNREF_SURFACE, &arg, sizeof(arg));
+}
+
bool CLinuxDMABUFParamsResource::commence() {
if (!PROTO::linuxDma->m_mainDeviceFD.isValid())
return true;
@@ -273,7 +298,7 @@
return false;
}
- if (drmCloseBufferHandle(PROTO::linuxDma->m_mainDeviceFD.get(), handle)) {
+ if (drmCloseBufferHandle(PROTO::linuxDma->m_mainDeviceFD.get(), handle) != 0 && closeVmwGFXHandle(PROTO::linuxDma->m_mainDeviceFD.get(), handle) != 0) {
LOGM(Log::ERR, "Failed to close dmabuf handle");
return false;
}And for wlroots --- a/types/wlr_linux_dmabuf_v1.c
+++ b/types/wlr_linux_dmabuf_v1.c
@@ -205,6 +205,30 @@
wlr_buffer_drop(&buffer->base);
}
+#define DRM_VMW_UNREF_SURFACE 10
+
+struct drmVmwSurfaceArg {
+ int32_t sid;
+ uint32_t handleType;
+};
+
+/* vmwgfx prime-imports surface-backed dmabufs as TTM handles, not GEM, so
+ * GEM_CLOSE fails with EINVAL; close them via DRM_VMW_UNREF_SURFACE instead. */
+static int closeVmwGFXHandle(int fd, uint32_t handle) {
+ bool isVmwgfx;
+ drmVersionPtr version;
+
+ version = drmGetVersion(fd);
+ isVmwgfx = version && version->name && strncmp(version->name, "vmwgfx", version->name_len) == 0;
+ if (version)
+ drmFreeVersion(version);
+ if (!isVmwgfx)
+ return -1;
+
+ struct drmVmwSurfaceArg arg = {(int32_t)handle, 0};
+ return drmCommandWrite(fd, DRM_VMW_UNREF_SURFACE, &arg, sizeof(arg));
+}
+
static bool check_import_dmabuf(struct wlr_dmabuf_attributes *attribs, void *data) {
struct wlr_linux_dmabuf_v1 *linux_dmabuf = data;
@@ -219,7 +243,8 @@
wlr_log_errno(WLR_ERROR, "Failed to import DMA-BUF FD for plane %d", i);
return false;
}
- if (drmCloseBufferHandle(linux_dmabuf->main_device_fd, handle) != 0) {
+ if (drmCloseBufferHandle(linux_dmabuf->main_device_fd, handle) != 0 &&
+ closeVmwGFXHandle(linux_dmabuf->main_device_fd, handle) != 0) {
wlr_log_errno(WLR_ERROR, "Failed to close buffer handle for plane %d", i);
return false;
}Success and NixOS PatchThis successfully let me patch my NixOS setup and now I can use multiple GPU accelerated programs just fine in Hyprland and Wayland in VMWare. For anyone else using NixOS here is how you can use these patches in NixOS. This is much like that one guy's patch more or less: { config, lib, ... }:
let
cfg = config.patches.vmwgfx-dmabuf;
in {
options.patches.vmwgfx-dmabuf.enable = lib.mkEnableOption
"vmwgfx dmabuf import fix for Hyprland/wlroots (VMware guests)";
config = lib.mkIf cfg.enable {
nixpkgs.overlays = [
(final: prev: {
hyprland = prev.hyprland.overrideAttrs (old: {
patches = (old.patches or [ ]) ++ [ ./hyprland-vmwgfx-dmabuf.patch ];
});
wlroots_0_20 = prev.wlroots_0_20.overrideAttrs (old: {
patches = (old.patches or [ ]) ++ [ ./wlroots-vmwgfx-dmabuf.patch ];
});
})
];
};
} |
|
I tested the vmwgfx TTM-handle close patch posted above against Hyprland The patch adds a vmwgfx-specific fallback in Only Before the patch, GPU-rendered Wayland clients failed with DMA-BUF / The original 120 FPS Omarchy screensaver provided a convenient repeatable workload and produced approximately:
After applying the patch:
Versions
We observed one RustDesk / This only validates one VMware configuration, but the result strongly supports the proposed vmwgfx TTM surface-handle close path as the fix for the reproduced failure. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
VMware workstation pro, version 17.5.0.
3d acceleration is enabled for the VM.
The host is windows 10 IoT Enterprise LTSC, version 21H2.
The VM's OS is ArchLinux, kernel 6.18.4-arch1-1.
The graphics information:
They launch fine in gnome and niri, but cannot launch in hyprland
kitty's output:
alacritty's output
All reactions