Skip to content

MaliBridge v0.5

Choose a tag to compare

@ASEbrahim ASEbrahim released this 19 Oct 01:16
· 27 commits to main since this release

MaliBridge v0.5

Re-signed on Oct 19, 2026 with MaliBridge's own key, so only official MaliBridge builds can update it. The code is unchanged. If you installed v0.5 before Oct 19, uninstall it first (Android won't update across different signatures). This removes the Steam login and installed games. Newer: v0.5.1.

Test APK: DroidDeck-MaliBridge-v0.5-test.apk is DroidDeck with MaliBridge built in. Install it on a Mali device, turn on the Mali bridge in Settings and start a Steam session; see INSTALL.md.

Highlights

On a Galaxy Tab S10+ (Mali-G720) or Galaxy Tab S11 Ultra (Mali-G925), v0.5 works well: of the 36 games we've tested on these two tablets, 26 run well, most at or near their frame cap, through Steam with the tablets' own GPU drivers.

Game Mali-G925 (Tab S11 Ultra) Mali-G720 (Tab S10+)
Half-Life 2 Excellent, ~94 fps Excellent, ~74 fps
Hollow Knight: Silksong Excellent, 72-96 fps Excellent, 62-66 fps
Risk of Rain Returns Excellent, 59-60 fps Excellent, 59-60 fps, boss fight included
Stardew Valley Excellent, 57-62 fps Excellent, 60 fps (cap)
Dark Souls Remastered Very playable, 54-60 fps (cap 60) not tested yet
Garry's Mod Excellent, 82-104 fps not tested yet
GRIS Excellent, ~119 fps not tested yet
Ace Attorney Trilogy Excellent, ~118 fps not tested yet
Stray not rated yet, ~58 fps on the title screen Barely runs, 17 fps
Subnautica Very playable, 28-40 in play Playable, 20-24 in play (Detail High)

Ratings, worst to best: barely runs, kinda playable, playable, very playable, excellent. The full list of 36 is in the README. On other Mali GPUs this is still a test: results depend on the GPU and its driver. The start-up checks and safe mode (below) exist so that a new device starts with the safest settings. Logs from other devices are very welcome (INSTALL.md has the steps).

What's new

This release is mostly about knowing what a device can do before a game finds out. The server now checks the driver at start, applies fixes for known Mali driver bugs, and starts in a new safe mode by default. Tested on two tablets (Galaxy Tab S10+ with a Mali-G720, Galaxy Tab S11 Ultra with a Mali-G925), plus reports from players.

Safe mode, on by default

  • Safe mode (the default): wherever the bridge has not confirmed that this GPU and driver handle something correctly, it keeps its workaround. Performance mode (Settings, "Safe mode: off") uses the driver's own paths where the start-up checks passed, waits 20 s instead of 10 s before stepping in on a slow shader compile, and uses cached readback for the frame copy.
  • We recommend starting in safe mode, and trying performance mode once a game works.
  • On our two tablets the difference is small. Median fps, one run per game and mode:
Game (scene) G720 safe G720 performance G925 safe G925 performance
Half-Life 2 (train ride) 74.1 75.9 93.7 93.7
Subnautica (menu) 62.0 62.3 81.3 81.5
Stray (title) 17.1 15.8 58.4 58.0
Stardew Valley (title, 60 cap) 60.0 60.0 60.0 60.0
Risk of Rain 2 (title) 35.6 35.8 56.8 no clean run
Skyrim SE (main menu, 60 cap) 60.7 60.7 not tested not tested

Safe mode matters most on GPUs we have not tested.

  • The switch applies from the next session. VKBRIDGE_MODE=safe|performance sets it outside DroidDeck.

