1#ifdef MESHLET_VISIBILITY_BUFFER_RASTER_PASS_OUTPUT 2@group(0) @binding(0) var mip_0: texture_storage_2d<r64uint, read>; 5@group(0) @binding(0) var mip_0: texture_storage_2d<r32uint, read>; 8@group(0) @binding(0) var mip_0: texture_depth_multisampled_2d; 10@group(0) @binding(0) var mip_0: texture_depth_2d; 13#endif // MESHLET_VISIBILITY_BUFFER_RASTER_PASS_OUTPUT 14@group(0) @binding(1) var mip_1: texture_storage_2d<r32float, write>; 15@group(0) @binding(2) var mip_2: texture_storage_2d<r32float, write>; 16@group(0) @binding(3) var mip_3: texture_storage_2d<r32float, write>; 17@group(0) @binding(4) var mip_4: texture_storage_2d<r32float, write>; 18@group(0) @binding(5) var mip_5: texture_storage_2d<r32float, write>; 19@group(0) @binding(6) var mip_6: texture_storage_2d<r32float, read_write>; 20@group(0) @binding(7) var mip_7: texture_storage_2d<r32float, write>; 21@group(0) @binding(8) var mip_8: texture_storage_2d<r32float, write>; 22@group(0) @binding(9) var mip_9: texture_storage_2d<r32float, write>; 23@group(0) @binding(10) var mip_10: texture_storage_2d<r32float, write>; 24@group(0) @binding(11) var mip_11: texture_storage_2d<r32float, write>; 25@group(0) @binding(12) var mip_12: texture_storage_2d<r32float, write>; 26@group(0) @binding(13) var samplr: sampler; 27struct Constants { max_mip_level: u32 } 28var<push_constant> constants: Constants; 37var<workgroup> intermediate_memory: array<array<f32, 16>, 16>; 40@workgroup_size(256, 1, 1) 41fn downsample_depth_first( 42 @builtin(workgroup_id) workgroup_id: vec3u, 43 @builtin(local_invocation_index) local_invocation_index: u32, 45 let sub_xy = remap_for_wave_reduction(local_invocation_index % 64u); 46 let x = sub_xy.x + 8u * ((local_invocation_index >> 6u) % 2u); 47 let y = sub_xy.y + 8u * (local_invocation_index >> 7u); 49 downsample_mips_0_and_1(x, y, workgroup_id.xy, local_invocation_index); 51 downsample_mips_2_to_5(x, y, workgroup_id.xy, local_invocation_index); 55@workgroup_size(256, 1, 1) 56fn downsample_depth_second(@builtin(local_invocation_index) local_invocation_index: u32) { 57 let sub_xy = remap_for_wave_reduction(local_invocation_index % 64u); 58 let x = sub_xy.x + 8u * ((local_invocation_index >> 6u) % 2u); 59 let y = sub_xy.y + 8u * (local_invocation_index >> 7u); 61 downsample_mips_6_and_7(x, y); 63 downsample_mips_8_to_11(x, y, local_invocation_index); 66fn downsample_mips_0_and_1(x: u32, y: u32, workgroup_id: vec2u, local_invocation_index: u32) { 69 var tex = vec2(workgroup_id * 64u) + vec2(x * 2u, y * 2u); 70 var pix = vec2(workgroup_id * 32u) + vec2(x, y); 71 v[0] = reduce_load_mip_0(tex); 72 textureStore(mip_1, pix, vec4(v[0])); 74 tex = vec2(workgroup_id * 64u) + vec2(x * 2u + 32u, y * 2u); 75 pix = vec2(workgroup_id * 32u) + vec2(x + 16u, y); 76 v[1] = reduce_load_mip_0(tex); 77 textureStore(mip_1, pix, vec4(v[1])); 79 tex = vec2(workgroup_id * 64u) + vec2(x * 2u, y * 2u + 32u); 80 pix = vec2(workgroup_id * 32u) + vec2(x, y + 16u); 81 v[2] = reduce_load_mip_0(tex); 82 textureStore(mip_1, pix, vec4(v[2])); 84 tex = vec2(workgroup_id * 64u) + vec2(x * 2u + 32u, y * 2u + 32u); 85 pix = vec2(workgroup_id * 32u) + vec2(x + 16u, y + 16u); 86 v[3] = reduce_load_mip_0(tex); 87 textureStore(mip_1, pix, vec4(v[3])); 89 if constants.max_mip_level <= 1u { return; } 91 for (var i = 0u; i < 4u; i++) { 92 intermediate_memory[x][y] = v[i]; 94 if local_invocation_index < 64u { 96 intermediate_memory[x * 2u + 0u][y * 2u + 0u], 97 intermediate_memory[x * 2u + 1u][y * 2u + 0u], 98 intermediate_memory[x * 2u + 0u][y * 2u + 1u], 99 intermediate_memory[x * 2u + 1u][y * 2u + 1u], 101 pix = (workgroup_id * 16u) + vec2( 105 textureStore(mip_2, pix, vec4(v[i])); 110 if local_invocation_index < 64u { 111 intermediate_memory[x + 0u][y + 0u] = v[0]; 112 intermediate_memory[x + 8u][y + 0u] = v[1]; 113 intermediate_memory[x + 0u][y + 8u] = v[2]; 114 intermediate_memory[x + 8u][y + 8u] = v[3]; 118fn downsample_mips_2_to_5(x: u32, y: u32, workgroup_id: vec2u, local_invocation_index: u32) { 119 if constants.max_mip_level <= 2u { return; } 121 downsample_mip_2(x, y, workgroup_id, local_invocation_index); 123 if constants.max_mip_level <= 3u { return; } 125 downsample_mip_3(x, y, workgroup_id, local_invocation_index); 127 if constants.max_mip_level <= 4u { return; } 129 downsample_mip_4(x, y, workgroup_id, local_invocation_index); 131 if constants.max_mip_level <= 5u { return; } 133 downsample_mip_5(workgroup_id, local_invocation_index); 136fn downsample_mip_2(x: u32, y: u32, workgroup_id: vec2u, local_invocation_index: u32) { 137 if local_invocation_index < 64u { 138 let v = reduce_4(vec4( 139 intermediate_memory[x * 2u + 0u][y * 2u + 0u], 140 intermediate_memory[x * 2u + 1u][y * 2u + 0u], 141 intermediate_memory[x * 2u + 0u][y * 2u + 1u], 142 intermediate_memory[x * 2u + 1u][y * 2u + 1u], 144 textureStore(mip_3, (workgroup_id * 8u) + vec2(x, y), vec4(v)); 145 intermediate_memory[x * 2u + y % 2u][y * 2u] = v; 149fn downsample_mip_3(x: u32, y: u32, workgroup_id: vec2u, local_invocation_index: u32) { 150 if local_invocation_index < 16u { 151 let v = reduce_4(vec4( 152 intermediate_memory[x * 4u + 0u + 0u][y * 4u + 0u], 153 intermediate_memory[x * 4u + 2u + 0u][y * 4u + 0u], 154 intermediate_memory[x * 4u + 0u + 1u][y * 4u + 2u], 155 intermediate_memory[x * 4u + 2u + 1u][y * 4u + 2u], 157 textureStore(mip_4, (workgroup_id * 4u) + vec2(x, y), vec4(v)); 158 intermediate_memory[x * 4u + y][y * 4u] = v; 162fn downsample_mip_4(x: u32, y: u32, workgroup_id: vec2u, local_invocation_index: u32) { 163 if local_invocation_index < 4u { 164 let v = reduce_4(vec4( 165 intermediate_memory[x * 8u + 0u + 0u + y * 2u][y * 8u + 0u], 166 intermediate_memory[x * 8u + 4u + 0u + y * 2u][y * 8u + 0u], 167 intermediate_memory[x * 8u + 0u + 1u + y * 2u][y * 8u + 4u], 168 intermediate_memory[x * 8u + 4u + 1u + y * 2u][y * 8u + 4u], 170 textureStore(mip_5, (workgroup_id * 2u) + vec2(x, y), vec4(v)); 171 intermediate_memory[x + y * 2u][0u] = v; 175fn downsample_mip_5(workgroup_id: vec2u, local_invocation_index: u32) { 176 if local_invocation_index < 1u { 177 let v = reduce_4(vec4( 178 intermediate_memory[0u][0u], 179 intermediate_memory[1u][0u], 180 intermediate_memory[2u][0u], 181 intermediate_memory[3u][0u], 183 textureStore(mip_6, workgroup_id, vec4(v)); 187fn downsample_mips_6_and_7(x: u32, y: u32) { 190 var tex = vec2(x * 4u + 0u, y * 4u + 0u); 191 var pix = vec2(x * 2u + 0u, y * 2u + 0u); 192 v[0] = reduce_load_mip_6(tex); 193 textureStore(mip_7, pix, vec4(v[0])); 195 tex = vec2(x * 4u + 2u, y * 4u + 0u); 196 pix = vec2(x * 2u + 1u, y * 2u + 0u); 197 v[1] = reduce_load_mip_6(tex); 198 textureStore(mip_7, pix, vec4(v[1])); 200 tex = vec2(x * 4u + 0u, y * 4u + 2u); 201 pix = vec2(x * 2u + 0u, y * 2u + 1u); 202 v[2] = reduce_load_mip_6(tex); 203 textureStore(mip_7, pix, vec4(v[2])); 205 tex = vec2(x * 4u + 2u, y * 4u + 2u); 206 pix = vec2(x * 2u + 1u, y * 2u + 1u); 207 v[3] = reduce_load_mip_6(tex); 208 textureStore(mip_7, pix, vec4(v[3])); 210 if constants.max_mip_level <= 7u { return; } 212 let vr = reduce_4(v); 213 textureStore(mip_8, vec2(x, y), vec4(vr)); 214 intermediate_memory[x][y] = vr; 217fn downsample_mips_8_to_11(x: u32, y: u32, local_invocation_index: u32) { 218 if constants.max_mip_level <= 8u { return; } 220 downsample_mip_8(x, y, local_invocation_index); 222 if constants.max_mip_level <= 9u { return; } 224 downsample_mip_9(x, y, local_invocation_index); 226 if constants.max_mip_level <= 10u { return; } 228 downsample_mip_10(x, y, local_invocation_index); 230 if constants.max_mip_level <= 11u { return; } 232 downsample_mip_11(local_invocation_index); 235fn downsample_mip_8(x: u32, y: u32, local_invocation_index: u32) { 236 if local_invocation_index < 64u { 237 let v = reduce_4(vec4( 238 intermediate_memory[x * 2u + 0u][y * 2u + 0u], 239 intermediate_memory[x * 2u + 1u][y * 2u + 0u], 240 intermediate_memory[x * 2u + 0u][y * 2u + 1u], 241 intermediate_memory[x * 2u + 1u][y * 2u + 1u], 243 textureStore(mip_9, vec2(x, y), vec4(v)); 244 intermediate_memory[x * 2u + y % 2u][y * 2u] = v; 248fn downsample_mip_9(x: u32, y: u32, local_invocation_index: u32) { 249 if local_invocation_index < 16u { 250 let v = reduce_4(vec4( 251 intermediate_memory[x * 4u + 0u + 0u][y * 4u + 0u], 252 intermediate_memory[x * 4u + 2u + 0u][y * 4u + 0u], 253 intermediate_memory[x * 4u + 0u + 1u][y * 4u + 2u], 254 intermediate_memory[x * 4u + 2u + 1u][y * 4u + 2u], 256 textureStore(mip_10, vec2(x, y), vec4(v)); 257 intermediate_memory[x * 4u + y][y * 4u] = v; 261fn downsample_mip_10(x: u32, y: u32, local_invocation_index: u32) { 262 if local_invocation_index < 4u { 263 let v = reduce_4(vec4( 264 intermediate_memory[x * 8u + 0u + 0u + y * 2u][y * 8u + 0u], 265 intermediate_memory[x * 8u + 4u + 0u + y * 2u][y * 8u + 0u], 266 intermediate_memory[x * 8u + 0u + 1u + y * 2u][y * 8u + 4u], 267 intermediate_memory[x * 8u + 4u + 1u + y * 2u][y * 8u + 4u], 269 textureStore(mip_11, vec2(x, y), vec4(v)); 270 intermediate_memory[x + y * 2u][0u] = v; 274fn downsample_mip_11(local_invocation_index: u32) { 275 if local_invocation_index < 1u { 276 let v = reduce_4(vec4( 277 intermediate_memory[0u][0u], 278 intermediate_memory[1u][0u], 279 intermediate_memory[2u][0u], 280 intermediate_memory[3u][0u], 282 textureStore(mip_12, vec2(0u, 0u), vec4(v)); 286fn remap_for_wave_reduction(a: u32) -> vec2u { 288 insertBits(extractBits(a, 2u, 3u), a, 0u, 1u), 289 insertBits(extractBits(a, 3u, 3u), extractBits(a, 1u, 2u), 0u, 2u), 293fn reduce_load_mip_0(tex: vec2u) -> f32 { 294 let a = load_mip_0(tex.x, tex.y); 295 let b = load_mip_0(tex.x + 1u, tex.y); 296 let c = load_mip_0(tex.x, tex.y + 1u); 297 let d = load_mip_0(tex.x + 1u, tex.y + 1u); 298 return reduce_4(vec4(a, b, c, d)); 301fn reduce_load_mip_6(tex: vec2u) -> f32 { 302 return reduce_4(vec4( 303 textureLoad(mip_6, tex + vec2(0u, 0u)).r, 304 textureLoad(mip_6, tex + vec2(0u, 1u)).r, 305 textureLoad(mip_6, tex + vec2(1u, 0u)).r, 306 textureLoad(mip_6, tex + vec2(1u, 1u)).r, 310fn load_mip_0(x: u32, y: u32) -> f32 { 311#ifdef MESHLET_VISIBILITY_BUFFER_RASTER_PASS_OUTPUT 312 let visibility = textureLoad(mip_0, vec2(x, y)).r; 313 return bitcast<f32>(u32(visibility >> 32u)); 314#else // MESHLET_VISIBILITY_BUFFER_RASTER_PASS_OUTPUT 316 let visibility = textureLoad(mip_0, vec2(x, y)).r; 317 return bitcast<f32>(visibility); 323 var result = textureLoad(mip_0, vec2(x, y), 0); 324 let sample_count = i32(textureNumSamples(mip_0)); 325 for (var sample = 1; sample < sample_count; sample += 1) { 326 result = min(result, textureLoad(mip_0, vec2(x, y), sample)); 330 return textureLoad(mip_0, vec2(x, y), 0); 333#endif // MESHLET_VISIBILITY_BUFFER_RASTER_PASS_OUTPUT 336fn reduce_4(v: vec4f) -> f32 { 337 return min(min(v.x, v.y), min(v.z, v.w));