Skip to content

feat(glx): derive GLX vendor names from the render driver - #119

Merged
joske merged 20 commits into
joske:masterfrom
ariel3259:glx-vendor-names-from-driver
Aug 7, 2026
Merged

feat(glx): derive GLX vendor names from the render driver#119
joske merged 20 commits into
joske:masterfrom
ariel3259:glx-vendor-names-from-driver

Conversation

@ariel3259

Copy link
Copy Markdown
Contributor

feat(glx): derive GLX vendor names from the render driver

Branch: glx-vendor-names-from-driver, opened against master.

Stacked PR — please merge #118 first. This branch is cut from it, so until that one lands the diff below also contains its six commits. Once it merges, this diff reduces to the ~2450 lines that are actually new here. The commits unique to this PR are dd63b51..HEAD.

Hardware numbers below were measured on this branch before it was merged with current master. The post-merge tree is green (2252 tests, clippy and fmt clean), and master's new commits touch the Present/TFP wait paths rather than the vendor derivation, but the probe has not been re-run against the exact merged tree. Say the word and I'll re-measure before you look at it seriously.

Problem

GLX_VENDOR_NAMES_EXT was answered with a hardcoded constant:

pub const VENDOR_NAMES: &str = "mesa";

libglvnd therefore loaded libGLX_mesa.so on every screen yserver serves. Mesa has no DRI driver for an NVIDIA PCI id, so DRI3 screen creation failed and GL fell back to llvmpipe — software rasterisation on a discrete GPU:

pci id for fd 4: 10de:2d04, driver (null)
kmsro: driver missing
glx: failed to create dri3 screen
failed to load driver: nvidia-drm
GL_RENDERER:  llvmpipe (LLVM 22.1.8, 256 bits)

The server already held the discriminating fact — vk.driver_id, which it consults today to suppress GLX_EXT_texture_from_pixmap on NVIDIA. It was simply never consulted for the vendor query.

This PR contains two separable changes

1. BackendCapabilities (commits dd63b51, b71a715) — a refactor that stands on its own.

yserver::run and yserver_core::nested::run each carried a duplicated backend→state snapshot block, inside functions no test can call (one needs a DRM device and a VT, the other a host X server). Nothing caught an omission at either site, and glx_tfp_supported already carried that defect.

Both ServerState randr constructors now require a BackendCapabilities, built only by from_backend, so the omission does not compile. This is cheap because those constructors have exactly one call site each — the two run() functions; the 617 call sites of ServerState::new are untouched.

This half touches dpms_capable and glx_tfp_supported, neither of which is the GLX defect. It is severable and reviewable on its own.

2. The vendor derivation (the rest). KmsBackend answers "nvidia mesa" on NVIDIA_PROPRIETARY and "mesa" everywhere else; the value crosses the Backend seam as a &'static str (ash is a yserver-crate dependency only), is snapshotted into ServerState at startup, and the reply arm reads it.

Deliberate divergence from Xorg

Xorg never emits more than one vendor name (glx/glxscreens.h:150 is a single char *, assigned once from gbm_device_get_backend_name or strdup("mesa")). This sends two.

GLX_EXT_libglvnd defines the reply as a space-separated list, so a one-element list is a subset, not a contradiction. The second entry is insurance for a routine package split: with a bare "nvidia" on a system where the NVIDIA Vulkan ICD is installed but libGLX_nvidia.so is not, libglvnd resolves no vendor and falls to FALLBACK_VENDOR_NAME = "indirect"worse than today's llvmpipe.

Verified against libglvnd 1.7.0 source (src/GLX/libglxmapping.c:519-600): __glXLookupVendorByScreen splits the reply with strtok_r(..., " ", ...), tries each name in order, moves to the next when a vendor fails to load or its isScreenSupported returns False, and uses the fallback only when all fail. Happy to drop to a bare "nvidia" if you'd rather stay strictly Xorg-shaped — that is a one-line change and nothing else in the design moves.

The mapping is deliberately binary. Arms for AMD proprietary, Imagination and the rest are omitted because nobody here can measure them, and an unmeasured mapping that redirects a working configuration onto a nonexistent libGLX_*.so is worse than the status quo.