New games and device results

  • Stray runs on the Mali-G925. The G925's compiler never finishes Unreal Engine 4's colour-grading shader. The compile watchdog from v0.4 is now confirmed on the device: the first launch waits 10 s once, then uses a neutral colour grade in its place, and later launches use it at once. The title screen runs at about 58 fps. The colours are plain rather than the game's own grading until the shader rewrite is done.
  • Dark Souls Remastered on the Mali-G925 (owner-played, 10 minutes, safe mode): median 53.7 fps, lowest 43.9, never below 40, and 60 fps (its cap) while the tablet is cool. Cutscenes render correctly, no crash.
  • Garry's Mod on the Mali-G925 (owner-played): median 104 fps on a plain map; median 82 fps on the Golden City Sandbox map, lowest 34.
  • The Witcher 3 (DX12) on the Mali-G925: the intro plays at 60 fps (see known issues for what happens after loading a save).
  • Community games on the Mali-G925. We picked 13 owned games that players often try on Mali (from GameNative's public crowd reports) and played them with v0.5 test builds, some ourselves and some by the owner. Median or typical fps in play:
Game G925 Note
Phoenix Wright: Ace Attorney Trilogy ~118 the 120 Hz display rate
GRIS ~119
A Dance of Fire and Ice 106-113 no input delay noticed with a Bluetooth PS5 controller
Risk of Rain Returns 59-60 needs the video texture fix below; also 59-60 on the Mali-G720, boss fight included
Stick Fight: The Game 59-60 its cap
Helltaker ~59
Don't Starve Together 60 only with PROTON_USE_WINED3D=1 (known issues)
Muck 45-48
R.E.P.O. ~40
Poppy Playtime (Ch. 1) 28-32 neutral colour grade, as Stray
The Forest 30-45 CPU-bound, the same at any resolution
Outer Wilds 17-80 ~75-80 in space, 35-45 on the starting planet, ~17 at the black hole
ASTRONEER 17-20 renders correctly; CPU-bound

For context only: GameNative's crowd reports (another app, many Mali devices) rate Outer Wilds, The Forest and ASTRONEER low on Mali. That is not a like-for-like comparison.

  • These games, plus Dark Souls Remastered and Garry's Mod, were tested on the Mali-G925. On the Mali-G720 only Risk of Rain Returns has been tested so far (59-60 fps).

New device support and fixes

  • Driver bug fixes. A layer just above the driver fixes ten known Mali driver bugs, each decided per device from the driver version, the bug's known range, a start-up check where there is one, and the mode. The log says why each one is on or off. VKBRIDGE_ERRATA=+name,-name forces one.
    • wait_retry: waits that fail with VK_ERROR_INITIALIZATION_FAILED after a signal are retried for the app's whole timeout. v0.4 covered semaphore and fence waits; now idle waits, query waits and fence status too.
    • viewport_flip: for drivers that ignore a negative viewport height (reported on a Mali-G715 r54p2). Checked at start. Untested on an affected driver: we have none; on our tablets it was verified forced on.
    • bitwise_scalar: integer vector bitwise ops on a swizzle are miscompiled on r18p0-r53p0. Both tablets fail this check.
    • dyn_reemit: dynamic state lost or mis-applied across pipeline binds.
    • vb_split: vkCmdBindVertexBuffers2 strides applied by array index.
    • view_quarantine: stale state for a recycled image view handle in vkCmdBeginRendering (r49p1-r49p2, r50p0-r51p0; on for the G925).
    • view_counts: a 2D-array view of a 3D image with VK_REMAINING_ARRAY_LAYERS. Without the fix the G720 driver crashed the server.
    • cull_nontri: dynamic cull mode culling points and lines below r52.
    • clamp_zero: a clamp with a zero limit miscompiled into a min or max (Godot's fullscreen triangle).
    • dedicated_import: imports carrying a dedicated-allocation struct for a resource not made for that handle type (older drivers).
  • Video textures on the Mali-G925: games that decode intro videos through Media Foundation froze, because the driver refuses multi-planar (NV12) images created with MUTABLE_FORMAT | EXTENDED_USAGE, which DXVK uses for them. Where the format already covers the usage, the client now leaves out the extended usage flag. Risk of Rain Returns now runs at 59-60 fps on both tablets. VKBRIDGE_PLANAR_EXT_FIX=0 turns it off.
  • Xiaomi XRing O3 (Mali-G2-Ultra): every image failed there (self-test 9 of 13, "no memory type for the image") because the driver does not list its first device-local type for images. The client now backs its device-local type with one that images allow. The host suite imitates that driver and passes, but the fix is not yet tested on the device.
  • Fixes from The412Banner's testing of an early copy of the bridge on Mali-G615 and Mali-G925 phones: a crash in vkBeginCommandBuffer from a malformed begin info (the decoders now refuse a single-element pointer without the count 1), and the self-test now says when no memory type is host-visible. Crash lines now name the faulting library and offset, and inside a replayed command buffer its last commands.
  • Polygon mode LINE and POINT (wireframe, fillModeNonSolid; DXVK 3 will not start without it) are now drawn as lines and points instead of solid. This covers indexed draws (edges written by a compute shader), strips, fans, restarts, dynamic topology (vkd3d-proton) and secondary command buffers (DXVK 3 records render passes into them on Mali). The G925 driver lacks fillModeNonSolid too, so it uses this as well. The device test passes 21 of 21 on both tablets. In game, Half-Life 2's wireframe (mat_wireframe 1) now draws as lines on the Mali-G720, where v0.4 drew it solid; it has not been checked in a game on the G925.
  • Shift barriers: a no-op after each left shift by a constant, so Mali's compiler cannot fold the shift into speculative memory accesses that fault the GPU (Lee Gao's MaliOptimizationBarrierPass, ported to C). On for every Arm GPU; VKBRIDGE_SHL_BARRIER=0 turns it off.
  • Pixel 9 (Mali-G715): the memory-sharing log now says why each strategy failed, and dma-buf is skipped where the driver exports nothing. Not retested on the device with v0.5.
  • The server logs which *_SCALED vertex formats the GPU fetches (all 12 on both tablets).

Performance

  • Dedicated allocations: where a driver prefers a dedicated allocation for an ordinary resource, the client now clears that preference so DXVK sub-allocates instead of making one allocation per texture (kept where the driver requires it, for external memory and for resources of 32 MiB or more). On the Mali-G925 it changes nothing measurable, because DXVK already sub-allocates almost every image there; it is a safeguard for drivers that do ask. VKBRIDGE_DEDICATED_HINT=0 turns it off.
  • BC transcoders go through the pipeline cache, and are built ahead on two threads from a device's first BC image, so a large texture no longer waits for a compile. The start-up check's transcoders have a cache of their own.
  • Cached readback (performance mode): the frame readback on the copy present path reads from CPU-cached pages, with cache maintenance at each flush and invalidate, where the start-up self-test passes it. The default present path on our tablets does not use it.
  • Pipeline caches are limited to 512 MB in all (VKBRIDGE_PCACHE_TOTAL_MB); the ones used longest ago go first.
  • Against v0.4 on the Mali-G925, Half-Life 2's train ride measured 93.7 fps in both modes, where v0.4 measured 95-103 (about 5% lower than v0.4's middle value). Other games were within noise.

