Repository navigation
perf(d3d11): mask-only post-weave alpha gate - no strip copy, no back-buffer read (2D-under-the-lens P1) - #305
Merged
Merged
Conversation
…-buffer read The post-weave alpha gate (client-present and compose-under-bg transparency) copied the whole woven target into ck_strip_tex every 3D weave, then re-read and rewrote every canvas pixel. In the common configuration - no 2D-under backdrop, no opaque-present flatten, and a 2D layer that is either absent (has_overlay 0) or coverage-alpha (SR order 3, has_overlay 2) - its result depends on the woven pixel only through the output-merger: all views transparent, has_overlay 2 : woven pixel unchanged all views transparent, has_overlay 0 : (0,0,0,0) any view opaque : (woven.rgb, 1) So a mask-only shader reads just the atlas and a blend state applies the result in place: has_overlay 2 = alpha-only write + discard on transparent pixels; has_overlay 0 = RGB*src.a, A=src.a. No CopyResource, no back-buffer read, and on the browser's whole-page-overlay path no writes outside the 3D content at all. has_overlay 1, backdrop, flatten and float targets keep the full gate unchanged; DXR_LEIA_ALPHA_GATE_FULL=1 forces it everywhere (A/B, rollback). The DXR_WEAVE_GPU_TIMING line keeps its fields and appends gate_mask_only=<n> so the A/B is read off the same knob. Co-Authored-By: Claude Opus 5.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.
P1 of the "2D under the lens" perf work. The P0 timing (#302) measured the post-weave
alpha_gateat 0.3-1.1 ms/frame, againstsr_weaveat 0.6-0.9 ms. That was on the browser present-owner weave (has_overlay=2): RTX 3080 laptop, 3840x2040, whole-page overlay, static gallery. The gate cost more than SR itself on many frames.What the alpha gate computes and why it exists
The SR weaver produces opaque RGB. Its alpha is either 1.0 (compose order 2) or the 2D layer's filtered coverage (order 3,
2D_OVER_COVERAGE), but never the 3D content's transparency. Two consumers need real transparency:The gate decides per screen pixel whether all views' atlas alpha are 0 at that tile-local position. Transparent pixels become the under-layer (live desktop, the 2D-under backdrop, the flattened bg, and/or the weaver's filtered 2D layer). Opaque pixels become
(woven.rgb, 1).It is not skippable on this path. The browser's composite needs alpha 1 on the 3D content and the weaver doesn't write it. So this PR makes the gate cheaper instead of skipping it.
What was expensive
Every 3D weave did all of the following:
CopyResourceof the whole woven target intock_strip_tex: 3840x2040 RGBA8 is 31 MB read + 31 MB written.The change: mask-only gate
In the common configuration, the full gate's result depends on the woven pixel only in ways the output-merger can apply in place. That configuration is: no 2D-under backdrop, no opaque-present flatten, a fixed-point (8/10-bit UNORM) target, and a 2D layer that is absent (
has_overlay 0) or coverage-alpha (has_overlay 2).(w.rgb + 0, a + 0)= woven unchangeddiscard(no write)(0,0,0,0)(0,0,0,0)with blendRGB = dst*src.a,A = src.a(woven.rgb, 1)(0,0,0,1)with the same blend (has_overlay 0)So
alpha_gate_mask_psreads only the atlas. It uses the full gate's transparency loop verbatim, including the exact-texelLoadrule from the 1-px-border fix. One of two blend states does the rest. There is noCopyResource, no back-buffer read, and withhas_overlay 2no writes at all outside the 3D content.has_overlay 1(it needsmax(layer.a, woven.rgb)), backdrop, flatten and float targets keep the full gate, unchanged.DXR_LEIA_ALPHA_GATE_FULL=1forces the full gate everywhere, for A/B and as a no-rebuild rollback. If the mask pipeline fails to build, it logs once and falls back to the full gate.Equivalence. The result is identical by construction for the configurations it takes, with one deliberate difference. The full gate reads the woven RGB back with a bilinear
Sampleat the texel centre. The shader comment in this same file documents that this can pick up 1/256 of the neighbouring column. The mask-only gate leaves the RGB untouched instead, so opaque-pixel RGB can differ from before by at most 1 LSB at hard vertical edges, toward the exact weaver output. Alpha is identical. The gate leaves the same default blend state bound on exit.Timing (P0 line kept)
Leia D3D11 DP timingkeeps every field (alpha_gate a/b (n=, with 2D layer=)unchanged) and appendsgate_mask_only=<n>: how many of the read-back gates took the mask-only pass.Expected savings
alpha_gateshould fall from 0.3-1.1 ms to a fraction of that. The 62 MB copy and the whole-canvas back-buffer read and write are gone. What remains is two atlas loads per pixel (the atlas is already hot from the weave) plus alpha writes on the 3D content only.sr_weaveis unchanged.Test plan
Build:
scripts\build-windows.bat buildin a worktree against the matching runtime worktree (done; compiles clean).Deploy: rename-swap the dev
DisplayXR-LeiaSR.dllintoC:\Program Files\DisplayXR\Plugins\LeiaSR\(keep the original as.orig-p1). Relaunch the service from anexplorer.exe.batwithDXR_WEAVE_GPU_TIMING=1andSR_SIMULATED_VIEWER=0,0,600,63in its env. Restore the DLL afterwards.bperf A/B on the same DLL. DisplayXR Browser whole-page overlay, static gallery, 100% overlay reuse, ~60 s per arm:
DXR_LEIA_ALPHA_GATE_FULL=1.Compare
alpha_gate,sr_weave(should be flat), runtimeweaveandtotal. Expectgate_mask_only == nin B and 0 in A.Visual, feat(gl,#613): GL DP display-zones vtable + #68 remap-skip gate #73 woven dump.
touch %TEMP%\dxr_weave_dump_triggerin each arm on the same page state, then diffdxr73_weave_output. Alpha should match exactly, and RGB to within 1 LSB (see Equivalence). Check the 1-px canvas border case (an element edge on an odd column): there must be no opaque black line outside the canvas.Transparent-window app. A shaped/transparent window on the compose-under-bg or client-present path (e.g.
cube_handle_d3d11_winwith transparency, or a transparent demo):workspace_screenshot.pngalpha withDXR_ATLAS_CAPTURE_RAW_ALPHA=1where applicable.DXR_PRESENT_OPAQUE=1, the full gate must still run (gate_mask_only=0).2D (V-toggle) on the transparent app: the gate also runs after the 2D blit with has_overlay 0. Holes must still punch.
Risks
DXR_LEIA_ALPHA_GATE_FULL=1.🤖 Generated with Claude Code