Skip to content

Record why the menu soft focus covers only the in-game menu - #2

Merged
themuffinator merged 1 commit into
mainfrom
menu-soft-focus-scope
Aug 6, 2026
Merged

Record why the menu soft focus covers only the in-game menu#2
themuffinator merged 1 commit into
mainfrom
menu-soft-focus-scope

Conversation

@themuffinator

Copy link
Copy Markdown
Owner

What this is

A behaviour-neutral change. Executable behaviour is identical to 8f79c27; the diff is guard comments, source gates, cvar help, and docs.

I extended cl_menuBlur to the connection dialog, the level-loading screen, and the console. All three broke the game. This PR withdraws them and records why, so the guards that prevent them are not read as redundant and removed again.

Why the extension failed

All three are 2D-only frames, which meant dropping the backEnd.doneSurfaces gate in every backend. That gate does more than name a scene: it is the only signal a backend has that the render target holds something the composite may read back, and nothing else in any of the three renderers post-processes a frame without one. Removing it faulted the device inside the ICD on the first connect screen — before the loading screen was even reached.

The console failed separately and for its own reason. It is the only layer that finishes the frame's own post-processing, calling re.FinishBloom from inside Con_DrawSolidConsole, and neither ordering around that call works:

  • request before it — bloom's blend-pass descriptor sets are still bound when the console draws, so the console does not appear at all;
  • bloom finished first — the Vulkan backends sit in RENDER_PASS_POST_BLOOM, which targets an attachment the pyramid does not sample.

Either ordering also composites over live gameplay for the 140 ms the request takes to fade out after the console closes, which dims the warmup ready-up prompt for no reason the player can see.

A third failure is recorded from the same work: vk_menu_blur must leave vk.cmd->last_pipeline as VK_NULL_HANDLE. vk_menu_blur_draw binds descriptor set 0 through vk.pipeline_layout_post_process, and binding through an incompatible layout disturbs the sets bound for vk.pipeline_layout. Nulling the cache is what forces the next draw to rebind them. Handing the frame's pipeline back — which looks like the tidier mirror of what vk_bloom does for its own binds — faults the device the same way.

What changed

  • backEnd.doneSurfaces restored in tr_arb.c and both vk.c, each with the reason inline.
  • vk.cmd->last_pipeline = VK_NULL_HANDLE documented as load-bearing in both Vulkan backends.
  • Client requests exactly one layer again, with the withdrawn ones explained at the two sites where they were tried.
  • cl_menuBlur's cvar help and the changelog no longer promise the withdrawn layers.
  • MENU_SOFT_FOCUS.md gains a "what cannot be softened, and why" section covering the connect/loading screens, the console, and the pre-existing cgame-overlay limitation.

Gates

tests/menu_blur_source_tests.py now fails if any of it regresses: all three backends must test doneSurfaces, both Vulkan backends must null last_pipeline, the client must request exactly one layer with no client-side re.FinishBloom, and the settings slider's bounds must match the cvar's Cvar_CheckRange. A future change has to argue with a failing test rather than with a comment.

For the reviewer

  • Not verified at runtime. I could not run the renderer; every diagnosis here came from source plus your crash reports, and I was wrong more than once on the way. The revert is what I trust — it returns behaviour to a build you had working.
  • The connect-screen blur you asked for is not delivered. The blocker is concrete: establishing what a 2D-only frame guarantees about the render target. That needs a run with the Vulkan validation layers on to turn a guess into a VUID. I would rather leave it out than ship another broken build.
  • One changelog line about external lightmap atlases rode along in this commit; it belongs to the separate fix/external-lightmap-parity branch, which is committed locally and not pushed.

🤖 Generated with Claude Code

The soft focus was extended to the connection dialog, the level-loading
screen, and the console. All three are 2D-only frames, which required
dropping the backEnd.doneSurfaces gate in every backend. That gate is not
just naming a scene: it is the only signal a backend has that the render
target holds something the composite may read back, and nothing else in
any of the three renderers post-processes a frame without it. Removing it
faulted the device inside the ICD on the first connect screen.

Those layers are withdrawn and the guards are restored, so the executable
behaviour matches 8f79c27 again. What is kept is the reasoning, in the
code and in MENU_SOFT_FOCUS.md, so the guards are not read as redundant
and removed a second time:

- backEnd.doneSurfaces in all three backends.
- vk.cmd->last_pipeline = VK_NULL_HANDLE in both Vulkan backends.
  vk_menu_blur_draw binds descriptor set 0 through
  vk.pipeline_layout_post_process, and binding through an incompatible
  layout disturbs the sets bound for vk.pipeline_layout. Nulling the cache
  is what forces the next draw to rebind them; handing the frame's
  pipeline back instead faults the device the same way.
- The console cannot be a layer at all. It is the only one that finishes
  the frame's own post-processing via re.FinishBloom, and neither ordering
  around that call works: before it, bloom's blend-pass descriptors are
  still bound when the console draws and it does not appear; after it, the
  Vulkan backends sit in RENDER_PASS_POST_BLOOM. Either ordering also
  composites over live gameplay while the request fades out, which dims
  the warmup ready-up prompt.

Source gates now hold all of that, so a future change has to argue with a
failing test rather than with a comment. cl_menuBlur's cvar help and the
changelog no longer promise the withdrawn layers.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@themuffinator
themuffinator merged commit d368743 into main Aug 6, 2026
@themuffinator
themuffinator deleted the menu-soft-focus-scope branch August 6, 2026 18:11
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.

1 participant