perf(ui): additive DispatchFused to collapse consecutive UI passes (#47) #93
No reviewers
Labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Catcrafts/Crafter.Graphics!93
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "claude/issue-47"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Adds a fifth UI compute path —
DispatchFused— alongside the four per-elementDispatch*calls (issue #47). It composites quads → circles → images → text (canonical back-to-front order) in one dispatch that loads the destination image once and stores once, eliminating the per-pass load+store and the inter-passVkMemoryBarriers a run of consecutiveDispatch*calls would pay.shaders/ui-fused.comp.glslreuses each category's exact cooperative shared-memory tile-cull + per-pixel accumulate (co-designed with #46), so a fused category is pixel-identical to its standalone pass. Categories run sequentially per thread and share one set of shared scratch, so the VGPR/shared-memory high-water mark stays at the per-category level, not the sum.Additive — frozen contract untouched
The per-element
Dispatch*calls and the 48-byteUIDispatchHeaderare unchanged.DispatchFusedgets its own 128-byte push-constant layout (UIFusedHeader: fouruvec4headers + four per-category clipvec4s — exactly the guaranteed push-constant minimum, no padding holes). To interleave a customui.Dispatch()between standard passes, bracket it with twoDispatchFusedcalls — the dispatch boundary is the explicit, app-declared flush point (fusing across a custom dispatch is a memory round-trip, i.e. physics, not removed here).WebGPU (Vulkan-second)
DispatchFusedfalls back to issuing the per-elementDispatch*calls in canonical order (one texture/sampler per dispatch there can't feed the bindless image phase), so the result matches — only the load/store fusion is Vulkan-only.Testing
UIFusedShader(crafter-build test): compiles the realui-fused.comp.glslwith glslang, validates withspirv-val, asserts exactly one push-constant block, and pins the push-constant member offsets to{0,16,32,48,64,80,96,112}— guarding the GLSL↔C++ layout drift that the C++-sidestatic_assert(sizeof(UIFusedHeader)==128)alone can't.crafter-build test --jobs=1).HelloUInow composites its background quads, mouse circle, and label text in a singleDispatchFused. Rendered on a real Vulkan/Wayland session — identical to the per-element path.Resolves #47
🤖 Generated with Claude Code
Screenshots
HelloUI compositing background quads, a mouse-following circle, and label text in a single
DispatchFused— pixel-identical to the per-element path: