ispc_texcomp/
bc6h.rs

1use more_asserts::assert_ge;
2
3use crate::bindings::kernel;
4use crate::RgbaSurface;
5
6#[derive(Debug, Copy, Clone)]
7pub struct EncodeSettings {
8    pub slow_mode: bool,
9    pub fast_mode: bool,
10    pub refine_iterations_1p: u32,
11    pub refine_iterations_2p: u32,
12    pub fast_skip_threshold: u32,
13}
14
15#[inline(always)]
16pub fn calc_output_size(width: u32, height: u32) -> usize {
17    // BC6H uses a fixed block size of 16 bytes (128 bits) and a fixed tile size of 4x4 texels.
18    let block_count = crate::cal_block_count(width, height, 4, 4) as usize;
19    block_count * 16
20}
21
22pub fn compress_blocks(settings: &EncodeSettings, surface: &RgbaSurface) -> Vec<u8> {
23    let output_size = calc_output_size(surface.width, surface.height);
24    let mut output = vec![0u8; output_size];
25    compress_blocks_into(settings, surface, &mut output);
26    output
27}
28
29pub fn compress_blocks_into(settings: &EncodeSettings, surface: &RgbaSurface, blocks: &mut [u8]) {
30    assert_ge!(
31        blocks.len(),
32        calc_output_size(surface.width, surface.height)
33    );
34    let mut surface = kernel::rgba_surface {
35        width: surface.width as i32,
36        height: surface.height as i32,
37        stride: surface.stride as i32,
38        ptr: surface.data.as_ptr() as *mut u8,
39    };
40    let mut settings = kernel::bc6h_enc_settings {
41        slow_mode: settings.slow_mode,
42        fast_mode: settings.fast_mode,
43        refineIterations_1p: settings.refine_iterations_1p as i32,
44        refineIterations_2p: settings.refine_iterations_2p as i32,
45        fastSkipTreshold: settings.fast_skip_threshold as i32,
46    };
47
48    unsafe {
49        kernel::CompressBlocksBC6H_ispc(&mut surface, blocks.as_mut_ptr(), &mut settings);
50    }
51}
52
53#[inline(always)]
54pub fn very_fast_settings() -> EncodeSettings {
55    EncodeSettings {
56        slow_mode: false,
57        fast_mode: true,
58        fast_skip_threshold: 0,
59        refine_iterations_1p: 0,
60        refine_iterations_2p: 0,
61    }
62}
63
64#[inline(always)]
65pub fn fast_settings() -> EncodeSettings {
66    EncodeSettings {
67        slow_mode: false,
68        fast_mode: true,
69        fast_skip_threshold: 2,
70        refine_iterations_1p: 0,
71        refine_iterations_2p: 1,
72    }
73}
74
75#[inline(always)]
76pub fn basic_settings() -> EncodeSettings {
77    EncodeSettings {
78        slow_mode: false,
79        fast_mode: false,
80        fast_skip_threshold: 4,
81        refine_iterations_1p: 2,
82        refine_iterations_2p: 2,
83    }
84}
85
86#[inline(always)]
87pub fn slow_settings() -> EncodeSettings {
88    EncodeSettings {
89        slow_mode: true,
90        fast_mode: false,
91        fast_skip_threshold: 10,
92        refine_iterations_1p: 2,
93        refine_iterations_2p: 2,
94    }
95}
96
97#[inline(always)]
98pub fn very_slow_settings() -> EncodeSettings {
99    EncodeSettings {
100        slow_mode: true,
101        fast_mode: false,
102        fast_skip_threshold: 32,
103        refine_iterations_1p: 2,
104        refine_iterations_2p: 2,
105    }
106}