13464ebd5Sriastradh/*
23464ebd5Sriastradh * Copyright (C) 2011 Red Hat Inc.
37ec681f3Smrg *
43464ebd5Sriastradh * block compression parts are:
53464ebd5Sriastradh * Copyright (C) 2004  Roland Scheidegger   All Rights Reserved.
63464ebd5Sriastradh *
73464ebd5Sriastradh * Permission is hereby granted, free of charge, to any person obtaining a
83464ebd5Sriastradh * copy of this software and associated documentation files (the "Software"),
93464ebd5Sriastradh * to deal in the Software without restriction, including without limitation
103464ebd5Sriastradh * the rights to use, copy, modify, merge, publish, distribute, sublicense,
113464ebd5Sriastradh * and/or sell copies of the Software, and to permit persons to whom the
123464ebd5Sriastradh * Software is furnished to do so, subject to the following conditions:
133464ebd5Sriastradh *
143464ebd5Sriastradh * The above copyright notice and this permission notice (including the next
153464ebd5Sriastradh * paragraph) shall be included in all copies or substantial portions of the
163464ebd5Sriastradh * Software.
173464ebd5Sriastradh *
183464ebd5Sriastradh * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
193464ebd5Sriastradh * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
203464ebd5Sriastradh * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
213464ebd5Sriastradh * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
223464ebd5Sriastradh * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
233464ebd5Sriastradh * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
243464ebd5Sriastradh * DEALINGS IN THE SOFTWARE.
253464ebd5Sriastradh *
263464ebd5Sriastradh * Author:
273464ebd5Sriastradh *    Dave Airlie
283464ebd5Sriastradh */
293464ebd5Sriastradh
303464ebd5Sriastradh/**
313464ebd5Sriastradh * \file texcompress_rgtc.c
323464ebd5Sriastradh * GL_EXT_texture_compression_rgtc support.
333464ebd5Sriastradh */
343464ebd5Sriastradh
357ec681f3Smrg#include <stdlib.h>
363464ebd5Sriastradh
3701e04c3fSmrg#include "config.h"
383464ebd5Sriastradh#include "glheader.h"
397ec681f3Smrg
403464ebd5Sriastradh#include "image.h"
413464ebd5Sriastradh#include "macros.h"
423464ebd5Sriastradh#include "mipmap.h"
433464ebd5Sriastradh#include "texcompress.h"
4401e04c3fSmrg#include "util/rgtc.h"
453464ebd5Sriastradh#include "texcompress_rgtc.h"
463464ebd5Sriastradh#include "texstore.h"
473464ebd5Sriastradh
48af69d88dSmrgstatic void extractsrc_u( GLubyte srcpixels[4][4], const GLubyte *srcaddr,
493464ebd5Sriastradh			  GLint srcRowStride, GLint numxpixels, GLint numypixels, GLint comps)
503464ebd5Sriastradh{
513464ebd5Sriastradh   GLubyte i, j;
52af69d88dSmrg   const GLubyte *curaddr;
533464ebd5Sriastradh   for (j = 0; j < numypixels; j++) {
543464ebd5Sriastradh      curaddr = srcaddr + j * srcRowStride * comps;
553464ebd5Sriastradh      for (i = 0; i < numxpixels; i++) {
56af69d88dSmrg	 srcpixels[j][i] = *curaddr;
573464ebd5Sriastradh	 curaddr += comps;
583464ebd5Sriastradh      }
593464ebd5Sriastradh   }
603464ebd5Sriastradh}
613464ebd5Sriastradh
623464ebd5Sriastradhstatic void extractsrc_s( GLbyte srcpixels[4][4], const GLfloat *srcaddr,
633464ebd5Sriastradh			  GLint srcRowStride, GLint numxpixels, GLint numypixels, GLint comps)
643464ebd5Sriastradh{
653464ebd5Sriastradh   GLubyte i, j;
663464ebd5Sriastradh   const GLfloat *curaddr;
673464ebd5Sriastradh   for (j = 0; j < numypixels; j++) {
683464ebd5Sriastradh      curaddr = srcaddr + j * srcRowStride * comps;
693464ebd5Sriastradh      for (i = 0; i < numxpixels; i++) {
703464ebd5Sriastradh	 srcpixels[j][i] = FLOAT_TO_BYTE_TEX(*curaddr);
713464ebd5Sriastradh	 curaddr += comps;
723464ebd5Sriastradh      }
733464ebd5Sriastradh   }
743464ebd5Sriastradh}
753464ebd5Sriastradh
763464ebd5Sriastradh
773464ebd5SriastradhGLboolean
783464ebd5Sriastradh_mesa_texstore_red_rgtc1(TEXSTORE_PARAMS)
793464ebd5Sriastradh{
803464ebd5Sriastradh   GLubyte *dst;
81af69d88dSmrg   const GLubyte *tempImage = NULL;
823464ebd5Sriastradh   int i, j;
833464ebd5Sriastradh   int numxpixels, numypixels;
84af69d88dSmrg   const GLubyte *srcaddr;
853464ebd5Sriastradh   GLubyte srcpixels[4][4];
863464ebd5Sriastradh   GLubyte *blkaddr;
8701e04c3fSmrg   GLint dstRowDiff, redRowStride;
8801e04c3fSmrg   GLubyte *tempImageSlices[1];
8901e04c3fSmrg
9001e04c3fSmrg   assert(dstFormat == MESA_FORMAT_R_RGTC1_UNORM ||
91af69d88dSmrg          dstFormat == MESA_FORMAT_L_LATC1_UNORM);
923464ebd5Sriastradh
9301e04c3fSmrg   tempImage = malloc(srcWidth * srcHeight * 1 * sizeof(GLubyte));
943464ebd5Sriastradh   if (!tempImage)
953464ebd5Sriastradh      return GL_FALSE; /* out of memory */
9601e04c3fSmrg   redRowStride = 1 * srcWidth * sizeof(GLubyte);
9701e04c3fSmrg   tempImageSlices[0] = (GLubyte *) tempImage;
9801e04c3fSmrg   _mesa_texstore(ctx, dims,
9901e04c3fSmrg                  baseInternalFormat,
10001e04c3fSmrg                  MESA_FORMAT_R_UNORM8,
10101e04c3fSmrg                  redRowStride, tempImageSlices,
10201e04c3fSmrg                  srcWidth, srcHeight, srcDepth,
10301e04c3fSmrg                  srcFormat, srcType, srcAddr,
10401e04c3fSmrg                  srcPacking);
1053464ebd5Sriastradh
106af69d88dSmrg   dst = dstSlices[0];
1073464ebd5Sriastradh
1083464ebd5Sriastradh   blkaddr = dst;
1093464ebd5Sriastradh   dstRowDiff = dstRowStride >= (srcWidth * 2) ? dstRowStride - (((srcWidth + 3) & ~3) * 2) : 0;
1103464ebd5Sriastradh   for (j = 0; j < srcHeight; j+=4) {
1113464ebd5Sriastradh      if (srcHeight > j + 3) numypixels = 4;
1123464ebd5Sriastradh      else numypixels = srcHeight - j;
1133464ebd5Sriastradh      srcaddr = tempImage + j * srcWidth;
1143464ebd5Sriastradh      for (i = 0; i < srcWidth; i += 4) {
1153464ebd5Sriastradh	 if (srcWidth > i + 3) numxpixels = 4;
1163464ebd5Sriastradh	 else numxpixels = srcWidth - i;
1173464ebd5Sriastradh	 extractsrc_u(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 1);
11801e04c3fSmrg	 util_format_unsigned_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
1193464ebd5Sriastradh	 srcaddr += numxpixels;
1203464ebd5Sriastradh	 blkaddr += 8;
1213464ebd5Sriastradh      }
1223464ebd5Sriastradh      blkaddr += dstRowDiff;
1233464ebd5Sriastradh   }
124af69d88dSmrg
125af69d88dSmrg   free((void *) tempImage);
1263464ebd5Sriastradh
1273464ebd5Sriastradh   return GL_TRUE;
1283464ebd5Sriastradh}
1293464ebd5Sriastradh
1303464ebd5SriastradhGLboolean
1313464ebd5Sriastradh_mesa_texstore_signed_red_rgtc1(TEXSTORE_PARAMS)
1323464ebd5Sriastradh{
1333464ebd5Sriastradh   GLbyte *dst;
1343464ebd5Sriastradh   const GLfloat *tempImage = NULL;
1353464ebd5Sriastradh   int i, j;
1363464ebd5Sriastradh   int numxpixels, numypixels;
1373464ebd5Sriastradh   const GLfloat *srcaddr;
1383464ebd5Sriastradh   GLbyte srcpixels[4][4];
1393464ebd5Sriastradh   GLbyte *blkaddr;
14001e04c3fSmrg   GLint dstRowDiff, redRowStride;
14101e04c3fSmrg   GLfloat *tempImageSlices[1];
14201e04c3fSmrg
14301e04c3fSmrg   assert(dstFormat == MESA_FORMAT_R_RGTC1_SNORM ||
144af69d88dSmrg          dstFormat == MESA_FORMAT_L_LATC1_SNORM);
1453464ebd5Sriastradh
14601e04c3fSmrg   redRowStride = 1 * srcWidth * sizeof(GLfloat);
14701e04c3fSmrg   tempImage = malloc(srcWidth * srcHeight * 1 * sizeof(GLfloat));
1483464ebd5Sriastradh   if (!tempImage)
1493464ebd5Sriastradh      return GL_FALSE; /* out of memory */
15001e04c3fSmrg   tempImageSlices[0] = (GLfloat *) tempImage;
15101e04c3fSmrg   _mesa_texstore(ctx, dims,
15201e04c3fSmrg                  baseInternalFormat,
15301e04c3fSmrg                  MESA_FORMAT_R_FLOAT32,
15401e04c3fSmrg                  redRowStride, (GLubyte **)tempImageSlices,
15501e04c3fSmrg                  srcWidth, srcHeight, srcDepth,
15601e04c3fSmrg                  srcFormat, srcType, srcAddr,
15701e04c3fSmrg                  srcPacking);
1583464ebd5Sriastradh
159af69d88dSmrg   dst = (GLbyte *) dstSlices[0];
1603464ebd5Sriastradh
1613464ebd5Sriastradh   blkaddr = dst;
1623464ebd5Sriastradh   dstRowDiff = dstRowStride >= (srcWidth * 2) ? dstRowStride - (((srcWidth + 3) & ~3) * 2) : 0;
1633464ebd5Sriastradh   for (j = 0; j < srcHeight; j+=4) {
1643464ebd5Sriastradh      if (srcHeight > j + 3) numypixels = 4;
1653464ebd5Sriastradh      else numypixels = srcHeight - j;
1663464ebd5Sriastradh      srcaddr = tempImage + j * srcWidth;
1673464ebd5Sriastradh      for (i = 0; i < srcWidth; i += 4) {
1683464ebd5Sriastradh	 if (srcWidth > i + 3) numxpixels = 4;
1693464ebd5Sriastradh	 else numxpixels = srcWidth - i;
1703464ebd5Sriastradh	 extractsrc_s(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 1);
17101e04c3fSmrg	 util_format_signed_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
1723464ebd5Sriastradh	 srcaddr += numxpixels;
1733464ebd5Sriastradh	 blkaddr += 8;
1743464ebd5Sriastradh      }
1753464ebd5Sriastradh      blkaddr += dstRowDiff;
1763464ebd5Sriastradh   }
177af69d88dSmrg
178af69d88dSmrg   free((void *) tempImage);
1793464ebd5Sriastradh
1803464ebd5Sriastradh   return GL_TRUE;
1813464ebd5Sriastradh}
1823464ebd5Sriastradh
1833464ebd5SriastradhGLboolean
1843464ebd5Sriastradh_mesa_texstore_rg_rgtc2(TEXSTORE_PARAMS)
1853464ebd5Sriastradh{
1863464ebd5Sriastradh   GLubyte *dst;
187af69d88dSmrg   const GLubyte *tempImage = NULL;
1883464ebd5Sriastradh   int i, j;
1893464ebd5Sriastradh   int numxpixels, numypixels;
190af69d88dSmrg   const GLubyte *srcaddr;
1913464ebd5Sriastradh   GLubyte srcpixels[4][4];
1923464ebd5Sriastradh   GLubyte *blkaddr;
19301e04c3fSmrg   GLint dstRowDiff, rgRowStride;
19401e04c3fSmrg   mesa_format tempFormat;
19501e04c3fSmrg   GLubyte *tempImageSlices[1];
1963464ebd5Sriastradh
19701e04c3fSmrg   assert(dstFormat == MESA_FORMAT_RG_RGTC2_UNORM ||
198af69d88dSmrg          dstFormat == MESA_FORMAT_LA_LATC2_UNORM);
1993464ebd5Sriastradh
20001e04c3fSmrg   if (baseInternalFormat == GL_RG)
2017ec681f3Smrg      tempFormat = MESA_FORMAT_RG_UNORM8;
20201e04c3fSmrg   else
2037ec681f3Smrg      tempFormat = MESA_FORMAT_LA_UNORM8;
20401e04c3fSmrg
20501e04c3fSmrg   rgRowStride = 2 * srcWidth * sizeof(GLubyte);
20601e04c3fSmrg   tempImage = malloc(srcWidth * srcHeight * 2 * sizeof(GLubyte));
2073464ebd5Sriastradh   if (!tempImage)
2083464ebd5Sriastradh      return GL_FALSE; /* out of memory */
20901e04c3fSmrg   tempImageSlices[0] = (GLubyte *) tempImage;
21001e04c3fSmrg   _mesa_texstore(ctx, dims,
21101e04c3fSmrg                  baseInternalFormat,
21201e04c3fSmrg                  tempFormat,
21301e04c3fSmrg                  rgRowStride, tempImageSlices,
21401e04c3fSmrg                  srcWidth, srcHeight, srcDepth,
21501e04c3fSmrg                  srcFormat, srcType, srcAddr,
21601e04c3fSmrg                  srcPacking);
2173464ebd5Sriastradh
218af69d88dSmrg   dst = dstSlices[0];
2193464ebd5Sriastradh
2203464ebd5Sriastradh   blkaddr = dst;
2213464ebd5Sriastradh   dstRowDiff = dstRowStride >= (srcWidth * 4) ? dstRowStride - (((srcWidth + 3) & ~3) * 4) : 0;
2223464ebd5Sriastradh   for (j = 0; j < srcHeight; j+=4) {
2233464ebd5Sriastradh      if (srcHeight > j + 3) numypixels = 4;
2243464ebd5Sriastradh      else numypixels = srcHeight - j;
2253464ebd5Sriastradh      srcaddr = tempImage + j * srcWidth * 2;
2263464ebd5Sriastradh      for (i = 0; i < srcWidth; i += 4) {
2273464ebd5Sriastradh	 if (srcWidth > i + 3) numxpixels = 4;
2283464ebd5Sriastradh	 else numxpixels = srcWidth - i;
2293464ebd5Sriastradh	 extractsrc_u(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 2);
23001e04c3fSmrg	 util_format_unsigned_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
2313464ebd5Sriastradh
2323464ebd5Sriastradh	 blkaddr += 8;
233af69d88dSmrg	 extractsrc_u(srcpixels, (GLubyte *)srcaddr + 1, srcWidth, numxpixels, numypixels, 2);
23401e04c3fSmrg	 util_format_unsigned_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
2353464ebd5Sriastradh
2363464ebd5Sriastradh	 blkaddr += 8;
2373464ebd5Sriastradh
2383464ebd5Sriastradh	 srcaddr += numxpixels * 2;
2393464ebd5Sriastradh      }
2403464ebd5Sriastradh      blkaddr += dstRowDiff;
2413464ebd5Sriastradh   }
242af69d88dSmrg
243af69d88dSmrg   free((void *) tempImage);
2443464ebd5Sriastradh
2453464ebd5Sriastradh   return GL_TRUE;
2463464ebd5Sriastradh}
2473464ebd5Sriastradh
2483464ebd5SriastradhGLboolean
2493464ebd5Sriastradh_mesa_texstore_signed_rg_rgtc2(TEXSTORE_PARAMS)
2503464ebd5Sriastradh{
2513464ebd5Sriastradh   GLbyte *dst;
2523464ebd5Sriastradh   const GLfloat *tempImage = NULL;
2533464ebd5Sriastradh   int i, j;
2543464ebd5Sriastradh   int numxpixels, numypixels;
2553464ebd5Sriastradh   const GLfloat *srcaddr;
2563464ebd5Sriastradh   GLbyte srcpixels[4][4];
2573464ebd5Sriastradh   GLbyte *blkaddr;
25801e04c3fSmrg   GLint dstRowDiff, rgRowStride;
25901e04c3fSmrg   mesa_format tempFormat;
26001e04c3fSmrg   GLfloat *tempImageSlices[1];
2613464ebd5Sriastradh
26201e04c3fSmrg   assert(dstFormat == MESA_FORMAT_RG_RGTC2_SNORM ||
263af69d88dSmrg          dstFormat == MESA_FORMAT_LA_LATC2_SNORM);
2643464ebd5Sriastradh
26501e04c3fSmrg   if (baseInternalFormat == GL_RG)
26601e04c3fSmrg      tempFormat = MESA_FORMAT_RG_FLOAT32;
26701e04c3fSmrg   else
26801e04c3fSmrg      tempFormat = MESA_FORMAT_LA_FLOAT32;
26901e04c3fSmrg
27001e04c3fSmrg   rgRowStride = 2 * srcWidth * sizeof(GLfloat);
27101e04c3fSmrg   tempImage = malloc(srcWidth * srcHeight * 2 * sizeof(GLfloat));
2723464ebd5Sriastradh   if (!tempImage)
2733464ebd5Sriastradh      return GL_FALSE; /* out of memory */
27401e04c3fSmrg   tempImageSlices[0] = (GLfloat *) tempImage;
27501e04c3fSmrg   _mesa_texstore(ctx, dims,
27601e04c3fSmrg                  baseInternalFormat,
27701e04c3fSmrg                  tempFormat,
27801e04c3fSmrg                  rgRowStride, (GLubyte **)tempImageSlices,
27901e04c3fSmrg                  srcWidth, srcHeight, srcDepth,
28001e04c3fSmrg                  srcFormat, srcType, srcAddr,
28101e04c3fSmrg                  srcPacking);
2823464ebd5Sriastradh
283af69d88dSmrg   dst = (GLbyte *) dstSlices[0];
2843464ebd5Sriastradh
2853464ebd5Sriastradh   blkaddr = dst;
2863464ebd5Sriastradh   dstRowDiff = dstRowStride >= (srcWidth * 4) ? dstRowStride - (((srcWidth + 3) & ~3) * 4) : 0;
2873464ebd5Sriastradh   for (j = 0; j < srcHeight; j += 4) {
2883464ebd5Sriastradh      if (srcHeight > j + 3) numypixels = 4;
2893464ebd5Sriastradh      else numypixels = srcHeight - j;
2903464ebd5Sriastradh      srcaddr = tempImage + j * srcWidth * 2;
2913464ebd5Sriastradh      for (i = 0; i < srcWidth; i += 4) {
2923464ebd5Sriastradh	 if (srcWidth > i + 3) numxpixels = 4;
2933464ebd5Sriastradh	 else numxpixels = srcWidth - i;
2943464ebd5Sriastradh
2953464ebd5Sriastradh	 extractsrc_s(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 2);
29601e04c3fSmrg	 util_format_signed_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
2973464ebd5Sriastradh	 blkaddr += 8;
2983464ebd5Sriastradh
2993464ebd5Sriastradh	 extractsrc_s(srcpixels, srcaddr + 1, srcWidth, numxpixels, numypixels, 2);
30001e04c3fSmrg	 util_format_signed_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
3013464ebd5Sriastradh	 blkaddr += 8;
3023464ebd5Sriastradh
3033464ebd5Sriastradh	 srcaddr += numxpixels * 2;
3043464ebd5Sriastradh
3053464ebd5Sriastradh      }
3063464ebd5Sriastradh      blkaddr += dstRowDiff;
3073464ebd5Sriastradh   }
308af69d88dSmrg
309af69d88dSmrg   free((void *) tempImage);
3103464ebd5Sriastradh
3113464ebd5Sriastradh   return GL_TRUE;
3123464ebd5Sriastradh}
3133464ebd5Sriastradh
314af69d88dSmrgstatic void
315af69d88dSmrgfetch_red_rgtc1(const GLubyte *map,
316af69d88dSmrg                GLint rowStride, GLint i, GLint j, GLfloat *texel)
3173464ebd5Sriastradh{
3183464ebd5Sriastradh   GLubyte red;
31901e04c3fSmrg   util_format_unsigned_fetch_texel_rgtc(rowStride, map, i, j, &red, 1);
3203464ebd5Sriastradh   texel[RCOMP] = UBYTE_TO_FLOAT(red);
3213464ebd5Sriastradh   texel[GCOMP] = 0.0;
3223464ebd5Sriastradh   texel[BCOMP] = 0.0;
3233464ebd5Sriastradh   texel[ACOMP] = 1.0;
3243464ebd5Sriastradh}
3253464ebd5Sriastradh
326af69d88dSmrgstatic void
327af69d88dSmrgfetch_l_latc1(const GLubyte *map,
328af69d88dSmrg              GLint rowStride, GLint i, GLint j, GLfloat *texel)
3293464ebd5Sriastradh{
330af69d88dSmrg   GLubyte red;
33101e04c3fSmrg   util_format_unsigned_fetch_texel_rgtc(rowStride, map, i, j, &red, 1);
332af69d88dSmrg   texel[RCOMP] =
333af69d88dSmrg   texel[GCOMP] =
334af69d88dSmrg   texel[BCOMP] = UBYTE_TO_FLOAT(red);
3353464ebd5Sriastradh   texel[ACOMP] = 1.0;
3363464ebd5Sriastradh}
3373464ebd5Sriastradh
338af69d88dSmrgstatic void
339af69d88dSmrgfetch_signed_red_rgtc1(const GLubyte *map,
340af69d88dSmrg                       GLint rowStride, GLint i, GLint j, GLfloat *texel)
3413464ebd5Sriastradh{
342af69d88dSmrg   GLbyte red;
34301e04c3fSmrg   util_format_signed_fetch_texel_rgtc(rowStride, (const GLbyte *) map,
344af69d88dSmrg                           i, j, &red, 1);
3453464ebd5Sriastradh   texel[RCOMP] = BYTE_TO_FLOAT_TEX(red);
346af69d88dSmrg   texel[GCOMP] = 0.0;
3473464ebd5Sriastradh   texel[BCOMP] = 0.0;
3483464ebd5Sriastradh   texel[ACOMP] = 1.0;
3493464ebd5Sriastradh}
3503464ebd5Sriastradh
351af69d88dSmrgstatic void
352af69d88dSmrgfetch_signed_l_latc1(const GLubyte *map,
353af69d88dSmrg                     GLint rowStride, GLint i, GLint j, GLfloat *texel)
3543464ebd5Sriastradh{
355af69d88dSmrg   GLbyte red;
35601e04c3fSmrg   util_format_signed_fetch_texel_rgtc(rowStride, (GLbyte *) map,
357af69d88dSmrg                           i, j, &red, 1);
3583464ebd5Sriastradh   texel[RCOMP] =
3593464ebd5Sriastradh   texel[GCOMP] =
360af69d88dSmrg   texel[BCOMP] = BYTE_TO_FLOAT(red);
3613464ebd5Sriastradh   texel[ACOMP] = 1.0;
3623464ebd5Sriastradh}
3633464ebd5Sriastradh
364af69d88dSmrgstatic void
365af69d88dSmrgfetch_rg_rgtc2(const GLubyte *map,
366af69d88dSmrg               GLint rowStride, GLint i, GLint j, GLfloat *texel)
3673464ebd5Sriastradh{
368af69d88dSmrg   GLubyte red, green;
36901e04c3fSmrg   util_format_unsigned_fetch_texel_rgtc(rowStride,
370af69d88dSmrg                             map,
371af69d88dSmrg                             i, j, &red, 2);
37201e04c3fSmrg   util_format_unsigned_fetch_texel_rgtc(rowStride,
373af69d88dSmrg                             map + 8,
374af69d88dSmrg                             i, j, &green, 2);
375af69d88dSmrg   texel[RCOMP] = UBYTE_TO_FLOAT(red);
376af69d88dSmrg   texel[GCOMP] = UBYTE_TO_FLOAT(green);
377af69d88dSmrg   texel[BCOMP] = 0.0;
3783464ebd5Sriastradh   texel[ACOMP] = 1.0;
3793464ebd5Sriastradh}
3803464ebd5Sriastradh
381af69d88dSmrgstatic void
382af69d88dSmrgfetch_la_latc2(const GLubyte *map,
383af69d88dSmrg               GLint rowStride, GLint i, GLint j, GLfloat *texel)
3843464ebd5Sriastradh{
3853464ebd5Sriastradh   GLubyte red, green;
38601e04c3fSmrg   util_format_unsigned_fetch_texel_rgtc(rowStride,
387af69d88dSmrg                             map,
388af69d88dSmrg                             i, j, &red, 2);
38901e04c3fSmrg   util_format_unsigned_fetch_texel_rgtc(rowStride,
390af69d88dSmrg                             map + 8,
391af69d88dSmrg                             i, j, &green, 2);
3923464ebd5Sriastradh   texel[RCOMP] =
3933464ebd5Sriastradh   texel[GCOMP] =
3943464ebd5Sriastradh   texel[BCOMP] = UBYTE_TO_FLOAT(red);
3953464ebd5Sriastradh   texel[ACOMP] = UBYTE_TO_FLOAT(green);
3963464ebd5Sriastradh}
3973464ebd5Sriastradh
398af69d88dSmrg
399af69d88dSmrgstatic void
400af69d88dSmrgfetch_signed_rg_rgtc2(const GLubyte *map,
401af69d88dSmrg                      GLint rowStride, GLint i, GLint j, GLfloat *texel)
402af69d88dSmrg{
403af69d88dSmrg   GLbyte red, green;
40401e04c3fSmrg   util_format_signed_fetch_texel_rgtc(rowStride,
405af69d88dSmrg                           (GLbyte *) map,
406af69d88dSmrg                           i, j, &red, 2);
40701e04c3fSmrg   util_format_signed_fetch_texel_rgtc(rowStride,
408af69d88dSmrg                           (GLbyte *) map + 8,
409af69d88dSmrg                           i, j, &green, 2);
410af69d88dSmrg   texel[RCOMP] = BYTE_TO_FLOAT_TEX(red);
411af69d88dSmrg   texel[GCOMP] = BYTE_TO_FLOAT_TEX(green);
412af69d88dSmrg   texel[BCOMP] = 0.0;
413af69d88dSmrg   texel[ACOMP] = 1.0;
414af69d88dSmrg}
415af69d88dSmrg
416af69d88dSmrg
417af69d88dSmrgstatic void
418af69d88dSmrgfetch_signed_la_latc2(const GLubyte *map,
419af69d88dSmrg                      GLint rowStride, GLint i, GLint j, GLfloat *texel)
4203464ebd5Sriastradh{
4213464ebd5Sriastradh   GLbyte red, green;
42201e04c3fSmrg   util_format_signed_fetch_texel_rgtc(rowStride,
423af69d88dSmrg                           (GLbyte *) map,
424af69d88dSmrg                           i, j, &red, 2);
42501e04c3fSmrg   util_format_signed_fetch_texel_rgtc(rowStride,
426af69d88dSmrg                           (GLbyte *) map + 8,
427af69d88dSmrg                           i, j, &green, 2);
4283464ebd5Sriastradh   texel[RCOMP] =
4293464ebd5Sriastradh   texel[GCOMP] =
4303464ebd5Sriastradh   texel[BCOMP] = BYTE_TO_FLOAT_TEX(red);
4313464ebd5Sriastradh   texel[ACOMP] = BYTE_TO_FLOAT_TEX(green);
4323464ebd5Sriastradh}
4333464ebd5Sriastradh
4343464ebd5Sriastradh
435af69d88dSmrgcompressed_fetch_func
436af69d88dSmrg_mesa_get_compressed_rgtc_func(mesa_format format)
437af69d88dSmrg{
438af69d88dSmrg   switch (format) {
439af69d88dSmrg   case MESA_FORMAT_R_RGTC1_UNORM:
440af69d88dSmrg      return fetch_red_rgtc1;
441af69d88dSmrg   case MESA_FORMAT_L_LATC1_UNORM:
442af69d88dSmrg      return fetch_l_latc1;
443af69d88dSmrg   case MESA_FORMAT_R_RGTC1_SNORM:
444af69d88dSmrg      return fetch_signed_red_rgtc1;
445af69d88dSmrg   case MESA_FORMAT_L_LATC1_SNORM:
446af69d88dSmrg      return fetch_signed_l_latc1;
447af69d88dSmrg   case MESA_FORMAT_RG_RGTC2_UNORM:
448af69d88dSmrg      return fetch_rg_rgtc2;
449af69d88dSmrg   case MESA_FORMAT_LA_LATC2_UNORM:
450af69d88dSmrg      return fetch_la_latc2;
451af69d88dSmrg   case MESA_FORMAT_RG_RGTC2_SNORM:
452af69d88dSmrg      return fetch_signed_rg_rgtc2;
453af69d88dSmrg   case MESA_FORMAT_LA_LATC2_SNORM:
454af69d88dSmrg      return fetch_signed_la_latc2;
455af69d88dSmrg   default:
456af69d88dSmrg      return NULL;
457af69d88dSmrg   }
458af69d88dSmrg}
459