Skip to content

feat(dehalo): opt-in shared-memory tiling of the box-blur window (ADR-0139)#38

Merged
lusoris merged 1 commit into
masterfrom
feat/dehalo-tile
Jun 27, 2026
Merged

feat(dehalo): opt-in shared-memory tiling of the box-blur window (ADR-0139)#38
lusoris merged 1 commit into
masterfrom
feat/dehalo-tile

Conversation

@lusoris

@lusoris lusoris commented Jun 27, 2026

Copy link
Copy Markdown
Contributor

What

Opt-in tile option (default 0) for vf_pelorus_dehalo_vulkan — shared-memory tiling of the box-blur window (ADR-0139). Bit-identical; a throughput win on bandwidth-limited GPUs.

Why + premise-check

box_blur re-reads an overlapping 17×17 window ~5× per pixel (centre + L/R/U/D cross) → ~1445 imageLoad/px with trivial ALU. A premise-check confirmed it's fetch-bound: an ALU-strip that keeps the full loop trip-count but cuts each box-blur to one load collapsed Arc rtime 11.5 s → 3.4 s (−70%). (The companion aa sobel kernel was the opposite — ALU-bound, so its tiling was refuted and not built.)

How

tile=1 has the 32×32 workgroup cooperatively load its output region + a MAX_R+1 halo (covering the union of the five box-blur windows + the Sobel/contrast 3×3 + the ring scan) into shared once per plane; pel_luma then reads shared memory. The tile load runs in uniform control flow (before the per-thread IS_WITHIN guard) so its barriers are valid; the tiled read mirrors the direct edge-clamp exactly. .comp kept in lockstep.

Validation (8×-chained, blur=8, 1080p, warm)

Bit-identical: cmp 0 differing bytes, SSIM 1.000000 every frame, both GPUs.

GPU tile=0 tile=1 Δ
Intel Arc A380 ~12.2 s ~7.5 s −38 % (1.6×)
NVIDIA RTX 4090 ~1.2–1.5 s ~1.25–1.6 s ~neutral

The win tracks bandwidth pressure (ADR-0134 profile) → default off, opt-in for weak/integrated/mobile GPUs + tune=anime.

Deliverables

ADR-0139 (Accepted) + index, dehalo.md tile row, changelog, regenerated patch 0014. Fast gate 11/11 (the .comp compiles).

The second filter to adopt the ADR-0134 tiling idiom — premise-checked first (the aa ALU-bound refutation + this fetch-bound confirmation map which kernels the pattern fits).

🤖 Generated with Claude Code

…-0139)

dehalo's box_blur re-reads an overlapping 17x17 window ~5x per pixel (centre +
L/R/U/D cross) -> ~1445 imageLoads/px with trivial ALU. A premise-check confirmed
it is FETCH-bound (an ALU-strip that keeps the loop trip-count but cuts each
box-blur to one load collapsed Arc rtime 11.5s -> 3.4s, -70%) -- the opposite of
the aa sobel kernel (ALU-bound, tiling refuted).

Add an opt-in `tile` option (default 0). tile=1 has the 32x32 workgroup
cooperatively load its output region + a MAX_R+1 halo (covering the union of the
five box-blur windows + the Sobel/contrast 3x3 + the ring scan) into a shared
float array once per plane; pel_luma then reads shared memory. The tile load runs
in uniform control flow before the per-thread IS_WITHIN guard so its barriers are
workgroup-uniform; the tiled read mirrors the direct edge-clamp exactly, so tile=1
is bit-identical. pelorus_dehalo.comp kept in lockstep.

Validated (8x-chained, blur=8, 1080p, warm): tile=1 bit-identical to tile=0 (cmp
0 bytes, SSIM 1.000000 both GPUs); Arc A380 12.2s -> 7.5s (-38%, 1.6x), 4090
~neutral. The ADR-0134 denoise-tiling idiom applied to its fetch-bound twin.
Default off (flagship-first); tune=anime + weak/integrated/mobile GPUs enable it.
Regenerates patch 0014.

ADR: docs/adr/0139-dehalo-shared-mem-tile.md (Accepted)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@lusoris
lusoris merged commit b27a0e9 into master Jun 27, 2026
3 checks passed
@lusoris
lusoris deleted the feat/dehalo-tile branch June 27, 2026 15:41
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