|
|
|
|
|
|
|
|
* image with stride==width. |
|
|
* image with stride==width. |
|
|
*/ |
|
|
*/ |
|
|
static void |
|
|
static void |
|
|
decompress_image(enum pipe_format format, |
|
|
|
|
|
const uint8_t *src, uint8_t *dst, |
|
|
|
|
|
|
|
|
decompress_image(enum pipe_format format, int datatype, |
|
|
|
|
|
const uint8_t *src, void *dst, |
|
|
unsigned width, unsigned height, unsigned src_stride) |
|
|
unsigned width, unsigned height, unsigned src_stride) |
|
|
{ |
|
|
{ |
|
|
const struct util_format_description *desc = util_format_description(format); |
|
|
const struct util_format_description *desc = util_format_description(format); |
|
|
const uint bw = util_format_get_blockwidth(format); |
|
|
const uint bw = util_format_get_blockwidth(format); |
|
|
const uint bh = util_format_get_blockheight(format); |
|
|
const uint bh = util_format_get_blockheight(format); |
|
|
const uint dst_stride = 4 * MAX2(width, bw); |
|
|
|
|
|
|
|
|
|
|
|
desc->unpack_rgba_8unorm(dst, dst_stride, src, src_stride, width, height); |
|
|
|
|
|
|
|
|
|
|
|
if (width < bw || height < bh) { |
|
|
|
|
|
/* We're decompressing an image smaller than the compression |
|
|
|
|
|
* block size. We don't want garbage pixel values in the region |
|
|
|
|
|
* outside (width x height) so replicate pixels from the (width |
|
|
|
|
|
* x height) region to fill out the (bw x bh) block size. |
|
|
|
|
|
*/ |
|
|
|
|
|
uint x, y; |
|
|
|
|
|
for (y = 0; y < bh; y++) { |
|
|
|
|
|
for (x = 0; x < bw; x++) { |
|
|
|
|
|
if (x >= width || y >= height) { |
|
|
|
|
|
uint p = (y * bw + x) * 4; |
|
|
|
|
|
dst[p + 0] = dst[0]; |
|
|
|
|
|
dst[p + 1] = dst[1]; |
|
|
|
|
|
dst[p + 2] = dst[2]; |
|
|
|
|
|
dst[p + 3] = dst[3]; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
uint dst_stride = 4 * MAX2(width, bw); |
|
|
|
|
|
|
|
|
|
|
|
if (datatype == GL_FLOAT) { |
|
|
|
|
|
desc->unpack_rgba_float((float *)dst, dst_stride * sizeof(GLfloat), src, src_stride, width, height); |
|
|
|
|
|
if (width < bw || height < bh) { |
|
|
|
|
|
float *dst_p = (float *)dst; |
|
|
|
|
|
/* We're decompressing an image smaller than the compression |
|
|
|
|
|
* block size. We don't want garbage pixel values in the region |
|
|
|
|
|
* outside (width x height) so replicate pixels from the (width |
|
|
|
|
|
* x height) region to fill out the (bw x bh) block size. |
|
|
|
|
|
*/ |
|
|
|
|
|
uint x, y; |
|
|
|
|
|
for (y = 0; y < bh; y++) { |
|
|
|
|
|
for (x = 0; x < bw; x++) { |
|
|
|
|
|
if (x >= width || y >= height) { |
|
|
|
|
|
uint p = (y * bw + x) * 4; |
|
|
|
|
|
dst_p[p + 0] = dst_p[0]; |
|
|
|
|
|
dst_p[p + 1] = dst_p[1]; |
|
|
|
|
|
dst_p[p + 2] = dst_p[2]; |
|
|
|
|
|
dst_p[p + 3] = dst_p[3]; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} else { |
|
|
|
|
|
desc->unpack_rgba_8unorm((uint8_t *)dst, dst_stride, src, src_stride, width, height); |
|
|
|
|
|
if (width < bw || height < bh) { |
|
|
|
|
|
uint8_t *dst_p = (uint8_t *)dst; |
|
|
|
|
|
/* We're decompressing an image smaller than the compression |
|
|
|
|
|
* block size. We don't want garbage pixel values in the region |
|
|
|
|
|
* outside (width x height) so replicate pixels from the (width |
|
|
|
|
|
* x height) region to fill out the (bw x bh) block size. |
|
|
|
|
|
*/ |
|
|
|
|
|
uint x, y; |
|
|
|
|
|
for (y = 0; y < bh; y++) { |
|
|
|
|
|
for (x = 0; x < bw; x++) { |
|
|
|
|
|
if (x >= width || y >= height) { |
|
|
|
|
|
uint p = (y * bw + x) * 4; |
|
|
|
|
|
dst_p[p + 0] = dst_p[0]; |
|
|
|
|
|
dst_p[p + 1] = dst_p[1]; |
|
|
|
|
|
dst_p[p + 2] = dst_p[2]; |
|
|
|
|
|
dst_p[p + 3] = dst_p[3]; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* Helper function to compress an image. The source is a 32-bpp RGBA image |
|
|
* Helper function to compress an image. The source is a 32-bpp RGBA image |
|
|
* with stride==width. |
|
|
* with stride==width. |
|
|
*/ |
|
|
*/ |
|
|
static void |
|
|
static void |
|
|
compress_image(enum pipe_format format, |
|
|
|
|
|
const uint8_t *src, uint8_t *dst, |
|
|
|
|
|
|
|
|
compress_image(enum pipe_format format, int datatype, |
|
|
|
|
|
const void *src, uint8_t *dst, |
|
|
unsigned width, unsigned height, unsigned dst_stride) |
|
|
unsigned width, unsigned height, unsigned dst_stride) |
|
|
{ |
|
|
{ |
|
|
const struct util_format_description *desc = util_format_description(format); |
|
|
const struct util_format_description *desc = util_format_description(format); |
|
|
const uint src_stride = 4 * width; |
|
|
const uint src_stride = 4 * width; |
|
|
|
|
|
|
|
|
desc->pack_rgba_8unorm(dst, dst_stride, src, src_stride, width, height); |
|
|
|
|
|
|
|
|
if (datatype == GL_FLOAT) |
|
|
|
|
|
desc->pack_rgba_float(dst, dst_stride, (GLfloat *)src, src_stride * sizeof(GLfloat), width, height); |
|
|
|
|
|
else |
|
|
|
|
|
desc->pack_rgba_8unorm(dst, dst_stride, (uint8_t *)src, src_stride, width, height); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
_mesa_is_format_compressed(texObj->Image[face][baseLevel]->TexFormat); |
|
|
_mesa_is_format_compressed(texObj->Image[face][baseLevel]->TexFormat); |
|
|
|
|
|
|
|
|
if (compressed) { |
|
|
if (compressed) { |
|
|
datatype = GL_UNSIGNED_BYTE; |
|
|
|
|
|
|
|
|
if (texObj->Image[face][baseLevel]->TexFormat == MESA_FORMAT_SIGNED_RED_RGTC1 || |
|
|
|
|
|
texObj->Image[face][baseLevel]->TexFormat == MESA_FORMAT_SIGNED_RG_RGTC2) |
|
|
|
|
|
datatype = GL_FLOAT; |
|
|
|
|
|
else |
|
|
|
|
|
datatype = GL_UNSIGNED_BYTE; |
|
|
|
|
|
|
|
|
comps = 4; |
|
|
comps = 4; |
|
|
} |
|
|
} |
|
|
else { |
|
|
else { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assert(comps == 4); |
|
|
assert(comps == 4); |
|
|
|
|
|
|
|
|
srcTemp = malloc(srcWidth2 * srcHeight2 * comps + 000); |
|
|
|
|
|
dstTemp = malloc(dstWidth2 * dstHeight2 * comps + 000); |
|
|
|
|
|
|
|
|
srcTemp = malloc(srcWidth2 * srcHeight2 * comps * (datatype == GL_FLOAT ? 4 : 1)); |
|
|
|
|
|
dstTemp = malloc(dstWidth2 * dstHeight2 * comps * (datatype == GL_FLOAT ? 4 : 1)); |
|
|
|
|
|
|
|
|
/* decompress the src image: srcData -> srcTemp */ |
|
|
/* decompress the src image: srcData -> srcTemp */ |
|
|
decompress_image(format, srcData, srcTemp, srcWidth, srcHeight, srcTrans->stride); |
|
|
|
|
|
|
|
|
decompress_image(format, datatype, srcData, srcTemp, srcWidth, srcHeight, srcTrans->stride); |
|
|
|
|
|
|
|
|
_mesa_generate_mipmap_level(target, datatype, comps, |
|
|
_mesa_generate_mipmap_level(target, datatype, comps, |
|
|
0 /*border*/, |
|
|
0 /*border*/, |
|
|
|
|
|
|
|
|
dstWidth2); /* stride in texels */ |
|
|
dstWidth2); /* stride in texels */ |
|
|
|
|
|
|
|
|
/* compress the new image: dstTemp -> dstData */ |
|
|
/* compress the new image: dstTemp -> dstData */ |
|
|
compress_image(format, dstTemp, dstData, dstWidth, dstHeight, dstTrans->stride); |
|
|
|
|
|
|
|
|
compress_image(format, datatype, dstTemp, dstData, dstWidth, dstHeight, dstTrans->stride); |
|
|
|
|
|
|
|
|
free(srcTemp); |
|
|
free(srcTemp); |
|
|
free(dstTemp); |
|
|
free(dstTemp); |