1#ifdef MESHLET_VISIBILITY_BUFFER_RASTER_PASS_OUTPUT 2@group(0) @binding(0) var<storage, read> mip_0: array<u64>; 4@group(0) @binding(0) var<storage, read> mip_0: array<u32>; 6@group(0) @binding(1) var mip_1: texture_storage_2d<r32float, write>; 7@group(0) @binding(2) var mip_2: texture_storage_2d<r32float, write>; 8@group(0) @binding(3) var mip_3: texture_storage_2d<r32float, write>; 9@group(0) @binding(4) var mip_4: texture_storage_2d<r32float, write>; 10@group(0) @binding(5) var mip_5: texture_storage_2d<r32float, write>; 11@group(0) @binding(6) var mip_6: texture_storage_2d<r32float, read_write>; 12@group(0) @binding(7) var mip_7: texture_storage_2d<r32float, write>; 13@group(0) @binding(8) var mip_8: texture_storage_2d<r32float, write>; 14@group(0) @binding(9) var mip_9: texture_storage_2d<r32float, write>; 15@group(0) @binding(10) var mip_10: texture_storage_2d<r32float, write>; 16@group(0) @binding(11) var mip_11: texture_storage_2d<r32float, write>; 17@group(0) @binding(12) var mip_12: texture_storage_2d<r32float, write>; 18@group(0) @binding(13) var samplr: sampler; 19struct Constants { max_mip_level: u32, view_width: u32 } 20var<push_constant> constants: Constants; 29var<workgroup> intermediate_memory: array<array<f32, 16>, 16>; 32@workgroup_size(256, 1, 1) 33fn downsample_depth_first( 34 @builtin(num_workgroups) num_workgroups: vec3u, 35 @builtin(workgroup_id) workgroup_id: vec3u, 36 @builtin(local_invocation_index) local_invocation_index: u32, 38 let sub_xy = remap_for_wave_reduction(local_invocation_index % 64u); 39 let x = sub_xy.x + 8u * ((local_invocation_index >> 6u) % 2u); 40 let y = sub_xy.y + 8u * (local_invocation_index >> 7u); 42 downsample_mips_0_and_1(x, y, workgroup_id.xy, local_invocation_index); 44 downsample_mips_2_to_5(x, y, workgroup_id.xy, local_invocation_index); 48@workgroup_size(256, 1, 1) 49fn downsample_depth_second(@builtin(local_invocation_index) local_invocation_index: u32) { 50 let sub_xy = remap_for_wave_reduction(local_invocation_index % 64u); 51 let x = sub_xy.x + 8u * ((local_invocation_index >> 6u) % 2u); 52 let y = sub_xy.y + 8u * (local_invocation_index >> 7u); 54 downsample_mips_6_and_7(x, y); 56 downsample_mips_8_to_11(x, y, local_invocation_index); 59fn downsample_mips_0_and_1(x: u32, y: u32, workgroup_id: vec2u, local_invocation_index: u32) { 62 var tex = vec2(workgroup_id * 64u) + vec2(x * 2u, y * 2u); 63 var pix = vec2(workgroup_id * 32u) + vec2(x, y); 64 v[0] = reduce_load_mip_0(tex); 65 textureStore(mip_1, pix, vec4(v[0])); 67 tex = vec2(workgroup_id * 64u) + vec2(x * 2u + 32u, y * 2u); 68 pix = vec2(workgroup_id * 32u) + vec2(x + 16u, y); 69 v[1] = reduce_load_mip_0(tex); 70 textureStore(mip_1, pix, vec4(v[1])); 72 tex = vec2(workgroup_id * 64u) + vec2(x * 2u, y * 2u + 32u); 73 pix = vec2(workgroup_id * 32u) + vec2(x, y + 16u); 74 v[2] = reduce_load_mip_0(tex); 75 textureStore(mip_1, pix, vec4(v[2])); 77 tex = vec2(workgroup_id * 64u) + vec2(x * 2u + 32u, y * 2u + 32u); 78 pix = vec2(workgroup_id * 32u) + vec2(x + 16u, y + 16u); 79 v[3] = reduce_load_mip_0(tex); 80 textureStore(mip_1, pix, vec4(v[3])); 82 if constants.max_mip_level <= 1u { return; } 84 for (var i = 0u; i < 4u; i++) { 85 intermediate_memory[x][y] = v[i]; 87 if local_invocation_index < 64u { 89 intermediate_memory[x * 2u + 0u][y * 2u + 0u], 90 intermediate_memory[x * 2u + 1u][y * 2u + 0u], 91 intermediate_memory[x * 2u + 0u][y * 2u + 1u], 92 intermediate_memory[x * 2u + 1u][y * 2u + 1u], 94 pix = (workgroup_id * 16u) + vec2( 98 textureStore(mip_2, pix, vec4(v[i])); 103 if local_invocation_index < 64u { 104 intermediate_memory[x + 0u][y + 0u] = v[0]; 105 intermediate_memory[x + 8u][y + 0u] = v[1]; 106 intermediate_memory[x + 0u][y + 8u] = v[2]; 107 intermediate_memory[x + 8u][y + 8u] = v[3]; 111fn downsample_mips_2_to_5(x: u32, y: u32, workgroup_id: vec2u, local_invocation_index: u32) { 112 if constants.max_mip_level <= 2u { return; } 114 downsample_mip_2(x, y, workgroup_id, local_invocation_index); 116 if constants.max_mip_level <= 3u { return; } 118 downsample_mip_3(x, y, workgroup_id, local_invocation_index); 120 if constants.max_mip_level <= 4u { return; } 122 downsample_mip_4(x, y, workgroup_id, local_invocation_index); 124 if constants.max_mip_level <= 5u { return; } 126 downsample_mip_5(workgroup_id, local_invocation_index); 129fn downsample_mip_2(x: u32, y: u32, workgroup_id: vec2u, local_invocation_index: u32) { 130 if local_invocation_index < 64u { 131 let v = reduce_4(vec4( 132 intermediate_memory[x * 2u + 0u][y * 2u + 0u], 133 intermediate_memory[x * 2u + 1u][y * 2u + 0u], 134 intermediate_memory[x * 2u + 0u][y * 2u + 1u], 135 intermediate_memory[x * 2u + 1u][y * 2u + 1u], 137 textureStore(mip_3, (workgroup_id * 8u) + vec2(x, y), vec4(v)); 138 intermediate_memory[x * 2u + y % 2u][y * 2u] = v; 142fn downsample_mip_3(x: u32, y: u32, workgroup_id: vec2u, local_invocation_index: u32) { 143 if local_invocation_index < 16u { 144 let v = reduce_4(vec4( 145 intermediate_memory[x * 4u + 0u + 0u][y * 4u + 0u], 146 intermediate_memory[x * 4u + 2u + 0u][y * 4u + 0u], 147 intermediate_memory[x * 4u + 0u + 1u][y * 4u + 2u], 148 intermediate_memory[x * 4u + 2u + 1u][y * 4u + 2u], 150 textureStore(mip_4, (workgroup_id * 4u) + vec2(x, y), vec4(v)); 151 intermediate_memory[x * 4u + y][y * 4u] = v; 155fn downsample_mip_4(x: u32, y: u32, workgroup_id: vec2u, local_invocation_index: u32) { 156 if local_invocation_index < 4u { 157 let v = reduce_4(vec4( 158 intermediate_memory[x * 8u + 0u + 0u + y * 2u][y * 8u + 0u], 159 intermediate_memory[x * 8u + 4u + 0u + y * 2u][y * 8u + 0u], 160 intermediate_memory[x * 8u + 0u + 1u + y * 2u][y * 8u + 4u], 161 intermediate_memory[x * 8u + 4u + 1u + y * 2u][y * 8u + 4u], 163 textureStore(mip_5, (workgroup_id * 2u) + vec2(x, y), vec4(v)); 164 intermediate_memory[x + y * 2u][0u] = v; 168fn downsample_mip_5(workgroup_id: vec2u, local_invocation_index: u32) { 169 if local_invocation_index < 1u { 170 let v = reduce_4(vec4( 171 intermediate_memory[0u][0u], 172 intermediate_memory[1u][0u], 173 intermediate_memory[2u][0u], 174 intermediate_memory[3u][0u], 176 textureStore(mip_6, workgroup_id, vec4(v)); 180fn downsample_mips_6_and_7(x: u32, y: u32) { 183 var tex = vec2(x * 4u + 0u, y * 4u + 0u); 184 var pix = vec2(x * 2u + 0u, y * 2u + 0u); 185 v[0] = reduce_load_mip_6(tex); 186 textureStore(mip_7, pix, vec4(v[0])); 188 tex = vec2(x * 4u + 2u, y * 4u + 0u); 189 pix = vec2(x * 2u + 1u, y * 2u + 0u); 190 v[1] = reduce_load_mip_6(tex); 191 textureStore(mip_7, pix, vec4(v[1])); 193 tex = vec2(x * 4u + 0u, y * 4u + 2u); 194 pix = vec2(x * 2u + 0u, y * 2u + 1u); 195 v[2] = reduce_load_mip_6(tex); 196 textureStore(mip_7, pix, vec4(v[2])); 198 tex = vec2(x * 4u + 2u, y * 4u + 2u); 199 pix = vec2(x * 2u + 1u, y * 2u + 1u); 200 v[3] = reduce_load_mip_6(tex); 201 textureStore(mip_7, pix, vec4(v[3])); 203 if constants.max_mip_level <= 7u { return; } 205 let vr = reduce_4(v); 206 textureStore(mip_8, vec2(x, y), vec4(vr)); 207 intermediate_memory[x][y] = vr; 210fn downsample_mips_8_to_11(x: u32, y: u32, local_invocation_index: u32) { 211 if constants.max_mip_level <= 8u { return; } 213 downsample_mip_8(x, y, local_invocation_index); 215 if constants.max_mip_level <= 9u { return; } 217 downsample_mip_9(x, y, local_invocation_index); 219 if constants.max_mip_level <= 10u { return; } 221 downsample_mip_10(x, y, local_invocation_index); 223 if constants.max_mip_level <= 11u { return; } 225 downsample_mip_11(local_invocation_index); 228fn downsample_mip_8(x: u32, y: u32, local_invocation_index: u32) { 229 if local_invocation_index < 64u { 230 let v = reduce_4(vec4( 231 intermediate_memory[x * 2u + 0u][y * 2u + 0u], 232 intermediate_memory[x * 2u + 1u][y * 2u + 0u], 233 intermediate_memory[x * 2u + 0u][y * 2u + 1u], 234 intermediate_memory[x * 2u + 1u][y * 2u + 1u], 236 textureStore(mip_9, vec2(x, y), vec4(v)); 237 intermediate_memory[x * 2u + y % 2u][y * 2u] = v; 241fn downsample_mip_9(x: u32, y: u32, local_invocation_index: u32) { 242 if local_invocation_index < 16u { 243 let v = reduce_4(vec4( 244 intermediate_memory[x * 4u + 0u + 0u][y * 4u + 0u], 245 intermediate_memory[x * 4u + 2u + 0u][y * 4u + 0u], 246 intermediate_memory[x * 4u + 0u + 1u][y * 4u + 2u], 247 intermediate_memory[x * 4u + 2u + 1u][y * 4u + 2u], 249 textureStore(mip_10, vec2(x, y), vec4(v)); 250 intermediate_memory[x * 4u + y][y * 4u] = v; 254fn downsample_mip_10(x: u32, y: u32, local_invocation_index: u32) { 255 if local_invocation_index < 4u { 256 let v = reduce_4(vec4( 257 intermediate_memory[x * 8u + 0u + 0u + y * 2u][y * 8u + 0u], 258 intermediate_memory[x * 8u + 4u + 0u + y * 2u][y * 8u + 0u], 259 intermediate_memory[x * 8u + 0u + 1u + y * 2u][y * 8u + 4u], 260 intermediate_memory[x * 8u + 4u + 1u + y * 2u][y * 8u + 4u], 262 textureStore(mip_11, vec2(x, y), vec4(v)); 263 intermediate_memory[x + y * 2u][0u] = v; 267fn downsample_mip_11(local_invocation_index: u32) { 268 if local_invocation_index < 1u { 269 let v = reduce_4(vec4( 270 intermediate_memory[0u][0u], 271 intermediate_memory[1u][0u], 272 intermediate_memory[2u][0u], 273 intermediate_memory[3u][0u], 275 textureStore(mip_12, vec2(0u, 0u), vec4(v)); 279fn remap_for_wave_reduction(a: u32) -> vec2u { 281 insertBits(extractBits(a, 2u, 3u), a, 0u, 1u), 282 insertBits(extractBits(a, 3u, 3u), extractBits(a, 1u, 2u), 0u, 2u), 286fn reduce_load_mip_0(tex: vec2u) -> f32 { 287 let a = load_mip_0(tex.x, tex.y); 288 let b = load_mip_0(tex.x + 1u, tex.y); 289 let c = load_mip_0(tex.x, tex.y + 1u); 290 let d = load_mip_0(tex.x + 1u, tex.y + 1u); 291 return reduce_4(vec4(a, b, c, d)); 294fn reduce_load_mip_6(tex: vec2u) -> f32 { 295 return reduce_4(vec4( 296 textureLoad(mip_6, tex + vec2(0u, 0u)).r, 297 textureLoad(mip_6, tex + vec2(0u, 1u)).r, 298 textureLoad(mip_6, tex + vec2(1u, 0u)).r, 299 textureLoad(mip_6, tex + vec2(1u, 1u)).r, 303fn load_mip_0(x: u32, y: u32) -> f32 { 304 let i = y * constants.view_width + x; 305#ifdef MESHLET_VISIBILITY_BUFFER_RASTER_PASS_OUTPUT 306 return bitcast<f32>(u32(mip_0[i] >> 32u)); 308 return bitcast<f32>(mip_0[i]); 312fn reduce_4(v: vec4f) -> f32 { 313 return min(min(v.x, v.y), min(v.z, v.w));