Escape hatch

YSERVER_GLX_VENDOR overrides the derived value verbatim (nvidia, mesa, nvidia mesa). Precedence is env > driver derivation > "mesa". A blank value warns and falls back rather than failing startup; an unloadable name is deliberately not validated server-side, since libglvnd falls through to the next entry. Documented in docs/status.md and in the man page's ENVIRONMENT section, including that it is read by the server, so changing it needs a server restart — unlike __GLX_VENDOR_LIBRARY_NAME, which takes effect on the next client launch.

Verification

Measured on an RTX 5060 Ti, NVIDIA 610.57.04, open kernel modules.

With no __GLX_VENDOR_LIBRARY_NAME set:

raw wire:     VENDOR_NAMES_EXT -> "nvidia mesa" (n=12)
server log:   GLX::QueryServerString name=0x20f6 -> "nvidia mesa"
GL_VERSION:   4.6.0 NVIDIA 610.57.04
GL_RENDERER:  NVIDIA GeForce RTX 5060 Ti/PCIe/SSE2
direct=1      RESULT: GL works

That probe output was byte-identical to the llvmpipe baseline before this change (md5 b45bacfb…); it is now 4760fdae…. Control: forcing __GLX_VENDOR_LIBRARY_NAME=mesa still lands on llvmpipe with the Mesa loader errors, so the NVIDIA result is caused by the vendor selection and not by something else on the branch.

Known limitation — please read before merging

KWin still cannot start GL compositing on NVIDIA, and this change moves where it fails.

kwin_x11 aborts with:

No provider of glXGetProcAddressARB found.  Requires one of:
    GLX_ARB_get_proc_address

The client-side GLX extension string that libGLX_nvidia computes against yserver omits GLX_ARB_get_proc_address, and libepoxy aborts resolving the entrypoint. Setting __GLX_VENDOR_LIBRARY_NAME=nvidia does not avoid it.

Two things worth stating plainly:

  • This is not a regression introduced by this PR in the "it used to work" sense. Plasma already crashed on the llvmpipe path, in libepoxy, on glXBindTexImageEXT. Both vendors break KWin; this changes which call aborts, and therefore what the default shipped failure is. Applications are unaffected — Steam and Hollow Knight launch and render on the GPU.
  • The obvious fix is the wrong fix. Xorg does not advertise GLX_ARB_get_proc_address either; it is excluded from known_glx_extensions with the comment "GLX_ARB_get_proc_address is implemented on the client" (glx/extension_string.c:74). Adding it server-side would diverge from Xorg without addressing the cause.

Measured so far, against a live XWayland on the same GPU and driver as a control: XWayland's client string leads with GLX_ARB_get_proc_address while its server string lacks it, so libGLX_nvidia adds it there and not here. An A/B eliminated the GLX vendor string, GLX_EXT_import_context, and the size/content of the server extension list. NVIDIA withholds exactly two entries against yserver — GLX_ARB_get_proc_address and GLX_SGIX_fbconfig, the latter one we do advertise — which points at something structural rather than at the list. The remaining untested difference is fbconfig synthesis: 2 configs against XWayland's 168. That investigation is ongoing and is not part of this PR.

Happy to hold this until that is resolved if you'd rather not change the default failure mode.

Notes

  • Workspace green: 2252 tests, cargo clippy --all-targets -- -D warnings clean, cargo +nightly fmt --check clean. All commits signed.
  • Design doc (rev 4) and implementation plan under docs/superpowers/.
  • Not validated: ynest against an NVIDIA host still reports "mesa"; PRIME/Optimus, where vk.driver_id names the render device's driver and need not match the KMS node's vendor.

🤖 Generated with Claude Code

ariel3259 and others added 19 commits August 3, 2026 23:28
…wable

