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_R_SRGB8:
53 return MESA_FORMAT_R_UNORM8;
54 case MESA_FORMAT_L_SRGB8:
55 return MESA_FORMAT_L_UNORM8;
56 case MESA_FORMAT_LA_SRGB8:
57 return MESA_FORMAT_LA_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_R_UNORM8:
155 return MESA_FORMAT_R_SRGB8;
156 case MESA_FORMAT_L_UNORM8:
157 return MESA_FORMAT_L_SRGB8;
158 case MESA_FORMAT_LA_UNORM8:
159 return MESA_FORMAT_LA_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_R_SRGB8:
235 case MESA_FORMAT_L_SRGB8:
236 case MESA_FORMAT_LA_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 * For an intensity format, return the corresponding red format. For other
278 * formats, return the format as-is.
279 */
280 mesa_format
_mesa_get_intensity_format_red(mesa_format format)281 _mesa_get_intensity_format_red(mesa_format format)
282 {
283 switch (format) {
284 case MESA_FORMAT_I_UNORM8:
285 return MESA_FORMAT_R_UNORM8;
286 case MESA_FORMAT_I_UNORM16:
287 return MESA_FORMAT_R_UNORM16;
288 case MESA_FORMAT_I_SNORM8:
289 return MESA_FORMAT_R_SNORM8;
290 case MESA_FORMAT_I_SNORM16:
291 return MESA_FORMAT_R_SNORM16;
292 case MESA_FORMAT_I_FLOAT16:
293 return MESA_FORMAT_R_FLOAT16;
294 case MESA_FORMAT_I_FLOAT32:
295 return MESA_FORMAT_R_FLOAT32;
296 case MESA_FORMAT_I_UINT8:
297 return MESA_FORMAT_R_UINT8;
298 case MESA_FORMAT_I_UINT16:
299 return MESA_FORMAT_R_UINT16;
300 case MESA_FORMAT_I_UINT32:
301 return MESA_FORMAT_R_UINT32;
302 case MESA_FORMAT_I_SINT8:
303 return MESA_FORMAT_R_SINT8;
304 case MESA_FORMAT_I_SINT16:
305 return MESA_FORMAT_R_SINT16;
306 case MESA_FORMAT_I_SINT32:
307 return MESA_FORMAT_R_SINT32;
308 default:
309 return format;
310 }
311 }
312
313 /**
314 * If the format has an alpha channel, and there exists a non-alpha
315 * variant of the format with an identical bit layout, then return
316 * the non-alpha format. Otherwise return the original format.
317 *
318 * Examples:
319 * Fallback exists:
320 * MESA_FORMAT_R8G8B8X8_UNORM -> MESA_FORMAT_R8G8B8A8_UNORM
321 * MESA_FORMAT_RGBX_UNORM16 -> MESA_FORMAT_RGBA_UNORM16
322 *
323 * No fallback:
324 * MESA_FORMAT_R8G8B8A8_UNORM -> MESA_FORMAT_R8G8B8A8_UNORM
325 * MESA_FORMAT_Z_FLOAT32 -> MESA_FORMAT_Z_FLOAT32
326 */
327 mesa_format
_mesa_format_fallback_rgbx_to_rgba(mesa_format format)328 _mesa_format_fallback_rgbx_to_rgba(mesa_format format)
329 {
330 switch (format) {
331 case MESA_FORMAT_X8B8G8R8_UNORM:
332 return MESA_FORMAT_A8B8G8R8_UNORM;
333 case MESA_FORMAT_R8G8B8X8_UNORM:
334 return MESA_FORMAT_R8G8B8A8_UNORM;
335 case MESA_FORMAT_B8G8R8X8_UNORM:
336 return MESA_FORMAT_B8G8R8A8_UNORM;
337 case MESA_FORMAT_X8R8G8B8_UNORM:
338 return MESA_FORMAT_A8R8G8B8_UNORM;
339 case MESA_FORMAT_B4G4R4X4_UNORM:
340 return MESA_FORMAT_B4G4R4A4_UNORM;
341 case MESA_FORMAT_X1B5G5R5_UNORM:
342 return MESA_FORMAT_A1B5G5R5_UNORM;
343 case MESA_FORMAT_B5G5R5X1_UNORM:
344 return MESA_FORMAT_B5G5R5A1_UNORM;
345 case MESA_FORMAT_B10G10R10X2_UNORM:
346 return MESA_FORMAT_B10G10R10A2_UNORM;
347 case MESA_FORMAT_R10G10B10X2_UNORM:
348 return MESA_FORMAT_R10G10B10A2_UNORM;
349 case MESA_FORMAT_RGBX_UNORM16:
350 return MESA_FORMAT_RGBA_UNORM16;
351 case MESA_FORMAT_X8B8G8R8_SNORM:
352 return MESA_FORMAT_A8B8G8R8_SNORM;
353 case MESA_FORMAT_R8G8B8X8_SNORM:
354 return MESA_FORMAT_R8G8B8A8_SNORM;
355 case MESA_FORMAT_RGBX_SNORM16:
356 return MESA_FORMAT_RGBA_SNORM16;
357 case MESA_FORMAT_B8G8R8X8_SRGB:
358 return MESA_FORMAT_B8G8R8A8_SRGB;
359 case MESA_FORMAT_X8R8G8B8_SRGB:
360 return MESA_FORMAT_A8R8G8B8_SRGB;
361 case MESA_FORMAT_R8G8B8X8_SRGB:
362 return MESA_FORMAT_R8G8B8A8_SRGB;
363 case MESA_FORMAT_X8B8G8R8_SRGB:
364 return MESA_FORMAT_A8B8G8R8_SRGB;
365 case MESA_FORMAT_RGBX_FLOAT16:
366 return MESA_FORMAT_RGBA_FLOAT16;
367 case MESA_FORMAT_RGBX_FLOAT32:
368 return MESA_FORMAT_RGBA_FLOAT32;
369 case MESA_FORMAT_RGBX_UINT16:
370 return MESA_FORMAT_RGBA_UINT16;
371 case MESA_FORMAT_RGBX_UINT32:
372 return MESA_FORMAT_RGBA_UINT32;
373 case MESA_FORMAT_RGBX_SINT8:
374 return MESA_FORMAT_RGBA_SINT8;
375 case MESA_FORMAT_RGBX_SINT16:
376 return MESA_FORMAT_RGBA_SINT16;
377 case MESA_FORMAT_RGBX_SINT32:
378 return MESA_FORMAT_RGBA_SINT32;
379 default:
380 return format;
381 }
382 }
383