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 */
32mesa_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_R_SRGB8:
57      return MESA_FORMAT_R_UNORM8;
58   case MESA_FORMAT_L_SRGB8:
59      return MESA_FORMAT_L_UNORM8;
60   case MESA_FORMAT_BGR_SRGB8:
61      return MESA_FORMAT_BGR_UNORM8;
62   case MESA_FORMAT_SRGB_DXT1:
63      return MESA_FORMAT_RGB_DXT1;
64   case MESA_FORMAT_SRGBA_DXT1:
65      return MESA_FORMAT_RGBA_DXT1;
66   case MESA_FORMAT_SRGBA_DXT3:
67      return MESA_FORMAT_RGBA_DXT3;
68   case MESA_FORMAT_SRGBA_DXT5:
69      return MESA_FORMAT_RGBA_DXT5;
70   case MESA_FORMAT_ETC2_SRGB8:
71      return MESA_FORMAT_ETC2_RGB8;
72   case MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC:
73      return MESA_FORMAT_ETC2_RGBA8_EAC;
74   case MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1:
75      return MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1;
76   case MESA_FORMAT_BPTC_SRGB_ALPHA_UNORM:
77      return MESA_FORMAT_BPTC_RGBA_UNORM;
78   case MESA_FORMAT_SRGB8_ALPHA8_ASTC_4x4:
79      return MESA_FORMAT_RGBA_ASTC_4x4;
80   case MESA_FORMAT_SRGB8_ALPHA8_ASTC_5x4:
81      return MESA_FORMAT_RGBA_ASTC_5x4;
82   case MESA_FORMAT_SRGB8_ALPHA8_ASTC_5x5:
83      return MESA_FORMAT_RGBA_ASTC_5x5;
84   case MESA_FORMAT_SRGB8_ALPHA8_ASTC_6x5:
85      return MESA_FORMAT_RGBA_ASTC_6x5;
86   case MESA_FORMAT_SRGB8_ALPHA8_ASTC_6x6:
87      return MESA_FORMAT_RGBA_ASTC_6x6;
88   case MESA_FORMAT_SRGB8_ALPHA8_ASTC_8x5:
89      return MESA_FORMAT_RGBA_ASTC_8x5;
90   case MESA_FORMAT_SRGB8_ALPHA8_ASTC_8x6:
91      return MESA_FORMAT_RGBA_ASTC_8x6;
92   case MESA_FORMAT_SRGB8_ALPHA8_ASTC_8x8:
93      return MESA_FORMAT_RGBA_ASTC_8x8;
94   case MESA_FORMAT_SRGB8_ALPHA8_ASTC_10x5:
95      return MESA_FORMAT_RGBA_ASTC_10x5;
96   case MESA_FORMAT_SRGB8_ALPHA8_ASTC_10x6:
97      return MESA_FORMAT_RGBA_ASTC_10x6;
98   case MESA_FORMAT_SRGB8_ALPHA8_ASTC_10x8:
99      return MESA_FORMAT_RGBA_ASTC_10x8;
100   case MESA_FORMAT_SRGB8_ALPHA8_ASTC_10x10:
101      return MESA_FORMAT_RGBA_ASTC_10x10;
102   case MESA_FORMAT_SRGB8_ALPHA8_ASTC_12x10:
103      return MESA_FORMAT_RGBA_ASTC_12x10;
104   case MESA_FORMAT_SRGB8_ALPHA8_ASTC_12x12:
105      return MESA_FORMAT_RGBA_ASTC_12x12;
106   case MESA_FORMAT_SRGB8_ALPHA8_ASTC_3x3x3:
107      return MESA_FORMAT_RGBA_ASTC_3x3x3;
108   case MESA_FORMAT_SRGB8_ALPHA8_ASTC_4x3x3:
109      return MESA_FORMAT_RGBA_ASTC_4x3x3;
110   case MESA_FORMAT_SRGB8_ALPHA8_ASTC_4x4x3:
111      return MESA_FORMAT_RGBA_ASTC_4x4x3;
112   case MESA_FORMAT_SRGB8_ALPHA8_ASTC_4x4x4:
113      return MESA_FORMAT_RGBA_ASTC_4x4x4;
114   case MESA_FORMAT_SRGB8_ALPHA8_ASTC_5x4x4:
115      return MESA_FORMAT_RGBA_ASTC_5x4x4;
116   case MESA_FORMAT_SRGB8_ALPHA8_ASTC_5x5x4:
117      return MESA_FORMAT_RGBA_ASTC_5x5x4;
118   case MESA_FORMAT_SRGB8_ALPHA8_ASTC_5x5x5:
119      return MESA_FORMAT_RGBA_ASTC_5x5x5;
120   case MESA_FORMAT_SRGB8_ALPHA8_ASTC_6x5x5:
121      return MESA_FORMAT_RGBA_ASTC_6x5x5;
122   case MESA_FORMAT_SRGB8_ALPHA8_ASTC_6x6x5:
123      return MESA_FORMAT_RGBA_ASTC_6x6x5;
124   case MESA_FORMAT_SRGB8_ALPHA8_ASTC_6x6x6:
125      return MESA_FORMAT_RGBA_ASTC_6x6x6;
126   default:
127      return format;
128   }
129}
130
131/**
132 * For a linear format, return the corresponding sRGB color space format.
133 * For an sRGB format, return the format as-is.
134 * Assert-fails if the format is not sRGB and does not have an sRGB equivalent.
135 */
136mesa_format
137_mesa_get_linear_format_srgb(mesa_format format)
138{
139   switch (format) {
140   case MESA_FORMAT_A8B8G8R8_UNORM:
141      return MESA_FORMAT_A8B8G8R8_SRGB;
142   case MESA_FORMAT_B8G8R8A8_UNORM:
143      return MESA_FORMAT_B8G8R8A8_SRGB;
144   case MESA_FORMAT_A8R8G8B8_UNORM:
145      return MESA_FORMAT_A8R8G8B8_SRGB;
146   case MESA_FORMAT_B8G8R8X8_UNORM:
147      return MESA_FORMAT_B8G8R8X8_SRGB;
148   case MESA_FORMAT_X8R8G8B8_UNORM:
149      return MESA_FORMAT_X8R8G8B8_SRGB;
150   case MESA_FORMAT_R8G8B8A8_UNORM:
151      return MESA_FORMAT_R8G8B8A8_SRGB;
152   case MESA_FORMAT_R8G8B8X8_UNORM:
153      return MESA_FORMAT_R8G8B8X8_SRGB;
154   case MESA_FORMAT_X8B8G8R8_UNORM:
155      return MESA_FORMAT_X8B8G8R8_SRGB;
156   case MESA_FORMAT_L8A8_UNORM:
157      return MESA_FORMAT_L8A8_SRGB;
158   case MESA_FORMAT_A8L8_UNORM:
159      return MESA_FORMAT_A8L8_SRGB;
160   case MESA_FORMAT_R_UNORM8:
161      return MESA_FORMAT_R_SRGB8;
162   case MESA_FORMAT_L_UNORM8:
163      return MESA_FORMAT_L_SRGB8;
164   case MESA_FORMAT_BGR_UNORM8:
165      return MESA_FORMAT_BGR_SRGB8;
166   case MESA_FORMAT_RGB_DXT1:
167      return MESA_FORMAT_SRGB_DXT1;
168   case MESA_FORMAT_RGBA_DXT1:
169      return MESA_FORMAT_SRGBA_DXT1;
170   case MESA_FORMAT_RGBA_DXT3:
171      return MESA_FORMAT_SRGBA_DXT3;
172   case MESA_FORMAT_RGBA_DXT5:
173      return MESA_FORMAT_SRGBA_DXT5;
174   case MESA_FORMAT_ETC2_RGB8:
175      return MESA_FORMAT_ETC2_SRGB8;
176   case MESA_FORMAT_ETC2_RGBA8_EAC:
177      return MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC;
178   case MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1:
179      return MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1;
180   case MESA_FORMAT_BPTC_RGBA_UNORM:
181      return MESA_FORMAT_BPTC_SRGB_ALPHA_UNORM;
182   case MESA_FORMAT_RGBA_ASTC_4x4:
183      return MESA_FORMAT_SRGB8_ALPHA8_ASTC_4x4;
184   case MESA_FORMAT_RGBA_ASTC_5x4:
185      return MESA_FORMAT_SRGB8_ALPHA8_ASTC_5x4;
186   case MESA_FORMAT_RGBA_ASTC_5x5:
187      return MESA_FORMAT_SRGB8_ALPHA8_ASTC_5x5;
188   case MESA_FORMAT_RGBA_ASTC_6x5:
189      return MESA_FORMAT_SRGB8_ALPHA8_ASTC_6x5;
190   case MESA_FORMAT_RGBA_ASTC_6x6:
191      return MESA_FORMAT_SRGB8_ALPHA8_ASTC_6x6;
192   case MESA_FORMAT_RGBA_ASTC_8x5:
193      return MESA_FORMAT_SRGB8_ALPHA8_ASTC_8x5;
194   case MESA_FORMAT_RGBA_ASTC_8x6:
195      return MESA_FORMAT_SRGB8_ALPHA8_ASTC_8x6;
196   case MESA_FORMAT_RGBA_ASTC_8x8:
197      return MESA_FORMAT_SRGB8_ALPHA8_ASTC_8x8;
198   case MESA_FORMAT_RGBA_ASTC_10x5:
199      return MESA_FORMAT_SRGB8_ALPHA8_ASTC_10x5;
200   case MESA_FORMAT_RGBA_ASTC_10x6:
201      return MESA_FORMAT_SRGB8_ALPHA8_ASTC_10x6;
202   case MESA_FORMAT_RGBA_ASTC_10x8:
203      return MESA_FORMAT_SRGB8_ALPHA8_ASTC_10x8;
204   case MESA_FORMAT_RGBA_ASTC_10x10:
205      return MESA_FORMAT_SRGB8_ALPHA8_ASTC_10x10;
206   case MESA_FORMAT_RGBA_ASTC_12x10:
207      return MESA_FORMAT_SRGB8_ALPHA8_ASTC_12x10;
208   case MESA_FORMAT_RGBA_ASTC_12x12:
209      return MESA_FORMAT_SRGB8_ALPHA8_ASTC_12x12;
210   case MESA_FORMAT_RGBA_ASTC_3x3x3:
211      return MESA_FORMAT_SRGB8_ALPHA8_ASTC_3x3x3;
212   case MESA_FORMAT_RGBA_ASTC_4x3x3:
213      return MESA_FORMAT_SRGB8_ALPHA8_ASTC_4x3x3;
214   case MESA_FORMAT_RGBA_ASTC_4x4x3:
215      return MESA_FORMAT_SRGB8_ALPHA8_ASTC_4x4x3;
216   case MESA_FORMAT_RGBA_ASTC_4x4x4:
217      return MESA_FORMAT_SRGB8_ALPHA8_ASTC_4x4x4;
218   case MESA_FORMAT_RGBA_ASTC_5x4x4:
219      return MESA_FORMAT_SRGB8_ALPHA8_ASTC_5x4x4;
220   case MESA_FORMAT_RGBA_ASTC_5x5x4:
221      return MESA_FORMAT_SRGB8_ALPHA8_ASTC_5x5x4;
222   case MESA_FORMAT_RGBA_ASTC_5x5x5:
223      return MESA_FORMAT_SRGB8_ALPHA8_ASTC_5x5x5;
224   case MESA_FORMAT_RGBA_ASTC_6x5x5:
225      return MESA_FORMAT_SRGB8_ALPHA8_ASTC_6x5x5;
226   case MESA_FORMAT_RGBA_ASTC_6x6x5:
227      return MESA_FORMAT_SRGB8_ALPHA8_ASTC_6x6x5;
228   case MESA_FORMAT_RGBA_ASTC_6x6x6:
229      return MESA_FORMAT_SRGB8_ALPHA8_ASTC_6x6x6;
230   case MESA_FORMAT_A8B8G8R8_SRGB:
231   case MESA_FORMAT_B8G8R8A8_SRGB:
232   case MESA_FORMAT_A8R8G8B8_SRGB:
233   case MESA_FORMAT_B8G8R8X8_SRGB:
234   case MESA_FORMAT_X8R8G8B8_SRGB:
235   case MESA_FORMAT_R8G8B8A8_SRGB:
236   case MESA_FORMAT_R8G8B8X8_SRGB:
237   case MESA_FORMAT_X8B8G8R8_SRGB:
238   case MESA_FORMAT_L8A8_SRGB:
239   case MESA_FORMAT_A8L8_SRGB:
240   case MESA_FORMAT_R_SRGB8:
241   case MESA_FORMAT_L_SRGB8:
242   case MESA_FORMAT_BGR_SRGB8:
243   case MESA_FORMAT_SRGB_DXT1:
244   case MESA_FORMAT_SRGBA_DXT1:
245   case MESA_FORMAT_SRGBA_DXT3:
246   case MESA_FORMAT_SRGBA_DXT5:
247   case MESA_FORMAT_ETC2_SRGB8:
248   case MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC:
249   case MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1:
250   case MESA_FORMAT_BPTC_SRGB_ALPHA_UNORM:
251   case MESA_FORMAT_SRGB8_ALPHA8_ASTC_4x4:
252   case MESA_FORMAT_SRGB8_ALPHA8_ASTC_5x4:
253   case MESA_FORMAT_SRGB8_ALPHA8_ASTC_5x5:
254   case MESA_FORMAT_SRGB8_ALPHA8_ASTC_6x5:
255   case MESA_FORMAT_SRGB8_ALPHA8_ASTC_6x6:
256   case MESA_FORMAT_SRGB8_ALPHA8_ASTC_8x5:
257   case MESA_FORMAT_SRGB8_ALPHA8_ASTC_8x6:
258   case MESA_FORMAT_SRGB8_ALPHA8_ASTC_8x8:
259   case MESA_FORMAT_SRGB8_ALPHA8_ASTC_10x5:
260   case MESA_FORMAT_SRGB8_ALPHA8_ASTC_10x6:
261   case MESA_FORMAT_SRGB8_ALPHA8_ASTC_10x8:
262   case MESA_FORMAT_SRGB8_ALPHA8_ASTC_10x10:
263   case MESA_FORMAT_SRGB8_ALPHA8_ASTC_12x10:
264   case MESA_FORMAT_SRGB8_ALPHA8_ASTC_12x12:
265   case MESA_FORMAT_SRGB8_ALPHA8_ASTC_3x3x3:
266   case MESA_FORMAT_SRGB8_ALPHA8_ASTC_4x3x3:
267   case MESA_FORMAT_SRGB8_ALPHA8_ASTC_4x4x3:
268   case MESA_FORMAT_SRGB8_ALPHA8_ASTC_4x4x4:
269   case MESA_FORMAT_SRGB8_ALPHA8_ASTC_5x4x4:
270   case MESA_FORMAT_SRGB8_ALPHA8_ASTC_5x5x4:
271   case MESA_FORMAT_SRGB8_ALPHA8_ASTC_5x5x5:
272   case MESA_FORMAT_SRGB8_ALPHA8_ASTC_6x5x5:
273   case MESA_FORMAT_SRGB8_ALPHA8_ASTC_6x6x5:
274   case MESA_FORMAT_SRGB8_ALPHA8_ASTC_6x6x6:
275      return format;
276   default:
277      unreachable("Given format does not have an sRGB equivalent");
278   }
279}
280
281/**
282 * If the format has an alpha channel, and there exists a non-alpha
283 * variant of the format with an identical bit layout, then return
284 * the non-alpha format. Otherwise return the original format.
285 *
286 * Examples:
287 *    Fallback exists:
288 *       MESA_FORMAT_R8G8B8X8_UNORM -> MESA_FORMAT_R8G8B8A8_UNORM
289 *       MESA_FORMAT_RGBX_UNORM16 -> MESA_FORMAT_RGBA_UNORM16
290 *
291 *    No fallback:
292 *       MESA_FORMAT_R8G8B8A8_UNORM -> MESA_FORMAT_R8G8B8A8_UNORM
293 *       MESA_FORMAT_Z_FLOAT32 -> MESA_FORMAT_Z_FLOAT32
294 */
295mesa_format
296_mesa_format_fallback_rgbx_to_rgba(mesa_format format)
297{
298   switch (format) {
299   case MESA_FORMAT_X8B8G8R8_UNORM:
300      return MESA_FORMAT_A8B8G8R8_UNORM;
301   case MESA_FORMAT_R8G8B8X8_UNORM:
302      return MESA_FORMAT_R8G8B8A8_UNORM;
303   case MESA_FORMAT_B8G8R8X8_UNORM:
304      return MESA_FORMAT_B8G8R8A8_UNORM;
305   case MESA_FORMAT_X8R8G8B8_UNORM:
306      return MESA_FORMAT_A8R8G8B8_UNORM;
307   case MESA_FORMAT_B4G4R4X4_UNORM:
308      return MESA_FORMAT_B4G4R4A4_UNORM;
309   case MESA_FORMAT_X1B5G5R5_UNORM:
310      return MESA_FORMAT_A1B5G5R5_UNORM;
311   case MESA_FORMAT_B5G5R5X1_UNORM:
312      return MESA_FORMAT_B5G5R5A1_UNORM;
313   case MESA_FORMAT_B10G10R10X2_UNORM:
314      return MESA_FORMAT_B10G10R10A2_UNORM;
315   case MESA_FORMAT_R10G10B10X2_UNORM:
316      return MESA_FORMAT_R10G10B10A2_UNORM;
317   case MESA_FORMAT_RGBX_UNORM16:
318      return MESA_FORMAT_RGBA_UNORM16;
319   case MESA_FORMAT_X8B8G8R8_SNORM:
320      return MESA_FORMAT_A8B8G8R8_SNORM;
321   case MESA_FORMAT_R8G8B8X8_SNORM:
322      return MESA_FORMAT_R8G8B8A8_SNORM;
323   case MESA_FORMAT_RGBX_SNORM16:
324      return MESA_FORMAT_RGBA_SNORM16;
325   case MESA_FORMAT_B8G8R8X8_SRGB:
326      return MESA_FORMAT_B8G8R8A8_SRGB;
327   case MESA_FORMAT_X8R8G8B8_SRGB:
328      return MESA_FORMAT_A8R8G8B8_SRGB;
329   case MESA_FORMAT_R8G8B8X8_SRGB:
330      return MESA_FORMAT_R8G8B8A8_SRGB;
331   case MESA_FORMAT_X8B8G8R8_SRGB:
332      return MESA_FORMAT_A8B8G8R8_SRGB;
333   case MESA_FORMAT_RGBX_FLOAT16:
334      return MESA_FORMAT_RGBA_FLOAT16;
335   case MESA_FORMAT_RGBX_FLOAT32:
336      return MESA_FORMAT_RGBA_FLOAT32;
337   case MESA_FORMAT_RGBX_UINT8:
338      return MESA_FORMAT_RGBA_UINT8;
339   case MESA_FORMAT_RGBX_UINT16:
340      return MESA_FORMAT_RGBA_UINT16;
341   case MESA_FORMAT_RGBX_UINT32:
342      return MESA_FORMAT_RGBA_UINT32;
343   case MESA_FORMAT_RGBX_SINT8:
344      return MESA_FORMAT_RGBA_SINT8;
345   case MESA_FORMAT_RGBX_SINT16:
346      return MESA_FORMAT_RGBA_SINT16;
347   case MESA_FORMAT_RGBX_SINT32:
348      return MESA_FORMAT_RGBA_SINT32;
349   default:
350      return format;
351   }
352}
353