1848b8605Smrg/*
2848b8605Smrg * Copyright (C) 2011 Red Hat Inc.
3848b8605Smrg *
4848b8605Smrg * block compression parts are:
5848b8605Smrg * Copyright (C) 2004  Roland Scheidegger   All Rights Reserved.
6848b8605Smrg *
7848b8605Smrg * Permission is hereby granted, free of charge, to any person obtaining a
8848b8605Smrg * copy of this software and associated documentation files (the "Software"),
9848b8605Smrg * to deal in the Software without restriction, including without limitation
10848b8605Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11848b8605Smrg * and/or sell copies of the Software, and to permit persons to whom the
12848b8605Smrg * Software is furnished to do so, subject to the following conditions:
13848b8605Smrg *
14848b8605Smrg * The above copyright notice and this permission notice (including the next
15848b8605Smrg * paragraph) shall be included in all copies or substantial portions of the
16848b8605Smrg * Software.
17848b8605Smrg *
18848b8605Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19848b8605Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20848b8605Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21848b8605Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22848b8605Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23848b8605Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24848b8605Smrg * DEALINGS IN THE SOFTWARE.
25848b8605Smrg *
26848b8605Smrg * Author:
27848b8605Smrg *    Dave Airlie
28848b8605Smrg */
29848b8605Smrg
30848b8605Smrg/**
31848b8605Smrg * \file texcompress_rgtc.c
32848b8605Smrg * GL_EXT_texture_compression_rgtc support.
33848b8605Smrg */
34848b8605Smrg
35848b8605Smrg
36b8e80941Smrg#include "config.h"
37848b8605Smrg#include "glheader.h"
38848b8605Smrg#include "imports.h"
39848b8605Smrg#include "image.h"
40848b8605Smrg#include "macros.h"
41848b8605Smrg#include "mipmap.h"
42848b8605Smrg#include "texcompress.h"
43b8e80941Smrg#include "util/rgtc.h"
44848b8605Smrg#include "texcompress_rgtc.h"
45848b8605Smrg#include "texstore.h"
46848b8605Smrg
47848b8605Smrgstatic void extractsrc_u( GLubyte srcpixels[4][4], const GLubyte *srcaddr,
48848b8605Smrg			  GLint srcRowStride, GLint numxpixels, GLint numypixels, GLint comps)
49848b8605Smrg{
50848b8605Smrg   GLubyte i, j;
51848b8605Smrg   const GLubyte *curaddr;
52848b8605Smrg   for (j = 0; j < numypixels; j++) {
53848b8605Smrg      curaddr = srcaddr + j * srcRowStride * comps;
54848b8605Smrg      for (i = 0; i < numxpixels; i++) {
55848b8605Smrg	 srcpixels[j][i] = *curaddr;
56848b8605Smrg	 curaddr += comps;
57848b8605Smrg      }
58848b8605Smrg   }
59848b8605Smrg}
60848b8605Smrg
61848b8605Smrgstatic void extractsrc_s( GLbyte srcpixels[4][4], const GLfloat *srcaddr,
62848b8605Smrg			  GLint srcRowStride, GLint numxpixels, GLint numypixels, GLint comps)
63848b8605Smrg{
64848b8605Smrg   GLubyte i, j;
65848b8605Smrg   const GLfloat *curaddr;
66848b8605Smrg   for (j = 0; j < numypixels; j++) {
67848b8605Smrg      curaddr = srcaddr + j * srcRowStride * comps;
68848b8605Smrg      for (i = 0; i < numxpixels; i++) {
69848b8605Smrg	 srcpixels[j][i] = FLOAT_TO_BYTE_TEX(*curaddr);
70848b8605Smrg	 curaddr += comps;
71848b8605Smrg      }
72848b8605Smrg   }
73848b8605Smrg}
74848b8605Smrg
75848b8605Smrg
76848b8605SmrgGLboolean
77848b8605Smrg_mesa_texstore_red_rgtc1(TEXSTORE_PARAMS)
78848b8605Smrg{
79848b8605Smrg   GLubyte *dst;
80848b8605Smrg   const GLubyte *tempImage = NULL;
81848b8605Smrg   int i, j;
82848b8605Smrg   int numxpixels, numypixels;
83848b8605Smrg   const GLubyte *srcaddr;
84848b8605Smrg   GLubyte srcpixels[4][4];
85848b8605Smrg   GLubyte *blkaddr;
86b8e80941Smrg   GLint dstRowDiff, redRowStride;
87b8e80941Smrg   GLubyte *tempImageSlices[1];
88b8e80941Smrg
89b8e80941Smrg   assert(dstFormat == MESA_FORMAT_R_RGTC1_UNORM ||
90848b8605Smrg          dstFormat == MESA_FORMAT_L_LATC1_UNORM);
91848b8605Smrg
92b8e80941Smrg   tempImage = malloc(srcWidth * srcHeight * 1 * sizeof(GLubyte));
93848b8605Smrg   if (!tempImage)
94848b8605Smrg      return GL_FALSE; /* out of memory */
95b8e80941Smrg   redRowStride = 1 * srcWidth * sizeof(GLubyte);
96b8e80941Smrg   tempImageSlices[0] = (GLubyte *) tempImage;
97b8e80941Smrg   _mesa_texstore(ctx, dims,
98b8e80941Smrg                  baseInternalFormat,
99b8e80941Smrg                  MESA_FORMAT_R_UNORM8,
100b8e80941Smrg                  redRowStride, tempImageSlices,
101b8e80941Smrg                  srcWidth, srcHeight, srcDepth,
102b8e80941Smrg                  srcFormat, srcType, srcAddr,
103b8e80941Smrg                  srcPacking);
104848b8605Smrg
105848b8605Smrg   dst = dstSlices[0];
106848b8605Smrg
107848b8605Smrg   blkaddr = dst;
108848b8605Smrg   dstRowDiff = dstRowStride >= (srcWidth * 2) ? dstRowStride - (((srcWidth + 3) & ~3) * 2) : 0;
109848b8605Smrg   for (j = 0; j < srcHeight; j+=4) {
110848b8605Smrg      if (srcHeight > j + 3) numypixels = 4;
111848b8605Smrg      else numypixels = srcHeight - j;
112848b8605Smrg      srcaddr = tempImage + j * srcWidth;
113848b8605Smrg      for (i = 0; i < srcWidth; i += 4) {
114848b8605Smrg	 if (srcWidth > i + 3) numxpixels = 4;
115848b8605Smrg	 else numxpixels = srcWidth - i;
116848b8605Smrg	 extractsrc_u(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 1);
117b8e80941Smrg	 util_format_unsigned_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
118848b8605Smrg	 srcaddr += numxpixels;
119848b8605Smrg	 blkaddr += 8;
120848b8605Smrg      }
121848b8605Smrg      blkaddr += dstRowDiff;
122848b8605Smrg   }
123848b8605Smrg
124848b8605Smrg   free((void *) tempImage);
125848b8605Smrg
126848b8605Smrg   return GL_TRUE;
127848b8605Smrg}
128848b8605Smrg
129848b8605SmrgGLboolean
130848b8605Smrg_mesa_texstore_signed_red_rgtc1(TEXSTORE_PARAMS)
131848b8605Smrg{
132848b8605Smrg   GLbyte *dst;
133848b8605Smrg   const GLfloat *tempImage = NULL;
134848b8605Smrg   int i, j;
135848b8605Smrg   int numxpixels, numypixels;
136848b8605Smrg   const GLfloat *srcaddr;
137848b8605Smrg   GLbyte srcpixels[4][4];
138848b8605Smrg   GLbyte *blkaddr;
139b8e80941Smrg   GLint dstRowDiff, redRowStride;
140b8e80941Smrg   GLfloat *tempImageSlices[1];
141b8e80941Smrg
142b8e80941Smrg   assert(dstFormat == MESA_FORMAT_R_RGTC1_SNORM ||
143848b8605Smrg          dstFormat == MESA_FORMAT_L_LATC1_SNORM);
144848b8605Smrg
145b8e80941Smrg   redRowStride = 1 * srcWidth * sizeof(GLfloat);
146b8e80941Smrg   tempImage = malloc(srcWidth * srcHeight * 1 * sizeof(GLfloat));
147848b8605Smrg   if (!tempImage)
148848b8605Smrg      return GL_FALSE; /* out of memory */
149b8e80941Smrg   tempImageSlices[0] = (GLfloat *) tempImage;
150b8e80941Smrg   _mesa_texstore(ctx, dims,
151b8e80941Smrg                  baseInternalFormat,
152b8e80941Smrg                  MESA_FORMAT_R_FLOAT32,
153b8e80941Smrg                  redRowStride, (GLubyte **)tempImageSlices,
154b8e80941Smrg                  srcWidth, srcHeight, srcDepth,
155b8e80941Smrg                  srcFormat, srcType, srcAddr,
156b8e80941Smrg                  srcPacking);
157848b8605Smrg
158848b8605Smrg   dst = (GLbyte *) dstSlices[0];
159848b8605Smrg
160848b8605Smrg   blkaddr = dst;
161848b8605Smrg   dstRowDiff = dstRowStride >= (srcWidth * 2) ? dstRowStride - (((srcWidth + 3) & ~3) * 2) : 0;
162848b8605Smrg   for (j = 0; j < srcHeight; j+=4) {
163848b8605Smrg      if (srcHeight > j + 3) numypixels = 4;
164848b8605Smrg      else numypixels = srcHeight - j;
165848b8605Smrg      srcaddr = tempImage + j * srcWidth;
166848b8605Smrg      for (i = 0; i < srcWidth; i += 4) {
167848b8605Smrg	 if (srcWidth > i + 3) numxpixels = 4;
168848b8605Smrg	 else numxpixels = srcWidth - i;
169848b8605Smrg	 extractsrc_s(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 1);
170b8e80941Smrg	 util_format_signed_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
171848b8605Smrg	 srcaddr += numxpixels;
172848b8605Smrg	 blkaddr += 8;
173848b8605Smrg      }
174848b8605Smrg      blkaddr += dstRowDiff;
175848b8605Smrg   }
176848b8605Smrg
177848b8605Smrg   free((void *) tempImage);
178848b8605Smrg
179848b8605Smrg   return GL_TRUE;
180848b8605Smrg}
181848b8605Smrg
182848b8605SmrgGLboolean
183848b8605Smrg_mesa_texstore_rg_rgtc2(TEXSTORE_PARAMS)
184848b8605Smrg{
185848b8605Smrg   GLubyte *dst;
186848b8605Smrg   const GLubyte *tempImage = NULL;
187848b8605Smrg   int i, j;
188848b8605Smrg   int numxpixels, numypixels;
189848b8605Smrg   const GLubyte *srcaddr;
190848b8605Smrg   GLubyte srcpixels[4][4];
191848b8605Smrg   GLubyte *blkaddr;
192b8e80941Smrg   GLint dstRowDiff, rgRowStride;
193b8e80941Smrg   mesa_format tempFormat;
194b8e80941Smrg   GLubyte *tempImageSlices[1];
195848b8605Smrg
196b8e80941Smrg   assert(dstFormat == MESA_FORMAT_RG_RGTC2_UNORM ||
197848b8605Smrg          dstFormat == MESA_FORMAT_LA_LATC2_UNORM);
198848b8605Smrg
199b8e80941Smrg   if (baseInternalFormat == GL_RG)
200b8e80941Smrg      tempFormat = _mesa_little_endian() ? MESA_FORMAT_R8G8_UNORM
201b8e80941Smrg                                         : MESA_FORMAT_G8R8_UNORM;
202b8e80941Smrg   else
203b8e80941Smrg      tempFormat = _mesa_little_endian() ? MESA_FORMAT_L8A8_UNORM
204b8e80941Smrg                                         : MESA_FORMAT_A8L8_UNORM;
205b8e80941Smrg
206b8e80941Smrg   rgRowStride = 2 * srcWidth * sizeof(GLubyte);
207b8e80941Smrg   tempImage = malloc(srcWidth * srcHeight * 2 * sizeof(GLubyte));
208848b8605Smrg   if (!tempImage)
209848b8605Smrg      return GL_FALSE; /* out of memory */
210b8e80941Smrg   tempImageSlices[0] = (GLubyte *) tempImage;
211b8e80941Smrg   _mesa_texstore(ctx, dims,
212b8e80941Smrg                  baseInternalFormat,
213b8e80941Smrg                  tempFormat,
214b8e80941Smrg                  rgRowStride, tempImageSlices,
215b8e80941Smrg                  srcWidth, srcHeight, srcDepth,
216b8e80941Smrg                  srcFormat, srcType, srcAddr,
217b8e80941Smrg                  srcPacking);
218848b8605Smrg
219848b8605Smrg   dst = dstSlices[0];
220848b8605Smrg
221848b8605Smrg   blkaddr = dst;
222848b8605Smrg   dstRowDiff = dstRowStride >= (srcWidth * 4) ? dstRowStride - (((srcWidth + 3) & ~3) * 4) : 0;
223848b8605Smrg   for (j = 0; j < srcHeight; j+=4) {
224848b8605Smrg      if (srcHeight > j + 3) numypixels = 4;
225848b8605Smrg      else numypixels = srcHeight - j;
226848b8605Smrg      srcaddr = tempImage + j * srcWidth * 2;
227848b8605Smrg      for (i = 0; i < srcWidth; i += 4) {
228848b8605Smrg	 if (srcWidth > i + 3) numxpixels = 4;
229848b8605Smrg	 else numxpixels = srcWidth - i;
230848b8605Smrg	 extractsrc_u(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 2);
231b8e80941Smrg	 util_format_unsigned_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
232848b8605Smrg
233848b8605Smrg	 blkaddr += 8;
234848b8605Smrg	 extractsrc_u(srcpixels, (GLubyte *)srcaddr + 1, srcWidth, numxpixels, numypixels, 2);
235b8e80941Smrg	 util_format_unsigned_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
236848b8605Smrg
237848b8605Smrg	 blkaddr += 8;
238848b8605Smrg
239848b8605Smrg	 srcaddr += numxpixels * 2;
240848b8605Smrg      }
241848b8605Smrg      blkaddr += dstRowDiff;
242848b8605Smrg   }
243848b8605Smrg
244848b8605Smrg   free((void *) tempImage);
245848b8605Smrg
246848b8605Smrg   return GL_TRUE;
247848b8605Smrg}
248848b8605Smrg
249848b8605SmrgGLboolean
250848b8605Smrg_mesa_texstore_signed_rg_rgtc2(TEXSTORE_PARAMS)
251848b8605Smrg{
252848b8605Smrg   GLbyte *dst;
253848b8605Smrg   const GLfloat *tempImage = NULL;
254848b8605Smrg   int i, j;
255848b8605Smrg   int numxpixels, numypixels;
256848b8605Smrg   const GLfloat *srcaddr;
257848b8605Smrg   GLbyte srcpixels[4][4];
258848b8605Smrg   GLbyte *blkaddr;
259b8e80941Smrg   GLint dstRowDiff, rgRowStride;
260b8e80941Smrg   mesa_format tempFormat;
261b8e80941Smrg   GLfloat *tempImageSlices[1];
262848b8605Smrg
263b8e80941Smrg   assert(dstFormat == MESA_FORMAT_RG_RGTC2_SNORM ||
264848b8605Smrg          dstFormat == MESA_FORMAT_LA_LATC2_SNORM);
265848b8605Smrg
266b8e80941Smrg   if (baseInternalFormat == GL_RG)
267b8e80941Smrg      tempFormat = MESA_FORMAT_RG_FLOAT32;
268b8e80941Smrg   else
269b8e80941Smrg      tempFormat = MESA_FORMAT_LA_FLOAT32;
270b8e80941Smrg
271b8e80941Smrg   rgRowStride = 2 * srcWidth * sizeof(GLfloat);
272b8e80941Smrg   tempImage = malloc(srcWidth * srcHeight * 2 * sizeof(GLfloat));
273848b8605Smrg   if (!tempImage)
274848b8605Smrg      return GL_FALSE; /* out of memory */
275b8e80941Smrg   tempImageSlices[0] = (GLfloat *) tempImage;
276b8e80941Smrg   _mesa_texstore(ctx, dims,
277b8e80941Smrg                  baseInternalFormat,
278b8e80941Smrg                  tempFormat,
279b8e80941Smrg                  rgRowStride, (GLubyte **)tempImageSlices,
280b8e80941Smrg                  srcWidth, srcHeight, srcDepth,
281b8e80941Smrg                  srcFormat, srcType, srcAddr,
282b8e80941Smrg                  srcPacking);
283848b8605Smrg
284848b8605Smrg   dst = (GLbyte *) dstSlices[0];
285848b8605Smrg
286848b8605Smrg   blkaddr = dst;
287848b8605Smrg   dstRowDiff = dstRowStride >= (srcWidth * 4) ? dstRowStride - (((srcWidth + 3) & ~3) * 4) : 0;
288848b8605Smrg   for (j = 0; j < srcHeight; j += 4) {
289848b8605Smrg      if (srcHeight > j + 3) numypixels = 4;
290848b8605Smrg      else numypixels = srcHeight - j;
291848b8605Smrg      srcaddr = tempImage + j * srcWidth * 2;
292848b8605Smrg      for (i = 0; i < srcWidth; i += 4) {
293848b8605Smrg	 if (srcWidth > i + 3) numxpixels = 4;
294848b8605Smrg	 else numxpixels = srcWidth - i;
295848b8605Smrg
296848b8605Smrg	 extractsrc_s(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 2);
297b8e80941Smrg	 util_format_signed_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
298848b8605Smrg	 blkaddr += 8;
299848b8605Smrg
300848b8605Smrg	 extractsrc_s(srcpixels, srcaddr + 1, srcWidth, numxpixels, numypixels, 2);
301b8e80941Smrg	 util_format_signed_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
302848b8605Smrg	 blkaddr += 8;
303848b8605Smrg
304848b8605Smrg	 srcaddr += numxpixels * 2;
305848b8605Smrg
306848b8605Smrg      }
307848b8605Smrg      blkaddr += dstRowDiff;
308848b8605Smrg   }
309848b8605Smrg
310848b8605Smrg   free((void *) tempImage);
311848b8605Smrg
312848b8605Smrg   return GL_TRUE;
313848b8605Smrg}
314848b8605Smrg
315848b8605Smrgstatic void
316848b8605Smrgfetch_red_rgtc1(const GLubyte *map,
317848b8605Smrg                GLint rowStride, GLint i, GLint j, GLfloat *texel)
318848b8605Smrg{
319848b8605Smrg   GLubyte red;
320b8e80941Smrg   util_format_unsigned_fetch_texel_rgtc(rowStride, map, i, j, &red, 1);
321848b8605Smrg   texel[RCOMP] = UBYTE_TO_FLOAT(red);
322848b8605Smrg   texel[GCOMP] = 0.0;
323848b8605Smrg   texel[BCOMP] = 0.0;
324848b8605Smrg   texel[ACOMP] = 1.0;
325848b8605Smrg}
326848b8605Smrg
327848b8605Smrgstatic void
328848b8605Smrgfetch_l_latc1(const GLubyte *map,
329848b8605Smrg              GLint rowStride, GLint i, GLint j, GLfloat *texel)
330848b8605Smrg{
331848b8605Smrg   GLubyte red;
332b8e80941Smrg   util_format_unsigned_fetch_texel_rgtc(rowStride, map, i, j, &red, 1);
333848b8605Smrg   texel[RCOMP] =
334848b8605Smrg   texel[GCOMP] =
335848b8605Smrg   texel[BCOMP] = UBYTE_TO_FLOAT(red);
336848b8605Smrg   texel[ACOMP] = 1.0;
337848b8605Smrg}
338848b8605Smrg
339848b8605Smrgstatic void
340848b8605Smrgfetch_signed_red_rgtc1(const GLubyte *map,
341848b8605Smrg                       GLint rowStride, GLint i, GLint j, GLfloat *texel)
342848b8605Smrg{
343848b8605Smrg   GLbyte red;
344b8e80941Smrg   util_format_signed_fetch_texel_rgtc(rowStride, (const GLbyte *) map,
345848b8605Smrg                           i, j, &red, 1);
346848b8605Smrg   texel[RCOMP] = BYTE_TO_FLOAT_TEX(red);
347848b8605Smrg   texel[GCOMP] = 0.0;
348848b8605Smrg   texel[BCOMP] = 0.0;
349848b8605Smrg   texel[ACOMP] = 1.0;
350848b8605Smrg}
351848b8605Smrg
352848b8605Smrgstatic void
353848b8605Smrgfetch_signed_l_latc1(const GLubyte *map,
354848b8605Smrg                     GLint rowStride, GLint i, GLint j, GLfloat *texel)
355848b8605Smrg{
356848b8605Smrg   GLbyte red;
357b8e80941Smrg   util_format_signed_fetch_texel_rgtc(rowStride, (GLbyte *) map,
358848b8605Smrg                           i, j, &red, 1);
359848b8605Smrg   texel[RCOMP] =
360848b8605Smrg   texel[GCOMP] =
361848b8605Smrg   texel[BCOMP] = BYTE_TO_FLOAT(red);
362848b8605Smrg   texel[ACOMP] = 1.0;
363848b8605Smrg}
364848b8605Smrg
365848b8605Smrgstatic void
366848b8605Smrgfetch_rg_rgtc2(const GLubyte *map,
367848b8605Smrg               GLint rowStride, GLint i, GLint j, GLfloat *texel)
368848b8605Smrg{
369848b8605Smrg   GLubyte red, green;
370b8e80941Smrg   util_format_unsigned_fetch_texel_rgtc(rowStride,
371848b8605Smrg                             map,
372848b8605Smrg                             i, j, &red, 2);
373b8e80941Smrg   util_format_unsigned_fetch_texel_rgtc(rowStride,
374848b8605Smrg                             map + 8,
375848b8605Smrg                             i, j, &green, 2);
376848b8605Smrg   texel[RCOMP] = UBYTE_TO_FLOAT(red);
377848b8605Smrg   texel[GCOMP] = UBYTE_TO_FLOAT(green);
378848b8605Smrg   texel[BCOMP] = 0.0;
379848b8605Smrg   texel[ACOMP] = 1.0;
380848b8605Smrg}
381848b8605Smrg
382848b8605Smrgstatic void
383848b8605Smrgfetch_la_latc2(const GLubyte *map,
384848b8605Smrg               GLint rowStride, GLint i, GLint j, GLfloat *texel)
385848b8605Smrg{
386848b8605Smrg   GLubyte red, green;
387b8e80941Smrg   util_format_unsigned_fetch_texel_rgtc(rowStride,
388848b8605Smrg                             map,
389848b8605Smrg                             i, j, &red, 2);
390b8e80941Smrg   util_format_unsigned_fetch_texel_rgtc(rowStride,
391848b8605Smrg                             map + 8,
392848b8605Smrg                             i, j, &green, 2);
393848b8605Smrg   texel[RCOMP] =
394848b8605Smrg   texel[GCOMP] =
395848b8605Smrg   texel[BCOMP] = UBYTE_TO_FLOAT(red);
396848b8605Smrg   texel[ACOMP] = UBYTE_TO_FLOAT(green);
397848b8605Smrg}
398848b8605Smrg
399848b8605Smrg
400848b8605Smrgstatic void
401848b8605Smrgfetch_signed_rg_rgtc2(const GLubyte *map,
402848b8605Smrg                      GLint rowStride, GLint i, GLint j, GLfloat *texel)
403848b8605Smrg{
404848b8605Smrg   GLbyte red, green;
405b8e80941Smrg   util_format_signed_fetch_texel_rgtc(rowStride,
406848b8605Smrg                           (GLbyte *) map,
407848b8605Smrg                           i, j, &red, 2);
408b8e80941Smrg   util_format_signed_fetch_texel_rgtc(rowStride,
409848b8605Smrg                           (GLbyte *) map + 8,
410848b8605Smrg                           i, j, &green, 2);
411848b8605Smrg   texel[RCOMP] = BYTE_TO_FLOAT_TEX(red);
412848b8605Smrg   texel[GCOMP] = BYTE_TO_FLOAT_TEX(green);
413848b8605Smrg   texel[BCOMP] = 0.0;
414848b8605Smrg   texel[ACOMP] = 1.0;
415848b8605Smrg}
416848b8605Smrg
417848b8605Smrg
418848b8605Smrgstatic void
419848b8605Smrgfetch_signed_la_latc2(const GLubyte *map,
420848b8605Smrg                      GLint rowStride, GLint i, GLint j, GLfloat *texel)
421848b8605Smrg{
422848b8605Smrg   GLbyte red, green;
423b8e80941Smrg   util_format_signed_fetch_texel_rgtc(rowStride,
424848b8605Smrg                           (GLbyte *) map,
425848b8605Smrg                           i, j, &red, 2);
426b8e80941Smrg   util_format_signed_fetch_texel_rgtc(rowStride,
427848b8605Smrg                           (GLbyte *) map + 8,
428848b8605Smrg                           i, j, &green, 2);
429848b8605Smrg   texel[RCOMP] =
430848b8605Smrg   texel[GCOMP] =
431848b8605Smrg   texel[BCOMP] = BYTE_TO_FLOAT_TEX(red);
432848b8605Smrg   texel[ACOMP] = BYTE_TO_FLOAT_TEX(green);
433848b8605Smrg}
434848b8605Smrg
435848b8605Smrg
436848b8605Smrgcompressed_fetch_func
437848b8605Smrg_mesa_get_compressed_rgtc_func(mesa_format format)
438848b8605Smrg{
439848b8605Smrg   switch (format) {
440848b8605Smrg   case MESA_FORMAT_R_RGTC1_UNORM:
441848b8605Smrg      return fetch_red_rgtc1;
442848b8605Smrg   case MESA_FORMAT_L_LATC1_UNORM:
443848b8605Smrg      return fetch_l_latc1;
444848b8605Smrg   case MESA_FORMAT_R_RGTC1_SNORM:
445848b8605Smrg      return fetch_signed_red_rgtc1;
446848b8605Smrg   case MESA_FORMAT_L_LATC1_SNORM:
447848b8605Smrg      return fetch_signed_l_latc1;
448848b8605Smrg   case MESA_FORMAT_RG_RGTC2_UNORM:
449848b8605Smrg      return fetch_rg_rgtc2;
450848b8605Smrg   case MESA_FORMAT_LA_LATC2_UNORM:
451848b8605Smrg      return fetch_la_latc2;
452848b8605Smrg   case MESA_FORMAT_RG_RGTC2_SNORM:
453848b8605Smrg      return fetch_signed_rg_rgtc2;
454848b8605Smrg   case MESA_FORMAT_LA_LATC2_SNORM:
455848b8605Smrg      return fetch_signed_la_latc2;
456848b8605Smrg   default:
457848b8605Smrg      return NULL;
458848b8605Smrg   }
459848b8605Smrg}
460