A GLXWindow/GLXPixmap XID is a fresh client-allocated id with no X
resource behind it, so resolving GLX_WIDTH/GLX_HEIGHT from the GLX XID
itself always missed and reported 0x0. Mesa's loader_dri3 sizes its
buffer from these fields and fails with "failed to create drawable";
measured on the wire against libGLX_nvidia (2026-08-03): a 64x32
backing drawable was reported as 0x0. Resolve from the backing X
drawable recorded at create time, as Xorg does
(pGlxDraw->pDraw->width/height, glxcmds.c:1891).
Add GlxDrawableKind { Window, Pixmap, Pbuffer } (no Default impl, so a
missed construction site is a compile error) and set it at all three
glx_drawables.insert sites plus the resource-allocator test literal.

ChangeDrawableAttributes now records only GLX_EVENT_MASK and ignores
every other attribute, matching Xorg's single-case switch
(glxcmds.c:1494-1503). Re-key the is_pbuffer checks in
drawable_attributes_for and glx_pbuffer_geometry onto the kind,
preserving both 0x0-pbuffer behaviours (backing-pixmap 1x1 fallthrough
and the GetGeometry BadDrawable guard).
Restructure drawable_attributes_for around Xorg's exact branch
(glxcmds.c:1863-1914): Y_INVERTED/WIDTH/HEIGHT/SCREEN always; the
TEXTURE_TARGET/EVENT_MASK/FBCONFIG_ID block (plus PRESERVED_CONTENTS
for pbuffers, STEREO_TREE_EXT for windows) only with a GLX record;
DRAWABLE_TYPE last, WINDOW_BIT for the no-record fallthrough. A naked
X window no longer gets a bogus GLX_FBCONFIG_ID = 0 (measured defect
against libGLX_nvidia), and GLX_RENDER_TYPE is dropped — Xorg never
sends it for a drawable.

Delete the generic ChangeDrawableAttributes override pass; the
event_mask field recorded in the previous commit is the only state.

GET_DRAWABLE_ATTRIBUTES now emits Xorg's two distinct error codes
instead of a silent Success: a naked X pixmap gets GLXBadDrawable
(GLX_FIRST_ERROR + 2; glxproto.h:43 — GLXVND forwards pixmaps, then
dixLookupWindow fails), and an XID that is not a drawable at all gets
core BadDrawable (the GLXVND dispatch stub errors before
DoGetDrawableAttributes is reached). Add the missing GLX_STEREO_TREE_EXT
and ERROR_GLX_BAD_DRAWABLE constants with citations.
Parse the request body, which the arm ignored entirely: the new
context XID sits at body[4..8] for minor 5 (MakeCurrent) and
body[12..16] for minor 26 (MakeContextCurrent), per
glxproto.h:225-233 and :471-481. The release form (context == None)
now returns contextTag = 0 — tag 0 is reserved by the protocol to
mean "no context current" — instead of allocating a fresh monotonic
tag, matching Xorg (vndcmds.c:232-234, :271-273). Measured defect:
yserver.log showed tag=1 then tag=2, the second being the release.
Defect A of the NVIDIA GLX investigation: GLX_VENDOR_NAMES_EXT is
hardcoded to "mesa" (glx.rs:179), so libglvnd loads libGLX_mesa.so on
every screen and falls back to llvmpipe on NVIDIA hardware. The server
already holds the discriminating fact in vk.driver_id.

Design derives the vendor from vk.driver_id, crosses the Backend seam
the same way glx_tfp_supported does, returns the list "nvidia mesa" for
the libglvnd fallback path, and adds a YSERVER_GLX_VENDOR override.

Rev 2: Opus adversarial review round 1 returned REJECT; all six blocking
findings applied. Notably the risk section was inverted — Plasma already
crashes on llvmpipe today (defect B), so this change moves an existing
crash rather than creating one — and the Plasma measurement was promoted
from a note to a merge precondition.

Base: glx-reply-xorg-alignment @ bd168cf. Not implemented yet.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Rev 2 named a defect in its own design and then documented it instead of
fixing it: the vendor crossed the Backend seam as a field assigned at two
call sites, so an implementer who forgot lib.rs:337 passed every unit
test while the server still shipped "mesa" on NVIDIA. That hole is the
shape of the surrounding code, not an oversight — lib.rs:336-337 and
nested.rs:416-417 are duplicated backend->state snapshot blocks inside
two run() functions no test can call, and glx_tfp_supported already
carries the same defect today.

