Auto fetches the open drivers itself; Xclipse named as such; sound and frame-gen in the logs

- Auto looks online again when its saved release list predates this device's open drivers, so a
  Samsung or Mali phone gets its pair without pressing refresh first.
- A Samsung Xclipse is labelled "Samsung Xclipse" (not PowerVR), with its own support line.
- Per-game logs add audio-streams.txt: PulseAudio's sink inputs 20 s and 60 s into the launch,
  so a silent game shows whether its stream reached Pulse.
- graphics-report.txt states the frame-generation setting and keeps the LSFG gate, FrameGen and
  audio lines from app.log.
This commit is contained in:
The412Banner committed 2026-10-12 20:28:51 -04:00
1 parent e5bea33cdc
commit e37f20625b
6 files changed
+23 -6

No files matched your search

@@ -61,7 +61,7 @@ internal class DriverMenus(private val activity: Activity, private val ui: Handl
private var autoCheckedThisProcess = false
fun state() = GpuDriversState(
gpuName = gpu.displayName(activity), gpuFamily = gpu.family.label(activity), soc = gpu.soc, supportText = gpu.supportText(activity),
gpuName = gpu.displayName(activity), gpuFamily = if (gpu.name.contains("Xclipse", ignoreCase = true)) gpu.family.label(gpu.name) else gpu.family.label(activity), soc = gpu.soc, supportText = gpu.supportText(activity),
supported = gpu.support == GpuInfo.Support.TESTED, unsupported = gpu.support == GpuInfo.Support.UNSUPPORTED,
auto = mode == SessionPrefs.GPU_DRIVERS_AUTO, pairs = pairRows, busy = pairBusy, percent = pairPercent,
autoStatus = autoStatus, releaseStatus = releaseStatus.ifEmpty { activity.getString(R.string.drivers_not_checked) }, checking = releaseChecking,
@@ -198,7 +198,9 @@ internal class DriverMenus(private val activity: Activity, private val ui: Handl
Thread({
val cached = TurnipReleases.cached(activity)
val stale = cached == null || System.currentTimeMillis() - cached.checkedAt > 24 * 3_600_000L ||
cached.assets.none { it.pair.isNotEmpty() }
cached.assets.none { it.pair.isNotEmpty() } ||
// A list checked before this device's open drivers were offered has none of them.
(!DeviceSupport.adreno() && cached.assets.none { DriverPairs.isNonAdreno(it.pair) })
val problem = if (force || stale) runCatching { TurnipReleases.refresh(activity) }.exceptionOrNull()?.message else null
ui.post {
releaseChecking = false
@@ -124,7 +124,7 @@ object DeviceReport {
h("Drivers")
val gpu = com.droiddeck.launcher.gpu.GpuInfo.detect()
k("GPU", "${gpu.name} · ${gpu.family.label} · ${gpu.supportText}" + if (gpu.oneUi8Gen2) " · One UI 8 Gen 2" else "")
k("GPU", "${gpu.name} · ${gpu.family.label(gpu.name)} · ${gpu.supportText}" + if (gpu.oneUi8Gen2) " · One UI 8 Gen 2" else "")
k("Driver mode", SessionPrefs.gpuDriverMode(context) +
(com.droiddeck.launcher.gpu.DriverPairs.recommendedKey(gpu, com.droiddeck.launcher.gpu.DriverPairs.from(
com.droiddeck.launcher.gpu.TurnipReleases.cached(context)))?.let { " (recommended pair: $it)" } ?: ""))
@@ -61,7 +61,7 @@ object DeviceInfo {
private fun gpu(gpu: GpuInfo) = Section("GPU", buildList<Pair<String, String>> {
add("GPU", gpu.name)
add("Family", gpu.family.label)
add("Family", gpu.family.label(gpu.name))
add("Model found from", when (gpu.modelSource) {
"kernel" -> "the kernel's GPU name"
"vulkan" -> "the Vulkan driver (the kernel's name has no model)"
@@ -49,6 +49,9 @@ data class GpuInfo(
val mali: Boolean get() = name.startsWith("MALI_")
/** [label] for this GPU: the system-driver family is a Samsung Xclipse or a PowerVR. */
fun label(gpuName: String): String = if (this == POWERVR && gpuName.contains("Xclipse", ignoreCase = true)) "Samsung Xclipse" else label
/** [label] in the app's language: the Adreno families are names, the rest is words. */
fun label(context: Context): String = if (this == NOT_ADRENO) context.getString(R.string.gpuinfo_not_adreno) else label
}
@@ -69,7 +72,8 @@ data class GpuInfo(
get() = when (support) {
Support.TESTED -> "Supported"
Support.UNTESTED -> when (family) {
Family.POWERVR -> "System PowerVR driver: compatibility varies by device"
Family.POWERVR -> if (name.contains("Xclipse", ignoreCase = true)) "Experimental: RADV or the system Xclipse driver"
else "System PowerVR driver: compatibility varies by device"
Family.MALI_OTHER -> "Experimental: Mali through the Vulkan bridge"
Family.MALI_JM, Family.MALI_G610_G710, Family.MALI_G615, Family.MALI_G720, Family.MALI_LATEST -> "Experimental: open Mali driver (test builds)"
Family.A7XX_LOW -> "Experimental: its drivers are test builds"
@@ -65,6 +65,8 @@ object GraphicsReport {
val pairs = DriverPairs.from(TurnipReleases.cached(context))
appendLine("auto would pick: " + (DriverPairs.recommendedKey(gpu, pairs) ?: "(no pair: system driver or bridge)"))
}
appendLine("frame generation: " + runCatching { com.droiddeck.launcher.gpu.FrameGen.mode(context).toString() }.getOrDefault("?") +
" (engine=off means it is switched off in Play settings; a driver that fails LSFG's gates logs \"device gates\" below)")
appendLine("mali bridge setting: " + SessionPrefs.vkBridge(context) + ", in use: " + DeviceSupport.vkBridge(context))
val standIn = runCatching { com.droiddeck.launcher.runtime.LinuxRuntime.gpuStandIn(context) }.getOrNull()
appendLine("render node for the guest: " + (standIn?.let { node ->
@@ -134,7 +136,8 @@ object GraphicsReport {
/** The compositor's driver lines from the app's own log. */
private val COMPOSITOR = Regex(
"""vk_present|waylandcomp|vk_loader|compositor|vkCreateDevice|extension|adrenotools|TurnipDriver|""" +
"""graphics driver|SystemVulkan|vkbridge|VkBridge|mali_gralloc|panvk|PanVK|radv|MESA|native buffer|first frame|present""",
"""graphics driver|SystemVulkan|vkbridge|VkBridge|mali_gralloc|panvk|PanVK|radv|MESA|native buffer|first frame|present|""" +
"""lsfg|FrameGen|device gates|AAudio|directaudio|pulse""",
RegexOption.IGNORE_CASE,
)
@@ -392,6 +392,14 @@ def game_logs(command, env, app_id, now=None):
if key.startswith(("VK_", "BL_VK", "BL_DRM", "MESA_", "PANVK", "DXVK_", "VKD3D", "ZINK", "TU_"))]) + "\n")
except OSError:
pass
# Whether the game's sound reaches PulseAudio: the streams 20 s and 60 s in, without waiting.
try:
subprocess.Popen(["sh", "-c", 'for t in 20 40; do sleep $t; { echo "== $(date +%T)"; '
'pactl list sink-inputs 2>&1 | head -80; } >> "$1/audio-streams.txt"; done', "audio", str(folder)],
stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
start_new_session=True)
except OSError:
pass
return result