perf(#862): clip the Local2D composite to its non-identity pixels - #866
Merged
Conversation
The composite reads the weave from a scratch that is a COPY of the target, so
wherever the pass reduces to 'weave' it rewrites bytes that are already there:
ALPHA_OVER / implicit LERP -> identity outside the 2D rects
ZONES -> identity inside a zone interior, no 2D over it
(outside every zone it genuinely clears, and a
feather ramp is not the identity either)
An explicitly authored mask may be anything anywhere, so it never clips.
Cover the non-identity pixels with up to 8 disjoint rects — the four bands
around the largest feather-inset zone interior, plus the part of the 2D
bounding box inside it — and issue one clipped draw per rect, snapshotting
only those rects. Disjointness is required by vkCmdCopyImage; the draws would
be idempotent anyway (no blending, output is a pure function of the inputs).
Bails out when the cover exceeds 80% of the region. Subsumes #858's
whole-frame special case. DXR_L2D_CLIP=0 restores the full-region pass.
Measured on the avatar (811x1421, 2D band + feathered zone): cover is 4 rects
= 32% of the region, GPU busy 53.9% -> 53.1% (mean of 3 alternating pairs,
lower in every pair). Modest, because the pass was never the 5.9 ms the
frame-stage timer suggested — that stage also spans the submit and the
whole-frame drain, so relabel it composite+wait so the next reader doesn't
optimise the wrong thing. Eyeball-verified twice by David: rounded corners,
bubble and weave all correct.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
Implements #862, generalising #858 from a whole-frame special case to a per-region one — and correcting the premise I filed #862 on.
What it does
The composite reads the weave from a scratch that is a copy of the target, so wherever the pass reduces to
weaveit rewrites bytes already present:So the pass is covered with up to 8 disjoint rects: the four bands around the largest feather-inset zone interior, plus the part of the 2D bbox inside it. One clipped draw per rect, and the weave snapshot copies only those rects. Disjointness is required by
vkCmdCopyImage; the draws would be idempotent regardless (blending off, output is a pure function of the sampled inputs). Bails out if the cover exceeds 80% of the region.DXR_L2D_CLIP=0restores the old path for A/B.The feather insetting is what makes a feathered zone clippable at all — the leftover is a ring, not a box, which is why a single scissor rect could never fire on the shipping avatar config (default feather is 16 px, 24 px via env).
Measured — and an important correction
Avatar, 811×1421, 2D band + feathered zone. Cover resolves to 4 rects = 32% of the region:
DXR_L2D_CLIP=0)Mean of 3 alternating pairs, clipped lower in every pair — so ~0.8 GPU points, real but modest.
This is much less than #862 predicted, and the prediction was wrong for an instructive reason: I read
composite=5.9 msfrom[FRAME_STAGES]as the cost of the composite. That stage actually spans the composite + HUD recording and the submit and whole-frame GPU drain — at a paced 60 fps it mostly measures the wait. Cutting the fill by 68% correctly did nothing to it. This PR relabels the stagecomposite+wait=so the next person doesn't optimise the wrong thing, and the issue is updated with the correction.Where it should matter more than on the avatar: apps whose Local2D overlay is small relative to a large region (non-zones path clips straight to the 2D bbox) — modelviewer's toast/HUD, gauss, Unity zones apps.
Verification
🤖 Generated with Claude Code