#include "colormac.h"
#include "image.h"
#include "macros.h"
-#include "mfeatures.h"
#include "mipmap.h"
#include "texcompress.h"
#include "texcompress_rgtc.h"
#include "texstore.h"
+
#define RGTC_DEBUG 0
-static void unsigned_encode_rgtc_chan(GLubyte *blkaddr, GLubyte srccolors[4][4],
+static void unsigned_encode_rgtc_ubyte(GLubyte *blkaddr, GLubyte srccolors[4][4],
GLint numxpixels, GLint numypixels);
-static void signed_encode_rgtc_chan(GLbyte *blkaddr, GLbyte srccolors[4][4],
+static void signed_encode_rgtc_ubyte(GLbyte *blkaddr, GLbyte srccolors[4][4],
GLint numxpixels, GLint numypixels);
-static void extractsrc_u( GLubyte srcpixels[4][4], const GLchan *srcaddr,
+static void unsigned_fetch_texel_rgtc(unsigned srcRowStride, const GLubyte *pixdata,
+ unsigned i, unsigned j, GLubyte *value, unsigned comps);
+
+static void signed_fetch_texel_rgtc(unsigned srcRowStride, const GLbyte *pixdata,
+ unsigned i, unsigned j, GLbyte *value, unsigned comps);
+
+static void extractsrc_u( GLubyte srcpixels[4][4], const GLubyte *srcaddr,
GLint srcRowStride, GLint numxpixels, GLint numypixels, GLint comps)
{
GLubyte i, j;
- const GLchan *curaddr;
+ const GLubyte *curaddr;
for (j = 0; j < numypixels; j++) {
curaddr = srcaddr + j * srcRowStride * comps;
for (i = 0; i < numxpixels; i++) {
- srcpixels[j][i] = *curaddr / (CHAN_MAX / 255);
+ srcpixels[j][i] = *curaddr;
curaddr += comps;
}
}
_mesa_texstore_red_rgtc1(TEXSTORE_PARAMS)
{
GLubyte *dst;
- const GLint texWidth = dstRowStride * 4 / 8; /* a bit of a hack */
- const GLchan *tempImage = NULL;
+ const GLubyte *tempImage = NULL;
int i, j;
int numxpixels, numypixels;
- const GLchan *srcaddr;
+ const GLubyte *srcaddr;
GLubyte srcpixels[4][4];
GLubyte *blkaddr;
GLint dstRowDiff;
- ASSERT(dstFormat == MESA_FORMAT_RED_RGTC1);
- ASSERT(dstXoffset % 4 == 0);
- ASSERT(dstYoffset % 4 == 0);
- ASSERT(dstZoffset % 4 == 0);
- (void) dstZoffset;
- (void) dstImageOffsets;
+ ASSERT(dstFormat == MESA_FORMAT_RED_RGTC1 ||
+ dstFormat == MESA_FORMAT_L_LATC1);
-
- tempImage = _mesa_make_temp_chan_image(ctx, dims,
+ tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
baseInternalFormat,
_mesa_get_format_base_format(dstFormat),
srcWidth, srcHeight, srcDepth,
if (!tempImage)
return GL_FALSE; /* out of memory */
- dst = _mesa_compressed_image_address(dstXoffset, dstYoffset, 0,
- dstFormat,
- texWidth, (GLubyte *) dstAddr);
+ dst = dstSlices[0];
blkaddr = dst;
- dstRowDiff = dstRowStride >= (srcWidth * 4) ? dstRowStride - (((srcWidth + 3) & ~3) * 4) : 0;
+ dstRowDiff = dstRowStride >= (srcWidth * 2) ? dstRowStride - (((srcWidth + 3) & ~3) * 2) : 0;
for (j = 0; j < srcHeight; j+=4) {
if (srcHeight > j + 3) numypixels = 4;
else numypixels = srcHeight - j;
if (srcWidth > i + 3) numxpixels = 4;
else numxpixels = srcWidth - i;
extractsrc_u(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 1);
- unsigned_encode_rgtc_chan(blkaddr, srcpixels, numxpixels, numypixels);
+ unsigned_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
srcaddr += numxpixels;
blkaddr += 8;
}
blkaddr += dstRowDiff;
}
- if (tempImage)
- free((void *) tempImage);
+
+ free((void *) tempImage);
return GL_TRUE;
}
_mesa_texstore_signed_red_rgtc1(TEXSTORE_PARAMS)
{
GLbyte *dst;
- const GLint texWidth = dstRowStride * 4 / 8; /* a bit of a hack */
const GLfloat *tempImage = NULL;
int i, j;
int numxpixels, numypixels;
GLbyte srcpixels[4][4];
GLbyte *blkaddr;
GLint dstRowDiff;
- ASSERT(dstFormat == MESA_FORMAT_SIGNED_RED_RGTC1);
- ASSERT(dstXoffset % 4 == 0);
- ASSERT(dstYoffset % 4 == 0);
- ASSERT(dstZoffset % 4 == 0);
- (void) dstZoffset;
- (void) dstImageOffsets;
+ ASSERT(dstFormat == MESA_FORMAT_SIGNED_RED_RGTC1 ||
+ dstFormat == MESA_FORMAT_SIGNED_L_LATC1);
tempImage = _mesa_make_temp_float_image(ctx, dims,
baseInternalFormat,
if (!tempImage)
return GL_FALSE; /* out of memory */
- dst = (GLbyte *)_mesa_compressed_image_address(dstXoffset, dstYoffset, 0,
- dstFormat,
- texWidth, (GLubyte *) dstAddr);
+ dst = (GLbyte *) dstSlices[0];
blkaddr = dst;
- dstRowDiff = dstRowStride >= (srcWidth * 4) ? dstRowStride - (((srcWidth + 3) & ~3) * 4) : 0;
+ dstRowDiff = dstRowStride >= (srcWidth * 2) ? dstRowStride - (((srcWidth + 3) & ~3) * 2) : 0;
for (j = 0; j < srcHeight; j+=4) {
if (srcHeight > j + 3) numypixels = 4;
else numypixels = srcHeight - j;
if (srcWidth > i + 3) numxpixels = 4;
else numxpixels = srcWidth - i;
extractsrc_s(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 1);
- signed_encode_rgtc_chan(blkaddr, srcpixels, numxpixels, numypixels);
+ signed_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
srcaddr += numxpixels;
blkaddr += 8;
}
blkaddr += dstRowDiff;
}
- if (tempImage)
- free((void *) tempImage);
+
+ free((void *) tempImage);
return GL_TRUE;
}
_mesa_texstore_rg_rgtc2(TEXSTORE_PARAMS)
{
GLubyte *dst;
- const GLint texWidth = dstRowStride * 4 / 16; /* a bit of a hack */
- const GLchan *tempImage = NULL;
+ const GLubyte *tempImage = NULL;
int i, j;
int numxpixels, numypixels;
- const GLchan *srcaddr;
+ const GLubyte *srcaddr;
GLubyte srcpixels[4][4];
GLubyte *blkaddr;
GLint dstRowDiff;
- ASSERT(dstFormat == MESA_FORMAT_RG_RGTC2);
- ASSERT(dstXoffset % 4 == 0);
- ASSERT(dstYoffset % 4 == 0);
- ASSERT(dstZoffset % 4 == 0);
- (void) dstZoffset;
- (void) dstImageOffsets;
+ ASSERT(dstFormat == MESA_FORMAT_RG_RGTC2 ||
+ dstFormat == MESA_FORMAT_LA_LATC2);
- tempImage = _mesa_make_temp_chan_image(ctx, dims,
+ tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
baseInternalFormat,
_mesa_get_format_base_format(dstFormat),
srcWidth, srcHeight, srcDepth,
if (!tempImage)
return GL_FALSE; /* out of memory */
- dst = _mesa_compressed_image_address(dstXoffset, dstYoffset, 0,
- dstFormat,
- texWidth, (GLubyte *) dstAddr);
+ dst = dstSlices[0];
blkaddr = dst;
- dstRowDiff = dstRowStride >= (srcWidth * 8) ? dstRowStride - (((srcWidth + 7) & ~7) * 8) : 0;
+ dstRowDiff = dstRowStride >= (srcWidth * 4) ? dstRowStride - (((srcWidth + 3) & ~3) * 4) : 0;
for (j = 0; j < srcHeight; j+=4) {
if (srcHeight > j + 3) numypixels = 4;
else numypixels = srcHeight - j;
if (srcWidth > i + 3) numxpixels = 4;
else numxpixels = srcWidth - i;
extractsrc_u(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 2);
- unsigned_encode_rgtc_chan(blkaddr, srcpixels, numxpixels, numypixels);
+ unsigned_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
blkaddr += 8;
- extractsrc_u(srcpixels, (GLchan *)srcaddr + 1, srcWidth, numxpixels, numypixels, 2);
- unsigned_encode_rgtc_chan(blkaddr, srcpixels, numxpixels, numypixels);
+ extractsrc_u(srcpixels, (GLubyte *)srcaddr + 1, srcWidth, numxpixels, numypixels, 2);
+ unsigned_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
blkaddr += 8;
}
blkaddr += dstRowDiff;
}
- if (tempImage)
- free((void *) tempImage);
+
+ free((void *) tempImage);
return GL_TRUE;
}
_mesa_texstore_signed_rg_rgtc2(TEXSTORE_PARAMS)
{
GLbyte *dst;
- const GLint texWidth = dstRowStride * 4 / 16; /* a bit of a hack */
const GLfloat *tempImage = NULL;
int i, j;
int numxpixels, numypixels;
GLbyte *blkaddr;
GLint dstRowDiff;
- ASSERT(dstFormat == MESA_FORMAT_SIGNED_RG_RGTC2);
- ASSERT(dstXoffset % 4 == 0);
- ASSERT(dstYoffset % 4 == 0);
- ASSERT(dstZoffset % 4 == 0);
- (void) dstZoffset;
- (void) dstImageOffsets;
+ ASSERT(dstFormat == MESA_FORMAT_SIGNED_RG_RGTC2 ||
+ dstFormat == MESA_FORMAT_SIGNED_LA_LATC2);
tempImage = _mesa_make_temp_float_image(ctx, dims,
baseInternalFormat,
if (!tempImage)
return GL_FALSE; /* out of memory */
- dst = (GLbyte *)_mesa_compressed_image_address(dstXoffset, dstYoffset, 0,
- dstFormat,
- texWidth, (GLubyte *) dstAddr);
+ dst = (GLbyte *) dstSlices[0];
blkaddr = dst;
- dstRowDiff = dstRowStride >= (srcWidth * 8) ? dstRowStride - (((srcWidth + 7) & ~7) * 8) : 0;
+ dstRowDiff = dstRowStride >= (srcWidth * 4) ? dstRowStride - (((srcWidth + 3) & ~3) * 4) : 0;
for (j = 0; j < srcHeight; j += 4) {
if (srcHeight > j + 3) numypixels = 4;
else numypixels = srcHeight - j;
else numxpixels = srcWidth - i;
extractsrc_s(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 2);
- signed_encode_rgtc_chan(blkaddr, srcpixels, numxpixels, numypixels);
+ signed_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
blkaddr += 8;
extractsrc_s(srcpixels, srcaddr + 1, srcWidth, numxpixels, numypixels, 2);
- signed_encode_rgtc_chan(blkaddr, srcpixels, numxpixels, numypixels);
+ signed_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
blkaddr += 8;
srcaddr += numxpixels * 2;
}
blkaddr += dstRowDiff;
}
- if (tempImage)
- free((void *) tempImage);
+
+ free((void *) tempImage);
return GL_TRUE;
}
-static void _fetch_texel_rgtc_u(GLint srcRowStride, const GLubyte *pixdata,
- GLint i, GLint j, GLchan *value, int comps)
-{
- GLchan decode;
- const GLubyte *blksrc = (pixdata + ((srcRowStride + 3) / 4 * (j / 4) + (i / 4)) * 8 * comps);
- const GLubyte alpha0 = blksrc[0];
- const GLubyte alpha1 = blksrc[1];
- const GLubyte bit_pos = ((j&3) * 4 + (i&3)) * 3;
- const GLubyte acodelow = blksrc[2 + bit_pos / 8];
- const GLubyte acodehigh = blksrc[3 + bit_pos / 8];
- const GLubyte code = (acodelow >> (bit_pos & 0x7) |
- (acodehigh << (8 - (bit_pos & 0x7)))) & 0x7;
-
- if (code == 0)
- decode = UBYTE_TO_CHAN( alpha0 );
- else if (code == 1)
- decode = UBYTE_TO_CHAN( alpha1 );
- else if (alpha0 > alpha1)
- decode = UBYTE_TO_CHAN( ((alpha0 * (8 - code) + (alpha1 * (code - 1))) / 7) );
- else if (code < 6)
- decode = UBYTE_TO_CHAN( ((alpha0 * (6 - code) + (alpha1 * (code - 1))) / 5) );
- else if (code == 6)
- decode = 0;
- else
- decode = CHAN_MAX;
-
- *value = decode;
-}
+
+#define TAG(x) unsigned_##x
+
+#define TYPE GLubyte
+#define T_MIN 0
+#define T_MAX 0xff
+
+#include "texcompress_rgtc_tmp.h"
+
+#undef TAG
+#undef TYPE
+#undef T_MIN
+#undef T_MAX
+
+#define TAG(x) signed_##x
+#define TYPE GLbyte
+#define T_MIN (GLbyte)-128
+#define T_MAX (GLbyte)127
+
+#include "texcompress_rgtc_tmp.h"
+
+#undef TAG
+#undef TYPE
+#undef T_MIN
+#undef T_MAX
-static void _fetch_texel_rgtc_s(GLint srcRowStride, const GLbyte *pixdata,
- GLint i, GLint j, GLbyte *value, int comps)
-{
- GLbyte decode;
- const GLbyte *blksrc = (pixdata + ((srcRowStride + 3) / 4 * (j / 4) + (i / 4)) * 8 * comps);
- const GLbyte alpha0 = blksrc[0];
- const GLbyte alpha1 = blksrc[1];
- const GLbyte bit_pos = ((j&3) * 4 + (i&3)) * 3;
- const GLbyte acodelow = blksrc[2 + bit_pos / 8];
- const GLbyte acodehigh = blksrc[3 + bit_pos / 8];
- const GLbyte code = (acodelow >> (bit_pos & 0x7) |
- (acodehigh << (8 - (bit_pos & 0x7)))) & 0x7;
-
- if (code == 0)
- decode = alpha0;
- else if (code == 1)
- decode = alpha1;
- else if (alpha0 > alpha1)
- decode = ((alpha0 * (8 - code) + (alpha1 * (code - 1))) / 7);
- else if (code < 6)
- decode = ((alpha0 * (6 - code) + (alpha1 * (code - 1))) / 5);
- else if (code == 6)
- decode = -128;
- else
- decode = 127;
-
- *value = decode;
-}
-void
-_mesa_fetch_texel_2d_f_red_rgtc1(const struct gl_texture_image *texImage,
- GLint i, GLint j, GLint k, GLfloat *texel)
+static void
+fetch_red_rgtc1(const GLubyte *map,
+ GLint rowStride, GLint i, GLint j, GLfloat *texel)
{
- GLchan red;
- _fetch_texel_rgtc_u(texImage->RowStride, (GLubyte *)(texImage->Data),
- i, j, &red, 1);
- texel[RCOMP] = CHAN_TO_FLOAT(red);
+ GLubyte red;
+ unsigned_fetch_texel_rgtc(rowStride, map, i, j, &red, 1);
+ texel[RCOMP] = UBYTE_TO_FLOAT(red);
texel[GCOMP] = 0.0;
texel[BCOMP] = 0.0;
texel[ACOMP] = 1.0;
}
-void
-_mesa_fetch_texel_2d_f_signed_red_rgtc1(const struct gl_texture_image *texImage,
- GLint i, GLint j, GLint k, GLfloat *texel)
+static void
+fetch_l_latc1(const GLubyte *map,
+ GLint rowStride, GLint i, GLint j, GLfloat *texel)
+{
+ GLubyte red;
+ unsigned_fetch_texel_rgtc(rowStride, map, i, j, &red, 1);
+ texel[RCOMP] =
+ texel[GCOMP] =
+ texel[BCOMP] = UBYTE_TO_FLOAT(red);
+ texel[ACOMP] = 1.0;
+}
+
+static void
+fetch_signed_red_rgtc1(const GLubyte *map,
+ GLint rowStride, GLint i, GLint j, GLfloat *texel)
{
GLbyte red;
- _fetch_texel_rgtc_s(texImage->RowStride, (GLbyte *)(texImage->Data),
- i, j, &red, 1);
+ signed_fetch_texel_rgtc(rowStride, (const GLbyte *) map,
+ i, j, &red, 1);
texel[RCOMP] = BYTE_TO_FLOAT_TEX(red);
texel[GCOMP] = 0.0;
texel[BCOMP] = 0.0;
texel[ACOMP] = 1.0;
}
-void
-_mesa_fetch_texel_2d_f_rg_rgtc2(const struct gl_texture_image *texImage,
- GLint i, GLint j, GLint k, GLfloat *texel)
+static void
+fetch_signed_l_latc1(const GLubyte *map,
+ GLint rowStride, GLint i, GLint j, GLfloat *texel)
+{
+ GLbyte red;
+ signed_fetch_texel_rgtc(rowStride, (GLbyte *) map,
+ i, j, &red, 1);
+ texel[RCOMP] =
+ texel[GCOMP] =
+ texel[BCOMP] = BYTE_TO_FLOAT(red);
+ texel[ACOMP] = 1.0;
+}
+
+static void
+fetch_rg_rgtc2(const GLubyte *map,
+ GLint rowStride, GLint i, GLint j, GLfloat *texel)
{
- GLchan red, green;
- _fetch_texel_rgtc_u(texImage->RowStride, (GLubyte *)(texImage->Data),
- i, j, &red, 2);
- _fetch_texel_rgtc_u(texImage->RowStride, (GLubyte *)(texImage->Data) + 8,
- i, j, &green, 2);
- texel[RCOMP] = CHAN_TO_FLOAT(red);
- texel[GCOMP] = CHAN_TO_FLOAT(green);
+ GLubyte red, green;
+ unsigned_fetch_texel_rgtc(rowStride,
+ map,
+ i, j, &red, 2);
+ unsigned_fetch_texel_rgtc(rowStride,
+ map + 8,
+ i, j, &green, 2);
+ texel[RCOMP] = UBYTE_TO_FLOAT(red);
+ texel[GCOMP] = UBYTE_TO_FLOAT(green);
texel[BCOMP] = 0.0;
texel[ACOMP] = 1.0;
}
-void
-_mesa_fetch_texel_2d_f_signed_rg_rgtc2(const struct gl_texture_image *texImage,
- GLint i, GLint j, GLint k, GLfloat *texel)
+static void
+fetch_la_latc2(const GLubyte *map,
+ GLint rowStride, GLint i, GLint j, GLfloat *texel)
+{
+ GLubyte red, green;
+ unsigned_fetch_texel_rgtc(rowStride,
+ map,
+ i, j, &red, 2);
+ unsigned_fetch_texel_rgtc(rowStride,
+ map + 8,
+ i, j, &green, 2);
+ texel[RCOMP] =
+ texel[GCOMP] =
+ texel[BCOMP] = UBYTE_TO_FLOAT(red);
+ texel[ACOMP] = UBYTE_TO_FLOAT(green);
+}
+
+
+static void
+fetch_signed_rg_rgtc2(const GLubyte *map,
+ GLint rowStride, GLint i, GLint j, GLfloat *texel)
{
GLbyte red, green;
- _fetch_texel_rgtc_s(texImage->RowStride, (GLbyte *)(texImage->Data),
- i, j, &red, 2);
- _fetch_texel_rgtc_s(texImage->RowStride, (GLbyte *)(texImage->Data) + 8,
- i, j, &green, 2);
+ signed_fetch_texel_rgtc(rowStride,
+ (GLbyte *) map,
+ i, j, &red, 2);
+ signed_fetch_texel_rgtc(rowStride,
+ (GLbyte *) map + 8,
+ i, j, &green, 2);
texel[RCOMP] = BYTE_TO_FLOAT_TEX(red);
texel[GCOMP] = BYTE_TO_FLOAT_TEX(green);
texel[BCOMP] = 0.0;
texel[ACOMP] = 1.0;
}
-#define TAG(x) unsigned_##x
-
-#define TYPE GLubyte
-#define T_MIN 0
-#define T_MAX 0xff
-
-#include "texcompress_rgtc_tmp.h"
-
-#undef TAG
-#undef TYPE
-#undef T_MIN
-#undef T_MAX
-#define TAG(x) signed_##x
-#define TYPE GLbyte
-#define T_MIN (GLbyte)-127
-#define T_MAX (GLbyte)128
+static void
+fetch_signed_la_latc2(const GLubyte *map,
+ GLint rowStride, GLint i, GLint j, GLfloat *texel)
+{
+ GLbyte red, green;
+ signed_fetch_texel_rgtc(rowStride,
+ (GLbyte *) map,
+ i, j, &red, 2);
+ signed_fetch_texel_rgtc(rowStride,
+ (GLbyte *) map + 8,
+ i, j, &green, 2);
+ texel[RCOMP] =
+ texel[GCOMP] =
+ texel[BCOMP] = BYTE_TO_FLOAT_TEX(red);
+ texel[ACOMP] = BYTE_TO_FLOAT_TEX(green);
+}
-#include "texcompress_rgtc_tmp.h"
-#undef TAG
-#undef TYPE
-#undef T_MIN
-#undef T_MAX
+compressed_fetch_func
+_mesa_get_compressed_rgtc_func(gl_format format)
+{
+ switch (format) {
+ case MESA_FORMAT_RED_RGTC1:
+ return fetch_red_rgtc1;
+ case MESA_FORMAT_L_LATC1:
+ return fetch_l_latc1;
+ case MESA_FORMAT_SIGNED_RED_RGTC1:
+ return fetch_signed_red_rgtc1;
+ case MESA_FORMAT_SIGNED_L_LATC1:
+ return fetch_signed_l_latc1;
+ case MESA_FORMAT_RG_RGTC2:
+ return fetch_rg_rgtc2;
+ case MESA_FORMAT_LA_LATC2:
+ return fetch_la_latc2;
+ case MESA_FORMAT_SIGNED_RG_RGTC2:
+ return fetch_signed_rg_rgtc2;
+ case MESA_FORMAT_SIGNED_LA_LATC2:
+ return fetch_signed_la_latc2;
+ default:
+ return NULL;
+ }
+}