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