-/* $Id: texformat.c,v 1.9 2001/04/04 23:56:33 brianp Exp $ */
+/* $Id: texformat.c,v 1.10 2001/04/20 16:46:04 brianp Exp $ */
/*
* Mesa 3-D graphics library
const struct gl_texture_format _mesa_texformat_rgba = {
MESA_FORMAT_RGBA, /* MesaFormat */
- GL_RGBA, /* IntFormat */
+ GL_RGBA, /* BaseFormat */
CHAN_TYPE, /* Type */
CHAN_BITS, /* RedBits */
CHAN_BITS, /* GreenBits */
const struct gl_texture_format _mesa_texformat_rgb = {
MESA_FORMAT_RGB, /* MesaFormat */
- GL_RGB, /* IntFormat */
+ GL_RGB, /* BaseFormat */
CHAN_TYPE, /* Type */
CHAN_BITS, /* RedBits */
CHAN_BITS, /* GreenBits */
const struct gl_texture_format _mesa_texformat_alpha = {
MESA_FORMAT_ALPHA, /* MesaFormat */
- GL_ALPHA, /* IntFormat */
+ GL_ALPHA, /* BaseFormat */
CHAN_TYPE, /* Type */
0, /* RedBits */
0, /* GreenBits */
const struct gl_texture_format _mesa_texformat_luminance = {
MESA_FORMAT_LUMINANCE, /* MesaFormat */
- GL_LUMINANCE, /* IntFormat */
+ GL_LUMINANCE, /* BaseFormat */
CHAN_TYPE, /* Type */
0, /* RedBits */
0, /* GreenBits */
const struct gl_texture_format _mesa_texformat_luminance_alpha = {
MESA_FORMAT_LUMINANCE_ALPHA, /* MesaFormat */
- GL_LUMINANCE_ALPHA, /* IntFormat */
+ GL_LUMINANCE_ALPHA, /* BaseFormat */
CHAN_TYPE, /* Type */
0, /* RedBits */
0, /* GreenBits */
const struct gl_texture_format _mesa_texformat_intensity = {
MESA_FORMAT_INTENSITY, /* MesaFormat */
- GL_INTENSITY, /* IntFormat */
+ GL_INTENSITY, /* BaseFormat */
CHAN_TYPE, /* Type */
0, /* RedBits */
0, /* GreenBits */
const struct gl_texture_format _mesa_texformat_color_index = {
MESA_FORMAT_COLOR_INDEX, /* MesaFormat */
- GL_COLOR_INDEX, /* IntFormat */
+ GL_COLOR_INDEX, /* BaseFormat */
CHAN_TYPE, /* Type */
0, /* RedBits */
0, /* GreenBits */
const struct gl_texture_format _mesa_texformat_depth_component = {
MESA_FORMAT_DEPTH_COMPONENT, /* MesaFormat */
- GL_DEPTH_COMPONENT, /* IntFormat */
+ GL_DEPTH_COMPONENT, /* BaseFormat */
GL_FLOAT, /* Type */
0, /* RedBits */
0, /* GreenBits */
const struct gl_texture_format _mesa_texformat_rgba8888 = {
MESA_FORMAT_RGBA8888, /* MesaFormat */
- GL_RGBA, /* IntFormat */
+ GL_RGBA, /* BaseFormat */
GL_UNSIGNED_INT_8_8_8_8, /* Type */
8, /* RedBits */
8, /* GreenBits */
const struct gl_texture_format _mesa_texformat_argb8888 = {
MESA_FORMAT_ARGB8888, /* MesaFormat */
- GL_RGBA, /* IntFormat */
+ GL_RGBA, /* BaseFormat */
GL_UNSIGNED_INT_8_8_8_8_REV, /* Type */
8, /* RedBits */
8, /* GreenBits */
const struct gl_texture_format _mesa_texformat_rgb888 = {
MESA_FORMAT_RGB888, /* MesaFormat */
- GL_BGR, /* IntFormat */
+ GL_RGB, /* BaseFormat */
GL_UNSIGNED_BYTE, /* Type */
8, /* RedBits */
8, /* GreenBits */
const struct gl_texture_format _mesa_texformat_rgb565 = {
MESA_FORMAT_RGB565, /* MesaFormat */
- GL_RGB, /* IntFormat */
+ GL_RGB, /* BaseFormat */
GL_UNSIGNED_SHORT_5_6_5, /* Type */
5, /* RedBits */
6, /* GreenBits */
const struct gl_texture_format _mesa_texformat_argb4444 = {
MESA_FORMAT_ARGB4444, /* MesaFormat */
- GL_RGBA, /* IntFormat */
+ GL_RGBA, /* BaseFormat */
GL_UNSIGNED_SHORT_4_4_4_4_REV, /* Type */
4, /* RedBits */
4, /* GreenBits */
const struct gl_texture_format _mesa_texformat_argb1555 = {
MESA_FORMAT_ARGB1555, /* MesaFormat */
- GL_RGBA, /* IntFormat */
+ GL_RGBA, /* BaseFormat */
GL_UNSIGNED_SHORT_1_5_5_5_REV, /* Type */
5, /* RedBits */
5, /* GreenBits */
const struct gl_texture_format _mesa_texformat_al88 = {
MESA_FORMAT_AL88, /* MesaFormat */
- GL_LUMINANCE_ALPHA, /* IntFormat */
+ GL_LUMINANCE_ALPHA, /* BaseFormat */
GL_UNSIGNED_BYTE, /* Type */
0, /* RedBits */
0, /* GreenBits */
const struct gl_texture_format _mesa_texformat_rgb332 = {
MESA_FORMAT_RGB332, /* MesaFormat */
- GL_RGB, /* IntFormat */
+ GL_RGB, /* BaseFormat */
GL_UNSIGNED_BYTE_3_3_2, /* Type */
3, /* RedBits */
3, /* GreenBits */
const struct gl_texture_format _mesa_texformat_a8 = {
MESA_FORMAT_A8, /* MesaFormat */
- GL_ALPHA, /* IntFormat */
+ GL_ALPHA, /* BaseFormat */
GL_UNSIGNED_BYTE, /* Type */
0, /* RedBits */
0, /* GreenBits */
const struct gl_texture_format _mesa_texformat_l8 = {
MESA_FORMAT_L8, /* MesaFormat */
- GL_LUMINANCE, /* IntFormat */
+ GL_LUMINANCE, /* BaseFormat */
GL_UNSIGNED_BYTE, /* Type */
0, /* RedBits */
0, /* GreenBits */
const struct gl_texture_format _mesa_texformat_i8 = {
MESA_FORMAT_I8, /* MesaFormat */
- GL_INTENSITY, /* IntFormat */
+ GL_INTENSITY, /* BaseFormat */
GL_UNSIGNED_BYTE, /* Type */
0, /* RedBits */
0, /* GreenBits */
const struct gl_texture_format _mesa_texformat_ci8 = {
MESA_FORMAT_CI8, /* MesaFormat */
- GL_COLOR_INDEX, /* IntFormat */
+ GL_COLOR_INDEX, /* BaseFormat */
GL_UNSIGNED_BYTE, /* Type */
0, /* RedBits */
0, /* GreenBits */
const struct gl_texture_format _mesa_null_texformat = {
-1, /* MesaFormat */
- 0, /* IntFormat */
+ 0, /* BaseFormat */
0, /* Type */
0, /* RedBits */
0, /* GreenBits */
-/* $Id: texstore.c,v 1.23 2001/04/04 22:41:23 brianp Exp $ */
+/* $Id: texstore.c,v 1.24 2001/04/20 16:46:04 brianp Exp $ */
/*
* Mesa 3-D graphics library
* Brian Paul
*/
-
-/*
- * The functions in this file are mostly related to software texture fallbacks.
- * This includes texture image transfer/packing and texel fetching.
- * Hardware drivers will likely override most of this.
- */
-
-
-
#include "colormac.h"
#include "context.h"
#include "convolve.h"
* srcFormat - source image format (GL_ALPHA, GL_RED, GL_RGB, etc)
* srcType - GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT_5_6_5, GL_FLOAT, etc
* srcPacking - describes packing of incoming image.
+ * transferOps - mask of pixel transfer operations
*/
static void
transfer_teximage(GLcontext *ctx, GLuint dimensions,
GLint dstRowStride, GLint dstImageStride,
GLenum srcFormat, GLenum srcType,
const GLvoid *srcAddr,
- const struct gl_pixelstore_attrib *srcPacking)
+ const struct gl_pixelstore_attrib *srcPacking,
+ GLuint transferOps)
{
GLint texComponents;
texComponents = components_in_intformat(texDestFormat);
/* try common 2D texture cases first */
- if (!ctx->_ImageTransferState && dimensions == 2 && srcType == CHAN_TYPE) {
+ if (!transferOps && dimensions == 2 && srcType == CHAN_TYPE) {
if (srcFormat == texDestFormat) {
/* This will cover the common GL_RGB, GL_RGBA, GL_ALPHA,
const GLvoid *src = _mesa_image_address(srcPacking,
srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
_mesa_unpack_index_span(ctx, srcWidth, texType, destRow,
- srcType, src, srcPacking,
- ctx->_ImageTransferState);
+ srcType, src, srcPacking, transferOps);
destRow += dstRowStride;
}
dest += dstImageStride;
srcFormat, srcType, img, row, 0);
_mesa_unpack_float_color_span(ctx, srcWidth, GL_RGBA, dstf,
srcFormat, srcType, src, srcPacking,
- ctx->_ImageTransferState & IMAGE_PRE_CONVOLUTION_BITS,
+ transferOps & IMAGE_PRE_CONVOLUTION_BITS,
GL_TRUE);
dstf += srcWidth * 4;
}
(const GLfloat (*)[4]) srcf,
texDestFormat, CHAN_TYPE,
dest, &_mesa_native_packing,
- ctx->_ImageTransferState
+ transferOps
& IMAGE_POST_CONVOLUTION_BITS);
srcf += convWidth * 4;
dest += dstRowStride;
srcFormat, srcType, img, row, 0);
_mesa_unpack_chan_color_span(ctx, srcWidth, texDestFormat,
destRow, srcFormat, srcType, srcRow,
- srcPacking, ctx->_ImageTransferState);
+ srcPacking, transferOps);
destRow += dstRowStride;
}
dest += dstImageStride;
* needed image transfer operations and storing the result in the format
* specified by <dstFormat>. <dstFormat> may be any format from texformat.h.
* Input:
+ * dimensions - 1, 2 or 3
+ * baseInternalFormat - base format of the internal texture format
+ * specified by the user. This is very important, see below.
+ * dstFormat - destination image format
+ * dstAddr - destination address
+ * srcWidth, srcHeight, srcDepth - size of source iamge
+ * dstX/Y/Zoffset - as specified by glTexSubImage
* dstRowStride - stride between dest rows in bytes
* dstImagetride - stride between dest images in bytes
+ * srcFormat, srcType - incoming image format and datatype
+ * srcAddr - source image address
+ * srcPacking - packing params of source image
*
* XXX this function is a bit more complicated than it should be. If
* _mesa_convert_texsubimage[123]d could handle any dest/source formats
*/
void
_mesa_transfer_teximage(GLcontext *ctx, GLuint dimensions,
+ GLenum baseInternalFormat,
const struct gl_texture_format *dstFormat,
GLvoid *dstAddr,
GLint srcWidth, GLint srcHeight, GLint srcDepth,
const GLint dstRowStridePixels = dstRowStride / dstFormat->TexelBytes;
const GLint dstImageStridePixels = dstImageStride / dstFormat->TexelBytes;
GLboolean makeTemp;
+ GLuint transferOps = ctx->_ImageTransferState;
+ GLboolean freeSourceData = GL_FALSE;
+ GLint postConvWidth = srcWidth, postConvHeight = srcHeight;
+
+ if (transferOps & IMAGE_CONVOLUTION_BIT) {
+ _mesa_adjust_image_for_convolution(ctx, dimensions, &postConvWidth,
+ &postConvHeight);
+ }
+
+ /*
+ * Consider this scenario: The user's source image is GL_RGB and the
+ * requested internal format is GL_LUMINANCE. Now suppose the device
+ * driver doesn't support GL_LUMINANCE and instead uses RGB16 as the
+ * texture format. In that case we still need to do an intermediate
+ * conversion to luminance format so that the incoming red channel gets
+ * replicated into the dest red, green and blue channels. The following
+ * code takes care of that.
+ */
+ if (dstFormat->BaseFormat != baseInternalFormat) {
+ /* Allocate storage for temporary image in the baseInternalFormat */
+ const GLint texelSize = _mesa_components_in_format(baseInternalFormat)
+ * sizeof(GLchan);
+ const GLint bytes = texelSize * postConvWidth * postConvHeight *srcDepth;
+ const GLint tmpRowStride = texelSize * postConvWidth;
+ const GLint tmpImgStride = texelSize * postConvWidth * postConvHeight;
+ GLvoid *tmpImage = MALLOC(bytes);
+ if (!tmpImage)
+ return;
+ transfer_teximage(ctx, dimensions, baseInternalFormat, tmpImage,
+ srcWidth, srcHeight, srcDepth,
+ 0, 0, 0, /* x/y/zoffset */
+ tmpRowStride, tmpImgStride,
+ srcFormat, srcType, srcAddr, srcPacking, transferOps);
+
+ /* this is our new source image */
+ srcWidth = postConvWidth;
+ srcHeight = postConvHeight;
+ srcFormat = baseInternalFormat;
+ srcType = CHAN_TYPE;
+ srcAddr = tmpImage;
+ srcPacking = &_mesa_native_packing;
+ freeSourceData = GL_TRUE;
+ transferOps = 0; /* image transfer ops were completed */
+ }
- /* First, determine if need to make a temporary, intermediate image */
+ /* Let the optimized tex conversion functions take a crack at the
+ * image conversion if the dest format is a h/w format.
+ */
if (_mesa_is_hardware_tex_format(dstFormat)) {
- if (ctx->_ImageTransferState) {
+ if (transferOps) {
makeTemp = GL_TRUE;
}
else {
}
if (!makeTemp) {
/* all done! */
+ if (freeSourceData)
+ FREE((void *) srcAddr);
return;
}
}
GLint tmpRowStride, tmpImageStride;
GLubyte *tmpImage;
- if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
+ if (transferOps & IMAGE_CONVOLUTION_BIT) {
_mesa_adjust_image_for_convolution(ctx, dimensions, &postConvWidth,
&postConvHeight);
}
- tmpFormat = _mesa_base_tex_format(ctx, dstFormat->IntFormat);
+ tmpFormat = dstFormat->BaseFormat;
tmpComps = _mesa_components_in_format(tmpFormat);
tmpTexelSize = tmpComps * sizeof(GLchan);
tmpRowStride = postConvWidth * tmpTexelSize;
tmpImageStride = postConvWidth * postConvHeight * tmpTexelSize;
tmpImage = (GLubyte *) MALLOC(postConvWidth * postConvHeight *
srcDepth * tmpTexelSize);
- if (!tmpImage)
+ if (!tmpImage) {
+ if (freeSourceData)
+ FREE((void *) srcAddr);
return;
+ }
transfer_teximage(ctx, dimensions, tmpFormat, tmpImage,
srcWidth, srcHeight, srcDepth,
0, 0, 0, /* x/y/zoffset */
tmpRowStride, tmpImageStride,
- srcFormat, srcType, srcAddr, srcPacking);
+ srcFormat, srcType, srcAddr, srcPacking, transferOps);
+
+ if (freeSourceData)
+ FREE((void *) srcAddr);
/* the temp image is our new source image */
srcWidth = postConvWidth;
srcType = CHAN_TYPE;
srcAddr = tmpImage;
srcPacking = &_mesa_native_packing;
+ freeSourceData = GL_TRUE;
}
if (_mesa_is_hardware_tex_format(dstFormat)) {
srcPacking, srcAddr, dstAddr);
assert(b);
}
- FREE((void *) srcAddr); /* the temp image */
}
else {
/* software format */
- GLenum dstBaseFormat = _mesa_base_tex_format(ctx, dstFormat->IntFormat);
assert(!makeTemp);
- transfer_teximage(ctx, dimensions, dstBaseFormat, dstAddr,
+ transfer_teximage(ctx, dimensions, dstFormat->BaseFormat, dstAddr,
srcWidth, srcHeight, srcDepth,
dstXoffset, dstYoffset, dstZoffset,
dstRowStride, dstImageStride,
- srcFormat, srcType, srcAddr, srcPacking);
+ srcFormat, srcType, srcAddr, srcPacking, transferOps);
}
+
+ if (freeSourceData)
+ FREE((void *) srcAddr); /* the temp image */
}
}
/* unpack image, apply transfer ops and store in texImage->Data */
- _mesa_transfer_teximage(ctx, 1, texImage->TexFormat, texImage->Data,
+ _mesa_transfer_teximage(ctx, 1, _mesa_base_tex_format(ctx, internalFormat),
+ texImage->TexFormat, texImage->Data,
width, 1, 1, 0, 0, 0,
0, /* dstRowStride */
0, /* dstImageStride */
}
/* unpack image, apply transfer ops and store in texImage->Data */
- _mesa_transfer_teximage(ctx, 2, texImage->TexFormat, texImage->Data,
+ _mesa_transfer_teximage(ctx, 2, _mesa_base_tex_format(ctx, internalFormat),
+ texImage->TexFormat, texImage->Data,
width, height, 1, 0, 0, 0,
texImage->Width * texelBytes,
0, /* dstImageStride */
}
/* unpack image, apply transfer ops and store in texImage->Data */
- _mesa_transfer_teximage(ctx, 3, texImage->TexFormat, texImage->Data,
+ _mesa_transfer_teximage(ctx, 3, _mesa_base_tex_format(ctx, internalFormat),
+ texImage->TexFormat, texImage->Data,
width, height, depth, 0, 0, 0,
texImage->Width * texelBytes,
texImage->Width * texImage->Height * texelBytes,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
- _mesa_transfer_teximage(ctx, 1, texImage->TexFormat, texImage->Data,
+ _mesa_transfer_teximage(ctx, 1,
+ _mesa_base_tex_format(ctx, texImage->IntFormat),
+ texImage->TexFormat, texImage->Data,
width, 1, 1, /* src size */
xoffset, 0, 0, /* dest offsets */
0, /* dstRowStride */
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
- _mesa_transfer_teximage(ctx, 2, texImage->TexFormat, texImage->Data,
+ _mesa_transfer_teximage(ctx, 2,
+ _mesa_base_tex_format(ctx, texImage->IntFormat),
+ texImage->TexFormat, texImage->Data,
width, height, 1, /* src size */
xoffset, yoffset, 0, /* dest offsets */
texImage->Width * texImage->TexFormat->TexelBytes,
struct gl_texture_image *texImage)
{
const GLint texelBytes = texImage->TexFormat->TexelBytes;
- _mesa_transfer_teximage(ctx, 3, texImage->TexFormat, texImage->Data,
+ _mesa_transfer_teximage(ctx, 3,
+ _mesa_base_tex_format(ctx, texImage->IntFormat),
+ texImage->TexFormat, texImage->Data,
width, height, depth, /* src size */
xoffset, yoffset, xoffset, /* dest offsets */
texImage->Width * texelBytes,