v0.1.0 47aaa0f

0003-vulkan-dmabuf-presentation.md RawHistoryFolder

ADR 0003 — Vulkan presentation through DMA-BUF

Status: accepted

Decision

NeferGUI renders with Vulkan into exportable images and presents them as zwp_linux_dmabuf_v1 buffers. It does not use VK_KHR_swapchain.

  • Synchronization uses wp_linux_drm_syncobj_v1 with Vulkan timeline semaphores. There is no CPU-fence fallback.
  • The Vulkan physical device must match the main_device of linux-dmabuf feedback. There is no cross-GPU fallback.
  • Formats: one-plane XRGB8888 for opaque windows (default) and ARGB8888 for transparent windows, both mapped to VK_FORMAT_B8G8R8A8_UNORM, with a modifier supported by both the compositor and the GPU.
  • Three exportable images per window.
  • Shaders are GLSL compiled by glslc through go generate. SPIR-V is committed and embedded; consumers do not need glslc.

Buffer lifecycle

Available → Rendering → acquire point exported → committed with acquire/release points
→ compositor reads → release point of its latest commit reached → Available

While a wp_linux_drm_syncobj_surface_v1 exists, wl_buffer.release delivery is undefined (linux-drm-syncobj-v1). A buffer is reused only after the release point set for its most recent commit is signaled; each buffer has its own release timeline because points may signal out of order. wl_buffer.release is traced when it arrives but never gates reuse. Frame callbacks schedule drawing; they never authorize reuse.

The UI loop never blocks in Wayland dispatch while GPU or compositor completion is pending. Blocking sources (Wayland socket, release timeline waits) run on their own goroutines and only post events to the loop, which owns all presentation state. Resize creates a new generation; old images are retired after their latest release point signals.

At shutdown, release points protect reuse of contents, not the lifetime of exported DMA-BUF memory: kernel FD references and compositor imports are independent of the client's Vulkan allocation. Detach and commit null, destroy the syncobj surface, wait at most 200 ms for outstanding release points for tracing, wait for client GPU completion, destroy wl_buffers and all client images/memory/semaphores/syncobj handles, then destroy the device. Never abandon Vulkan allocations solely because a compositor release point has not arrived.

Opaque() sets a full-surface opaque region. Transparent() uses premultiplied alpha and no opaque region. Background blur is a compositor setting, not a NeferGUI feature.

source
1# ADR 0003 — Vulkan presentation through DMA-BUF
2
3Status: accepted
4
5## Decision
6
7NeferGUI renders with Vulkan into exportable images and presents them as `zwp_linux_dmabuf_v1` buffers. It does not use `VK_KHR_swapchain`.
8
9- Synchronization uses `wp_linux_drm_syncobj_v1` with Vulkan timeline semaphores. There is no CPU-fence fallback.
10- The Vulkan physical device must match the `main_device` of linux-dmabuf feedback. There is no cross-GPU fallback.
11- Formats: one-plane `XRGB8888` for opaque windows (default) and `ARGB8888` for transparent windows, both mapped to `VK_FORMAT_B8G8R8A8_UNORM`, with a modifier supported by both the compositor and the GPU.
12- Three exportable images per window.
13- Shaders are GLSL compiled by `glslc` through `go generate`. SPIR-V is committed and embedded; consumers do not need `glslc`.
14
15## Buffer lifecycle
16
17```text
18Available → Rendering → acquire point exported → committed with acquire/release points
19→ compositor reads → release point of its latest commit reached → Available
20```
21
22While a `wp_linux_drm_syncobj_surface_v1` exists, `wl_buffer.release` delivery is undefined (linux-drm-syncobj-v1). A buffer is reused only after the release point set for its most recent commit is signaled; each buffer has its own release timeline because points may signal out of order. `wl_buffer.release` is traced when it arrives but never gates reuse. Frame callbacks schedule drawing; they never authorize reuse.
23
24The UI loop never blocks in Wayland dispatch while GPU or compositor completion is pending. Blocking sources (Wayland socket, release timeline waits) run on their own goroutines and only post events to the loop, which owns all presentation state. Resize creates a new generation; old images are retired after their latest release point signals.
25
26At shutdown, release points protect reuse of contents, **not** the lifetime of exported DMA-BUF memory: kernel FD references and compositor imports are independent of the client's Vulkan allocation. Detach and commit null, destroy the syncobj surface, wait at most 200 ms for outstanding release points for tracing, wait for client GPU completion, destroy `wl_buffer`s and **all** client images/memory/semaphores/syncobj handles, then destroy the device. Never abandon Vulkan allocations solely because a compositor release point has not arrived.
27
28`Opaque()` sets a full-surface opaque region. `Transparent()` uses premultiplied alpha and no opaque region. Background blur is a compositor setting, not a NeferGUI feature.

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 1

Tags 12

↑↓ moveenter openesc close