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