Reliability

  • Start-up checks. At its first start on a GPU, driver and bridge build, the server runs small workloads on the driver for features that have failed before (memory sharing, dma-buf export, push descriptors, the divisor, depth clip, clip distance, null descriptors, the driver bugs above, the UE4 colour-grading compile, the BC transcoders). A check that fails, crashes or hangs turns on its workaround. The part before the server listens took 88-130 ms on our tablets; the rest runs in the background (about 1.3-1.5 s, up to 4 s the first time). Cached results take under 2 ms. A session stopped during a check runs it again next time instead of counting it as a crash.
  • Session report. malibridge-report.md and .json sit beside the server log, so Share logs includes them. Line 1 states the mode; then a summary of issues, the device, the check results, and per game its frame times, compile times and missing features. Test switches left on (<cache dir>/env overrides, a leftover SPIR-V dump folder) are flagged.
  • Per-game presets: <cache dir>/presets/<appid>.env holds one game's settings. Built-in presets apply only on GPUs they were tested on. The four built-in entries in this release (Garry's Mod, Dark Souls Remastered, Poppy Playtime, The Forest) come from GameNative's public Mali configs and are untested here, so they are not applied; the server logs the lines to copy if you want to try them.
  • New opt-in switches, off by default and usable per game:
    • VKBRIDGE_HEAP_MAX_MB: shows the game a smaller device-local heap, since on Mali the one heap is about all of RAM.
    • VKBRIDGE_SPOOF_GPU=nvidia|amd: shows the game a desktop GPU identity. Not a speed-up, and not for D3D12 games; the README lists the risks.
    • VKBRIDGE_HIDE_CALIBRATED_TS: hides the calibrated timestamps extensions. No game is known to need it yet.
  • Cache directory: Android can empty the app's cache directory when storage runs low. The server now makes it again and says so once, and says once when storage is full.