D2 now routes the snapshot through a BackendCapabilities struct that both
ServerState constructors take as a required parameter, so the omission
does not compile. This is cheap because those two constructors have
exactly one call site each — the two run() functions; the 617 call sites
of ServerState::new are untouched. The pre-existing glx_tfp_supported gap
closes with it.

D1 drops the cached field: under D2 the getter runs once per server
lifetime and the computation is a matches! on an enum, so caching would
buy nothing and would cost an initialiser in for_tests_seed, which this
design now leaves alone.

D4 gained the rewrite of the comment above the arm it changes, which rev
2 modified the code under and left standing ("returning mesa (matching
Xorg)"). The Asahi/cogl SIGSEGV rationale underneath is still live and is
preserved, now carried by the non-NVIDIA arm of D1.

Rev 2's "Unverified here" section was wrong about this box: ~/Projects/
xserver is checked out here at 5541a5c8 and libglvnd 1.7.0's source ships
in Gentoo's distfiles. All six Xorg citations verified exact, plus
glxscreens.h:150 (char *glvnd — a single string) as structural proof that
Xorg never emits more than one name. libglvnd's __glXLookupVendorByScreen
verified exact at libglxmapping.c:519-600, which closes rev 2's escape
hatch in favour of the "nvidia mesa" list rather than a bare "nvidia".
25 of 26 yserver citations exact; backend.rs:2107 corrected to 2104.

Base: glx-reply-xorg-alignment @ bd168cf. Still not implemented.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Rev 3 was reviewed against AGENTS.md and against the norms this project
already set. Six findings applied, one dismissed with its reasoning
recorded.

Withdrew overstated evidence. Rev 3 added glxscreens.h:150 (char *glvnd)
as "structural confirmation" that Xorg never emits more than one vendor
name. It confirms nothing: a char * holds "nvidia mesa" as readily as
"mesa", so the field type is compatible with one name and with many. The
claim rests on the assignment sites alone, which rev 2 already cited.
This mattered because it sat in the section whose entire purpose is
closing rev 2's escape hatch on the divergence — the same failure mode
(a citation that does not support what it is cited for) that Opus round 1
caught in rev 1.

Scoped an unverified universal negative. Rev 3 asserted "no X client
parses this string itself" in the exact sentence carrying AGENTS.md:19's
"clients are tested for 40+ years on Xorg". Reading one library cannot
establish that. Narrowed to the checked claim — libglvnd is the only
known consumer and handles a list as described — with the residual
exposure named: a client that queries GLX_VENDOR_NAMES_EXT on raw
xcb-glx and assumes one name. Our own rawglx probe issues that query.

Declared severability. D2's BackendCapabilities refactor touches
dpms_capable and glx_tfp_supported and closes a pre-existing wiring gap;
none of that is defect A. The two changes now have their own section and
the plan must order the refactor first. This is not bookkeeping: the
vendor work is gated on a Plasma measurement that can fail, since defect
B is open and unmeasured, and a change that is independently correct must
not be held behind a hardware result it does not depend on. It also keeps
the AGENTS.md:18 squash honest.

Moved from_backend out of trait_def.rs into backend/mod.rs — core does
read YSERVER_* elsewhere, but every such read is in a behaviour module,
and startup policy does not belong in the contract. Not params.rs either:
that module is explicitly core -> backend, per-request.

Named the module and test homes rev 3 left ambiguous, and gave
docs/status.md a second entry for the seam change, belonging to task 1.

Dismissed: the with_* constructor naming. It reads like a break until you
notice width/height are already absent from two of the three names — the
convention names the differentiator from the base constructor, and
capabilities becomes common to both randr constructors. Recorded so it is
not re-raised.

Base: glx-reply-xorg-alignment @ bd168cf. Still not implemented.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Six tasks against spec rev 4. Task 1 is the severable BackendCapabilities
refactor and carries no hardware precondition; tasks 2-6 are defect A
proper, gated on the Plasma measurement in task 6.

