1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Mesa 3-D graphics library
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci * Copyright (C) 1999-2007  Brian Paul   All Rights Reserved.
5bf215546Sopenharmony_ci * Copyright (c) 2008 VMware, Inc.
6bf215546Sopenharmony_ci *
7bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
8bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
9bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
10bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
12bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
13bf215546Sopenharmony_ci *
14bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be included
15bf215546Sopenharmony_ci * in all copies or substantial portions of the Software.
16bf215546Sopenharmony_ci *
17bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
20bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21bf215546Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22bf215546Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23bf215546Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE.
24bf215546Sopenharmony_ci */
25bf215546Sopenharmony_ci
26bf215546Sopenharmony_ci
27bf215546Sopenharmony_ci/**
28bf215546Sopenharmony_ci * \file texcompress_s3tc.c
29bf215546Sopenharmony_ci * GL_EXT_texture_compression_s3tc support.
30bf215546Sopenharmony_ci */
31bf215546Sopenharmony_ci
32bf215546Sopenharmony_ci#include "glheader.h"
33bf215546Sopenharmony_ci
34bf215546Sopenharmony_ci#include "image.h"
35bf215546Sopenharmony_ci#include "macros.h"
36bf215546Sopenharmony_ci#include "mtypes.h"
37bf215546Sopenharmony_ci#include "texcompress.h"
38bf215546Sopenharmony_ci#include "texcompress_s3tc.h"
39bf215546Sopenharmony_ci#include "texcompress_s3tc_tmp.h"
40bf215546Sopenharmony_ci#include "texstore.h"
41bf215546Sopenharmony_ci#include "format_unpack.h"
42bf215546Sopenharmony_ci#include "util/format_srgb.h"
43bf215546Sopenharmony_ci
44bf215546Sopenharmony_ci
45bf215546Sopenharmony_ci/**
46bf215546Sopenharmony_ci * Store user's image in rgb_dxt1 format.
47bf215546Sopenharmony_ci */
48bf215546Sopenharmony_ciGLboolean
49bf215546Sopenharmony_ci_mesa_texstore_rgb_dxt1(TEXSTORE_PARAMS)
50bf215546Sopenharmony_ci{
51bf215546Sopenharmony_ci   const GLubyte *pixels;
52bf215546Sopenharmony_ci   GLubyte *dst;
53bf215546Sopenharmony_ci   const GLubyte *tempImage = NULL;
54bf215546Sopenharmony_ci   int srccomps = srcFormat == GL_RGB ? 3 : 4;
55bf215546Sopenharmony_ci
56bf215546Sopenharmony_ci   assert(dstFormat == MESA_FORMAT_RGB_DXT1 ||
57bf215546Sopenharmony_ci          dstFormat == MESA_FORMAT_SRGB_DXT1);
58bf215546Sopenharmony_ci
59bf215546Sopenharmony_ci   if (!(srcFormat == GL_RGB || srcFormat == GL_RGBA) ||
60bf215546Sopenharmony_ci       srcType != GL_UNSIGNED_BYTE ||
61bf215546Sopenharmony_ci       ctx->_ImageTransferState ||
62bf215546Sopenharmony_ci       _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType) != srccomps * srcWidth * sizeof(GLubyte) ||
63bf215546Sopenharmony_ci       srcPacking->SkipImages ||
64bf215546Sopenharmony_ci       srcPacking->SwapBytes) {
65bf215546Sopenharmony_ci      /* convert image to RGB/GLubyte */
66bf215546Sopenharmony_ci      GLubyte *tempImageSlices[1];
67bf215546Sopenharmony_ci      int rgbRowStride = 3 * srcWidth * sizeof(GLubyte);
68bf215546Sopenharmony_ci      tempImage = malloc(srcWidth * srcHeight * 3 * sizeof(GLubyte));
69bf215546Sopenharmony_ci      if (!tempImage)
70bf215546Sopenharmony_ci         return GL_FALSE; /* out of memory */
71bf215546Sopenharmony_ci      tempImageSlices[0] = (GLubyte *) tempImage;
72bf215546Sopenharmony_ci      _mesa_texstore(ctx, dims,
73bf215546Sopenharmony_ci                     baseInternalFormat,
74bf215546Sopenharmony_ci                     MESA_FORMAT_RGB_UNORM8,
75bf215546Sopenharmony_ci                     rgbRowStride, tempImageSlices,
76bf215546Sopenharmony_ci                     srcWidth, srcHeight, srcDepth,
77bf215546Sopenharmony_ci                     srcFormat, srcType, srcAddr,
78bf215546Sopenharmony_ci                     srcPacking);
79bf215546Sopenharmony_ci      pixels = tempImage;
80bf215546Sopenharmony_ci      srcFormat = GL_RGB;
81bf215546Sopenharmony_ci      srccomps = 3;
82bf215546Sopenharmony_ci   }
83bf215546Sopenharmony_ci   else {
84bf215546Sopenharmony_ci      pixels = _mesa_image_address2d(srcPacking, srcAddr, srcWidth, srcHeight,
85bf215546Sopenharmony_ci                                     srcFormat, srcType, 0, 0);
86bf215546Sopenharmony_ci   }
87bf215546Sopenharmony_ci
88bf215546Sopenharmony_ci   dst = dstSlices[0];
89bf215546Sopenharmony_ci
90bf215546Sopenharmony_ci   tx_compress_dxt1(srccomps, srcWidth, srcHeight, pixels,
91bf215546Sopenharmony_ci                    dst, dstRowStride, 3);
92bf215546Sopenharmony_ci
93bf215546Sopenharmony_ci   free((void *) tempImage);
94bf215546Sopenharmony_ci
95bf215546Sopenharmony_ci   return GL_TRUE;
96bf215546Sopenharmony_ci}
97bf215546Sopenharmony_ci
98bf215546Sopenharmony_ci
99bf215546Sopenharmony_ci/**
100bf215546Sopenharmony_ci * Store user's image in rgba_dxt1 format.
101bf215546Sopenharmony_ci */
102bf215546Sopenharmony_ciGLboolean
103bf215546Sopenharmony_ci_mesa_texstore_rgba_dxt1(TEXSTORE_PARAMS)
104bf215546Sopenharmony_ci{
105bf215546Sopenharmony_ci   const GLubyte *pixels;
106bf215546Sopenharmony_ci   GLubyte *dst;
107bf215546Sopenharmony_ci   const GLubyte *tempImage = NULL;
108bf215546Sopenharmony_ci   int rgbaRowStride = 4 * srcWidth * sizeof(GLubyte);
109bf215546Sopenharmony_ci
110bf215546Sopenharmony_ci   assert(dstFormat == MESA_FORMAT_RGBA_DXT1 ||
111bf215546Sopenharmony_ci          dstFormat == MESA_FORMAT_SRGBA_DXT1);
112bf215546Sopenharmony_ci
113bf215546Sopenharmony_ci   if (srcFormat != GL_RGBA ||
114bf215546Sopenharmony_ci       srcType != GL_UNSIGNED_BYTE ||
115bf215546Sopenharmony_ci       ctx->_ImageTransferState ||
116bf215546Sopenharmony_ci       _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType) != rgbaRowStride ||
117bf215546Sopenharmony_ci       srcPacking->SkipImages ||
118bf215546Sopenharmony_ci       srcPacking->SwapBytes) {
119bf215546Sopenharmony_ci      /* convert image to RGBA/GLubyte */
120bf215546Sopenharmony_ci      GLubyte *tempImageSlices[1];
121bf215546Sopenharmony_ci      tempImage = malloc(srcWidth * srcHeight * 4 * sizeof(GLubyte));
122bf215546Sopenharmony_ci      if (!tempImage)
123bf215546Sopenharmony_ci         return GL_FALSE; /* out of memory */
124bf215546Sopenharmony_ci      tempImageSlices[0] = (GLubyte *) tempImage;
125bf215546Sopenharmony_ci      _mesa_texstore(ctx, dims,
126bf215546Sopenharmony_ci                     baseInternalFormat,
127bf215546Sopenharmony_ci#if UTIL_ARCH_LITTLE_ENDIAN
128bf215546Sopenharmony_ci                     MESA_FORMAT_R8G8B8A8_UNORM,
129bf215546Sopenharmony_ci#else
130bf215546Sopenharmony_ci                     MESA_FORMAT_A8B8G8R8_UNORM,
131bf215546Sopenharmony_ci#endif
132bf215546Sopenharmony_ci                     rgbaRowStride, tempImageSlices,
133bf215546Sopenharmony_ci                     srcWidth, srcHeight, srcDepth,
134bf215546Sopenharmony_ci                     srcFormat, srcType, srcAddr,
135bf215546Sopenharmony_ci                     srcPacking);
136bf215546Sopenharmony_ci      pixels = tempImage;
137bf215546Sopenharmony_ci      srcFormat = GL_RGBA;
138bf215546Sopenharmony_ci   }
139bf215546Sopenharmony_ci   else {
140bf215546Sopenharmony_ci      pixels = _mesa_image_address2d(srcPacking, srcAddr, srcWidth, srcHeight,
141bf215546Sopenharmony_ci                                     srcFormat, srcType, 0, 0);
142bf215546Sopenharmony_ci   }
143bf215546Sopenharmony_ci
144bf215546Sopenharmony_ci   dst = dstSlices[0];
145bf215546Sopenharmony_ci
146bf215546Sopenharmony_ci   tx_compress_dxt1(4, srcWidth, srcHeight, pixels, dst, dstRowStride, 4);
147bf215546Sopenharmony_ci
148bf215546Sopenharmony_ci   free((void*) tempImage);
149bf215546Sopenharmony_ci
150bf215546Sopenharmony_ci   return GL_TRUE;
151bf215546Sopenharmony_ci}
152bf215546Sopenharmony_ci
153bf215546Sopenharmony_ci
154bf215546Sopenharmony_ci/**
155bf215546Sopenharmony_ci * Store user's image in rgba_dxt3 format.
156bf215546Sopenharmony_ci */
157bf215546Sopenharmony_ciGLboolean
158bf215546Sopenharmony_ci_mesa_texstore_rgba_dxt3(TEXSTORE_PARAMS)
159bf215546Sopenharmony_ci{
160bf215546Sopenharmony_ci   const GLubyte *pixels;
161bf215546Sopenharmony_ci   GLubyte *dst;
162bf215546Sopenharmony_ci   const GLubyte *tempImage = NULL;
163bf215546Sopenharmony_ci   int rgbaRowStride = 4 * srcWidth * sizeof(GLubyte);
164bf215546Sopenharmony_ci
165bf215546Sopenharmony_ci   assert(dstFormat == MESA_FORMAT_RGBA_DXT3 ||
166bf215546Sopenharmony_ci          dstFormat == MESA_FORMAT_SRGBA_DXT3);
167bf215546Sopenharmony_ci
168bf215546Sopenharmony_ci   if (srcFormat != GL_RGBA ||
169bf215546Sopenharmony_ci       srcType != GL_UNSIGNED_BYTE ||
170bf215546Sopenharmony_ci       ctx->_ImageTransferState ||
171bf215546Sopenharmony_ci       _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType) != rgbaRowStride ||
172bf215546Sopenharmony_ci       srcPacking->SkipImages ||
173bf215546Sopenharmony_ci       srcPacking->SwapBytes) {
174bf215546Sopenharmony_ci      /* convert image to RGBA/GLubyte */
175bf215546Sopenharmony_ci      GLubyte *tempImageSlices[1];
176bf215546Sopenharmony_ci      tempImage = malloc(srcWidth * srcHeight * 4 * sizeof(GLubyte));
177bf215546Sopenharmony_ci      if (!tempImage)
178bf215546Sopenharmony_ci         return GL_FALSE; /* out of memory */
179bf215546Sopenharmony_ci      tempImageSlices[0] = (GLubyte *) tempImage;
180bf215546Sopenharmony_ci      _mesa_texstore(ctx, dims,
181bf215546Sopenharmony_ci                     baseInternalFormat,
182bf215546Sopenharmony_ci#if UTIL_ARCH_LITTLE_ENDIAN
183bf215546Sopenharmony_ci                     MESA_FORMAT_R8G8B8A8_UNORM,
184bf215546Sopenharmony_ci#else
185bf215546Sopenharmony_ci                     MESA_FORMAT_A8B8G8R8_UNORM,
186bf215546Sopenharmony_ci#endif
187bf215546Sopenharmony_ci                     rgbaRowStride, tempImageSlices,
188bf215546Sopenharmony_ci                     srcWidth, srcHeight, srcDepth,
189bf215546Sopenharmony_ci                     srcFormat, srcType, srcAddr,
190bf215546Sopenharmony_ci                     srcPacking);
191bf215546Sopenharmony_ci      pixels = tempImage;
192bf215546Sopenharmony_ci   }
193bf215546Sopenharmony_ci   else {
194bf215546Sopenharmony_ci      pixels = _mesa_image_address2d(srcPacking, srcAddr, srcWidth, srcHeight,
195bf215546Sopenharmony_ci                                     srcFormat, srcType, 0, 0);
196bf215546Sopenharmony_ci   }
197bf215546Sopenharmony_ci
198bf215546Sopenharmony_ci   dst = dstSlices[0];
199bf215546Sopenharmony_ci
200bf215546Sopenharmony_ci   tx_compress_dxt3(4, srcWidth, srcHeight, pixels, dst, dstRowStride);
201bf215546Sopenharmony_ci
202bf215546Sopenharmony_ci   free((void *) tempImage);
203bf215546Sopenharmony_ci
204bf215546Sopenharmony_ci   return GL_TRUE;
205bf215546Sopenharmony_ci}
206bf215546Sopenharmony_ci
207bf215546Sopenharmony_ci
208bf215546Sopenharmony_ci/**
209bf215546Sopenharmony_ci * Store user's image in rgba_dxt5 format.
210bf215546Sopenharmony_ci */
211bf215546Sopenharmony_ciGLboolean
212bf215546Sopenharmony_ci_mesa_texstore_rgba_dxt5(TEXSTORE_PARAMS)
213bf215546Sopenharmony_ci{
214bf215546Sopenharmony_ci   const GLubyte *pixels;
215bf215546Sopenharmony_ci   GLubyte *dst;
216bf215546Sopenharmony_ci   const GLubyte *tempImage = NULL;
217bf215546Sopenharmony_ci   int rgbaRowStride = 4 * srcWidth * sizeof(GLubyte);
218bf215546Sopenharmony_ci
219bf215546Sopenharmony_ci   assert(dstFormat == MESA_FORMAT_RGBA_DXT5 ||
220bf215546Sopenharmony_ci          dstFormat == MESA_FORMAT_SRGBA_DXT5);
221bf215546Sopenharmony_ci
222bf215546Sopenharmony_ci   if (srcFormat != GL_RGBA ||
223bf215546Sopenharmony_ci       srcType != GL_UNSIGNED_BYTE ||
224bf215546Sopenharmony_ci       ctx->_ImageTransferState ||
225bf215546Sopenharmony_ci       _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType) != rgbaRowStride ||
226bf215546Sopenharmony_ci       srcPacking->SkipImages ||
227bf215546Sopenharmony_ci       srcPacking->SwapBytes) {
228bf215546Sopenharmony_ci      /* convert image to RGBA/GLubyte */
229bf215546Sopenharmony_ci      GLubyte *tempImageSlices[1];
230bf215546Sopenharmony_ci      tempImage = malloc(srcWidth * srcHeight * 4 * sizeof(GLubyte));
231bf215546Sopenharmony_ci      if (!tempImage)
232bf215546Sopenharmony_ci         return GL_FALSE; /* out of memory */
233bf215546Sopenharmony_ci      tempImageSlices[0] = (GLubyte *) tempImage;
234bf215546Sopenharmony_ci      _mesa_texstore(ctx, dims,
235bf215546Sopenharmony_ci                     baseInternalFormat,
236bf215546Sopenharmony_ci#if UTIL_ARCH_LITTLE_ENDIAN
237bf215546Sopenharmony_ci                     MESA_FORMAT_R8G8B8A8_UNORM,
238bf215546Sopenharmony_ci#else
239bf215546Sopenharmony_ci                     MESA_FORMAT_A8B8G8R8_UNORM,
240bf215546Sopenharmony_ci#endif
241bf215546Sopenharmony_ci                     rgbaRowStride, tempImageSlices,
242bf215546Sopenharmony_ci                     srcWidth, srcHeight, srcDepth,
243bf215546Sopenharmony_ci                     srcFormat, srcType, srcAddr,
244bf215546Sopenharmony_ci                     srcPacking);
245bf215546Sopenharmony_ci      pixels = tempImage;
246bf215546Sopenharmony_ci   }
247bf215546Sopenharmony_ci   else {
248bf215546Sopenharmony_ci      pixels = _mesa_image_address2d(srcPacking, srcAddr, srcWidth, srcHeight,
249bf215546Sopenharmony_ci                                     srcFormat, srcType, 0, 0);
250bf215546Sopenharmony_ci   }
251bf215546Sopenharmony_ci
252bf215546Sopenharmony_ci   dst = dstSlices[0];
253bf215546Sopenharmony_ci
254bf215546Sopenharmony_ci   tx_compress_dxt5(4, srcWidth, srcHeight, pixels, dst, dstRowStride);
255bf215546Sopenharmony_ci
256bf215546Sopenharmony_ci   free((void *) tempImage);
257bf215546Sopenharmony_ci
258bf215546Sopenharmony_ci   return GL_TRUE;
259bf215546Sopenharmony_ci}
260bf215546Sopenharmony_ci
261bf215546Sopenharmony_ci
262bf215546Sopenharmony_cistatic void
263bf215546Sopenharmony_cifetch_rgb_dxt1(const GLubyte *map,
264bf215546Sopenharmony_ci               GLint rowStride, GLint i, GLint j, GLfloat *texel)
265bf215546Sopenharmony_ci{
266bf215546Sopenharmony_ci   GLubyte tex[4];
267bf215546Sopenharmony_ci   fetch_2d_texel_rgb_dxt1(rowStride, map, i, j, tex);
268bf215546Sopenharmony_ci   texel[RCOMP] = UBYTE_TO_FLOAT(tex[RCOMP]);
269bf215546Sopenharmony_ci   texel[GCOMP] = UBYTE_TO_FLOAT(tex[GCOMP]);
270bf215546Sopenharmony_ci   texel[BCOMP] = UBYTE_TO_FLOAT(tex[BCOMP]);
271bf215546Sopenharmony_ci   texel[ACOMP] = UBYTE_TO_FLOAT(tex[ACOMP]);
272bf215546Sopenharmony_ci}
273bf215546Sopenharmony_ci
274bf215546Sopenharmony_cistatic void
275bf215546Sopenharmony_cifetch_rgba_dxt1(const GLubyte *map,
276bf215546Sopenharmony_ci                GLint rowStride, GLint i, GLint j, GLfloat *texel)
277bf215546Sopenharmony_ci{
278bf215546Sopenharmony_ci   GLubyte tex[4];
279bf215546Sopenharmony_ci   fetch_2d_texel_rgba_dxt1(rowStride, map, i, j, tex);
280bf215546Sopenharmony_ci   texel[RCOMP] = UBYTE_TO_FLOAT(tex[RCOMP]);
281bf215546Sopenharmony_ci   texel[GCOMP] = UBYTE_TO_FLOAT(tex[GCOMP]);
282bf215546Sopenharmony_ci   texel[BCOMP] = UBYTE_TO_FLOAT(tex[BCOMP]);
283bf215546Sopenharmony_ci   texel[ACOMP] = UBYTE_TO_FLOAT(tex[ACOMP]);
284bf215546Sopenharmony_ci}
285bf215546Sopenharmony_ci
286bf215546Sopenharmony_cistatic void
287bf215546Sopenharmony_cifetch_rgba_dxt3(const GLubyte *map,
288bf215546Sopenharmony_ci                GLint rowStride, GLint i, GLint j, GLfloat *texel)
289bf215546Sopenharmony_ci{
290bf215546Sopenharmony_ci   GLubyte tex[4];
291bf215546Sopenharmony_ci   fetch_2d_texel_rgba_dxt3(rowStride, map, i, j, tex);
292bf215546Sopenharmony_ci   texel[RCOMP] = UBYTE_TO_FLOAT(tex[RCOMP]);
293bf215546Sopenharmony_ci   texel[GCOMP] = UBYTE_TO_FLOAT(tex[GCOMP]);
294bf215546Sopenharmony_ci   texel[BCOMP] = UBYTE_TO_FLOAT(tex[BCOMP]);
295bf215546Sopenharmony_ci   texel[ACOMP] = UBYTE_TO_FLOAT(tex[ACOMP]);
296bf215546Sopenharmony_ci}
297bf215546Sopenharmony_ci
298bf215546Sopenharmony_cistatic void
299bf215546Sopenharmony_cifetch_rgba_dxt5(const GLubyte *map,
300bf215546Sopenharmony_ci                GLint rowStride, GLint i, GLint j, GLfloat *texel)
301bf215546Sopenharmony_ci{
302bf215546Sopenharmony_ci   GLubyte tex[4];
303bf215546Sopenharmony_ci   fetch_2d_texel_rgba_dxt5(rowStride, map, i, j, tex);
304bf215546Sopenharmony_ci   texel[RCOMP] = UBYTE_TO_FLOAT(tex[RCOMP]);
305bf215546Sopenharmony_ci   texel[GCOMP] = UBYTE_TO_FLOAT(tex[GCOMP]);
306bf215546Sopenharmony_ci   texel[BCOMP] = UBYTE_TO_FLOAT(tex[BCOMP]);
307bf215546Sopenharmony_ci   texel[ACOMP] = UBYTE_TO_FLOAT(tex[ACOMP]);
308bf215546Sopenharmony_ci}
309bf215546Sopenharmony_ci
310bf215546Sopenharmony_ci
311bf215546Sopenharmony_cistatic void
312bf215546Sopenharmony_cifetch_srgb_dxt1(const GLubyte *map,
313bf215546Sopenharmony_ci                GLint rowStride, GLint i, GLint j, GLfloat *texel)
314bf215546Sopenharmony_ci{
315bf215546Sopenharmony_ci   GLubyte tex[4];
316bf215546Sopenharmony_ci   fetch_2d_texel_rgb_dxt1(rowStride, map, i, j, tex);
317bf215546Sopenharmony_ci   texel[RCOMP] = util_format_srgb_8unorm_to_linear_float(tex[RCOMP]);
318bf215546Sopenharmony_ci   texel[GCOMP] = util_format_srgb_8unorm_to_linear_float(tex[GCOMP]);
319bf215546Sopenharmony_ci   texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(tex[BCOMP]);
320bf215546Sopenharmony_ci   texel[ACOMP] = UBYTE_TO_FLOAT(tex[ACOMP]);
321bf215546Sopenharmony_ci}
322bf215546Sopenharmony_ci
323bf215546Sopenharmony_cistatic void
324bf215546Sopenharmony_cifetch_srgba_dxt1(const GLubyte *map,
325bf215546Sopenharmony_ci                 GLint rowStride, GLint i, GLint j, GLfloat *texel)
326bf215546Sopenharmony_ci{
327bf215546Sopenharmony_ci   GLubyte tex[4];
328bf215546Sopenharmony_ci   fetch_2d_texel_rgba_dxt1(rowStride, map, i, j, tex);
329bf215546Sopenharmony_ci   texel[RCOMP] = util_format_srgb_8unorm_to_linear_float(tex[RCOMP]);
330bf215546Sopenharmony_ci   texel[GCOMP] = util_format_srgb_8unorm_to_linear_float(tex[GCOMP]);
331bf215546Sopenharmony_ci   texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(tex[BCOMP]);
332bf215546Sopenharmony_ci   texel[ACOMP] = UBYTE_TO_FLOAT(tex[ACOMP]);
333bf215546Sopenharmony_ci}
334bf215546Sopenharmony_ci
335bf215546Sopenharmony_cistatic void
336bf215546Sopenharmony_cifetch_srgba_dxt3(const GLubyte *map,
337bf215546Sopenharmony_ci                 GLint rowStride, GLint i, GLint j, GLfloat *texel)
338bf215546Sopenharmony_ci{
339bf215546Sopenharmony_ci   GLubyte tex[4];
340bf215546Sopenharmony_ci   fetch_2d_texel_rgba_dxt3(rowStride, map, i, j, tex);
341bf215546Sopenharmony_ci   texel[RCOMP] = util_format_srgb_8unorm_to_linear_float(tex[RCOMP]);
342bf215546Sopenharmony_ci   texel[GCOMP] = util_format_srgb_8unorm_to_linear_float(tex[GCOMP]);
343bf215546Sopenharmony_ci   texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(tex[BCOMP]);
344bf215546Sopenharmony_ci   texel[ACOMP] = UBYTE_TO_FLOAT(tex[ACOMP]);
345bf215546Sopenharmony_ci}
346bf215546Sopenharmony_ci
347bf215546Sopenharmony_cistatic void
348bf215546Sopenharmony_cifetch_srgba_dxt5(const GLubyte *map,
349bf215546Sopenharmony_ci                 GLint rowStride, GLint i, GLint j, GLfloat *texel)
350bf215546Sopenharmony_ci{
351bf215546Sopenharmony_ci   GLubyte tex[4];
352bf215546Sopenharmony_ci   fetch_2d_texel_rgba_dxt5(rowStride, map, i, j, tex);
353bf215546Sopenharmony_ci   texel[RCOMP] = util_format_srgb_8unorm_to_linear_float(tex[RCOMP]);
354bf215546Sopenharmony_ci   texel[GCOMP] = util_format_srgb_8unorm_to_linear_float(tex[GCOMP]);
355bf215546Sopenharmony_ci   texel[BCOMP] = util_format_srgb_8unorm_to_linear_float(tex[BCOMP]);
356bf215546Sopenharmony_ci   texel[ACOMP] = UBYTE_TO_FLOAT(tex[ACOMP]);
357bf215546Sopenharmony_ci}
358bf215546Sopenharmony_ci
359bf215546Sopenharmony_ci
360bf215546Sopenharmony_ci
361bf215546Sopenharmony_cicompressed_fetch_func
362bf215546Sopenharmony_ci_mesa_get_dxt_fetch_func(mesa_format format)
363bf215546Sopenharmony_ci{
364bf215546Sopenharmony_ci   switch (format) {
365bf215546Sopenharmony_ci   case MESA_FORMAT_RGB_DXT1:
366bf215546Sopenharmony_ci      return fetch_rgb_dxt1;
367bf215546Sopenharmony_ci   case MESA_FORMAT_RGBA_DXT1:
368bf215546Sopenharmony_ci      return fetch_rgba_dxt1;
369bf215546Sopenharmony_ci   case MESA_FORMAT_RGBA_DXT3:
370bf215546Sopenharmony_ci      return fetch_rgba_dxt3;
371bf215546Sopenharmony_ci   case MESA_FORMAT_RGBA_DXT5:
372bf215546Sopenharmony_ci      return fetch_rgba_dxt5;
373bf215546Sopenharmony_ci   case MESA_FORMAT_SRGB_DXT1:
374bf215546Sopenharmony_ci      return fetch_srgb_dxt1;
375bf215546Sopenharmony_ci   case MESA_FORMAT_SRGBA_DXT1:
376bf215546Sopenharmony_ci      return fetch_srgba_dxt1;
377bf215546Sopenharmony_ci   case MESA_FORMAT_SRGBA_DXT3:
378bf215546Sopenharmony_ci      return fetch_srgba_dxt3;
379bf215546Sopenharmony_ci   case MESA_FORMAT_SRGBA_DXT5:
380bf215546Sopenharmony_ci      return fetch_srgba_dxt5;
381bf215546Sopenharmony_ci   default:
382bf215546Sopenharmony_ci      return NULL;
383bf215546Sopenharmony_ci   }
384bf215546Sopenharmony_ci}
385