3260297c6c1c18e03b748115fe1aaf59de857bfd
[mesa.git] / src / mesa / state_tracker / st_format.c
1 /**************************************************************************
2 *
3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * Copyright (c) 2008-2010 VMware, Inc.
5 * All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sub license, and/or sell copies of the Software, and to
12 * permit persons to whom the Software is furnished to do so, subject to
13 * the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the
16 * next paragraph) shall be included in all copies or substantial portions
17 * of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
23 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 *
27 **************************************************************************/
28
29
30 /**
31 * Mesa / Gallium format conversion and format selection code.
32 * \author Brian Paul
33 */
34
35 #include "main/imports.h"
36 #include "main/context.h"
37 #include "main/texstore.h"
38 #include "main/image.h"
39 #include "main/macros.h"
40 #include "main/mfeatures.h"
41
42 #include "pipe/p_context.h"
43 #include "pipe/p_defines.h"
44 #include "pipe/p_screen.h"
45 #include "util/u_format.h"
46 #include "st_context.h"
47 #include "st_format.h"
48
49
50 static GLuint
51 format_max_bits(enum pipe_format format)
52 {
53 GLuint size = util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 0);
54
55 size = MAX2(size, util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 1));
56 size = MAX2(size, util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 2));
57 size = MAX2(size, util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 3));
58 size = MAX2(size, util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 0));
59 size = MAX2(size, util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_ZS, 1));
60 return size;
61 }
62
63
64 /**
65 * Return basic GL datatype for the given gallium format.
66 */
67 GLenum
68 st_format_datatype(enum pipe_format format)
69 {
70 const struct util_format_description *desc;
71 int i;
72
73 desc = util_format_description(format);
74 assert(desc);
75
76 /* Find the first non-VOID channel. */
77 for (i = 0; i < 4; i++) {
78 if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) {
79 break;
80 }
81 }
82
83 if (desc->layout == UTIL_FORMAT_LAYOUT_PLAIN) {
84 if (format == PIPE_FORMAT_B5G5R5A1_UNORM ||
85 format == PIPE_FORMAT_B5G6R5_UNORM) {
86 return GL_UNSIGNED_SHORT;
87 }
88 else if (format == PIPE_FORMAT_Z24_UNORM_S8_USCALED ||
89 format == PIPE_FORMAT_S8_USCALED_Z24_UNORM ||
90 format == PIPE_FORMAT_Z24X8_UNORM ||
91 format == PIPE_FORMAT_X8Z24_UNORM) {
92 return GL_UNSIGNED_INT_24_8;
93 }
94 else {
95 const GLuint size = format_max_bits(format);
96
97 assert(i < 4);
98 if (i == 4)
99 return GL_NONE;
100
101 if (size == 8) {
102 if (desc->channel[i].type == UTIL_FORMAT_TYPE_UNSIGNED)
103 return GL_UNSIGNED_BYTE;
104 else
105 return GL_BYTE;
106 }
107 else if (size == 16) {
108 if (desc->channel[i].type == UTIL_FORMAT_TYPE_UNSIGNED)
109 return GL_UNSIGNED_SHORT;
110 else
111 return GL_SHORT;
112 }
113 else {
114 assert( size <= 32 );
115 if (desc->channel[i].type == UTIL_FORMAT_TYPE_UNSIGNED)
116 return GL_UNSIGNED_INT;
117 else
118 return GL_INT;
119 }
120 }
121 }
122 else if (format == PIPE_FORMAT_UYVY) {
123 return GL_UNSIGNED_SHORT;
124 }
125 else if (format == PIPE_FORMAT_YUYV) {
126 return GL_UNSIGNED_SHORT;
127 }
128 else {
129 /* probably a compressed format, unsupported anyway */
130 return GL_NONE;
131 }
132 }
133
134
135 /**
136 * Translate Mesa format to Gallium format.
137 */
138 enum pipe_format
139 st_mesa_format_to_pipe_format(gl_format mesaFormat)
140 {
141 switch (mesaFormat) {
142 case MESA_FORMAT_RGBA8888:
143 return PIPE_FORMAT_A8B8G8R8_UNORM;
144 case MESA_FORMAT_RGBA8888_REV:
145 return PIPE_FORMAT_R8G8B8A8_UNORM;
146 case MESA_FORMAT_ARGB8888:
147 return PIPE_FORMAT_B8G8R8A8_UNORM;
148 case MESA_FORMAT_ARGB8888_REV:
149 return PIPE_FORMAT_A8R8G8B8_UNORM;
150 case MESA_FORMAT_XRGB8888:
151 return PIPE_FORMAT_B8G8R8X8_UNORM;
152 case MESA_FORMAT_XRGB8888_REV:
153 return PIPE_FORMAT_X8R8G8B8_UNORM;
154 case MESA_FORMAT_ARGB1555:
155 return PIPE_FORMAT_B5G5R5A1_UNORM;
156 case MESA_FORMAT_ARGB4444:
157 return PIPE_FORMAT_B4G4R4A4_UNORM;
158 case MESA_FORMAT_RGB565:
159 return PIPE_FORMAT_B5G6R5_UNORM;
160 case MESA_FORMAT_RGB332:
161 return PIPE_FORMAT_B2G3R3_UNORM;
162 case MESA_FORMAT_ARGB2101010:
163 return PIPE_FORMAT_B10G10R10A2_UNORM;
164 case MESA_FORMAT_AL44:
165 return PIPE_FORMAT_L4A4_UNORM;
166 case MESA_FORMAT_AL88:
167 return PIPE_FORMAT_L8A8_UNORM;
168 case MESA_FORMAT_AL1616:
169 return PIPE_FORMAT_L16A16_UNORM;
170 case MESA_FORMAT_A8:
171 return PIPE_FORMAT_A8_UNORM;
172 case MESA_FORMAT_A16:
173 return PIPE_FORMAT_A16_UNORM;
174 case MESA_FORMAT_L8:
175 return PIPE_FORMAT_L8_UNORM;
176 case MESA_FORMAT_L16:
177 return PIPE_FORMAT_L16_UNORM;
178 case MESA_FORMAT_I8:
179 return PIPE_FORMAT_I8_UNORM;
180 case MESA_FORMAT_I16:
181 return PIPE_FORMAT_I16_UNORM;
182 case MESA_FORMAT_Z16:
183 return PIPE_FORMAT_Z16_UNORM;
184 case MESA_FORMAT_Z32:
185 return PIPE_FORMAT_Z32_UNORM;
186 case MESA_FORMAT_Z24_S8:
187 return PIPE_FORMAT_S8_USCALED_Z24_UNORM;
188 case MESA_FORMAT_S8_Z24:
189 return PIPE_FORMAT_Z24_UNORM_S8_USCALED;
190 case MESA_FORMAT_Z24_X8:
191 return PIPE_FORMAT_X8Z24_UNORM;
192 case MESA_FORMAT_X8_Z24:
193 return PIPE_FORMAT_Z24X8_UNORM;
194 case MESA_FORMAT_S8:
195 return PIPE_FORMAT_S8_USCALED;
196 case MESA_FORMAT_YCBCR:
197 return PIPE_FORMAT_UYVY;
198 #if FEATURE_texture_s3tc
199 case MESA_FORMAT_RGB_DXT1:
200 return PIPE_FORMAT_DXT1_RGB;
201 case MESA_FORMAT_RGBA_DXT1:
202 return PIPE_FORMAT_DXT1_RGBA;
203 case MESA_FORMAT_RGBA_DXT3:
204 return PIPE_FORMAT_DXT3_RGBA;
205 case MESA_FORMAT_RGBA_DXT5:
206 return PIPE_FORMAT_DXT5_RGBA;
207 #if FEATURE_EXT_texture_sRGB
208 case MESA_FORMAT_SRGB_DXT1:
209 return PIPE_FORMAT_DXT1_SRGB;
210 case MESA_FORMAT_SRGBA_DXT1:
211 return PIPE_FORMAT_DXT1_SRGBA;
212 case MESA_FORMAT_SRGBA_DXT3:
213 return PIPE_FORMAT_DXT3_SRGBA;
214 case MESA_FORMAT_SRGBA_DXT5:
215 return PIPE_FORMAT_DXT5_SRGBA;
216 #endif
217 #endif
218 #if FEATURE_EXT_texture_sRGB
219 case MESA_FORMAT_SLA8:
220 return PIPE_FORMAT_L8A8_SRGB;
221 case MESA_FORMAT_SL8:
222 return PIPE_FORMAT_L8_SRGB;
223 case MESA_FORMAT_SRGB8:
224 return PIPE_FORMAT_R8G8B8_SRGB;
225 case MESA_FORMAT_SRGBA8:
226 return PIPE_FORMAT_A8B8G8R8_SRGB;
227 case MESA_FORMAT_SARGB8:
228 return PIPE_FORMAT_B8G8R8A8_SRGB;
229 #endif
230 case MESA_FORMAT_RGBA_FLOAT32:
231 return PIPE_FORMAT_R32G32B32A32_FLOAT;
232 case MESA_FORMAT_RGBA_FLOAT16:
233 return PIPE_FORMAT_R16G16B16A16_FLOAT;
234 case MESA_FORMAT_RGB_FLOAT32:
235 return PIPE_FORMAT_R32G32B32_FLOAT;
236 case MESA_FORMAT_RGB_FLOAT16:
237 return PIPE_FORMAT_R16G16B16_FLOAT;
238 case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32:
239 return PIPE_FORMAT_L32A32_FLOAT;
240 case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16:
241 return PIPE_FORMAT_L16A16_FLOAT;
242 case MESA_FORMAT_LUMINANCE_FLOAT32:
243 return PIPE_FORMAT_L32_FLOAT;
244 case MESA_FORMAT_LUMINANCE_FLOAT16:
245 return PIPE_FORMAT_L16_FLOAT;
246 case MESA_FORMAT_ALPHA_FLOAT32:
247 return PIPE_FORMAT_A32_FLOAT;
248 case MESA_FORMAT_ALPHA_FLOAT16:
249 return PIPE_FORMAT_A16_FLOAT;
250 case MESA_FORMAT_INTENSITY_FLOAT32:
251 return PIPE_FORMAT_I32_FLOAT;
252 case MESA_FORMAT_INTENSITY_FLOAT16:
253 return PIPE_FORMAT_I16_FLOAT;
254 case MESA_FORMAT_R_FLOAT32:
255 return PIPE_FORMAT_R32_FLOAT;
256 case MESA_FORMAT_R_FLOAT16:
257 return PIPE_FORMAT_R16_FLOAT;
258 case MESA_FORMAT_RG_FLOAT32:
259 return PIPE_FORMAT_R32G32_FLOAT;
260 case MESA_FORMAT_RG_FLOAT16:
261 return PIPE_FORMAT_R16G16_FLOAT;
262
263 case MESA_FORMAT_R8:
264 return PIPE_FORMAT_R8_UNORM;
265 case MESA_FORMAT_R16:
266 return PIPE_FORMAT_R16_UNORM;
267 case MESA_FORMAT_RG88:
268 return PIPE_FORMAT_R8G8_UNORM;
269 case MESA_FORMAT_RG1616:
270 return PIPE_FORMAT_R16G16_UNORM;
271 case MESA_FORMAT_RGBA_16:
272 return PIPE_FORMAT_R16G16B16A16_UNORM;
273
274 /* signed int formats */
275 case MESA_FORMAT_RGBA_INT8:
276 return PIPE_FORMAT_R8G8B8A8_SSCALED;
277 case MESA_FORMAT_RGBA_INT16:
278 return PIPE_FORMAT_R16G16B16A16_SSCALED;
279 case MESA_FORMAT_RGBA_INT32:
280 return PIPE_FORMAT_R32G32B32A32_SSCALED;
281
282 /* unsigned int formats */
283 case MESA_FORMAT_RGBA_UINT8:
284 return PIPE_FORMAT_R8G8B8A8_USCALED;
285 case MESA_FORMAT_RGBA_UINT16:
286 return PIPE_FORMAT_R16G16B16A16_USCALED;
287 case MESA_FORMAT_RGBA_UINT32:
288 return PIPE_FORMAT_R32G32B32A32_USCALED;
289
290 case MESA_FORMAT_RED_RGTC1:
291 return PIPE_FORMAT_RGTC1_UNORM;
292 case MESA_FORMAT_SIGNED_RED_RGTC1:
293 return PIPE_FORMAT_RGTC1_SNORM;
294 case MESA_FORMAT_RG_RGTC2:
295 return PIPE_FORMAT_RGTC2_UNORM;
296 case MESA_FORMAT_SIGNED_RG_RGTC2:
297 return PIPE_FORMAT_RGTC2_SNORM;
298
299 case MESA_FORMAT_L_LATC1:
300 return PIPE_FORMAT_LATC1_UNORM;
301 case MESA_FORMAT_SIGNED_L_LATC1:
302 return PIPE_FORMAT_LATC1_SNORM;
303 case MESA_FORMAT_LA_LATC2:
304 return PIPE_FORMAT_LATC2_UNORM;
305 case MESA_FORMAT_SIGNED_LA_LATC2:
306 return PIPE_FORMAT_LATC2_SNORM;
307
308 /* signed normalized formats */
309 case MESA_FORMAT_SIGNED_R8:
310 return PIPE_FORMAT_R8_SNORM;
311 case MESA_FORMAT_SIGNED_RG88_REV:
312 return PIPE_FORMAT_R8G8_SNORM;
313 case MESA_FORMAT_SIGNED_RGBA8888_REV:
314 return PIPE_FORMAT_R8G8B8A8_SNORM;
315
316 case MESA_FORMAT_SIGNED_A8:
317 return PIPE_FORMAT_A8_SNORM;
318 case MESA_FORMAT_SIGNED_L8:
319 return PIPE_FORMAT_L8_SNORM;
320 case MESA_FORMAT_SIGNED_AL88:
321 return PIPE_FORMAT_L8A8_SNORM;
322 case MESA_FORMAT_SIGNED_I8:
323 return PIPE_FORMAT_I8_SNORM;
324
325 case MESA_FORMAT_SIGNED_R16:
326 return PIPE_FORMAT_R16_SNORM;
327 case MESA_FORMAT_SIGNED_GR1616:
328 return PIPE_FORMAT_R16G16_SNORM;
329 case MESA_FORMAT_SIGNED_RGBA_16:
330 return PIPE_FORMAT_R16G16B16A16_SNORM;
331
332 case MESA_FORMAT_SIGNED_A16:
333 return PIPE_FORMAT_A16_SNORM;
334 case MESA_FORMAT_SIGNED_L16:
335 return PIPE_FORMAT_L16_SNORM;
336 case MESA_FORMAT_SIGNED_AL1616:
337 return PIPE_FORMAT_L16A16_SNORM;
338 case MESA_FORMAT_SIGNED_I16:
339 return PIPE_FORMAT_I16_SNORM;
340
341 case MESA_FORMAT_RGB9_E5_FLOAT:
342 return PIPE_FORMAT_R9G9B9E5_FLOAT;
343 case MESA_FORMAT_R11_G11_B10_FLOAT:
344 return PIPE_FORMAT_R11G11B10_FLOAT;
345
346 default:
347 assert(0);
348 return PIPE_FORMAT_NONE;
349 }
350 }
351
352
353 /**
354 * Translate Gallium format to Mesa format.
355 */
356 gl_format
357 st_pipe_format_to_mesa_format(enum pipe_format format)
358 {
359 switch (format) {
360 case PIPE_FORMAT_A8B8G8R8_UNORM:
361 return MESA_FORMAT_RGBA8888;
362 case PIPE_FORMAT_R8G8B8A8_UNORM:
363 return MESA_FORMAT_RGBA8888_REV;
364 case PIPE_FORMAT_B8G8R8A8_UNORM:
365 return MESA_FORMAT_ARGB8888;
366 case PIPE_FORMAT_A8R8G8B8_UNORM:
367 return MESA_FORMAT_ARGB8888_REV;
368 case PIPE_FORMAT_B8G8R8X8_UNORM:
369 return MESA_FORMAT_XRGB8888;
370 case PIPE_FORMAT_X8R8G8B8_UNORM:
371 return MESA_FORMAT_XRGB8888_REV;
372 case PIPE_FORMAT_B5G5R5A1_UNORM:
373 return MESA_FORMAT_ARGB1555;
374 case PIPE_FORMAT_B4G4R4A4_UNORM:
375 return MESA_FORMAT_ARGB4444;
376 case PIPE_FORMAT_B5G6R5_UNORM:
377 return MESA_FORMAT_RGB565;
378 case PIPE_FORMAT_B2G3R3_UNORM:
379 return MESA_FORMAT_RGB332;
380 case PIPE_FORMAT_B10G10R10A2_UNORM:
381 return MESA_FORMAT_ARGB2101010;
382 case PIPE_FORMAT_L4A4_UNORM:
383 return MESA_FORMAT_AL44;
384 case PIPE_FORMAT_L8A8_UNORM:
385 return MESA_FORMAT_AL88;
386 case PIPE_FORMAT_L16A16_UNORM:
387 return MESA_FORMAT_AL1616;
388 case PIPE_FORMAT_A8_UNORM:
389 return MESA_FORMAT_A8;
390 case PIPE_FORMAT_A16_UNORM:
391 return MESA_FORMAT_A16;
392 case PIPE_FORMAT_L8_UNORM:
393 return MESA_FORMAT_L8;
394 case PIPE_FORMAT_L16_UNORM:
395 return MESA_FORMAT_L16;
396 case PIPE_FORMAT_I8_UNORM:
397 return MESA_FORMAT_I8;
398 case PIPE_FORMAT_I16_UNORM:
399 return MESA_FORMAT_I16;
400 case PIPE_FORMAT_S8_USCALED:
401 return MESA_FORMAT_S8;
402
403 case PIPE_FORMAT_R16G16B16A16_UNORM:
404 return MESA_FORMAT_RGBA_16;
405
406 case PIPE_FORMAT_Z16_UNORM:
407 return MESA_FORMAT_Z16;
408 case PIPE_FORMAT_Z32_UNORM:
409 return MESA_FORMAT_Z32;
410 case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
411 return MESA_FORMAT_Z24_S8;
412 case PIPE_FORMAT_X8Z24_UNORM:
413 return MESA_FORMAT_Z24_X8;
414 case PIPE_FORMAT_Z24X8_UNORM:
415 return MESA_FORMAT_X8_Z24;
416 case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
417 return MESA_FORMAT_S8_Z24;
418
419 case PIPE_FORMAT_UYVY:
420 return MESA_FORMAT_YCBCR;
421 case PIPE_FORMAT_YUYV:
422 return MESA_FORMAT_YCBCR_REV;
423
424 #if FEATURE_texture_s3tc
425 case PIPE_FORMAT_DXT1_RGB:
426 return MESA_FORMAT_RGB_DXT1;
427 case PIPE_FORMAT_DXT1_RGBA:
428 return MESA_FORMAT_RGBA_DXT1;
429 case PIPE_FORMAT_DXT3_RGBA:
430 return MESA_FORMAT_RGBA_DXT3;
431 case PIPE_FORMAT_DXT5_RGBA:
432 return MESA_FORMAT_RGBA_DXT5;
433 #if FEATURE_EXT_texture_sRGB
434 case PIPE_FORMAT_DXT1_SRGB:
435 return MESA_FORMAT_SRGB_DXT1;
436 case PIPE_FORMAT_DXT1_SRGBA:
437 return MESA_FORMAT_SRGBA_DXT1;
438 case PIPE_FORMAT_DXT3_SRGBA:
439 return MESA_FORMAT_SRGBA_DXT3;
440 case PIPE_FORMAT_DXT5_SRGBA:
441 return MESA_FORMAT_SRGBA_DXT5;
442 #endif
443 #endif
444
445 #if FEATURE_EXT_texture_sRGB
446 case PIPE_FORMAT_L8A8_SRGB:
447 return MESA_FORMAT_SLA8;
448 case PIPE_FORMAT_L8_SRGB:
449 return MESA_FORMAT_SL8;
450 case PIPE_FORMAT_R8G8B8_SRGB:
451 return MESA_FORMAT_SRGB8;
452 case PIPE_FORMAT_A8B8G8R8_SRGB:
453 return MESA_FORMAT_SRGBA8;
454 case PIPE_FORMAT_B8G8R8A8_SRGB:
455 return MESA_FORMAT_SARGB8;
456 #endif
457 case PIPE_FORMAT_R32G32B32A32_FLOAT:
458 return MESA_FORMAT_RGBA_FLOAT32;
459 case PIPE_FORMAT_R16G16B16A16_FLOAT:
460 return MESA_FORMAT_RGBA_FLOAT16;
461 case PIPE_FORMAT_R32G32B32_FLOAT:
462 return MESA_FORMAT_RGB_FLOAT32;
463 case PIPE_FORMAT_R16G16B16_FLOAT:
464 return MESA_FORMAT_RGB_FLOAT16;
465 case PIPE_FORMAT_L32A32_FLOAT:
466 return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32;
467 case PIPE_FORMAT_L16A16_FLOAT:
468 return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16;
469 case PIPE_FORMAT_L32_FLOAT:
470 return MESA_FORMAT_LUMINANCE_FLOAT32;
471 case PIPE_FORMAT_L16_FLOAT:
472 return MESA_FORMAT_LUMINANCE_FLOAT16;
473 case PIPE_FORMAT_A32_FLOAT:
474 return MESA_FORMAT_ALPHA_FLOAT32;
475 case PIPE_FORMAT_A16_FLOAT:
476 return MESA_FORMAT_ALPHA_FLOAT16;
477 case PIPE_FORMAT_I32_FLOAT:
478 return MESA_FORMAT_INTENSITY_FLOAT32;
479 case PIPE_FORMAT_I16_FLOAT:
480 return MESA_FORMAT_INTENSITY_FLOAT16;
481 case PIPE_FORMAT_R32_FLOAT:
482 return MESA_FORMAT_R_FLOAT32;
483 case PIPE_FORMAT_R16_FLOAT:
484 return MESA_FORMAT_R_FLOAT16;
485 case PIPE_FORMAT_R32G32_FLOAT:
486 return MESA_FORMAT_RG_FLOAT32;
487 case PIPE_FORMAT_R16G16_FLOAT:
488 return MESA_FORMAT_RG_FLOAT16;
489
490 case PIPE_FORMAT_R8_UNORM:
491 return MESA_FORMAT_R8;
492 case PIPE_FORMAT_R16_UNORM:
493 return MESA_FORMAT_R16;
494 case PIPE_FORMAT_R8G8_UNORM:
495 return MESA_FORMAT_RG88;
496 case PIPE_FORMAT_R16G16_UNORM:
497 return MESA_FORMAT_RG1616;
498
499 /* signed int formats */
500 case PIPE_FORMAT_R8G8B8A8_SSCALED:
501 return MESA_FORMAT_RGBA_INT8;
502 case PIPE_FORMAT_R16G16B16A16_SSCALED:
503 return MESA_FORMAT_RGBA_INT16;
504 case PIPE_FORMAT_R32G32B32A32_SSCALED:
505 return MESA_FORMAT_RGBA_INT32;
506
507 /* unsigned int formats */
508 case PIPE_FORMAT_R8G8B8A8_USCALED:
509 return MESA_FORMAT_RGBA_UINT8;
510 case PIPE_FORMAT_R16G16B16A16_USCALED:
511 return MESA_FORMAT_RGBA_UINT16;
512 case PIPE_FORMAT_R32G32B32A32_USCALED:
513 return MESA_FORMAT_RGBA_UINT32;
514
515 case PIPE_FORMAT_RGTC1_UNORM:
516 return MESA_FORMAT_RED_RGTC1;
517 case PIPE_FORMAT_RGTC1_SNORM:
518 return MESA_FORMAT_SIGNED_RED_RGTC1;
519 case PIPE_FORMAT_RGTC2_UNORM:
520 return MESA_FORMAT_RG_RGTC2;
521 case PIPE_FORMAT_RGTC2_SNORM:
522 return MESA_FORMAT_SIGNED_RG_RGTC2;
523
524 case PIPE_FORMAT_LATC1_UNORM:
525 return MESA_FORMAT_L_LATC1;
526 case PIPE_FORMAT_LATC1_SNORM:
527 return MESA_FORMAT_SIGNED_L_LATC1;
528 case PIPE_FORMAT_LATC2_UNORM:
529 return MESA_FORMAT_LA_LATC2;
530 case PIPE_FORMAT_LATC2_SNORM:
531 return MESA_FORMAT_SIGNED_LA_LATC2;
532
533 /* signed normalized formats */
534 case PIPE_FORMAT_R8_SNORM:
535 return MESA_FORMAT_SIGNED_R8;
536 case PIPE_FORMAT_R8G8_SNORM:
537 return MESA_FORMAT_SIGNED_RG88_REV;
538 case PIPE_FORMAT_R8G8B8A8_SNORM:
539 return MESA_FORMAT_SIGNED_RGBA8888_REV;
540
541 case PIPE_FORMAT_A8_SNORM:
542 return MESA_FORMAT_SIGNED_A8;
543 case PIPE_FORMAT_L8_SNORM:
544 return MESA_FORMAT_SIGNED_L8;
545 case PIPE_FORMAT_L8A8_SNORM:
546 return MESA_FORMAT_SIGNED_AL88;
547 case PIPE_FORMAT_I8_SNORM:
548 return MESA_FORMAT_SIGNED_I8;
549
550 case PIPE_FORMAT_R16_SNORM:
551 return MESA_FORMAT_SIGNED_R16;
552 case PIPE_FORMAT_R16G16_SNORM:
553 return MESA_FORMAT_SIGNED_GR1616;
554 case PIPE_FORMAT_R16G16B16A16_SNORM:
555 return MESA_FORMAT_SIGNED_RGBA_16;
556
557 case PIPE_FORMAT_A16_SNORM:
558 return MESA_FORMAT_SIGNED_A16;
559 case PIPE_FORMAT_L16_SNORM:
560 return MESA_FORMAT_SIGNED_L16;
561 case PIPE_FORMAT_L16A16_SNORM:
562 return MESA_FORMAT_SIGNED_AL1616;
563 case PIPE_FORMAT_I16_SNORM:
564 return MESA_FORMAT_SIGNED_I16;
565
566 case PIPE_FORMAT_R9G9B9E5_FLOAT:
567 return MESA_FORMAT_RGB9_E5_FLOAT;
568 case PIPE_FORMAT_R11G11B10_FLOAT:
569 return MESA_FORMAT_R11_G11_B10_FLOAT;
570
571 default:
572 assert(0);
573 return MESA_FORMAT_NONE;
574 }
575 }
576
577
578 /**
579 * Map GL texture formats to Gallium pipe formats.
580 */
581 struct format_mapping
582 {
583 GLenum glFormats[18]; /**< list of GLenum formats, 0-terminated */
584 enum pipe_format pipeFormats[10]; /**< list of pipe formats, 0-terminated */
585 };
586
587
588 #define DEFAULT_RGBA_FORMATS \
589 PIPE_FORMAT_B8G8R8A8_UNORM, \
590 PIPE_FORMAT_A8R8G8B8_UNORM, \
591 PIPE_FORMAT_A8B8G8R8_UNORM, \
592 PIPE_FORMAT_B5G6R5_UNORM, \
593 0
594
595 #define DEFAULT_RGB_FORMATS \
596 PIPE_FORMAT_B8G8R8X8_UNORM, \
597 PIPE_FORMAT_X8R8G8B8_UNORM, \
598 PIPE_FORMAT_X8B8G8R8_UNORM, \
599 PIPE_FORMAT_B8G8R8A8_UNORM, \
600 PIPE_FORMAT_A8R8G8B8_UNORM, \
601 PIPE_FORMAT_A8B8G8R8_UNORM, \
602 PIPE_FORMAT_B5G6R5_UNORM, \
603 0
604
605 #define DEFAULT_SRGBA_FORMATS \
606 PIPE_FORMAT_B8G8R8A8_SRGB, \
607 PIPE_FORMAT_A8R8G8B8_SRGB, \
608 PIPE_FORMAT_A8B8G8R8_SRGB, \
609 0
610
611 #define DEFAULT_DEPTH_FORMATS \
612 PIPE_FORMAT_Z24X8_UNORM, \
613 PIPE_FORMAT_X8Z24_UNORM, \
614 PIPE_FORMAT_Z16_UNORM, \
615 PIPE_FORMAT_Z24_UNORM_S8_USCALED, \
616 PIPE_FORMAT_S8_USCALED_Z24_UNORM, \
617 0
618
619 /**
620 * This table maps OpenGL texture format enums to Gallium pipe_format enums.
621 * Multiple GL enums might map to multiple pipe_formats.
622 * The first pipe format in the list that's supported is the one that's chosen.
623 */
624 static const struct format_mapping format_map[] = {
625 /* Basic RGB, RGBA formats */
626 {
627 { GL_RGB10, GL_RGB10_A2, 0 },
628 { PIPE_FORMAT_B10G10R10A2_UNORM, DEFAULT_RGBA_FORMATS }
629 },
630 {
631 { 4, GL_RGBA, GL_RGBA8, 0 },
632 { PIPE_FORMAT_R8G8B8A8_UNORM, DEFAULT_RGBA_FORMATS }
633 },
634 {
635 { GL_BGRA, 0 },
636 { PIPE_FORMAT_B8G8R8A8_UNORM, DEFAULT_RGBA_FORMATS }
637 },
638 {
639 { 3, GL_RGB, GL_RGB8, 0 },
640 { DEFAULT_RGB_FORMATS }
641 },
642 {
643 { GL_RGB12, GL_RGB16, GL_RGBA12, GL_RGBA16, 0 },
644 { PIPE_FORMAT_R16G16B16A16_UNORM, DEFAULT_RGBA_FORMATS }
645 },
646 {
647 { GL_RGBA4, GL_RGBA2, 0 },
648 { PIPE_FORMAT_B4G4R4A4_UNORM, DEFAULT_RGBA_FORMATS }
649 },
650 {
651 { GL_RGB5_A1, 0 },
652 { PIPE_FORMAT_B5G5R5A1_UNORM, DEFAULT_RGBA_FORMATS }
653 },
654 {
655 { GL_R3_G3_B2, 0 },
656 { PIPE_FORMAT_B2G3R3_UNORM, PIPE_FORMAT_B5G6R5_UNORM,
657 PIPE_FORMAT_B5G5R5A1_UNORM, DEFAULT_RGBA_FORMATS }
658 },
659 {
660 { GL_RGB5, GL_RGB4 },
661 { PIPE_FORMAT_B5G6R5_UNORM, PIPE_FORMAT_B5G5R5A1_UNORM,
662 DEFAULT_RGBA_FORMATS }
663 },
664
665 /* basic Alpha formats */
666 {
667 { GL_ALPHA12, GL_ALPHA16, 0 },
668 { PIPE_FORMAT_A16_UNORM, PIPE_FORMAT_A8_UNORM,
669 DEFAULT_RGBA_FORMATS }
670 },
671 {
672 { GL_ALPHA, GL_ALPHA4, GL_ALPHA8, GL_COMPRESSED_ALPHA, 0 },
673 { PIPE_FORMAT_A8_UNORM, DEFAULT_RGBA_FORMATS }
674 },
675
676 /* basic Luminance formats */
677 {
678 { GL_LUMINANCE12, GL_LUMINANCE16, 0 },
679 { PIPE_FORMAT_L16_UNORM, PIPE_FORMAT_L8_UNORM, DEFAULT_RGB_FORMATS }
680 },
681 {
682 { 1, GL_LUMINANCE, GL_LUMINANCE4, GL_LUMINANCE8, 0 },
683 { PIPE_FORMAT_L8_UNORM, DEFAULT_RGB_FORMATS }
684 },
685
686 /* basic Luminance/Alpha formats */
687 {
688 { GL_LUMINANCE12_ALPHA4, GL_LUMINANCE12_ALPHA12,
689 GL_LUMINANCE16_ALPHA16, 0},
690 { PIPE_FORMAT_L16A16_UNORM, PIPE_FORMAT_L8A8_UNORM,
691 DEFAULT_RGBA_FORMATS }
692 },
693 {
694 { 2, GL_LUMINANCE_ALPHA, GL_LUMINANCE6_ALPHA2, GL_LUMINANCE8_ALPHA8, 0 },
695 { PIPE_FORMAT_L8A8_UNORM, DEFAULT_RGBA_FORMATS }
696 },
697 {
698 { GL_LUMINANCE4_ALPHA4, 0 },
699 { PIPE_FORMAT_L4A4_UNORM, PIPE_FORMAT_L8A8_UNORM,
700 DEFAULT_RGBA_FORMATS }
701 },
702
703 /* basic Intensity formats */
704 {
705 { GL_INTENSITY12, GL_INTENSITY16, 0 },
706 { PIPE_FORMAT_I16_UNORM, PIPE_FORMAT_I8_UNORM, DEFAULT_RGBA_FORMATS }
707 },
708 {
709 { GL_INTENSITY, GL_INTENSITY4, GL_INTENSITY8,
710 GL_COMPRESSED_INTENSITY, 0 },
711 { PIPE_FORMAT_I8_UNORM, DEFAULT_RGBA_FORMATS }
712 },
713
714 /* YCbCr */
715 {
716 { GL_YCBCR_MESA, 0 },
717 { PIPE_FORMAT_UYVY, PIPE_FORMAT_YUYV, 0 }
718 },
719
720 /* compressed formats */ /* XXX PIPE_BIND_SAMPLER_VIEW only */
721 {
722 { GL_COMPRESSED_RGB, 0 },
723 { PIPE_FORMAT_DXT1_RGB, DEFAULT_RGB_FORMATS }
724 },
725 {
726 { GL_COMPRESSED_RGBA, 0 },
727 { PIPE_FORMAT_DXT5_RGBA, DEFAULT_RGBA_FORMATS }
728 },
729 {
730 { GL_RGB_S3TC, GL_RGB4_S3TC, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, 0 },
731 { PIPE_FORMAT_DXT1_RGB, 0 }
732 },
733 {
734 { GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 0 },
735 { PIPE_FORMAT_DXT1_RGBA, 0 }
736 },
737 {
738 { GL_RGBA_S3TC, GL_RGBA4_S3TC, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, 0 },
739 { PIPE_FORMAT_DXT3_RGBA, 0 }
740 },
741 {
742 { GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, 0 },
743 { PIPE_FORMAT_DXT5_RGBA, 0 }
744 },
745
746 #if 0
747 {
748 { GL_COMPRESSED_RGB_FXT1_3DFX, 0 },
749 { PIPE_FORMAT_RGB_FXT1, 0 }
750 },
751 {
752 { GL_COMPRESSED_RGBA_FXT1_3DFX, 0 },
753 { PIPE_FORMAT_RGBA_FXT1, 0 }
754 },
755 #endif
756
757 /* Depth formats */
758 {
759 { GL_DEPTH_COMPONENT16, 0 },
760 { PIPE_FORMAT_Z16_UNORM, DEFAULT_DEPTH_FORMATS }
761 },
762 {
763 { GL_DEPTH_COMPONENT24, 0 },
764 { PIPE_FORMAT_Z24X8_UNORM, PIPE_FORMAT_X8Z24_UNORM,
765 DEFAULT_DEPTH_FORMATS }
766 },
767 {
768 { GL_DEPTH_COMPONENT32, 0 },
769 { PIPE_FORMAT_Z32_UNORM, DEFAULT_DEPTH_FORMATS }
770 },
771 {
772 { GL_DEPTH_COMPONENT, 0 },
773 { DEFAULT_DEPTH_FORMATS }
774 },
775
776 /* stencil formats */
777 {
778 { GL_STENCIL_INDEX, GL_STENCIL_INDEX1_EXT, GL_STENCIL_INDEX4_EXT,
779 GL_STENCIL_INDEX8_EXT, GL_STENCIL_INDEX16_EXT, 0 },
780 {
781 PIPE_FORMAT_S8_USCALED, PIPE_FORMAT_Z24_UNORM_S8_USCALED,
782 PIPE_FORMAT_S8_USCALED_Z24_UNORM, 0
783 }
784 },
785
786 /* Depth / Stencil formats */
787 {
788 { GL_DEPTH_STENCIL_EXT, GL_DEPTH24_STENCIL8_EXT, 0 },
789 { PIPE_FORMAT_Z24_UNORM_S8_USCALED, PIPE_FORMAT_S8_USCALED_Z24_UNORM, 0 }
790 },
791
792 /* sRGB formats */
793 {
794 { GL_SRGB_EXT, GL_SRGB8_EXT, GL_SRGB_ALPHA_EXT, GL_SRGB8_ALPHA8_EXT, 0 },
795 { DEFAULT_SRGBA_FORMATS }
796 },
797 {
798 { GL_COMPRESSED_SRGB_EXT, GL_COMPRESSED_SRGB_S3TC_DXT1_EXT, 0 },
799 { PIPE_FORMAT_DXT1_SRGB, DEFAULT_SRGBA_FORMATS }
800 },
801 {
802 { GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0 },
803 { PIPE_FORMAT_DXT1_SRGBA, 0 }
804 },
805 {
806 { GL_COMPRESSED_SRGB_ALPHA_EXT,
807 GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0 },
808 { PIPE_FORMAT_DXT3_SRGBA, DEFAULT_SRGBA_FORMATS }
809 },
810 {
811 { GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0 },
812 { PIPE_FORMAT_DXT5_SRGBA, 0 }
813 },
814 {
815 { GL_SLUMINANCE_ALPHA_EXT, GL_SLUMINANCE8_ALPHA8_EXT,
816 GL_COMPRESSED_SLUMINANCE_EXT, GL_COMPRESSED_SLUMINANCE_ALPHA_EXT, 0 },
817 { PIPE_FORMAT_L8A8_SRGB, DEFAULT_SRGBA_FORMATS }
818 },
819 {
820 { GL_SLUMINANCE_EXT, GL_SLUMINANCE8_EXT, 0 },
821 { PIPE_FORMAT_L8_SRGB, DEFAULT_SRGBA_FORMATS }
822 },
823
824 /* 16-bit float formats */
825 {
826 { GL_RGBA16F_ARB, 0 },
827 { PIPE_FORMAT_R16G16B16A16_FLOAT, PIPE_FORMAT_R32G32B32A32_FLOAT, 0 }
828 },
829 {
830 { GL_RGB16F_ARB, 0 },
831 { PIPE_FORMAT_R16G16B16_FLOAT, PIPE_FORMAT_R16G16B16A16_FLOAT,
832 PIPE_FORMAT_R32G32B32_FLOAT, PIPE_FORMAT_R32G32B32A32_FLOAT, 0 }
833 },
834 {
835 { GL_LUMINANCE_ALPHA16F_ARB, 0 },
836 { PIPE_FORMAT_L16A16_FLOAT, PIPE_FORMAT_R16G16B16A16_FLOAT,
837 PIPE_FORMAT_L32A32_FLOAT, PIPE_FORMAT_R32G32B32A32_FLOAT, 0 }
838 },
839 {
840 { GL_ALPHA16F_ARB, 0 },
841 { PIPE_FORMAT_A16_FLOAT, PIPE_FORMAT_L16A16_FLOAT,
842 PIPE_FORMAT_A32_FLOAT, PIPE_FORMAT_R16G16B16A16_FLOAT,
843 PIPE_FORMAT_L32A32_FLOAT, PIPE_FORMAT_R32G32B32A32_FLOAT, 0 }
844 },
845 {
846 { GL_INTENSITY16F_ARB, 0 },
847 { PIPE_FORMAT_I16_FLOAT, PIPE_FORMAT_L16A16_FLOAT,
848 PIPE_FORMAT_I32_FLOAT, PIPE_FORMAT_R16G16B16A16_FLOAT,
849 PIPE_FORMAT_L32A32_FLOAT, PIPE_FORMAT_R32G32B32A32_FLOAT, 0 }
850 },
851 {
852 { GL_LUMINANCE16F_ARB, 0 },
853 { PIPE_FORMAT_L16_FLOAT, PIPE_FORMAT_L16A16_FLOAT,
854 PIPE_FORMAT_L32_FLOAT, PIPE_FORMAT_R16G16B16A16_FLOAT,
855 PIPE_FORMAT_L32A32_FLOAT, PIPE_FORMAT_R32G32B32A32_FLOAT, 0 }
856 },
857 {
858 { GL_R16F, 0 },
859 { PIPE_FORMAT_R16_FLOAT, PIPE_FORMAT_R16G16_FLOAT,
860 PIPE_FORMAT_R32_FLOAT, PIPE_FORMAT_R16G16B16A16_FLOAT,
861 PIPE_FORMAT_R32G32_FLOAT, PIPE_FORMAT_R32G32B32A32_FLOAT, 0 }
862 },
863 {
864 { GL_RG16F, 0 },
865 { PIPE_FORMAT_R16G16_FLOAT, PIPE_FORMAT_R16G16B16A16_FLOAT,
866 PIPE_FORMAT_R32G32_FLOAT, PIPE_FORMAT_R32G32B32A32_FLOAT, 0 }
867 },
868
869 /* 32-bit float formats */
870 {
871 { GL_RGBA32F_ARB, 0 },
872 { PIPE_FORMAT_R32G32B32A32_FLOAT, PIPE_FORMAT_R16G16B16A16_FLOAT, 0 }
873 },
874 {
875 { GL_RGB32F_ARB, 0 },
876 { PIPE_FORMAT_R32G32B32_FLOAT, PIPE_FORMAT_R32G32B32A32_FLOAT,
877 PIPE_FORMAT_R16G16B16A16_FLOAT, 0 }
878 },
879 {
880 { GL_LUMINANCE_ALPHA32F_ARB, 0 },
881 { PIPE_FORMAT_L32A32_FLOAT, PIPE_FORMAT_R32G32B32A32_FLOAT,
882 PIPE_FORMAT_L16A16_FLOAT, PIPE_FORMAT_R16G16B16A16_FLOAT, 0 }
883 },
884 {
885 { GL_ALPHA32F_ARB, 0 },
886 { PIPE_FORMAT_A32_FLOAT, PIPE_FORMAT_L32A32_FLOAT,
887 PIPE_FORMAT_R32G32B32A32_FLOAT, PIPE_FORMAT_A16_FLOAT,
888 PIPE_FORMAT_L16A16_FLOAT, PIPE_FORMAT_R16G16B16A16_FLOAT, 0 }
889 },
890 {
891 { GL_INTENSITY32F_ARB, 0 },
892 { PIPE_FORMAT_I32_FLOAT, PIPE_FORMAT_L32A32_FLOAT,
893 PIPE_FORMAT_R32G32B32A32_FLOAT, PIPE_FORMAT_I16_FLOAT,
894 PIPE_FORMAT_L16A16_FLOAT, PIPE_FORMAT_R16G16B16A16_FLOAT, 0 }
895 },
896 {
897 { GL_LUMINANCE32F_ARB, 0 },
898 { PIPE_FORMAT_L32_FLOAT, PIPE_FORMAT_L32A32_FLOAT,
899 PIPE_FORMAT_R32G32B32A32_FLOAT, PIPE_FORMAT_L16_FLOAT,
900 PIPE_FORMAT_L16A16_FLOAT, PIPE_FORMAT_R16G16B16A16_FLOAT, 0 }
901 },
902 {
903 { GL_R32F, 0 },
904 { PIPE_FORMAT_R32_FLOAT, PIPE_FORMAT_R32G32_FLOAT,
905 PIPE_FORMAT_R32G32B32A32_FLOAT, PIPE_FORMAT_R16_FLOAT,
906 PIPE_FORMAT_R16G16_FLOAT, PIPE_FORMAT_R16G16B16A16_FLOAT, 0 }
907 },
908 {
909 { GL_RG32F, 0 },
910 { PIPE_FORMAT_R32G32_FLOAT, PIPE_FORMAT_R32G32B32A32_FLOAT,
911 PIPE_FORMAT_R16G16_FLOAT, PIPE_FORMAT_R16G16B16A16_FLOAT, 0 }
912 },
913
914 /* R, RG formats */
915 {
916 { GL_RED, GL_R8, 0 },
917 { PIPE_FORMAT_R8_UNORM, 0 }
918 },
919 {
920 { GL_RG, GL_RG8, 0 },
921 { PIPE_FORMAT_R8G8_UNORM, 0 }
922 },
923 {
924 { GL_R16, 0 },
925 { PIPE_FORMAT_R16_UNORM, 0 }
926 },
927 {
928 { GL_RG16, 0 },
929 { PIPE_FORMAT_R16G16_UNORM, 0 }
930 },
931
932 /* compressed R, RG formats */
933 {
934 { GL_COMPRESSED_RED, GL_COMPRESSED_RED_RGTC1, 0 },
935 { PIPE_FORMAT_RGTC1_UNORM, PIPE_FORMAT_R8_UNORM, 0 }
936 },
937 {
938 { GL_COMPRESSED_SIGNED_RED_RGTC1, 0 },
939 { PIPE_FORMAT_RGTC1_SNORM, 0 }
940 },
941 {
942 { GL_COMPRESSED_RG, GL_COMPRESSED_RG_RGTC2, 0 },
943 { PIPE_FORMAT_RGTC2_UNORM, PIPE_FORMAT_R8G8_UNORM, 0 }
944 },
945 {
946 { GL_COMPRESSED_SIGNED_RG_RGTC2, 0 },
947 { PIPE_FORMAT_RGTC2_SNORM, 0 }
948 },
949 {
950 { GL_COMPRESSED_LUMINANCE, GL_COMPRESSED_LUMINANCE_LATC1_EXT, 0 },
951 { PIPE_FORMAT_LATC1_UNORM, PIPE_FORMAT_L8_UNORM, 0 }
952 },
953 {
954 { GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT, 0 },
955 { PIPE_FORMAT_LATC1_SNORM, 0 }
956 },
957 {
958 { GL_COMPRESSED_LUMINANCE_ALPHA, GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT,
959 GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI, 0 },
960 { PIPE_FORMAT_LATC2_UNORM, PIPE_FORMAT_L8A8_UNORM, 0 }
961 },
962 {
963 { GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT, 0 },
964 { PIPE_FORMAT_LATC2_SNORM, 0 }
965 },
966
967 /* signed/unsigned integer formats.
968 * XXX Mesa only has formats for RGBA signed/unsigned integer formats.
969 * If/when new formats are added this code should be updated.
970 */
971 {
972 { GL_RED_INTEGER_EXT,
973 GL_GREEN_INTEGER_EXT,
974 GL_BLUE_INTEGER_EXT,
975 GL_ALPHA_INTEGER_EXT,
976 GL_RGB_INTEGER_EXT,
977 GL_RGBA_INTEGER_EXT,
978 GL_BGR_INTEGER_EXT,
979 GL_BGRA_INTEGER_EXT,
980 GL_LUMINANCE_INTEGER_EXT,
981 GL_LUMINANCE_ALPHA_INTEGER_EXT,
982 GL_RGBA8I_EXT,
983 GL_RGB8I_EXT,
984 GL_ALPHA8I_EXT,
985 GL_INTENSITY8I_EXT,
986 GL_LUMINANCE8I_EXT,
987 GL_LUMINANCE_ALPHA8I_EXT, 0 },
988 { PIPE_FORMAT_R8G8B8A8_SSCALED, 0 }
989 },
990 {
991 {
992 GL_RGBA16I_EXT,
993 GL_RGB16I_EXT,
994 GL_ALPHA16I_EXT,
995 GL_INTENSITY16I_EXT,
996 GL_LUMINANCE16I_EXT,
997 GL_LUMINANCE_ALPHA16I_EXT, 0 },
998 { PIPE_FORMAT_R16G16B16A16_SSCALED, 0 },
999 },
1000 {
1001 {
1002 GL_RGBA32I_EXT,
1003 GL_RGB32I_EXT,
1004 GL_ALPHA32I_EXT,
1005 GL_INTENSITY32I_EXT,
1006 GL_LUMINANCE32I_EXT,
1007 GL_LUMINANCE_ALPHA32I_EXT, 0 },
1008 { PIPE_FORMAT_R32G32B32A32_SSCALED, 0 }
1009 },
1010 {
1011 {
1012 GL_RGBA8UI_EXT,
1013 GL_RGB8UI_EXT,
1014 GL_ALPHA8UI_EXT,
1015 GL_INTENSITY8UI_EXT,
1016 GL_LUMINANCE8UI_EXT,
1017 GL_LUMINANCE_ALPHA8UI_EXT, 0 },
1018 { PIPE_FORMAT_R8G8B8A8_USCALED, 0 }
1019 },
1020 {
1021 {
1022 GL_RGBA16UI_EXT,
1023 GL_RGB16UI_EXT,
1024 GL_ALPHA16UI_EXT,
1025 GL_INTENSITY16UI_EXT,
1026 GL_LUMINANCE16UI_EXT,
1027 GL_LUMINANCE_ALPHA16UI_EXT, 0 },
1028 { PIPE_FORMAT_R16G16B16A16_USCALED, 0 }
1029 },
1030 {
1031 {
1032 GL_RGBA32UI_EXT,
1033 GL_RGB32UI_EXT,
1034 GL_ALPHA32UI_EXT,
1035 GL_INTENSITY32UI_EXT,
1036 GL_LUMINANCE32UI_EXT,
1037 GL_LUMINANCE_ALPHA32UI_EXT, 0 },
1038 { PIPE_FORMAT_R32G32B32A32_USCALED, 0 }
1039 },
1040
1041 /* signed normalized formats */
1042 {
1043 { GL_RED_SNORM, GL_R8_SNORM, 0 },
1044 { PIPE_FORMAT_R8_SNORM, PIPE_FORMAT_R8G8_SNORM,
1045 PIPE_FORMAT_R8G8B8A8_SNORM, 0 }
1046 },
1047 {
1048 { GL_R16_SNORM, 0 },
1049 { PIPE_FORMAT_R16_SNORM,
1050 PIPE_FORMAT_R16G16_SNORM,
1051 PIPE_FORMAT_R16G16B16A16_SNORM,
1052 PIPE_FORMAT_R8_SNORM,
1053 PIPE_FORMAT_R8G8_SNORM,
1054 PIPE_FORMAT_R8G8B8A8_SNORM, 0 }
1055 },
1056 {
1057 { GL_RG_SNORM, GL_RG8_SNORM, 0 },
1058 { PIPE_FORMAT_R8G8_SNORM, PIPE_FORMAT_R8G8B8A8_SNORM, 0 }
1059 },
1060 {
1061 { GL_RG16_SNORM, 0 },
1062 { PIPE_FORMAT_R16G16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM,
1063 PIPE_FORMAT_R8G8_SNORM, PIPE_FORMAT_R8G8B8A8_SNORM, 0 }
1064 },
1065 {
1066 { GL_RGB_SNORM, GL_RGB8_SNORM, GL_RGBA_SNORM, GL_RGBA8_SNORM, 0 },
1067 { PIPE_FORMAT_R8G8B8A8_SNORM, 0 }
1068 },
1069 {
1070 { GL_RGB16_SNORM, GL_RGBA16_SNORM, 0 },
1071 { PIPE_FORMAT_R16G16B16A16_SNORM, PIPE_FORMAT_R8G8B8A8_SNORM, 0 }
1072 },
1073 {
1074 { GL_ALPHA_SNORM, GL_ALPHA8_SNORM, 0 },
1075 { PIPE_FORMAT_A8_SNORM, PIPE_FORMAT_R8G8B8A8_SNORM, 0 }
1076 },
1077 {
1078 { GL_ALPHA16_SNORM, 0 },
1079 { PIPE_FORMAT_A16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM,
1080 PIPE_FORMAT_A8_SNORM, PIPE_FORMAT_R8G8B8A8_SNORM, 0 }
1081 },
1082 {
1083 { GL_LUMINANCE_SNORM, GL_LUMINANCE8_SNORM, 0 },
1084 { PIPE_FORMAT_L8_SNORM, PIPE_FORMAT_R8G8B8A8_SNORM, 0 }
1085 },
1086 {
1087 { GL_LUMINANCE16_SNORM, 0 },
1088 { PIPE_FORMAT_L16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM,
1089 PIPE_FORMAT_L8_SNORM, PIPE_FORMAT_R8G8B8A8_SNORM, 0 }
1090 },
1091 {
1092 { GL_LUMINANCE_ALPHA_SNORM, GL_LUMINANCE8_ALPHA8_SNORM, 0 },
1093 { PIPE_FORMAT_L8A8_SNORM, PIPE_FORMAT_R8G8B8A8_SNORM, 0 }
1094 },
1095 {
1096 { GL_LUMINANCE16_ALPHA16_SNORM, 0 },
1097 { PIPE_FORMAT_L16A16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM,
1098 PIPE_FORMAT_L8A8_SNORM, PIPE_FORMAT_R8G8B8A8_SNORM, 0 }
1099 },
1100 {
1101 { GL_INTENSITY_SNORM, GL_INTENSITY8_SNORM, 0 },
1102 { PIPE_FORMAT_I8_SNORM, PIPE_FORMAT_R8G8B8A8_SNORM, 0 }
1103 },
1104 {
1105 { GL_INTENSITY16_SNORM, 0 },
1106 { PIPE_FORMAT_I16_SNORM, PIPE_FORMAT_R16G16B16A16_SNORM,
1107 PIPE_FORMAT_I8_SNORM, PIPE_FORMAT_R8G8B8A8_SNORM, 0 }
1108 },
1109 {
1110 { GL_RGB9_E5, 0 },
1111 { PIPE_FORMAT_R9G9B9E5_FLOAT, 0 }
1112 },
1113 {
1114 { GL_R11F_G11F_B10F, 0 },
1115 { PIPE_FORMAT_R11G11B10_FLOAT, 0 }
1116 }
1117 };
1118
1119
1120 /**
1121 * Return first supported format from the given list.
1122 */
1123 static enum pipe_format
1124 find_supported_format(struct pipe_screen *screen,
1125 const enum pipe_format formats[],
1126 enum pipe_texture_target target,
1127 unsigned sample_count,
1128 unsigned tex_usage)
1129 {
1130 uint i;
1131 for (i = 0; formats[i]; i++) {
1132 if (screen->is_format_supported(screen, formats[i], target,
1133 sample_count, tex_usage)) {
1134 return formats[i];
1135 }
1136 }
1137 return PIPE_FORMAT_NONE;
1138 }
1139
1140 struct exact_format_mapping
1141 {
1142 GLenum format;
1143 GLenum type;
1144 enum pipe_format pformat;
1145 };
1146
1147 static const struct exact_format_mapping rgba8888_tbl[] =
1148 {
1149 { GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, PIPE_FORMAT_A8B8G8R8_UNORM },
1150 { GL_ABGR_EXT, GL_UNSIGNED_INT_8_8_8_8_REV, PIPE_FORMAT_A8B8G8R8_UNORM },
1151 { GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, PIPE_FORMAT_R8G8B8A8_UNORM },
1152 { GL_ABGR_EXT, GL_UNSIGNED_INT_8_8_8_8, PIPE_FORMAT_R8G8B8A8_UNORM },
1153 { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, PIPE_FORMAT_A8R8G8B8_UNORM },
1154 { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, PIPE_FORMAT_B8G8R8A8_UNORM },
1155 { GL_RGBA, GL_UNSIGNED_BYTE, PIPE_FORMAT_R8G8B8A8_UNORM },
1156 { GL_ABGR_EXT, GL_UNSIGNED_BYTE, PIPE_FORMAT_A8B8G8R8_UNORM },
1157 { GL_BGRA, GL_UNSIGNED_BYTE, PIPE_FORMAT_B8G8R8A8_UNORM },
1158 { 0, 0, 0 }
1159 };
1160
1161 static const struct exact_format_mapping rgbx8888_tbl[] =
1162 {
1163 { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, PIPE_FORMAT_X8R8G8B8_UNORM },
1164 { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, PIPE_FORMAT_B8G8R8X8_UNORM },
1165 { GL_BGRA, GL_UNSIGNED_BYTE, PIPE_FORMAT_B8G8R8X8_UNORM },
1166 /* No Mesa formats for these Gallium formats:
1167 { GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, PIPE_FORMAT_X8B8G8R8_UNORM },
1168 { GL_ABGR_EXT, GL_UNSIGNED_INT_8_8_8_8_REV, PIPE_FORMAT_X8B8G8R8_UNORM },
1169 { GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, PIPE_FORMAT_R8G8B8X8_UNORM },
1170 { GL_ABGR_EXT, GL_UNSIGNED_INT_8_8_8_8, PIPE_FORMAT_R8G8B8X8_UNORM },
1171 { GL_RGBA, GL_UNSIGNED_BYTE, PIPE_FORMAT_R8G8B8X8_UNORM },
1172 { GL_ABGR_EXT, GL_UNSIGNED_BYTE, PIPE_FORMAT_X8B8G8R8_UNORM },
1173 */
1174 { 0, 0, 0 }
1175 };
1176
1177 static const struct exact_format_mapping rgba1010102_tbl[] =
1178 {
1179 { GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV, PIPE_FORMAT_B10G10R10A2_UNORM },
1180 /* No Mesa formats for these Gallium formats:
1181 { GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, PIPE_FORMAT_R10G10B10A2_UNORM },
1182 { GL_ABGR_EXT, GL_UNSIGNED_INT_10_10_10_2, PIPE_FORMAT_R10G10B10A2_UNORM },
1183 { GL_ABGR_EXT, GL_UNSIGNED_INT, PIPE_FORMAT_R10G10B10A2_UNORM },
1184 */
1185 { 0, 0, 0 }
1186 };
1187
1188 /**
1189 * If there is an exact pipe_format match for {internalFormat, format, type}
1190 * return that, otherwise return PIPE_FORMAT_NONE so we can do fuzzy matching.
1191 */
1192 static enum pipe_format
1193 find_exact_format(GLint internalFormat, GLenum format, GLenum type)
1194 {
1195 uint i;
1196 const struct exact_format_mapping* tbl;
1197
1198 if (format == GL_NONE || type == GL_NONE)
1199 return PIPE_FORMAT_NONE;
1200
1201 switch (internalFormat) {
1202 case 4:
1203 case GL_RGBA:
1204 case GL_RGBA8:
1205 tbl = rgba8888_tbl;
1206 break;
1207 case 3:
1208 case GL_RGB:
1209 case GL_RGB8:
1210 tbl = rgbx8888_tbl;
1211 break;
1212 case GL_RGB10_A2:
1213 tbl = rgba1010102_tbl;
1214 break;
1215 default:
1216 return PIPE_FORMAT_NONE;
1217 }
1218
1219 for (i = 0; tbl[i].format; i++)
1220 if (tbl[i].format == format && tbl[i].type == type)
1221 return tbl[i].pformat;
1222
1223 return PIPE_FORMAT_NONE;
1224 }
1225
1226 /**
1227 * Given an OpenGL internalFormat value for a texture or surface, return
1228 * the best matching PIPE_FORMAT_x, or PIPE_FORMAT_NONE if there's no match.
1229 * This is called during glTexImage2D, for example.
1230 *
1231 * The bindings parameter typically has PIPE_BIND_SAMPLER_VIEW set, plus
1232 * either PIPE_BINDING_RENDER_TARGET or PIPE_BINDING_DEPTH_STENCIL if
1233 * we want render-to-texture ability.
1234 *
1235 * \param internalFormat the user value passed to glTexImage2D
1236 * \param target one of PIPE_TEXTURE_x
1237 * \param bindings bitmask of PIPE_BIND_x flags.
1238 */
1239 enum pipe_format
1240 st_choose_format(struct pipe_screen *screen, GLenum internalFormat,
1241 GLenum format, GLenum type,
1242 enum pipe_texture_target target, unsigned sample_count,
1243 unsigned bindings)
1244 {
1245 GET_CURRENT_CONTEXT(ctx); /* XXX this should be a function parameter */
1246 int i, j;
1247 enum pipe_format pf;
1248
1249 /* can't render to compressed formats at this time */
1250 if (_mesa_is_compressed_format(ctx, internalFormat)
1251 && (bindings & ~PIPE_BIND_SAMPLER_VIEW)) {
1252 return PIPE_FORMAT_NONE;
1253 }
1254
1255 /* search for exact matches */
1256 pf = find_exact_format(internalFormat, format, type);
1257 if (pf != PIPE_FORMAT_NONE &&
1258 screen->is_format_supported(screen, pf,
1259 target, sample_count, bindings))
1260 return pf;
1261
1262 /* search table for internalFormat */
1263 for (i = 0; i < Elements(format_map); i++) {
1264 const struct format_mapping *mapping = &format_map[i];
1265 for (j = 0; mapping->glFormats[j]; j++) {
1266 if (mapping->glFormats[j] == internalFormat) {
1267 /* Found the desired internal format. Find first pipe format
1268 * which is supported by the driver.
1269 */
1270 return find_supported_format(screen, mapping->pipeFormats,
1271 target, sample_count, bindings);
1272 }
1273 }
1274 }
1275
1276 _mesa_problem(NULL, "unhandled format!\n");
1277 return PIPE_FORMAT_NONE;
1278 }
1279
1280
1281 /**
1282 * Called by FBO code to choose a PIPE_FORMAT_ for drawing surfaces.
1283 */
1284 enum pipe_format
1285 st_choose_renderbuffer_format(struct pipe_screen *screen,
1286 GLenum internalFormat, unsigned sample_count)
1287 {
1288 uint usage;
1289 if (_mesa_is_depth_or_stencil_format(internalFormat))
1290 usage = PIPE_BIND_DEPTH_STENCIL;
1291 else
1292 usage = PIPE_BIND_RENDER_TARGET;
1293 return st_choose_format(screen, internalFormat, GL_NONE, GL_NONE, PIPE_TEXTURE_2D,
1294 sample_count, usage);
1295 }
1296
1297
1298 gl_format
1299 st_ChooseTextureFormat_renderable(struct gl_context *ctx, GLint internalFormat,
1300 GLenum format, GLenum type, GLboolean renderable)
1301 {
1302 struct pipe_screen *screen = st_context(ctx)->pipe->screen;
1303 enum pipe_format pFormat;
1304 uint bindings;
1305
1306 (void) format;
1307 (void) type;
1308
1309 /* GL textures may wind up being render targets, but we don't know
1310 * that in advance. Specify potential render target flags now.
1311 */
1312 bindings = PIPE_BIND_SAMPLER_VIEW;
1313 if (renderable) {
1314 if (_mesa_is_depth_or_stencil_format(internalFormat))
1315 bindings |= PIPE_BIND_DEPTH_STENCIL;
1316 else
1317 bindings |= PIPE_BIND_RENDER_TARGET;
1318 }
1319
1320 pFormat = st_choose_format(screen, internalFormat, format, type,
1321 PIPE_TEXTURE_2D, 0, bindings);
1322
1323 if (pFormat == PIPE_FORMAT_NONE) {
1324 /* try choosing format again, this time without render target bindings */
1325 pFormat = st_choose_format(screen, internalFormat, format, type,
1326 PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW);
1327 }
1328
1329 if (pFormat == PIPE_FORMAT_NONE) {
1330 /* no luck at all */
1331 return MESA_FORMAT_NONE;
1332 }
1333
1334 return st_pipe_format_to_mesa_format(pFormat);
1335 }
1336
1337
1338 /**
1339 * Called via ctx->Driver.ChooseTextureFormat().
1340 */
1341 gl_format
1342 st_ChooseTextureFormat(struct gl_context *ctx, GLint internalFormat,
1343 GLenum format, GLenum type)
1344 {
1345 boolean want_renderable =
1346 internalFormat == 3 || internalFormat == 4 ||
1347 internalFormat == GL_RGB || internalFormat == GL_RGBA ||
1348 internalFormat == GL_RGB8 || internalFormat == GL_RGBA8 ||
1349 internalFormat == GL_BGRA;
1350
1351 return st_ChooseTextureFormat_renderable(ctx, internalFormat,
1352 format, type, want_renderable);
1353 }
1354
1355 /**
1356 * Test if a gallium format is equivalent to a GL format/type.
1357 */
1358 GLboolean
1359 st_equal_formats(enum pipe_format pFormat, GLenum format, GLenum type)
1360 {
1361 switch (pFormat) {
1362 case PIPE_FORMAT_A8B8G8R8_UNORM:
1363 return format == GL_RGBA && type == GL_UNSIGNED_BYTE;
1364 case PIPE_FORMAT_A8R8G8B8_UNORM:
1365 return format == GL_BGRA && type == GL_UNSIGNED_BYTE;
1366 case PIPE_FORMAT_B5G6R5_UNORM:
1367 return format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5;
1368 /* XXX more combos... */
1369 default:
1370 return GL_FALSE;
1371 }
1372 }
1373
1374 GLboolean
1375 st_sampler_compat_formats(enum pipe_format format1, enum pipe_format format2)
1376 {
1377 if (format1 == format2)
1378 return GL_TRUE;
1379
1380 if (format1 == PIPE_FORMAT_B8G8R8A8_UNORM &&
1381 format2 == PIPE_FORMAT_B8G8R8X8_UNORM)
1382 return GL_TRUE;
1383
1384 if (format1 == PIPE_FORMAT_B8G8R8X8_UNORM &&
1385 format2 == PIPE_FORMAT_B8G8R8A8_UNORM)
1386 return GL_TRUE;
1387
1388 if (format1 == PIPE_FORMAT_A8B8G8R8_UNORM &&
1389 format2 == PIPE_FORMAT_X8B8G8R8_UNORM)
1390 return GL_TRUE;
1391
1392 if (format1 == PIPE_FORMAT_X8B8G8R8_UNORM &&
1393 format2 == PIPE_FORMAT_A8B8G8R8_UNORM)
1394 return GL_TRUE;
1395
1396 if (format1 == PIPE_FORMAT_A8R8G8B8_UNORM &&
1397 format2 == PIPE_FORMAT_X8R8G8B8_UNORM)
1398 return GL_TRUE;
1399
1400 if (format1 == PIPE_FORMAT_X8R8G8B8_UNORM &&
1401 format2 == PIPE_FORMAT_A8R8G8B8_UNORM)
1402 return GL_TRUE;
1403
1404 return GL_FALSE;
1405 }
1406
1407
1408
1409 /**
1410 * This is used for translating texture border color and the clear
1411 * color. For example, the clear color is interpreted according to
1412 * the renderbuffer's base format. For example, if clearing a
1413 * GL_LUMINANCE buffer, ClearColor[0] = luminance and ClearColor[1] =
1414 * alpha. Similarly for texture border colors.
1415 */
1416 void
1417 st_translate_color(const GLfloat colorIn[4], GLenum baseFormat,
1418 GLfloat colorOut[4])
1419 {
1420 switch (baseFormat) {
1421 case GL_RED:
1422 colorOut[0] = colorIn[0];
1423 colorOut[1] = 0.0F;
1424 colorOut[2] = 0.0F;
1425 colorOut[3] = 1.0F;
1426 break;
1427 case GL_RG:
1428 colorOut[0] = colorIn[0];
1429 colorOut[1] = colorIn[1];
1430 colorOut[2] = 0.0F;
1431 colorOut[3] = 1.0F;
1432 break;
1433 case GL_RGB:
1434 colorOut[0] = colorIn[0];
1435 colorOut[1] = colorIn[1];
1436 colorOut[2] = colorIn[2];
1437 colorOut[3] = 1.0F;
1438 break;
1439 case GL_ALPHA:
1440 colorOut[0] = colorOut[1] = colorOut[2] = 0.0;
1441 colorOut[3] = colorIn[3];
1442 break;
1443 case GL_LUMINANCE:
1444 colorOut[0] = colorOut[1] = colorOut[2] = colorIn[0];
1445 colorOut[3] = 1.0;
1446 break;
1447 case GL_LUMINANCE_ALPHA:
1448 colorOut[0] = colorOut[1] = colorOut[2] = colorIn[0];
1449 colorOut[3] = colorIn[3];
1450 break;
1451 case GL_INTENSITY:
1452 colorOut[0] = colorOut[1] = colorOut[2] = colorOut[3] = colorIn[0];
1453 break;
1454 default:
1455 COPY_4V(colorOut, colorIn);
1456 }
1457 }