Task 1 deliberately does NOT add the glx_vendor_names field. That is the
severability boundary, and it exercises the mechanism the refactor exists
for: task 2's new field fails to compile at from_backend's struct literal
until it is handled.

Task 4's integration test is the designated verified-failing-first test —
against today's code the arm returns the VENDOR_NAMES constant regardless
of state, so it fails with "mesa" rather than failing to compile.

Both docs/status.md entries are folded into the tasks that own them: the
seam entry into task 1, the YSERVER_GLX_VENDOR knob into task 4.

Task 6 leads with the branch check. run-probe-session-0805.sh builds
whatever branch is checked out, and on 2026-08-05 that produced four
output files byte-identical to the baseline — a re-measurement of the bug
mistaken for a measurement of the fix.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
lib.rs:336-337 and nested.rs:416-417 were duplicated backend->state
snapshot blocks inside two run() functions no test can call: yserver::run
needs a DRM device and a VT, nested::run needs a host X server. Nothing
caught an omission at either site, so a missed glx_tfp_supported
assignment compiled, passed every unit test, and silently shipped the
default.

Both randr constructors now require a BackendCapabilities, built only by
from_backend, so the omission does not compile. This is cheap because
those constructors have exactly one call site each -- the two run()
functions; the 617 call sites of ServerState::new are untouched.

The move is semantically inert: with_randr_outputs_and_modes' body reads
neither dpms nor glx_tfp_supported, so assigning them inside the
constructor rather than after it is indistinguishable.

Severable from the GLX vendor work it was written for.
…ed-assignment test

Review findings on the BackendCapabilities commit:

- backend/mod.rs re-exported BackendCapabilities as pub(crate), letting
  nested.rs reach it via crate::backend::BackendCapabilities. That path
  contradicts the type's own doc comment (server.rs): backend depends on
  server, not the reverse, and the type lives in crate::server. lib.rs
  already named it correctly. Drop the re-export back to a private use
  (still visible to the test submodule) and call it as
  crate::server::BackendCapabilities from nested.rs, matching lib.rs.

- randr_constructors_deposit_capabilities_into_server_state built both
  BackendCapabilities fields as true/true, so a crossed assignment in
  with_randr_outputs_and_modes (dpms <-> glx_tfp_supported swapped) left
  the test green. Made each call's two fields disagree, and inverted
  between the two calls, so either call alone still proves both fields
  land un-mixed. Verified by swapping the two assignments in
  with_randr_outputs_and_modes locally: the amended test fails, as
  expected; reverted before committing.
Adds Backend::glx_vendor_names (default "mesa", the same value Xorg's
glamor provider falls back to), the ServerState field it feeds, and
resolve_glx_vendor_names for the YSERVER_GLX_VENDOR override.

ash is a yserver-crate dependency only, so the value crosses the seam as
a &'static str the way glx_tfp_supported crosses as a bool.

The override takes the env value as a parameter rather than reading it
inside the resolver: env mutation races under a parallel test runner.
from_backend is the single place that reads std::env, and it runs once
per server lifetime, so no OnceLock caching is warranted.

Blank or whitespace-only input degrades to the derived value with a
warning -- a typo must not keep the display server from starting. An
unloadable name is deliberately not validated server-side: libglvnd
falls through to the next entry in the list.

No behaviour change yet; the reply arm still returns the constant.
KmsBackend now answers "nvidia mesa" on NVIDIA_PROPRIETARY and keeps
"mesa" everywhere else. Same shape as the tree's other per-driver
policies, scanout_prefers_linear and VkContext::supports_dri3_syncobj.

The mapping is deliberately binary: an unmeasured mapping that redirects
a configuration working today onto a nonexistent libGLX_*.so is worse
than the status quo.

The second entry is insurance for the package split where the NVIDIA
Vulkan ICD is present but libGLX_nvidia.so is not -- a bare "nvidia"
would leave libglvnd on FALLBACK_VENDOR_NAME "indirect", worse than
today's llvmpipe. libglvnd 1.7.0 honours a list
(src/GLX/libglxmapping.c:519-600).

