Enable B8G8R8A8 frame buffer emulation in the wrapper WSI for 32-bit games on Mali - #6
Merged
Merged
Conversation
leegao
marked this pull request as ready for review
July 21, 2026 17:55
leegao
force-pushed
the
rgba8-mali
branch
2 times, most recently
from
July 22, 2026 10:52
c3f282f to
16f143e
Compare
1. X11 requires framebuffers in bgra8 format. 2. Mali can only support direct-rendering on rgba8 format (unlike Qcom) 3. Blitting is also broken when opaque-fd is not available on pre-5.10 GKI kernels All of these can be solved by enabling DRI (AHB framebuffers) on Mali, via emulating bgra8 Design sketch: allocate back buffer images backed physically by rgba8 device memory, but allow WSI to read this back as bgra8 (during vkCreateImageView - by creating the backing images with VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) TODO: certain flows (direct memory writes) are still broken, and this is still a bit brittle.
the primary frame buffer in the AHB flow
Design: check WINEPRELOADRESERVE to see if the base address is < 0xFFFFFFFF
In particular, if EXT_map_memory_placed emulation fails for memory backing a swapchain image, then we'll just skip it and fallback instead of erroring.
This was referenced Jul 23, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Investigation: leegao/bionic-vulkan-wrapper#157
Problems:
This PR specifically tackles the 32-bit black screen/crash, but the design here should also enable the Direct Rendering (blit-less) path for all Mali devices as well, speeding up the rendering by eliminating one framebuffer copy per frame.
Additionally, we also allow blitting to work on win32 games for affected device by allowing VK_EXT_map_memory_placed emulation failures to be bypassed (meaning these swapchain images cannot be host-mapped anymore by the game)
See also:
Design:
Mali's implementation of AHB supports both R8G8B8A8 and B8G8R8A8 formats when you gralloc for system memory, but its blob Vulkan driver does not support importing B8G8R8A8 buffers into Vulkan, as can be seen by calling
vkGetAndroidHardwareBufferPropertiesANDROIDObserve that there's a valid external format (47), but no vulkan importable format (0).
Instead, on these devices, only R8G8B8A8 ahb buffers are importable into Vulkan.
The TL;DR for this PR is to allocate AND present the frame buffer image in [R, G, B, A] format, but internally store color data in the swizzled [B, G, R, A] mode using
VK_IMAGE_CREATE_MUTABLE_FORMAT_BITto trick the game/engine to still write the swizzled [B, G, R, A] data into this physically [R, G, B, A] formatted memory.This PR specifically emulates a B8G8R8A8 frame buffer over a physical R8G8B8A8 buffer. This allows the buffer to be imported as an AHB resource into Vulkan, this enabling the fast direct rendering path.
In particular, we create the backing image as R8G8B8A8, and then rely on the WSI engine to create compatible (via the addition of the MUTABLE_FORMATS flag) B8G8R8A8 image views as the render target.
New flags:
WRAPPER_EMULATE_BGRA8is introduced that explicitly enables this behavior.WRAPPER_DONT_EMULATE_BGRA8is a generic killswitch for thisIn addition, 32bit games running on Mali will also enable this emulation paths automatically, so that by default, only 32bit games running on Mali are affected by this change.
Rendering Scenarios:
X11 expects the AHB memory to be in BGRA byte order (and will import it as a BGRA8 ahb)
VkImageView: OKAY
When DXVK creates a VkImageView with format VK_FORMAT_B8G8R8A8_UNORM (backing image is actually in [B, G, R, A] byte order):
vkCmdCopyImage(BGRA -> RGBA (emulated BGRA)): OKAY
When DXVK calls an explicit vkCmdCopyImage on a backing destination image in R8G8B8A8_UNORM (but with memory containing B, G, R, A ordered data), it just performs raw byte-for-byte copying:
note however that if the engine for some reason decides to render to a temporary frame buffer in RGBA mode, then copy it to what it would've originally have thought was a BGRA backend buffer, then we'll also get the wrong colors, but I can't see a single reason to do this.
vkCmdBlitImage(BGRA -> RGBA (emulated BGRA)): NEEDS SWIZZLE
When DXVK calls an explicit vkCmdBlitImage on a backing destination image in R8G8B8A8_UNORM (but with memory containing B, G, R, A ordered data), it actually swizzles B->R and R->B during the copy:
As a result, the
vkCmdBlitImagecase will actually require an additional swizzle (or just be translated tp avkCmdCopyImage), as it will otherwise over-correct and switch the blue/red channels.This is currently implemented as an error log.
Only tested on a G615, but I don't have a GKI <5.10 device)
TODO(P1): we should still add an explicit kill switch to disable this feature.TODO(P1): implement blit-mode fixes for win32 games on <5.10 devices