1use more_asserts::assert_ge;
2
3use crate::bindings::kernel;
4use crate::RgbaSurface;
5
6#[derive(Debug, Copy, Clone)]
7pub struct EncodeSettings {
8 pub mode_selection: [bool; 4usize],
9 pub refine_iterations: [u32; 8usize],
10 pub skip_mode2: bool,
11 pub fast_skip_threshold_mode1: u32,
12 pub fast_skip_threshold_mode3: u32,
13 pub fast_skip_threshold_mode7: u32,
14 pub mode45_channel0: u32,
15 pub refine_iterations_channel: u32,
16 pub channels: i32,
17}
18
19#[inline(always)]
20pub fn calc_output_size(width: u32, height: u32) -> usize {
21 let block_count = crate::cal_block_count(width, height, 4, 4) as usize;
23 block_count * 16
24}
25
26pub fn compress_blocks(settings: &EncodeSettings, surface: &RgbaSurface) -> Vec<u8> {
27 let output_size = calc_output_size(surface.width, surface.height);
28 let mut output = vec![0u8; output_size];
29 compress_blocks_into(settings, surface, &mut output);
30 output
31}
32
33pub fn compress_blocks_into(settings: &EncodeSettings, surface: &RgbaSurface, blocks: &mut [u8]) {
34 assert_ge!(
35 blocks.len(),
36 calc_output_size(surface.width, surface.height)
37 );
38 let mut surface = kernel::rgba_surface {
39 width: surface.width as i32,
40 height: surface.height as i32,
41 stride: surface.stride as i32,
42 ptr: surface.data.as_ptr() as *mut u8,
43 };
44 let mut settings = kernel::bc7_enc_settings {
45 mode_selection: settings.mode_selection,
46 refineIterations: [
47 settings.refine_iterations[0] as i32,
48 settings.refine_iterations[1] as i32,
49 settings.refine_iterations[2] as i32,
50 settings.refine_iterations[3] as i32,
51 settings.refine_iterations[4] as i32,
52 settings.refine_iterations[5] as i32,
53 settings.refine_iterations[6] as i32,
54 settings.refine_iterations[7] as i32,
55 ],
56 skip_mode2: settings.skip_mode2,
57 fastSkipTreshold_mode1: settings.fast_skip_threshold_mode1 as i32,
58 fastSkipTreshold_mode3: settings.fast_skip_threshold_mode3 as i32,
59 fastSkipTreshold_mode7: settings.fast_skip_threshold_mode7 as i32,
60 mode45_channel0: settings.mode45_channel0 as i32,
61 refineIterations_channel: settings.refine_iterations_channel as i32,
62 channels: settings.channels as i32,
63 };
64
65 unsafe {
66 kernel::CompressBlocksBC7_ispc(&mut surface, blocks.as_mut_ptr(), &mut settings);
67 }
68}
69
70#[inline(always)]
71pub fn opaque_ultra_fast_settings() -> EncodeSettings {
72 EncodeSettings {
73 channels: 3,
74 mode_selection: [false, false, false, true],
75 fast_skip_threshold_mode1: 3,
76 fast_skip_threshold_mode3: 1,
77 fast_skip_threshold_mode7: 0,
78 skip_mode2: true,
79 mode45_channel0: 0,
80 refine_iterations_channel: 0,
81 refine_iterations: [2, 2, 2, 1, 2, 2, 1, 0],
82 }
83}
84
85#[inline(always)]
86pub fn opaque_very_fast_settings() -> EncodeSettings {
87 EncodeSettings {
88 channels: 3,
89 mode_selection: [false, true, false, true],
90 fast_skip_threshold_mode1: 3,
91 fast_skip_threshold_mode3: 1,
92 fast_skip_threshold_mode7: 0,
93 skip_mode2: true,
94 mode45_channel0: 0,
95 refine_iterations_channel: 0,
96 refine_iterations: [2, 2, 2, 1, 2, 2, 1, 0],
97 }
98}
99
100#[inline(always)]
101pub fn opaque_fast_settings() -> EncodeSettings {
102 EncodeSettings {
103 channels: 3,
104 mode_selection: [false, true, false, true],
105 fast_skip_threshold_mode1: 12,
106 fast_skip_threshold_mode3: 4,
107 fast_skip_threshold_mode7: 0,
108 skip_mode2: true,
109 mode45_channel0: 0,
110 refine_iterations_channel: 0,
111 refine_iterations: [2, 2, 2, 1, 2, 2, 2, 0],
112 }
113}
114
115#[inline(always)]
116pub fn opaque_basic_settings() -> EncodeSettings {
117 EncodeSettings {
118 channels: 3,
119 mode_selection: [true, true, true, true],
120 fast_skip_threshold_mode1: 8 + 4,
121 fast_skip_threshold_mode3: 8,
122 fast_skip_threshold_mode7: 0,
123 skip_mode2: true,
124 mode45_channel0: 0,
125 refine_iterations_channel: 2,
126 refine_iterations: [2, 2, 2, 2, 2, 2, 2, 0],
127 }
128}
129
130#[inline(always)]
131pub fn opaque_slow_settings() -> EncodeSettings {
132 let more_refinement = 2;
133 EncodeSettings {
134 channels: 3,
135 mode_selection: [true, true, true, true],
136 fast_skip_threshold_mode1: 64,
137 fast_skip_threshold_mode3: 64,
138 fast_skip_threshold_mode7: 0,
139 skip_mode2: false,
140 mode45_channel0: 0,
141 refine_iterations_channel: 2 + more_refinement,
142 refine_iterations: [
143 2 + more_refinement,
144 2 + more_refinement,
145 2 + more_refinement,
146 2 + more_refinement,
147 2 + more_refinement,
148 2 + more_refinement,
149 2 + more_refinement,
150 0,
151 ],
152 }
153}
154
155#[inline(always)]
156pub fn alpha_ultra_fast_settings() -> EncodeSettings {
157 EncodeSettings {
158 channels: 4,
159 mode_selection: [false, false, true, true],
160 fast_skip_threshold_mode1: 0,
161 fast_skip_threshold_mode3: 0,
162 fast_skip_threshold_mode7: 4,
163 skip_mode2: true,
164 mode45_channel0: 3,
165 refine_iterations_channel: 1,
166 refine_iterations: [2, 1, 2, 1, 1, 1, 2, 2],
167 }
168}
169
170#[inline(always)]
171pub fn alpha_very_fast_settings() -> EncodeSettings {
172 EncodeSettings {
173 channels: 4,
174 mode_selection: [false, true, true, true],
175 fast_skip_threshold_mode1: 0,
176 fast_skip_threshold_mode3: 0,
177 fast_skip_threshold_mode7: 4,
178 skip_mode2: true,
179 mode45_channel0: 3,
180 refine_iterations_channel: 2,
181 refine_iterations: [2, 1, 2, 1, 2, 2, 2, 2],
182 }
183}
184
185#[inline(always)]
186pub fn alpha_fast_settings() -> EncodeSettings {
187 EncodeSettings {
188 channels: 4,
189 mode_selection: [false, true, true, true],
190 fast_skip_threshold_mode1: 4,
191 fast_skip_threshold_mode3: 4,
192 fast_skip_threshold_mode7: 8,
193 skip_mode2: true,
194 mode45_channel0: 3,
195 refine_iterations_channel: 2,
196 refine_iterations: [2, 1, 2, 1, 2, 2, 2, 2],
197 }
198}
199
200#[inline(always)]
201pub fn alpha_basic_settings() -> EncodeSettings {
202 EncodeSettings {
203 channels: 4,
204 mode_selection: [true, true, true, true],
205 fast_skip_threshold_mode1: 8 + 4,
206 fast_skip_threshold_mode3: 8,
207 fast_skip_threshold_mode7: 4,
208 skip_mode2: true,
209 mode45_channel0: 0,
210 refine_iterations_channel: 2,
211 refine_iterations: [2, 2, 2, 2, 2, 2, 2, 2],
212 }
213}
214
215#[inline(always)]
216pub fn alpha_slow_settings() -> EncodeSettings {
217 let more_refinement = 2;
218 EncodeSettings {
219 channels: 4,
220 mode_selection: [true, true, true, true],
221 fast_skip_threshold_mode1: 64,
222 fast_skip_threshold_mode3: 64,
223 fast_skip_threshold_mode7: 64,
224 skip_mode2: false,
225 mode45_channel0: 0,
226 refine_iterations_channel: 2 + more_refinement,
227 refine_iterations: [
228 2 + more_refinement,
229 2 + more_refinement,
230 2 + more_refinement,
231 2 + more_refinement,
232 2 + more_refinement,
233 2 + more_refinement,
234 2 + more_refinement,
235 2 + more_refinement,
236 ],
237 }
238}