texformat.c revision 001d944fd50e0579739b8865e6e09be5d267c05a
1/*
2 * Mesa 3-D graphics library
3 * Version:  7.7
4 *
5 * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
6 * Copyright (c) 2008-2009 VMware, Inc.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26
27/**
28 * \file texformat.c
29 * Texture formats.
30 *
31 * \author Gareth Hughes
32 * \author Brian Paul
33 */
34
35
36#include "context.h"
37#include "texcompress.h"
38#include "texformat.h"
39
40#define RETURN_IF_SUPPORTED(f) do {		\
41   if (ctx->TextureFormatSupported[f])		\
42      return f;					\
43} while (0)
44
45/**
46 * Choose an appropriate texture format given the format, type and
47 * internalFormat parameters passed to glTexImage().
48 *
49 * \param ctx  the GL context.
50 * \param internalFormat  user's prefered internal texture format.
51 * \param format  incoming image pixel format.
52 * \param type  incoming image data type.
53 *
54 * \return a pointer to a gl_texture_format object which describes the
55 * choosen texture format, or NULL on failure.
56 *
57 * This is called via dd_function_table::ChooseTextureFormat.  Hardware drivers
58 * will typically override this function with a specialized version.
59 */
60gl_format
61_mesa_choose_tex_format( struct gl_context *ctx, GLint internalFormat,
62                         GLenum format, GLenum type )
63{
64   (void) format;
65   (void) type;
66
67   switch (internalFormat) {
68      /* shallow RGBA formats */
69      case 4:
70      case GL_RGBA:
71      case GL_RGBA8:
72	 RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA8888);
73	 break;
74      case GL_RGB5_A1:
75	 RETURN_IF_SUPPORTED(MESA_FORMAT_ARGB1555);
76	 break;
77      case GL_RGBA2:
78	 RETURN_IF_SUPPORTED(MESA_FORMAT_ARGB4444_REV); /* just to test another format*/
79	 break;
80      case GL_RGBA4:
81	 RETURN_IF_SUPPORTED(MESA_FORMAT_ARGB4444);
82	 break;
83
84      /* deep RGBA formats */
85      case GL_RGB10_A2:
86	 RETURN_IF_SUPPORTED(MESA_FORMAT_ARGB2101010);
87	 break;
88      case GL_RGBA12:
89      case GL_RGBA16:
90	 RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_16);
91	 break;
92
93      /* shallow RGB formats */
94      case 3:
95      case GL_RGB:
96      case GL_RGB8:
97	 RETURN_IF_SUPPORTED(MESA_FORMAT_RGB888);
98	 break;
99      case GL_R3_G3_B2:
100	 RETURN_IF_SUPPORTED(MESA_FORMAT_RGB332);
101	 break;
102      case GL_RGB4:
103	 RETURN_IF_SUPPORTED(MESA_FORMAT_RGB565_REV); /* just to test another format */
104	 break;
105      case GL_RGB5:
106	 RETURN_IF_SUPPORTED(MESA_FORMAT_RGB565);
107	 break;
108
109      /* deep RGB formats */
110      case GL_RGB10:
111      case GL_RGB12:
112      case GL_RGB16:
113	 RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_16);
114	 break;
115
116      /* Alpha formats */
117      case GL_ALPHA:
118      case GL_ALPHA4:
119      case GL_ALPHA8:
120	 RETURN_IF_SUPPORTED(MESA_FORMAT_A8);
121	 break;
122
123      case GL_ALPHA12:
124      case GL_ALPHA16:
125	 RETURN_IF_SUPPORTED(MESA_FORMAT_A16);
126	 break;
127
128      /* Luminance formats */
129      case 1:
130      case GL_LUMINANCE:
131      case GL_LUMINANCE4:
132      case GL_LUMINANCE8:
133	 RETURN_IF_SUPPORTED(MESA_FORMAT_L8);
134	 break;
135
136      case GL_LUMINANCE12:
137      case GL_LUMINANCE16:
138	 RETURN_IF_SUPPORTED(MESA_FORMAT_L16);
139	 break;
140
141      /* Luminance/Alpha formats */
142      case GL_LUMINANCE4_ALPHA4:
143	 RETURN_IF_SUPPORTED(MESA_FORMAT_AL44);
144	 break;
145
146      case 2:
147      case GL_LUMINANCE_ALPHA:
148      case GL_LUMINANCE6_ALPHA2:
149      case GL_LUMINANCE8_ALPHA8:
150	 RETURN_IF_SUPPORTED(MESA_FORMAT_AL88);
151	 break;
152
153      case GL_LUMINANCE12_ALPHA4:
154      case GL_LUMINANCE12_ALPHA12:
155      case GL_LUMINANCE16_ALPHA16:
156	 RETURN_IF_SUPPORTED(MESA_FORMAT_AL1616);
157	 break;
158
159      case GL_INTENSITY:
160      case GL_INTENSITY4:
161      case GL_INTENSITY8:
162	 RETURN_IF_SUPPORTED(MESA_FORMAT_I8);
163	 break;
164
165      case GL_INTENSITY12:
166      case GL_INTENSITY16:
167	 RETURN_IF_SUPPORTED(MESA_FORMAT_I16);
168	 break;
169
170      case GL_COLOR_INDEX:
171      case GL_COLOR_INDEX1_EXT:
172      case GL_COLOR_INDEX2_EXT:
173      case GL_COLOR_INDEX4_EXT:
174      case GL_COLOR_INDEX12_EXT:
175      case GL_COLOR_INDEX16_EXT:
176      case GL_COLOR_INDEX8_EXT:
177	 RETURN_IF_SUPPORTED(MESA_FORMAT_CI8);
178	 break;
179
180      default:
181         ; /* fallthrough */
182   }
183
184   if (ctx->Extensions.ARB_depth_texture) {
185      switch (internalFormat) {
186         case GL_DEPTH_COMPONENT:
187         case GL_DEPTH_COMPONENT24:
188         case GL_DEPTH_COMPONENT32:
189	    RETURN_IF_SUPPORTED(MESA_FORMAT_Z32);
190	    break;
191         case GL_DEPTH_COMPONENT16:
192	    RETURN_IF_SUPPORTED(MESA_FORMAT_Z16);
193	    break;
194         default:
195            ; /* fallthrough */
196      }
197   }
198
199   switch (internalFormat) {
200      case GL_COMPRESSED_ALPHA_ARB:
201	 RETURN_IF_SUPPORTED(MESA_FORMAT_A8);
202	 break;
203      case GL_COMPRESSED_LUMINANCE_ARB:
204	 RETURN_IF_SUPPORTED(MESA_FORMAT_L8);
205	 break;
206      case GL_COMPRESSED_LUMINANCE_ALPHA_ARB:
207	 RETURN_IF_SUPPORTED(MESA_FORMAT_AL88);
208	 break;
209      case GL_COMPRESSED_INTENSITY_ARB:
210	 RETURN_IF_SUPPORTED(MESA_FORMAT_I8);
211	 break;
212      case GL_COMPRESSED_RGB_ARB:
213         if (ctx->Extensions.EXT_texture_compression_s3tc ||
214             ctx->Extensions.S3_s3tc)
215	    RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_DXT1);
216         if (ctx->Extensions.TDFX_texture_compression_FXT1)
217	    RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_FXT1);
218	 RETURN_IF_SUPPORTED(MESA_FORMAT_RGB888);
219	 break;
220      case GL_COMPRESSED_RGBA_ARB:
221         if (ctx->Extensions.EXT_texture_compression_s3tc ||
222             ctx->Extensions.S3_s3tc)
223	    RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_DXT3); /* Not rgba_dxt1, see spec */
224         if (ctx->Extensions.TDFX_texture_compression_FXT1)
225	    RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FXT1);
226	 RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA8888);
227	 break;
228      default:
229         ; /* fallthrough */
230   }
231
232   if (ctx->Extensions.MESA_ycbcr_texture) {
233      if (internalFormat == GL_YCBCR_MESA) {
234         if (type == GL_UNSIGNED_SHORT_8_8_MESA)
235	    RETURN_IF_SUPPORTED(MESA_FORMAT_YCBCR);
236         else
237	    RETURN_IF_SUPPORTED(MESA_FORMAT_YCBCR_REV);
238      }
239   }
240
241#if FEATURE_texture_fxt1
242   if (ctx->Extensions.TDFX_texture_compression_FXT1) {
243      switch (internalFormat) {
244         case GL_COMPRESSED_RGB_FXT1_3DFX:
245	    RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_FXT1);
246	 break;
247         case GL_COMPRESSED_RGBA_FXT1_3DFX:
248	    RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FXT1);
249	 break;
250         default:
251            ; /* fallthrough */
252      }
253   }
254#endif
255
256#if FEATURE_texture_s3tc
257   if (ctx->Extensions.EXT_texture_compression_s3tc) {
258      switch (internalFormat) {
259         case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
260	    RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_DXT1);
261	    break;
262         case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
263	    RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_DXT1);
264	    break;
265         case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
266	    RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_DXT3);
267	    break;
268         case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
269	    RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_DXT5);
270	    break;
271         default:
272            ; /* fallthrough */
273      }
274   }
275
276   if (ctx->Extensions.S3_s3tc) {
277      switch (internalFormat) {
278         case GL_RGB_S3TC:
279         case GL_RGB4_S3TC:
280	    RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_DXT1);
281	    break;
282         case GL_RGBA_S3TC:
283         case GL_RGBA4_S3TC:
284	    RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_DXT3);
285	    break;
286         default:
287            ; /* fallthrough */
288      }
289   }
290#endif
291
292   if (ctx->Extensions.ARB_texture_float) {
293      switch (internalFormat) {
294         case GL_ALPHA16F_ARB:
295	    RETURN_IF_SUPPORTED(MESA_FORMAT_ALPHA_FLOAT16);
296	    break;
297         case GL_ALPHA32F_ARB:
298	    RETURN_IF_SUPPORTED(MESA_FORMAT_ALPHA_FLOAT32);
299	    break;
300         case GL_LUMINANCE16F_ARB:
301	    RETURN_IF_SUPPORTED(MESA_FORMAT_LUMINANCE_FLOAT16);
302	    break;
303         case GL_LUMINANCE32F_ARB:
304	    RETURN_IF_SUPPORTED(MESA_FORMAT_LUMINANCE_FLOAT32);
305	    break;
306         case GL_LUMINANCE_ALPHA16F_ARB:
307	    RETURN_IF_SUPPORTED(MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16);
308	    break;
309         case GL_LUMINANCE_ALPHA32F_ARB:
310	    RETURN_IF_SUPPORTED(MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32);
311	    break;
312         case GL_INTENSITY16F_ARB:
313	    RETURN_IF_SUPPORTED(MESA_FORMAT_INTENSITY_FLOAT16);
314	    break;
315         case GL_INTENSITY32F_ARB:
316	    RETURN_IF_SUPPORTED(MESA_FORMAT_INTENSITY_FLOAT32);
317	    break;
318         case GL_RGB16F_ARB:
319	    RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_FLOAT16);
320	    break;
321         case GL_RGB32F_ARB:
322	    RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_FLOAT32);
323	    break;
324         case GL_RGBA16F_ARB:
325	    RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16);
326	    break;
327         case GL_RGBA32F_ARB:
328	    RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32);
329	    break;
330         default:
331            ; /* fallthrough */
332      }
333   }
334
335   if (ctx->Extensions.EXT_packed_depth_stencil) {
336      switch (internalFormat) {
337         case GL_DEPTH_STENCIL_EXT:
338         case GL_DEPTH24_STENCIL8_EXT:
339	    RETURN_IF_SUPPORTED(MESA_FORMAT_Z24_S8);
340	    break;
341         default:
342            ; /* fallthrough */
343      }
344   }
345
346   if (ctx->Extensions.ATI_envmap_bumpmap) {
347      switch (internalFormat) {
348         case GL_DUDV_ATI:
349         case GL_DU8DV8_ATI:
350	    RETURN_IF_SUPPORTED(MESA_FORMAT_DUDV8);
351	    break;
352         default:
353            ; /* fallthrough */
354      }
355   }
356
357   if (ctx->Extensions.MESA_texture_signed_rgba) {
358      switch (internalFormat) {
359         case GL_RGBA_SNORM:
360         case GL_RGBA8_SNORM:
361	    RETURN_IF_SUPPORTED(MESA_FORMAT_SIGNED_RGBA8888);
362	    break;
363         default:
364            ; /* fallthrough */
365      }
366   }
367
368   if (ctx->VersionMajor * 10 + ctx->VersionMinor >= 31) {
369      switch (internalFormat) {
370         case GL_RED_SNORM:
371         case GL_R8_SNORM:
372	    RETURN_IF_SUPPORTED(MESA_FORMAT_SIGNED_R8);
373	    break;
374         case GL_RG_SNORM:
375         case GL_RG8_SNORM:
376	    RETURN_IF_SUPPORTED(MESA_FORMAT_SIGNED_RG88);
377	    break;
378         case GL_RGB_SNORM:
379         case GL_RGB8_SNORM:
380	    RETURN_IF_SUPPORTED(MESA_FORMAT_SIGNED_RGBX8888);
381	    break;
382         case GL_RGBA_SNORM:
383         case GL_RGBA8_SNORM:
384	    RETURN_IF_SUPPORTED(MESA_FORMAT_SIGNED_RGBA8888);
385	    break;
386         case GL_R16_SNORM:
387	    RETURN_IF_SUPPORTED(MESA_FORMAT_SIGNED_R_16);
388	    break;
389         case GL_RG16_SNORM:
390	    RETURN_IF_SUPPORTED(MESA_FORMAT_SIGNED_RG_16);
391	    break;
392         case GL_RGB16_SNORM:
393	    RETURN_IF_SUPPORTED(MESA_FORMAT_SIGNED_RGB_16);
394	    break;
395         case GL_RGBA16_SNORM:
396	    RETURN_IF_SUPPORTED(MESA_FORMAT_SIGNED_RGBA_16);
397	    break;
398         default:
399            ; /* fall-through */
400      }
401   }
402
403#if FEATURE_EXT_texture_sRGB
404   if (ctx->Extensions.EXT_texture_sRGB) {
405      switch (internalFormat) {
406         case GL_SRGB_EXT:
407         case GL_SRGB8_EXT:
408	    RETURN_IF_SUPPORTED(MESA_FORMAT_SRGB8);
409	    break;
410         case GL_SRGB_ALPHA_EXT:
411         case GL_SRGB8_ALPHA8_EXT:
412	    RETURN_IF_SUPPORTED(MESA_FORMAT_SRGBA8);
413	    break;
414         case GL_SLUMINANCE_EXT:
415         case GL_SLUMINANCE8_EXT:
416	    RETURN_IF_SUPPORTED(MESA_FORMAT_SL8);
417	    break;
418         case GL_SLUMINANCE_ALPHA_EXT:
419         case GL_SLUMINANCE8_ALPHA8_EXT:
420	    RETURN_IF_SUPPORTED(MESA_FORMAT_SLA8);
421	    break;
422         case GL_COMPRESSED_SLUMINANCE_EXT:
423	    RETURN_IF_SUPPORTED(MESA_FORMAT_SL8);
424	    break;
425         case GL_COMPRESSED_SLUMINANCE_ALPHA_EXT:
426	    RETURN_IF_SUPPORTED(MESA_FORMAT_SLA8);
427	    break;
428         case GL_COMPRESSED_SRGB_EXT:
429#if FEATURE_texture_s3tc
430            if (ctx->Extensions.EXT_texture_compression_s3tc)
431	       RETURN_IF_SUPPORTED(MESA_FORMAT_SRGB_DXT1);
432#endif
433	    RETURN_IF_SUPPORTED(MESA_FORMAT_SRGB8);
434	    break;
435         case GL_COMPRESSED_SRGB_ALPHA_EXT:
436#if FEATURE_texture_s3tc
437            if (ctx->Extensions.EXT_texture_compression_s3tc)
438	       RETURN_IF_SUPPORTED(MESA_FORMAT_SRGBA_DXT3); /* Not srgba_dxt1, see spec */
439#endif
440	    RETURN_IF_SUPPORTED(MESA_FORMAT_SRGBA8);
441	    break;
442#if FEATURE_texture_s3tc
443         case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
444            if (ctx->Extensions.EXT_texture_compression_s3tc)
445	       RETURN_IF_SUPPORTED(MESA_FORMAT_SRGB_DXT1);
446            break;
447         case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
448            if (ctx->Extensions.EXT_texture_compression_s3tc)
449	       RETURN_IF_SUPPORTED(MESA_FORMAT_SRGBA_DXT1);
450            break;
451         case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
452            if (ctx->Extensions.EXT_texture_compression_s3tc)
453	       RETURN_IF_SUPPORTED(MESA_FORMAT_SRGBA_DXT3);
454            break;
455         case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
456            if (ctx->Extensions.EXT_texture_compression_s3tc)
457	       RETURN_IF_SUPPORTED(MESA_FORMAT_SRGBA_DXT5);
458            break;
459#endif
460         default:
461            ; /* fallthrough */
462      }
463   }
464#endif /* FEATURE_EXT_texture_sRGB */
465
466   if (ctx->Extensions.EXT_texture_integer) {
467      switch (internalFormat) {
468      case GL_RGBA32UI_EXT:
469      case GL_RGB32UI_EXT:
470      case GL_ALPHA32UI_EXT:
471      case GL_INTENSITY32UI_EXT:
472      case GL_LUMINANCE32UI_EXT:
473      case GL_LUMINANCE_ALPHA32UI_EXT:
474	 RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT32);
475	 break;
476      case GL_RGBA16UI_EXT:
477      case GL_RGB16UI_EXT:
478      case GL_ALPHA16UI_EXT:
479      case GL_INTENSITY16UI_EXT:
480      case GL_LUMINANCE16UI_EXT:
481      case GL_LUMINANCE_ALPHA16UI_EXT:
482	 RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT16);
483	 break;
484      case GL_RGBA8UI_EXT:
485      case GL_RGB8UI_EXT:
486      case GL_ALPHA8UI_EXT:
487      case GL_INTENSITY8UI_EXT:
488      case GL_LUMINANCE8UI_EXT:
489      case GL_LUMINANCE_ALPHA8UI_EXT:
490	 RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT8);
491	 break;
492      case GL_RGBA32I_EXT:
493      case GL_RGB32I_EXT:
494      case GL_ALPHA32I_EXT:
495      case GL_INTENSITY32I_EXT:
496      case GL_LUMINANCE32I_EXT:
497      case GL_LUMINANCE_ALPHA32I_EXT:
498	 RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_INT32);
499	 break;
500      case GL_RGBA16I_EXT:
501      case GL_RGB16I_EXT:
502      case GL_ALPHA16I_EXT:
503      case GL_INTENSITY16I_EXT:
504      case GL_LUMINANCE16I_EXT:
505      case GL_LUMINANCE_ALPHA16I_EXT:
506	 RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_INT16);
507	 break;
508      case GL_RGBA8I_EXT:
509      case GL_RGB8I_EXT:
510      case GL_ALPHA8I_EXT:
511      case GL_INTENSITY8I_EXT:
512      case GL_LUMINANCE8I_EXT:
513      case GL_LUMINANCE_ALPHA8I_EXT:
514	 RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_INT8);
515	 break;
516      }
517   }
518
519   if (ctx->Extensions.ARB_texture_rg) {
520      switch (internalFormat) {
521      case GL_R8:
522      case GL_RED:
523      case GL_COMPRESSED_RED:
524	 RETURN_IF_SUPPORTED(MESA_FORMAT_R8);
525	 break;
526
527      case GL_R16:
528	 RETURN_IF_SUPPORTED(MESA_FORMAT_R16);
529	 break;
530
531      case GL_RG:
532      case GL_RG8:
533      case GL_COMPRESSED_RG:
534	 RETURN_IF_SUPPORTED(MESA_FORMAT_RG88);
535	 break;
536
537      case GL_RG16:
538	 RETURN_IF_SUPPORTED(MESA_FORMAT_RG1616);
539	 break;
540
541      default:
542         ; /* fallthrough */
543      }
544   }
545
546   _mesa_problem(ctx, "unexpected format in _mesa_choose_tex_format()");
547   return MESA_FORMAT_NONE;
548}
549
550