1 /*
2  * Copyright 2017 Google
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the
6  * "Software"), to deal in the Software without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sub license, and/or sell copies of the Software, and to
9  * permit persons to whom the Software is furnished to do so, subject to
10  * the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the
13  * next paragraph) shall be included in all copies or substantial portions
14  * of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
19  * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
20  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  */
24 
25 #include "formats.h"
26 #include "util/macros.h"
27 
28 /**
29  * For an sRGB format, return the corresponding linear color space format.
30  * For non-sRGB formats, return the format as-is.
31  */
32 mesa_format
_mesa_get_srgb_format_linear(mesa_format format)33 _mesa_get_srgb_format_linear(mesa_format format)
34 {
35    switch (format) {
36    case MESA_FORMAT_A8B8G8R8_SRGB:
37       return MESA_FORMAT_A8B8G8R8_UNORM;
38    case MESA_FORMAT_B8G8R8A8_SRGB:
39       return MESA_FORMAT_B8G8R8A8_UNORM;
40    case MESA_FORMAT_A8R8G8B8_SRGB:
41       return MESA_FORMAT_A8R8G8B8_UNORM;
42    case MESA_FORMAT_B8G8R8X8_SRGB:
43       return MESA_FORMAT_B8G8R8X8_UNORM;
44    case MESA_FORMAT_X8R8G8B8_SRGB:
45       return MESA_FORMAT_X8R8G8B8_UNORM;
46    case MESA_FORMAT_R8G8B8A8_SRGB:
47       return MESA_FORMAT_R8G8B8A8_UNORM;
48    case MESA_FORMAT_R8G8B8X8_SRGB:
49       return MESA_FORMAT_R8G8B8X8_UNORM;
50    case MESA_FORMAT_X8B8G8R8_SRGB:
51       return MESA_FORMAT_X8B8G8R8_UNORM;
52    case MESA_FORMAT_L8A8_SRGB:
53       return MESA_FORMAT_L8A8_UNORM;
54    case MESA_FORMAT_A8L8_SRGB:
55       return MESA_FORMAT_A8L8_UNORM;
56    case MESA_FORMAT_L_SRGB8:
57       return MESA_FORMAT_L_UNORM8;
58    case MESA_FORMAT_BGR_SRGB8:
59       return MESA_FORMAT_BGR_UNORM8;
60    case MESA_FORMAT_SRGB_DXT1:
61       return MESA_FORMAT_RGB_DXT1;
62    case MESA_FORMAT_SRGBA_DXT1:
63       return MESA_FORMAT_RGBA_DXT1;
64    case MESA_FORMAT_SRGBA_DXT3:
65       return MESA_FORMAT_RGBA_DXT3;
66    case MESA_FORMAT_SRGBA_DXT5:
67       return MESA_FORMAT_RGBA_DXT5;
68    case MESA_FORMAT_ETC2_SRGB8:
69       return MESA_FORMAT_ETC2_RGB8;
70    case MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC:
71       return MESA_FORMAT_ETC2_RGBA8_EAC;
72    case MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1:
73       return MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1;
74    case MESA_FORMAT_BPTC_SRGB_ALPHA_UNORM:
75       return MESA_FORMAT_BPTC_RGBA_UNORM;
76    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_4x4:
77       return MESA_FORMAT_RGBA_ASTC_4x4;
78    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_5x4:
79       return MESA_FORMAT_RGBA_ASTC_5x4;
80    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_5x5:
81       return MESA_FORMAT_RGBA_ASTC_5x5;
82    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_6x5:
83       return MESA_FORMAT_RGBA_ASTC_6x5;
84    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_6x6:
85       return MESA_FORMAT_RGBA_ASTC_6x6;
86    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_8x5:
87       return MESA_FORMAT_RGBA_ASTC_8x5;
88    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_8x6:
89       return MESA_FORMAT_RGBA_ASTC_8x6;
90    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_8x8:
91       return MESA_FORMAT_RGBA_ASTC_8x8;
92    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_10x5:
93       return MESA_FORMAT_RGBA_ASTC_10x5;
94    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_10x6:
95       return MESA_FORMAT_RGBA_ASTC_10x6;
96    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_10x8:
97       return MESA_FORMAT_RGBA_ASTC_10x8;
98    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_10x10:
99       return MESA_FORMAT_RGBA_ASTC_10x10;
100    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_12x10:
101       return MESA_FORMAT_RGBA_ASTC_12x10;
102    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_12x12:
103       return MESA_FORMAT_RGBA_ASTC_12x12;
104    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_3x3x3:
105       return MESA_FORMAT_RGBA_ASTC_3x3x3;
106    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_4x3x3:
107       return MESA_FORMAT_RGBA_ASTC_4x3x3;
108    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_4x4x3:
109       return MESA_FORMAT_RGBA_ASTC_4x4x3;
110    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_4x4x4:
111       return MESA_FORMAT_RGBA_ASTC_4x4x4;
112    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_5x4x4:
113       return MESA_FORMAT_RGBA_ASTC_5x4x4;
114    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_5x5x4:
115       return MESA_FORMAT_RGBA_ASTC_5x5x4;
116    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_5x5x5:
117       return MESA_FORMAT_RGBA_ASTC_5x5x5;
118    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_6x5x5:
119       return MESA_FORMAT_RGBA_ASTC_6x5x5;
120    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_6x6x5:
121       return MESA_FORMAT_RGBA_ASTC_6x6x5;
122    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_6x6x6:
123       return MESA_FORMAT_RGBA_ASTC_6x6x6;
124    default:
125       return format;
126    }
127 }
128 
129 /**
130  * For a linear format, return the corresponding sRGB color space format.
131  * For an sRGB format, return the format as-is.
132  * Assert-fails if the format is not sRGB and does not have an sRGB equivalent.
133  */
134 mesa_format
_mesa_get_linear_format_srgb(mesa_format format)135 _mesa_get_linear_format_srgb(mesa_format format)
136 {
137    switch (format) {
138    case MESA_FORMAT_A8B8G8R8_UNORM:
139       return MESA_FORMAT_A8B8G8R8_SRGB;
140    case MESA_FORMAT_B8G8R8A8_UNORM:
141       return MESA_FORMAT_B8G8R8A8_SRGB;
142    case MESA_FORMAT_A8R8G8B8_UNORM:
143       return MESA_FORMAT_A8R8G8B8_SRGB;
144    case MESA_FORMAT_B8G8R8X8_UNORM:
145       return MESA_FORMAT_B8G8R8X8_SRGB;
146    case MESA_FORMAT_X8R8G8B8_UNORM:
147       return MESA_FORMAT_X8R8G8B8_SRGB;
148    case MESA_FORMAT_R8G8B8A8_UNORM:
149       return MESA_FORMAT_R8G8B8A8_SRGB;
150    case MESA_FORMAT_R8G8B8X8_UNORM:
151       return MESA_FORMAT_R8G8B8X8_SRGB;
152    case MESA_FORMAT_X8B8G8R8_UNORM:
153       return MESA_FORMAT_X8B8G8R8_SRGB;
154    case MESA_FORMAT_L8A8_UNORM:
155       return MESA_FORMAT_L8A8_SRGB;
156    case MESA_FORMAT_A8L8_UNORM:
157       return MESA_FORMAT_A8L8_SRGB;
158    case MESA_FORMAT_L_UNORM8:
159       return MESA_FORMAT_L_SRGB8;
160    case MESA_FORMAT_BGR_UNORM8:
161       return MESA_FORMAT_BGR_SRGB8;
162    case MESA_FORMAT_RGB_DXT1:
163       return MESA_FORMAT_SRGB_DXT1;
164    case MESA_FORMAT_RGBA_DXT1:
165       return MESA_FORMAT_SRGBA_DXT1;
166    case MESA_FORMAT_RGBA_DXT3:
167       return MESA_FORMAT_SRGBA_DXT3;
168    case MESA_FORMAT_RGBA_DXT5:
169       return MESA_FORMAT_SRGBA_DXT5;
170    case MESA_FORMAT_ETC2_RGB8:
171       return MESA_FORMAT_ETC2_SRGB8;
172    case MESA_FORMAT_ETC2_RGBA8_EAC:
173       return MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC;
174    case MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1:
175       return MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1;
176    case MESA_FORMAT_BPTC_RGBA_UNORM:
177       return MESA_FORMAT_BPTC_SRGB_ALPHA_UNORM;
178    case MESA_FORMAT_RGBA_ASTC_4x4:
179       return MESA_FORMAT_SRGB8_ALPHA8_ASTC_4x4;
180    case MESA_FORMAT_RGBA_ASTC_5x4:
181       return MESA_FORMAT_SRGB8_ALPHA8_ASTC_5x4;
182    case MESA_FORMAT_RGBA_ASTC_5x5:
183       return MESA_FORMAT_SRGB8_ALPHA8_ASTC_5x5;
184    case MESA_FORMAT_RGBA_ASTC_6x5:
185       return MESA_FORMAT_SRGB8_ALPHA8_ASTC_6x5;
186    case MESA_FORMAT_RGBA_ASTC_6x6:
187       return MESA_FORMAT_SRGB8_ALPHA8_ASTC_6x6;
188    case MESA_FORMAT_RGBA_ASTC_8x5:
189       return MESA_FORMAT_SRGB8_ALPHA8_ASTC_8x5;
190    case MESA_FORMAT_RGBA_ASTC_8x6:
191       return MESA_FORMAT_SRGB8_ALPHA8_ASTC_8x6;
192    case MESA_FORMAT_RGBA_ASTC_8x8:
193       return MESA_FORMAT_SRGB8_ALPHA8_ASTC_8x8;
194    case MESA_FORMAT_RGBA_ASTC_10x5:
195       return MESA_FORMAT_SRGB8_ALPHA8_ASTC_10x5;
196    case MESA_FORMAT_RGBA_ASTC_10x6:
197       return MESA_FORMAT_SRGB8_ALPHA8_ASTC_10x6;
198    case MESA_FORMAT_RGBA_ASTC_10x8:
199       return MESA_FORMAT_SRGB8_ALPHA8_ASTC_10x8;
200    case MESA_FORMAT_RGBA_ASTC_10x10:
201       return MESA_FORMAT_SRGB8_ALPHA8_ASTC_10x10;
202    case MESA_FORMAT_RGBA_ASTC_12x10:
203       return MESA_FORMAT_SRGB8_ALPHA8_ASTC_12x10;
204    case MESA_FORMAT_RGBA_ASTC_12x12:
205       return MESA_FORMAT_SRGB8_ALPHA8_ASTC_12x12;
206    case MESA_FORMAT_RGBA_ASTC_3x3x3:
207       return MESA_FORMAT_SRGB8_ALPHA8_ASTC_3x3x3;
208    case MESA_FORMAT_RGBA_ASTC_4x3x3:
209       return MESA_FORMAT_SRGB8_ALPHA8_ASTC_4x3x3;
210    case MESA_FORMAT_RGBA_ASTC_4x4x3:
211       return MESA_FORMAT_SRGB8_ALPHA8_ASTC_4x4x3;
212    case MESA_FORMAT_RGBA_ASTC_4x4x4:
213       return MESA_FORMAT_SRGB8_ALPHA8_ASTC_4x4x4;
214    case MESA_FORMAT_RGBA_ASTC_5x4x4:
215       return MESA_FORMAT_SRGB8_ALPHA8_ASTC_5x4x4;
216    case MESA_FORMAT_RGBA_ASTC_5x5x4:
217       return MESA_FORMAT_SRGB8_ALPHA8_ASTC_5x5x4;
218    case MESA_FORMAT_RGBA_ASTC_5x5x5:
219       return MESA_FORMAT_SRGB8_ALPHA8_ASTC_5x5x5;
220    case MESA_FORMAT_RGBA_ASTC_6x5x5:
221       return MESA_FORMAT_SRGB8_ALPHA8_ASTC_6x5x5;
222    case MESA_FORMAT_RGBA_ASTC_6x6x5:
223       return MESA_FORMAT_SRGB8_ALPHA8_ASTC_6x6x5;
224    case MESA_FORMAT_RGBA_ASTC_6x6x6:
225       return MESA_FORMAT_SRGB8_ALPHA8_ASTC_6x6x6;
226    case MESA_FORMAT_A8B8G8R8_SRGB:
227    case MESA_FORMAT_B8G8R8A8_SRGB:
228    case MESA_FORMAT_A8R8G8B8_SRGB:
229    case MESA_FORMAT_B8G8R8X8_SRGB:
230    case MESA_FORMAT_X8R8G8B8_SRGB:
231    case MESA_FORMAT_R8G8B8A8_SRGB:
232    case MESA_FORMAT_R8G8B8X8_SRGB:
233    case MESA_FORMAT_X8B8G8R8_SRGB:
234    case MESA_FORMAT_L8A8_SRGB:
235    case MESA_FORMAT_A8L8_SRGB:
236    case MESA_FORMAT_L_SRGB8:
237    case MESA_FORMAT_BGR_SRGB8:
238    case MESA_FORMAT_SRGB_DXT1:
239    case MESA_FORMAT_SRGBA_DXT1:
240    case MESA_FORMAT_SRGBA_DXT3:
241    case MESA_FORMAT_SRGBA_DXT5:
242    case MESA_FORMAT_ETC2_SRGB8:
243    case MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC:
244    case MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1:
245    case MESA_FORMAT_BPTC_SRGB_ALPHA_UNORM:
246    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_4x4:
247    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_5x4:
248    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_5x5:
249    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_6x5:
250    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_6x6:
251    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_8x5:
252    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_8x6:
253    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_8x8:
254    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_10x5:
255    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_10x6:
256    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_10x8:
257    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_10x10:
258    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_12x10:
259    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_12x12:
260    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_3x3x3:
261    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_4x3x3:
262    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_4x4x3:
263    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_4x4x4:
264    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_5x4x4:
265    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_5x5x4:
266    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_5x5x5:
267    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_6x5x5:
268    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_6x6x5:
269    case MESA_FORMAT_SRGB8_ALPHA8_ASTC_6x6x6:
270       return format;
271    default:
272       unreachable("Given format does not have an sRGB equivalent");
273    }
274 }
275 
276 /**
277  * If the format has an alpha channel, and there exists a non-alpha
278  * variant of the format with an identical bit layout, then return
279  * the non-alpha format. Otherwise return the original format.
280  *
281  * Examples:
282  *    Fallback exists:
283  *       MESA_FORMAT_R8G8B8X8_UNORM -> MESA_FORMAT_R8G8B8A8_UNORM
284  *       MESA_FORMAT_RGBX_UNORM16 -> MESA_FORMAT_RGBA_UNORM16
285  *
286  *    No fallback:
287  *       MESA_FORMAT_R8G8B8A8_UNORM -> MESA_FORMAT_R8G8B8A8_UNORM
288  *       MESA_FORMAT_Z_FLOAT32 -> MESA_FORMAT_Z_FLOAT32
289  */
290 mesa_format
_mesa_format_fallback_rgbx_to_rgba(mesa_format format)291 _mesa_format_fallback_rgbx_to_rgba(mesa_format format)
292 {
293    switch (format) {
294    case MESA_FORMAT_X8B8G8R8_UNORM:
295       return MESA_FORMAT_A8B8G8R8_UNORM;
296    case MESA_FORMAT_R8G8B8X8_UNORM:
297       return MESA_FORMAT_R8G8B8A8_UNORM;
298    case MESA_FORMAT_B8G8R8X8_UNORM:
299       return MESA_FORMAT_B8G8R8A8_UNORM;
300    case MESA_FORMAT_X8R8G8B8_UNORM:
301       return MESA_FORMAT_A8R8G8B8_UNORM;
302    case MESA_FORMAT_B4G4R4X4_UNORM:
303       return MESA_FORMAT_B4G4R4A4_UNORM;
304    case MESA_FORMAT_X1B5G5R5_UNORM:
305       return MESA_FORMAT_A1B5G5R5_UNORM;
306    case MESA_FORMAT_B5G5R5X1_UNORM:
307       return MESA_FORMAT_B5G5R5A1_UNORM;
308    case MESA_FORMAT_B10G10R10X2_UNORM:
309       return MESA_FORMAT_B10G10R10A2_UNORM;
310    case MESA_FORMAT_R10G10B10X2_UNORM:
311       return MESA_FORMAT_R10G10B10A2_UNORM;
312    case MESA_FORMAT_RGBX_UNORM16:
313       return MESA_FORMAT_RGBA_UNORM16;
314    case MESA_FORMAT_X8B8G8R8_SNORM:
315       return MESA_FORMAT_A8B8G8R8_SNORM;
316    case MESA_FORMAT_R8G8B8X8_SNORM:
317       return MESA_FORMAT_R8G8B8A8_SNORM;
318    case MESA_FORMAT_RGBX_SNORM16:
319       return MESA_FORMAT_RGBA_SNORM16;
320    case MESA_FORMAT_B8G8R8X8_SRGB:
321       return MESA_FORMAT_B8G8R8A8_SRGB;
322    case MESA_FORMAT_X8R8G8B8_SRGB:
323       return MESA_FORMAT_A8R8G8B8_SRGB;
324    case MESA_FORMAT_R8G8B8X8_SRGB:
325       return MESA_FORMAT_R8G8B8A8_SRGB;
326    case MESA_FORMAT_X8B8G8R8_SRGB:
327       return MESA_FORMAT_A8B8G8R8_SRGB;
328    case MESA_FORMAT_RGBX_FLOAT16:
329       return MESA_FORMAT_RGBA_FLOAT16;
330    case MESA_FORMAT_RGBX_FLOAT32:
331       return MESA_FORMAT_RGBA_FLOAT32;
332    case MESA_FORMAT_RGBX_UINT8:
333       return MESA_FORMAT_RGBA_UINT8;
334    case MESA_FORMAT_RGBX_UINT16:
335       return MESA_FORMAT_RGBA_UINT16;
336    case MESA_FORMAT_RGBX_UINT32:
337       return MESA_FORMAT_RGBA_UINT32;
338    case MESA_FORMAT_RGBX_SINT8:
339       return MESA_FORMAT_RGBA_SINT8;
340    case MESA_FORMAT_RGBX_SINT16:
341       return MESA_FORMAT_RGBA_SINT16;
342    case MESA_FORMAT_RGBX_SINT32:
343       return MESA_FORMAT_RGBA_SINT32;
344    default:
345       return format;
346    }
347 }
348