}
-#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) */
/* 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++) {
}
-#define STRIDE_3D 0
+/**
+ * Store a 24-bit integer depth component texture image.
+ */
+static GLboolean
+_mesa_texstore_z24_x8(TEXSTORE_PARAMS)
+{
+ const GLuint depthScale = 0xffffff;
+ const GLuint texelBytes = 4;
+
+ (void) dims;
+ ASSERT(dstFormat == MESA_FORMAT_Z24_X8);
+
+ {
+ /* general path */
+ GLint img, row;
+ for (img = 0; img < srcDepth; img++) {
+ GLubyte *dstRow = (GLubyte *) dstAddr
+ + dstImageOffsets[dstZoffset + img] * texelBytes
+ + dstYoffset * dstRowStride
+ + dstXoffset * texelBytes;
+ 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, dst,
+ depthScale, srcType, src, srcPacking);
+ for (i = 0; i < srcWidth; i++)
+ dst[i] <<= 8;
+ dstRow += dstRowStride;
+ }
+ }
+ }
+ return GL_TRUE;
+}
+
/**
* Store a 16-bit integer depth component texture image.
{
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_XRGB8888);
+ dstFormat == MESA_FORMAT_XRGB8888 ||
+ dstFormat == MESA_FORMAT_XRGB8888_REV );
ASSERT(texelBytes == 4);
if (!ctx->_ImageTransferState &&
}
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) ||
*/
if ((littleEndian && dstFormat == MESA_FORMAT_ARGB8888) ||
(littleEndian && dstFormat == MESA_FORMAT_XRGB8888) ||
- (!littleEndian && dstFormat == MESA_FORMAT_ARGB8888_REV)) {
+ (!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_XRGB8888_REV) ||
(!littleEndian && dstFormat == MESA_FORMAT_XRGB8888));
dstmap[3] = 2;
dstmap[2] = 1;
}
+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)
{
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_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_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_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 },
};
+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,
static GLuint
texture_row_stride(const struct gl_texture_image *texImage)
{
- GLuint stride;
-
- if (_mesa_is_format_compressed(texImage->TexFormat)) {
- stride = _mesa_compressed_row_stride(texImage->TexFormat,
+ GLuint stride = _mesa_format_row_stride(texImage->TexFormat,
texImage->Width);
- }
- else {
- GLuint texelBytes = _mesa_get_format_bytes(texImage->TexFormat);
- stride = texImage->RowStride * texelBytes;
- }
-
return stride;
}
GLuint sizeInBytes;
(void) border;
- texImage->TexFormat
- = ctx->Driver.ChooseTextureFormat(ctx, internalFormat, format, type);
- ASSERT(texImage->TexFormat);
-
/* allocate memory */
sizeInBytes = texture_size(texImage);
texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
GLuint sizeInBytes;
(void) border;
- texImage->TexFormat
- = ctx->Driver.ChooseTextureFormat(ctx, internalFormat, format, type);
- ASSERT(texImage->TexFormat);
-
/* allocate memory */
sizeInBytes = texture_size(texImage);
texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
GLuint sizeInBytes;
(void) border;
- texImage->TexFormat
- = ctx->Driver.ChooseTextureFormat(ctx, internalFormat, format, type);
- ASSERT(texImage->TexFormat);
-
/* allocate memory */
sizeInBytes = texture_size(texImage);
texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
ASSERT(texImage->Depth == 1);
ASSERT(texImage->Data == NULL); /* was freed in glCompressedTexImage2DARB */
- texImage->TexFormat
- = ctx->Driver.ChooseTextureFormat(ctx, internalFormat, 0, 0);
- ASSERT(texImage->TexFormat);
-
/* allocate storage */
texImage->Data = _mesa_alloc_texmemory(imageSize);
if (!texImage->Data) {
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;