diff --git a/crates/horizon-client/src/gfx.rs b/crates/horizon-client/src/gfx.rs index b2dd58247..b22a66280 100644 --- a/crates/horizon-client/src/gfx.rs +++ b/crates/horizon-client/src/gfx.rs @@ -3197,7 +3197,7 @@ impl Renderer { /// The Mipmap Levels option: block textures sample at most `levels` /// reduced copies (0: none). pub fn set_mipmap_levels(&mut self, levels: u32) { - let levels = sprite_mipmap_limit( + let levels = crate::sprites::sprite_mipmap_limit( levels, self.sprite_textures[0].width(), self.sprite_minimum_size, @@ -5479,11 +5479,6 @@ mod tests { } } -pub(crate) fn sprite_mipmap_limit(requested: u32, size: u32, minimum: u32, available: u32) -> u32 { - // Only the atlas native minimum determines how many resampling-only mips to skip. - let upscale = (size / minimum.max(1)).max(1).ilog2(); - requested.saturating_add(upscale).min(available - 1) -} #[cfg(test)] mod sprite_upload_tests { use super::*; @@ -5544,13 +5539,6 @@ mod sprite_upload_tests { } } #[test] - fn mipmap_option_keeps_real_16px_reductions() { - for levels in 0..=4 { - assert_eq!(sprite_mipmap_limit(levels, 32, 16, 6), levels + 1); - assert_eq!(sprite_mipmap_limit(levels, 16, 16, 5), levels); - } - } - #[test] fn prepared_texture_uploads_preserve_layer_order_and_settings() { let size = 4; let layers = 5; diff --git a/crates/horizon-client/src/sprites.rs b/crates/horizon-client/src/sprites.rs index 6d754894a..b720c5bfd 100644 --- a/crates/horizon-client/src/sprites.rs +++ b/crates/horizon-client/src/sprites.rs @@ -342,10 +342,25 @@ pub(crate) fn test_frames(layer: u32, frames: Vec>, metadata: &str) -> S } } +/// How many reduced copies a sprite atlas keeps: the Mipmap Levels option plus the +/// resampling-only levels an upscaled pack needs, within what the atlas holds. +pub(crate) fn sprite_mipmap_limit(requested: u32, size: u32, minimum: u32, available: u32) -> u32 { + // Only the atlas native minimum determines how many resampling-only mips to skip. + let upscale = (size / minimum.max(1)).max(1).ilog2(); + requested.saturating_add(upscale).min(available - 1) +} + #[cfg(test)] mod tests { use super::*; #[test] + fn mipmap_option_keeps_real_16px_reductions() { + for levels in 0..=4 { + assert_eq!(sprite_mipmap_limit(levels, 32, 16, 6), levels + 1); + assert_eq!(sprite_mipmap_limit(levels, 16, 16, 5), levels); + } + } + #[test] fn identical_still_textures_share_a_layer() { let root = std::env::temp_dir().join(format!("horizon-sprite-share-{}", std::process::id())); @@ -398,7 +413,7 @@ mod tests { assert_eq!((sprites.size, sprites.minimum_size), (32, 32)); for level in 0..=4 { assert_eq!( - crate::gfx::sprite_mipmap_limit(level, sprites.size, sprites.minimum_size, 6), + sprite_mipmap_limit(level, sprites.size, sprites.minimum_size, 6), level ); } @@ -408,7 +423,7 @@ mod tests { sprites.finish(); assert_eq!((sprites.size, sprites.minimum_size), (32, 16)); assert_eq!( - crate::gfx::sprite_mipmap_limit(0, sprites.size, sprites.minimum_size, 6), + sprite_mipmap_limit(0, sprites.size, sprites.minimum_size, 6), 1 ); } diff --git a/tools/bench_sprite_mips.py b/tools/bench_sprite_mips.py index 68024d6d2..e2456e3e9 100644 --- a/tools/bench_sprite_mips.py +++ b/tools/bench_sprite_mips.py @@ -52,7 +52,9 @@ def main(): baseline = subprocess.check_output(['git', 'show', '89b58991bbc02eb79b6965fc4ca56357fe2297d9:crates/horizon-client/src/gfx.rs'], cwd=ROOT, text=True) code += '\n' + function(baseline, 'animate_sprites').replace('fn animate_sprites(', 'fn reference_animate_sprites(', 1) if args.test: - code += '\n' + function(source, 'sprite_mipmap_limit') + # sprites.rs holds it since the gfx -> sprites cut; older refs kept it in gfx.rs. + code += '\n' + (function(source, 'sprite_mipmap_limit') if 'fn sprite_mipmap_limit' in source + else 'use sprites::sprite_mipmap_limit;') code += '\n' + source[source.index('#[cfg(test)]\nmod sprite_upload_tests'):] modules = '\n'.join(f'#[path = {json.dumps(str(ROOT / "crates/horizon-client/src" / (name + ".rs")))}] mod {name};' for name in ('mipmap', 'sprites', 'fast_hash'))