st/mesa: try to get actual compressed format for GL_COMPRESSED_RGB[A] formats
[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 tex_usage,
315 unsigned geom_flags)
316 {
317 uint i;
318 for (i = 0; i < num_formats; i++) {
319 if (screen->is_format_supported(screen, formats[i], target,
320 tex_usage, geom_flags)) {
321 return formats[i];
322 }
323 }
324 return PIPE_FORMAT_NONE;
325 }
326
327
328 /**
329 * Find an RGBA format supported by the context/winsys.
330 */
331 static enum pipe_format
332 default_rgba_format(struct pipe_screen *screen,
333 enum pipe_texture_target target,
334 unsigned tex_usage,
335 unsigned geom_flags)
336 {
337 static const enum pipe_format colorFormats[] = {
338 PIPE_FORMAT_B8G8R8A8_UNORM,
339 PIPE_FORMAT_A8R8G8B8_UNORM,
340 PIPE_FORMAT_A8B8G8R8_UNORM,
341 PIPE_FORMAT_B5G6R5_UNORM
342 };
343 return find_supported_format(screen, colorFormats, Elements(colorFormats),
344 target, tex_usage, geom_flags);
345 }
346
347
348 /**
349 * Find an RGB format supported by the context/winsys.
350 */
351 static enum pipe_format
352 default_rgb_format(struct pipe_screen *screen,
353 enum pipe_texture_target target,
354 unsigned tex_usage,
355 unsigned geom_flags)
356 {
357 static const enum pipe_format colorFormats[] = {
358 PIPE_FORMAT_B8G8R8X8_UNORM,
359 PIPE_FORMAT_X8R8G8B8_UNORM,
360 PIPE_FORMAT_X8B8G8R8_UNORM,
361 PIPE_FORMAT_B8G8R8A8_UNORM,
362 PIPE_FORMAT_A8R8G8B8_UNORM,
363 PIPE_FORMAT_A8B8G8R8_UNORM,
364 PIPE_FORMAT_B5G6R5_UNORM
365 };
366 return find_supported_format(screen, colorFormats, Elements(colorFormats),
367 target, tex_usage, geom_flags);
368 }
369
370 /**
371 * Find an sRGBA format supported by the context/winsys.
372 */
373 static enum pipe_format
374 default_srgba_format(struct pipe_screen *screen,
375 enum pipe_texture_target target,
376 unsigned tex_usage,
377 unsigned geom_flags)
378 {
379 static const enum pipe_format colorFormats[] = {
380 PIPE_FORMAT_B8G8R8A8_SRGB,
381 PIPE_FORMAT_A8R8G8B8_SRGB,
382 PIPE_FORMAT_A8B8G8R8_SRGB,
383 };
384 return find_supported_format(screen, colorFormats, Elements(colorFormats),
385 target, tex_usage, geom_flags);
386 }
387
388
389 /**
390 * Given an OpenGL internalFormat value for a texture or surface, return
391 * the best matching PIPE_FORMAT_x, or PIPE_FORMAT_NONE if there's no match.
392 * \param target one of PIPE_TEXTURE_x
393 * \param tex_usage either PIPE_BIND_RENDER_TARGET
394 * or PIPE_BIND_SAMPLER_VIEW
395 */
396 enum pipe_format
397 st_choose_format(struct pipe_screen *screen, GLenum internalFormat,
398 enum pipe_texture_target target, unsigned tex_usage)
399 {
400 unsigned geom_flags = 0;
401
402 switch (internalFormat) {
403 case 4:
404 case GL_RGBA:
405 case GL_RGBA8:
406 case GL_RGB10_A2:
407 case GL_RGBA12:
408 return default_rgba_format( screen, target, tex_usage, geom_flags );
409 case 3:
410 case GL_RGB:
411 return default_rgb_format( screen, target, tex_usage, geom_flags );
412 case GL_RGBA16:
413 return default_rgba_format( screen, target, tex_usage, geom_flags );
414
415 case GL_RGBA4:
416 case GL_RGBA2:
417 if (screen->is_format_supported( screen, PIPE_FORMAT_B4G4R4A4_UNORM, target, tex_usage, geom_flags ))
418 return PIPE_FORMAT_B4G4R4A4_UNORM;
419 return default_rgba_format( screen, target, tex_usage, geom_flags );
420
421 case GL_RGB5_A1:
422 if (screen->is_format_supported( screen, PIPE_FORMAT_B5G5R5A1_UNORM, target, tex_usage, geom_flags ))
423 return PIPE_FORMAT_B5G5R5A1_UNORM;
424 return default_rgba_format( screen, target, tex_usage, geom_flags );
425
426 case GL_RGB8:
427 case GL_RGB10:
428 case GL_RGB12:
429 case GL_RGB16:
430 return default_rgb_format( screen, target, tex_usage, geom_flags );
431
432 case GL_RGB5:
433 case GL_RGB4:
434 case GL_R3_G3_B2:
435 if (screen->is_format_supported( screen, PIPE_FORMAT_B5G6R5_UNORM, target, tex_usage, geom_flags ))
436 return PIPE_FORMAT_B5G6R5_UNORM;
437 if (screen->is_format_supported( screen, PIPE_FORMAT_B5G5R5A1_UNORM, target, tex_usage, geom_flags ))
438 return PIPE_FORMAT_B5G5R5A1_UNORM;
439 return default_rgba_format( screen, target, tex_usage, geom_flags );
440
441 case GL_ALPHA:
442 case GL_ALPHA4:
443 case GL_ALPHA8:
444 case GL_ALPHA12:
445 case GL_ALPHA16:
446 case GL_COMPRESSED_ALPHA:
447 if (screen->is_format_supported( screen, PIPE_FORMAT_A8_UNORM, target, tex_usage, geom_flags ))
448 return PIPE_FORMAT_A8_UNORM;
449 return default_rgba_format( screen, target, tex_usage, geom_flags );
450
451 case 1:
452 case GL_LUMINANCE:
453 case GL_LUMINANCE4:
454 case GL_LUMINANCE8:
455 case GL_LUMINANCE12:
456 case GL_LUMINANCE16:
457 case GL_COMPRESSED_LUMINANCE:
458 if (screen->is_format_supported( screen, PIPE_FORMAT_L8_UNORM, target, tex_usage, geom_flags ))
459 return PIPE_FORMAT_L8_UNORM;
460 return default_rgba_format( screen, target, tex_usage, geom_flags );
461
462 case 2:
463 case GL_LUMINANCE_ALPHA:
464 case GL_LUMINANCE4_ALPHA4:
465 case GL_LUMINANCE6_ALPHA2:
466 case GL_LUMINANCE8_ALPHA8:
467 case GL_LUMINANCE12_ALPHA4:
468 case GL_LUMINANCE12_ALPHA12:
469 case GL_LUMINANCE16_ALPHA16:
470 case GL_COMPRESSED_LUMINANCE_ALPHA:
471 if (screen->is_format_supported( screen, PIPE_FORMAT_L8A8_UNORM, target, tex_usage, geom_flags ))
472 return PIPE_FORMAT_L8A8_UNORM;
473 return default_rgba_format( screen, target, tex_usage, geom_flags );
474
475 case GL_INTENSITY:
476 case GL_INTENSITY4:
477 case GL_INTENSITY8:
478 case GL_INTENSITY12:
479 case GL_INTENSITY16:
480 case GL_COMPRESSED_INTENSITY:
481 if (screen->is_format_supported( screen, PIPE_FORMAT_I8_UNORM, target, tex_usage, geom_flags ))
482 return PIPE_FORMAT_I8_UNORM;
483 return default_rgba_format( screen, target, tex_usage, geom_flags );
484
485 case GL_YCBCR_MESA:
486 if (screen->is_format_supported(screen, PIPE_FORMAT_UYVY,
487 target, tex_usage, geom_flags)) {
488 return PIPE_FORMAT_UYVY;
489 }
490 if (screen->is_format_supported(screen, PIPE_FORMAT_YUYV,
491 target, tex_usage, geom_flags)) {
492 return PIPE_FORMAT_YUYV;
493 }
494 return PIPE_FORMAT_NONE;
495
496 case GL_COMPRESSED_RGB:
497 /* can only sample from compressed formats */
498 if (tex_usage & ~PIPE_BIND_SAMPLER_VIEW)
499 return PIPE_FORMAT_NONE;
500 else if (screen->is_format_supported(screen, PIPE_FORMAT_DXT1_RGB,
501 target, tex_usage, geom_flags))
502 return PIPE_FORMAT_DXT1_RGB;
503 else
504 return default_rgb_format(screen, target, tex_usage, geom_flags);
505
506 case GL_COMPRESSED_RGBA:
507 /* can only sample from compressed formats */
508 if (tex_usage & ~PIPE_BIND_SAMPLER_VIEW)
509 return PIPE_FORMAT_NONE;
510 else if (screen->is_format_supported(screen, PIPE_FORMAT_DXT3_RGBA,
511 target, tex_usage, geom_flags))
512 return PIPE_FORMAT_DXT3_RGBA;
513 else
514 return default_rgba_format(screen, target, tex_usage, geom_flags);
515
516 case GL_RGB_S3TC:
517 case GL_RGB4_S3TC:
518 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
519 return PIPE_FORMAT_DXT1_RGB;
520
521 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
522 return PIPE_FORMAT_DXT1_RGBA;
523
524 case GL_RGBA_S3TC:
525 case GL_RGBA4_S3TC:
526 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
527 return PIPE_FORMAT_DXT3_RGBA;
528
529 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
530 return PIPE_FORMAT_DXT5_RGBA;
531
532 #if 0
533 case GL_COMPRESSED_RGB_FXT1_3DFX:
534 return PIPE_FORMAT_RGB_FXT1;
535 case GL_COMPRESSED_RGBA_FXT1_3DFX:
536 return PIPE_FORMAT_RGB_FXT1;
537 #endif
538
539 case GL_DEPTH_COMPONENT16:
540 if (screen->is_format_supported( screen, PIPE_FORMAT_Z16_UNORM, target, tex_usage, geom_flags ))
541 return PIPE_FORMAT_Z16_UNORM;
542 /* fall-through */
543 case GL_DEPTH_COMPONENT24:
544 if (screen->is_format_supported( screen, PIPE_FORMAT_Z24_UNORM_S8_USCALED, target, tex_usage, geom_flags ))
545 return PIPE_FORMAT_Z24_UNORM_S8_USCALED;
546 if (screen->is_format_supported( screen, PIPE_FORMAT_S8_USCALED_Z24_UNORM, target, tex_usage, geom_flags ))
547 return PIPE_FORMAT_S8_USCALED_Z24_UNORM;
548 /* fall-through */
549 case GL_DEPTH_COMPONENT32:
550 if (screen->is_format_supported( screen, PIPE_FORMAT_Z32_UNORM, target, tex_usage, geom_flags ))
551 return PIPE_FORMAT_Z32_UNORM;
552 /* fall-through */
553 case GL_DEPTH_COMPONENT:
554 {
555 static const enum pipe_format formats[] = {
556 PIPE_FORMAT_Z16_UNORM,
557 PIPE_FORMAT_Z32_UNORM,
558 PIPE_FORMAT_Z24_UNORM_S8_USCALED,
559 PIPE_FORMAT_S8_USCALED_Z24_UNORM
560 };
561 return find_supported_format(screen, formats, Elements(formats),
562 target, tex_usage, geom_flags);
563 }
564
565 case GL_STENCIL_INDEX:
566 case GL_STENCIL_INDEX1_EXT:
567 case GL_STENCIL_INDEX4_EXT:
568 case GL_STENCIL_INDEX8_EXT:
569 case GL_STENCIL_INDEX16_EXT:
570 {
571 static const enum pipe_format formats[] = {
572 PIPE_FORMAT_S8_USCALED,
573 PIPE_FORMAT_Z24_UNORM_S8_USCALED,
574 PIPE_FORMAT_S8_USCALED_Z24_UNORM
575 };
576 return find_supported_format(screen, formats, Elements(formats),
577 target, tex_usage, geom_flags);
578 }
579
580 case GL_DEPTH_STENCIL_EXT:
581 case GL_DEPTH24_STENCIL8_EXT:
582 {
583 static const enum pipe_format formats[] = {
584 PIPE_FORMAT_Z24_UNORM_S8_USCALED,
585 PIPE_FORMAT_S8_USCALED_Z24_UNORM
586 };
587 return find_supported_format(screen, formats, Elements(formats),
588 target, tex_usage, geom_flags);
589 }
590
591 case GL_SRGB_EXT:
592 case GL_SRGB8_EXT:
593 case GL_COMPRESSED_SRGB_EXT:
594 case GL_COMPRESSED_SRGB_ALPHA_EXT:
595 case GL_SRGB_ALPHA_EXT:
596 case GL_SRGB8_ALPHA8_EXT:
597 return default_srgba_format( screen, target, tex_usage, geom_flags );
598 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
599 return PIPE_FORMAT_DXT1_SRGB;
600 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
601 return PIPE_FORMAT_DXT1_SRGBA;
602 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
603 return PIPE_FORMAT_DXT3_SRGBA;
604 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
605 return PIPE_FORMAT_DXT5_SRGBA;
606
607 case GL_SLUMINANCE_ALPHA_EXT:
608 case GL_SLUMINANCE8_ALPHA8_EXT:
609 case GL_COMPRESSED_SLUMINANCE_EXT:
610 case GL_COMPRESSED_SLUMINANCE_ALPHA_EXT:
611 if (screen->is_format_supported( screen, PIPE_FORMAT_L8A8_SRGB, target, tex_usage, geom_flags ))
612 return PIPE_FORMAT_L8A8_SRGB;
613 return default_srgba_format( screen, target, tex_usage, geom_flags );
614
615 case GL_SLUMINANCE_EXT:
616 case GL_SLUMINANCE8_EXT:
617 if (screen->is_format_supported( screen, PIPE_FORMAT_L8_SRGB, target, tex_usage, geom_flags ))
618 return PIPE_FORMAT_L8_SRGB;
619 return default_srgba_format( screen, target, tex_usage, geom_flags );
620
621 default:
622 return PIPE_FORMAT_NONE;
623 }
624 }
625
626
627 static GLboolean
628 is_depth_or_stencil_format(GLenum internalFormat)
629 {
630 switch (internalFormat) {
631 case GL_DEPTH_COMPONENT:
632 case GL_DEPTH_COMPONENT16:
633 case GL_DEPTH_COMPONENT24:
634 case GL_DEPTH_COMPONENT32:
635 case GL_STENCIL_INDEX:
636 case GL_STENCIL_INDEX1_EXT:
637 case GL_STENCIL_INDEX4_EXT:
638 case GL_STENCIL_INDEX8_EXT:
639 case GL_STENCIL_INDEX16_EXT:
640 case GL_DEPTH_STENCIL_EXT:
641 case GL_DEPTH24_STENCIL8_EXT:
642 return GL_TRUE;
643 default:
644 return GL_FALSE;
645 }
646 }
647
648 /**
649 * Called by FBO code to choose a PIPE_FORMAT_ for drawing surfaces.
650 */
651 enum pipe_format
652 st_choose_renderbuffer_format(struct pipe_screen *screen,
653 GLenum internalFormat)
654 {
655 uint usage;
656 if (is_depth_or_stencil_format(internalFormat))
657 usage = PIPE_BIND_DEPTH_STENCIL;
658 else
659 usage = PIPE_BIND_RENDER_TARGET;
660 return st_choose_format(screen, internalFormat, PIPE_TEXTURE_2D, usage);
661 }
662
663
664 /**
665 * Called via ctx->Driver.chooseTextureFormat().
666 */
667 gl_format
668 st_ChooseTextureFormat(GLcontext *ctx, GLint internalFormat,
669 GLenum format, GLenum type)
670 {
671 struct pipe_screen *screen = st_context(ctx)->pipe->screen;
672 enum pipe_format pFormat;
673 uint bindings;
674
675 (void) format;
676 (void) type;
677
678 /* GL textures may wind up being render targets, but we don't know
679 * that in advance. Specify potential render target flags now.
680 */
681 if (_mesa_is_depth_format(internalFormat) ||
682 _mesa_is_depthstencil_format(internalFormat))
683 bindings = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_DEPTH_STENCIL;
684 else
685 bindings = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
686
687 pFormat = st_choose_format(screen, internalFormat,
688 PIPE_TEXTURE_2D, bindings);
689
690 if (pFormat == PIPE_FORMAT_NONE) {
691 /* try choosing format again, this time without render target bindings */
692 pFormat = st_choose_format(screen, internalFormat,
693 PIPE_TEXTURE_2D, PIPE_BIND_SAMPLER_VIEW);
694 }
695
696 if (pFormat == PIPE_FORMAT_NONE) {
697 /* no luck at all */
698 return MESA_FORMAT_NONE;
699 }
700
701 return st_pipe_format_to_mesa_format(pFormat);
702 }
703
704
705 /**
706 * Test if a gallium format is equivalent to a GL format/type.
707 */
708 GLboolean
709 st_equal_formats(enum pipe_format pFormat, GLenum format, GLenum type)
710 {
711 switch (pFormat) {
712 case PIPE_FORMAT_A8B8G8R8_UNORM:
713 return format == GL_RGBA && type == GL_UNSIGNED_BYTE;
714 case PIPE_FORMAT_A8R8G8B8_UNORM:
715 return format == GL_BGRA && type == GL_UNSIGNED_BYTE;
716 case PIPE_FORMAT_B5G6R5_UNORM:
717 return format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5;
718 /* XXX more combos... */
719 default:
720 return GL_FALSE;
721 }
722 }