wgsl-compute-comparison-sampling

star 0

textureSampleCompare is fragment-stage-only — compute shaders must use textureSampleCompareLevel with 4 params (no LOD, no offset). Also: bind group layouts must match pipeline stage visibility. When adding passes to shared RONs, all benches inherit them.

Solidor777 By Solidor777 schedule Updated 6/16/2026

name: wgsl-compute-comparison-sampling description: textureSampleCompare is fragment-stage-only — compute shaders must use textureSampleCompareLevel with 4 params (no LOD, no offset). Also: bind group layouts must match pipeline stage visibility. When adding passes to shared RONs, all benches inherit them. source: auto-skill extracted_at: '2026-06-16T01:35:34.704Z'

WGSL Compute Comparison Sampling + Pass Inheritance

Two distinct traps found during scene culling integration (2026-06-15).

Trap 1: textureSampleCompare in compute shaders

textureSampleCompare(t, s, coords, depth_ref) is fragment-stage-only — it uses implicit LOD which requires fragment derivative hardware. Compute shaders must use the explicit-LOD variant:

// WRONG — fragment-only, will fail naga validation:
return textureSampleCompare(vsm_physical_pool, vsm_sampler, phys_uv, depth_ref);

// CORRECT — compute-safe, implicit LOD 0:
return textureSampleCompareLevel(vsm_physical_pool, vsm_sampler, phys_uv, depth_ref);

Why: WGSL § texture builtins: comparison sampling with implicit LOD (textureSampleCompare) requires fragment stage. The Level variant takes an explicit LOD that the return type supports, but with 4 params it defaults to level 0. Do NOT add a 5th 0i param — WGSL interprets the 5th param as a vec2<i32> offset for texture_sample_2d, not as the LOD, and naga rejects it with "Sample offset constant doesn't match the image dimension."

Verification: textureSampleComparetextureSampleCompareLevel in all .wgsl files under crates/. The commit hook at .qwen/local-scripts/rendering_naming_guard.py does not catch this — it blocks proprietary names, not WGSL API misuse. A manual grep at review time is the only gate.

Trap 2: Bind group layout stage visibility mismatch

When creating a simplified pipeline (e.g. depth-only prepass) that reuses a bind group from the main rendering pipeline, the bind group's BGL must match the pipeline's BGL stage visibility:

// WRONG — frame_bind_group() was created with VERTEX|FRAGMENT visibility,
// but the depth prepass pipeline expects VERTEX-only at group 0:
rp.set_bind_group(0, self.viewport.frame_bind_group(), &[]);

// CORRECT — create a dedicated camera BG matching the pipeline's BGL:
let cam_bgl = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
    entries: &[wgpu::BindGroupLayoutEntry {
        binding: 0,
        visibility: wgpu::ShaderStages::VERTEX,  // match the pipeline
        ty: wgpu::BindingType::Buffer {
            ty: wgpu::BufferBindingType::Uniform,
            has_dynamic_offset: false,
            min_binding_size: None,
        },
        count: None,
    }],
    label: Some("depth_prepass camera bgl (per-frame)"),
});

Why: wgpu validates BGL compatibility at set_bind_group time. A BGL with VERTEX|FRAGMENT is not compatible with one that has only VERTEX, even if both have the same binding count and types.

Trap 3: Shared RON pass inheritance

When new passes are added to shared RON configs (pipeline_deferred_stratum_mid.ron, etc.), ALL benches that use those configs inherit the passes. If a bench doesn't populate the pass-specific data structures (e.g. SceneCullData), the dispatch arm must gracefully fall through:

// Required pattern for every new pass dispatch arm:
if let Some(ref data) = self.pass_specific_data {
    // GPU-driven path
} else {
    // Fallback: warn once and skip, or use legacy path
    self.warn_once_unimplemented_pass("PassName (data not populated)", "boot");
    continue;
}

Verification checklist when adding new passes:

  1. Run cargo run -p titan-render-bench-probe -- --capture-fps 60 --capture-start 0 --capture-end 1 to smoke-test the probe bench
  2. If it crashes, the new pass is interfering with an existing bench
  3. Add fallback path in the dispatch arm
Install via CLI
npx skills add https://github.com/Solidor777/Titan --skill wgsl-compute-comparison-sampling
Repository Details
star Stars 0
call_split Forks 0
navigation Branch main
article Path SKILL.md
More from Creator