Testing tools

  • tools/malibridge_report_diff.py compares two session reports. With --regressions it gives a pass/fail answer, and it warns first when the two used different modes.
  • A host test for every driver bug fix: each one puts the bug beneath the fix on a desktop driver and checks that the fix hides it. Device versions of the same checks (dynstate_check, bitwise_check, viewport_check, polygon_check and others) were run on both tablets.
  • host/run_tests.sh runs from different checkouts can go side by side. The host suite passes 82 of 82.
  • tests/mali_xproc_probe: a device tool that checks whether a second process can map the Mali driver's mapping (on the G720: no, the kernel driver refuses it).
  • The protocol hash is unchanged (4a9da939fdf65896).

Known issues

  • The Witcher 3 (DX12) on the Mali-G925 plays its intro, but after loading a save it drops below 1 fps. The GPU stays about 98% busy, so this looks like GPU work that does not finish rather than a shader compile. Being investigated. The current Steam version is DX12-only, so DX11 has not been tried.
  • Stray on the Mali-G925 uses a neutral colour-grading stand-in (see above) until the shader rewrite is done.
  • Stray with -dx12 closes about 60 s after starting on the G925 (an access violation inside the game, no bridge errors). The default DX11 path is not affected.
  • Risk of Rain 2: one performance-mode launch on the G925 showed no frames for about 2 minutes on its title load. Not reproduced in a rerun; still unexplained.
  • Steam's window on the Mali-G925 can be slow: its web view crashes and falls back to drawing on the CPU. Drawing it through ANGLE on Vulkan (BL_VKBRIDGE_CEF_ANGLE=vulkan) stops the crashes, but compositing is still done on the CPU. A full fix is pending; it is not on by default, and it should not be turned on for the Mali-G720, where the default window is smooth and this setting makes it slow.
  • Don't Starve Together needs PROTON_USE_WINED3D=1 %command% as its launch option. With the default DXVK it closes at start (an assert in DXVK's shader model 3 translator). This is a DXVK bug, not a bridge one.
  • Outer Wilds, ASTRONEER and The Forest are limited by the CPU on the G925, so lower settings help little.
  • Just Cause 2 does not start: Steam's copy protection (CEG) runs a helper that fingerprints the Windows folders, and inside DroidDeck's sandbox it takes about 5 minutes, while Steam gives up after about 100 s. The game never reaches the GPU, so this is not a bridge issue. The fix belongs in DroidDeck's sandbox (faster file lookups) and is planned after this release.
  • viewport_flip has not been tested on a driver that has the bug.
  • The XRing O3 fix is untested on that device, and the Pixel 9 has not been retested with v0.5.

Thanks

  • The412Banner for testing an early copy of the bridge on Mali-G615 and Mali-G925 phones. The crash logs led to the begin info fix above, and the crash detail and the self-test's memory message follow that work.
  • Lee Gao (leegao) for the MaliOptimizationBarrierPass that the shift barriers port, the "WSI woes on Mali" write-up behind dedicated_import, and compat_layer.
  • Julius Pinsker for bionic-vulkan-wrapper PR #228 and its GTA V allocation counts, which the dedicated-allocation change follows.
  • David Cimo for the Venus notes on the Mali-G715 that cached readback follows.
  • taowen for the libhybris compatibility layer, whose approach the polygon mode emulation follows.
  • wallentx for the placed-memory layer that mali_xproc_probe's mapping lookup follows.
  • GameNative, for ideas only: the heap cap, the GPU identity spoof, the calibrated timestamps switch, and the values in the untested built-in presets. No code is copied.
  • Players who sent logs from their devices.

Attached files

  • DroidDeck-MaliBridge-v0.5-test.apk: test build of DroidDeck with MaliBridge (Android arm64). Signed with a test key: uninstall the official DroidDeck first. Source: branch mali-test-build of ASEbrahim/DroidDeck (GPL-3.0).
  • libvkbridge_server.so, libvkbridge_jni.so: server (Android arm64-v8a, API 26+)
  • libvulkan_droidbridge.so, droidbridge_icd.json: client ICD (Linux glibc, aarch64)