mesa: fixes for srgb, new srgb formats
[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 0
34 #endif
35
36 #include "glheader.h"
37 #include "imports.h"
38 #include "colormac.h"
39 #include "context.h"
40 #include "convolve.h"
41 #include "image.h"
42 #include "texcompress.h"
43 #include "texformat.h"
44 #include "texstore.h"
45
46 #if USE_EXTERNAL_DXTN_LIB && !defined(__MINGW32__)
47 #include <dlfcn.h>
48 #endif
49
50 #ifdef __MINGW32__
51 #define DXTN_LIBNAME "dxtn.dll"
52 #define RTLD_LAZY 0
53 #define RTLD_GLOBAL 0
54 #elif defined(__DJGPP__)
55 #define DXTN_LIBNAME "dxtn.dxe"
56 #else
57 #define DXTN_LIBNAME "libtxc_dxtn.so"
58 #endif
59
60 #if FEATURE_EXT_texture_sRGB
61 /**
62 * Convert an 8-bit sRGB value from non-linear space to a
63 * linear RGB value in [0, 1].
64 * Implemented with a 256-entry lookup table.
65 */
66 static INLINE GLfloat
67 nonlinear_to_linear(GLubyte cs8)
68 {
69 static GLfloat table[256];
70 static GLboolean tableReady = GL_FALSE;
71 if (!tableReady) {
72 /* compute lookup table now */
73 GLuint i;
74 for (i = 0; i < 256; i++) {
75 const GLfloat cs = UBYTE_TO_FLOAT(i);
76 if (cs <= 0.04045) {
77 table[i] = cs / 12.92f;
78 }
79 else {
80 table[i] = (GLfloat) _mesa_pow((cs + 0.055) / 1.055, 2.4);
81 }
82 }
83 tableReady = GL_TRUE;
84 }
85 return table[cs8];
86 }
87 #endif /* FEATURE_EXT_texture_sRGB */
88
89 typedef void (*dxtFetchTexelFuncExt)( GLint srcRowstride, GLubyte *pixdata, GLint col, GLint row, GLvoid *texelOut );
90
91 dxtFetchTexelFuncExt fetch_ext_rgb_dxt1 = NULL;
92 dxtFetchTexelFuncExt fetch_ext_rgba_dxt1 = NULL;
93 dxtFetchTexelFuncExt fetch_ext_rgba_dxt3 = NULL;
94 dxtFetchTexelFuncExt fetch_ext_rgba_dxt5 = NULL;
95
96 typedef void (*dxtCompressTexFuncExt)(GLint srccomps, GLint width,
97 GLint height, const GLchan *srcPixData,
98 GLenum destformat, GLubyte *dest,
99 GLint dstRowStride);
100
101 static dxtCompressTexFuncExt ext_tx_compress_dxtn = NULL;
102
103 static void *dxtlibhandle = NULL;
104
105
106 typedef void (*GenericFunc)(void);
107
108
109 /**
110 * Wrapper for dlopen().
111 * XXX Probably move this and the following wrappers into imports.h someday.
112 */
113 static void *
114 _mesa_dlopen(const char *libname, int flags)
115 {
116 #if USE_EXTERNAL_DXTN_LIB
117 #ifdef __MINGW32__
118 return LoadLibrary(libname);
119 #else
120 return dlopen(libname, flags);
121 #endif
122 #else
123 return NULL;
124 #endif /* USE_EXTERNAL_DXTN_LIB */
125 }
126
127
128 /**
129 * Wrapper for dlsym() that does a cast to a generic function type,
130 * rather than a void *. This reduces the number of warnings that are
131 * generated.
132 */
133 static GenericFunc
134 _mesa_dlsym(void *handle, const char *fname)
135 {
136 #if USE_EXTERNAL_DXTN_LIB
137 #ifdef __MINGW32__
138 return (GenericFunc) GetProcAddress(handle, fname);
139 #elif defined(__DJGPP__)
140 /* need '_' prefix on symbol names */
141 char fname2[1000];
142 fname2[0] = '_';
143 _mesa_strncpy(fname2 + 1, fname, 998);
144 fname2[999] = 0;
145 return (GenericFunc) dlsym(handle, fname2);
146 #else
147 return (GenericFunc) dlsym(handle, fname);
148 #endif
149 #else
150 return (GenericFunc) NULL;
151 #endif /* USE_EXTERNAL_DXTN_LIB */
152 }
153
154
155 /**
156 * Wrapper for dlclose().
157 */
158 static void
159 _mesa_dlclose(void *handle)
160 {
161 #if USE_EXTERNAL_DXTN_LIB
162 #ifdef __MINGW32__
163 FreeLibrary(handle);
164 #else
165 dlclose(handle);
166 #endif
167 #endif
168 }
169
170
171
172 void
173 _mesa_init_texture_s3tc( GLcontext *ctx )
174 {
175 /* called during context initialization */
176 ctx->Mesa_DXTn = GL_FALSE;
177 #if USE_EXTERNAL_DXTN_LIB
178 if (!dxtlibhandle) {
179 dxtlibhandle = _mesa_dlopen(DXTN_LIBNAME, RTLD_LAZY | RTLD_GLOBAL);
180 if (!dxtlibhandle) {
181 _mesa_warning(ctx, "couldn't open " DXTN_LIBNAME ", software DXTn "
182 "compression/decompression unavailable");
183 }
184 else {
185 /* the fetch functions are not per context! Might be problematic... */
186 fetch_ext_rgb_dxt1 = (dxtFetchTexelFuncExt)
187 _mesa_dlsym(dxtlibhandle, "fetch_2d_texel_rgb_dxt1");
188 fetch_ext_rgba_dxt1 = (dxtFetchTexelFuncExt)
189 _mesa_dlsym(dxtlibhandle, "fetch_2d_texel_rgba_dxt1");
190 fetch_ext_rgba_dxt3 = (dxtFetchTexelFuncExt)
191 _mesa_dlsym(dxtlibhandle, "fetch_2d_texel_rgba_dxt3");
192 fetch_ext_rgba_dxt5 = (dxtFetchTexelFuncExt)
193 _mesa_dlsym(dxtlibhandle, "fetch_2d_texel_rgba_dxt5");
194 ext_tx_compress_dxtn = (dxtCompressTexFuncExt)
195 _mesa_dlsym(dxtlibhandle, "tx_compress_dxtn");
196
197 if (!fetch_ext_rgb_dxt1 ||
198 !fetch_ext_rgba_dxt1 ||
199 !fetch_ext_rgba_dxt3 ||
200 !fetch_ext_rgba_dxt5 ||
201 !ext_tx_compress_dxtn) {
202 _mesa_warning(ctx, "couldn't reference all symbols in "
203 DXTN_LIBNAME ", software DXTn compression/decompression "
204 "unavailable");
205 fetch_ext_rgb_dxt1 = NULL;
206 fetch_ext_rgba_dxt1 = NULL;
207 fetch_ext_rgba_dxt3 = NULL;
208 fetch_ext_rgba_dxt5 = NULL;
209 ext_tx_compress_dxtn = NULL;
210 _mesa_dlclose(dxtlibhandle);
211 dxtlibhandle = NULL;
212 }
213 }
214 }
215 if (dxtlibhandle) {
216 ctx->Mesa_DXTn = GL_TRUE;
217 _mesa_warning(ctx, "software DXTn compression/decompression available");
218 }
219 #else
220 (void) ctx;
221 #endif
222 }
223
224 /**
225 * Called via TexFormat->StoreImage to store an RGB_DXT1 texture.
226 */
227 static GLboolean
228 texstore_rgb_dxt1(TEXSTORE_PARAMS)
229 {
230 const GLchan *pixels;
231 GLint srcRowStride;
232 GLubyte *dst;
233 const GLint texWidth = dstRowStride * 4 / 8; /* a bit of a hack */
234 const GLchan *tempImage = NULL;
235
236 ASSERT(dstFormat == &_mesa_texformat_rgb_dxt1);
237 ASSERT(dstXoffset % 4 == 0);
238 ASSERT(dstYoffset % 4 == 0);
239 ASSERT(dstZoffset % 4 == 0);
240 (void) dstZoffset;
241 (void) dstImageOffsets;
242
243 if (srcFormat != GL_RGB ||
244 srcType != CHAN_TYPE ||
245 ctx->_ImageTransferState ||
246 srcPacking->SwapBytes) {
247 /* convert image to RGB/GLchan */
248 tempImage = _mesa_make_temp_chan_image(ctx, dims,
249 baseInternalFormat,
250 dstFormat->BaseFormat,
251 srcWidth, srcHeight, srcDepth,
252 srcFormat, srcType, srcAddr,
253 srcPacking);
254 if (!tempImage)
255 return GL_FALSE; /* out of memory */
256 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
257 pixels = tempImage;
258 srcRowStride = 3 * srcWidth;
259 srcFormat = GL_RGB;
260 }
261 else {
262 pixels = (const GLchan *) srcAddr;
263 srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat,
264 srcType) / sizeof(GLchan);
265 }
266
267 dst = _mesa_compressed_image_address(dstXoffset, dstYoffset, 0,
268 dstFormat->MesaFormat,
269 texWidth, (GLubyte *) dstAddr);
270
271 if (ext_tx_compress_dxtn) {
272 (*ext_tx_compress_dxtn)(3, srcWidth, srcHeight, pixels,
273 GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
274 dst, dstRowStride);
275 }
276 else {
277 _mesa_warning(ctx, "external dxt library not available");
278 }
279
280 if (tempImage)
281 _mesa_free((void *) tempImage);
282
283 return GL_TRUE;
284 }
285
286
287 /**
288 * Called via TexFormat->StoreImage to store an RGBA_DXT1 texture.
289 */
290 static GLboolean
291 texstore_rgba_dxt1(TEXSTORE_PARAMS)
292 {
293 const GLchan *pixels;
294 GLint srcRowStride;
295 GLubyte *dst;
296 const GLint texWidth = dstRowStride * 4 / 8; /* a bit of a hack */
297 const GLchan *tempImage = NULL;
298
299 ASSERT(dstFormat == &_mesa_texformat_rgba_dxt1);
300 ASSERT(dstXoffset % 4 == 0);
301 ASSERT(dstYoffset % 4 == 0);
302 ASSERT(dstZoffset % 4 == 0);
303 (void) dstZoffset;
304 (void) dstImageOffsets;
305
306 if (srcFormat != GL_RGBA ||
307 srcType != CHAN_TYPE ||
308 ctx->_ImageTransferState ||
309 srcPacking->SwapBytes) {
310 /* convert image to RGBA/GLchan */
311 tempImage = _mesa_make_temp_chan_image(ctx, dims,
312 baseInternalFormat,
313 dstFormat->BaseFormat,
314 srcWidth, srcHeight, srcDepth,
315 srcFormat, srcType, srcAddr,
316 srcPacking);
317 if (!tempImage)
318 return GL_FALSE; /* out of memory */
319 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
320 pixels = tempImage;
321 srcRowStride = 4 * srcWidth;
322 srcFormat = GL_RGBA;
323 }
324 else {
325 pixels = (const GLchan *) srcAddr;
326 srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat,
327 srcType) / sizeof(GLchan);
328 }
329
330 dst = _mesa_compressed_image_address(dstXoffset, dstYoffset, 0,
331 dstFormat->MesaFormat,
332 texWidth, (GLubyte *) dstAddr);
333 if (ext_tx_compress_dxtn) {
334 (*ext_tx_compress_dxtn)(4, srcWidth, srcHeight, pixels,
335 GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
336 dst, dstRowStride);
337 }
338 else {
339 _mesa_warning(ctx, "external dxt library not available");
340 }
341
342 if (tempImage)
343 _mesa_free((void*) tempImage);
344
345 return GL_TRUE;
346 }
347
348
349 /**
350 * Called via TexFormat->StoreImage to store an RGBA_DXT3 texture.
351 */
352 static GLboolean
353 texstore_rgba_dxt3(TEXSTORE_PARAMS)
354 {
355 const GLchan *pixels;
356 GLint srcRowStride;
357 GLubyte *dst;
358 const GLint texWidth = dstRowStride * 4 / 16; /* a bit of a hack */
359 const GLchan *tempImage = NULL;
360
361 ASSERT(dstFormat == &_mesa_texformat_rgba_dxt3);
362 ASSERT(dstXoffset % 4 == 0);
363 ASSERT(dstYoffset % 4 == 0);
364 ASSERT(dstZoffset % 4 == 0);
365 (void) dstZoffset;
366 (void) dstImageOffsets;
367
368 if (srcFormat != GL_RGBA ||
369 srcType != CHAN_TYPE ||
370 ctx->_ImageTransferState ||
371 srcPacking->SwapBytes) {
372 /* convert image to RGBA/GLchan */
373 tempImage = _mesa_make_temp_chan_image(ctx, dims,
374 baseInternalFormat,
375 dstFormat->BaseFormat,
376 srcWidth, srcHeight, srcDepth,
377 srcFormat, srcType, srcAddr,
378 srcPacking);
379 if (!tempImage)
380 return GL_FALSE; /* out of memory */
381 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
382 pixels = tempImage;
383 srcRowStride = 4 * srcWidth;
384 }
385 else {
386 pixels = (const GLchan *) srcAddr;
387 srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat,
388 srcType) / sizeof(GLchan);
389 }
390
391 dst = _mesa_compressed_image_address(dstXoffset, dstYoffset, 0,
392 dstFormat->MesaFormat,
393 texWidth, (GLubyte *) dstAddr);
394 if (ext_tx_compress_dxtn) {
395 (*ext_tx_compress_dxtn)(4, srcWidth, srcHeight, pixels,
396 GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
397 dst, dstRowStride);
398 }
399 else {
400 _mesa_warning(ctx, "external dxt library not available");
401 }
402
403 if (tempImage)
404 _mesa_free((void *) tempImage);
405
406 return GL_TRUE;
407 }
408
409
410 /**
411 * Called via TexFormat->StoreImage to store an RGBA_DXT5 texture.
412 */
413 static GLboolean
414 texstore_rgba_dxt5(TEXSTORE_PARAMS)
415 {
416 const GLchan *pixels;
417 GLint srcRowStride;
418 GLubyte *dst;
419 const GLint texWidth = dstRowStride * 4 / 16; /* a bit of a hack */
420 const GLchan *tempImage = NULL;
421
422 ASSERT(dstFormat == &_mesa_texformat_rgba_dxt5);
423 ASSERT(dstXoffset % 4 == 0);
424 ASSERT(dstYoffset % 4 == 0);
425 ASSERT(dstZoffset % 4 == 0);
426 (void) dstZoffset;
427 (void) dstImageOffsets;
428
429 if (srcFormat != GL_RGBA ||
430 srcType != CHAN_TYPE ||
431 ctx->_ImageTransferState ||
432 srcPacking->SwapBytes) {
433 /* convert image to RGBA/GLchan */
434 tempImage = _mesa_make_temp_chan_image(ctx, dims,
435 baseInternalFormat,
436 dstFormat->BaseFormat,
437 srcWidth, srcHeight, srcDepth,
438 srcFormat, srcType, srcAddr,
439 srcPacking);
440 if (!tempImage)
441 return GL_FALSE; /* out of memory */
442 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
443 pixels = tempImage;
444 srcRowStride = 4 * srcWidth;
445 }
446 else {
447 pixels = (const GLchan *) srcAddr;
448 srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat,
449 srcType) / sizeof(GLchan);
450 }
451
452 dst = _mesa_compressed_image_address(dstXoffset, dstYoffset, 0,
453 dstFormat->MesaFormat,
454 texWidth, (GLubyte *) dstAddr);
455 if (ext_tx_compress_dxtn) {
456 (*ext_tx_compress_dxtn)(4, srcWidth, srcHeight, pixels,
457 GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,
458 dst, dstRowStride);
459 }
460 else {
461 _mesa_warning(ctx, "external dxt library not available");
462 }
463
464 if (tempImage)
465 _mesa_free((void *) tempImage);
466
467 return GL_TRUE;
468 }
469
470
471 static void
472 fetch_texel_2d_rgb_dxt1( const struct gl_texture_image *texImage,
473 GLint i, GLint j, GLint k, GLchan *texel )
474 {
475 (void) k;
476 if (fetch_ext_rgb_dxt1) {
477 ASSERT (sizeof(GLchan) == sizeof(GLubyte));
478 fetch_ext_rgb_dxt1(texImage->RowStride,
479 (GLubyte *)(texImage)->Data, i, j, texel);
480 }
481 else
482 _mesa_debug(NULL, "attempted to decode s3tc texture without library available\n");
483 }
484
485
486 static void
487 fetch_texel_2d_f_rgb_dxt1( const struct gl_texture_image *texImage,
488 GLint i, GLint j, GLint k, GLfloat *texel )
489 {
490 /* just sample as GLchan and convert to float here */
491 GLchan rgba[4];
492 fetch_texel_2d_rgb_dxt1(texImage, i, j, k, rgba);
493 texel[RCOMP] = CHAN_TO_FLOAT(rgba[RCOMP]);
494 texel[GCOMP] = CHAN_TO_FLOAT(rgba[GCOMP]);
495 texel[BCOMP] = CHAN_TO_FLOAT(rgba[BCOMP]);
496 texel[ACOMP] = CHAN_TO_FLOAT(rgba[ACOMP]);
497 }
498
499
500 static void
501 fetch_texel_2d_rgba_dxt1( const struct gl_texture_image *texImage,
502 GLint i, GLint j, GLint k, GLchan *texel )
503 {
504 (void) k;
505 if (fetch_ext_rgba_dxt1) {
506 fetch_ext_rgba_dxt1(texImage->RowStride,
507 (GLubyte *)(texImage)->Data, i, j, texel);
508 }
509 else
510 _mesa_debug(NULL, "attempted to decode s3tc texture without library available\n");
511 }
512
513
514 static void
515 fetch_texel_2d_f_rgba_dxt1( const struct gl_texture_image *texImage,
516 GLint i, GLint j, GLint k, GLfloat *texel )
517 {
518 /* just sample as GLchan and convert to float here */
519 GLchan rgba[4];
520 fetch_texel_2d_rgba_dxt1(texImage, i, j, k, rgba);
521 texel[RCOMP] = CHAN_TO_FLOAT(rgba[RCOMP]);
522 texel[GCOMP] = CHAN_TO_FLOAT(rgba[GCOMP]);
523 texel[BCOMP] = CHAN_TO_FLOAT(rgba[BCOMP]);
524 texel[ACOMP] = CHAN_TO_FLOAT(rgba[ACOMP]);
525 }
526
527
528 static void
529 fetch_texel_2d_rgba_dxt3( const struct gl_texture_image *texImage,
530 GLint i, GLint j, GLint k, GLchan *texel )
531 {
532 (void) k;
533 if (fetch_ext_rgba_dxt3) {
534 ASSERT (sizeof(GLchan) == sizeof(GLubyte));
535 fetch_ext_rgba_dxt3(texImage->RowStride, (GLubyte *)(texImage)->Data,
536 i, j, texel);
537 }
538 else
539 _mesa_debug(NULL, "attempted to decode s3tc texture without library available\n");
540 }
541
542
543 static void
544 fetch_texel_2d_f_rgba_dxt3( const struct gl_texture_image *texImage,
545 GLint i, GLint j, GLint k, GLfloat *texel )
546 {
547 /* just sample as GLchan and convert to float here */
548 GLchan rgba[4];
549 fetch_texel_2d_rgba_dxt3(texImage, i, j, k, rgba);
550 texel[RCOMP] = CHAN_TO_FLOAT(rgba[RCOMP]);
551 texel[GCOMP] = CHAN_TO_FLOAT(rgba[GCOMP]);
552 texel[BCOMP] = CHAN_TO_FLOAT(rgba[BCOMP]);
553 texel[ACOMP] = CHAN_TO_FLOAT(rgba[ACOMP]);
554 }
555
556
557 static void
558 fetch_texel_2d_rgba_dxt5( const struct gl_texture_image *texImage,
559 GLint i, GLint j, GLint k, GLchan *texel )
560 {
561 (void) k;
562 if (fetch_ext_rgba_dxt5) {
563 fetch_ext_rgba_dxt5(texImage->RowStride, (GLubyte *)(texImage)->Data,
564 i, j, texel);
565 }
566 else
567 _mesa_debug(NULL, "attempted to decode s3tc texture without library available\n");
568 }
569
570
571 static void
572 fetch_texel_2d_f_rgba_dxt5( const struct gl_texture_image *texImage,
573 GLint i, GLint j, GLint k, GLfloat *texel )
574 {
575 /* just sample as GLchan and convert to float here */
576 GLchan rgba[4];
577 fetch_texel_2d_rgba_dxt5(texImage, i, j, k, rgba);
578 texel[RCOMP] = CHAN_TO_FLOAT(rgba[RCOMP]);
579 texel[GCOMP] = CHAN_TO_FLOAT(rgba[GCOMP]);
580 texel[BCOMP] = CHAN_TO_FLOAT(rgba[BCOMP]);
581 texel[ACOMP] = CHAN_TO_FLOAT(rgba[ACOMP]);
582 }
583
584 #if FEATURE_EXT_texture_sRGB
585 static void
586 fetch_texel_2d_f_srgb_dxt1( const struct gl_texture_image *texImage,
587 GLint i, GLint j, GLint k, GLfloat *texel )
588 {
589 /* just sample as GLchan and convert to float here */
590 GLchan rgba[4];
591 fetch_texel_2d_rgb_dxt1(texImage, i, j, k, rgba);
592 texel[RCOMP] = nonlinear_to_linear(rgba[RCOMP]);
593 texel[GCOMP] = nonlinear_to_linear(rgba[GCOMP]);
594 texel[BCOMP] = nonlinear_to_linear(rgba[BCOMP]);
595 texel[ACOMP] = CHAN_TO_FLOAT(rgba[ACOMP]);
596 }
597
598 static void
599 fetch_texel_2d_f_srgba_dxt1( const struct gl_texture_image *texImage,
600 GLint i, GLint j, GLint k, GLfloat *texel )
601 {
602 /* just sample as GLchan and convert to float here */
603 GLchan rgba[4];
604 fetch_texel_2d_rgba_dxt1(texImage, i, j, k, rgba);
605 texel[RCOMP] = nonlinear_to_linear(rgba[RCOMP]);
606 texel[GCOMP] = nonlinear_to_linear(rgba[GCOMP]);
607 texel[BCOMP] = nonlinear_to_linear(rgba[BCOMP]);
608 texel[ACOMP] = CHAN_TO_FLOAT(rgba[ACOMP]);
609 }
610
611 static void
612 fetch_texel_2d_f_srgba_dxt3( const struct gl_texture_image *texImage,
613 GLint i, GLint j, GLint k, GLfloat *texel )
614 {
615 /* just sample as GLchan and convert to float here */
616 GLchan rgba[4];
617 fetch_texel_2d_rgba_dxt3(texImage, i, j, k, rgba);
618 texel[RCOMP] = nonlinear_to_linear(rgba[RCOMP]);
619 texel[GCOMP] = nonlinear_to_linear(rgba[GCOMP]);
620 texel[BCOMP] = nonlinear_to_linear(rgba[BCOMP]);
621 texel[ACOMP] = CHAN_TO_FLOAT(rgba[ACOMP]);
622 }
623
624 static void
625 fetch_texel_2d_f_srgba_dxt5( const struct gl_texture_image *texImage,
626 GLint i, GLint j, GLint k, GLfloat *texel )
627 {
628 /* just sample as GLchan and convert to float here */
629 GLchan rgba[4];
630 fetch_texel_2d_rgba_dxt5(texImage, i, j, k, rgba);
631 texel[RCOMP] = nonlinear_to_linear(rgba[RCOMP]);
632 texel[GCOMP] = nonlinear_to_linear(rgba[GCOMP]);
633 texel[BCOMP] = nonlinear_to_linear(rgba[BCOMP]);
634 texel[ACOMP] = CHAN_TO_FLOAT(rgba[ACOMP]);
635 }
636 #endif
637
638 const struct gl_texture_format _mesa_texformat_rgb_dxt1 = {
639 MESA_FORMAT_RGB_DXT1, /* MesaFormat */
640 GL_RGB, /* BaseFormat */
641 GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
642 4, /*approx*/ /* RedBits */
643 4, /*approx*/ /* GreenBits */
644 4, /*approx*/ /* BlueBits */
645 0, /* AlphaBits */
646 0, /* LuminanceBits */
647 0, /* IntensityBits */
648 0, /* IndexBits */
649 0, /* DepthBits */
650 0, /* StencilBits */
651 0, /* TexelBytes */
652 texstore_rgb_dxt1, /* StoreTexImageFunc */
653 NULL, /*impossible*/ /* FetchTexel1D */
654 fetch_texel_2d_rgb_dxt1, /* FetchTexel2D */
655 NULL, /*impossible*/ /* FetchTexel3D */
656 NULL, /*impossible*/ /* FetchTexel1Df */
657 fetch_texel_2d_f_rgb_dxt1, /* FetchTexel2Df */
658 NULL, /*impossible*/ /* FetchTexel3Df */
659 NULL /* StoreTexel */
660 };
661
662 const struct gl_texture_format _mesa_texformat_rgba_dxt1 = {
663 MESA_FORMAT_RGBA_DXT1, /* MesaFormat */
664 GL_RGBA, /* BaseFormat */
665 GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
666 4, /*approx*/ /* RedBits */
667 4, /*approx*/ /* GreenBits */
668 4, /*approx*/ /* BlueBits */
669 1, /*approx*/ /* AlphaBits */
670 0, /* LuminanceBits */
671 0, /* IntensityBits */
672 0, /* IndexBits */
673 0, /* DepthBits */
674 0, /* StencilBits */
675 0, /* TexelBytes */
676 texstore_rgba_dxt1, /* StoreTexImageFunc */
677 NULL, /*impossible*/ /* FetchTexel1D */
678 fetch_texel_2d_rgba_dxt1, /* FetchTexel2D */
679 NULL, /*impossible*/ /* FetchTexel3D */
680 NULL, /*impossible*/ /* FetchTexel1Df */
681 fetch_texel_2d_f_rgba_dxt1, /* FetchTexel2Df */
682 NULL, /*impossible*/ /* FetchTexel3Df */
683 NULL /* StoreTexel */
684 };
685
686 const struct gl_texture_format _mesa_texformat_rgba_dxt3 = {
687 MESA_FORMAT_RGBA_DXT3, /* MesaFormat */
688 GL_RGBA, /* BaseFormat */
689 GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
690 4, /*approx*/ /* RedBits */
691 4, /*approx*/ /* GreenBits */
692 4, /*approx*/ /* BlueBits */
693 4, /*approx*/ /* AlphaBits */
694 0, /* LuminanceBits */
695 0, /* IntensityBits */
696 0, /* IndexBits */
697 0, /* DepthBits */
698 0, /* StencilBits */
699 0, /* TexelBytes */
700 texstore_rgba_dxt3, /* StoreTexImageFunc */
701 NULL, /*impossible*/ /* FetchTexel1D */
702 fetch_texel_2d_rgba_dxt3, /* FetchTexel2D */
703 NULL, /*impossible*/ /* FetchTexel3D */
704 NULL, /*impossible*/ /* FetchTexel1Df */
705 fetch_texel_2d_f_rgba_dxt3, /* FetchTexel2Df */
706 NULL, /*impossible*/ /* FetchTexel3Df */
707 NULL /* StoreTexel */
708 };
709
710 const struct gl_texture_format _mesa_texformat_rgba_dxt5 = {
711 MESA_FORMAT_RGBA_DXT5, /* MesaFormat */
712 GL_RGBA, /* BaseFormat */
713 GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
714 4,/*approx*/ /* RedBits */
715 4,/*approx*/ /* GreenBits */
716 4,/*approx*/ /* BlueBits */
717 4,/*approx*/ /* AlphaBits */
718 0, /* LuminanceBits */
719 0, /* IntensityBits */
720 0, /* IndexBits */
721 0, /* DepthBits */
722 0, /* StencilBits */
723 0, /* TexelBytes */
724 texstore_rgba_dxt5, /* StoreTexImageFunc */
725 NULL, /*impossible*/ /* FetchTexel1D */
726 fetch_texel_2d_rgba_dxt5, /* FetchTexel2D */
727 NULL, /*impossible*/ /* FetchTexel3D */
728 NULL, /*impossible*/ /* FetchTexel1Df */
729 fetch_texel_2d_f_rgba_dxt5, /* FetchTexel2Df */
730 NULL, /*impossible*/ /* FetchTexel3Df */
731 NULL /* StoreTexel */
732 };
733
734 #if FEATURE_EXT_texture_sRGB
735 const struct gl_texture_format _mesa_texformat_srgb_dxt1 = {
736 MESA_FORMAT_SRGB_DXT1, /* MesaFormat */
737 GL_RGB, /* BaseFormat */
738 GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
739 4, /*approx*/ /* RedBits */
740 4, /*approx*/ /* GreenBits */
741 4, /*approx*/ /* BlueBits */
742 0, /* AlphaBits */
743 0, /* LuminanceBits */
744 0, /* IntensityBits */
745 0, /* IndexBits */
746 0, /* DepthBits */
747 0, /* StencilBits */
748 0, /* TexelBytes */
749 texstore_rgb_dxt1, /* StoreTexImageFunc */
750 NULL, /*impossible*/ /* FetchTexel1D */
751 NULL, /* FetchTexel2D */
752 NULL, /*impossible*/ /* FetchTexel3D */
753 NULL, /*impossible*/ /* FetchTexel1Df */
754 fetch_texel_2d_f_srgb_dxt1, /* FetchTexel2Df */
755 NULL, /*impossible*/ /* FetchTexel3Df */
756 NULL /* StoreTexel */
757 };
758
759 const struct gl_texture_format _mesa_texformat_srgba_dxt1 = {
760 MESA_FORMAT_SRGBA_DXT1, /* MesaFormat */
761 GL_RGBA, /* BaseFormat */
762 GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
763 4, /*approx*/ /* RedBits */
764 4, /*approx*/ /* GreenBits */
765 4, /*approx*/ /* BlueBits */
766 1, /*approx*/ /* AlphaBits */
767 0, /* LuminanceBits */
768 0, /* IntensityBits */
769 0, /* IndexBits */
770 0, /* DepthBits */
771 0, /* StencilBits */
772 0, /* TexelBytes */
773 texstore_rgba_dxt1, /* StoreTexImageFunc */
774 NULL, /*impossible*/ /* FetchTexel1D */
775 NULL, /* FetchTexel2D */
776 NULL, /*impossible*/ /* FetchTexel3D */
777 NULL, /*impossible*/ /* FetchTexel1Df */
778 fetch_texel_2d_f_srgba_dxt1, /* FetchTexel2Df */
779 NULL, /*impossible*/ /* FetchTexel3Df */
780 NULL /* StoreTexel */
781 };
782
783 const struct gl_texture_format _mesa_texformat_srgba_dxt3 = {
784 MESA_FORMAT_SRGBA_DXT3, /* MesaFormat */
785 GL_RGBA, /* BaseFormat */
786 GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
787 4, /*approx*/ /* RedBits */
788 4, /*approx*/ /* GreenBits */
789 4, /*approx*/ /* BlueBits */
790 4, /*approx*/ /* AlphaBits */
791 0, /* LuminanceBits */
792 0, /* IntensityBits */
793 0, /* IndexBits */
794 0, /* DepthBits */
795 0, /* StencilBits */
796 0, /* TexelBytes */
797 texstore_rgba_dxt3, /* StoreTexImageFunc */
798 NULL, /*impossible*/ /* FetchTexel1D */
799 NULL, /* FetchTexel2D */
800 NULL, /*impossible*/ /* FetchTexel3D */
801 NULL, /*impossible*/ /* FetchTexel1Df */
802 fetch_texel_2d_f_srgba_dxt3, /* FetchTexel2Df */
803 NULL, /*impossible*/ /* FetchTexel3Df */
804 NULL /* StoreTexel */
805 };
806
807 const struct gl_texture_format _mesa_texformat_srgba_dxt5 = {
808 MESA_FORMAT_SRGBA_DXT5, /* MesaFormat */
809 GL_RGBA, /* BaseFormat */
810 GL_UNSIGNED_NORMALIZED_ARB, /* DataType */
811 4,/*approx*/ /* RedBits */
812 4,/*approx*/ /* GreenBits */
813 4,/*approx*/ /* BlueBits */
814 4,/*approx*/ /* AlphaBits */
815 0, /* LuminanceBits */
816 0, /* IntensityBits */
817 0, /* IndexBits */
818 0, /* DepthBits */
819 0, /* StencilBits */
820 0, /* TexelBytes */
821 texstore_rgba_dxt5, /* StoreTexImageFunc */
822 NULL, /*impossible*/ /* FetchTexel1D */
823 NULL, /* FetchTexel2D */
824 NULL, /*impossible*/ /* FetchTexel3D */
825 NULL, /*impossible*/ /* FetchTexel1Df */
826 fetch_texel_2d_f_srgba_dxt5, /* FetchTexel2Df */
827 NULL, /*impossible*/ /* FetchTexel3Df */
828 NULL /* StoreTexel */
829 };
830 #endif