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