• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     // yes, we use non depth formats for CL_DEPTH, because OpenCL requires normal pixel semantics
187     // and not implicit depth format semantics (e.g. implicit value clamping). Intel NEO does the
188     // same.
189     (CL_DEPTH,     CL_FLOAT)              => pipe_format::PIPE_FORMAT_R32_FLOAT,
190     (CL_DEPTH,     CL_UNORM_INT16)        => pipe_format::PIPE_FORMAT_R16_UNORM,
191 
192     (CL_LUMINANCE, CL_HALF_FLOAT)         => pipe_format::PIPE_FORMAT_L16_FLOAT,
193     (CL_LUMINANCE, CL_FLOAT)              => pipe_format::PIPE_FORMAT_L32_FLOAT,
194     (CL_LUMINANCE, CL_SIGNED_INT8)        => pipe_format::PIPE_FORMAT_L8_SINT,
195     (CL_LUMINANCE, CL_SIGNED_INT16)       => pipe_format::PIPE_FORMAT_L16_SINT,
196     (CL_LUMINANCE, CL_SIGNED_INT32)       => pipe_format::PIPE_FORMAT_L32_SINT,
197     (CL_LUMINANCE, CL_UNSIGNED_INT8)      => pipe_format::PIPE_FORMAT_L8_UINT,
198     (CL_LUMINANCE, CL_UNSIGNED_INT16)     => pipe_format::PIPE_FORMAT_L16_UINT,
199     (CL_LUMINANCE, CL_UNSIGNED_INT32)     => pipe_format::PIPE_FORMAT_L32_UINT,
200     (CL_LUMINANCE, CL_SNORM_INT8)         => pipe_format::PIPE_FORMAT_L8_SNORM,
201     (CL_LUMINANCE, CL_SNORM_INT16)        => pipe_format::PIPE_FORMAT_L16_SNORM,
202     (CL_LUMINANCE, CL_UNORM_INT8)         => pipe_format::PIPE_FORMAT_L8_UNORM,
203     (CL_LUMINANCE, CL_UNORM_INT16)        => pipe_format::PIPE_FORMAT_L16_UNORM,
204 
205     (CL_INTENSITY, CL_HALF_FLOAT)         => pipe_format::PIPE_FORMAT_I16_FLOAT,
206     (CL_INTENSITY, CL_FLOAT)              => pipe_format::PIPE_FORMAT_I32_FLOAT,
207     (CL_INTENSITY, CL_SIGNED_INT8)        => pipe_format::PIPE_FORMAT_I8_SINT,
208     (CL_INTENSITY, CL_SIGNED_INT16)       => pipe_format::PIPE_FORMAT_I16_SINT,
209     (CL_INTENSITY, CL_SIGNED_INT32)       => pipe_format::PIPE_FORMAT_I32_SINT,
210     (CL_INTENSITY, CL_UNSIGNED_INT8)      => pipe_format::PIPE_FORMAT_I8_UINT,
211     (CL_INTENSITY, CL_UNSIGNED_INT16)     => pipe_format::PIPE_FORMAT_I16_UINT,
212     (CL_INTENSITY, CL_UNSIGNED_INT32)     => pipe_format::PIPE_FORMAT_I32_UINT,
213     (CL_INTENSITY, CL_SNORM_INT8)         => pipe_format::PIPE_FORMAT_I8_SNORM,
214     (CL_INTENSITY, CL_SNORM_INT16)        => pipe_format::PIPE_FORMAT_I16_SNORM,
215     (CL_INTENSITY, CL_UNORM_INT8)         => pipe_format::PIPE_FORMAT_I8_UNORM,
216     (CL_INTENSITY, CL_UNORM_INT16)        => pipe_format::PIPE_FORMAT_I16_UNORM,
217 ]);
218 
219 #[rustfmt::skip]
req_for_full_r_or_w( ch_order: cl_channel_order, ch_type: cl_channel_type ) -> bool220 const fn req_for_full_r_or_w(
221     ch_order: cl_channel_order,
222     ch_type: cl_channel_type
223 ) -> bool {
224     matches!((ch_order, ch_type),
225           (CL_RGBA, CL_UNORM_INT8)
226         | (CL_RGBA, CL_UNORM_INT16)
227         | (CL_RGBA, CL_SIGNED_INT8)
228         | (CL_RGBA, CL_SIGNED_INT16)
229         | (CL_RGBA, CL_SIGNED_INT32)
230         | (CL_RGBA, CL_UNSIGNED_INT8)
231         | (CL_RGBA, CL_UNSIGNED_INT16)
232         | (CL_RGBA, CL_UNSIGNED_INT32)
233         | (CL_RGBA, CL_HALF_FLOAT)
234         | (CL_RGBA, CL_FLOAT)
235         | (CL_BGRA, CL_UNORM_INT8))
236 }
237 
238 #[rustfmt::skip]
req_for_embedded_r_or_w( ch_order: cl_channel_order, ch_type: cl_channel_type ) -> bool239 const fn req_for_embedded_r_or_w(
240     ch_order: cl_channel_order,
241     ch_type: cl_channel_type
242 ) -> bool {
243     matches!((ch_order, ch_type),
244           (CL_RGBA, CL_UNORM_INT8)
245         | (CL_RGBA, CL_UNORM_INT16)
246         | (CL_RGBA, CL_SIGNED_INT8)
247         | (CL_RGBA, CL_SIGNED_INT16)
248         | (CL_RGBA, CL_SIGNED_INT32)
249         | (CL_RGBA, CL_UNSIGNED_INT8)
250         | (CL_RGBA, CL_UNSIGNED_INT16)
251         | (CL_RGBA, CL_UNSIGNED_INT32)
252         | (CL_RGBA, CL_HALF_FLOAT)
253         | (CL_RGBA, CL_FLOAT))
254 }
255 
256 #[rustfmt::skip]
req_for_full_rw( ch_order: cl_channel_order, ch_type: cl_channel_type ) -> bool257 const fn req_for_full_rw(
258     ch_order: cl_channel_order,
259     ch_type: cl_channel_type
260 ) -> bool {
261     matches!((ch_order, ch_type),
262           (CL_R,    CL_UNORM_INT8)
263         | (CL_R,    CL_SIGNED_INT8)
264         | (CL_R,    CL_SIGNED_INT16)
265         | (CL_R,    CL_SIGNED_INT32)
266         | (CL_R,    CL_UNSIGNED_INT8)
267         | (CL_R,    CL_UNSIGNED_INT16)
268         | (CL_R,    CL_UNSIGNED_INT32)
269         | (CL_R,    CL_HALF_FLOAT)
270         | (CL_R,    CL_FLOAT)
271         | (CL_RGBA, CL_UNORM_INT8)
272         | (CL_RGBA, CL_SIGNED_INT8)
273         | (CL_RGBA, CL_SIGNED_INT16)
274         | (CL_RGBA, CL_SIGNED_INT32)
275         | (CL_RGBA, CL_UNSIGNED_INT8)
276         | (CL_RGBA, CL_UNSIGNED_INT16)
277         | (CL_RGBA, CL_UNSIGNED_INT32)
278         | (CL_RGBA, CL_HALF_FLOAT)
279         | (CL_RGBA, CL_FLOAT))
280 }
281 
282 #[rustfmt::skip]
283 #[allow(non_upper_case_globals)]
req_for_full_cl2( ch_order: cl_channel_order, ch_type: cl_channel_type ) -> bool284 const fn req_for_full_cl2(
285     ch_order: cl_channel_order,
286     ch_type: cl_channel_type
287 ) -> bool {
288     matches!((ch_order, ch_type),
289           (CL_R,     CL_UNORM_INT8)
290         | (CL_R,     CL_UNORM_INT16)
291         | (CL_R,     CL_SNORM_INT8)
292         | (CL_R,     CL_SNORM_INT16)
293         | (CL_R,     CL_SIGNED_INT8)
294         | (CL_R,     CL_SIGNED_INT16)
295         | (CL_R,     CL_SIGNED_INT32)
296         | (CL_R,     CL_UNSIGNED_INT8)
297         | (CL_R,     CL_UNSIGNED_INT16)
298         | (CL_R,     CL_UNSIGNED_INT32)
299         | (CL_R,     CL_HALF_FLOAT)
300         | (CL_R,     CL_FLOAT)
301         | (CL_DEPTH, CL_UNORM_INT16)
302         | (CL_DEPTH, CL_FLOAT)
303         | (CL_RG,    CL_UNORM_INT8)
304         | (CL_RG,    CL_UNORM_INT16)
305         | (CL_RG,    CL_SNORM_INT8)
306         | (CL_RG,    CL_SNORM_INT16)
307         | (CL_RG,    CL_SIGNED_INT8)
308         | (CL_RG,    CL_SIGNED_INT16)
309         | (CL_RG,    CL_SIGNED_INT32)
310         | (CL_RG,    CL_UNSIGNED_INT8)
311         | (CL_RG,    CL_UNSIGNED_INT16)
312         | (CL_RG,    CL_UNSIGNED_INT32)
313         | (CL_RG,    CL_HALF_FLOAT)
314         | (CL_RG,    CL_FLOAT)
315         | (CL_RGBA,  CL_UNORM_INT8)
316         | (CL_RGBA,  CL_UNORM_INT16)
317         | (CL_RGBA,  CL_SNORM_INT8)
318         | (CL_RGBA,  CL_SNORM_INT16)
319         | (CL_RGBA,  CL_SIGNED_INT8)
320         | (CL_RGBA,  CL_SIGNED_INT16)
321         | (CL_RGBA,  CL_SIGNED_INT32)
322         | (CL_RGBA,  CL_UNSIGNED_INT8)
323         | (CL_RGBA,  CL_UNSIGNED_INT16)
324         | (CL_RGBA,  CL_UNSIGNED_INT32)
325         | (CL_RGBA,  CL_HALF_FLOAT)
326         | (CL_RGBA,  CL_FLOAT)
327         | (CL_BGRA,  CL_UNORM_INT8)
328         | (CL_sRGBA, CL_UNORM_INT8))
329 }
330 
331 #[allow(non_upper_case_globals)]
is_srgb(ch_order: cl_channel_order) -> bool332 const fn is_srgb(ch_order: cl_channel_order) -> bool {
333     matches!(ch_order, CL_sBGRA | CL_sRGB | CL_sRGBA | CL_sRGBx)
334 }
335 
rusticl_image_format( ch_order: cl_channel_order, ch_type: cl_channel_type, ) -> RusticlImageFormat336 const fn rusticl_image_format(
337     ch_order: cl_channel_order,
338     ch_type: cl_channel_type,
339 ) -> RusticlImageFormat {
340     let pipe = match cl_format_to_pipe(ch_order, ch_type) {
341         Some(pipe) => pipe,
342         None => panic!("unknown CL format!"),
343     };
344 
345     RusticlImageFormat {
346         cl_image_format: cl_image_format {
347             image_channel_order: ch_order,
348             image_channel_data_type: ch_type,
349         },
350         req_for_full_read_or_write: req_for_full_r_or_w(ch_order, ch_type),
351         req_for_embeded_read_or_write: req_for_embedded_r_or_w(ch_order, ch_type),
352         req_for_full_read_and_write: req_for_full_rw(ch_order, ch_type),
353         req_for_full_cl2: req_for_full_cl2(ch_order, ch_type),
354         is_srgb: is_srgb(ch_order),
355         pipe: pipe,
356     }
357 }
358 
359 pub trait CLFormatInfo {
channels(&self) -> Option<u8>360     fn channels(&self) -> Option<u8>;
format_info(&self) -> Option<(u8, bool)>361     fn format_info(&self) -> Option<(u8, bool)>;
to_pipe_format(&self) -> Option<pipe_format>362     fn to_pipe_format(&self) -> Option<pipe_format>;
363 
channel_size(&self) -> Option<u8>364     fn channel_size(&self) -> Option<u8> {
365         if let Some(packed) = self.is_packed() {
366             assert!(!packed);
367             self.format_info().map(|i| i.0)
368         } else {
369             None
370         }
371     }
372 
packed_size(&self) -> Option<u8>373     fn packed_size(&self) -> Option<u8> {
374         if let Some(packed) = self.is_packed() {
375             assert!(packed);
376             self.format_info().map(|i| i.0)
377         } else {
378             None
379         }
380     }
381 
is_packed(&self) -> Option<bool>382     fn is_packed(&self) -> Option<bool> {
383         self.format_info().map(|i| i.1)
384     }
385 
pixel_size(&self) -> Option<u8>386     fn pixel_size(&self) -> Option<u8> {
387         if let Some(packed) = self.is_packed() {
388             if packed {
389                 self.packed_size()
390             } else {
391                 self.channels().zip(self.channel_size()).map(|(c, s)| c * s)
392             }
393         } else {
394             None
395         }
396     }
397 }
398 
399 impl CLFormatInfo for cl_image_format {
400     #[allow(non_upper_case_globals)]
channels(&self) -> Option<u8>401     fn channels(&self) -> Option<u8> {
402         match self.image_channel_order {
403             CL_R | CL_A | CL_DEPTH | CL_INTENSITY | CL_LUMINANCE | CL_NONE => Some(1),
404             CL_RG | CL_RA | CL_Rx => Some(2),
405             CL_RGB | CL_RGx | CL_sRGB => Some(3),
406             CL_RGBA | CL_ARGB | CL_BGRA | CL_ABGR | CL_RGBx | CL_sRGBA | CL_sBGRA | CL_sRGBx => {
407                 Some(4)
408             }
409             _ => None,
410         }
411     }
412 
format_info(&self) -> Option<(u8, bool)>413     fn format_info(&self) -> Option<(u8, bool)> {
414         match self.image_channel_data_type {
415             CL_SIGNED_INT8 | CL_UNSIGNED_INT8 | CL_SNORM_INT8 | CL_UNORM_INT8 | CL_NONE => {
416                 Some((1, false))
417             }
418             CL_SIGNED_INT16 | CL_UNSIGNED_INT16 | CL_SNORM_INT16 | CL_UNORM_INT16
419             | CL_HALF_FLOAT => Some((2, false)),
420             CL_SIGNED_INT32 | CL_UNSIGNED_INT32 | CL_FLOAT => Some((4, false)),
421             CL_UNORM_SHORT_555 | CL_UNORM_SHORT_565 => Some((2, true)),
422             CL_UNORM_INT_101010 | CL_UNORM_INT_101010_2 => Some((4, true)),
423             _ => None,
424         }
425     }
426 
to_pipe_format(&self) -> Option<pipe_format>427     fn to_pipe_format(&self) -> Option<pipe_format> {
428         cl_format_to_pipe(self.image_channel_order, self.image_channel_data_type)
429     }
430 }
431 
432 macro_rules! gl_cl_format_table {
433     ([$($gl: ident => ($order: expr, $dtype: expr),)+]) => {
434         #[allow(non_upper_case_globals)]
435         const fn gl_format_to_cl(
436             gl_format: cl_GLenum
437         ) -> Option<(cl_channel_order, cl_channel_type)> {
438             Some(match gl_format {
439                 $($gl => ($order, $dtype),)+
440                 _ => return None,
441             })
442         }
443     };
444 }
445 
446 gl_cl_format_table!([
447     GL_RGBA8                        => (CL_RGBA, CL_UNORM_INT8),
448     GL_SRGB8_ALPHA8                 => (CL_sRGBA, CL_UNORM_INT8),
449     GL_RGBA                         => (CL_RGBA, CL_UNORM_INT8),
450     GL_UNSIGNED_INT_8_8_8_8_REV     => (CL_RGBA, CL_UNORM_INT8),
451     GL_BGRA                         => (CL_BGRA, CL_UNORM_INT8),
452     GL_RGBA8I                       => (CL_RGBA, CL_SIGNED_INT8),
453     GL_RGBA16I                      => (CL_RGBA, CL_SIGNED_INT16),
454     GL_RGBA32I                      => (CL_RGBA, CL_SIGNED_INT32),
455     GL_RGBA8UI                      => (CL_RGBA, CL_UNSIGNED_INT8),
456     GL_RGBA16UI                     => (CL_RGBA, CL_UNSIGNED_INT16),
457     GL_RGBA32UI                     => (CL_RGBA, CL_UNSIGNED_INT32),
458     GL_RGBA8_SNORM                  => (CL_RGBA, CL_SNORM_INT8),
459     GL_RGBA16                       => (CL_RGBA, CL_UNORM_INT16),
460     GL_RGBA16_SNORM                 => (CL_RGBA, CL_SNORM_INT16),
461     GL_RGBA16F                      => (CL_RGBA, CL_HALF_FLOAT),
462     GL_RGBA32F                      => (CL_RGBA, CL_FLOAT),
463 
464     GL_R8                           => (CL_R, CL_UNORM_INT8),
465     GL_R8_SNORM                     => (CL_R, CL_SNORM_INT8),
466     GL_R16                          => (CL_R, CL_UNORM_INT16),
467     GL_R16_SNORM                    => (CL_R, CL_SNORM_INT16),
468     GL_R16F                         => (CL_R, CL_HALF_FLOAT),
469     GL_R32F                         => (CL_R, CL_FLOAT),
470     GL_R8I                          => (CL_R, CL_SIGNED_INT8),
471     GL_R16I                         => (CL_R, CL_SIGNED_INT16),
472     GL_R32I                         => (CL_R, CL_SIGNED_INT32),
473     GL_R8UI                         => (CL_R, CL_UNSIGNED_INT8),
474     GL_R16UI                        => (CL_R, CL_UNSIGNED_INT16),
475     GL_R32UI                        => (CL_R, CL_UNSIGNED_INT32),
476 
477     GL_RG8                          => (CL_RG, CL_UNORM_INT8),
478     GL_RG8_SNORM                    => (CL_RG, CL_SNORM_INT8),
479     GL_RG16                         => (CL_RG, CL_UNORM_INT16),
480     GL_RG16_SNORM                   => (CL_RG, CL_SNORM_INT16),
481     GL_RG16F                        => (CL_RG, CL_HALF_FLOAT),
482     GL_RG32F                        => (CL_RG, CL_FLOAT),
483     GL_RG8I                         => (CL_RG, CL_SIGNED_INT8),
484     GL_RG16I                        => (CL_RG, CL_SIGNED_INT16),
485     GL_RG32I                        => (CL_RG, CL_SIGNED_INT32),
486     GL_RG8UI                        => (CL_RG, CL_UNSIGNED_INT8),
487     GL_RG16UI                       => (CL_RG, CL_UNSIGNED_INT16),
488     GL_RG32UI                       => (CL_RG, CL_UNSIGNED_INT32),
489 ]);
490 
format_from_gl(internal_format: cl_GLenum) -> Option<cl_image_format>491 pub fn format_from_gl(internal_format: cl_GLenum) -> Option<cl_image_format> {
492     gl_format_to_cl(internal_format).map(|(order, dtype)| cl_image_format {
493         image_channel_order: order,
494         image_channel_data_type: dtype,
495     })
496 }
497