1. The fullscreen photo that froze a laptop

I opened a photo from Telegram Web in Brave and switched it to fullscreen. The display froze. After failed attempts to recover it, I forced the Framework Laptop to restart.

A TTY later showed Vulkan selecting my AMD Radeon 780M. Two warnings about dynamic-buffer limits followed. They looked relevant, but appeared more than ten minutes after the next boot began.

The previous boot told a different story. Its kernel journal pointed at AMD’s display path: Display Core, DCN, DMCUB, MPCC and CRTC operations. That fault led to a larger question: how does a Linux application get pixels from its own code to a laptop panel?

flowchart LR T1["11:15:04
Mutter stacking assertion"] --> T2["11:15:08
first DMCUB errors"] T2 --> T3["11:15:09
MPCC idle timeout"] T3 --> T4["11:15:33
DMUB command queue errors"]

The short answer is that the display stack wedged in AMD’s DCN and DMCUB path. The logs do not prove whether kernel code, firmware, hardware or their interaction created the first bad state. To understand why that wording matters, we need to build the stack one layer at a time.

New to Linux graphics? Read sections 3 to 13 in order. Investigating a freeze? Start at sections 14 to 16. Returning for a definition? Jump to the type glossary.

2. Read logs as a timeline, not a bag of errors

I reduced the failed boot to five decisive lines:

11:15:04  Mutter stacking assertion
11:15:08  DMCUB error
11:15:09  MPCC idle timeout
11:15:33  Error queueing DMUB command
11:18:17  failed to blank CRTC

The first line came from Mutter, GNOME’s compositor and window manager. The remaining lines came from amdgpu, the Linux kernel driver for the Radeon GPU. DMCUB, MPCC and CRTC all belong to the display side of the stack.

Order matters. The first DMCUB failure appeared at 11:15:08. I pressed the power key at 11:16:18. A kernel trace in the PSR path appeared four seconds after that press, during the suspend attempt. The suspend and PSR failures therefore show what an already broken display path could no longer do. They do not show what broke it first.

I use three labels for the rest of this account:

  • Fact: a log or primary source states it directly.
  • Inference: an explanation connects several facts, but the logs do not state it.
  • Unknown: a reproduction, trace, code fix or bisect is still needed.

3. The smallest useful model

Before naming every library and kernel object, I use three stages:

flowchart LR A["1. App rendering
(stage)"] --> W["Wayland commit
(protocol exchange)"] W --> C["2. Compositor composition
(optional stage)"] C --> P["3. KMS presentation
(stage through kernel ABI)"] P --> D["Display scanout
(hardware operation)"]

These boxes describe dependencies for one buffer. They are not three processes, nor a strict schedule for the whole machine.

  1. Rendering produces pixels for an application’s window.
  2. Composition may combine several application buffers into an output buffer.
  3. Presentation selects a buffer for display through Kernel Mode Setting (KMS).

The display engine then scans out that buffer. It reads pixels at the required pace and sends them towards the panel.

Composition is optional. A suitable fullscreen buffer may go to presentation through direct scanout. Across several frames, the stages overlap: an application can render a new buffer while the panel displays an older one.

4. A legend for components and rules

Linux graphics discussions often put a process, a protocol and a kernel interface in the same sentence. I clarify the stack by labelling what each name is.

GroupExamplesWhat the group means
User-space componentsBrave, Mutter, SwayRunning programs that perform work.
Frameworks and librariesGTK, Qt, SDL, GLFW, wlroots, libwayland-client, libdrmReusable code used by applications or compositors.
Graphics project and runtime componentsMesa, RadeonSI, RADVUser-space implementations of graphics APIs and GPU support.
API specificationsOpenGL, VulkanRules for asking a graphics implementation to render or compute.
Protocol specificationsWayland, eDPRules for communication between parties.
Kernel framework and ABIDRM and KMSKernel interfaces for graphics devices, buffers, command submission and displays.
Kernel driver componentamdgpuAMD-specific code that implements DRM and KMS operations.
Protocol objectswl_surface, wl_bufferNamed objects defined by Wayland.
Kernel objectsDRM framebuffer, plane, CRTCNamed objects exposed through the DRM/KMS ABI.
Sharing and sync objectsDMA-BUF file descriptor, fence, sync objectHandles to storage or completion state.
FirmwareDMCUB or DMUB firmwareCode run by AMD’s display microcontroller.
HardwareDMCUB microcontroller, graphics engine, display engine, eDP link, panelPhysical blocks that control, render, fetch and show pixels.

Some names cover both a project and several runtime libraries. Mesa is one example. The useful question is not only, “Where is Mesa?” It is also, “Which Mesa component and which interface are we discussing?”

5. Stage one: how an application produces pixels

An application has several valid routes to a window buffer:

  • GTK or Qt can choose a GPU or CPU renderer for it.
  • A game can use SDL or GLFW, then call OpenGL or Vulkan.
  • An application can use Wayland and a graphics API directly.
  • A CPU renderer can write a shared-memory buffer and skip Mesa and the GPU graphics engine.

For GPU rendering on this Radeon 780M, the main route looks like this:

flowchart LR APP["Application
(component)"] --> TK["GTK, Qt, SDL or app renderer
(optional library, framework or code)"] TK --> API["OpenGL or Vulkan
(API)"] API --> MESA["Mesa plus RadeonSI or RADV
(components)"] MESA --> DRM["DRM render node
(device-file interface to kernel ABI)"] DRM --> AMD["amdgpu
(kernel component)"] AMD --> GPU["Graphics engine
(hardware)"] GPU --> BUF["Rendered pixel buffer
(data object)"]

OpenGL and Vulkan are specifications, not running programs. Mesa supplies their Linux implementations. For supported AMD GPUs, Mesa’s RadeonSI driver implements OpenGL through its Gallium stack, while RADV implements Vulkan.

Mesa translates API work into AMD-specific commands. It submits those commands through DRM’s rendering interface to amdgpu. The graphics engine executes them and writes pixels into buffer storage. A fence can signal when the asynchronous work has finished.

GTK and Qt are optional. They provide widgets, layout, input and window-system support, and they often choose a renderer. They are not required hops between an application and Mesa.

6. The Wayland conversation

Rendering and Wayland communication are two parallel interfaces used by the same application. Rendering makes pixels. Wayland lets the client describe a surface and offer its content to the compositor.

flowchart LR APP["Application
(component)"] TK["GTK, Qt, SDL or direct code
(optional library, framework or app code)"] API["OpenGL or Vulkan
(API)"] MESA["Mesa plus RadeonSI or RADV
(components)"] DRM["DRM render node
(device-file interface to kernel ABI)"] GPU["Graphics engine
(hardware)"] BUF["Rendered buffer
(data object)"] WLC["libwayland-client or generated bindings
(library or client code)"] WAY["Wayland
(protocol)"] COMP["Mutter or Sway
(component, Wayland server)"] APP --> TK TK --> API --> MESA --> DRM --> GPU --> BUF TK --> WLC --> WAY --> COMP BUF -->|"attached as wl_buffer"| WAY

The two routes meet at a reference to the buffer and its synchronisation state. OpenGL and Vulkan draw calls do not travel through Wayland.

A typical client update works like this:

  1. The client creates a wl_surface and gives it a desktop role through an extension such as xdg-shell.
  2. It renders content into storage.
  3. It exposes that content as a wl_buffer, often through Linux DMA-BUF or wl_shm.
  4. It attaches the buffer, marks damaged regions and commits the surface state.
  5. The compositor releases the buffer when it no longer needs it.

Wayland defines asynchronous requests from client to server and events in the other direction. Input, window configuration, frame callbacks and buffer release return as events. GTK and Qt normally hide much of this through their Wayland backends and libwayland-client.

Mutter, KWin and Sway implement the server side in the compositor. Wayland is not serverless. The compositor also acts as the display server.

7. Buffers are where the paths meet

We often say “the buffer” as if one object travels unchanged through every layer. In practice, each interface has its own view.

ViewTypeMeaning
Pixel storageData storageMemory that contains image data.
DMA-BUF FDKernel sharing handleA file descriptor that can export shared storage between processes or devices.
wl_bufferWayland protocol objectContent that a client can attach to a wl_surface.
DRM framebufferKMS kernel objectA description of storage that KMS can use for scanout.
Fence or sync objectSynchronisation objectCompletion or ownership state. It contains no pixels.

These views can refer to the same underlying storage without being the same object. A wl_buffer might come from DMA-BUF storage, but it might instead come from wl_shm. A compositor can import storage and create a DRM framebuffer view suitable for KMS.

Zero-copy is a goal, not a promise. Pixel format, layout modifier, colour conversion, scaling or device limits may force the compositor to copy or redraw content.

This distinction also matters for the integrated Radeon 780M. It shares system memory with the CPU rather than using separate dedicated VRAM. The stack still manages buffer objects and GPU addresses.

8. Stage two: how the compositor builds an output frame

Mutter acts as GNOME’s Wayland server, compositor and window manager. Sway performs the same broad roles and uses wlroots, a library that supplies reusable backends, renderers, allocators, buffer support and Wayland protocol support.

The compositor receives committed surfaces. Its scene graph tracks their position, visibility, clipping, scale, effects and stacking. For normal composition, its renderer samples the current usable client buffers and draws an output buffer.

committed client buffers
  -> compositor component and scene graph
  -> compositor renderer component
  -> OpenGL, OpenGL ES or Vulkan API plus Mesa, or a CPU renderer
  -> output buffer plus synchronisation state

A GPU compositor submits another render job. A software compositor can combine pixels on the CPU. Either route produces a buffer that can later be presented.

Wayland does not define this renderer. Nor does it require DRM/KMS. A compositor can run nested inside another Wayland compositor, inside an X11 window, without a physical display, or with software rendering. This is why “Wayland renders the desktop” is the wrong model. The compositor chooses how to render and where to present.

9. The shortcut: direct scanout and hardware planes

Composition may be unnecessary. The compositor can sometimes assign a client’s buffer directly to a display plane.

flowchart TB B["Client wl_buffer
(protocol object backed by storage)"] --> Q{"Compositor policy and
hardware checks"} Q -->|"compose"| R["Compositor renderer
(component)"] R --> O["Output buffer
(data object)"] O --> K["DRM/KMS atomic commit
(kernel ABI)"] Q -->|"direct scanout"| K K --> E["Display engine
(hardware)"]

Direct scanout skips the compositor’s render job. It does not skip the compositor or KMS. The compositor still receives the surface, checks policy and hardware limits, and chooses the KMS state.

A fullscreen window makes direct scanout possible, not certain. Effects, scaling, cursor state, colour transforms, pixel formats and layout modifiers can rule it out. Hardware overlay planes offer another option: KMS can place several buffers into the display pipeline without first flattening every pixel in a GPU render job.

Inference: the Telegram fullscreen action may have changed composition or plane state.

Unknown: the journal does not show whether Mutter selected direct scanout, an overlay plane or normal composition for that photo.

10. Stage three: KMS presents

DRM has two related branches. Mesa uses its rendering ABI. The compositor separately uses its KMS display ABI.

flowchart TB APP["Application or compositor renderer
(user-space component)"] M["Mesa AMD driver
(component)"] RN["renderD*
(device-file interface to DRM ABI)"] CO["Compositor
(component)"] LD["libdrm
(library)"] PN["cardN
(device-file interface to DRM/KMS ABI)"] AMD["amdgpu
(kernel driver)"] GFX["Graphics engine
(hardware)"] DISP["Display engine
(hardware)"] APP --> M --> RN --> AMD --> GFX CO --> LD --> PN --> AMD --> DISP

Mesa’s output can later be presented through KMS, but Mesa rendering calls do not pass through the KMS API. Mesa and KMS are not alternatives. They often serve the same visible frame at different stages.

A DRM render node such as /dev/dri/renderD128 allows unprivileged rendering without modesetting or DRM master. A primary node such as /dev/dri/card1 exposes KMS and other controlled operations. Those numeric suffixes are not stable, so general diagrams should use renderD* and cardN.

The compositor commonly uses libdrm to prepare DRM calls. libdrm is a user-space wrapper and helper library, not a driver. Direct ioctls are possible.

KMS expresses display state with a stable object model:

flowchart LR FB["DRM framebuffer
(kernel object)"] --> PL["Plane
(KMS object)"] PL --> CR["CRTC
(KMS object)"] CR --> EN["Encoder
(KMS object)"] EN --> CN["Connector eDP-1
(KMS object)"] CN --> PA["Laptop panel
(hardware)"]
  • A framebuffer describes pixel storage for scanout.
  • A plane supplies a pixel source, position and size.
  • A CRTC controls an output scan sequence and mode. Its name is historical; it is still the stable KMS abstraction.
  • An encoder represents conversion towards an output link.
  • A connector represents the display sink, such as eDP-1.
  • A mode defines dimensions, refresh and timings.

An atomic commit proposes the complete next state. The kernel validates it, then applies all accepted properties as one coherent update. KMS does not render the application’s pixels. Display planes may scale or blend during scanout, but that operation differs from the OpenGL or Vulkan render jobs discussed earlier.

11. Why the stages overlap

For one specific buffer, the dependencies remain ordered:

render -> make available -> compose or select -> present -> scan out

The machine does not wait for that full chain before starting all other work.

sequenceDiagram participant A as App component participant G as GPU graphics hardware participant C as Compositor component participant K as DRM/KMS plus amdgpu participant D as Display engine A->>G: Submit app render for buffer A2 G-->>A: Signal render fence A->>C: Commit wl_surface with wl_buffer A2 C->>G: Submit output composition O2 G-->>C: Signal composition fence C->>K: Atomic commit O2 with fence state K->>D: Program next scanout state D-->>C: Page-flip or completion event Note over A,D: While O2 progresses, the display may scan O1 and the app may prepare A3.

Double or triple buffering lets an application prepare a new image while another buffer remains in use. Fences tell consumers when asynchronous work has completed. Wayland frame callbacks help clients pace new work. Buffer-release events tell a client when the compositor has finished with a buffer. KMS can accept fence state and later send a page-flip or completion event.

An output presentation does not occur once for every application frame. The compositor builds monitor output frames from the latest usable buffers. It can reuse one client’s buffer across many output frames, skip an intermediate client buffer, or present while another client remains unchanged.

12. Zooming into the Radeon 780M display side

The word “GPU” hides separate hardware blocks. That distinction explains why a display can wedge without a logged graphics-ring timeout.

flowchart LR K["DRM/KMS atomic state
(kernel ABI)"] --> AD["amdgpu Display Manager and DC
(kernel components)"] FW["DMCUB or DMUB firmware
(firmware component)"] -. "runs on" .-> MCU["DMCUB or DMUB microcontroller
(hardware)"] AD --> MCU AD --> DCN["DCN display engine
(hardware)"] MCU <--> DCN DCN --> STREAM["eDP data stream
(link protocol)"] STREAM --> EDP["eDP electrical link
(hardware)"] EDP --> TCON["Panel timing controller
(hardware)"] TCON -. "retains image during PSR" .-> RET["Retained frame
(data and state)"] TCON --> LCD["LCD panel
(hardware)"]

The Radeon 780M’s graphics engine executes application and compositor render work. Its DCN display engine handles planes, composition blocks, output timing and links. This machine reported DCN 3.1.4.

AMD Display Core, often shortened to DC, is kernel display code inside amdgpu. It translates DRM display state into AMD display-pipeline state.

DMCUB, also called DMUB in interfaces and logs, is a display microcontroller block. It runs AMD display firmware. The driver uses this path for some display features and commands. DMCUB does not receive every rendered pixel, so it does not belong in every rendering call.

The final path uses the eDP protocol. The physical eDP link carries its data stream to the laptop panel.

This map gives the log terms a home. MPCC names a display composition block. CRTC messages concern the KMS output pipeline. DMCUB command failures concern the firmware-controlled display path. None of those names, by itself, reports a Vulkan render failure.

13. PSR: when the panel keeps the picture

Panel Self Refresh (PSR) lets a capable eDP panel retain an unchanged frame. The source can then reduce repeated memory fetches and link activity until content changes.

unchanged output
  -> panel retains frame
  -> source reduces link and memory work

content changes
  -> source exits PSR
  -> new frame reaches panel

PSR has entry, steady and exit states. It saves power, but it also adds state changes around the display path. On this Framework Laptop, the internal eDP-1 panel advertised PSR support and PSR was enabled.

The incident needs careful wording:

  • Fact: a warning at 11:16:22 ran through dmub_psr_get_state, dmub_psr_enable, edp_set_psr_allow_active, amdgpu_dm_atomic_commit_tail and drm_mode_atomic_ioctl.
  • Fact: this trace appeared after the first DMCUB errors and after my power-key suspend request.
  • Inference: the existing display fault affected later PSR control during an atomic KMS commit.
  • Unknown: whether PSR was active at 11:15:08, whether fullscreen caused a PSR exit, and whether PSR initiated the fault.

Disabling PSR can be a useful controlled test, but it is not proof in advance. Current mainline AMD source defines 0x10 in amdgpu.dcdebugmask as disabling PSR and PSR selective update. Anyone testing it should confirm the flag against the source for the kernel in use, test one change at a time and expect possible extra power use.

14. Reconstructing the failure

Here is the full sequence. The first display fault comes before the suspend attempt and the PSR trace.

flowchart LR T1["11:15:04
Mutter stacking assertion"] --> T2["11:15:08
first DMCUB errors"] T2 --> T3["11:15:09
MPCC idle timeout"] T3 --> T4["11:15:33
DMUB command queue errors"] T4 --> T5["11:16:18
power key starts suspend"] T5 --> T6["11:16:22
PSR call trace in KMS thread"] T6 --> T7["11:17:24
user.slice freeze times out"] T7 --> T8["11:18:17
CRTC blank fails"] T8 --> T9["11:25 to 11:28
more suspend and display failures"] T9 --> T10["11:29:35
new boot"]
Time on 2026-08-30EvidenceWhat I can conclude
11:15:04.809Mutter logged meta_window_set_stack_position_no_sync.Fact: a compositor warning occurred near the fullscreen action. Unknown: whether it caused, reflected or merely accompanied the fault. The same assertion later appeared without a display failure.
11:15:08.363First DMCUB error - collecting diagnostic data.Fact: AMD’s display path detected a DMCUB failure about 3.6 seconds later.
11:15:09.126mpc2_assert_idle_mpcc timed out.Fact: a DCN display composition block did not reach its expected idle state.
11:15:33.059Error queueing DMUB command: status=2 began repeating.Fact: the driver could no longer queue display firmware commands normally. Unknown: the exact meaning of status 2 in this Fedora kernel build.
11:16:18.661Power key pressed short; logind began suspend.Fact: my first recovery attempt came after the display fault.
11:16:22.251The KMS thread warned in dmub_psr_get_state during an atomic commit.Fact: later suspend work reached the broken DMCUB PSR path. This does not put PSR before the first failure.
11:17:24.003Freezing user.slice timed out.Fact: suspend preparation stalled while the session was unhealthy.
11:18:12.849More MPCC and CRTC-disable timeouts appeared around resume.Fact: the display state remained broken across the suspend attempt.
11:18:17.955DC: failed to blank crtc!Fact: the driver could not complete a basic display disable operation.
11:25:27 onwardsMore power-key presses, suspend failures and display errors.Fact: later recovery attempts added fallout after the original fault.
11:28:47.874The old journal ended with repeated DMCUB errors.Fact: no recovery appears in the stored log.
11:29:35The next boot began.Fact: the prior session ended. Inference: a forced restart or power cycle ended it; the journal does not record the physical act.
11:39:37The supplied Dawn and Vulkan warnings appeared.Fact: they occurred after the failed boot had ended. They cannot explain the earlier hang.

The system was a Framework Laptop 13 with an AMD Ryzen 7040 Series processor and Radeon 780M integrated GPU. The failed boot ran Fedora kernel 7.1.6-201.fc44.x86_64, Mesa 26.1.5, Mutter 50.3 and BIOS 03.18. amdgpu reported Display Core 3.2.378, DCN 3.1.4 and DMCUB firmware 0x08005D00.

Fact: the journal held no graphics-ring timeout, GPU page fault, Vulkan device loss or successful GPU reset for this event. Inference: that absence weighs against those specific failure signatures. It does not prove that rendering had no role in triggering a display transition.

Fact: earlier dates also showed dcn31_program_compbuf_size timeouts, including a GNOME Shell KMS thread inside an AMD atomic display commit. Inference: those signs make the display fault less isolated. Unknown: whether they share a root cause with this incident.

The evidence supports this conclusion:

The display stack wedged in the AMD DCN and DMCUB path after the fullscreen action. Later atomic commits, PSR queries, blanking and suspend could not recover it. The evidence does not isolate the first bad command or prove whether kernel code, firmware, hardware or their interaction owns the bug.

Calling this a “DMCUB firmware bug” is plausible shorthand, but stronger than the evidence. The same symptoms could arise if kernel code sent a bad sequence, firmware stopped servicing valid commands, hardware wedged, or two parts violated a timing assumption.

15. Why the Vulkan warning was a red herring

The TTY showed these lines after reboot:

Warning: maxDynamicUniformBuffersPerPipelineLayout artificially reduced from 500000 to 16 to fit dynamic offset allocation limit.
Warning: maxDynamicStorageBuffersPerPipelineLayout artificially reduced from 500000 to 16 to fit dynamic offset allocation limit.

It also said that a Dawn-based process had selected AMD Radeon 780M Graphics (RADV PHOENIX) with the Vulkan backend. Dawn’s current Limits.cpp emits those exact warnings when it clamps adapter limits to its internal maximum. The lines report exposed WebGPU capability adjustment. They do not report Vulkan device loss.

The timing settles this incident. They appeared at 11:39:37, about ten minutes after the new boot began. The failed boot ended before 11:29:35.

Dawn capability warningKernel display failure
User-space warningKernel [drm] errors
Adjusts an exposed WebGPU limitDMCUB command and DCN register timeouts
Does not report device lossBlocks CRTC blanking and later atomic display work
Seen after rebootPersisted during the failed prior boot

I would not declare every such warning harmless. I can say that this message alone is not an error report, and its time does not fit this crash.

16. A repeatable way to investigate a graphics freeze

I start narrow and widen only when the evidence asks for it. First I identify the failed boot and read its kernel log:

journalctl --list-boots --no-pager
journalctl -k -b -1 --no-pager

Then I restrict the journal to the event window. Exact times keep later recovery attempts from masquerading as the cause:

journalctl -b -1 \
  --since '2026-08-30 11:14:00' \
  --until '2026-08-30 11:20:00' \
  --no-pager

Next I filter by the graphics and display terms already present in the log:

journalctl -k -b -1 --no-pager \
  | rg -i 'amdgpu|drm|dmub|dmcub|psr|crtc|mpcc|timeout|reset|fault'

journalctl -b -1 --no-pager \
  | rg -i 'mutter|gnome-shell|brave|suspend|power key'

I record the hardware and user-space renderer separately:

lspci -nnk | rg -A3 'VGA|Display|3D'
vulkaninfo --summary

vulkaninfo comes from Fedora’s optional vulkan-tools package. It tells me what Vulkan sees now. It does not reconstruct a previous boot. Package, firmware and BIOS versions belong beside the incident log because an update can change any part of the path.

A stronger follow-up would collect:

  • The exact wall-clock time and action for a safe reproduction.
  • Kernel, Mesa, Mutter, firmware and BIOS versions.
  • AMD firmware information and a DMUB trace, following the current kernel debug guide.
  • A controlled PSR-disabled comparison after checking the flag against the running kernel source.
  • Full logs and clear steps for the upstream project that owns the failing area.

Debugfs tracing can require root, produce a great deal of data and alter timing. I would enable only the trace groups needed for a planned reproduction. AMD’s Display Core debug guide lists the relevant DMCU, DMCUB and PSR tools.

At the time of the incident, cached Fedora metadata listed newer kernel, AMD firmware, Mesa and Mutter packages. Updating those distro packages was a sensible first test. Framework also listed BIOS 3.20 for this model. I would treat a BIOS update as separate work: read the current Framework release guidance and recovery notes before deciding. Versions and advice age quickly.

17. The stack in four lines

This is the reference I wanted when I began:

Rendering:    app or toolkit -> graphics API -> Mesa -> DRM render node -> amdgpu -> graphics engine -> buffer
Submission:   app or toolkit -> Wayland client support -> Wayland protocol -> compositor
Composition:  client buffers -> compositor renderer -> output buffer, unless direct scanout or planes avoid it
Presentation: compositor -> libdrm -> DRM/KMS -> amdgpu Display Core -> display engine -> eDP -> panel

The first two lines are parallel interfaces from a normal accelerated Wayland application. They meet when the client attaches rendered content as a Wayland buffer. Composition may follow. Presentation and scanout put a selected buffer on the panel.

Type glossary

NameTypeWhat it does
Brave, GTK app, Qt appUser-space componentRuns application logic and produces window content.
GTK, Qt, SDL, GLFWUser-space library or frameworkProvides UI, input, window integration and often a renderer. Each is optional.
OpenGL, VulkanGraphics API specificationDefines rendering and compute operations. Neither is a process or driver.
MesaUser-space graphics project and runtime componentsSupplies Linux graphics API implementations and GPU-specific user-space drivers.
RadeonSIMesa user-space driver componentImplements OpenGL for supported AMD GPUs through Mesa’s Gallium stack.
RADVMesa user-space driver componentImplements Vulkan for supported AMD GCN and RDNA GPUs.
Wayland core and extensionsProtocol specificationDefines requests and events between clients and a compositor.
libwayland-client, libwayland-serverUser-space libraryMarshals and dispatches Wayland messages.
wl_surface, wl_bufferWayland protocol objectRepresents surface state and attachable content.
Mutter, SwayUser-space componentActs as Wayland server, compositor and window manager.
wlrootsUser-space librarySupplies reusable compositor backends, renderers, buffer support and protocol support. Sway uses it.
DMA-BUFKernel sharing framework and exported objectShares buffer storage through file descriptors.
dma_fence, sync file, DRM sync objectSynchronisation primitive or objectSignals completion and coordinates asynchronous buffer access.
libdrmUser-space libraryWraps many DRM ioctls and provides common definitions and helpers.
DRMLinux kernel framework and user-space ABIProvides device nodes, memory and buffer management, command submission, synchronisation and display interfaces.
DRM render node, such as renderD128Device-file interfaceAllows rendering without modesetting or DRM master.
DRM primary node, such as card1Device-file interfaceExposes KMS and other primary-node operations under access control.
KMSDRM display-control API and frameworkControls framebuffers, planes, CRTCs, connectors, modes and atomic state.
amdgpuLinux kernel driver componentImplements AMD-specific DRM rendering and KMS operations.
AMD Display CoreKernel subsystem inside amdgpuTranslates DRM display state into AMD display-pipeline state.
DCN 3.1.4AMD display hardware generationThe display controller generation reported on this system.
DMCUB or DMUB microcontrollerHardwareRuns display firmware and handles commands for some display features.
DMCUB or DMUB firmwareFirmware componentCode that runs on the display microcontroller.
GPU graphics engineHardwareExecutes drawing, shader and compute command streams.
Display engineHardwareFetches scanout buffers, processes planes and drives output links.
eDPLink protocolDefines the data stream between the display source and panel.
eDP linkHardwareCarries that stream from the display engine to the laptop panel.
PSReDP feature and state machineLets a capable panel retain an unchanged frame to save power.
Render target or pixel storageData object and storage interpretationHolds pixels produced by rendering.
DRM framebufferKMS kernel objectDescribes storage that KMS can select for scanout.

Primary references

For Wayland’s client, server and buffer model, I used the Wayland architecture guide, protocol model, reference documentation and core protocol. GTK documents its Wayland backend, while Qt documents its Wayland Client module.

For graphics APIs and Mesa, I used the Vulkan Registry, OpenGL Registry, Mesa platform overview, RADV documentation and Mesa source-tree guide.

For shared buffers and synchronisation, the kernel’s DMA-BUF documentation defines DMA-BUF, reservations and fences.

For the kernel graphics boundary, I used the DRM user-space interfaces, DRM internals and KMS documentation.

For compositor roles, I used the Mutter API overview, Mutter backend documentation, Sway README, wlroots documentation and Wayland compositor guide.

For the AMD path, I used the kernel’s amdgpu guide, driver-core guide, DCN programming model and Display Core debug guide. The current mainline AMD debug-mask definitions document the PSR and idle-power flags. VESA’s eDP presentation illustrates panel-side frame retention.

The crash began as a fullscreen photograph. The useful result is a map: APIs describe rendering, Wayland carries surface state and buffer references, Mesa implements graphics APIs, the compositor chooses an output plan, KMS presents it, and AMD’s display hardware scans it out. When the screen next freezes, that map tells me which logs belong together and which merely arrived wearing a suspicious hat.