feat(window): use Wayland on NVIDIA Wayland sessions

The X11/XWayland fallback guarded against the explicit-sync disconnect
that is fixed, so the rule and its driver detection are removed.
This commit is contained in:
vii committed 2026-10-09 23:57:41 -05:00
1 parent dfc3c8d555
commit 227895faa4
4 files changed
+11 -121

No files matched your search

-17
View File
@@ -1,8 +1,6 @@
#include "window/video_driver_policy.h"
#include <algorithm>
#include <system_error>
#include <unistd.h>
namespace mocktail {
namespace window {
@@ -18,10 +16,6 @@ VideoDriverChoice ResolveVideoDriverChoice(
if (input.force_x11 && input.has_x11_display) {
return VideoDriverChoice::kX11;
}
if (input.uses_direct_vulkan && input.has_nvidia_kernel_driver &&
input.has_wayland_session && input.has_x11_display) {
return VideoDriverChoice::kNvidiaDirectVulkanX11;
}
if (input.prefer_wayland && input.has_wayland_session) {
return VideoDriverChoice::kWayland;
}
@@ -33,7 +27,6 @@ const char* VideoDriverChoiceName(VideoDriverChoice choice) {
case VideoDriverChoice::kWayland:
return "wayland";
case VideoDriverChoice::kX11:
case VideoDriverChoice::kNvidiaDirectVulkanX11:
return "x11";
case VideoDriverChoice::kSdlDefault:
return nullptr;
@@ -41,16 +34,6 @@ const char* VideoDriverChoiceName(VideoDriverChoice choice) {
return nullptr;
}
bool HasNvidiaKernelDriver(const std::filesystem::path& proc_version,
const std::filesystem::path& pci_driver) {
if (access(proc_version.c_str(), R_OK) == 0) {
return true;
}
std::error_code error;
return std::filesystem::is_directory(pci_driver, error);
}
bool HasAvailableVideoDriverCandidate(
std::string_view requested,
const std::vector<std::string_view>& available_drivers) {
+2 -12
View File
@@ -1,7 +1,6 @@
#ifndef MOCKTAIL_WINDOW_VIDEO_DRIVER_POLICY_H_
#define MOCKTAIL_WINDOW_VIDEO_DRIVER_POLICY_H_
#include <filesystem>
#include <string_view>
#include <vector>
@@ -12,7 +11,6 @@ enum class VideoDriverChoice {
kSdlDefault,
kWayland,
kX11,
kNvidiaDirectVulkanX11,
};
struct VideoDriverPolicyInput {
@@ -22,23 +20,15 @@ struct VideoDriverPolicyInput {
bool prefer_wayland = true;
bool has_wayland_session = false;
bool has_x11_display = false;
bool uses_direct_vulkan = false;
bool has_nvidia_kernel_driver = false;
};
// Resolves the SDL video backend before SDL_Init. An explicit SDL driver is
// always authoritative. NVIDIA's direct Vulkan WSI uses X11/XWayland by
// default when both display transports are available to avoid native Wayland
// WSI hangs and explicit-sync protocol errors that disconnect the display.
// always authoritative. A Wayland session uses native Wayland unless X11 is
// forced or the Wayland preference is disabled.
VideoDriverChoice ResolveVideoDriverChoice(const VideoDriverPolicyInput& input);
const char* VideoDriverChoiceName(VideoDriverChoice choice);
// Also detects sandboxed drivers through sysfs when procfs is unavailable.
bool HasNvidiaKernelDriver(
const std::filesystem::path& proc_version = "/proc/driver/nvidia/version",
const std::filesystem::path& pci_driver = "/sys/bus/pci/drivers/nvidia");
// SDL accepts a comma-separated priority list. An inherited override is only
// useful when at least one requested driver exists in the linked SDL build.
bool HasAvailableVideoDriverCandidate(
-7
View File
@@ -481,8 +481,6 @@ VideoDriverChoice ResolveConfiguredVideoDriverChoice() {
!StringEquals(GetEnvNonEmpty("MOCKTAIL_FORCE_WAYLAND"), "0");
input.has_wayland_session = HasWaylandSession();
input.has_x11_display = GetEnvNonEmpty("DISPLAY") != nullptr;
input.uses_direct_vulkan = ShouldUseNativeVulkanBackend();
input.has_nvidia_kernel_driver = HasNvidiaKernelDriver();
return ResolveVideoDriverChoice(input);
}
@@ -671,11 +669,6 @@ bool ConfigureGraphicsBackendBeforeSDL() {
setenv("SDL_VIDEODRIVER", video_driver, 1);
SDL_SetHint(SDL_HINT_VIDEO_DRIVER, video_driver);
}
if (video_driver_choice == VideoDriverChoice::kNvidiaDirectVulkanX11) {
fprintf(stderr,
" [window] NVIDIA direct Vulkan on Wayland session: using "
"X11/XWayland WSI; set SDL_VIDEODRIVER=wayland to override\n");
}
const GraphicsLibraries libraries = ResolveGraphicsLibraries();
const char* egl_library =
+9 -85
View File
@@ -21,30 +21,29 @@ namespace mocktail {
namespace window {
namespace {
VideoDriverPolicyInput NvidiaWaylandDirectVulkan() {
VideoDriverPolicyInput WaylandSessionWithXwayland() {
VideoDriverPolicyInput input;
input.prefer_wayland = true;
input.has_wayland_session = true;
input.has_x11_display = true;
input.uses_direct_vulkan = true;
input.has_nvidia_kernel_driver = true;
return input;
}
TEST(VideoDriverPolicyTest, UsesXwaylandForNvidiaDirectVulkanByDefault) {
EXPECT_EQ(ResolveVideoDriverChoice(NvidiaWaylandDirectVulkan()),
VideoDriverChoice::kNvidiaDirectVulkanX11);
TEST(VideoDriverPolicyTest, UsesWaylandOnWaylandSessionWithXwayland) {
EXPECT_EQ(ResolveVideoDriverChoice(WaylandSessionWithXwayland()),
VideoDriverChoice::kWayland);
}
TEST(VideoDriverPolicyTest, ExplicitSdlDriverRemainsAuthoritative) {
VideoDriverPolicyInput input = NvidiaWaylandDirectVulkan();
VideoDriverPolicyInput input = WaylandSessionWithXwayland();
input.has_explicit_sdl_driver = true;
EXPECT_EQ(ResolveVideoDriverChoice(input), VideoDriverChoice::kSdlDefault);
}
TEST(VideoDriverPolicyTest, ForceWaylandOverridesNvidiaFallback) {
VideoDriverPolicyInput input = NvidiaWaylandDirectVulkan();
TEST(VideoDriverPolicyTest, ForceWaylandSelectsWaylandWithoutPreference) {
VideoDriverPolicyInput input = WaylandSessionWithXwayland();
input.prefer_wayland = false;
input.force_wayland = true;
EXPECT_EQ(ResolveVideoDriverChoice(input), VideoDriverChoice::kWayland);
@@ -60,19 +59,8 @@ TEST(VideoDriverPolicyTest, ForceX11WinsForAvailableDisplay) {
EXPECT_EQ(ResolveVideoDriverChoice(input), VideoDriverChoice::kX11);
}
TEST(VideoDriverPolicyTest, KeepsWaylandForNonNvidiaAndNonDirectBackends) {
VideoDriverPolicyInput input = NvidiaWaylandDirectVulkan();
input.uses_direct_vulkan = false;
EXPECT_EQ(ResolveVideoDriverChoice(input), VideoDriverChoice::kWayland);
input.uses_direct_vulkan = true;
input.has_nvidia_kernel_driver = false;
EXPECT_EQ(ResolveVideoDriverChoice(input), VideoDriverChoice::kWayland);
}
TEST(VideoDriverPolicyTest, KeepsWaylandWhenXwaylandIsUnavailable) {
VideoDriverPolicyInput input = NvidiaWaylandDirectVulkan();
VideoDriverPolicyInput input = WaylandSessionWithXwayland();
input.has_x11_display = false;
EXPECT_EQ(ResolveVideoDriverChoice(input), VideoDriverChoice::kWayland);
@@ -90,8 +78,6 @@ TEST(VideoDriverPolicyTest, UsesSdlDefaultWhenWaylandPreferenceIsDisabled) {
TEST(VideoDriverPolicyTest, NamesOnlySelectedDrivers) {
EXPECT_STREQ(VideoDriverChoiceName(VideoDriverChoice::kWayland), "wayland");
EXPECT_STREQ(VideoDriverChoiceName(VideoDriverChoice::kX11), "x11");
EXPECT_STREQ(VideoDriverChoiceName(VideoDriverChoice::kNvidiaDirectVulkanX11),
"x11");
EXPECT_EQ(VideoDriverChoiceName(VideoDriverChoice::kSdlDefault), nullptr);
}
@@ -112,68 +98,6 @@ TEST(VideoDriverPolicyTest, RejectsUnavailableOrEmptyDriverList) {
EXPECT_FALSE(HasAvailableVideoDriverCandidate("", available));
}
class NvidiaDriverDetectionTest : public ::testing::Test {
protected:
void SetUp() override {
char pattern[] = "/tmp/mocktail_video_driver_XXXXXX";
const char* created = mkdtemp(pattern);
ASSERT_NE(created, nullptr);
root_ = created;
proc_version_ = root_ / "proc/driver/nvidia/version";
pci_drivers_ = root_ / "sys/bus/pci/drivers";
}
void TearDown() override {
std::error_code error;
std::filesystem::remove_all(root_, error);
}
bool Detect() const {
return HasNvidiaKernelDriver(proc_version_, pci_drivers_ / "nvidia");
}
std::filesystem::path root_;
std::filesystem::path proc_version_;
std::filesystem::path pci_drivers_;
};
TEST_F(NvidiaDriverDetectionTest, DetectsProcDriverWithoutSysfs) {
std::filesystem::create_directories(proc_version_.parent_path());
std::ofstream(proc_version_) << "NVRM version: NVIDIA UNIX Kernel Module\n";
EXPECT_TRUE(Detect());
}
TEST_F(NvidiaDriverDetectionTest, HybridGpuUsesXwaylandWhenProcIsHidden) {
std::filesystem::create_directories(pci_drivers_ / "i915");
std::filesystem::create_directories(pci_drivers_ / "nvidia");
VideoDriverPolicyInput input = NvidiaWaylandDirectVulkan();
input.has_nvidia_kernel_driver = Detect();
EXPECT_TRUE(input.has_nvidia_kernel_driver);
EXPECT_EQ(ResolveVideoDriverChoice(input),
VideoDriverChoice::kNvidiaDirectVulkanX11);
input.force_wayland = true;
EXPECT_EQ(ResolveVideoDriverChoice(input), VideoDriverChoice::kWayland);
input.has_explicit_sdl_driver = true;
EXPECT_EQ(ResolveVideoDriverChoice(input), VideoDriverChoice::kSdlDefault);
}
TEST_F(NvidiaDriverDetectionTest, DoesNotTreatNouveauAsTheNvidiaDriver) {
std::filesystem::create_directories(pci_drivers_ / "nouveau");
std::filesystem::create_directories(pci_drivers_ / "i915");
std::filesystem::create_directories(pci_drivers_ / "amdgpu");
EXPECT_FALSE(Detect());
}
TEST_F(NvidiaDriverDetectionTest, IgnoresMissingAndUnrelatedDeviceInformation) {
EXPECT_FALSE(Detect());
std::filesystem::create_directories(pci_drivers_ / "nvidia_drm");
std::ofstream(pci_drivers_ / "nvidia") << "not a registered driver\n";
EXPECT_FALSE(Detect());
}
TEST(VideoDriverPolicyIntegrationTest,
DropsUnavailableLegacyOverrideBeforeSdlInit) {
bool has_dummy_driver = false;