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