texformat.c revision 74ae14a2bde4f87a554c3d96e6f4a9a02591308d
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 "texcompress_fxt1.h"
39#include "texcompress_s3tc.h"
40#include "texformat.h"
41
42
43/**
44 * Choose an appropriate texture format given the format, type and
45 * internalFormat parameters passed to glTexImage().
46 *
47 * \param ctx  the GL context.
48 * \param internalFormat  user's prefered internal texture format.
49 * \param format  incoming image pixel format.
50 * \param type  incoming image data type.
51 *
52 * \return a pointer to a gl_texture_format object which describes the
53 * choosen texture format, or NULL on failure.
54 *
55 * This is called via dd_function_table::ChooseTextureFormat.  Hardware drivers
56 * will typically override this function with a specialized version.
57 */
58gl_format
59_mesa_choose_tex_format( GLcontext *ctx, GLint internalFormat,
60                         GLenum format, GLenum type )
61{
62   (void) format;
63   (void) type;
64
65   switch (internalFormat) {
66      /* RGBA formats */
67      case 4:
68      case GL_RGBA:
69      case GL_RGB10_A2:
70      case GL_RGBA12:
71      case GL_RGBA16:
72         return MESA_FORMAT_RGBA;
73      case GL_RGBA8:
74         return MESA_FORMAT_RGBA8888;
75      case GL_RGB5_A1:
76         return MESA_FORMAT_ARGB1555;
77      case GL_RGBA2:
78         return MESA_FORMAT_ARGB4444_REV; /* just to test another format*/
79      case GL_RGBA4:
80         return MESA_FORMAT_ARGB4444;
81
82      /* RGB formats */
83      case 3:
84      case GL_RGB:
85      case GL_RGB10:
86      case GL_RGB12:
87      case GL_RGB16:
88         return MESA_FORMAT_RGB;
89      case GL_RGB8:
90         return MESA_FORMAT_RGB888;
91      case GL_R3_G3_B2:
92         return MESA_FORMAT_RGB332;
93      case GL_RGB4:
94         return MESA_FORMAT_RGB565_REV; /* just to test another format */
95      case GL_RGB5:
96         return MESA_FORMAT_RGB565;
97
98      /* Alpha formats */
99      case GL_ALPHA:
100      case GL_ALPHA4:
101      case GL_ALPHA12:
102      case GL_ALPHA16:
103         return MESA_FORMAT_ALPHA;
104      case GL_ALPHA8:
105         return MESA_FORMAT_A8;
106
107      /* Luminance formats */
108      case 1:
109      case GL_LUMINANCE:
110      case GL_LUMINANCE4:
111      case GL_LUMINANCE12:
112      case GL_LUMINANCE16:
113         return MESA_FORMAT_LUMINANCE;
114      case GL_LUMINANCE8:
115         return MESA_FORMAT_L8;
116
117      /* Luminance/Alpha formats */
118      case 2:
119      case GL_LUMINANCE_ALPHA:
120      case GL_LUMINANCE4_ALPHA4:
121      case GL_LUMINANCE6_ALPHA2:
122      case GL_LUMINANCE12_ALPHA4:
123      case GL_LUMINANCE12_ALPHA12:
124      case GL_LUMINANCE16_ALPHA16:
125         return MESA_FORMAT_LUMINANCE_ALPHA;
126      case GL_LUMINANCE8_ALPHA8:
127         return MESA_FORMAT_AL88;
128
129      case GL_INTENSITY:
130      case GL_INTENSITY4:
131      case GL_INTENSITY12:
132      case GL_INTENSITY16:
133         return MESA_FORMAT_INTENSITY;
134      case GL_INTENSITY8:
135         return MESA_FORMAT_I8;
136
137      case GL_COLOR_INDEX:
138      case GL_COLOR_INDEX1_EXT:
139      case GL_COLOR_INDEX2_EXT:
140      case GL_COLOR_INDEX4_EXT:
141      case GL_COLOR_INDEX12_EXT:
142      case GL_COLOR_INDEX16_EXT:
143      case GL_COLOR_INDEX8_EXT:
144         return MESA_FORMAT_CI8;
145
146      default:
147         ; /* fallthrough */
148   }
149
150   if (ctx->Extensions.ARB_depth_texture) {
151      switch (internalFormat) {
152         case GL_DEPTH_COMPONENT:
153         case GL_DEPTH_COMPONENT24:
154         case GL_DEPTH_COMPONENT32:
155            return MESA_FORMAT_Z32;
156         case GL_DEPTH_COMPONENT16:
157            return MESA_FORMAT_Z16;
158         default:
159            ; /* fallthrough */
160      }
161   }
162
163   switch (internalFormat) {
164      case GL_COMPRESSED_ALPHA_ARB:
165         return MESA_FORMAT_ALPHA;
166      case GL_COMPRESSED_LUMINANCE_ARB:
167         return MESA_FORMAT_LUMINANCE;
168      case GL_COMPRESSED_LUMINANCE_ALPHA_ARB:
169         return MESA_FORMAT_LUMINANCE_ALPHA;
170      case GL_COMPRESSED_INTENSITY_ARB:
171         return MESA_FORMAT_INTENSITY;
172      case GL_COMPRESSED_RGB_ARB:
173#if FEATURE_texture_fxt1
174         if (ctx->Extensions.TDFX_texture_compression_FXT1)
175            return MESA_FORMAT_RGB_FXT1;
176#endif
177#if FEATURE_texture_s3tc
178         if (ctx->Extensions.EXT_texture_compression_s3tc ||
179             ctx->Extensions.S3_s3tc)
180            return MESA_FORMAT_RGB_DXT1;
181#endif
182         return MESA_FORMAT_RGB;
183      case GL_COMPRESSED_RGBA_ARB:
184#if FEATURE_texture_fxt1
185         if (ctx->Extensions.TDFX_texture_compression_FXT1)
186            return MESA_FORMAT_RGBA_FXT1;
187#endif
188#if FEATURE_texture_s3tc
189         if (ctx->Extensions.EXT_texture_compression_s3tc ||
190             ctx->Extensions.S3_s3tc)
191            return MESA_FORMAT_RGBA_DXT3; /* Not rgba_dxt1, see spec */
192#endif
193         return MESA_FORMAT_RGBA;
194      default:
195         ; /* fallthrough */
196   }
197
198   if (ctx->Extensions.MESA_ycbcr_texture) {
199      if (internalFormat == GL_YCBCR_MESA) {
200         if (type == GL_UNSIGNED_SHORT_8_8_MESA)
201            return MESA_FORMAT_YCBCR;
202         else
203            return MESA_FORMAT_YCBCR_REV;
204      }
205   }
206
207#if FEATURE_texture_fxt1
208   if (ctx->Extensions.TDFX_texture_compression_FXT1) {
209      switch (internalFormat) {
210         case GL_COMPRESSED_RGB_FXT1_3DFX:
211            return MESA_FORMAT_RGB_FXT1;
212         case GL_COMPRESSED_RGBA_FXT1_3DFX:
213            return MESA_FORMAT_RGBA_FXT1;
214         default:
215            ; /* fallthrough */
216      }
217   }
218#endif
219
220#if FEATURE_texture_s3tc
221   if (ctx->Extensions.EXT_texture_compression_s3tc) {
222      switch (internalFormat) {
223         case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
224            return MESA_FORMAT_RGB_DXT1;
225         case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
226            return MESA_FORMAT_RGBA_DXT1;
227         case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
228            return MESA_FORMAT_RGBA_DXT3;
229         case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
230            return MESA_FORMAT_RGBA_DXT5;
231         default:
232            ; /* fallthrough */
233      }
234   }
235
236   if (ctx->Extensions.S3_s3tc) {
237      switch (internalFormat) {
238         case GL_RGB_S3TC:
239         case GL_RGB4_S3TC:
240            return MESA_FORMAT_RGB_DXT1;
241         case GL_RGBA_S3TC:
242         case GL_RGBA4_S3TC:
243            return MESA_FORMAT_RGBA_DXT3;
244         default:
245            ; /* fallthrough */
246      }
247   }
248#endif
249
250   if (ctx->Extensions.ARB_texture_float) {
251      switch (internalFormat) {
252         case GL_ALPHA16F_ARB:
253            return MESA_FORMAT_ALPHA_FLOAT16;
254         case GL_ALPHA32F_ARB:
255            return MESA_FORMAT_ALPHA_FLOAT32;
256         case GL_LUMINANCE16F_ARB:
257            return MESA_FORMAT_LUMINANCE_FLOAT16;
258         case GL_LUMINANCE32F_ARB:
259            return MESA_FORMAT_LUMINANCE_FLOAT32;
260         case GL_LUMINANCE_ALPHA16F_ARB:
261            return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16;
262         case GL_LUMINANCE_ALPHA32F_ARB:
263            return MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32;
264         case GL_INTENSITY16F_ARB:
265            return MESA_FORMAT_INTENSITY_FLOAT16;
266         case GL_INTENSITY32F_ARB:
267            return MESA_FORMAT_INTENSITY_FLOAT32;
268         case GL_RGB16F_ARB:
269            return MESA_FORMAT_RGB_FLOAT16;
270         case GL_RGB32F_ARB:
271            return MESA_FORMAT_RGB_FLOAT32;
272         case GL_RGBA16F_ARB:
273            return MESA_FORMAT_RGBA_FLOAT16;
274         case GL_RGBA32F_ARB:
275            return MESA_FORMAT_RGBA_FLOAT32;
276         default:
277            ; /* fallthrough */
278      }
279   }
280
281   if (ctx->Extensions.EXT_packed_depth_stencil) {
282      switch (internalFormat) {
283         case GL_DEPTH_STENCIL_EXT:
284         case GL_DEPTH24_STENCIL8_EXT:
285            return MESA_FORMAT_Z24_S8;
286         default:
287            ; /* fallthrough */
288      }
289   }
290
291   if (ctx->Extensions.ATI_envmap_bumpmap) {
292      switch (internalFormat) {
293         case GL_DUDV_ATI:
294         case GL_DU8DV8_ATI:
295            return MESA_FORMAT_DUDV8;
296         default:
297            ; /* fallthrough */
298      }
299   }
300
301   if (ctx->Extensions.MESA_texture_signed_rgba) {
302      switch (internalFormat) {
303         case GL_RGBA_SNORM:
304         case GL_RGBA8_SNORM:
305            return MESA_FORMAT_SIGNED_RGBA8888;
306         default:
307            ; /* fallthrough */
308      }
309   }
310
311
312#if FEATURE_EXT_texture_sRGB
313   if (ctx->Extensions.EXT_texture_sRGB) {
314      switch (internalFormat) {
315         case GL_SRGB_EXT:
316         case GL_SRGB8_EXT:
317            return MESA_FORMAT_SRGB8;
318         case GL_SRGB_ALPHA_EXT:
319         case GL_SRGB8_ALPHA8_EXT:
320            return MESA_FORMAT_SRGBA8;
321         case GL_SLUMINANCE_EXT:
322         case GL_SLUMINANCE8_EXT:
323            return MESA_FORMAT_SL8;
324         case GL_SLUMINANCE_ALPHA_EXT:
325         case GL_SLUMINANCE8_ALPHA8_EXT:
326            return MESA_FORMAT_SLA8;
327         case GL_COMPRESSED_SLUMINANCE_EXT:
328            return MESA_FORMAT_SL8;
329         case GL_COMPRESSED_SLUMINANCE_ALPHA_EXT:
330            return MESA_FORMAT_SLA8;
331         case GL_COMPRESSED_SRGB_EXT:
332#if FEATURE_texture_s3tc
333            if (ctx->Extensions.EXT_texture_compression_s3tc)
334               return MESA_FORMAT_SRGB_DXT1;
335#endif
336            return MESA_FORMAT_SRGB8;
337         case GL_COMPRESSED_SRGB_ALPHA_EXT:
338#if FEATURE_texture_s3tc
339            if (ctx->Extensions.EXT_texture_compression_s3tc)
340               return MESA_FORMAT_SRGBA_DXT3; /* Not srgba_dxt1, see spec */
341#endif
342            return MESA_FORMAT_SRGBA8;
343#if FEATURE_texture_s3tc
344         case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
345            if (ctx->Extensions.EXT_texture_compression_s3tc)
346               return MESA_FORMAT_SRGB_DXT1;
347            break;
348         case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
349            if (ctx->Extensions.EXT_texture_compression_s3tc)
350               return MESA_FORMAT_SRGBA_DXT1;
351            break;
352         case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
353            if (ctx->Extensions.EXT_texture_compression_s3tc)
354               return MESA_FORMAT_SRGBA_DXT3;
355            break;
356         case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
357            if (ctx->Extensions.EXT_texture_compression_s3tc)
358               return MESA_FORMAT_SRGBA_DXT5;
359            break;
360#endif
361         default:
362            ; /* fallthrough */
363      }
364   }
365#endif /* FEATURE_EXT_texture_sRGB */
366
367   _mesa_problem(ctx, "unexpected format in _mesa_choose_tex_format()");
368   return MESA_FORMAT_NONE;
369}
370
371
372
373/**
374 * Return datatype and number of components per texel for the given gl_format.
375 */
376void
377_mesa_format_to_type_and_comps(gl_format format,
378                               GLenum *datatype, GLuint *comps)
379{
380   switch (format) {
381   case MESA_FORMAT_RGBA8888:
382   case MESA_FORMAT_RGBA8888_REV:
383   case MESA_FORMAT_ARGB8888:
384   case MESA_FORMAT_ARGB8888_REV:
385      *datatype = CHAN_TYPE;
386      *comps = 4;
387      return;
388   case MESA_FORMAT_RGB888:
389   case MESA_FORMAT_BGR888:
390      *datatype = GL_UNSIGNED_BYTE;
391      *comps = 3;
392      return;
393   case MESA_FORMAT_RGB565:
394   case MESA_FORMAT_RGB565_REV:
395      *datatype = GL_UNSIGNED_SHORT_5_6_5;
396      *comps = 3;
397      return;
398
399   case MESA_FORMAT_ARGB4444:
400   case MESA_FORMAT_ARGB4444_REV:
401      *datatype = GL_UNSIGNED_SHORT_4_4_4_4;
402      *comps = 4;
403      return;
404
405   case MESA_FORMAT_ARGB1555:
406   case MESA_FORMAT_ARGB1555_REV:
407      *datatype = GL_UNSIGNED_SHORT_1_5_5_5_REV;
408      *comps = 4;
409      return;
410
411   case MESA_FORMAT_AL88:
412   case MESA_FORMAT_AL88_REV:
413      *datatype = GL_UNSIGNED_BYTE;
414      *comps = 2;
415      return;
416   case MESA_FORMAT_RGB332:
417      *datatype = GL_UNSIGNED_BYTE_3_3_2;
418      *comps = 3;
419      return;
420
421   case MESA_FORMAT_A8:
422   case MESA_FORMAT_L8:
423   case MESA_FORMAT_I8:
424   case MESA_FORMAT_CI8:
425      *datatype = GL_UNSIGNED_BYTE;
426      *comps = 1;
427      return;
428
429   case MESA_FORMAT_YCBCR:
430   case MESA_FORMAT_YCBCR_REV:
431      *datatype = GL_UNSIGNED_SHORT;
432      *comps = 2;
433      return;
434
435   case MESA_FORMAT_Z24_S8:
436      *datatype = GL_UNSIGNED_INT;
437      *comps = 1; /* XXX OK? */
438      return;
439
440   case MESA_FORMAT_S8_Z24:
441      *datatype = GL_UNSIGNED_INT;
442      *comps = 1; /* XXX OK? */
443      return;
444
445   case MESA_FORMAT_Z16:
446      *datatype = GL_UNSIGNED_SHORT;
447      *comps = 1;
448      return;
449
450   case MESA_FORMAT_Z32:
451      *datatype = GL_UNSIGNED_INT;
452      *comps = 1;
453      return;
454
455   case MESA_FORMAT_DUDV8:
456      *datatype = GL_BYTE;
457      *comps = 2;
458      return;
459
460   case MESA_FORMAT_SIGNED_RGBA8888:
461   case MESA_FORMAT_SIGNED_RGBA8888_REV:
462      *datatype = GL_BYTE;
463      *comps = 4;
464      return;
465
466#if FEATURE_EXT_texture_sRGB
467   case MESA_FORMAT_SRGB8:
468      *datatype = GL_UNSIGNED_BYTE;
469      *comps = 3;
470      return;
471   case MESA_FORMAT_SRGBA8:
472   case MESA_FORMAT_SARGB8:
473      *datatype = GL_UNSIGNED_BYTE;
474      *comps = 4;
475      return;
476   case MESA_FORMAT_SL8:
477      *datatype = GL_UNSIGNED_BYTE;
478      *comps = 1;
479      return;
480   case MESA_FORMAT_SLA8:
481      *datatype = GL_UNSIGNED_BYTE;
482      *comps = 2;
483      return;
484#endif
485
486#if FEATURE_texture_fxt1
487   case MESA_FORMAT_RGB_FXT1:
488   case MESA_FORMAT_RGBA_FXT1:
489#endif
490#if FEATURE_texture_s3tc
491   case MESA_FORMAT_RGB_DXT1:
492   case MESA_FORMAT_RGBA_DXT1:
493   case MESA_FORMAT_RGBA_DXT3:
494   case MESA_FORMAT_RGBA_DXT5:
495#if FEATURE_EXT_texture_sRGB
496   case MESA_FORMAT_SRGB_DXT1:
497   case MESA_FORMAT_SRGBA_DXT1:
498   case MESA_FORMAT_SRGBA_DXT3:
499   case MESA_FORMAT_SRGBA_DXT5:
500#endif
501      /* XXX generate error instead? */
502      *datatype = GL_UNSIGNED_BYTE;
503      *comps = 0;
504      return;
505#endif
506
507   case MESA_FORMAT_RGBA:
508      *datatype = CHAN_TYPE;
509      *comps = 4;
510      return;
511   case MESA_FORMAT_RGB:
512      *datatype = CHAN_TYPE;
513      *comps = 3;
514      return;
515   case MESA_FORMAT_LUMINANCE_ALPHA:
516      *datatype = CHAN_TYPE;
517      *comps = 2;
518      return;
519   case MESA_FORMAT_ALPHA:
520   case MESA_FORMAT_LUMINANCE:
521   case MESA_FORMAT_INTENSITY:
522      *datatype = CHAN_TYPE;
523      *comps = 1;
524      return;
525
526   case MESA_FORMAT_RGBA_FLOAT32:
527      *datatype = GL_FLOAT;
528      *comps = 4;
529      return;
530   case MESA_FORMAT_RGBA_FLOAT16:
531      *datatype = GL_HALF_FLOAT_ARB;
532      *comps = 4;
533      return;
534   case MESA_FORMAT_RGB_FLOAT32:
535      *datatype = GL_FLOAT;
536      *comps = 3;
537      return;
538   case MESA_FORMAT_RGB_FLOAT16:
539      *datatype = GL_HALF_FLOAT_ARB;
540      *comps = 3;
541      return;
542   case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32:
543      *datatype = GL_FLOAT;
544      *comps = 2;
545      return;
546   case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16:
547      *datatype = GL_HALF_FLOAT_ARB;
548      *comps = 2;
549      return;
550   case MESA_FORMAT_ALPHA_FLOAT32:
551   case MESA_FORMAT_LUMINANCE_FLOAT32:
552   case MESA_FORMAT_INTENSITY_FLOAT32:
553      *datatype = GL_FLOAT;
554      *comps = 1;
555      return;
556   case MESA_FORMAT_ALPHA_FLOAT16:
557   case MESA_FORMAT_LUMINANCE_FLOAT16:
558   case MESA_FORMAT_INTENSITY_FLOAT16:
559      *datatype = GL_HALF_FLOAT_ARB;
560      *comps = 1;
561      return;
562
563   default:
564      _mesa_problem(NULL, "bad format in _mesa_format_to_type_and_comps");
565      *datatype = 0;
566      *comps = 1;
567   }
568}
569