c9fa7a62e19131ce820c1bf8db840f20b047ea84
[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/enums.h"
39 #include "main/image.h"
40 #include "main/macros.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
72 desc = util_format_description(format);
73 assert(desc);
74
75 if (desc->layout == UTIL_FORMAT_LAYOUT_PLAIN) {
76 if (format == PIPE_FORMAT_B5G5R5A1_UNORM ||
77 format == PIPE_FORMAT_B5G6R5_UNORM) {
78 return GL_UNSIGNED_SHORT;
79 }
80 else if (format == PIPE_FORMAT_Z24_UNORM_S8_USCALED ||
81 format == PIPE_FORMAT_S8_USCALED_Z24_UNORM) {
82 return GL_UNSIGNED_INT_24_8;
83 }
84 else {
85 const GLuint size = format_max_bits(format);
86 if (size == 8) {
87 if (desc->channel[0].type == UTIL_FORMAT_TYPE_UNSIGNED)
88 return GL_UNSIGNED_BYTE;
89 else
90 return GL_BYTE;
91 }
92 else if (size == 16) {
93 if (desc->channel[0].type == UTIL_FORMAT_TYPE_UNSIGNED)
94 return GL_UNSIGNED_SHORT;
95 else
96 return GL_SHORT;
97 }
98 else {
99 assert( size <= 32 );
100 if (desc->channel[0].type == UTIL_FORMAT_TYPE_UNSIGNED)
101 return GL_UNSIGNED_INT;
102 else
103 return GL_INT;
104 }
105 }
106 }
107 else if (format == PIPE_FORMAT_UYVY) {
108 return GL_UNSIGNED_SHORT;
109 }
110 else if (format == PIPE_FORMAT_YUYV) {
111 return GL_UNSIGNED_SHORT;
112 }
113 else {
114 /* compressed format? */
115 assert(0);
116 }
117
118 assert(0);
119 return GL_NONE;
120 }
121
122
123 /**
124 * Translate Mesa format to Gallium format.
125 */
126 enum pipe_format
127 st_mesa_format_to_pipe_format(gl_format mesaFormat)
128 {
129 switch (mesaFormat) {
130 case MESA_FORMAT_RGBA8888:
131 return PIPE_FORMAT_A8B8G8R8_UNORM;
132 case MESA_FORMAT_RGBA8888_REV:
133 return PIPE_FORMAT_R8G8B8A8_UNORM;
134 case MESA_FORMAT_ARGB8888:
135 return PIPE_FORMAT_B8G8R8A8_UNORM;
136 case MESA_FORMAT_ARGB8888_REV:
137 return PIPE_FORMAT_A8R8G8B8_UNORM;
138 case MESA_FORMAT_XRGB8888:
139 return PIPE_FORMAT_B8G8R8X8_UNORM;
140 case MESA_FORMAT_XRGB8888_REV:
141 return PIPE_FORMAT_X8R8G8B8_UNORM;
142 case MESA_FORMAT_ARGB1555:
143 return PIPE_FORMAT_B5G5R5A1_UNORM;
144 case MESA_FORMAT_ARGB4444:
145 return PIPE_FORMAT_B4G4R4A4_UNORM;
146 case MESA_FORMAT_RGB565:
147 return PIPE_FORMAT_B5G6R5_UNORM;
148 case MESA_FORMAT_AL88:
149 return PIPE_FORMAT_L8A8_UNORM;
150 case MESA_FORMAT_A8:
151 return PIPE_FORMAT_A8_UNORM;
152 case MESA_FORMAT_L8:
153 return PIPE_FORMAT_L8_UNORM;
154 case MESA_FORMAT_I8:
155 return PIPE_FORMAT_I8_UNORM;
156 case MESA_FORMAT_Z16:
157 return PIPE_FORMAT_Z16_UNORM;
158 case MESA_FORMAT_Z32:
159 return PIPE_FORMAT_Z32_UNORM;
160 case MESA_FORMAT_Z24_S8:
161 return PIPE_FORMAT_S8_USCALED_Z24_UNORM;
162 case MESA_FORMAT_S8_Z24:
163 return PIPE_FORMAT_Z24_UNORM_S8_USCALED;
164 case MESA_FORMAT_Z24_X8:
165 return PIPE_FORMAT_X8Z24_UNORM;
166 case MESA_FORMAT_X8_Z24:
167 return PIPE_FORMAT_Z24X8_UNORM;
168 case MESA_FORMAT_YCBCR:
169 return PIPE_FORMAT_UYVY;
170 #if FEATURE_texture_s3tc
171 case MESA_FORMAT_RGB_DXT1:
172 return PIPE_FORMAT_DXT1_RGB;
173 case MESA_FORMAT_RGBA_DXT1:
174 return PIPE_FORMAT_DXT1_RGBA;
175 case MESA_FORMAT_RGBA_DXT3:
176 return PIPE_FORMAT_DXT3_RGBA;
177 case MESA_FORMAT_RGBA_DXT5:
178 return PIPE_FORMAT_DXT5_RGBA;
179 #if FEATURE_EXT_texture_sRGB
180 case MESA_FORMAT_SRGB_DXT1:
181 return PIPE_FORMAT_DXT1_SRGB;
182 case MESA_FORMAT_SRGBA_DXT1:
183 return PIPE_FORMAT_DXT1_SRGBA;
184 case MESA_FORMAT_SRGBA_DXT3:
185 return PIPE_FORMAT_DXT3_SRGBA;
186 case MESA_FORMAT_SRGBA_DXT5:
187 return PIPE_FORMAT_DXT5_SRGBA;
188 #endif
189 #endif
190 #if FEATURE_EXT_texture_sRGB
191 case MESA_FORMAT_SLA8:
192 return PIPE_FORMAT_L8A8_SRGB;
193 case MESA_FORMAT_SL8:
194 return PIPE_FORMAT_L8_SRGB;
195 case MESA_FORMAT_SRGB8:
196 return PIPE_FORMAT_R8G8B8_SRGB;
197 case MESA_FORMAT_SRGBA8:
198 return PIPE_FORMAT_A8B8G8R8_SRGB;
199 case MESA_FORMAT_SARGB8:
200 return PIPE_FORMAT_B8G8R8A8_SRGB;
201 #endif
202 default:
203 assert(0);
204 return PIPE_FORMAT_NONE;
205 }
206 }
207
208
209 /**
210 * Translate Gallium format to Mesa format.
211 */
212 gl_format
213 st_pipe_format_to_mesa_format(enum pipe_format format)
214 {
215 switch (format) {
216 case PIPE_FORMAT_A8B8G8R8_UNORM:
217 return MESA_FORMAT_RGBA8888;
218 case PIPE_FORMAT_R8G8B8A8_UNORM:
219 return MESA_FORMAT_RGBA8888_REV;
220 case PIPE_FORMAT_B8G8R8A8_UNORM:
221 return MESA_FORMAT_ARGB8888;
222 case PIPE_FORMAT_A8R8G8B8_UNORM:
223 return MESA_FORMAT_ARGB8888_REV;
224 case PIPE_FORMAT_B8G8R8X8_UNORM:
225 return MESA_FORMAT_XRGB8888;
226 case PIPE_FORMAT_X8R8G8B8_UNORM:
227 return MESA_FORMAT_XRGB8888_REV;
228 case PIPE_FORMAT_B5G5R5A1_UNORM:
229 return MESA_FORMAT_ARGB1555;
230 case PIPE_FORMAT_B4G4R4A4_UNORM:
231 return MESA_FORMAT_ARGB4444;
232 case PIPE_FORMAT_B5G6R5_UNORM:
233 return MESA_FORMAT_RGB565;
234 case PIPE_FORMAT_L8A8_UNORM:
235 return MESA_FORMAT_AL88;
236 case PIPE_FORMAT_A8_UNORM:
237 return MESA_FORMAT_A8;
238 case PIPE_FORMAT_L8_UNORM:
239 return MESA_FORMAT_L8;
240 case PIPE_FORMAT_I8_UNORM:
241 return MESA_FORMAT_I8;
242 case PIPE_FORMAT_S8_USCALED:
243 return MESA_FORMAT_S8;
244
245 case PIPE_FORMAT_R16G16B16A16_SNORM:
246 return MESA_FORMAT_SIGNED_RGBA_16;
247
248 case PIPE_FORMAT_Z16_UNORM:
249 return MESA_FORMAT_Z16;
250 case PIPE_FORMAT_Z32_UNORM:
251 return MESA_FORMAT_Z32;
252 case PIPE_FORMAT_S8_USCALED_Z24_UNORM:
253 return MESA_FORMAT_Z24_S8;
254 case PIPE_FORMAT_X8Z24_UNORM:
255 return MESA_FORMAT_Z24_X8;
256 case PIPE_FORMAT_Z24X8_UNORM:
257 return MESA_FORMAT_X8_Z24;
258 case PIPE_FORMAT_Z24_UNORM_S8_USCALED:
259 return MESA_FORMAT_S8_Z24;
260
261 case PIPE_FORMAT_UYVY:
262 return MESA_FORMAT_YCBCR;
263 case PIPE_FORMAT_YUYV:
264 return MESA_FORMAT_YCBCR_REV;
265
266 #if FEATURE_texture_s3tc
267 case PIPE_FORMAT_DXT1_RGB:
268 return MESA_FORMAT_RGB_DXT1;
269 case PIPE_FORMAT_DXT1_RGBA:
270 return MESA_FORMAT_RGBA_DXT1;
271 case PIPE_FORMAT_DXT3_RGBA:
272 return MESA_FORMAT_RGBA_DXT3;
273 case PIPE_FORMAT_DXT5_RGBA:
274 return MESA_FORMAT_RGBA_DXT5;
275 #if FEATURE_EXT_texture_sRGB
276 case PIPE_FORMAT_DXT1_SRGB:
277 return MESA_FORMAT_SRGB_DXT1;
278 case PIPE_FORMAT_DXT1_SRGBA:
279 return MESA_FORMAT_SRGBA_DXT1;
280 case PIPE_FORMAT_DXT3_SRGBA:
281 return MESA_FORMAT_SRGBA_DXT3;
282 case PIPE_FORMAT_DXT5_SRGBA:
283 return MESA_FORMAT_SRGBA_DXT5;
284 #endif
285 #endif
286
287 #if FEATURE_EXT_texture_sRGB
288 case PIPE_FORMAT_L8A8_SRGB:
289 return MESA_FORMAT_SLA8;
290 case PIPE_FORMAT_L8_SRGB:
291 return MESA_FORMAT_SL8;
292 case PIPE_FORMAT_R8G8B8_SRGB:
293 return MESA_FORMAT_SRGB8;
294 case PIPE_FORMAT_A8B8G8R8_SRGB:
295 return MESA_FORMAT_SRGBA8;
296 case PIPE_FORMAT_B8G8R8A8_SRGB:
297 return MESA_FORMAT_SARGB8;
298 #endif
299 default:
300 assert(0);
301 return MESA_FORMAT_NONE;
302 }
303 }
304
305
306 /**
307 * Return first supported format from the given list.
308 */
309 static enum pipe_format
310 find_supported_format(struct pipe_screen *screen,
311 const enum pipe_format formats[],
312 uint num_formats,
313 enum pipe_texture_target target,
314 unsigned sample_count,
315 unsigned tex_usage,
316 unsigned geom_flags)
317 {
318 uint i;
319 for (i = 0; i < num_formats; i++) {
320 if (screen->is_format_supported(screen, formats[i], target,
321 sample_count, tex_usage, geom_flags)) {
322 return formats[i];
323 }
324 }
325 return PIPE_FORMAT_NONE;
326 }
327
328
329 /**
330 * Find an RGBA format supported by the context/winsys.
331 */
332 static enum pipe_format
333 default_rgba_format(struct pipe_screen *screen,
334 enum pipe_texture_target target,
335 unsigned sample_count,
336 unsigned tex_usage,
337 unsigned geom_flags)
338 {
339 static const enum pipe_format colorFormats[] = {
340 PIPE_FORMAT_B8G8R8A8_UNORM,
341 PIPE_FORMAT_A8R8G8B8_UNORM,
342 PIPE_FORMAT_A8B8G8R8_UNORM,
343 PIPE_FORMAT_B5G6R5_UNORM
344 };
345 return find_supported_format(screen, colorFormats, Elements(colorFormats),
346 target, sample_count, tex_usage, geom_flags);
347 }
348
349
350 /**
351 * Find an RGB format supported by the context/winsys.
352 */
353 static enum pipe_format
354 default_rgb_format(struct pipe_screen *screen,
355 enum pipe_texture_target target,
356 unsigned sample_count,
357 unsigned tex_usage,
358 unsigned geom_flags)
359 {
360 static const enum pipe_format colorFormats[] = {
361 PIPE_FORMAT_B8G8R8X8_UNORM,
362 PIPE_FORMAT_X8R8G8B8_UNORM,
363 PIPE_FORMAT_X8B8G8R8_UNORM,
364 PIPE_FORMAT_B8G8R8A8_UNORM,
365 PIPE_FORMAT_A8R8G8B8_UNORM,
366 PIPE_FORMAT_A8B8G8R8_UNORM,
367 PIPE_FORMAT_B5G6R5_UNORM
368 };
369 return find_supported_format(screen, colorFormats, Elements(colorFormats),
370 target, sample_count, tex_usage, geom_flags);
371 }
372
373 /**
374 * Find an sRGBA format supported by the context/winsys.
375 */
376 static enum pipe_format
377 default_srgba_format(struct pipe_screen *screen,
378 enum pipe_texture_target target,
379 unsigned sample_count,
380 unsigned tex_usage,
381 unsigned geom_flags)
382 {
383 static const enum pipe_format colorFormats[] = {
384 PIPE_FORMAT_B8G8R8A8_SRGB,
385 PIPE_FORMAT_A8R8G8B8_SRGB,
386 PIPE_FORMAT_A8B8G8R8_SRGB,
387 };
388 return find_supported_format(screen, colorFormats, Elements(colorFormats),
389 target, sample_count, tex_usage, geom_flags);
390 }
391
392
393 /**
394 * Given an OpenGL internalFormat value for a texture or surface, return
395 * the best matching PIPE_FORMAT_x, or PIPE_FORMAT_NONE if there's no match.
396 * This is called during glTexImage2D, for example.
397 *
398 * The bindings parameter typically has PIPE_BIND_SAMPLER_VIEW set, plus
399 * either PIPE_BINDING_RENDER_TARGET or PIPE_BINDING_DEPTH_STENCIL if
400 * we want render-to-texture ability.
401 *
402 * \param internalFormat the user value passed to glTexImage2D
403 * \param target one of PIPE_TEXTURE_x
404 * \param bindings bitmask of PIPE_BIND_x flags.
405 */
406 enum pipe_format
407 st_choose_format(struct pipe_screen *screen, GLenum internalFormat,
408 enum pipe_texture_target target, unsigned sample_count,
409 unsigned bindings)
410 {
411 unsigned geom_flags = 0; /* we don't care about POT vs. NPOT here, yet */
412
413 switch (internalFormat) {
414 case 4:
415 case GL_RGBA:
416 case GL_RGBA8:
417 case GL_RGB10_A2:
418 case GL_RGBA12:
419 return default_rgba_format( screen, target, sample_count, bindings,
420 geom_flags );
421 case 3:
422 case GL_RGB:
423 return default_rgb_format( screen, target, sample_count, bindings,
424 geom_flags );
425 case GL_RGBA16:
426 return default_rgba_format( screen, target, sample_count, bindings,
427 geom_flags );
428
429 case GL_RGBA4:
430 case GL_RGBA2:
431 if (screen->is_format_supported( screen, PIPE_FORMAT_B4G4R4A4_UNORM,
432 target, sample_count, bindings,
433 geom_flags ))
434 return PIPE_FORMAT_B4G4R4A4_UNORM;
435 return default_rgba_format( screen, target, sample_count, bindings,
436 geom_flags );
437
438 case GL_RGB5_A1:
439 if (screen->is_format_supported( screen, PIPE_FORMAT_B5G5R5A1_UNORM,
440 target, sample_count, bindings,
441 geom_flags ))
442 return PIPE_FORMAT_B5G5R5A1_UNORM;
443 return default_rgba_format( screen, target, sample_count, bindings,
444 geom_flags );
445
446 case GL_RGB8:
447 case GL_RGB10:
448 case GL_RGB12:
449 case GL_RGB16:
450 return default_rgb_format( screen, target, sample_count, bindings,
451 geom_flags );
452
453 case GL_RGB5:
454 case GL_RGB4:
455 case GL_R3_G3_B2:
456 if (screen->is_format_supported( screen, PIPE_FORMAT_B5G6R5_UNORM,
457 target, sample_count, bindings,
458 geom_flags ))
459 return PIPE_FORMAT_B5G6R5_UNORM;
460 if (screen->is_format_supported( screen, PIPE_FORMAT_B5G5R5A1_UNORM,
461 target, sample_count, bindings,
462 geom_flags ))
463 return PIPE_FORMAT_B5G5R5A1_UNORM;
464 return default_rgba_format( screen, target, sample_count, bindings,
465 geom_flags );
466
467 case GL_ALPHA:
468 case GL_ALPHA4:
469 case GL_ALPHA8:
470 case GL_ALPHA12:
471 case GL_ALPHA16:
472 case GL_COMPRESSED_ALPHA:
473 if (screen->is_format_supported( screen, PIPE_FORMAT_A8_UNORM, target,
474 sample_count, bindings, geom_flags ))
475 return PIPE_FORMAT_A8_UNORM;
476 return default_rgba_format( screen, target, sample_count, bindings,
477 geom_flags );
478
479 case 1:
480 case GL_LUMINANCE:
481 case GL_LUMINANCE4:
482 case GL_LUMINANCE8:
483 case GL_LUMINANCE12:
484 case GL_LUMINANCE16:
485 case GL_COMPRESSED_LUMINANCE:
486 if (screen->is_format_supported( screen, PIPE_FORMAT_L8_UNORM, target,
487 sample_count, bindings, geom_flags ))
488 return PIPE_FORMAT_L8_UNORM;
489 return default_rgba_format( screen, target, sample_count, bindings,
490 geom_flags );
491
492 case 2:
493 case GL_LUMINANCE_ALPHA:
494 case GL_LUMINANCE4_ALPHA4:
495 case GL_LUMINANCE6_ALPHA2:
496 case GL_LUMINANCE8_ALPHA8:
497 case GL_LUMINANCE12_ALPHA4:
498 case GL_LUMINANCE12_ALPHA12:
499 case GL_LUMINANCE16_ALPHA16:
500 case GL_COMPRESSED_LUMINANCE_ALPHA:
501 if (screen->is_format_supported( screen, PIPE_FORMAT_L8A8_UNORM, target,
502 sample_count, bindings, geom_flags ))
503 return PIPE_FORMAT_L8A8_UNORM;
504 return default_rgba_format( screen, target, sample_count, bindings,
505 geom_flags );
506
507 case GL_INTENSITY:
508 case GL_INTENSITY4:
509 case GL_INTENSITY8:
510 case GL_INTENSITY12:
511 case GL_INTENSITY16:
512 case GL_COMPRESSED_INTENSITY:
513 if (screen->is_format_supported( screen, PIPE_FORMAT_I8_UNORM, target,
514 sample_count, bindings, geom_flags ))
515 return PIPE_FORMAT_I8_UNORM;
516 return default_rgba_format( screen, target, sample_count, bindings,
517 geom_flags );
518
519 case GL_YCBCR_MESA:
520 if (screen->is_format_supported(screen, PIPE_FORMAT_UYVY, target,
521 sample_count, bindings, geom_flags)) {
522 return PIPE_FORMAT_UYVY;
523 }
524 if (screen->is_format_supported(screen, PIPE_FORMAT_YUYV, target,
525 sample_count, bindings, geom_flags)) {
526 return PIPE_FORMAT_YUYV;
527 }
528 return PIPE_FORMAT_NONE;
529
530 case GL_COMPRESSED_RGB:
531 /* can only sample from compressed formats */
532 if (bindings & ~PIPE_BIND_SAMPLER_VIEW)
533 return PIPE_FORMAT_NONE;
534 else if (screen->is_format_supported(screen, PIPE_FORMAT_DXT1_RGB,
535 target, sample_count, bindings,
536 geom_flags))
537 return PIPE_FORMAT_DXT1_RGB;
538 else
539 return default_rgb_format(screen, target, sample_count, bindings,
540 geom_flags);
541
542 case GL_COMPRESSED_RGBA:
543 /* can only sample from compressed formats */
544 if (bindings & ~PIPE_BIND_SAMPLER_VIEW)
545 return PIPE_FORMAT_NONE;
546 else if (screen->is_format_supported(screen, PIPE_FORMAT_DXT3_RGBA,
547 target, sample_count, bindings,
548 geom_flags))
549 return PIPE_FORMAT_DXT3_RGBA;
550 else
551 return default_rgba_format(screen, target, sample_count, bindings,
552 geom_flags);
553
554 case GL_RGB_S3TC:
555 case GL_RGB4_S3TC:
556 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
557 if (screen->is_format_supported(screen, PIPE_FORMAT_DXT1_RGB,
558 target, sample_count, bindings,
559 geom_flags))
560 return PIPE_FORMAT_DXT1_RGB;
561 else
562 return PIPE_FORMAT_NONE;
563
564 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
565 if (screen->is_format_supported(screen, PIPE_FORMAT_DXT1_RGBA,
566 target, sample_count, bindings,
567 geom_flags))
568 return PIPE_FORMAT_DXT1_RGBA;
569 else
570 return PIPE_FORMAT_NONE;
571
572 case GL_RGBA_S3TC:
573 case GL_RGBA4_S3TC:
574 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
575 if (screen->is_format_supported(screen, PIPE_FORMAT_DXT3_RGBA,
576 target, sample_count, bindings,
577 geom_flags))
578 return PIPE_FORMAT_DXT3_RGBA;
579 else
580 return PIPE_FORMAT_NONE;
581
582 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
583 if (screen->is_format_supported(screen, PIPE_FORMAT_DXT5_RGBA,
584 target, sample_count, bindings,
585 geom_flags))
586 return PIPE_FORMAT_DXT5_RGBA;
587 else
588 return PIPE_FORMAT_NONE;
589
590 #if 0
591 case GL_COMPRESSED_RGB_FXT1_3DFX:
592 return PIPE_FORMAT_RGB_FXT1;
593 case GL_COMPRESSED_RGBA_FXT1_3DFX:
594 return PIPE_FORMAT_RGB_FXT1;
595 #endif
596
597 case GL_DEPTH_COMPONENT16:
598 if (screen->is_format_supported(screen, PIPE_FORMAT_Z16_UNORM, target,
599 sample_count, bindings, geom_flags))
600 return PIPE_FORMAT_Z16_UNORM;
601 /* fall-through */
602 case GL_DEPTH_COMPONENT24:
603 if (screen->is_format_supported(screen, PIPE_FORMAT_Z24_UNORM_S8_USCALED,
604 target, sample_count, bindings, geom_flags))
605 return PIPE_FORMAT_Z24_UNORM_S8_USCALED;
606 if (screen->is_format_supported(screen, PIPE_FORMAT_S8_USCALED_Z24_UNORM,
607 target, sample_count, bindings, geom_flags))
608 return PIPE_FORMAT_S8_USCALED_Z24_UNORM;
609 /* fall-through */
610 case GL_DEPTH_COMPONENT32:
611 if (screen->is_format_supported(screen, PIPE_FORMAT_Z32_UNORM, target,
612 sample_count, bindings, geom_flags))
613 return PIPE_FORMAT_Z32_UNORM;
614 /* fall-through */
615 case GL_DEPTH_COMPONENT:
616 {
617 static const enum pipe_format formats[] = {
618 PIPE_FORMAT_Z16_UNORM,
619 PIPE_FORMAT_Z32_UNORM,
620 PIPE_FORMAT_Z24_UNORM_S8_USCALED,
621 PIPE_FORMAT_S8_USCALED_Z24_UNORM
622 };
623 return find_supported_format(screen, formats, Elements(formats),
624 target, sample_count, bindings, geom_flags);
625 }
626
627 case GL_STENCIL_INDEX:
628 case GL_STENCIL_INDEX1_EXT:
629 case GL_STENCIL_INDEX4_EXT:
630 case GL_STENCIL_INDEX8_EXT:
631 case GL_STENCIL_INDEX16_EXT:
632 {
633 static const enum pipe_format formats[] = {
634 PIPE_FORMAT_S8_USCALED,
635 PIPE_FORMAT_Z24_UNORM_S8_USCALED,
636 PIPE_FORMAT_S8_USCALED_Z24_UNORM
637 };
638 return find_supported_format(screen, formats, Elements(formats),
639 target, sample_count, bindings, geom_flags);
640 }
641
642 case GL_DEPTH_STENCIL_EXT:
643 case GL_DEPTH24_STENCIL8_EXT:
644 {
645 static const enum pipe_format formats[] = {
646 PIPE_FORMAT_Z24_UNORM_S8_USCALED,
647 PIPE_FORMAT_S8_USCALED_Z24_UNORM
648 };
649 return find_supported_format(screen, formats, Elements(formats),
650 target, sample_count, bindings, geom_flags);
651 }
652
653 case GL_SRGB_EXT:
654 case GL_SRGB8_EXT:
655 case GL_COMPRESSED_SRGB_EXT:
656 case GL_COMPRESSED_SRGB_ALPHA_EXT:
657 case GL_SRGB_ALPHA_EXT:
658 case GL_SRGB8_ALPHA8_EXT:
659 return default_srgba_format( screen, target, sample_count, bindings,
660 geom_flags );
661 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
662 return PIPE_FORMAT_DXT1_SRGB;
663 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
664 return PIPE_FORMAT_DXT1_SRGBA;
665 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
666 return PIPE_FORMAT_DXT3_SRGBA;
667 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
668 return PIPE_FORMAT_DXT5_SRGBA;
669
670 case GL_SLUMINANCE_ALPHA_EXT:
671 case GL_SLUMINANCE8_ALPHA8_EXT:
672 case GL_COMPRESSED_SLUMINANCE_EXT:
673 case GL_COMPRESSED_SLUMINANCE_ALPHA_EXT:
674 if (screen->is_format_supported(screen, PIPE_FORMAT_L8A8_SRGB, target,
675 sample_count, bindings, geom_flags))
676 return PIPE_FORMAT_L8A8_SRGB;
677 return default_srgba_format( screen, target, sample_count, bindings,
678 geom_flags );
679
680 case GL_SLUMINANCE_EXT:
681 case GL_SLUMINANCE8_EXT:
682 if (screen->is_format_supported(screen, PIPE_FORMAT_L8_SRGB, target,
683 sample_count, bindings, geom_flags))
684 return PIPE_FORMAT_L8_SRGB;
685 return default_srgba_format( screen, target, sample_count, bindings,
686 geom_flags );
687
688 default:
689 return PIPE_FORMAT_NONE;
690 }
691 }
692
693
694 /**
695 * Called by FBO code to choose a PIPE_FORMAT_ for drawing surfaces.
696 */
697 enum pipe_format
698 st_choose_renderbuffer_format(struct pipe_screen *screen,
699 GLenum internalFormat, unsigned sample_count)
700 {
701 uint usage;
702 if (_mesa_is_depth_or_stencil_format(internalFormat))
703 usage = PIPE_BIND_DEPTH_STENCIL;
704 else
705 usage = PIPE_BIND_RENDER_TARGET;
706 return st_choose_format(screen, internalFormat, PIPE_TEXTURE_2D,
707 sample_count, usage);
708 }
709
710
711 /**
712 * Called via ctx->Driver.chooseTextureFormat().
713 */
714 gl_format
715 st_ChooseTextureFormat(GLcontext *ctx, GLint internalFormat,
716 GLenum format, GLenum type)
717 {
718 struct pipe_screen *screen = st_context(ctx)->pipe->screen;
719 enum pipe_format pFormat;
720 uint bindings;
721
722 (void) format;
723 (void) type;
724
725 /* GL textures may wind up being render targets, but we don't know
726 * that in advance. Specify potential render target flags now.
727 */
728 if (_mesa_is_depth_format(internalFormat) ||
729 _mesa_is_depthstencil_format(internalFormat))
730 bindings = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_DEPTH_STENCIL;
731 else
732 bindings = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
733
734 pFormat = st_choose_format(screen, internalFormat,
735 PIPE_TEXTURE_2D, 0, bindings);
736
737 if (pFormat == PIPE_FORMAT_NONE) {
738 /* try choosing format again, this time without render target bindings */
739 pFormat = st_choose_format(screen, internalFormat,
740 PIPE_TEXTURE_2D, 0, PIPE_BIND_SAMPLER_VIEW);
741 }
742
743 if (pFormat == PIPE_FORMAT_NONE) {
744 /* no luck at all */
745 return MESA_FORMAT_NONE;
746 }
747
748 return st_pipe_format_to_mesa_format(pFormat);
749 }
750
751
752 /**
753 * Test if a gallium format is equivalent to a GL format/type.
754 */
755 GLboolean
756 st_equal_formats(enum pipe_format pFormat, GLenum format, GLenum type)
757 {
758 switch (pFormat) {
759 case PIPE_FORMAT_A8B8G8R8_UNORM:
760 return format == GL_RGBA && type == GL_UNSIGNED_BYTE;
761 case PIPE_FORMAT_A8R8G8B8_UNORM:
762 return format == GL_BGRA && type == GL_UNSIGNED_BYTE;
763 case PIPE_FORMAT_B5G6R5_UNORM:
764 return format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5;
765 /* XXX more combos... */
766 default:
767 return GL_FALSE;
768 }
769 }
770
771 GLboolean
772 st_sampler_compat_formats(enum pipe_format format1, enum pipe_format format2)
773 {
774 if (format1 == format2)
775 return GL_TRUE;
776
777 if (format1 == PIPE_FORMAT_B8G8R8A8_UNORM &&
778 format2 == PIPE_FORMAT_B8G8R8X8_UNORM)
779 return GL_TRUE;
780
781 if (format1 == PIPE_FORMAT_B8G8R8X8_UNORM &&
782 format2 == PIPE_FORMAT_B8G8R8A8_UNORM)
783 return GL_TRUE;
784
785 if (format1 == PIPE_FORMAT_A8B8G8R8_UNORM &&
786 format2 == PIPE_FORMAT_X8B8G8R8_UNORM)
787 return GL_TRUE;
788
789 if (format1 == PIPE_FORMAT_X8B8G8R8_UNORM &&
790 format2 == PIPE_FORMAT_A8B8G8R8_UNORM)
791 return GL_TRUE;
792
793 if (format1 == PIPE_FORMAT_A8R8G8B8_UNORM &&
794 format2 == PIPE_FORMAT_X8R8G8B8_UNORM)
795 return GL_TRUE;
796
797 if (format1 == PIPE_FORMAT_X8R8G8B8_UNORM &&
798 format2 == PIPE_FORMAT_A8R8G8B8_UNORM)
799 return GL_TRUE;
800
801 return GL_FALSE;
802 }