Tizen 2.0 Release
[profile/ivi/osmesa.git] / src / mesa / main / texcompress.c
1 /*
2  * Mesa 3-D graphics library
3  * Version:  6.5.1
4  *
5  * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
6  * Copyright (c) 2008 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 texcompress.c
29  * Helper functions for texture compression.
30  */
31
32
33 #include "glheader.h"
34 #include "imports.h"
35 #include "colormac.h"
36 #include "formats.h"
37 #include "mfeatures.h"
38 #include "mtypes.h"
39 #include "texcompress.h"
40
41
42 /**
43  * Get the GL base format of a specified GL compressed texture format
44  *
45  * From page 232 of the OpenGL 3.3 (Compatiblity Profile) spec:
46  *
47  *     "Compressed Internal Format      Base Internal Format    Type
48  *     ---------------------------     --------------------    ---------
49  *     COMPRESSED_ALPHA                ALPHA                   Generic
50  *     COMPRESSED_LUMINANCE            LUMINANCE               Generic
51  *     COMPRESSED_LUMINANCE_ALPHA      LUMINANCE_ALPHA         Generic
52  *     COMPRESSED_INTENSITY            INTENSITY               Generic
53  *     COMPRESSED_RED                  RED                     Generic
54  *     COMPRESSED_RG                   RG                      Generic
55  *     COMPRESSED_RGB                  RGB                     Generic
56  *     COMPRESSED_RGBA                 RGBA                    Generic
57  *     COMPRESSED_SRGB                 RGB                     Generic
58  *     COMPRESSED_SRGB_ALPHA           RGBA                    Generic
59  *     COMPRESSED_SLUMINANCE           LUMINANCE               Generic
60  *     COMPRESSED_SLUMINANCE_ALPHA     LUMINANCE_ALPHA         Generic
61  *     COMPRESSED_RED_RGTC1            RED                     Specific
62  *     COMPRESSED_SIGNED_RED_RGTC1     RED                     Specific
63  *     COMPRESSED_RG_RGTC2             RG                      Specific
64  *     COMPRESSED_SIGNED_RG_RGTC2      RG                      Specific"
65  *
66  * \return
67  * The base format of \c format if \c format is a compressed format (either
68  * generic or specific.  Otherwise 0 is returned.
69  */
70 GLenum
71 _mesa_gl_compressed_format_base_format(GLenum format)
72 {
73    switch (format) {
74    case GL_COMPRESSED_RED:
75    case GL_COMPRESSED_RED_RGTC1:
76    case GL_COMPRESSED_SIGNED_RED_RGTC1:
77       return GL_RED;
78
79    case GL_COMPRESSED_RG:
80    case GL_COMPRESSED_RG_RGTC2:
81    case GL_COMPRESSED_SIGNED_RG_RGTC2:
82       return GL_RG;
83
84    case GL_COMPRESSED_RGB:
85    case GL_COMPRESSED_SRGB:
86    case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
87    case GL_COMPRESSED_RGB_FXT1_3DFX:
88    case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
89       return GL_RGB;
90
91    case GL_COMPRESSED_RGBA:
92    case GL_COMPRESSED_SRGB_ALPHA:
93    case GL_COMPRESSED_RGBA_BPTC_UNORM_ARB:
94    case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB:
95    case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB:
96    case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB:
97    case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
98    case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
99    case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
100    case GL_COMPRESSED_RGBA_FXT1_3DFX:
101    case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
102    case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
103    case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
104       return GL_RGBA;
105
106    case GL_COMPRESSED_ALPHA:
107       return GL_ALPHA;
108
109    case GL_COMPRESSED_LUMINANCE:
110    case GL_COMPRESSED_SLUMINANCE:
111    case GL_COMPRESSED_LUMINANCE_LATC1_EXT:
112    case GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT:
113       return GL_LUMINANCE;
114
115    case GL_COMPRESSED_LUMINANCE_ALPHA:
116    case GL_COMPRESSED_SLUMINANCE_ALPHA:
117    case GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT:
118    case GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT:
119    case GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI:
120       return GL_LUMINANCE_ALPHA;
121
122    case GL_COMPRESSED_INTENSITY:
123       return GL_INTENSITY;
124
125    default:
126       return 0;
127    }
128 }
129
130 /**
131  * Return list of (and count of) all specific texture compression
132  * formats that are supported.
133  *
134  * Some formats are \b not returned by this function.  The
135  * \c GL_COMPRESSED_TEXTURE_FORMATS query only returns formats that are
136  * "suitable for general-purpose usage."  All texture compression extensions
137  * have taken this to mean either linear RGB or linear RGBA.
138  *
139  * The GL_ARB_texture_compress_rgtc spec says:
140  *
141  *    "19) Should the GL_NUM_COMPRESSED_TEXTURE_FORMATS and
142  *        GL_COMPRESSED_TEXTURE_FORMATS queries return the RGTC formats?
143  *
144  *        RESOLVED:  No.
145  *
146  *        The OpenGL 2.1 specification says "The only values returned
147  *        by this query [GL_COMPRESSED_TEXTURE_FORMATS"] are those
148  *        corresponding to formats suitable for general-purpose usage.
149  *        The renderer will not enumerate formats with restrictions that
150  *        need to be specifically understood prior to use."
151  *
152  *        Compressed textures with just red or red-green components are
153  *        not general-purpose so should not be returned by these queries
154  *        because they have restrictions.
155  *
156  *        Applications that seek to use the RGTC formats should do so
157  *        by looking for this extension's name in the string returned by
158  *        glGetString(GL_EXTENSIONS) rather than
159  *        what GL_NUM_COMPRESSED_TEXTURE_FORMATS and
160  *        GL_COMPRESSED_TEXTURE_FORMATS return."
161  *
162  * There is nearly identical wording in the GL_EXT_texture_compression_rgtc
163  * spec.
164  *
165  * The GL_EXT_texture_rRGB spec says:
166  *
167  *    "22) Should the new COMPRESSED_SRGB_* formats be listed in an
168  *        implementation's GL_COMPRESSED_TEXTURE_FORMATS list?
169  *
170  *        RESOLVED:  No.  Section 3.8.1 says formats listed by
171  *        GL_COMPRESSED_TEXTURE_FORMATS are "suitable for general-purpose
172  *        usage."  The non-linear distribution of red, green, and
173  *        blue for these sRGB compressed formats makes them not really
174  *        general-purpose."
175  *
176  * The GL_EXT_texture_compression_latc spec says:
177  *
178  *    "16) Should the GL_NUM_COMPRESSED_TEXTURE_FORMATS and
179  *        GL_COMPRESSED_TEXTURE_FORMATS queries return the LATC formats?
180  *
181  *        RESOLVED:  No.
182  *
183  *        The OpenGL 2.1 specification says "The only values returned
184  *        by this query [GL_COMPRESSED_TEXTURE_FORMATS"] are those
185  *        corresponding to formats suitable for general-purpose usage.
186  *        The renderer will not enumerate formats with restrictions that
187  *        need to be specifically understood prior to use."
188  *
189  *        Historically, OpenGL implementation have advertised the RGB and
190  *        RGBA versions of the S3TC extensions compressed format tokens
191  *        through this mechanism.
192  *
193  *        The specification is not sufficiently clear about what "suitable
194  *        for general-purpose usage" means.  Historically that seems to mean
195  *        unsigned RGB or unsigned RGBA.  The DXT1 format supporting alpha
196  *        (GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) is not exposed in the list (at
197  *        least for NVIDIA drivers) because the alpha is always 1.0 expect
198  *        when it is 0.0 when RGB is required to be black.  NVIDIA's even
199  *        limits itself to true linear RGB or RGBA formats, specifically
200  *        not including EXT_texture_sRGB's sRGB S3TC compressed formats.
201  *
202  *        Adding luminance and luminance-alpha texture formats (and
203  *        certainly signed versions of luminance and luminance-alpha
204  *        formats!) invites potential comptaibility problems with old
205  *        applications using this mechanism since old applications are
206  *        unlikely to expect non-RGB or non-RGBA formats to be advertised
207  *        through this mechanism.  However no specific misinteractions
208  *        with old applications is known.
209  *
210  *        Applications that seek to use the LATC formats should do so
211  *        by looking for this extension's name in the string returned by
212  *        glGetString(GL_EXTENSIONS) rather than
213  *        what GL_NUM_COMPRESSED_TEXTURE_FORMATS and
214  *        GL_COMPRESSED_TEXTURE_FORMATS return."
215  *
216  * There is no formal spec for GL_ATI_texture_compression_3dc.  Since the
217  * formats added by this extension are luminance-alpha formats, it is
218  * reasonable to expect them to follow the same rules as
219  * GL_EXT_texture_compression_latc.  At the very least, Catalyst 11.6 does not
220  * expose the 3dc formats through this mechanism.
221  *
222  * \param ctx  the GL context
223  * \param formats  the resulting format list (may be NULL).
224  *
225  * \return number of formats.
226  */
227 GLuint
228 _mesa_get_compressed_formats(struct gl_context *ctx, GLint *formats)
229 {
230    GLuint n = 0;
231    if (ctx->Extensions.TDFX_texture_compression_FXT1) {
232       if (formats) {
233          formats[n++] = GL_COMPRESSED_RGB_FXT1_3DFX;
234          formats[n++] = GL_COMPRESSED_RGBA_FXT1_3DFX;
235       }
236       else {
237          n += 2;
238       }
239    }
240
241    if (ctx->Extensions.EXT_texture_compression_s3tc) {
242       if (formats) {
243          formats[n++] = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
244          formats[n++] = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
245          formats[n++] = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
246       }
247       else {
248          n += 3;
249       }
250    }
251    if (ctx->Extensions.S3_s3tc) {
252       if (formats) {
253          formats[n++] = GL_RGB_S3TC;
254          formats[n++] = GL_RGB4_S3TC;
255          formats[n++] = GL_RGBA_S3TC;
256          formats[n++] = GL_RGBA4_S3TC;
257       }
258       else {
259          n += 4;
260       }
261    }
262    return n;
263
264 #if FEATURE_ES1 || FEATURE_ES2
265    if (formats) {
266       formats[n++] = GL_PALETTE4_RGB8_OES;
267       formats[n++] = GL_PALETTE4_RGBA8_OES;
268       formats[n++] = GL_PALETTE4_R5_G6_B5_OES;
269       formats[n++] = GL_PALETTE4_RGBA4_OES;
270       formats[n++] = GL_PALETTE4_RGB5_A1_OES;
271       formats[n++] = GL_PALETTE8_RGB8_OES;
272       formats[n++] = GL_PALETTE8_RGBA8_OES;
273       formats[n++] = GL_PALETTE8_R5_G6_B5_OES;
274       formats[n++] = GL_PALETTE8_RGBA4_OES;
275       formats[n++] = GL_PALETTE8_RGB5_A1_OES;
276    }
277    else {
278       n += 10;
279    }
280 #endif
281 }
282
283
284 /**
285  * Convert a compressed MESA_FORMAT_x to a GLenum.
286  */
287 gl_format
288 _mesa_glenum_to_compressed_format(GLenum format)
289 {
290    switch (format) {
291    case GL_COMPRESSED_RGB_FXT1_3DFX:
292       return MESA_FORMAT_RGB_FXT1;
293    case GL_COMPRESSED_RGBA_FXT1_3DFX:
294       return MESA_FORMAT_RGBA_FXT1;
295
296    case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
297    case GL_RGB_S3TC:
298       return MESA_FORMAT_RGB_DXT1;
299    case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
300    case GL_RGB4_S3TC:
301       return MESA_FORMAT_RGBA_DXT1;
302    case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
303    case GL_RGBA_S3TC:
304       return MESA_FORMAT_RGBA_DXT3;
305    case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
306    case GL_RGBA4_S3TC:
307       return MESA_FORMAT_RGBA_DXT5;
308
309    case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
310       return MESA_FORMAT_SRGB_DXT1;
311    case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
312       return MESA_FORMAT_SRGBA_DXT1;
313    case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
314       return MESA_FORMAT_SRGBA_DXT3;
315    case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
316       return MESA_FORMAT_SRGBA_DXT5;
317
318    case GL_COMPRESSED_RED_RGTC1:
319       return MESA_FORMAT_RED_RGTC1;
320    case GL_COMPRESSED_SIGNED_RED_RGTC1:
321       return MESA_FORMAT_SIGNED_RED_RGTC1;
322    case GL_COMPRESSED_RG_RGTC2:
323       return MESA_FORMAT_RG_RGTC2;
324    case GL_COMPRESSED_SIGNED_RG_RGTC2:
325       return MESA_FORMAT_SIGNED_RG_RGTC2;
326
327    case GL_COMPRESSED_LUMINANCE_LATC1_EXT:
328       return MESA_FORMAT_L_LATC1;
329    case GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT:
330       return MESA_FORMAT_SIGNED_L_LATC1;
331    case GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT:
332    case GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI:
333       return MESA_FORMAT_LA_LATC2;
334    case GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT:
335       return MESA_FORMAT_SIGNED_LA_LATC2;
336
337    default:
338       return MESA_FORMAT_NONE;
339    }
340 }
341
342
343 /**
344  * Given a compressed MESA_FORMAT_x value, return the corresponding
345  * GLenum for that format.
346  * This is needed for glGetTexLevelParameter(GL_TEXTURE_INTERNAL_FORMAT)
347  * which must return the specific texture format used when the user might
348  * have originally specified a generic compressed format in their
349  * glTexImage2D() call.
350  * For non-compressed textures, we always return the user-specified
351  * internal format unchanged.
352  */
353 GLenum
354 _mesa_compressed_format_to_glenum(struct gl_context *ctx, GLuint mesaFormat)
355 {
356    switch (mesaFormat) {
357 #if FEATURE_texture_fxt1
358    case MESA_FORMAT_RGB_FXT1:
359       return GL_COMPRESSED_RGB_FXT1_3DFX;
360    case MESA_FORMAT_RGBA_FXT1:
361       return GL_COMPRESSED_RGBA_FXT1_3DFX;
362 #endif
363 #if FEATURE_texture_s3tc
364    case MESA_FORMAT_RGB_DXT1:
365       return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
366    case MESA_FORMAT_RGBA_DXT1:
367       return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
368    case MESA_FORMAT_RGBA_DXT3:
369       return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
370    case MESA_FORMAT_RGBA_DXT5:
371       return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
372 #if FEATURE_EXT_texture_sRGB
373    case MESA_FORMAT_SRGB_DXT1:
374       return GL_COMPRESSED_SRGB_S3TC_DXT1_EXT;
375    case MESA_FORMAT_SRGBA_DXT1:
376       return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT;
377    case MESA_FORMAT_SRGBA_DXT3:
378       return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT;
379    case MESA_FORMAT_SRGBA_DXT5:
380       return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT;
381 #endif
382 #endif
383
384    case MESA_FORMAT_RED_RGTC1:
385       return GL_COMPRESSED_RED_RGTC1;
386    case MESA_FORMAT_SIGNED_RED_RGTC1:
387       return GL_COMPRESSED_SIGNED_RED_RGTC1;
388    case MESA_FORMAT_RG_RGTC2:
389       return GL_COMPRESSED_RG_RGTC2;
390    case MESA_FORMAT_SIGNED_RG_RGTC2:
391       return GL_COMPRESSED_SIGNED_RG_RGTC2;
392
393    case MESA_FORMAT_L_LATC1:
394       return GL_COMPRESSED_LUMINANCE_LATC1_EXT;
395    case MESA_FORMAT_SIGNED_L_LATC1:
396       return GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT;
397    case MESA_FORMAT_LA_LATC2:
398       return GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT;
399    case MESA_FORMAT_SIGNED_LA_LATC2:
400       return GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT;
401
402    default:
403       _mesa_problem(ctx, "Unexpected mesa texture format in"
404                     " _mesa_compressed_format_to_glenum()");
405       return 0;
406    }
407 }
408
409
410 /*
411  * Return the address of the pixel at (col, row, img) in a
412  * compressed texture image.
413  * \param col, row, img - image position (3D), should be a multiple of the
414  *                        format's block size.
415  * \param format - compressed image format
416  * \param width - image width (stride) in pixels
417  * \param image - the image address
418  * \return address of pixel at (row, col, img)
419  */
420 GLubyte *
421 _mesa_compressed_image_address(GLint col, GLint row, GLint img,
422                                gl_format mesaFormat,
423                                GLsizei width, const GLubyte *image)
424 {
425    /* XXX only 2D images implemented, not 3D */
426    const GLuint blockSize = _mesa_get_format_bytes(mesaFormat);
427    GLuint bw, bh;
428    GLint offset;
429
430    _mesa_get_format_block_size(mesaFormat, &bw, &bh);
431
432    ASSERT(col % bw == 0);
433    ASSERT(row % bh == 0);
434
435    offset = ((width + bw - 1) / bw) * (row / bh) + col / bw;
436    offset *= blockSize;
437
438    return (GLubyte *) image + offset;
439 }