3 * Compressed textures functions.
7 * Mesa 3-D graphics library
10 * Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
12 * Permission is hereby granted, free of charge, to any person obtaining a
13 * copy of this software and associated documentation files (the "Software"),
14 * to deal in the Software without restriction, including without limitation
15 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16 * and/or sell copies of the Software, and to permit persons to whom the
17 * Software is furnished to do so, subject to the following conditions:
19 * The above copyright notice and this permission notice shall be included
20 * in all copies or substantial portions of the Software.
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
26 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
27 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35 #include "texcompress.h"
36 #include "texformat.h"
40 * Get the list of supported internal compression formats.
42 * \param ctx GL context.
43 * \param formats the resulting format list (may be NULL).
45 * \return number of formats.
48 _mesa_get_compressed_formats( GLcontext
*ctx
, GLint
*formats
)
51 if (ctx
->Extensions
.ARB_texture_compression
) {
52 if (ctx
->Extensions
.TDFX_texture_compression_FXT1
) {
54 formats
[n
++] = GL_COMPRESSED_RGB_FXT1_3DFX
;
55 formats
[n
++] = GL_COMPRESSED_RGBA_FXT1_3DFX
;
61 if (ctx
->Extensions
.EXT_texture_compression_s3tc
) {
63 formats
[n
++] = GL_COMPRESSED_RGB_S3TC_DXT1_EXT
;
64 /* Skip this one because it has a restriction (all transparent
65 * pixels become black). See the texture compressions spec for
66 * a detailed explanation. This is what NVIDIA does.
67 formats[n++] = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
69 formats
[n
++] = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
;
70 formats
[n
++] = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
;
76 if (ctx
->Extensions
.S3_s3tc
) {
78 formats
[n
++] = GL_RGB_S3TC
;
79 formats
[n
++] = GL_RGB4_S3TC
;
80 formats
[n
++] = GL_RGBA_S3TC
;
81 formats
[n
++] = GL_RGBA4_S3TC
;
93 * Return bytes of storage needed for the given texture size and
96 * \param width texture width in texels.
97 * \param height texture height in texels.
98 * \param depth texture depth in texels.
99 * \param texFormat one of the compressed format enums
101 * \return size in bytes, or zero if bad \p texFormat.
104 _mesa_compressed_texture_size( GLcontext
*ctx
,
105 GLsizei width
, GLsizei height
, GLsizei depth
,
110 if (ctx
->Driver
.CompressedTextureSize
) {
111 return ctx
->Driver
.CompressedTextureSize(ctx
, width
, height
, depth
, format
);
117 case GL_COMPRESSED_RGB_FXT1_3DFX
:
118 case GL_COMPRESSED_RGBA_FXT1_3DFX
:
119 /* round up width to next multiple of 8, height to next multiple of 4 */
120 width
= (width
+ 7) & ~7;
121 height
= (height
+ 3) & ~3;
122 /* 16 bytes per 8x4 tile of RGB[A] texels */
123 size
= width
* height
/ 2;
124 /* Textures smaller than 8x4 will effectively be made into 8x4 and
130 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
131 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
134 /* round up width, height to next multiple of 4 */
135 width
= (width
+ 3) & ~3;
136 height
= (height
+ 3) & ~3;
137 /* 8 bytes per 4x4 tile of RGB[A] texels */
138 size
= width
* height
/ 2;
139 /* Textures smaller than 4x4 will effectively be made into 4x4 and
145 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
146 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
149 /* round up width, height to next multiple of 4 */
150 width
= (width
+ 3) & ~3;
151 height
= (height
+ 3) & ~3;
152 /* 16 bytes per 4x4 tile of RGBA texels */
153 size
= width
* height
; /* simple! */
154 /* Textures smaller than 4x4 will effectively be made into 4x4 and
161 _mesa_problem(ctx
, "bad texformat in compressed_texture_size");
168 * Compute the bytes per row in a compressed texture image.
169 * We use this for computing the destination address for sub-texture updates.
170 * \param format one of the specific texture compression formats
171 * \param width image width in pixels
172 * \return stride, in bytes, between rows for compressed image
175 _mesa_compressed_row_stride(GLenum format
, GLsizei width
)
180 case GL_COMPRESSED_RGB_FXT1_3DFX
:
181 case GL_COMPRESSED_RGBA_FXT1_3DFX
:
182 stride
= ((width
+ 7) / 8) * 16; /* 16 bytes per 8x4 tile */
184 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
185 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
188 stride
= ((width
+ 3) / 4) * 8; /* 8 bytes per 4x4 tile */
190 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
191 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
194 stride
= ((width
+ 3) / 4) * 16; /* 16 bytes per 4x4 tile */
205 * Return the address of the pixel at (col, row, img) in a
206 * compressed texture image.
208 * \param col image position.
209 * \param row image position.
210 * \param img image position.
211 * \param format compressed image format.
212 * \param width image width.
213 * \param image the image address.
215 * \return address of pixel at (row, col).
218 _mesa_compressed_image_address(GLint col
, GLint row
, GLint img
,
220 GLsizei width
, const GLubyte
*image
)
226 /* We try to spot a "complete" subtexture "above" ROW, COL;
227 * this texture is given by appropriate rounding of WIDTH x ROW.
228 * Then we just add the amount left (usually on the left).
230 * Example for X*Y microtiles (Z bytes each)
231 * offset = Z * (((width + X - 1) / X) * (row / Y) + col / X);
235 case GL_COMPRESSED_RGB_FXT1_3DFX
:
236 case GL_COMPRESSED_RGBA_FXT1_3DFX
:
237 addr
= (GLubyte
*) image
+ 16 * (((width
+ 7) / 8) * (row
/ 4) + col
/ 8);
239 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
240 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
243 addr
= (GLubyte
*) image
+ 8 * (((width
+ 3) / 4) * (row
/ 4) + col
/ 4);
245 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
246 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
249 addr
= (GLubyte
*) image
+ 16 * (((width
+ 3) / 4) * (row
/ 4) + col
/ 4);
260 * \param srcRowStride source stride, in pixels
263 _mesa_compress_teximage( GLcontext
*ctx
, GLsizei width
, GLsizei height
,
264 GLenum srcFormat
, const GLchan
*source
,
266 const struct gl_texture_format
*dstFormat
,
267 GLubyte
*dest
, GLint dstRowStride
)
269 switch (dstFormat
->MesaFormat
) {
271 _mesa_problem(ctx
, "Bad dstFormat in _mesa_compress_teximage()");