mirror of
https://github.com/Droid-Deck/DroidDeck.git
synced 2026-11-07 10:46:06 -10:00
gamescope: explicit sync off where the kernel or the stand-in node cannot signal its timelines
Adds tools/gamescope/patches/0126 (GAMESCOPE_DISABLE_EXPLICIT_SYNC=1 for the nested backends) and sets it on a GPU that is not an Adreno when the kernel is older than 6.6 (no DRM_IOCTL_SYNCOBJ_EVENTFD) or the guest's render node is Mali's stand-in. The graphics report lists it with the rest of the guest's graphics environment.
This commit is contained in:
1 parent
13e712c849
commit
0136fb6196
4 files changed
+57
-1
No files matched your search
@@ -35,7 +35,7 @@ object GraphicsReport {
|
||||
/** The guest keys the report repeats: everything that decides which Vulkan driver loads. */
|
||||
private val ENV_PREFIXES = listOf(
|
||||
"VK_", "BL_VK", "BL_DRM", "BL_VKBRIDGE", "VKBRIDGE", "MESA_", "GALLIUM_", "ZINK", "TU_", "PANVK",
|
||||
"DROIDDECK_POWERVR", "DROIDDECK_HYBRIS", "BL_GAME_LOGS", "LIBGL_",
|
||||
"DROIDDECK_POWERVR", "DROIDDECK_HYBRIS", "BL_GAME_LOGS", "LIBGL_", "GAMESCOPE_DISABLE", "XWAYLAND",
|
||||
)
|
||||
|
||||
/** Per-game graphics logs and the guest's Vulkan summary: on for a non-Adreno GPU, or by Setup's switch. */
|
||||
|
||||
@@ -307,6 +307,13 @@ class SessionService : Service() {
|
||||
return lines
|
||||
}
|
||||
|
||||
/** Whether a kernel release ("6.1.157-android14-11") is older than [major].[minor]; false if unreadable. */
|
||||
internal fun kernelBefore(release: String, major: Int, minor: Int): Boolean {
|
||||
val m = Regex("""^(\d+)\.(\d+)""").find(release) ?: return false
|
||||
val (a, b) = m.destructured
|
||||
return a.toInt() < major || (a.toInt() == major && b.toInt() < minor)
|
||||
}
|
||||
|
||||
/** Whether the newest finished session's log shows Xwayland itself crashing. */
|
||||
private fun lastXwaylandCrashed(): Boolean = runCatching {
|
||||
val last = SessionPaths.sessionFolders(this).filter { it != SessionPaths.current() }.lastOrNull() ?: return false
|
||||
@@ -663,6 +670,20 @@ class SessionService : Service() {
|
||||
guest.add("XWAYLAND_NO_GLAMOR=1")
|
||||
Log.w(TAG, "xwayland: the last session's Xwayland crashed; glamor off for this one (XWAYLAND_NO_GLAMOR=1)")
|
||||
}
|
||||
// gamescope's explicit sync waits on DRM syncobj timelines through
|
||||
// DRM_IOCTL_SYNCOBJ_EVENTFD, which a kernel before 6.6 does not have (Exynos 2400e on 6.1:
|
||||
// hundreds of "timeline ... failed" and a game stuck at black), and Mali's stand-in node
|
||||
// (/dev/mali0) has no syncobjs at all. There clients use implicit sync instead
|
||||
// (tools/gamescope/patches/0126). Never on an Adreno.
|
||||
if (!com.droiddeck.launcher.core.DeviceSupport.adreno()) {
|
||||
val kernel = System.getProperty("os.version").orEmpty()
|
||||
val old = kernelBefore(kernel, 6, 6)
|
||||
val maliNode = LinuxRuntime.gpuStandIn(this) == LinuxRuntime.MALI_DEVICE
|
||||
if (old || maliNode) {
|
||||
guest.add("GAMESCOPE_DISABLE_EXPLICIT_SYNC=1")
|
||||
Log.i(TAG, "gamescope: explicit sync off (" + (if (old) "kernel $kernel has no SYNCOBJ_EVENTFD" else "Mali stand-in node has no syncobjs") + ")")
|
||||
}
|
||||
}
|
||||
if (!bridge && com.droiddeck.launcher.core.DeviceSupport.openDriverActive(this)) {
|
||||
LinuxRuntime.gpuStandIn(this)?.takeIf { it == LinuxRuntime.MALI_DEVICE }?.let { guest.add("BL_DRM_STANDIN=$it") }
|
||||
}
|
||||
|
||||
@@ -62,3 +62,9 @@ The system PowerVR driver uses the existing SDL/Wayland swapchain backend. Its a
|
||||
|
||||
Sixteen more of Armada's patches are DRM/lease/HDR-on-KMS work for a native display, which this
|
||||
app's Wayland-hosted gamescope never reaches, or need a newer gamescope than the runtime has.
|
||||
- `0126-explicit-sync-switch.patch`: `GAMESCOPE_DISABLE_EXPLICIT_SYNC=1` makes the nested
|
||||
(Wayland and SDL) backends report no explicit sync, so gamescope does not offer
|
||||
wp_linux_drm_syncobj_manager_v1 and clients use implicit sync. The app sets it on a GPU that is
|
||||
not an Adreno when the kernel is older than 6.6 (no DRM_IOCTL_SYNCOBJ_EVENTFD: an Exynos 2400e
|
||||
on 6.1 logged hundreds of "timeline: DRM_IOCTL_SYNCOBJ_EVENTFD failed" and a game hung at a
|
||||
black screen) or when the render node is Mali's stand-in (/dev/mali0 has no DRM syncobjs).
|
||||
@@ -0,0 +1,29 @@
|
||||
--- a/src/Backends/WaylandBackend.cpp
|
||||
+++ b/src/Backends/WaylandBackend.cpp
|
||||
@@ -2309,7 +2309,10 @@
|
||||
|
||||
bool CWaylandBackend::SupportsExplicitSync() const
|
||||
{
|
||||
- return true;
|
||||
+ // GAMESCOPE_DISABLE_EXPLICIT_SYNC=1: a kernel without DRM_IOCTL_SYNCOBJ_EVENTFD (before
|
||||
+ // Linux 6.6) cannot signal the timelines, so clients use implicit sync instead.
|
||||
+ const char *pszDisable = getenv( "GAMESCOPE_DISABLE_EXPLICIT_SYNC" );
|
||||
+ return !( pszDisable && *pszDisable == '1' );
|
||||
}
|
||||
|
||||
bool CWaylandBackend::IsPaused() const
|
||||
--- a/src/Backends/SDLBackend.cpp
|
||||
+++ b/src/Backends/SDLBackend.cpp
|
||||
@@ -506,8 +506,10 @@
|
||||
|
||||
bool CSDLBackend::SupportsExplicitSync() const
|
||||
{
|
||||
- // We use a Vulkan swapchain, so yes.
|
||||
- return true;
|
||||
+ // We use a Vulkan swapchain, so yes - unless the kernel cannot signal the timelines
|
||||
+ // (no DRM_IOCTL_SYNCOBJ_EVENTFD before Linux 6.6): GAMESCOPE_DISABLE_EXPLICIT_SYNC=1.
|
||||
+ const char *pszDisable = getenv( "GAMESCOPE_DISABLE_EXPLICIT_SYNC" );
|
||||
+ return !( pszDisable && *pszDisable == '1' );
|
||||
}
|
||||
|
||||
bool CSDLBackend::IsPaused() const
|
||||
Reference in new issue
Block a user