xref: /aosp_15_r20/external/mesa3d/src/gallium/frontends/rusticl/core/format.rs (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 use mesa_rust_gen::pipe_format;
2 use rusticl_opencl_gen::*;
3 
4 pub struct RusticlImageFormat {
5     pub cl_image_format: cl_image_format,
6     pub req_for_full_read_or_write: bool,
7     pub req_for_embeded_read_or_write: bool,
8     pub req_for_full_read_and_write: bool,
9     pub req_for_full_cl2: bool,
10     pub is_srgb: bool,
11     pub pipe: pipe_format,
12 }
13 
14 // cl -> pipe mapping:
15 //
16 // channels (x: bit size):
17 // CL_R         => Rx
18 // CL_A         => Ax
19 // CL_DEPTH     => Zx
20 // CL_LUMINANCE => Lx
21 // CL_INTENSITY => Ix
22 // CL_RG        => RxGx
23 // CL_RA        => RxAx
24 // CL_Rx        => not supported
25 // CL_RGB       => RxGxBx
26 // CL_RGx       => not supported
27 // CL_RGBA      => RxGxBxAx
28 // CL_ARGB      => AxRxGxBx
29 // CL_BGRA      => BxGxRxAx
30 // CL_ABGR      => AxBxGxRx
31 // CL_RGBx      => RxGxBxXx
32 // CL_sRGB      => RxGxBx_SRGB
33 // CL_sRGBA     => RxGxBxAx_SRGB
34 // CL_sBGRA     => BxGxRxAx_SRGB
35 // CL_sRGBx     => RxGxBxXx_SRGB
36 //
37 // data types:
38 // SNORM        => x  SNORM
39 // UNORM        => x  UNORM
40 // SIGNED_INT   => x  SINT
41 // UNSIGNED_INT => x  UINT
42 // HALF_FLOAT   => 16 FLOAT
43 // FLOAT        => 32 FLOAT
44 macro_rules! cl_format_table {
45     ([$(($order: ident, $type: ident) => $pipe: expr,)+]) => {
46         #[allow(non_upper_case_globals)]
47         const fn cl_format_to_pipe(
48             ch_order: cl_channel_order,
49             ch_type: cl_channel_type
50         ) -> Option<pipe_format> {
51             Some(match (ch_order, ch_type) {
52                 $(($order, $type) => $pipe,)+
53                 _ => return None,
54             })
55         }
56 
57         pub const FORMATS: &[RusticlImageFormat] = &[
58             $(rusticl_image_format($order, $type),)+
59         ];
60     };
61 }
62 
63 cl_format_table!([
64 // broken on iris/gen12
65 //  (CL_A,         CL_HALF_FLOAT)         => pipe_format::PIPE_FORMAT_A16_FLOAT,
66 //  (CL_A,         CL_FLOAT)              => pipe_format::PIPE_FORMAT_A32_FLOAT,
67 //  (CL_A,         CL_SIGNED_INT8)        => pipe_format::PIPE_FORMAT_A8_SINT,
68 //  (CL_A,         CL_SIGNED_INT16)       => pipe_format::PIPE_FORMAT_A16_SINT,
69     (CL_A,         CL_SIGNED_INT32)       => pipe_format::PIPE_FORMAT_A32_SINT,
70 // broken on iris/gen12
71 //  (CL_A,         CL_UNSIGNED_INT8)      => pipe_format::PIPE_FORMAT_A8_UINT,
72 //  (CL_A,         CL_UNSIGNED_INT16)     => pipe_format::PIPE_FORMAT_A16_UINT,
73     (CL_A,         CL_UNSIGNED_INT32)     => pipe_format::PIPE_FORMAT_A32_UINT,
74     (CL_A,         CL_SNORM_INT8)         => pipe_format::PIPE_FORMAT_A8_SNORM,
75     (CL_A,         CL_SNORM_INT16)        => pipe_format::PIPE_FORMAT_A16_SNORM,
76     (CL_A,         CL_UNORM_INT8)         => pipe_format::PIPE_FORMAT_A8_UNORM,
77     (CL_A,         CL_UNORM_INT16)        => pipe_format::PIPE_FORMAT_A16_UNORM,
78 
79     (CL_R,         CL_HALF_FLOAT)         => pipe_format::PIPE_FORMAT_R16_FLOAT,
80     (CL_R,         CL_FLOAT)              => pipe_format::PIPE_FORMAT_R32_FLOAT,
81     (CL_R,         CL_SIGNED_INT8)        => pipe_format::PIPE_FORMAT_R8_SINT,
82     (CL_R,         CL_SIGNED_INT16)       => pipe_format::PIPE_FORMAT_R16_SINT,
83     (CL_R,         CL_SIGNED_INT32)       => pipe_format::PIPE_FORMAT_R32_SINT,
84     (CL_R,         CL_UNSIGNED_INT8)      => pipe_format::PIPE_FORMAT_R8_UINT,
85     (CL_R,         CL_UNSIGNED_INT16)     => pipe_format::PIPE_FORMAT_R16_UINT,
86     (CL_R,         CL_UNSIGNED_INT32)     => pipe_format::PIPE_FORMAT_R32_UINT,
87     (CL_R,         CL_SNORM_INT8)         => pipe_format::PIPE_FORMAT_R8_SNORM,
88     (CL_R,         CL_SNORM_INT16)        => pipe_format::PIPE_FORMAT_R16_SNORM,
89     (CL_R,         CL_UNORM_INT8)         => pipe_format::PIPE_FORMAT_R8_UNORM,
90     (CL_R,         CL_UNORM_INT16)        => pipe_format::PIPE_FORMAT_R16_UNORM,
91 
92     (CL_RA,        CL_HALF_FLOAT)         => pipe_format::PIPE_FORMAT_R16A16_FLOAT,
93     (CL_RA,        CL_FLOAT)              => pipe_format::PIPE_FORMAT_R32A32_FLOAT,
94     (CL_RA,        CL_SIGNED_INT8)        => pipe_format::PIPE_FORMAT_R8A8_SINT,
95     (CL_RA,        CL_SIGNED_INT16)       => pipe_format::PIPE_FORMAT_R16A16_SINT,
96     (CL_RA,        CL_SIGNED_INT32)       => pipe_format::PIPE_FORMAT_R32A32_SINT,
97     (CL_RA,        CL_UNSIGNED_INT8)      => pipe_format::PIPE_FORMAT_R8A8_UINT,
98     (CL_RA,        CL_UNSIGNED_INT16)     => pipe_format::PIPE_FORMAT_R16A16_UINT,
99     (CL_RA,        CL_UNSIGNED_INT32)     => pipe_format::PIPE_FORMAT_R32A32_UINT,
100     (CL_RA,        CL_SNORM_INT8)         => pipe_format::PIPE_FORMAT_R8A8_SNORM,
101     (CL_RA,        CL_SNORM_INT16)        => pipe_format::PIPE_FORMAT_R16A16_SNORM,
102     (CL_RA,        CL_UNORM_INT8)         => pipe_format::PIPE_FORMAT_R8A8_UNORM,
103     (CL_RA,        CL_UNORM_INT16)        => pipe_format::PIPE_FORMAT_R16A16_UNORM,
104 
105     (CL_RG,        CL_HALF_FLOAT)         => pipe_format::PIPE_FORMAT_R16G16_FLOAT,
106     (CL_RG,        CL_FLOAT)              => pipe_format::PIPE_FORMAT_R32G32_FLOAT,
107     (CL_RG,        CL_SIGNED_INT8)        => pipe_format::PIPE_FORMAT_R8G8_SINT,
108     (CL_RG,        CL_SIGNED_INT16)       => pipe_format::PIPE_FORMAT_R16G16_SINT,
109     (CL_RG,        CL_SIGNED_INT32)       => pipe_format::PIPE_FORMAT_R32G32_SINT,
110     (CL_RG,        CL_UNSIGNED_INT8)      => pipe_format::PIPE_FORMAT_R8G8_UINT,
111     (CL_RG,        CL_UNSIGNED_INT16)     => pipe_format::PIPE_FORMAT_R16G16_UINT,
112     (CL_RG,        CL_UNSIGNED_INT32)     => pipe_format::PIPE_FORMAT_R32G32_UINT,
113     (CL_RG,        CL_SNORM_INT8)         => pipe_format::PIPE_FORMAT_R8G8_SNORM,
114     (CL_RG,        CL_SNORM_INT16)        => pipe_format::PIPE_FORMAT_R16G16_SNORM,
115     (CL_RG,        CL_UNORM_INT8)         => pipe_format::PIPE_FORMAT_R8G8_UNORM,
116     (CL_RG,        CL_UNORM_INT16)        => pipe_format::PIPE_FORMAT_R16G16_UNORM,
117 
118     (CL_RGB,       CL_HALF_FLOAT)         => pipe_format::PIPE_FORMAT_R16G16B16_FLOAT,
119     (CL_RGB,       CL_FLOAT)              => pipe_format::PIPE_FORMAT_R32G32B32_FLOAT,
120     (CL_RGB,       CL_SIGNED_INT8)        => pipe_format::PIPE_FORMAT_R8G8B8_SINT,
121     (CL_RGB,       CL_SIGNED_INT16)       => pipe_format::PIPE_FORMAT_R16G16B16_SINT,
122     (CL_RGB,       CL_SIGNED_INT32)       => pipe_format::PIPE_FORMAT_R32G32B32_SINT,
123     (CL_RGB,       CL_UNSIGNED_INT8)      => pipe_format::PIPE_FORMAT_R8G8B8_UINT,
124     (CL_RGB,       CL_UNSIGNED_INT16)     => pipe_format::PIPE_FORMAT_R16G16B16_UINT,
125     (CL_RGB,       CL_UNSIGNED_INT32)     => pipe_format::PIPE_FORMAT_R32G32B32_UINT,
126     (CL_RGB,       CL_SNORM_INT8)         => pipe_format::PIPE_FORMAT_R8G8B8_SNORM,
127     (CL_RGB,       CL_SNORM_INT16)        => pipe_format::PIPE_FORMAT_R16G16B16_SNORM,
128     (CL_RGB,       CL_UNORM_INT8)         => pipe_format::PIPE_FORMAT_R8G8B8_UNORM,
129     (CL_RGB,       CL_UNORM_INT16)        => pipe_format::PIPE_FORMAT_R16G16B16_UNORM,
130 // broken
131 //  (CL_RGB,       CL_UNORM_SHORT_565)    => pipe_format::PIPE_FORMAT_R5G6B5_UNORM,
132 
133     (CL_ABGR,      CL_SIGNED_INT8)        => pipe_format::PIPE_FORMAT_A8B8G8R8_SINT,
134     (CL_ABGR,      CL_UNSIGNED_INT8)      => pipe_format::PIPE_FORMAT_A8B8G8R8_UINT,
135     (CL_ABGR,      CL_SNORM_INT8)         => pipe_format::PIPE_FORMAT_A8B8G8R8_SNORM,
136     (CL_ABGR,      CL_UNORM_INT8)         => pipe_format::PIPE_FORMAT_A8B8G8R8_UNORM,
137 
138     (CL_ARGB,      CL_SIGNED_INT8)        => pipe_format::PIPE_FORMAT_A8R8G8B8_SINT,
139     (CL_ARGB,      CL_UNSIGNED_INT8)      => pipe_format::PIPE_FORMAT_A8R8G8B8_UINT,
140     (CL_ARGB,      CL_SNORM_INT8)         => pipe_format::PIPE_FORMAT_A8R8G8B8_SNORM,
141     (CL_ARGB,      CL_UNORM_INT8)         => pipe_format::PIPE_FORMAT_A8R8G8B8_UNORM,
142 
143     (CL_BGRA,      CL_SIGNED_INT8)        => pipe_format::PIPE_FORMAT_B8G8R8A8_SINT,
144     (CL_BGRA,      CL_UNSIGNED_INT8)      => pipe_format::PIPE_FORMAT_B8G8R8A8_UINT,
145     (CL_BGRA,      CL_SNORM_INT8)         => pipe_format::PIPE_FORMAT_B8G8R8A8_SNORM,
146     (CL_BGRA,      CL_UNORM_INT8)         => pipe_format::PIPE_FORMAT_B8G8R8A8_UNORM,
147 
148     (CL_RGBA,      CL_HALF_FLOAT)         => pipe_format::PIPE_FORMAT_R16G16B16A16_FLOAT,
149     (CL_RGBA,      CL_FLOAT)              => pipe_format::PIPE_FORMAT_R32G32B32A32_FLOAT,
150     (CL_RGBA,      CL_SIGNED_INT8)        => pipe_format::PIPE_FORMAT_R8G8B8A8_SINT,
151     (CL_RGBA,      CL_SIGNED_INT16)       => pipe_format::PIPE_FORMAT_R16G16B16A16_SINT,
152     (CL_RGBA,      CL_SIGNED_INT32)       => pipe_format::PIPE_FORMAT_R32G32B32A32_SINT,
153     (CL_RGBA,      CL_UNSIGNED_INT8)      => pipe_format::PIPE_FORMAT_R8G8B8A8_UINT,
154     (CL_RGBA,      CL_UNSIGNED_INT16)     => pipe_format::PIPE_FORMAT_R16G16B16A16_UINT,
155     (CL_RGBA,      CL_UNSIGNED_INT32)     => pipe_format::PIPE_FORMAT_R32G32B32A32_UINT,
156     (CL_RGBA,      CL_SNORM_INT8)         => pipe_format::PIPE_FORMAT_R8G8B8A8_SNORM,
157     (CL_RGBA,      CL_SNORM_INT16)        => pipe_format::PIPE_FORMAT_R16G16B16A16_SNORM,
158     (CL_RGBA,      CL_UNORM_INT8)         => pipe_format::PIPE_FORMAT_R8G8B8A8_UNORM,
159     (CL_RGBA,      CL_UNORM_INT16)        => pipe_format::PIPE_FORMAT_R16G16B16A16_UNORM,
160 // broken
161 //  (CL_RGBA,      CL_UNORM_INT_101010_2) => pipe_format::PIPE_FORMAT_R10G10B10A2_UNORM,
162 
163 // broken
164 //  (CL_RGBx,      CL_HALF_FLOAT)         => pipe_format::PIPE_FORMAT_R16G16B16X16_FLOAT,
165 //  (CL_RGBx,      CL_FLOAT)              => pipe_format::PIPE_FORMAT_R32G32B32X32_FLOAT,
166 //  (CL_RGBx,      CL_SIGNED_INT8)        => pipe_format::PIPE_FORMAT_R8G8B8X8_SINT,
167 //  (CL_RGBx,      CL_SIGNED_INT16)       => pipe_format::PIPE_FORMAT_R16G16B16X16_SINT,
168 //  (CL_RGBx,      CL_SIGNED_INT32)       => pipe_format::PIPE_FORMAT_R32G32B32X32_SINT,
169 //  (CL_RGBx,      CL_UNSIGNED_INT8)      => pipe_format::PIPE_FORMAT_R8G8B8X8_UINT,
170 //  (CL_RGBx,      CL_UNSIGNED_INT16)     => pipe_format::PIPE_FORMAT_R16G16B16X16_UINT,
171 //  (CL_RGBx,      CL_UNSIGNED_INT32)     => pipe_format::PIPE_FORMAT_R32G32B32X32_UINT,
172 //  (CL_RGBx,      CL_SNORM_INT8)         => pipe_format::PIPE_FORMAT_R8G8B8X8_SNORM,
173 //  (CL_RGBx,      CL_SNORM_INT16)        => pipe_format::PIPE_FORMAT_R16G16B16X16_SNORM,
174 //  (CL_RGBx,      CL_UNORM_INT8)         => pipe_format::PIPE_FORMAT_R8G8B8X8_UNORM,
175 //  (CL_RGBx,      CL_UNORM_INT16)        => pipe_format::PIPE_FORMAT_R16G16B16X16_UNORM,
176 //  (CL_RGBx,      CL_UNORM_SHORT_555)    => pipe_format::PIPE_FORMAT_R5G5B5X1_UNORM,
177 //  (CL_RGBx,      CL_UNORM_INT_101010)   => pipe_format::PIPE_FORMAT_R10G10B10X2_UNORM,
178 
179 // broken
180 //  (CL_sRGB,      CL_UNORM_INT8)         => pipe_format::PIPE_FORMAT_R8G8B8_SRGB,
181 //  (CL_sRGBA,     CL_UNORM_INT8)         => pipe_format::PIPE_FORMAT_R8G8B8A8_SRGB,
182 //  (CL_sBGRA,     CL_UNORM_INT8)         => pipe_format::PIPE_FORMAT_B8G8R8A8_SRGB,
183 // broken
184 //  (CL_sRGBx,     CL_UNORM_INT8)         => pipe_format::PIPE_FORMAT_R8G8B8X8_SRGB,
185 
186 // broken
187 //  (CL_DEPTH,     CL_FLOAT)              => pipe_format::PIPE_FORMAT_Z32_FLOAT,
188 //  (CL_DEPTH,     CL_UNORM_INT16)        => pipe_format::PIPE_FORMAT_Z16_UNORM,
189 
190     (CL_LUMINANCE, CL_HALF_FLOAT)         => pipe_format::PIPE_FORMAT_L16_FLOAT,
191     (CL_LUMINANCE, CL_FLOAT)              => pipe_format::PIPE_FORMAT_L32_FLOAT,
192     (CL_LUMINANCE, CL_SIGNED_INT8)        => pipe_format::PIPE_FORMAT_L8_SINT,
193     (CL_LUMINANCE, CL_SIGNED_INT16)       => pipe_format::PIPE_FORMAT_L16_SINT,
194     (CL_LUMINANCE, CL_SIGNED_INT32)       => pipe_format::PIPE_FORMAT_L32_SINT,
195     (CL_LUMINANCE, CL_UNSIGNED_INT8)      => pipe_format::PIPE_FORMAT_L8_UINT,
196     (CL_LUMINANCE, CL_UNSIGNED_INT16)     => pipe_format::PIPE_FORMAT_L16_UINT,
197     (CL_LUMINANCE, CL_UNSIGNED_INT32)     => pipe_format::PIPE_FORMAT_L32_UINT,
198     (CL_LUMINANCE, CL_SNORM_INT8)         => pipe_format::PIPE_FORMAT_L8_SNORM,
199     (CL_LUMINANCE, CL_SNORM_INT16)        => pipe_format::PIPE_FORMAT_L16_SNORM,
200     (CL_LUMINANCE, CL_UNORM_INT8)         => pipe_format::PIPE_FORMAT_L8_UNORM,
201     (CL_LUMINANCE, CL_UNORM_INT16)        => pipe_format::PIPE_FORMAT_L16_UNORM,
202 
203     (CL_INTENSITY, CL_HALF_FLOAT)         => pipe_format::PIPE_FORMAT_I16_FLOAT,
204     (CL_INTENSITY, CL_FLOAT)              => pipe_format::PIPE_FORMAT_I32_FLOAT,
205     (CL_INTENSITY, CL_SIGNED_INT8)        => pipe_format::PIPE_FORMAT_I8_SINT,
206     (CL_INTENSITY, CL_SIGNED_INT16)       => pipe_format::PIPE_FORMAT_I16_SINT,
207     (CL_INTENSITY, CL_SIGNED_INT32)       => pipe_format::PIPE_FORMAT_I32_SINT,
208     (CL_INTENSITY, CL_UNSIGNED_INT8)      => pipe_format::PIPE_FORMAT_I8_UINT,
209     (CL_INTENSITY, CL_UNSIGNED_INT16)     => pipe_format::PIPE_FORMAT_I16_UINT,
210     (CL_INTENSITY, CL_UNSIGNED_INT32)     => pipe_format::PIPE_FORMAT_I32_UINT,
211     (CL_INTENSITY, CL_SNORM_INT8)         => pipe_format::PIPE_FORMAT_I8_SNORM,
212     (CL_INTENSITY, CL_SNORM_INT16)        => pipe_format::PIPE_FORMAT_I16_SNORM,
213     (CL_INTENSITY, CL_UNORM_INT8)         => pipe_format::PIPE_FORMAT_I8_UNORM,
214     (CL_INTENSITY, CL_UNORM_INT16)        => pipe_format::PIPE_FORMAT_I16_UNORM,
215 ]);
216 
217 #[rustfmt::skip]
req_for_full_r_or_w( ch_order: cl_channel_order, ch_type: cl_channel_type ) -> bool218 const fn req_for_full_r_or_w(
219     ch_order: cl_channel_order,
220     ch_type: cl_channel_type
221 ) -> bool {
222     matches!((ch_order, ch_type),
223           (CL_RGBA, CL_UNORM_INT8)
224         | (CL_RGBA, CL_UNORM_INT16)
225         | (CL_RGBA, CL_SIGNED_INT8)
226         | (CL_RGBA, CL_SIGNED_INT16)
227         | (CL_RGBA, CL_SIGNED_INT32)
228         | (CL_RGBA, CL_UNSIGNED_INT8)
229         | (CL_RGBA, CL_UNSIGNED_INT16)
230         | (CL_RGBA, CL_UNSIGNED_INT32)
231         | (CL_RGBA, CL_HALF_FLOAT)
232         | (CL_RGBA, CL_FLOAT)
233         | (CL_BGRA, CL_UNORM_INT8))
234 }
235 
236 #[rustfmt::skip]
req_for_embedded_r_or_w( ch_order: cl_channel_order, ch_type: cl_channel_type ) -> bool237 const fn req_for_embedded_r_or_w(
238     ch_order: cl_channel_order,
239     ch_type: cl_channel_type
240 ) -> bool {
241     matches!((ch_order, ch_type),
242           (CL_RGBA, CL_UNORM_INT8)
243         | (CL_RGBA, CL_UNORM_INT16)
244         | (CL_RGBA, CL_SIGNED_INT8)
245         | (CL_RGBA, CL_SIGNED_INT16)
246         | (CL_RGBA, CL_SIGNED_INT32)
247         | (CL_RGBA, CL_UNSIGNED_INT8)
248         | (CL_RGBA, CL_UNSIGNED_INT16)
249         | (CL_RGBA, CL_UNSIGNED_INT32)
250         | (CL_RGBA, CL_HALF_FLOAT)
251         | (CL_RGBA, CL_FLOAT))
252 }
253 
254 #[rustfmt::skip]
req_for_full_rw( ch_order: cl_channel_order, ch_type: cl_channel_type ) -> bool255 const fn req_for_full_rw(
256     ch_order: cl_channel_order,
257     ch_type: cl_channel_type
258 ) -> bool {
259     matches!((ch_order, ch_type),
260           (CL_R,    CL_UNORM_INT8)
261         | (CL_R,    CL_SIGNED_INT8)
262         | (CL_R,    CL_SIGNED_INT16)
263         | (CL_R,    CL_SIGNED_INT32)
264         | (CL_R,    CL_UNSIGNED_INT8)
265         | (CL_R,    CL_UNSIGNED_INT16)
266         | (CL_R,    CL_UNSIGNED_INT32)
267         | (CL_R,    CL_HALF_FLOAT)
268         | (CL_R,    CL_FLOAT)
269         | (CL_RGBA, CL_UNORM_INT8)
270         | (CL_RGBA, CL_SIGNED_INT8)
271         | (CL_RGBA, CL_SIGNED_INT16)
272         | (CL_RGBA, CL_SIGNED_INT32)
273         | (CL_RGBA, CL_UNSIGNED_INT8)
274         | (CL_RGBA, CL_UNSIGNED_INT16)
275         | (CL_RGBA, CL_UNSIGNED_INT32)
276         | (CL_RGBA, CL_HALF_FLOAT)
277         | (CL_RGBA, CL_FLOAT))
278 }
279 
280 #[rustfmt::skip]
281 #[allow(non_upper_case_globals)]
req_for_full_cl2( ch_order: cl_channel_order, ch_type: cl_channel_type ) -> bool282 const fn req_for_full_cl2(
283     ch_order: cl_channel_order,
284     ch_type: cl_channel_type
285 ) -> bool {
286     matches!((ch_order, ch_type),
287           (CL_R,     CL_UNORM_INT8)
288         | (CL_R,     CL_UNORM_INT16)
289         | (CL_R,     CL_SNORM_INT8)
290         | (CL_R,     CL_SNORM_INT16)
291         | (CL_R,     CL_SIGNED_INT8)
292         | (CL_R,     CL_SIGNED_INT16)
293         | (CL_R,     CL_SIGNED_INT32)
294         | (CL_R,     CL_UNSIGNED_INT8)
295         | (CL_R,     CL_UNSIGNED_INT16)
296         | (CL_R,     CL_UNSIGNED_INT32)
297         | (CL_R,     CL_HALF_FLOAT)
298         | (CL_R,     CL_FLOAT)
299         | (CL_DEPTH, CL_UNORM_INT16)
300         | (CL_DEPTH, CL_FLOAT)
301         | (CL_RG,    CL_UNORM_INT8)
302         | (CL_RG,    CL_UNORM_INT16)
303         | (CL_RG,    CL_SNORM_INT8)
304         | (CL_RG,    CL_SNORM_INT16)
305         | (CL_RG,    CL_SIGNED_INT8)
306         | (CL_RG,    CL_SIGNED_INT16)
307         | (CL_RG,    CL_SIGNED_INT32)
308         | (CL_RG,    CL_UNSIGNED_INT8)
309         | (CL_RG,    CL_UNSIGNED_INT16)
310         | (CL_RG,    CL_UNSIGNED_INT32)
311         | (CL_RG,    CL_HALF_FLOAT)
312         | (CL_RG,    CL_FLOAT)
313         | (CL_RGBA,  CL_UNORM_INT8)
314         | (CL_RGBA,  CL_UNORM_INT16)
315         | (CL_RGBA,  CL_SNORM_INT8)
316         | (CL_RGBA,  CL_SNORM_INT16)
317         | (CL_RGBA,  CL_SIGNED_INT8)
318         | (CL_RGBA,  CL_SIGNED_INT16)
319         | (CL_RGBA,  CL_SIGNED_INT32)
320         | (CL_RGBA,  CL_UNSIGNED_INT8)
321         | (CL_RGBA,  CL_UNSIGNED_INT16)
322         | (CL_RGBA,  CL_UNSIGNED_INT32)
323         | (CL_RGBA,  CL_HALF_FLOAT)
324         | (CL_RGBA,  CL_FLOAT)
325         | (CL_BGRA,  CL_UNORM_INT8)
326         | (CL_sRGBA, CL_UNORM_INT8))
327 }
328 
329 #[allow(non_upper_case_globals)]
is_srgb(ch_order: cl_channel_order) -> bool330 const fn is_srgb(ch_order: cl_channel_order) -> bool {
331     matches!(ch_order, CL_sBGRA | CL_sRGB | CL_sRGBA | CL_sRGBx)
332 }
333 
rusticl_image_format( ch_order: cl_channel_order, ch_type: cl_channel_type, ) -> RusticlImageFormat334 const fn rusticl_image_format(
335     ch_order: cl_channel_order,
336     ch_type: cl_channel_type,
337 ) -> RusticlImageFormat {
338     let pipe = match cl_format_to_pipe(ch_order, ch_type) {
339         Some(pipe) => pipe,
340         None => panic!("unknown CL format!"),
341     };
342 
343     RusticlImageFormat {
344         cl_image_format: cl_image_format {
345             image_channel_order: ch_order,
346             image_channel_data_type: ch_type,
347         },
348         req_for_full_read_or_write: req_for_full_r_or_w(ch_order, ch_type),
349         req_for_embeded_read_or_write: req_for_embedded_r_or_w(ch_order, ch_type),
350         req_for_full_read_and_write: req_for_full_rw(ch_order, ch_type),
351         req_for_full_cl2: req_for_full_cl2(ch_order, ch_type),
352         is_srgb: is_srgb(ch_order),
353         pipe: pipe,
354     }
355 }
356 
357 pub trait CLFormatInfo {
channels(&self) -> Option<u8>358     fn channels(&self) -> Option<u8>;
format_info(&self) -> Option<(u8, bool)>359     fn format_info(&self) -> Option<(u8, bool)>;
to_pipe_format(&self) -> Option<pipe_format>360     fn to_pipe_format(&self) -> Option<pipe_format>;
361 
channel_size(&self) -> Option<u8>362     fn channel_size(&self) -> Option<u8> {
363         if let Some(packed) = self.is_packed() {
364             assert!(!packed);
365             self.format_info().map(|i| i.0)
366         } else {
367             None
368         }
369     }
370 
packed_size(&self) -> Option<u8>371     fn packed_size(&self) -> Option<u8> {
372         if let Some(packed) = self.is_packed() {
373             assert!(packed);
374             self.format_info().map(|i| i.0)
375         } else {
376             None
377         }
378     }
379 
is_packed(&self) -> Option<bool>380     fn is_packed(&self) -> Option<bool> {
381         self.format_info().map(|i| i.1)
382     }
383 
pixel_size(&self) -> Option<u8>384     fn pixel_size(&self) -> Option<u8> {
385         if let Some(packed) = self.is_packed() {
386             if packed {
387                 self.packed_size()
388             } else {
389                 self.channels().zip(self.channel_size()).map(|(c, s)| c * s)
390             }
391         } else {
392             None
393         }
394     }
395 }
396 
397 impl CLFormatInfo for cl_image_format {
398     #[allow(non_upper_case_globals)]
channels(&self) -> Option<u8>399     fn channels(&self) -> Option<u8> {
400         match self.image_channel_order {
401             CL_R | CL_A | CL_DEPTH | CL_INTENSITY | CL_LUMINANCE | CL_NONE => Some(1),
402             CL_RG | CL_RA | CL_Rx => Some(2),
403             CL_RGB | CL_RGx | CL_sRGB => Some(3),
404             CL_RGBA | CL_ARGB | CL_BGRA | CL_ABGR | CL_RGBx | CL_sRGBA | CL_sBGRA | CL_sRGBx => {
405                 Some(4)
406             }
407             _ => None,
408         }
409     }
410 
format_info(&self) -> Option<(u8, bool)>411     fn format_info(&self) -> Option<(u8, bool)> {
412         match self.image_channel_data_type {
413             CL_SIGNED_INT8 | CL_UNSIGNED_INT8 | CL_SNORM_INT8 | CL_UNORM_INT8 | CL_NONE => {
414                 Some((1, false))
415             }
416             CL_SIGNED_INT16 | CL_UNSIGNED_INT16 | CL_SNORM_INT16 | CL_UNORM_INT16
417             | CL_HALF_FLOAT => Some((2, false)),
418             CL_SIGNED_INT32 | CL_UNSIGNED_INT32 | CL_FLOAT => Some((4, false)),
419             CL_UNORM_SHORT_555 | CL_UNORM_SHORT_565 => Some((2, true)),
420             CL_UNORM_INT_101010 | CL_UNORM_INT_101010_2 => Some((4, true)),
421             _ => None,
422         }
423     }
424 
to_pipe_format(&self) -> Option<pipe_format>425     fn to_pipe_format(&self) -> Option<pipe_format> {
426         cl_format_to_pipe(self.image_channel_order, self.image_channel_data_type)
427     }
428 }
429 
430 macro_rules! gl_cl_format_table {
431     ([$($gl: ident => ($order: expr, $dtype: expr),)+]) => {
432         #[allow(non_upper_case_globals)]
433         const fn gl_format_to_cl(
434             gl_format: cl_GLenum
435         ) -> Option<(cl_channel_order, cl_channel_type)> {
436             Some(match gl_format {
437                 $($gl => ($order, $dtype),)+
438                 _ => return None,
439             })
440         }
441     };
442 }
443 
444 gl_cl_format_table!([
445     GL_RGBA8                        => (CL_RGBA, CL_UNORM_INT8),
446     GL_SRGB8_ALPHA8                 => (CL_sRGBA, CL_UNORM_INT8),
447     GL_RGBA                         => (CL_RGBA, CL_UNORM_INT8),
448     GL_UNSIGNED_INT_8_8_8_8_REV     => (CL_RGBA, CL_UNORM_INT8),
449     GL_BGRA                         => (CL_BGRA, CL_UNORM_INT8),
450     GL_RGBA8I                       => (CL_RGBA, CL_SIGNED_INT8),
451     GL_RGBA16I                      => (CL_RGBA, CL_SIGNED_INT16),
452     GL_RGBA32I                      => (CL_RGBA, CL_SIGNED_INT32),
453     GL_RGBA8UI                      => (CL_RGBA, CL_UNSIGNED_INT8),
454     GL_RGBA16UI                     => (CL_RGBA, CL_UNSIGNED_INT16),
455     GL_RGBA32UI                     => (CL_RGBA, CL_UNSIGNED_INT32),
456     GL_RGBA8_SNORM                  => (CL_RGBA, CL_SNORM_INT8),
457     GL_RGBA16                       => (CL_RGBA, CL_UNORM_INT16),
458     GL_RGBA16_SNORM                 => (CL_RGBA, CL_SNORM_INT16),
459     GL_RGBA16F                      => (CL_RGBA, CL_HALF_FLOAT),
460     GL_RGBA32F                      => (CL_RGBA, CL_FLOAT),
461 
462     GL_R8                           => (CL_R, CL_UNORM_INT8),
463     GL_R8_SNORM                     => (CL_R, CL_SNORM_INT8),
464     GL_R16                          => (CL_R, CL_UNORM_INT16),
465     GL_R16_SNORM                    => (CL_R, CL_SNORM_INT16),
466     GL_R16F                         => (CL_R, CL_HALF_FLOAT),
467     GL_R32F                         => (CL_R, CL_FLOAT),
468     GL_R8I                          => (CL_R, CL_SIGNED_INT8),
469     GL_R16I                         => (CL_R, CL_SIGNED_INT16),
470     GL_R32I                         => (CL_R, CL_SIGNED_INT32),
471     GL_R8UI                         => (CL_R, CL_UNSIGNED_INT8),
472     GL_R16UI                        => (CL_R, CL_UNSIGNED_INT16),
473     GL_R32UI                        => (CL_R, CL_UNSIGNED_INT32),
474 
475     GL_RG8                          => (CL_RG, CL_UNORM_INT8),
476     GL_RG8_SNORM                    => (CL_RG, CL_SNORM_INT8),
477     GL_RG16                         => (CL_RG, CL_UNORM_INT16),
478     GL_RG16_SNORM                   => (CL_RG, CL_SNORM_INT16),
479     GL_RG16F                        => (CL_RG, CL_HALF_FLOAT),
480     GL_RG32F                        => (CL_RG, CL_FLOAT),
481     GL_RG8I                         => (CL_RG, CL_SIGNED_INT8),
482     GL_RG16I                        => (CL_RG, CL_SIGNED_INT16),
483     GL_RG32I                        => (CL_RG, CL_SIGNED_INT32),
484     GL_RG8UI                        => (CL_RG, CL_UNSIGNED_INT8),
485     GL_RG16UI                       => (CL_RG, CL_UNSIGNED_INT16),
486     GL_RG32UI                       => (CL_RG, CL_UNSIGNED_INT32),
487 ]);
488 
format_from_gl(internal_format: cl_GLenum) -> Option<cl_image_format>489 pub fn format_from_gl(internal_format: cl_GLenum) -> Option<cl_image_format> {
490     gl_format_to_cl(internal_format).map(|(order, dtype)| cl_image_format {
491         image_channel_order: order,
492         image_channel_data_type: dtype,
493     })
494 }
495