texcompress_s3tc.c revision 7117f1b4
1/*
2 * Mesa 3-D graphics library
3 * Version:  6.5.3
4 *
5 * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25
26/**
27 * \file texcompress_s3tc.c
28 * GL_EXT_texture_compression_s3tc support.
29 */
30
31#ifndef USE_EXTERNAL_DXTN_LIB
32#define USE_EXTERNAL_DXTN_LIB 0
33#endif
34
35#include "glheader.h"
36#include "imports.h"
37#include "colormac.h"
38#include "context.h"
39#include "convolve.h"
40#include "image.h"
41#include "texcompress.h"
42#include "texformat.h"
43#include "texstore.h"
44
45#if USE_EXTERNAL_DXTN_LIB && !defined(__MINGW32__)
46#include <dlfcn.h>
47#endif
48
49#ifdef __MINGW32__
50#define DXTN_LIBNAME "dxtn.dll"
51#define RTLD_LAZY 0
52#define RTLD_GLOBAL 0
53#elif defined(__DJGPP__)
54#define DXTN_LIBNAME "dxtn.dxe"
55#else
56#define DXTN_LIBNAME "libtxc_dxtn.so"
57#endif
58
59
60typedef void (*dxtFetchTexelFuncExt)( GLint srcRowstride, GLubyte *pixdata, GLint col, GLint row, GLvoid *texelOut );
61
62dxtFetchTexelFuncExt fetch_ext_rgb_dxt1 = NULL;
63dxtFetchTexelFuncExt fetch_ext_rgba_dxt1 = NULL;
64dxtFetchTexelFuncExt fetch_ext_rgba_dxt3 = NULL;
65dxtFetchTexelFuncExt fetch_ext_rgba_dxt5 = NULL;
66
67typedef void (*dxtCompressTexFuncExt)(GLint srccomps, GLint width,
68                                      GLint height, const GLchan *srcPixData,
69                                      GLenum destformat, GLubyte *dest,
70                                      GLint dstRowStride);
71
72static dxtCompressTexFuncExt ext_tx_compress_dxtn = NULL;
73
74static void *dxtlibhandle = NULL;
75
76
77typedef void (*GenericFunc)(void);
78
79
80/**
81 * Wrapper for dlopen().
82 * XXX Probably move this and the following wrappers into imports.h someday.
83 */
84static void *
85_mesa_dlopen(const char *libname, int flags)
86{
87#if USE_EXTERNAL_DXTN_LIB
88#ifdef __MINGW32__
89   return LoadLibrary(libname);
90#else
91   return dlopen(libname, flags);
92#endif
93#else
94   return NULL;
95#endif /* USE_EXTERNAL_DXTN_LIB */
96}
97
98
99/**
100 * Wrapper for dlsym() that does a cast to a generic function type,
101 * rather than a void *.  This reduces the number of warnings that are
102 * generated.
103 */
104static GenericFunc
105_mesa_dlsym(void *handle, const char *fname)
106{
107#if USE_EXTERNAL_DXTN_LIB
108#ifdef __MINGW32__
109   return (GenericFunc) GetProcAddress(handle, fname);
110#elif defined(__DJGPP__)
111   /* need '_' prefix on symbol names */
112   char fname2[1000];
113   fname2[0] = '_';
114   _mesa_strncpy(fname2 + 1, fname, 998);
115   fname2[999] = 0;
116   return (GenericFunc) dlsym(handle, fname2);
117#else
118   return (GenericFunc) dlsym(handle, fname);
119#endif
120#else
121   return (GenericFunc) NULL;
122#endif /* USE_EXTERNAL_DXTN_LIB */
123}
124
125
126/**
127 * Wrapper for dlclose().
128 */
129static void
130_mesa_dlclose(void *handle)
131{
132#if USE_EXTERNAL_DXTN_LIB
133#ifdef __MINGW32__
134   FreeLibrary(handle);
135#else
136   dlclose(handle);
137#endif
138#endif
139}
140
141
142
143void
144_mesa_init_texture_s3tc( GLcontext *ctx )
145{
146   /* called during context initialization */
147   ctx->Mesa_DXTn = GL_FALSE;
148#if USE_EXTERNAL_DXTN_LIB
149   if (!dxtlibhandle) {
150      dxtlibhandle = _mesa_dlopen(DXTN_LIBNAME, RTLD_LAZY | RTLD_GLOBAL);
151      if (!dxtlibhandle) {
152	 _mesa_warning(ctx, "couldn't open " DXTN_LIBNAME ", software DXTn "
153	    "compression/decompression unavailable");
154      }
155      else {
156         /* the fetch functions are not per context! Might be problematic... */
157         fetch_ext_rgb_dxt1 = (dxtFetchTexelFuncExt)
158            _mesa_dlsym(dxtlibhandle, "fetch_2d_texel_rgb_dxt1");
159         fetch_ext_rgba_dxt1 = (dxtFetchTexelFuncExt)
160            _mesa_dlsym(dxtlibhandle, "fetch_2d_texel_rgba_dxt1");
161         fetch_ext_rgba_dxt3 = (dxtFetchTexelFuncExt)
162            _mesa_dlsym(dxtlibhandle, "fetch_2d_texel_rgba_dxt3");
163         fetch_ext_rgba_dxt5 = (dxtFetchTexelFuncExt)
164            _mesa_dlsym(dxtlibhandle, "fetch_2d_texel_rgba_dxt5");
165         ext_tx_compress_dxtn = (dxtCompressTexFuncExt)
166            _mesa_dlsym(dxtlibhandle, "tx_compress_dxtn");
167
168         if (!fetch_ext_rgb_dxt1 ||
169             !fetch_ext_rgba_dxt1 ||
170             !fetch_ext_rgba_dxt3 ||
171             !fetch_ext_rgba_dxt5 ||
172             !ext_tx_compress_dxtn) {
173	    _mesa_warning(ctx, "couldn't reference all symbols in "
174	       DXTN_LIBNAME ", software DXTn compression/decompression "
175	       "unavailable");
176            fetch_ext_rgb_dxt1 = NULL;
177            fetch_ext_rgba_dxt1 = NULL;
178            fetch_ext_rgba_dxt3 = NULL;
179            fetch_ext_rgba_dxt5 = NULL;
180            ext_tx_compress_dxtn = NULL;
181            _mesa_dlclose(dxtlibhandle);
182            dxtlibhandle = NULL;
183         }
184      }
185   }
186   if (dxtlibhandle) {
187      ctx->Mesa_DXTn = GL_TRUE;
188      _mesa_warning(ctx, "software DXTn compression/decompression available");
189   }
190#else
191   (void) ctx;
192#endif
193}
194
195/**
196 * Called via TexFormat->StoreImage to store an RGB_DXT1 texture.
197 */
198static GLboolean
199texstore_rgb_dxt1(TEXSTORE_PARAMS)
200{
201   const GLchan *pixels;
202   GLint srcRowStride;
203   GLubyte *dst;
204   const GLint texWidth = dstRowStride * 4 / 8; /* a bit of a hack */
205   const GLchan *tempImage = NULL;
206
207   ASSERT(dstFormat == &_mesa_texformat_rgb_dxt1);
208   ASSERT(dstXoffset % 4 == 0);
209   ASSERT(dstYoffset % 4 == 0);
210   ASSERT(dstZoffset % 4 == 0);
211   (void) dstZoffset;
212   (void) dstImageOffsets;
213
214   if (srcFormat != GL_RGB ||
215       srcType != CHAN_TYPE ||
216       ctx->_ImageTransferState ||
217       srcPacking->SwapBytes) {
218      /* convert image to RGB/GLchan */
219      tempImage = _mesa_make_temp_chan_image(ctx, dims,
220                                             baseInternalFormat,
221                                             dstFormat->BaseFormat,
222                                             srcWidth, srcHeight, srcDepth,
223                                             srcFormat, srcType, srcAddr,
224                                             srcPacking);
225      if (!tempImage)
226         return GL_FALSE; /* out of memory */
227      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
228      pixels = tempImage;
229      srcRowStride = 3 * srcWidth;
230      srcFormat = GL_RGB;
231   }
232   else {
233      pixels = (const GLchan *) srcAddr;
234      srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat,
235                                            srcType) / sizeof(GLchan);
236   }
237
238   dst = _mesa_compressed_image_address(dstXoffset, dstYoffset, 0,
239                                        dstFormat->MesaFormat,
240                                        texWidth, (GLubyte *) dstAddr);
241
242   if (ext_tx_compress_dxtn) {
243      (*ext_tx_compress_dxtn)(3, srcWidth, srcHeight, pixels,
244                              GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
245                              dst, dstRowStride);
246   }
247   else {
248      _mesa_warning(ctx, "external dxt library not available");
249   }
250
251   if (tempImage)
252      _mesa_free((void *) tempImage);
253
254   return GL_TRUE;
255}
256
257
258/**
259 * Called via TexFormat->StoreImage to store an RGBA_DXT1 texture.
260 */
261static GLboolean
262texstore_rgba_dxt1(TEXSTORE_PARAMS)
263{
264   const GLchan *pixels;
265   GLint srcRowStride;
266   GLubyte *dst;
267   const GLint texWidth = dstRowStride * 4 / 8; /* a bit of a hack */
268   const GLchan *tempImage = NULL;
269
270   ASSERT(dstFormat == &_mesa_texformat_rgba_dxt1);
271   ASSERT(dstXoffset % 4 == 0);
272   ASSERT(dstYoffset % 4 == 0);
273   ASSERT(dstZoffset % 4 == 0);
274   (void) dstZoffset;
275   (void) dstImageOffsets;
276
277   if (srcFormat != GL_RGBA ||
278       srcType != CHAN_TYPE ||
279       ctx->_ImageTransferState ||
280       srcPacking->SwapBytes) {
281      /* convert image to RGBA/GLchan */
282      tempImage = _mesa_make_temp_chan_image(ctx, dims,
283                                             baseInternalFormat,
284                                             dstFormat->BaseFormat,
285                                             srcWidth, srcHeight, srcDepth,
286                                             srcFormat, srcType, srcAddr,
287                                             srcPacking);
288      if (!tempImage)
289         return GL_FALSE; /* out of memory */
290      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
291      pixels = tempImage;
292      srcRowStride = 4 * srcWidth;
293      srcFormat = GL_RGBA;
294   }
295   else {
296      pixels = (const GLchan *) srcAddr;
297      srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat,
298                                            srcType) / sizeof(GLchan);
299   }
300
301   dst = _mesa_compressed_image_address(dstXoffset, dstYoffset, 0,
302                                        dstFormat->MesaFormat,
303                                        texWidth, (GLubyte *) dstAddr);
304   if (ext_tx_compress_dxtn) {
305      (*ext_tx_compress_dxtn)(4, srcWidth, srcHeight, pixels,
306                              GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
307                              dst, dstRowStride);
308   }
309   else {
310      _mesa_warning(ctx, "external dxt library not available");
311   }
312
313   if (tempImage)
314      _mesa_free((void*) tempImage);
315
316   return GL_TRUE;
317}
318
319
320/**
321 * Called via TexFormat->StoreImage to store an RGBA_DXT3 texture.
322 */
323static GLboolean
324texstore_rgba_dxt3(TEXSTORE_PARAMS)
325{
326   const GLchan *pixels;
327   GLint srcRowStride;
328   GLubyte *dst;
329   const GLint texWidth = dstRowStride * 4 / 16; /* a bit of a hack */
330   const GLchan *tempImage = NULL;
331
332   ASSERT(dstFormat == &_mesa_texformat_rgba_dxt3);
333   ASSERT(dstXoffset % 4 == 0);
334   ASSERT(dstYoffset % 4 == 0);
335   ASSERT(dstZoffset % 4 == 0);
336   (void) dstZoffset;
337   (void) dstImageOffsets;
338
339   if (srcFormat != GL_RGBA ||
340       srcType != CHAN_TYPE ||
341       ctx->_ImageTransferState ||
342       srcPacking->SwapBytes) {
343      /* convert image to RGBA/GLchan */
344      tempImage = _mesa_make_temp_chan_image(ctx, dims,
345                                             baseInternalFormat,
346                                             dstFormat->BaseFormat,
347                                             srcWidth, srcHeight, srcDepth,
348                                             srcFormat, srcType, srcAddr,
349                                             srcPacking);
350      if (!tempImage)
351         return GL_FALSE; /* out of memory */
352      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
353      pixels = tempImage;
354      srcRowStride = 4 * srcWidth;
355   }
356   else {
357      pixels = (const GLchan *) srcAddr;
358      srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat,
359                                            srcType) / sizeof(GLchan);
360   }
361
362   dst = _mesa_compressed_image_address(dstXoffset, dstYoffset, 0,
363                                        dstFormat->MesaFormat,
364                                        texWidth, (GLubyte *) dstAddr);
365   if (ext_tx_compress_dxtn) {
366      (*ext_tx_compress_dxtn)(4, srcWidth, srcHeight, pixels,
367                              GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
368                              dst, dstRowStride);
369   }
370   else {
371      _mesa_warning(ctx, "external dxt library not available");
372   }
373
374   if (tempImage)
375      _mesa_free((void *) tempImage);
376
377   return GL_TRUE;
378}
379
380
381/**
382 * Called via TexFormat->StoreImage to store an RGBA_DXT5 texture.
383 */
384static GLboolean
385texstore_rgba_dxt5(TEXSTORE_PARAMS)
386{
387   const GLchan *pixels;
388   GLint srcRowStride;
389   GLubyte *dst;
390   const GLint texWidth = dstRowStride * 4 / 16; /* a bit of a hack */
391   const GLchan *tempImage = NULL;
392
393   ASSERT(dstFormat == &_mesa_texformat_rgba_dxt5);
394   ASSERT(dstXoffset % 4 == 0);
395   ASSERT(dstYoffset % 4 == 0);
396   ASSERT(dstZoffset % 4 == 0);
397   (void) dstZoffset;
398   (void) dstImageOffsets;
399
400   if (srcFormat != GL_RGBA ||
401       srcType != CHAN_TYPE ||
402       ctx->_ImageTransferState ||
403       srcPacking->SwapBytes) {
404      /* convert image to RGBA/GLchan */
405      tempImage = _mesa_make_temp_chan_image(ctx, dims,
406                                             baseInternalFormat,
407                                             dstFormat->BaseFormat,
408                                             srcWidth, srcHeight, srcDepth,
409                                             srcFormat, srcType, srcAddr,
410                                             srcPacking);
411      if (!tempImage)
412         return GL_FALSE; /* out of memory */
413      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
414      pixels = tempImage;
415      srcRowStride = 4 * srcWidth;
416   }
417   else {
418      pixels = (const GLchan *) srcAddr;
419      srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat,
420                                            srcType) / sizeof(GLchan);
421   }
422
423   dst = _mesa_compressed_image_address(dstXoffset, dstYoffset, 0,
424                                        dstFormat->MesaFormat,
425                                        texWidth, (GLubyte *) dstAddr);
426   if (ext_tx_compress_dxtn) {
427      (*ext_tx_compress_dxtn)(4, srcWidth, srcHeight, pixels,
428                              GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,
429                              dst, dstRowStride);
430   }
431   else {
432      _mesa_warning(ctx, "external dxt library not available");
433   }
434
435   if (tempImage)
436      _mesa_free((void *) tempImage);
437
438   return GL_TRUE;
439}
440
441
442static void
443fetch_texel_2d_rgb_dxt1( const struct gl_texture_image *texImage,
444                         GLint i, GLint j, GLint k, GLchan *texel )
445{
446   (void) k;
447   if (fetch_ext_rgb_dxt1) {
448      ASSERT (sizeof(GLchan) == sizeof(GLubyte));
449      fetch_ext_rgb_dxt1(texImage->RowStride,
450                         (GLubyte *)(texImage)->Data, i, j, texel);
451   }
452   else
453      _mesa_debug(NULL, "attempted to decode s3tc texture without library available\n");
454}
455
456
457static void
458fetch_texel_2d_f_rgb_dxt1( const struct gl_texture_image *texImage,
459                            GLint i, GLint j, GLint k, GLfloat *texel )
460{
461   /* just sample as GLchan and convert to float here */
462   GLchan rgba[4];
463   fetch_texel_2d_rgb_dxt1(texImage, i, j, k, rgba);
464   texel[RCOMP] = CHAN_TO_FLOAT(rgba[RCOMP]);
465   texel[GCOMP] = CHAN_TO_FLOAT(rgba[GCOMP]);
466   texel[BCOMP] = CHAN_TO_FLOAT(rgba[BCOMP]);
467   texel[ACOMP] = CHAN_TO_FLOAT(rgba[ACOMP]);
468}
469
470
471static void
472fetch_texel_2d_rgba_dxt1( const struct gl_texture_image *texImage,
473                          GLint i, GLint j, GLint k, GLchan *texel )
474{
475   (void) k;
476   if (fetch_ext_rgba_dxt1) {
477      fetch_ext_rgba_dxt1(texImage->RowStride,
478                          (GLubyte *)(texImage)->Data, i, j, texel);
479   }
480   else
481      _mesa_debug(NULL, "attempted to decode s3tc texture without library available\n");
482}
483
484
485static void
486fetch_texel_2d_f_rgba_dxt1( const struct gl_texture_image *texImage,
487                            GLint i, GLint j, GLint k, GLfloat *texel )
488{
489   /* just sample as GLchan and convert to float here */
490   GLchan rgba[4];
491   fetch_texel_2d_rgba_dxt1(texImage, i, j, k, rgba);
492   texel[RCOMP] = CHAN_TO_FLOAT(rgba[RCOMP]);
493   texel[GCOMP] = CHAN_TO_FLOAT(rgba[GCOMP]);
494   texel[BCOMP] = CHAN_TO_FLOAT(rgba[BCOMP]);
495   texel[ACOMP] = CHAN_TO_FLOAT(rgba[ACOMP]);
496}
497
498
499static void
500fetch_texel_2d_rgba_dxt3( const struct gl_texture_image *texImage,
501                          GLint i, GLint j, GLint k, GLchan *texel )
502{
503   (void) k;
504   if (fetch_ext_rgba_dxt3) {
505      ASSERT (sizeof(GLchan) == sizeof(GLubyte));
506      fetch_ext_rgba_dxt3(texImage->RowStride, (GLubyte *)(texImage)->Data,
507                          i, j, texel);
508   }
509   else
510      _mesa_debug(NULL, "attempted to decode s3tc texture without library available\n");
511}
512
513
514static void
515fetch_texel_2d_f_rgba_dxt3( 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_dxt3(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
528static void
529fetch_texel_2d_rgba_dxt5( const struct gl_texture_image *texImage,
530                          GLint i, GLint j, GLint k, GLchan *texel )
531{
532   (void) k;
533   if (fetch_ext_rgba_dxt5) {
534      fetch_ext_rgba_dxt5(texImage->RowStride, (GLubyte *)(texImage)->Data,
535                          i, j, texel);
536   }
537   else
538      _mesa_debug(NULL, "attempted to decode s3tc texture without library available\n");
539}
540
541
542static void
543fetch_texel_2d_f_rgba_dxt5( const struct gl_texture_image *texImage,
544                            GLint i, GLint j, GLint k, GLfloat *texel )
545{
546   /* just sample as GLchan and convert to float here */
547   GLchan rgba[4];
548   fetch_texel_2d_rgba_dxt5(texImage, i, j, k, rgba);
549   texel[RCOMP] = CHAN_TO_FLOAT(rgba[RCOMP]);
550   texel[GCOMP] = CHAN_TO_FLOAT(rgba[GCOMP]);
551   texel[BCOMP] = CHAN_TO_FLOAT(rgba[BCOMP]);
552   texel[ACOMP] = CHAN_TO_FLOAT(rgba[ACOMP]);
553}
554
555
556const struct gl_texture_format _mesa_texformat_rgb_dxt1 = {
557   MESA_FORMAT_RGB_DXT1,		/* MesaFormat */
558   GL_RGB,				/* BaseFormat */
559   GL_UNSIGNED_NORMALIZED_ARB,		/* DataType */
560   4, /*approx*/			/* RedBits */
561   4, /*approx*/			/* GreenBits */
562   4, /*approx*/			/* BlueBits */
563   0,					/* AlphaBits */
564   0,					/* LuminanceBits */
565   0,					/* IntensityBits */
566   0,					/* IndexBits */
567   0,					/* DepthBits */
568   0,					/* StencilBits */
569   0,					/* TexelBytes */
570   texstore_rgb_dxt1,			/* StoreTexImageFunc */
571   NULL, /*impossible*/ 		/* FetchTexel1D */
572   fetch_texel_2d_rgb_dxt1, 		/* FetchTexel2D */
573   NULL, /*impossible*/ 		/* FetchTexel3D */
574   NULL, /*impossible*/ 		/* FetchTexel1Df */
575   fetch_texel_2d_f_rgb_dxt1, 		/* FetchTexel2Df */
576   NULL, /*impossible*/ 		/* FetchTexel3Df */
577   NULL					/* StoreTexel */
578};
579
580const struct gl_texture_format _mesa_texformat_rgba_dxt1 = {
581   MESA_FORMAT_RGBA_DXT1,		/* MesaFormat */
582   GL_RGBA,				/* BaseFormat */
583   GL_UNSIGNED_NORMALIZED_ARB,		/* DataType */
584   4, /*approx*/			/* RedBits */
585   4, /*approx*/			/* GreenBits */
586   4, /*approx*/			/* BlueBits */
587   1, /*approx*/			/* AlphaBits */
588   0,					/* LuminanceBits */
589   0,					/* IntensityBits */
590   0,					/* IndexBits */
591   0,					/* DepthBits */
592   0,					/* StencilBits */
593   0,					/* TexelBytes */
594   texstore_rgba_dxt1,			/* StoreTexImageFunc */
595   NULL, /*impossible*/ 		/* FetchTexel1D */
596   fetch_texel_2d_rgba_dxt1, 		/* FetchTexel2D */
597   NULL, /*impossible*/ 		/* FetchTexel3D */
598   NULL, /*impossible*/ 		/* FetchTexel1Df */
599   fetch_texel_2d_f_rgba_dxt1, 		/* FetchTexel2Df */
600   NULL, /*impossible*/ 		/* FetchTexel3Df */
601   NULL					/* StoreTexel */
602};
603
604const struct gl_texture_format _mesa_texformat_rgba_dxt3 = {
605   MESA_FORMAT_RGBA_DXT3,		/* MesaFormat */
606   GL_RGBA,				/* BaseFormat */
607   GL_UNSIGNED_NORMALIZED_ARB,		/* DataType */
608   4, /*approx*/			/* RedBits */
609   4, /*approx*/			/* GreenBits */
610   4, /*approx*/			/* BlueBits */
611   4, /*approx*/			/* AlphaBits */
612   0,					/* LuminanceBits */
613   0,					/* IntensityBits */
614   0,					/* IndexBits */
615   0,					/* DepthBits */
616   0,					/* StencilBits */
617   0,					/* TexelBytes */
618   texstore_rgba_dxt3,			/* StoreTexImageFunc */
619   NULL, /*impossible*/ 		/* FetchTexel1D */
620   fetch_texel_2d_rgba_dxt3, 		/* FetchTexel2D */
621   NULL, /*impossible*/ 		/* FetchTexel3D */
622   NULL, /*impossible*/ 		/* FetchTexel1Df */
623   fetch_texel_2d_f_rgba_dxt3, 		/* FetchTexel2Df */
624   NULL, /*impossible*/ 		/* FetchTexel3Df */
625   NULL					/* StoreTexel */
626};
627
628const struct gl_texture_format _mesa_texformat_rgba_dxt5 = {
629   MESA_FORMAT_RGBA_DXT5,		/* MesaFormat */
630   GL_RGBA,				/* BaseFormat */
631   GL_UNSIGNED_NORMALIZED_ARB,		/* DataType */
632   4,/*approx*/				/* RedBits */
633   4,/*approx*/				/* GreenBits */
634   4,/*approx*/				/* BlueBits */
635   4,/*approx*/				/* AlphaBits */
636   0,					/* LuminanceBits */
637   0,					/* IntensityBits */
638   0,					/* IndexBits */
639   0,					/* DepthBits */
640   0,					/* StencilBits */
641   0,					/* TexelBytes */
642   texstore_rgba_dxt5,			/* StoreTexImageFunc */
643   NULL, /*impossible*/ 		/* FetchTexel1D */
644   fetch_texel_2d_rgba_dxt5, 		/* FetchTexel2D */
645   NULL, /*impossible*/ 		/* FetchTexel3D */
646   NULL, /*impossible*/ 		/* FetchTexel1Df */
647   fetch_texel_2d_f_rgba_dxt5, 		/* FetchTexel2Df */
648   NULL, /*impossible*/ 		/* FetchTexel3Df */
649   NULL					/* StoreTexel */
650};
651