mesa: Don't warn when the desired result of s3tc lib available occurs.
[mesa.git] / src / mesa / main / texcompress_s3tc.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 6.5.3
4 *
5 * Copyright (C) 1999-2007 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_s3tc.c
29 * GL_EXT_texture_compression_s3tc support.
30 */
31
32 #ifndef USE_EXTERNAL_DXTN_LIB
33 #define USE_EXTERNAL_DXTN_LIB 1
34 #endif
35
36 #include "glheader.h"
37 #include "imports.h"
38 #include "colormac.h"
39 #include "convolve.h"
40 #include "dlopen.h"
41 #include "image.h"
42 #include "macros.h"
43 #include "texcompress.h"
44 #include "texcompress_s3tc.h"
45 #include "texstore.h"
46
47
48 #if FEATURE_texture_s3tc
49
50
51 #if defined(_WIN32) || defined(WIN32)
52 #define DXTN_LIBNAME "dxtn.dll"
53 #define RTLD_LAZY 0
54 #define RTLD_GLOBAL 0
55 #elif defined(__DJGPP__)
56 #define DXTN_LIBNAME "dxtn.dxe"
57 #else
58 #define DXTN_LIBNAME "libtxc_dxtn.so"
59 #endif
60
61 #if FEATURE_EXT_texture_sRGB
62 /**
63 * Convert an 8-bit sRGB value from non-linear space to a
64 * linear RGB value in [0, 1].
65 * Implemented with a 256-entry lookup table.
66 */
67 static INLINE GLfloat
68 nonlinear_to_linear(GLubyte cs8)
69 {
70 static GLfloat table[256];
71 static GLboolean tableReady = GL_FALSE;
72 if (!tableReady) {
73 /* compute lookup table now */
74 GLuint i;
75 for (i = 0; i < 256; i++) {
76 const GLfloat cs = UBYTE_TO_FLOAT(i);
77 if (cs <= 0.04045) {
78 table[i] = cs / 12.92f;
79 }
80 else {
81 table[i] = (GLfloat) pow((cs + 0.055) / 1.055, 2.4);
82 }
83 }
84 tableReady = GL_TRUE;
85 }
86 return table[cs8];
87 }
88 #endif /* FEATURE_EXT_texture_sRGB */
89
90 typedef void (*dxtFetchTexelFuncExt)( GLint srcRowstride, GLubyte *pixdata, GLint col, GLint row, GLvoid *texelOut );
91
92 dxtFetchTexelFuncExt fetch_ext_rgb_dxt1 = NULL;
93 dxtFetchTexelFuncExt fetch_ext_rgba_dxt1 = NULL;
94 dxtFetchTexelFuncExt fetch_ext_rgba_dxt3 = NULL;
95 dxtFetchTexelFuncExt fetch_ext_rgba_dxt5 = NULL;
96
97 typedef void (*dxtCompressTexFuncExt)(GLint srccomps, GLint width,
98 GLint height, const GLchan *srcPixData,
99 GLenum destformat, GLubyte *dest,
100 GLint dstRowStride);
101
102 static dxtCompressTexFuncExt ext_tx_compress_dxtn = NULL;
103
104 static void *dxtlibhandle = NULL;
105
106
107 void
108 _mesa_init_texture_s3tc( GLcontext *ctx )
109 {
110 /* called during context initialization */
111 ctx->Mesa_DXTn = GL_FALSE;
112 #if USE_EXTERNAL_DXTN_LIB
113 if (!dxtlibhandle) {
114 dxtlibhandle = _mesa_dlopen(DXTN_LIBNAME, 0);
115 if (!dxtlibhandle) {
116 _mesa_warning(ctx, "couldn't open " DXTN_LIBNAME ", software DXTn "
117 "compression/decompression unavailable");
118 }
119 else {
120 /* the fetch functions are not per context! Might be problematic... */
121 fetch_ext_rgb_dxt1 = (dxtFetchTexelFuncExt)
122 _mesa_dlsym(dxtlibhandle, "fetch_2d_texel_rgb_dxt1");
123 fetch_ext_rgba_dxt1 = (dxtFetchTexelFuncExt)
124 _mesa_dlsym(dxtlibhandle, "fetch_2d_texel_rgba_dxt1");
125 fetch_ext_rgba_dxt3 = (dxtFetchTexelFuncExt)
126 _mesa_dlsym(dxtlibhandle, "fetch_2d_texel_rgba_dxt3");
127 fetch_ext_rgba_dxt5 = (dxtFetchTexelFuncExt)
128 _mesa_dlsym(dxtlibhandle, "fetch_2d_texel_rgba_dxt5");
129 ext_tx_compress_dxtn = (dxtCompressTexFuncExt)
130 _mesa_dlsym(dxtlibhandle, "tx_compress_dxtn");
131
132 if (!fetch_ext_rgb_dxt1 ||
133 !fetch_ext_rgba_dxt1 ||
134 !fetch_ext_rgba_dxt3 ||
135 !fetch_ext_rgba_dxt5 ||
136 !ext_tx_compress_dxtn) {
137 _mesa_warning(ctx, "couldn't reference all symbols in "
138 DXTN_LIBNAME ", software DXTn compression/decompression "
139 "unavailable");
140 fetch_ext_rgb_dxt1 = NULL;
141 fetch_ext_rgba_dxt1 = NULL;
142 fetch_ext_rgba_dxt3 = NULL;
143 fetch_ext_rgba_dxt5 = NULL;
144 ext_tx_compress_dxtn = NULL;
145 _mesa_dlclose(dxtlibhandle);
146 dxtlibhandle = NULL;
147 }
148 }
149 }
150 if (dxtlibhandle) {
151 ctx->Mesa_DXTn = GL_TRUE;
152 }
153 #else
154 (void) ctx;
155 #endif
156 }
157
158 /**
159 * Store user's image in rgb_dxt1 format.
160 */
161 GLboolean
162 _mesa_texstore_rgb_dxt1(TEXSTORE_PARAMS)
163 {
164 const GLchan *pixels;
165 GLint srcRowStride;
166 GLubyte *dst;
167 const GLint texWidth = dstRowStride * 4 / 8; /* a bit of a hack */
168 const GLchan *tempImage = NULL;
169
170 ASSERT(dstFormat == MESA_FORMAT_RGB_DXT1);
171 ASSERT(dstXoffset % 4 == 0);
172 ASSERT(dstYoffset % 4 == 0);
173 ASSERT(dstZoffset % 4 == 0);
174 (void) dstZoffset;
175 (void) dstImageOffsets;
176
177 if (srcFormat != GL_RGB ||
178 srcType != CHAN_TYPE ||
179 ctx->_ImageTransferState ||
180 srcPacking->SwapBytes) {
181 /* convert image to RGB/GLchan */
182 tempImage = _mesa_make_temp_chan_image(ctx, dims,
183 baseInternalFormat,
184 _mesa_get_format_base_format(dstFormat),
185 srcWidth, srcHeight, srcDepth,
186 srcFormat, srcType, srcAddr,
187 srcPacking);
188 if (!tempImage)
189 return GL_FALSE; /* out of memory */
190 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
191 pixels = tempImage;
192 srcRowStride = 3 * srcWidth;
193 srcFormat = GL_RGB;
194 }
195 else {
196 pixels = (const GLchan *) srcAddr;
197 srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat,
198 srcType) / sizeof(GLchan);
199 }
200
201 dst = _mesa_compressed_image_address(dstXoffset, dstYoffset, 0,
202 dstFormat,
203 texWidth, (GLubyte *) dstAddr);
204
205 if (ext_tx_compress_dxtn) {
206 (*ext_tx_compress_dxtn)(3, srcWidth, srcHeight, pixels,
207 GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
208 dst, dstRowStride);
209 }
210 else {
211 _mesa_warning(ctx, "external dxt library not available: texstore_rgb_dxt1");
212 }
213
214 if (tempImage)
215 free((void *) tempImage);
216
217 return GL_TRUE;
218 }
219
220
221 /**
222 * Store user's image in rgba_dxt1 format.
223 */
224 GLboolean
225 _mesa_texstore_rgba_dxt1(TEXSTORE_PARAMS)
226 {
227 const GLchan *pixels;
228 GLint srcRowStride;
229 GLubyte *dst;
230 const GLint texWidth = dstRowStride * 4 / 8; /* a bit of a hack */
231 const GLchan *tempImage = NULL;
232
233 ASSERT(dstFormat == MESA_FORMAT_RGBA_DXT1);
234 ASSERT(dstXoffset % 4 == 0);
235 ASSERT(dstYoffset % 4 == 0);
236 ASSERT(dstZoffset % 4 == 0);
237 (void) dstZoffset;
238 (void) dstImageOffsets;
239
240 if (srcFormat != GL_RGBA ||
241 srcType != CHAN_TYPE ||
242 ctx->_ImageTransferState ||
243 srcPacking->SwapBytes) {
244 /* convert image to RGBA/GLchan */
245 tempImage = _mesa_make_temp_chan_image(ctx, dims,
246 baseInternalFormat,
247 _mesa_get_format_base_format(dstFormat),
248 srcWidth, srcHeight, srcDepth,
249 srcFormat, srcType, srcAddr,
250 srcPacking);
251 if (!tempImage)
252 return GL_FALSE; /* out of memory */
253 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
254 pixels = tempImage;
255 srcRowStride = 4 * srcWidth;
256 srcFormat = GL_RGBA;
257 }
258 else {
259 pixels = (const GLchan *) srcAddr;
260 srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat,
261 srcType) / sizeof(GLchan);
262 }
263
264 dst = _mesa_compressed_image_address(dstXoffset, dstYoffset, 0,
265 dstFormat,
266 texWidth, (GLubyte *) dstAddr);
267 if (ext_tx_compress_dxtn) {
268 (*ext_tx_compress_dxtn)(4, srcWidth, srcHeight, pixels,
269 GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
270 dst, dstRowStride);
271 }
272 else {
273 _mesa_warning(ctx, "external dxt library not available: texstore_rgba_dxt1");
274 }
275
276 if (tempImage)
277 free((void*) tempImage);
278
279 return GL_TRUE;
280 }
281
282
283 /**
284 * Store user's image in rgba_dxt3 format.
285 */
286 GLboolean
287 _mesa_texstore_rgba_dxt3(TEXSTORE_PARAMS)
288 {
289 const GLchan *pixels;
290 GLint srcRowStride;
291 GLubyte *dst;
292 const GLint texWidth = dstRowStride * 4 / 16; /* a bit of a hack */
293 const GLchan *tempImage = NULL;
294
295 ASSERT(dstFormat == MESA_FORMAT_RGBA_DXT3);
296 ASSERT(dstXoffset % 4 == 0);
297 ASSERT(dstYoffset % 4 == 0);
298 ASSERT(dstZoffset % 4 == 0);
299 (void) dstZoffset;
300 (void) dstImageOffsets;
301
302 if (srcFormat != GL_RGBA ||
303 srcType != CHAN_TYPE ||
304 ctx->_ImageTransferState ||
305 srcPacking->SwapBytes) {
306 /* convert image to RGBA/GLchan */
307 tempImage = _mesa_make_temp_chan_image(ctx, dims,
308 baseInternalFormat,
309 _mesa_get_format_base_format(dstFormat),
310 srcWidth, srcHeight, srcDepth,
311 srcFormat, srcType, srcAddr,
312 srcPacking);
313 if (!tempImage)
314 return GL_FALSE; /* out of memory */
315 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
316 pixels = tempImage;
317 srcRowStride = 4 * srcWidth;
318 }
319 else {
320 pixels = (const GLchan *) srcAddr;
321 srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat,
322 srcType) / sizeof(GLchan);
323 }
324
325 dst = _mesa_compressed_image_address(dstXoffset, dstYoffset, 0,
326 dstFormat,
327 texWidth, (GLubyte *) dstAddr);
328 if (ext_tx_compress_dxtn) {
329 (*ext_tx_compress_dxtn)(4, srcWidth, srcHeight, pixels,
330 GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
331 dst, dstRowStride);
332 }
333 else {
334 _mesa_warning(ctx, "external dxt library not available: texstore_rgba_dxt3");
335 }
336
337 if (tempImage)
338 free((void *) tempImage);
339
340 return GL_TRUE;
341 }
342
343
344 /**
345 * Store user's image in rgba_dxt5 format.
346 */
347 GLboolean
348 _mesa_texstore_rgba_dxt5(TEXSTORE_PARAMS)
349 {
350 const GLchan *pixels;
351 GLint srcRowStride;
352 GLubyte *dst;
353 const GLint texWidth = dstRowStride * 4 / 16; /* a bit of a hack */
354 const GLchan *tempImage = NULL;
355
356 ASSERT(dstFormat == MESA_FORMAT_RGBA_DXT5);
357 ASSERT(dstXoffset % 4 == 0);
358 ASSERT(dstYoffset % 4 == 0);
359 ASSERT(dstZoffset % 4 == 0);
360 (void) dstZoffset;
361 (void) dstImageOffsets;
362
363 if (srcFormat != GL_RGBA ||
364 srcType != CHAN_TYPE ||
365 ctx->_ImageTransferState ||
366 srcPacking->SwapBytes) {
367 /* convert image to RGBA/GLchan */
368 tempImage = _mesa_make_temp_chan_image(ctx, dims,
369 baseInternalFormat,
370 _mesa_get_format_base_format(dstFormat),
371 srcWidth, srcHeight, srcDepth,
372 srcFormat, srcType, srcAddr,
373 srcPacking);
374 if (!tempImage)
375 return GL_FALSE; /* out of memory */
376 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
377 pixels = tempImage;
378 srcRowStride = 4 * srcWidth;
379 }
380 else {
381 pixels = (const GLchan *) srcAddr;
382 srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat,
383 srcType) / sizeof(GLchan);
384 }
385
386 dst = _mesa_compressed_image_address(dstXoffset, dstYoffset, 0,
387 dstFormat,
388 texWidth, (GLubyte *) dstAddr);
389 if (ext_tx_compress_dxtn) {
390 (*ext_tx_compress_dxtn)(4, srcWidth, srcHeight, pixels,
391 GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,
392 dst, dstRowStride);
393 }
394 else {
395 _mesa_warning(ctx, "external dxt library not available: texstore_rgba_dxt5");
396 }
397
398 if (tempImage)
399 free((void *) tempImage);
400
401 return GL_TRUE;
402 }
403
404
405 static void
406 fetch_texel_2d_rgb_dxt1( const struct gl_texture_image *texImage,
407 GLint i, GLint j, GLint k, GLchan *texel )
408 {
409 (void) k;
410 if (fetch_ext_rgb_dxt1) {
411 ASSERT (sizeof(GLchan) == sizeof(GLubyte));
412 fetch_ext_rgb_dxt1(texImage->RowStride,
413 (GLubyte *)(texImage)->Data, i, j, texel);
414 }
415 else
416 _mesa_debug(NULL, "attempted to decode s3tc texture without library available: fetch_texel_2d_rgb_dxt1");
417 }
418
419
420 void
421 _mesa_fetch_texel_2d_f_rgb_dxt1(const struct gl_texture_image *texImage,
422 GLint i, GLint j, GLint k, GLfloat *texel)
423 {
424 /* just sample as GLchan and convert to float here */
425 GLchan rgba[4];
426 fetch_texel_2d_rgb_dxt1(texImage, i, j, k, rgba);
427 texel[RCOMP] = CHAN_TO_FLOAT(rgba[RCOMP]);
428 texel[GCOMP] = CHAN_TO_FLOAT(rgba[GCOMP]);
429 texel[BCOMP] = CHAN_TO_FLOAT(rgba[BCOMP]);
430 texel[ACOMP] = CHAN_TO_FLOAT(rgba[ACOMP]);
431 }
432
433
434 static void
435 fetch_texel_2d_rgba_dxt1( const struct gl_texture_image *texImage,
436 GLint i, GLint j, GLint k, GLchan *texel )
437 {
438 (void) k;
439 if (fetch_ext_rgba_dxt1) {
440 fetch_ext_rgba_dxt1(texImage->RowStride,
441 (GLubyte *)(texImage)->Data, i, j, texel);
442 }
443 else
444 _mesa_debug(NULL, "attempted to decode s3tc texture without library available: fetch_texel_2d_rgba_dxt1\n");
445 }
446
447
448 void
449 _mesa_fetch_texel_2d_f_rgba_dxt1(const struct gl_texture_image *texImage,
450 GLint i, GLint j, GLint k, GLfloat *texel)
451 {
452 /* just sample as GLchan and convert to float here */
453 GLchan rgba[4];
454 fetch_texel_2d_rgba_dxt1(texImage, i, j, k, rgba);
455 texel[RCOMP] = CHAN_TO_FLOAT(rgba[RCOMP]);
456 texel[GCOMP] = CHAN_TO_FLOAT(rgba[GCOMP]);
457 texel[BCOMP] = CHAN_TO_FLOAT(rgba[BCOMP]);
458 texel[ACOMP] = CHAN_TO_FLOAT(rgba[ACOMP]);
459 }
460
461
462 static void
463 fetch_texel_2d_rgba_dxt3( const struct gl_texture_image *texImage,
464 GLint i, GLint j, GLint k, GLchan *texel )
465 {
466 (void) k;
467 if (fetch_ext_rgba_dxt3) {
468 ASSERT (sizeof(GLchan) == sizeof(GLubyte));
469 fetch_ext_rgba_dxt3(texImage->RowStride, (GLubyte *)(texImage)->Data,
470 i, j, texel);
471 }
472 else
473 _mesa_debug(NULL, "attempted to decode s3tc texture without library available: fetch_texel_2d_rgba_dxt3\n");
474 }
475
476
477 void
478 _mesa_fetch_texel_2d_f_rgba_dxt3(const struct gl_texture_image *texImage,
479 GLint i, GLint j, GLint k, GLfloat *texel)
480 {
481 /* just sample as GLchan and convert to float here */
482 GLchan rgba[4];
483 fetch_texel_2d_rgba_dxt3(texImage, i, j, k, rgba);
484 texel[RCOMP] = CHAN_TO_FLOAT(rgba[RCOMP]);
485 texel[GCOMP] = CHAN_TO_FLOAT(rgba[GCOMP]);
486 texel[BCOMP] = CHAN_TO_FLOAT(rgba[BCOMP]);
487 texel[ACOMP] = CHAN_TO_FLOAT(rgba[ACOMP]);
488 }
489
490
491 static void
492 fetch_texel_2d_rgba_dxt5( const struct gl_texture_image *texImage,
493 GLint i, GLint j, GLint k, GLchan *texel )
494 {
495 (void) k;
496 if (fetch_ext_rgba_dxt5) {
497 fetch_ext_rgba_dxt5(texImage->RowStride, (GLubyte *)(texImage)->Data,
498 i, j, texel);
499 }
500 else
501 _mesa_debug(NULL, "attempted to decode s3tc texture without library available: fetch_texel_2d_rgba_dxt5\n");
502 }
503
504
505 void
506 _mesa_fetch_texel_2d_f_rgba_dxt5(const struct gl_texture_image *texImage,
507 GLint i, GLint j, GLint k, GLfloat *texel)
508 {
509 /* just sample as GLchan and convert to float here */
510 GLchan rgba[4];
511 fetch_texel_2d_rgba_dxt5(texImage, i, j, k, rgba);
512 texel[RCOMP] = CHAN_TO_FLOAT(rgba[RCOMP]);
513 texel[GCOMP] = CHAN_TO_FLOAT(rgba[GCOMP]);
514 texel[BCOMP] = CHAN_TO_FLOAT(rgba[BCOMP]);
515 texel[ACOMP] = CHAN_TO_FLOAT(rgba[ACOMP]);
516 }
517
518 #if FEATURE_EXT_texture_sRGB
519 void
520 _mesa_fetch_texel_2d_f_srgb_dxt1( const struct gl_texture_image *texImage,
521 GLint i, GLint j, GLint k, GLfloat *texel )
522 {
523 /* just sample as GLchan and convert to float here */
524 GLchan rgba[4];
525 fetch_texel_2d_rgb_dxt1(texImage, i, j, k, rgba);
526 texel[RCOMP] = nonlinear_to_linear(rgba[RCOMP]);
527 texel[GCOMP] = nonlinear_to_linear(rgba[GCOMP]);
528 texel[BCOMP] = nonlinear_to_linear(rgba[BCOMP]);
529 texel[ACOMP] = CHAN_TO_FLOAT(rgba[ACOMP]);
530 }
531
532 void
533 _mesa_fetch_texel_2d_f_srgba_dxt1(const struct gl_texture_image *texImage,
534 GLint i, GLint j, GLint k, GLfloat *texel)
535 {
536 /* just sample as GLchan and convert to float here */
537 GLchan rgba[4];
538 fetch_texel_2d_rgba_dxt1(texImage, i, j, k, rgba);
539 texel[RCOMP] = nonlinear_to_linear(rgba[RCOMP]);
540 texel[GCOMP] = nonlinear_to_linear(rgba[GCOMP]);
541 texel[BCOMP] = nonlinear_to_linear(rgba[BCOMP]);
542 texel[ACOMP] = CHAN_TO_FLOAT(rgba[ACOMP]);
543 }
544
545 void
546 _mesa_fetch_texel_2d_f_srgba_dxt3(const struct gl_texture_image *texImage,
547 GLint i, GLint j, GLint k, GLfloat *texel)
548 {
549 /* just sample as GLchan and convert to float here */
550 GLchan rgba[4];
551 fetch_texel_2d_rgba_dxt3(texImage, i, j, k, rgba);
552 texel[RCOMP] = nonlinear_to_linear(rgba[RCOMP]);
553 texel[GCOMP] = nonlinear_to_linear(rgba[GCOMP]);
554 texel[BCOMP] = nonlinear_to_linear(rgba[BCOMP]);
555 texel[ACOMP] = CHAN_TO_FLOAT(rgba[ACOMP]);
556 }
557
558 void
559 _mesa_fetch_texel_2d_f_srgba_dxt5(const struct gl_texture_image *texImage,
560 GLint i, GLint j, GLint k, GLfloat *texel)
561 {
562 /* just sample as GLchan and convert to float here */
563 GLchan rgba[4];
564 fetch_texel_2d_rgba_dxt5(texImage, i, j, k, rgba);
565 texel[RCOMP] = nonlinear_to_linear(rgba[RCOMP]);
566 texel[GCOMP] = nonlinear_to_linear(rgba[GCOMP]);
567 texel[BCOMP] = nonlinear_to_linear(rgba[BCOMP]);
568 texel[ACOMP] = CHAN_TO_FLOAT(rgba[ACOMP]);
569 }
570 #endif /* FEATURE_EXT_texture_sRGB */
571
572
573 #endif /* FEATURE_texture_s3tc */