No cached field: the getter runs once per server lifetime and the
computation is a matches! on an enum, so for_tests_seed is untouched.
The arm returned the hardcoded VENDOR_NAMES ("mesa") for every screen,
so libglvnd loaded libGLX_mesa.so on NVIDIA hardware, Mesa found no DRI
driver for the PCI id, and GL fell back to llvmpipe on a discrete GPU.

It now reads ServerState::glx_vendor_names, derived from vk.driver_id at
startup. The regression test was verified failing against the previous
commit first.

Also adds a debug! on the QueryServerString path. That path had no
logging at all, which made the server log structurally incapable of
showing the query this whole change rests on -- without it a hardware
run cannot tell "libglvnd honoured our list" from "libglvnd guessed
nvidia for unrelated reasons".

The comment above the arm was rewritten rather than dropped: the
Asahi/cogl SIGSEGV rationale is still live, now carried by the
non-NVIDIA arm of the driver mapping instead of by a constant.
…efault

The end-to-end reviewer traced vk.driver_id through Backend::glx_vendor_names,
BackendCapabilities::from_backend, ServerState, and the QueryServerString
reply arm and found the value's path correct. But
from_backend_takes_vendor_names_from_the_backend asserted "mesa" -- byte-
identical to the trait default, the with_geometry struct-literal default,
and what a hardcoded glx::VENDOR_NAMES.to_string() inside from_backend
would also produce. The test passed whether or not from_backend actually
called backend.glx_vendor_names(). RecordingBackend now carries its own
overridable glx_vendor_names field, following the exact pattern already
used for dpms_capable, and the test sets it to a non-default value before
asserting it survives the round trip. Temporarily hardcoding the constant
inside from_backend was confirmed to fail this test and reverted.

KmsBackend's override -- the one place the driver-derived value is actually
computed -- had no test reaching it through the Backend trait at all,
leaving room for the override to end up on an inherent impl instead of the
trait impl, which compiles and is silently dead against &dyn Backend call
sites. Added a UFCS-style call through the trait that also pins the
platform.vk == None fallback.

resolve_glx_vendor_names trimmed only the ends of YSERVER_GLX_VENDOR, so
an internal tab or newline would reach the wire intact. libglvnd splits
the reply on a literal single space, so that survivor becomes one
unloadable token with no fallback entry behind it -- worse than not
overriding at all. Switched to split_whitespace().join(" "), which
normalizes instead of rejecting and keeps the existing trim-equivalent
behaviour and the deliberate no-server-side-validation stance intact.
Reworded the doc comment and the blank-value log line, which called
whitespace-only input "empty."

randr_constructors_deposit_capabilities_into_server_state used "mesa" for
the with_randr_outputs case -- the constructor ynest actually calls, and
the one no other test reaches -- so that half of the test couldn't detect
the field being dropped either. Swapped the two vendor strings between
the cases so each half carries a non-default value in the constructor it
covers.

Updated the two comments left stale by this field's addition: nested.rs's
capability-snapshot comment still said "DPMS support, GLX
texture-from-pixmap support," and mod.rs's cross-reference had drifted to
a stale line number after with_randr_outputs moved.

docs/status.md's precedence paragraph didn't say what YSERVER_GLX_VENDOR=""
actually does (warn and fall back, same as unset) -- worth stating since
an operator clearing the variable to disable the override would otherwise
have to read the code to find out. The Task-1 bullet referenced a "Task 2"
that doesn't exist as changelog vocabulary and described this file's own
follow-on commits in future tense; rewritten in past tense.

YSERVER_GLX_VENDOR is an operator rollback lever, not developer tracing,
so it belongs in the man page's ENVIRONMENT section alongside
YSERVER_DRM_DEVICE and friends rather than under the "further YSERVER_*
variables are deliberately not documented" clause -- docs/status.md gets
archived periodically and isn't a durable home for it.

