@@ -504,52 +504,40 @@ VoxelGI::VoxelGI(Scene::ptr& scene) :scene(scene), VariableContext(L"VoxelGI")
504504 compute.set_signature (Layouts::DefaultLayout);
505505 context.graph ->set_slot (SlotID::VoxelInfo, compute);
506506
507- compute.set_pipeline <PSOS ::VoxelZero>();
507+ const uint mip_levels = tex_lighting.tex_result ->get_desc ().as_texture ().MipLevels ;
508+
508509 {
509- PROFILE_GPU (L" ZERO" );
510- for (uint i = 1 ; i < tex_lighting.tex_result ->get_desc ().as_texture ().MipLevels ; i++)
511- {
510+ // Only the tail mips without a tile list (packed) still need a
511+ // clear — they are never downsampled and the cone trace samples
512+ // them at high LODs. Tiny textures, cost is negligible.
513+ PROFILE_GPU (L" clear tail mips" );
514+ for (uint i = 1 ; i < mip_levels; i++)
512515 if (i >= gpu_tiles_buffer.size () || !gpu_tiles_buffer[i])
513- {
514516 list.clear_uav (tex_lighting.tex_result ->texture_3d ().mips [i].rwTexture3D ,
515517 vec4 (0 , 0 , 0 , 0 ));
516- continue ;
517- }
518-
519- {
520- Slots::VoxelZero utils;
521- utils.GetTarget () = tex_lighting.tex_result ->texture_3d ().mips [i].rwTexture3D ;
522- auto & params = utils.GetParams ();
523- params.GetTiles () = gpu_tiles_buffer[i]->buffer ;
524- params.GetVoxels_per_tile ().xyz =
525- tex_lighting.tex_result ->resource ->get_tiled_manager ().get_tile_shape ();
526- compute.set (utils);
527- }
528-
529- compute.exec_indirect (gpu_tiles_buffer[i]->dispatch_buffer , 1 );
530- }
531518 }
532519
533520 {
521+ // One dispatch per mip over that mip's OWN tile list: every texel
522+ // of every loaded tile is written, and unmapped source tiles read
523+ // as 0 — so the old per-tile VoxelZero pre-pass is unnecessary.
524+ // (The old 3-mips-per-dispatch batches covered mips 2,3,5,6 only
525+ // under loaded finer tiles, which is what the zero pass patched.)
534526 PROFILE_GPU (L" EXEC" );
535- unsigned int mip_count = 1 ;
536- while (mip_count < tex_lighting.tex_result ->get_desc ().as_texture ().MipLevels )
527+ compute.set_pipeline <PSOS ::VoxelDownsample>(PSOS::VoxelDownsample::Count (1 ));
528+
529+ for (uint mip = 1 ; mip < mip_levels; mip++)
537530 {
538- if (!gpu_tiles_buffer[mip_count]) break ;
539- unsigned int current_mips = std::min (
540- 3u , tex_lighting.tex_result ->get_desc ().as_texture ().MipLevels - mip_count);
541- compute.set_pipeline <PSOS ::VoxelDownsample>(
542- PSOS::VoxelDownsample::Count (current_mips));
531+ if (mip >= gpu_tiles_buffer.size () || !gpu_tiles_buffer[mip]) break ;
543532
544533 {
545534 Slots::VoxelMipMap mipmapping;
546535 mipmapping.GetSrcMip () =
547- tex_lighting.tex_result ->texture_3d ().mips [mip_count - 1 ].texture3D ;
548- for (unsigned int i = 0 ; i < current_mips; i++)
549- mipmapping.GetOutMips ()[i] =
550- tex_lighting.tex_result ->texture_3d ().mips [mip_count + i].rwTexture3D ;
536+ tex_lighting.tex_result ->texture_3d ().mips [mip - 1 ].texture3D ;
537+ mipmapping.GetOutMips ()[0 ] =
538+ tex_lighting.tex_result ->texture_3d ().mips [mip].rwTexture3D ;
551539 auto & params = mipmapping.GetParams ();
552- params.GetTiles () = gpu_tiles_buffer[mip_count ]->buffer ;
540+ params.GetTiles () = gpu_tiles_buffer[mip ]->buffer ;
553541 params.GetVoxels_per_tile ().xyz =
554542 tex_lighting.tex_result ->resource ->get_tiled_manager ().get_tile_shape ();
555543 compute.set (mipmapping);
@@ -560,9 +548,8 @@ VoxelGI::VoxelGI(Scene::ptr& scene) :scene(scene), VariableContext(L"VoxelGI")
560548 L" mip_8" , L" mip_9" , L" mip_10" , L" mip_11" ,
561549 L" mip_12" , L" mip_13" , L" mip_14" , L" mip_15" ,
562550 };
563- PROFILE_GPU (mip_names[mip_count < 16 ? mip_count : 0 ]);
564- compute.exec_indirect (gpu_tiles_buffer[mip_count]->dispatch_buffer , 1 );
565- mip_count += current_mips;
551+ PROFILE_GPU (mip_names[mip < 16 ? mip : 0 ]);
552+ compute.exec_indirect (gpu_tiles_buffer[mip]->dispatch_buffer , 1 );
566553 }
567554 }
568555 };
0 commit comments