mirror of
https://github.com/Droid-Deck/DroidDeck.git
synced 2026-10-14 19:27:09 -04:00
Open driver pairs: vkd3d-proton reports the driver's caps; buffer attach/release tracing; Mesa log
- With a PanVK or RADV pair (BL_OPEN_DRIVER=1), droiddeck-game-env drops the app-wide VKD3D_FEATURE_LEVEL=12_2 and VKD3D_SHADER_MODEL=6_9 so vkd3d-proton reports what the driver has (an Unreal DX12 game crashed at start on PanVK with the overrides); a game's own setting still wins, and launch.txt records DROIDDECK_VKD3D_CAPS=driver. - The compositor traces, on a GPU that is not an Adreno, the first 400 dma-buf attaches and buffer releases by wl_buffer id and sending line, and logs any release of a buffer already released and not attached again (gamescope's "Compositor released us but we were not acquired" on G925). - Per-game logs no longer set MESA_DEBUG=silent, which kept mesa.log empty.
This commit is contained in:
1 parent
0e44b3a032
commit
d16ca4d8a8
5 files changed
+64
-5
No files matched your search
@@ -385,8 +385,39 @@ static struct dmabuf_buffer *get_dmabuf(struct wl_resource *buffer);
|
||||
static int buffer_release_blocked(struct wl_resource *buffer) {
|
||||
return vkp_completion_unknown() && get_dmabuf(buffer) != NULL;
|
||||
}
|
||||
static void send_buffer_release(struct wl_resource *buffer) {
|
||||
if (!buffer_release_blocked(buffer)) wl_buffer_send_release(buffer);
|
||||
/* Buffer tracing on a GPU that is not an Adreno (no KGSL node): every attach and release of the
|
||||
* first 400 buffer events, by wl_buffer id and the line that sent it, and any release of a buffer
|
||||
* already released and not attached again since (gamescope: "Compositor released us but we were
|
||||
* not acquired"). Off on an Adreno. */
|
||||
static int g_buf_trace = -1;
|
||||
static int g_buf_trace_left = 400;
|
||||
static uint32_t g_released_ids[128];
|
||||
static int buf_trace_on(void) {
|
||||
if (g_buf_trace < 0) g_buf_trace = access("/dev/kgsl-3d0", F_OK) != 0;
|
||||
return g_buf_trace;
|
||||
}
|
||||
static void buf_trace_attach(struct wl_resource *buffer) {
|
||||
if (!buffer || !buf_trace_on()) return;
|
||||
uint32_t id = wl_resource_get_id(buffer);
|
||||
for (int i = 0; i < 128; i++) if (g_released_ids[i] == id) g_released_ids[i] = 0;
|
||||
if (g_buf_trace_left > 0) { g_buf_trace_left--; droiddeck_log("buffer", "attach id %u", id); }
|
||||
}
|
||||
static void buf_trace_release(struct wl_resource *buffer, int line) {
|
||||
if (!buffer || !buf_trace_on()) return;
|
||||
uint32_t id = wl_resource_get_id(buffer);
|
||||
int twice = 0, slot = -1;
|
||||
for (int i = 0; i < 128; i++) {
|
||||
if (g_released_ids[i] == id) twice = 1;
|
||||
if (slot < 0 && g_released_ids[i] == 0) slot = i;
|
||||
}
|
||||
if (twice) droiddeck_log("buffer", "DOUBLE release id %u (line %d): released again without an attach", id, line);
|
||||
else if (slot >= 0) g_released_ids[slot] = id;
|
||||
if (g_buf_trace_left > 0) { g_buf_trace_left--; droiddeck_log("buffer", "release id %u (line %d)", id, line); }
|
||||
}
|
||||
|
||||
#define send_buffer_release(b) send_buffer_release_at((b), __LINE__)
|
||||
static void send_buffer_release_at(struct wl_resource *buffer, int line) {
|
||||
if (!buffer_release_blocked(buffer)) { buf_trace_release(buffer, line); wl_buffer_send_release(buffer); }
|
||||
}
|
||||
|
||||
static void pending_release_free(struct pending_release *pr) {
|
||||
@@ -1147,6 +1178,7 @@ static void surface_commit(struct wl_client *c, struct wl_resource *r) {
|
||||
/* Role-less surface: never drawn, but its buffer is kept for a set_cursor to come. */
|
||||
if (buffer) surface_hold_idle(s, buffer);
|
||||
} else if (db) {
|
||||
buf_trace_attach(buffer);
|
||||
take_dmabuf(s, db, buffer);
|
||||
} else if (shm) {
|
||||
drop_dmabuf(s, 1);
|
||||
|
||||
@@ -688,6 +688,8 @@ class SessionService : Service() {
|
||||
// CEF's accelerated shared-texture output showed stale, half-written tiles on RADV
|
||||
// (Xclipse), as #570 found on PowerVR: web compositing in software, GPU raster kept.
|
||||
guest.add("BL_STEAM_SOFT_COMPOSITING=1")
|
||||
// droiddeck-game-env leaves vkd3d-proton to report the driver's own caps on this path.
|
||||
guest.add("BL_OPEN_DRIVER=1")
|
||||
Log.i(TAG, "steam: software web compositing for the open driver pair (GPU raster kept)")
|
||||
LinuxRuntime.gpuStandIn(this)?.takeIf { it == LinuxRuntime.MALI_DEVICE }?.let { guest.add("BL_DRM_STANDIN=$it") }
|
||||
}
|
||||
|
||||
@@ -178,6 +178,15 @@ def apply_config(env, config, app_id, fixes=None):
|
||||
if dxvk:
|
||||
own = result.get("DXVK_CONFIG", "").strip().rstrip(";").strip()
|
||||
result["DXVK_CONFIG"] = own + "; " + dxvk if own else dxvk
|
||||
# An open driver pair (PanVK, RADV) on a GPU that is not an Adreno: vkd3d-proton reports the
|
||||
# driver's own feature level and shader model. The app-wide 12_2 / 6_9 over-promised what PanVK
|
||||
# has, and an Unreal DX12 game took paths that crashed. A game's own setting still wins.
|
||||
if env.get("BL_OPEN_DRIVER") == "1":
|
||||
game = config.get("games", {}).get(app_id, {}) or {}
|
||||
for name in ("VKD3D_FEATURE_LEVEL", "VKD3D_SHADER_MODEL"):
|
||||
if name not in game and name in result:
|
||||
result.pop(name)
|
||||
result["DROIDDECK_VKD3D_CAPS"] = "driver"
|
||||
return result
|
||||
|
||||
|
||||
@@ -379,7 +388,6 @@ def game_logs(command, env, app_id, now=None):
|
||||
"VKD3D_DEBUG": env.get("VKD3D_DEBUG", "warn"),
|
||||
"VKD3D_SHADER_DEBUG": env.get("VKD3D_SHADER_DEBUG", "none"),
|
||||
"MESA_LOG_FILE": str(folder / "mesa.log"),
|
||||
"MESA_DEBUG": env.get("MESA_DEBUG", "silent"),
|
||||
"PANVK_DEBUG": env.get("PANVK_DEBUG", "startup"),
|
||||
})
|
||||
try:
|
||||
@@ -389,7 +397,7 @@ def game_logs(command, env, app_id, now=None):
|
||||
"proton: %s" % command[0],
|
||||
"started: %s" % time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(now)),
|
||||
] + ["%s=%s" % (key, env[key]) for key in sorted(env)
|
||||
if key.startswith(("VK_", "BL_VK", "BL_DRM", "MESA_", "PANVK", "DXVK_", "VKD3D", "ZINK", "TU_"))]) + "\n")
|
||||
if key.startswith(("VK_", "BL_VK", "BL_DRM", "BL_OPEN", "MESA_", "PANVK", "DXVK_", "VKD3D", "ZINK", "TU_", "DROIDDECK_VKD3D"))]) + "\n")
|
||||
except OSError:
|
||||
pass
|
||||
# Whether the game's sound reaches PulseAudio: the streams 20 s and 60 s in, without waiting.
|
||||
|
||||
@@ -393,6 +393,20 @@ class GameEnvironmentTest(unittest.TestCase):
|
||||
named = game_logs(command, on, None, now=0)
|
||||
self.assertTrue(Path(named["PROTON_LOG_DIR"]).name.endswith("-Hades"))
|
||||
|
||||
def test_open_driver_pairs_report_the_drivers_own_vkd3d_caps(self):
|
||||
apply = MODULE["apply_config"]
|
||||
config = {"version": 1, "shared": {"VKD3D_FEATURE_LEVEL": "12_2", "VKD3D_SHADER_MODEL": "6_9"},
|
||||
"games": {"42": {"VKD3D_SHADER_MODEL": "6_6"}}}
|
||||
adreno = apply({}, config, "1")
|
||||
self.assertEqual(adreno["VKD3D_FEATURE_LEVEL"], "12_2")
|
||||
pair = apply({"BL_OPEN_DRIVER": "1"}, config, "1")
|
||||
self.assertNotIn("VKD3D_FEATURE_LEVEL", pair)
|
||||
self.assertNotIn("VKD3D_SHADER_MODEL", pair)
|
||||
self.assertEqual(pair["DROIDDECK_VKD3D_CAPS"], "driver")
|
||||
own = apply({"BL_OPEN_DRIVER": "1"}, config, "42")
|
||||
self.assertEqual(own["VKD3D_SHADER_MODEL"], "6_6")
|
||||
self.assertNotIn("VKD3D_FEATURE_LEVEL", own)
|
||||
|
||||
def test_game_ids_and_probes(self):
|
||||
for prefix in ("", "/compatdata/0", "/compatdata/0-123", "/compatdata/nope", "/compatdata/4294967296"):
|
||||
self.assertIsNone(MODULE["game_id"]({"STEAM_COMPAT_DATA_PATH": prefix}))
|
||||
|
||||
@@ -73,7 +73,10 @@ int __android_log_print(int, const char *, const char *, ...);
|
||||
''')
|
||||
(tmp / 'wayland-server.h').write_text('#pragma once\nstruct wl_display; struct wl_resource; struct wl_client;\n')
|
||||
compositor = (SOURCE.parent / 'compositor.c').read_text()
|
||||
callers = '\n'.join(function(compositor, n) for n in ('buffer_release_blocked', 'send_buffer_release', 'take_shm', 'take_pixel'))
|
||||
# send_buffer_release is a macro over send_buffer_release_at (with buffer tracing).
|
||||
callers = ('static void buf_trace_release(struct wl_resource *b, int line) { (void)b; (void)line; }\n'
|
||||
+ '#define send_buffer_release(b) send_buffer_release_at((b), __LINE__)\n'
|
||||
+ '\n'.join(function(compositor, n) for n in ('buffer_release_blocked', 'send_buffer_release_at', 'take_shm', 'take_pixel')))
|
||||
harness = (Path(__file__).with_name('vk_terminal_callers_test.c')).read_text()
|
||||
probe = tmp / 'probe.c'
|
||||
probe.write_text(harness.replace('/* COMPOSITOR_CALLERS */', callers))
|
||||
|
||||
Reference in new issue
Block a user