#include "texcompress.h"
#include "texcompress_fxt1.h"
#include "texcompress_s3tc.h"
-#include "texformat.h"
#include "teximage.h"
#include "texstore.h"
#include "enums.h"
}
-#if !FEATURE_convolve
-static void
-_mesa_adjust_image_for_convolution(GLcontext *ctx, GLuint dims,
- GLsizei *srcWidth, GLsizei *srcHeight)
-{
- /* no-op */
-}
-#endif
-
-
/**
* Make a temporary (color) texture image with GLfloat components.
* Apply all needed pixel unpacking and pixel transfer operations.
const GLuint postConvTransferOps
= (transferOps & IMAGE_POST_CONVOLUTION_BITS) | IMAGE_CLAMP_BIT;
GLint img, row;
- GLint convWidth, convHeight;
+ GLint convWidth = srcWidth, convHeight = srcHeight;
GLfloat *convImage;
/* pre-convolution image buffer (3D) */
else {
/* no convolution */
const GLint components = _mesa_components_in_format(logicalBaseFormat);
- const GLint srcStride = _mesa_image_row_stride(srcPacking,
- srcWidth, srcFormat, srcType);
+ const GLint srcStride =
+ _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
GLfloat *dst;
GLint img, row;
/* unpack and transfer the source image */
tempImage = (GLchan *) _mesa_malloc(srcWidth * srcHeight * srcDepth
* components * sizeof(GLchan));
- if (!tempImage)
+ if (!tempImage) {
+ if (freeSrcImage) {
+ _mesa_free((void *) srcAddr);
+ }
return NULL;
+ }
dst = tempImage;
for (img = 0; img < srcDepth; img++) {
- const GLint srcStride = _mesa_image_row_stride(srcPacking,
- srcWidth, srcFormat,
- srcType);
- const GLubyte *src
- = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
- srcWidth, srcHeight,
- srcFormat, srcType,
- img, 0, 0);
+ const GLint srcStride =
+ _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
+ const GLubyte *src =
+ (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
+ srcWidth, srcHeight,
+ srcFormat, srcType,
+ img, 0, 0);
for (row = 0; row < srcHeight; row++) {
_mesa_unpack_color_span_chan(ctx, srcWidth, logicalBaseFormat, dst,
srcFormat, srcType, src, srcPacking,
/**
- * Store an image in any of the formats:
- * _mesa_texformat_rgba
- * _mesa_texformat_rgb
- * _mesa_texformat_alpha
- * _mesa_texformat_luminance
- * _mesa_texformat_luminance_alpha
- * _mesa_texformat_intensity
- *
+ * Store a 32-bit integer depth component texture image.
*/
static GLboolean
-_mesa_texstore_rgba(TEXSTORE_PARAMS)
+_mesa_texstore_z32(TEXSTORE_PARAMS)
{
- const GLint components = _mesa_components_in_format(baseInternalFormat);
+ const GLuint depthScale = 0xffffffff;
const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
- const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
-
- ASSERT(dstFormat == MESA_FORMAT_RGBA ||
- dstFormat == MESA_FORMAT_RGB ||
- dstFormat == MESA_FORMAT_ALPHA ||
- dstFormat == MESA_FORMAT_LUMINANCE ||
- dstFormat == MESA_FORMAT_LUMINANCE_ALPHA ||
- dstFormat == MESA_FORMAT_INTENSITY);
- ASSERT(baseInternalFormat == GL_RGBA ||
- baseInternalFormat == GL_RGB ||
- baseInternalFormat == GL_ALPHA ||
- baseInternalFormat == GL_LUMINANCE ||
- baseInternalFormat == GL_LUMINANCE_ALPHA ||
- baseInternalFormat == GL_INTENSITY);
- ASSERT(texelBytes == components * sizeof(GLchan));
+ (void) dims;
+ ASSERT(dstFormat == MESA_FORMAT_Z32);
+ ASSERT(texelBytes == sizeof(GLuint));
- if (!ctx->_ImageTransferState &&
+ if (ctx->Pixel.DepthScale == 1.0f &&
+ ctx->Pixel.DepthBias == 0.0f &&
!srcPacking->SwapBytes &&
- baseInternalFormat == srcFormat &&
- srcType == CHAN_TYPE) {
+ baseInternalFormat == GL_DEPTH_COMPONENT &&
+ srcFormat == GL_DEPTH_COMPONENT &&
+ srcType == GL_UNSIGNED_INT) {
/* simple memcpy path */
memcpy_texture(ctx, dims,
dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
srcWidth, srcHeight, srcDepth, srcFormat, srcType,
srcAddr, srcPacking);
}
- else if (!ctx->_ImageTransferState &&
- !srcPacking->SwapBytes &&
- dstFormat == MESA_FORMAT_RGB &&
- srcFormat == GL_RGBA &&
- srcType == CHAN_TYPE) {
- /* extract RGB from RGBA */
- GLint img, row, col;
+ else {
+ /* general path */
+ GLint img, row;
for (img = 0; img < srcDepth; img++) {
- GLchan *dstImage = (GLchan *)
- ((GLubyte *) dstAddr
- + dstImageOffsets[dstZoffset + img] * texelBytes
- + dstYoffset * dstRowStride
- + dstXoffset * texelBytes);
-
- const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
- srcWidth, srcFormat, srcType);
- GLchan *srcRow = (GLchan *) _mesa_image_address(dims, srcPacking,
- srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
- GLchan *dstRow = dstImage;
+ GLubyte *dstRow = (GLubyte *) dstAddr
+ + dstImageOffsets[dstZoffset + img] * texelBytes
+ + dstYoffset * dstRowStride
+ + dstXoffset * texelBytes;
for (row = 0; row < srcHeight; row++) {
- for (col = 0; col < srcWidth; col++) {
- dstRow[col * 3 + RCOMP] = srcRow[col * 4 + RCOMP];
- dstRow[col * 3 + GCOMP] = srcRow[col * 4 + GCOMP];
- dstRow[col * 3 + BCOMP] = srcRow[col * 4 + BCOMP];
- }
- dstRow += dstRowStride / sizeof(GLchan);
- srcRow = (GLchan *) ((GLubyte *) srcRow + srcRowStride);
+ const GLvoid *src = _mesa_image_address(dims, srcPacking,
+ srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
+ _mesa_unpack_depth_span(ctx, srcWidth,
+ GL_UNSIGNED_INT, (GLuint *) dstRow,
+ depthScale, srcType, src, srcPacking);
+ dstRow += dstRowStride;
}
}
}
- else if (!ctx->_ImageTransferState &&
- CHAN_TYPE == GL_UNSIGNED_BYTE &&
- (srcType == GL_UNSIGNED_BYTE ||
- srcType == GL_UNSIGNED_INT_8_8_8_8 ||
- srcType == GL_UNSIGNED_INT_8_8_8_8_REV) &&
- can_swizzle(baseInternalFormat) &&
- can_swizzle(srcFormat)) {
+ return GL_TRUE;
+}
- const GLubyte *dstmap;
- GLuint components;
- /* dstmap - how to swizzle from RGBA to dst format:
- */
- if (dstFormat == MESA_FORMAT_RGBA) {
- dstmap = mappings[IDX_RGBA].from_rgba;
- components = 4;
- }
- else if (dstFormat == MESA_FORMAT_RGB) {
- dstmap = mappings[IDX_RGB].from_rgba;
- components = 3;
- }
- else if (dstFormat == MESA_FORMAT_ALPHA) {
- dstmap = mappings[IDX_ALPHA].from_rgba;
- components = 1;
- }
- else if (dstFormat == MESA_FORMAT_LUMINANCE) {
- dstmap = mappings[IDX_LUMINANCE].from_rgba;
- components = 1;
- }
- else if (dstFormat == MESA_FORMAT_LUMINANCE_ALPHA) {
- dstmap = mappings[IDX_LUMINANCE_ALPHA].from_rgba;
- components = 2;
- }
- else if (dstFormat == MESA_FORMAT_INTENSITY) {
- dstmap = mappings[IDX_INTENSITY].from_rgba;
- components = 1;
- }
- else {
- _mesa_problem(ctx, "Unexpected dstFormat in _mesa_texstore_rgba");
- return GL_FALSE;
- }
+/**
+ * Store a 24-bit integer depth component texture image.
+ */
+static GLboolean
+_mesa_texstore_x8_z24(TEXSTORE_PARAMS)
+{
+ const GLuint depthScale = 0xffffff;
+ const GLuint texelBytes = 4;
- _mesa_swizzle_ubyte_image(ctx, dims,
- srcFormat,
- srcType,
- baseInternalFormat,
- dstmap, components,
- dstAddr, dstXoffset, dstYoffset, dstZoffset,
- dstRowStride, dstImageOffsets,
- srcWidth, srcHeight, srcDepth, srcAddr,
- srcPacking);
- }
- else {
+ (void) dims;
+ ASSERT(dstFormat == MESA_FORMAT_X8_Z24);
+
+ {
/* general path */
- const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
- baseInternalFormat,
- baseFormat,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr,
- srcPacking);
- const GLchan *src = tempImage;
- GLint bytesPerRow;
GLint img, row;
- if (!tempImage)
- return GL_FALSE;
- _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
- bytesPerRow = srcWidth * components * sizeof(GLchan);
for (img = 0; img < srcDepth; img++) {
GLubyte *dstRow = (GLubyte *) dstAddr
+ dstImageOffsets[dstZoffset + img] * texelBytes
+ dstYoffset * dstRowStride
+ dstXoffset * texelBytes;
for (row = 0; row < srcHeight; row++) {
- _mesa_memcpy(dstRow, src, bytesPerRow);
+ const GLvoid *src = _mesa_image_address(dims, srcPacking,
+ srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
+ _mesa_unpack_depth_span(ctx, srcWidth,
+ GL_UNSIGNED_INT, (GLuint *) dstRow,
+ depthScale, srcType, src, srcPacking);
dstRow += dstRowStride;
- src += srcWidth * components;
}
}
-
- _mesa_free((void *) tempImage);
}
return GL_TRUE;
}
/**
- * Store a 32-bit integer depth component texture image.
+ * Store a 24-bit integer depth component texture image.
*/
static GLboolean
-_mesa_texstore_z32(TEXSTORE_PARAMS)
+_mesa_texstore_z24_x8(TEXSTORE_PARAMS)
{
- const GLuint depthScale = 0xffffffff;
- const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
+ const GLuint depthScale = 0xffffff;
+ const GLuint texelBytes = 4;
+
(void) dims;
- ASSERT(dstFormat == MESA_FORMAT_Z32);
- ASSERT(texelBytes == sizeof(GLuint));
+ ASSERT(dstFormat == MESA_FORMAT_Z24_X8);
- if (ctx->Pixel.DepthScale == 1.0f &&
- ctx->Pixel.DepthBias == 0.0f &&
- !srcPacking->SwapBytes &&
- baseInternalFormat == GL_DEPTH_COMPONENT &&
- srcFormat == GL_DEPTH_COMPONENT &&
- srcType == GL_UNSIGNED_INT) {
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
- dstRowStride,
- dstImageOffsets,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else {
+ {
/* general path */
GLint img, row;
for (img = 0; img < srcDepth; img++) {
for (row = 0; row < srcHeight; row++) {
const GLvoid *src = _mesa_image_address(dims, srcPacking,
srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
+ GLuint *dst = (GLuint *) dstRow;
+ GLint i;
_mesa_unpack_depth_span(ctx, srcWidth,
- GL_UNSIGNED_INT, (GLuint *) dstRow,
+ GL_UNSIGNED_INT, dst,
depthScale, srcType, src, srcPacking);
+ for (i = 0; i < srcWidth; i++)
+ dst[i] <<= 8;
dstRow += dstRowStride;
}
}
return GL_TRUE;
}
-#define STRIDE_3D 0
/**
* Store a 16-bit integer depth component texture image.
srcType == GL_UNSIGNED_BYTE &&
dims == 2) {
/* do optimized tex store */
- const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth,
- srcFormat, srcType);
+ const GLint srcRowStride =
+ _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
const GLubyte *src = (const GLubyte *)
_mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight,
srcFormat, srcType, 0, 0, 0);
{
const GLboolean littleEndian = _mesa_little_endian();
const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
- const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
+ const GLenum baseFormat = GL_RGBA;
ASSERT(dstFormat == MESA_FORMAT_ARGB8888 ||
- dstFormat == MESA_FORMAT_ARGB8888_REV);
+ dstFormat == MESA_FORMAT_ARGB8888_REV ||
+ dstFormat == MESA_FORMAT_XRGB8888 ||
+ dstFormat == MESA_FORMAT_XRGB8888_REV );
ASSERT(texelBytes == 4);
if (!ctx->_ImageTransferState &&
!srcPacking->SwapBytes &&
- dstFormat == MESA_FORMAT_ARGB8888 &&
+ (dstFormat == MESA_FORMAT_ARGB8888 ||
+ dstFormat == MESA_FORMAT_XRGB8888) &&
baseInternalFormat == GL_RGBA &&
srcFormat == GL_BGRA &&
((srcType == GL_UNSIGNED_BYTE && littleEndian) ||
}
else if (!ctx->_ImageTransferState &&
!srcPacking->SwapBytes &&
- dstFormat == MESA_FORMAT_ARGB8888_REV &&
+ (dstFormat == MESA_FORMAT_ARGB8888_REV ||
+ dstFormat == MESA_FORMAT_XRGB8888_REV) &&
baseInternalFormat == GL_RGBA &&
srcFormat == GL_BGRA &&
((srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
}
else if (!ctx->_ImageTransferState &&
!srcPacking->SwapBytes &&
- dstFormat == MESA_FORMAT_ARGB8888 &&
+ (dstFormat == MESA_FORMAT_ARGB8888 ||
+ dstFormat == MESA_FORMAT_XRGB8888) &&
srcFormat == GL_RGB &&
(baseInternalFormat == GL_RGBA ||
baseInternalFormat == GL_RGB) &&
srcType == GL_UNSIGNED_BYTE) {
int img, row, col;
for (img = 0; img < srcDepth; img++) {
- const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
- srcWidth, srcFormat, srcType);
+ const GLint srcRowStride =
+ _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
GLubyte *dstRow = (GLubyte *) dstAddr
* Strangely the same isn't required for the RGB path, above.
*/
for (img = 0; img < srcDepth; img++) {
- const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
- srcWidth, srcFormat, srcType);
+ const GLint srcRowStride =
+ _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
GLubyte *dstRow = (GLubyte *) dstAddr
/* dstmap - how to swizzle from RGBA to dst format:
*/
if ((littleEndian && dstFormat == MESA_FORMAT_ARGB8888) ||
- (!littleEndian && dstFormat == MESA_FORMAT_ARGB8888_REV)) {
+ (littleEndian && dstFormat == MESA_FORMAT_XRGB8888) ||
+ (!littleEndian && dstFormat == MESA_FORMAT_ARGB8888_REV) ||
+ (!littleEndian && dstFormat == MESA_FORMAT_XRGB8888_REV)) {
dstmap[3] = 3; /* alpha */
dstmap[2] = 0; /* red */
dstmap[1] = 1; /* green */
}
else {
assert((littleEndian && dstFormat == MESA_FORMAT_ARGB8888_REV) ||
- (!littleEndian && dstFormat == MESA_FORMAT_ARGB8888));
+ (!littleEndian && dstFormat == MESA_FORMAT_ARGB8888) ||
+ (littleEndian && dstFormat == MESA_FORMAT_XRGB8888_REV) ||
+ (!littleEndian && dstFormat == MESA_FORMAT_XRGB8888));
dstmap[3] = 2;
dstmap[2] = 1;
dstmap[1] = 0;
src += 4;
}
}
+ else if (dstFormat == MESA_FORMAT_XRGB8888) {
+ for (col = 0; col < srcWidth; col++) {
+ dstUI[col] = PACK_COLOR_8888( 0xff,
+ CHAN_TO_UBYTE(src[RCOMP]),
+ CHAN_TO_UBYTE(src[GCOMP]),
+ CHAN_TO_UBYTE(src[BCOMP]) );
+ src += 4;
+ }
+ }
else {
for (col = 0; col < srcWidth; col++) {
dstUI[col] = PACK_COLOR_8888_REV( CHAN_TO_UBYTE(src[ACOMP]),
/* extract RGB from RGBA */
GLint img, row, col;
for (img = 0; img < srcDepth; img++) {
- const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
- srcWidth, srcFormat, srcType);
+ const GLint srcRowStride =
+ _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
GLubyte *dstRow = (GLubyte *) dstAddr
/* extract BGR from RGBA */
int img, row, col;
for (img = 0; img < srcDepth; img++) {
- const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
- srcWidth, srcFormat, srcType);
+ const GLint srcRowStride =
+ _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
GLubyte *dstRow = (GLubyte *) dstAddr
return GL_TRUE;
}
-static GLboolean
-_mesa_texstore_rgba4444(TEXSTORE_PARAMS)
-{
- const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
- const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
-
- ASSERT(dstFormat == MESA_FORMAT_RGBA4444);
- ASSERT(texelBytes == 2);
-
- if (!ctx->_ImageTransferState &&
- !srcPacking->SwapBytes &&
- dstFormat == MESA_FORMAT_RGBA4444 &&
- baseInternalFormat == GL_RGBA &&
- srcFormat == GL_RGBA &&
- srcType == GL_UNSIGNED_SHORT_4_4_4_4){
- /* simple memcpy path */
- memcpy_texture(ctx, dims,
- dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
- dstRowStride,
- dstImageOffsets,
- srcWidth, srcHeight, srcDepth, srcFormat, srcType,
- srcAddr, srcPacking);
- }
- else {
- /* general path */
- const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
- baseInternalFormat,
- baseFormat,
- srcWidth, srcHeight, srcDepth,
- srcFormat, srcType, srcAddr,
- srcPacking);
- const GLchan *src = tempImage;
- GLint img, row, col;
- if (!tempImage)
- return GL_FALSE;
- _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
- for (img = 0; img < srcDepth; img++) {
- GLubyte *dstRow = (GLubyte *) dstAddr
- + dstImageOffsets[dstZoffset + img] * texelBytes
- + dstYoffset * dstRowStride
- + dstXoffset * texelBytes;
- for (row = 0; row < srcHeight; row++) {
- GLushort *dstUS = (GLushort *) dstRow;
- for (col = 0; col < srcWidth; col++) {
- dstUS[col] = PACK_COLOR_4444( CHAN_TO_UBYTE(src[RCOMP]),
- CHAN_TO_UBYTE(src[GCOMP]),
- CHAN_TO_UBYTE(src[BCOMP]),
- CHAN_TO_UBYTE(src[ACOMP]) );
- src += 4;
- }
- dstRow += dstRowStride;
- }
- }
- _mesa_free((void *) tempImage);
- }
- return GL_TRUE;
-}
static GLboolean
_mesa_texstore_argb4444(TEXSTORE_PARAMS)
}
+static GLboolean
+_mesa_texstore_al1616(TEXSTORE_PARAMS)
+{
+ const GLboolean littleEndian = _mesa_little_endian();
+ const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
+ const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
+
+ ASSERT(dstFormat == MESA_FORMAT_AL1616 ||
+ dstFormat == MESA_FORMAT_AL1616_REV);
+ ASSERT(texelBytes == 4);
+
+ if (!ctx->_ImageTransferState &&
+ !srcPacking->SwapBytes &&
+ dstFormat == MESA_FORMAT_AL1616 &&
+ baseInternalFormat == GL_LUMINANCE_ALPHA &&
+ srcFormat == GL_LUMINANCE_ALPHA &&
+ srcType == GL_UNSIGNED_SHORT &&
+ littleEndian) {
+ /* simple memcpy path */
+ memcpy_texture(ctx, dims,
+ dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
+ dstRowStride,
+ dstImageOffsets,
+ srcWidth, srcHeight, srcDepth, srcFormat, srcType,
+ srcAddr, srcPacking);
+ }
+ else {
+ /* general path */
+ const GLfloat *tempImage = make_temp_float_image(ctx, dims,
+ baseInternalFormat,
+ baseFormat,
+ srcWidth, srcHeight, srcDepth,
+ srcFormat, srcType, srcAddr,
+ srcPacking);
+ const GLfloat *src = tempImage;
+ GLint img, row, col;
+ if (!tempImage)
+ return GL_FALSE;
+ _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
+ for (img = 0; img < srcDepth; img++) {
+ GLubyte *dstRow = (GLubyte *) dstAddr
+ + dstImageOffsets[dstZoffset + img] * texelBytes
+ + dstYoffset * dstRowStride
+ + dstXoffset * texelBytes;
+ for (row = 0; row < srcHeight; row++) {
+ GLuint *dstUI = (GLuint *) dstRow;
+ if (dstFormat == MESA_FORMAT_AL1616) {
+ for (col = 0; col < srcWidth; col++) {
+ /* src[0] is luminance, src[1] is alpha */
+ dstUI[col] = PACK_COLOR_88( FLOAT_TO_USHORT(src[1]),
+ FLOAT_TO_USHORT(src[0]) );
+ src += 2;
+ }
+ }
+ else {
+ for (col = 0; col < srcWidth; col++) {
+ /* src[0] is luminance, src[1] is alpha */
+ dstUI[col] = PACK_COLOR_1616_REV( FLOAT_TO_UBYTE(src[1]),
+ FLOAT_TO_UBYTE(src[0]) );
+ src += 2;
+ }
+ }
+ dstRow += dstRowStride;
+ }
+ }
+ _mesa_free((void *) tempImage);
+ }
+ return GL_TRUE;
+}
+
+
static GLboolean
_mesa_texstore_rgb332(TEXSTORE_PARAMS)
{
else {
/* general path - note this is defined for 2d textures only */
const GLint components = _mesa_components_in_format(baseInternalFormat);
- const GLint srcStride = _mesa_image_row_stride(srcPacking,
- srcWidth, srcFormat, srcType);
+ const GLint srcStride = _mesa_image_row_stride(srcPacking, srcWidth,
+ srcFormat, srcType);
GLbyte *tempImage, *dst, *src;
GLint row;
return k;
}
+#else
+
+/* these are used only in texstore_funcs[] below */
+#define _mesa_texstore_srgb8 NULL
+#define _mesa_texstore_srgba8 NULL
+#define _mesa_texstore_sargb8 NULL
+#define _mesa_texstore_sl8 NULL
+#define _mesa_texstore_sla8 NULL
+
#endif /* FEATURE_EXT_texture_sRGB */
* Table mapping MESA_FORMAT_8 to _mesa_texstore_*()
* XXX this is somewhat temporary.
*/
-static struct {
+static const struct {
gl_format Name;
StoreTexImageFunc Store;
}
{ MESA_FORMAT_RGBA8888_REV, _mesa_texstore_rgba8888 },
{ MESA_FORMAT_ARGB8888, _mesa_texstore_argb8888 },
{ MESA_FORMAT_ARGB8888_REV, _mesa_texstore_argb8888 },
+ { MESA_FORMAT_XRGB8888, _mesa_texstore_argb8888 },
+ { MESA_FORMAT_XRGB8888_REV, _mesa_texstore_argb8888 },
{ MESA_FORMAT_RGB888, _mesa_texstore_rgb888 },
{ MESA_FORMAT_BGR888, _mesa_texstore_bgr888 },
{ MESA_FORMAT_RGB565, _mesa_texstore_rgb565 },
{ MESA_FORMAT_RGB565_REV, _mesa_texstore_rgb565 },
- { MESA_FORMAT_RGBA4444, _mesa_texstore_rgba4444 },
{ MESA_FORMAT_ARGB4444, _mesa_texstore_argb4444 },
{ MESA_FORMAT_ARGB4444_REV, _mesa_texstore_argb4444 },
{ MESA_FORMAT_RGBA5551, _mesa_texstore_rgba5551 },
{ MESA_FORMAT_ARGB1555_REV, _mesa_texstore_argb1555 },
{ MESA_FORMAT_AL88, _mesa_texstore_al88 },
{ MESA_FORMAT_AL88_REV, _mesa_texstore_al88 },
+ { MESA_FORMAT_AL1616, _mesa_texstore_al1616 },
+ { MESA_FORMAT_AL1616_REV, _mesa_texstore_al1616 },
{ MESA_FORMAT_RGB332, _mesa_texstore_rgb332 },
{ MESA_FORMAT_A8, _mesa_texstore_a8 },
{ MESA_FORMAT_L8, _mesa_texstore_a8 },
{ MESA_FORMAT_Z24_S8, _mesa_texstore_z24_s8 },
{ MESA_FORMAT_S8_Z24, _mesa_texstore_s8_z24 },
{ MESA_FORMAT_Z16, _mesa_texstore_z16 },
+ { MESA_FORMAT_X8_Z24, _mesa_texstore_x8_z24 },
+ { MESA_FORMAT_Z24_X8, _mesa_texstore_z24_x8 },
{ MESA_FORMAT_Z32, _mesa_texstore_z32 },
{ MESA_FORMAT_S8, NULL/*_mesa_texstore_s8*/ },
{ MESA_FORMAT_SRGB8, _mesa_texstore_srgb8 },
{ MESA_FORMAT_RGBA_DXT1, _mesa_texstore_rgba_dxt1 },
{ MESA_FORMAT_RGBA_DXT3, _mesa_texstore_rgba_dxt3 },
{ MESA_FORMAT_RGBA_DXT5, _mesa_texstore_rgba_dxt5 },
- { MESA_FORMAT_RGBA, _mesa_texstore_rgba },
- { MESA_FORMAT_RGB, _mesa_texstore_rgba },
- { MESA_FORMAT_ALPHA, _mesa_texstore_rgba },
- { MESA_FORMAT_LUMINANCE, _mesa_texstore_rgba },
- { MESA_FORMAT_LUMINANCE_ALPHA, _mesa_texstore_rgba },
- { MESA_FORMAT_INTENSITY, _mesa_texstore_rgba },
{ MESA_FORMAT_RGBA_FLOAT32, _mesa_texstore_rgba_float32 },
{ MESA_FORMAT_RGBA_FLOAT16, _mesa_texstore_rgba_float16 },
{ MESA_FORMAT_RGB_FLOAT32, _mesa_texstore_rgba_float32 },
{ MESA_FORMAT_DUDV8, _mesa_texstore_dudv8 },
{ MESA_FORMAT_SIGNED_RGBA8888, _mesa_texstore_signed_rgba8888 },
{ MESA_FORMAT_SIGNED_RGBA8888_REV, _mesa_texstore_signed_rgba8888 },
+ { MESA_FORMAT_SIGNED_RGBA_16, NULL },
};
+static GLboolean
+_mesa_texstore_null(TEXSTORE_PARAMS)
+{
+ (void) ctx; (void) dims;
+ (void) baseInternalFormat;
+ (void) dstFormat;
+ (void) dstAddr;
+ (void) dstXoffset; (void) dstYoffset; (void) dstZoffset;
+ (void) dstRowStride; (void) dstImageOffsets;
+ (void) srcWidth; (void) srcHeight; (void) srcDepth;
+ (void) srcFormat; (void) srcType;
+ (void) srcAddr;
+ (void) srcPacking;
+
+ /* should never happen */
+ _mesa_problem(NULL, "_mesa_texstore_null() is called");
+ return GL_FALSE;
+}
+
+
/**
* Return the StoreTexImageFunc pointer to store an image in the given format.
*/
static StoreTexImageFunc
_mesa_get_texstore_func(gl_format format)
{
- GLuint i;
#ifdef DEBUG
+ GLuint i;
for (i = 0; i < MESA_FORMAT_COUNT; i++) {
ASSERT(texstore_funcs[i].Name == i);
}
#endif
ASSERT(texstore_funcs[format].Name == format);
- return texstore_funcs[format].Store;
+
+ if (texstore_funcs[format].Store)
+ return texstore_funcs[format].Store;
+ else
+ return _mesa_texstore_null;
}
storeImage = _mesa_get_texstore_func(dstFormat);
- assert(storeImage);
-
success = storeImage(ctx, dims, baseInternalFormat,
dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
dstRowStride, dstImageOffsets,
}
-
-/**
- * Adaptor for fetching a GLchan texel from a float-valued texture.
- */
-static void
-fetch_texel_float_to_chan(const struct gl_texture_image *texImage,
- GLint i, GLint j, GLint k, GLchan *texelOut)
-{
- GLfloat temp[4];
- GLenum baseFormat = _mesa_get_format_base_format(texImage->TexFormat);
-
- ASSERT(texImage->FetchTexelf);
- texImage->FetchTexelf(texImage, i, j, k, temp);
- if (baseFormat == GL_DEPTH_COMPONENT ||
- baseFormat == GL_DEPTH_STENCIL_EXT) {
- /* just one channel */
- UNCLAMPED_FLOAT_TO_CHAN(texelOut[0], temp[0]);
- }
- else {
- /* four channels */
- UNCLAMPED_FLOAT_TO_CHAN(texelOut[0], temp[0]);
- UNCLAMPED_FLOAT_TO_CHAN(texelOut[1], temp[1]);
- UNCLAMPED_FLOAT_TO_CHAN(texelOut[2], temp[2]);
- UNCLAMPED_FLOAT_TO_CHAN(texelOut[3], temp[3]);
- }
-}
-
-
-/**
- * Adaptor for fetching a float texel from a GLchan-valued texture.
- */
-static void
-fetch_texel_chan_to_float(const struct gl_texture_image *texImage,
- GLint i, GLint j, GLint k, GLfloat *texelOut)
-{
- GLchan temp[4];
- GLenum baseFormat = _mesa_get_format_base_format(texImage->TexFormat);
-
- ASSERT(texImage->FetchTexelc);
- texImage->FetchTexelc(texImage, i, j, k, temp);
- if (baseFormat == GL_DEPTH_COMPONENT ||
- baseFormat == GL_DEPTH_STENCIL_EXT) {
- /* just one channel */
- texelOut[0] = CHAN_TO_FLOAT(temp[0]);
- }
- else {
- /* four channels */
- texelOut[0] = CHAN_TO_FLOAT(temp[0]);
- texelOut[1] = CHAN_TO_FLOAT(temp[1]);
- texelOut[2] = CHAN_TO_FLOAT(temp[2]);
- texelOut[3] = CHAN_TO_FLOAT(temp[3]);
- }
-}
-
-
-/**
- * Initialize the texture image's FetchTexelc and FetchTexelf methods.
- */
-void
-_mesa_set_fetch_functions(struct gl_texture_image *texImage, GLuint dims)
+/** Return texture size in bytes */
+static GLuint
+texture_size(const struct gl_texture_image *texImage)
{
- ASSERT(dims == 1 || dims == 2 || dims == 3);
- ASSERT(texImage->TexFormat);
-
- texImage->FetchTexelf =
- _mesa_get_texel_fetch_func(texImage->TexFormat, dims);
-
- /* now check if we need to use a float/chan adaptor */
- if (!texImage->FetchTexelc) {
- texImage->FetchTexelc = fetch_texel_float_to_chan;
- }
- else if (!texImage->FetchTexelf) {
- texImage->FetchTexelf = fetch_texel_chan_to_float;
- }
-
-
- ASSERT(texImage->FetchTexelc);
- ASSERT(texImage->FetchTexelf);
+ GLuint sz = _mesa_format_image_size(texImage->TexFormat, texImage->Width,
+ texImage->Height, texImage->Depth);
+ return sz;
}
-static void
-compute_texture_size(GLcontext *ctx, struct gl_texture_image *texImage)
+/** Return row stride in bytes */
+static GLuint
+texture_row_stride(const struct gl_texture_image *texImage)
{
- texImage->IsCompressed =
- _mesa_is_format_compressed(texImage->TexFormat);
-
- if (texImage->IsCompressed) {
- texImage->CompressedSize =
- ctx->Driver.CompressedTextureSize(ctx, texImage->Width,
- texImage->Height, texImage->Depth,
- texImage->TexFormat);
- }
- else {
- /* non-compressed format */
- texImage->CompressedSize = 0;
- }
+ GLuint stride = _mesa_format_row_stride(texImage->TexFormat,
+ texImage->Width);
+ return stride;
}
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
- GLint sizeInBytes;
+ GLuint sizeInBytes;
(void) border;
- texImage->TexFormat
- = ctx->Driver.ChooseTextureFormat(ctx, internalFormat, format, type);
- ASSERT(texImage->TexFormat);
-
- _mesa_set_fetch_functions(texImage, 1);
- compute_texture_size(ctx, texImage);
-
/* allocate memory */
- if (texImage->IsCompressed)
- sizeInBytes = texImage->CompressedSize;
- else
- sizeInBytes = texImage->Width * _mesa_get_format_bytes(texImage->TexFormat);
+ sizeInBytes = texture_size(texImage);
texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
if (!texImage->Data) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
}
else {
const GLint dstRowStride = 0;
- GLboolean success;
-
- success = _mesa_texstore(ctx, 1, texImage->_BaseFormat,
- texImage->TexFormat,
- texImage->Data,
- 0, 0, 0, /* dstX/Y/Zoffset */
- dstRowStride,
- texImage->ImageOffsets,
- width, 1, 1,
- format, type, pixels, packing);
+ GLboolean success = _mesa_texstore(ctx, 1, texImage->_BaseFormat,
+ texImage->TexFormat,
+ texImage->Data,
+ 0, 0, 0, /* dstX/Y/Zoffset */
+ dstRowStride,
+ texImage->ImageOffsets,
+ width, 1, 1,
+ format, type, pixels, packing);
if (!success) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
}
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
- GLint texelBytes, sizeInBytes;
+ GLuint sizeInBytes;
(void) border;
- texImage->TexFormat
- = ctx->Driver.ChooseTextureFormat(ctx, internalFormat, format, type);
- ASSERT(texImage->TexFormat);
-
- _mesa_set_fetch_functions(texImage, 2);
- compute_texture_size(ctx, texImage);
-
- texelBytes = _mesa_get_format_bytes(texImage->TexFormat);
-
/* allocate memory */
- if (texImage->IsCompressed)
- sizeInBytes = texImage->CompressedSize;
- else
- sizeInBytes = texImage->Width * texImage->Height * texelBytes;
+ sizeInBytes = texture_size(texImage);
texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
if (!texImage->Data) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
return;
}
else {
- GLint dstRowStride;
- GLboolean success;
-
- if (texImage->IsCompressed) {
- dstRowStride
- = _mesa_compressed_row_stride(texImage->TexFormat, width);
- }
- else {
- dstRowStride = texImage->RowStride * texelBytes;
- }
-
- success = _mesa_texstore(ctx, 2, texImage->_BaseFormat,
- texImage->TexFormat,
- texImage->Data,
- 0, 0, 0, /* dstX/Y/Zoffset */
- dstRowStride,
- texImage->ImageOffsets,
- width, height, 1,
- format, type, pixels, packing);
-
+ GLint dstRowStride = texture_row_stride(texImage);
+ GLboolean success = _mesa_texstore(ctx, 2, texImage->_BaseFormat,
+ texImage->TexFormat,
+ texImage->Data,
+ 0, 0, 0, /* dstX/Y/Zoffset */
+ dstRowStride,
+ texImage->ImageOffsets,
+ width, height, 1,
+ format, type, pixels, packing);
if (!success) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
}
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
- GLint texelBytes, sizeInBytes;
+ GLuint sizeInBytes;
(void) border;
- texImage->TexFormat
- = ctx->Driver.ChooseTextureFormat(ctx, internalFormat, format, type);
- ASSERT(texImage->TexFormat);
-
- _mesa_set_fetch_functions(texImage, 3);
- compute_texture_size(ctx, texImage);
-
- texelBytes = _mesa_get_format_bytes(texImage->TexFormat);
-
/* allocate memory */
- if (texImage->IsCompressed)
- sizeInBytes = texImage->CompressedSize;
- else
- sizeInBytes = width * height * depth * texelBytes;
+ sizeInBytes = texture_size(texImage);
texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
if (!texImage->Data) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
return;
}
else {
- GLint dstRowStride;
- GLboolean success;
-
- if (texImage->IsCompressed) {
- dstRowStride
- = _mesa_compressed_row_stride(texImage->TexFormat, width);
- }
- else {
- dstRowStride = texImage->RowStride * texelBytes;
- }
-
- success = _mesa_texstore(ctx, 3, texImage->_BaseFormat,
- texImage->TexFormat,
- texImage->Data,
- 0, 0, 0, /* dstX/Y/Zoffset */
- dstRowStride,
- texImage->ImageOffsets,
- width, height, depth,
- format, type, pixels, packing);
+ GLint dstRowStride = texture_row_stride(texImage);
+ GLboolean success = _mesa_texstore(ctx, 3, texImage->_BaseFormat,
+ texImage->TexFormat,
+ texImage->Data,
+ 0, 0, 0, /* dstX/Y/Zoffset */
+ dstRowStride,
+ texImage->ImageOffsets,
+ width, height, depth,
+ format, type, pixels, packing);
if (!success) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
}
{
const GLint dstRowStride = 0;
- GLboolean success;
-
- success = _mesa_texstore(ctx, 1, texImage->_BaseFormat,
- texImage->TexFormat,
- texImage->Data,
- xoffset, 0, 0, /* offsets */
- dstRowStride,
- texImage->ImageOffsets,
- width, 1, 1,
- format, type, pixels, packing);
+ GLboolean success = _mesa_texstore(ctx, 1, texImage->_BaseFormat,
+ texImage->TexFormat,
+ texImage->Data,
+ xoffset, 0, 0, /* offsets */
+ dstRowStride,
+ texImage->ImageOffsets,
+ width, 1, 1,
+ format, type, pixels, packing);
if (!success) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D");
}
return;
{
- GLint dstRowStride = 0;
- GLboolean success;
-
- if (texImage->IsCompressed) {
- dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat,
- texImage->Width);
- }
- else {
- dstRowStride = texImage->RowStride *
- _mesa_get_format_bytes(texImage->TexFormat);
- }
-
- success = _mesa_texstore(ctx, 2, texImage->_BaseFormat,
- texImage->TexFormat,
- texImage->Data,
- xoffset, yoffset, 0,
- dstRowStride,
- texImage->ImageOffsets,
- width, height, 1,
- format, type, pixels, packing);
+ GLint dstRowStride = texture_row_stride(texImage);
+ GLboolean success = _mesa_texstore(ctx, 2, texImage->_BaseFormat,
+ texImage->TexFormat,
+ texImage->Data,
+ xoffset, yoffset, 0,
+ dstRowStride,
+ texImage->ImageOffsets,
+ width, height, 1,
+ format, type, pixels, packing);
if (!success) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
}
return;
{
- GLint dstRowStride;
- GLboolean success;
-
- if (texImage->IsCompressed) {
- dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat,
- texImage->Width);
- }
- else {
- dstRowStride = texImage->RowStride *
- _mesa_get_format_bytes(texImage->TexFormat);
- }
-
- success = _mesa_texstore(ctx, 3, texImage->_BaseFormat,
- texImage->TexFormat,
- texImage->Data,
- xoffset, yoffset, zoffset,
- dstRowStride,
- texImage->ImageOffsets,
- width, height, depth,
- format, type, pixels, packing);
+ GLint dstRowStride = texture_row_stride(texImage);
+ GLboolean success = _mesa_texstore(ctx, 3, texImage->_BaseFormat,
+ texImage->TexFormat,
+ texImage->Data,
+ xoffset, yoffset, zoffset,
+ dstRowStride,
+ texImage->ImageOffsets,
+ width, height, depth,
+ format, type, pixels, packing);
if (!success) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage3D");
}
ASSERT(texImage->Depth == 1);
ASSERT(texImage->Data == NULL); /* was freed in glCompressedTexImage2DARB */
- texImage->TexFormat
- = ctx->Driver.ChooseTextureFormat(ctx, internalFormat, 0, 0);
- ASSERT(texImage->TexFormat);
-
- _mesa_set_fetch_functions(texImage, 2);
- compute_texture_size(ctx, texImage);
-
/* allocate storage */
texImage->Data = _mesa_alloc_texmemory(imageSize);
if (!texImage->Data) {
return;
/* copy the data */
- ASSERT(texImage->CompressedSize == (GLuint) imageSize);
MEMCPY(texImage->Data, data, imageSize);
_mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
GLubyte *dest;
const GLubyte *src;
const gl_format texFormat = texImage->TexFormat;
+ const GLint destWidth = texImage->Width;
+ GLuint bw, bh;
+
+ _mesa_get_format_block_size(texFormat, &bw, &bh);
+ (void) level;
(void) format;
/* these should have been caught sooner */
- ASSERT((width & 3) == 0 || width == 2 || width == 1);
- ASSERT((height & 3) == 0 || height == 2 || height == 1);
- ASSERT((xoffset & 3) == 0);
- ASSERT((yoffset & 3) == 0);
+ ASSERT((width % bw) == 0 || width == 2 || width == 1);
+ ASSERT((height % bh) == 0 || height == 2 || height == 1);
+ ASSERT((xoffset % bw) == 0);
+ ASSERT((yoffset % bh) == 0);
/* get pointer to src pixels (may be in a pbo which we'll map here) */
data = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, data,
if (!data)
return;
- srcRowStride = _mesa_compressed_row_stride(texFormat, width);
+ srcRowStride = _mesa_format_row_stride(texFormat, width);
src = (const GLubyte *) data;
- destRowStride = _mesa_compressed_row_stride(texFormat, texImage->Width);
+ destRowStride = _mesa_format_row_stride(texFormat, destWidth);
dest = _mesa_compressed_image_address(xoffset, yoffset, 0,
- texFormat,
- texImage->Width,
+ texFormat, destWidth,
(GLubyte *) texImage->Data);
- bytesPerRow = srcRowStride;
- rows = height / 4;
+ bytesPerRow = srcRowStride; /* bytes per row of blocks */
+ rows = height / bh; /* rows in blocks */
+ /* copy rows of blocks */
for (i = 0; i < rows; i++) {
MEMCPY(dest, src, bytesPerRow);
dest += destRowStride;