mirror of
https://github.com/InstanceBrick/nightcap.git
synced 2026-10-17 17:00:55 +02:00
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:
1 parent
dfc3c8d555
commit
227895faa4
4 files changed
+11
-121
No files matched your search
@@ -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) {
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in new issue
Block a user