Finally, dropped the Default derive from BackendCapabilities. Nothing in
the workspace called ::default() or ..Default::default(), and Default
was a compiling bypass of the exact invariant the type exists to
enforce -- that a ServerState cannot be built without consulting a
backend.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
scdoc parses a leading double-underscore as an empty italic span and
silently drops it -- exit status 0 either way. The YSERVER_GLX_VENDOR
entry named libglvnd's own override as GLX_VENDOR_LIBRARY_NAME in the
rendered roff, missing its leading __ entirely, which points an operator
at a variable that doesn't exist. Escaped both underscores
(*\_\_GLX_VENDOR_LIBRARY_NAME*) and restored the bold markup that had to
be dropped earlier to work around the parse error; the surrounding
entries already bold variable names mentioned in body text (see
GLX_VENDOR_NAMES_EXT two lines up), so this brings it back in line.
Verified against the actual roff output, not just scdoc's exit code:
before, \fI\fRGLX_VENDOR_LIBRARY_NAME; after,
\fB__GLX_VENDOR_LIBRARY_NAME\fR.

backend/mod.rs's cross-reference to RecordingBackend::dpms_capable() had
drifted to recording.rs:1526 -- a field added since now pushes the
getter down to 1533, and 1526 lands inside an unrelated COW-release
method's Ok(final_release).

The doc comment on glx_vendor_names_falls_back_to_mesa_with_no_vk
claimed the UFCS call "forces dispatch through impl Backend for
KmsBackend rather than a same-named inherent method." True, but with
platform.vk == None the override and the trait default return the
identical &'static str, so the assertion passes regardless of which
impl supplies the method, and the trait's default means UFCS still
resolves even if the inherent method vanished -- no compile-time
discrimination either. Added a sentence naming what the test actually
pins: the map_or fallback body in glx_vendor_names, which breaks if that
map_or becomes an unwrap/expect on vk or if the no-Vulkan default moves
off "mesa" -- and saying plainly that it does not distinguish trait from
inherent dispatch.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…iver

# Conflicts:
#	crates/yserver/src/kms/render/backend.rs
#	docs/status.md
@joske

joske commented Aug 7, 2026

Copy link
Copy Markdown
Owner

Thx, I'll review later, please fix the conflicts first.

PR joske#118 (glx-reply-xorg-alignment) was squash-merged upstream as 247b7a4,
so the reply-alignment commits this branch carries individually now exist
on master as one commit. The content is identical, so git collapsed the
duplication cleanly -- the branch's net diff against upstream/master is
now purely the vendor-name work.

Conflicts resolved:

- process_request.rs, GET_DRAWABLE_ATTRIBUTES error arm: took upstream's
  47b0633 (fix(glx): preserve minor opcode in drawable errors), switching
  the unknown-XID path from emit_x11_error to emit_x11_error_with_minor
  and passing u16::from(header.data). The pixmap arm directly above
  already reported the minor opcode; this brings the core BadDrawable arm
  in line, and the paired assertions on buf[8..10]/buf[10] in
  glx_get_drawable_attributes_unknown_xid_returns_core_bad_drawable came
  in with it.

- process_request.rs tests: kept
  glx_vendor_names_query_answers_from_server_state, which upstream does
  not have -- an adjacency conflict, not a semantic one.

- docs/status.md: kept both entries. Upstream's direct-scanout idle paint
  starvation note and this branch's GLX_VENDOR_NAMES_EXT /
  BackendCapabilities notes are independent.

Verified: cargo clippy --all-targets -D warnings and the full test suite
(1474 tests) on yserver-core and yserver-protocol, plus cargo +nightly
fmt --check. The yserver crate could not be built here -- its build
script needs glslc, which is not installed in this environment -- but no
conflict touched that crate.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@ariel3259

Copy link
Copy Markdown
Contributor Author

I fixed the conflicts

@joske
joske merged commit f4c0b60 into joske:master Aug 7, 2026
1 check passed
@joske

joske commented Aug 7, 2026

Copy link
Copy Markdown
Owner

Thx! I tested cinnamon on my 1050 box, and it was UNUSABLE on master, and with your branch, everything was fixed!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants