diff options
author | Brian Paul <[email protected]> | 2001-04-04 21:54:20 +0000 |
---|---|---|
committer | Brian Paul <[email protected]> | 2001-04-04 21:54:20 +0000 |
commit | 7d58f44f73be59bd3583e6dfeedf56c43f7fbd55 (patch) | |
tree | ff9f85c072c0fb669a959f12f74ca5f2b2bfc1e4 /src/mesa/main | |
parent | bb0830da9e35666f26bb0e5e530d18d8b9ec8e71 (diff) |
More texture image changes.
1. Added ctx->Driver.ChooseTextureFormat() function. Examines user's
internalFormat, format, type params and returns a gl_texture_format.
2. _mesa_store_teximage[123]d() calls ctx->Driver.ChooseTextureFormat(),
allocates storage and transfers the image into the desired format.
3. _mesa_transfer_teximage() now takes a gl_texture_format to describe
the destination format. Any combination of input format/type and
output gl_texture_format is accepted. Uses optimized _mesa_convert_-
texsubimage[123]d() functions when possible.
3. DRI driver's TexImage[123]D functions should be a lot simpler now.
Diffstat (limited to 'src/mesa/main')
-rw-r--r-- | src/mesa/main/dd.h | 10 | ||||
-rw-r--r-- | src/mesa/main/texformat.c | 65 | ||||
-rw-r--r-- | src/mesa/main/texformat.h | 11 | ||||
-rw-r--r-- | src/mesa/main/texstore.c | 246 | ||||
-rw-r--r-- | src/mesa/main/texstore.h | 5 |
5 files changed, 254 insertions, 83 deletions
diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h index 469f2363cb7..e69ad2d740f 100644 --- a/src/mesa/main/dd.h +++ b/src/mesa/main/dd.h @@ -1,4 +1,4 @@ -/* $Id: dd.h,v 1.60 2001/03/22 00:36:27 gareth Exp $ */ +/* $Id: dd.h,v 1.61 2001/04/04 21:54:20 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -170,6 +170,14 @@ struct dd_function_table { /*** *** Texture image functions: ***/ + const struct gl_texture_format * + (*ChooseTextureFormat)( GLcontext *ctx, GLint internalFormat, + GLenum srcFormat, GLenum srcType ); + /* This is called by the _mesa_store_tex[sub]image[123]d() fallback + * functions. The driver should examine <internalFormat> and return a + * pointer to an appropriate gl_texture_format. + */ + void (*TexImage1D)( GLcontext *ctx, GLenum target, GLint level, GLint internalFormat, GLint width, GLint border, diff --git a/src/mesa/main/texformat.c b/src/mesa/main/texformat.c index 8c770f664a4..739df30346c 100644 --- a/src/mesa/main/texformat.c +++ b/src/mesa/main/texformat.c @@ -1,4 +1,4 @@ -/* $Id: texformat.c,v 1.7 2001/03/30 14:44:43 gareth Exp $ */ +/* $Id: texformat.c,v 1.8 2001/04/04 21:54:21 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -462,26 +462,24 @@ const struct gl_texture_format _mesa_null_texformat = { +GLboolean +_mesa_is_hardware_tex_format( const struct gl_texture_format *format ) +{ + return (format->MesaFormat < MESA_FORMAT_RGBA); +} + + /* Given an internal texture format or 1, 2, 3, 4 initialize the texture * image structure's default format and type information. Drivers will * initialize these fields accordingly if they override the default * storage format. */ -void _mesa_init_tex_format( GLcontext *ctx, GLenum internalFormat, - struct gl_texture_image *texImage ) +const struct gl_texture_format * +_mesa_choose_tex_format( GLcontext *ctx, GLint internalFormat, + GLenum format, GLenum type ) { - const struct gl_texture_format *texFormat; - - /* Ask the driver for the base format, if it doesn't know, it will - * return -1; - */ - if ( ctx->Driver.BaseCompressedTexFormat ) { - GLint format = 0; /* Silence compiler warning */ - format = (*ctx->Driver.BaseCompressedTexFormat)( ctx, format ); - if ( format >= 0 ) { - internalFormat = format; - } - } + (void) format; + (void) type; switch ( internalFormat ) { /* GH: Bias towards GL_RGB, GL_RGBA texture formats. This has @@ -490,13 +488,11 @@ void _mesa_init_tex_format( GLcontext *ctx, GLenum internalFormat, */ case 4: /* Quake3 uses this... */ case GL_RGBA: - texFormat = &_mesa_texformat_rgba; - break; + return &_mesa_texformat_rgba; case 3: /* ... and this. */ case GL_RGB: - texFormat = &_mesa_texformat_rgb; - break; + return &_mesa_texformat_rgb; /* GH: Okay, keep checking as normal. Still test for GL_RGB, * GL_RGBA formats first. @@ -508,8 +504,7 @@ void _mesa_init_tex_format( GLcontext *ctx, GLenum internalFormat, case GL_RGB10_A2: case GL_RGBA12: case GL_RGBA16: - texFormat = &_mesa_texformat_rgba; - break; + return &_mesa_texformat_rgba; case GL_R3_G3_B2: case GL_RGB4: @@ -518,16 +513,14 @@ void _mesa_init_tex_format( GLcontext *ctx, GLenum internalFormat, case GL_RGB10: case GL_RGB12: case GL_RGB16: - texFormat = &_mesa_texformat_rgb; - break; + return &_mesa_texformat_rgb; case GL_ALPHA: case GL_ALPHA4: case GL_ALPHA8: case GL_ALPHA12: case GL_ALPHA16: - texFormat = &_mesa_texformat_alpha; - break; + return &_mesa_texformat_alpha; case 1: case GL_LUMINANCE: @@ -535,8 +528,7 @@ void _mesa_init_tex_format( GLcontext *ctx, GLenum internalFormat, case GL_LUMINANCE8: case GL_LUMINANCE12: case GL_LUMINANCE16: - texFormat = &_mesa_texformat_luminance; - break; + return &_mesa_texformat_luminance; case 2: case GL_LUMINANCE_ALPHA: @@ -546,16 +538,14 @@ void _mesa_init_tex_format( GLcontext *ctx, GLenum internalFormat, case GL_LUMINANCE12_ALPHA4: case GL_LUMINANCE12_ALPHA12: case GL_LUMINANCE16_ALPHA16: - texFormat = &_mesa_texformat_luminance_alpha; - break; + return &_mesa_texformat_luminance_alpha; case GL_INTENSITY: case GL_INTENSITY4: case GL_INTENSITY8: case GL_INTENSITY12: case GL_INTENSITY16: - texFormat = &_mesa_texformat_intensity; - break; + return &_mesa_texformat_intensity; case GL_COLOR_INDEX: case GL_COLOR_INDEX1_EXT: @@ -564,8 +554,7 @@ void _mesa_init_tex_format( GLcontext *ctx, GLenum internalFormat, case GL_COLOR_INDEX8_EXT: case GL_COLOR_INDEX12_EXT: case GL_COLOR_INDEX16_EXT: - texFormat = &_mesa_texformat_color_index; - break; + return &_mesa_texformat_color_index; case GL_DEPTH_COMPONENT: case GL_DEPTH_COMPONENT16_SGIX: @@ -573,13 +562,11 @@ void _mesa_init_tex_format( GLcontext *ctx, GLenum internalFormat, case GL_DEPTH_COMPONENT32_SGIX: if ( !ctx->Extensions.SGIX_depth_texture ) _mesa_problem( ctx, "depth format without GL_SGIX_depth_texture" ); - texFormat = &_mesa_texformat_depth_component; - break; + return &_mesa_texformat_depth_component; default: - _mesa_problem( ctx, "unexpected format in _mesa_init_tex_format" ); - return; + _mesa_problem( ctx, "unexpected format in _mesa_choose_tex_format()" ); + printf("intformat = %d %x\n", internalFormat, internalFormat ); + return NULL; } - - texImage->TexFormat = texFormat; } diff --git a/src/mesa/main/texformat.h b/src/mesa/main/texformat.h index 6f686265ef2..ac6dbc0cb72 100644 --- a/src/mesa/main/texformat.h +++ b/src/mesa/main/texformat.h @@ -1,4 +1,4 @@ -/* $Id: texformat.h,v 1.5 2001/03/22 06:26:18 gareth Exp $ */ +/* $Id: texformat.h,v 1.6 2001/04/04 21:54:21 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -83,9 +83,12 @@ enum _format { }; -extern void -_mesa_init_tex_format( GLcontext *ctx, GLenum internalFormat, - struct gl_texture_image *texImage ); +extern GLboolean +_mesa_is_hardware_tex_format( const struct gl_texture_format *format ); + +extern const struct gl_texture_format * +_mesa_choose_tex_format( GLcontext *ctx, GLint internalFormat, + GLenum format, GLenum type ); /* The default formats, GLchan per component: diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c index 0647b2c7d55..95f16b20768 100644 --- a/src/mesa/main/texstore.c +++ b/src/mesa/main/texstore.c @@ -1,4 +1,4 @@ -/* $Id: texstore.c,v 1.21 2001/03/28 20:40:51 gareth Exp $ */ +/* $Id: texstore.c,v 1.22 2001/04/04 21:54:21 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -47,6 +47,7 @@ #include "texformat.h" #include "teximage.h" #include "texstore.h" +#include "texutil.h" /* @@ -154,15 +155,15 @@ components_in_intformat( GLint format ) * srcType - GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT_5_6_5, GL_FLOAT, etc * srcPacking - describes packing of incoming image. */ -void -_mesa_transfer_teximage(GLcontext *ctx, GLuint dimensions, - GLenum texDestFormat, GLvoid *texDestAddr, - GLint srcWidth, GLint srcHeight, GLint srcDepth, - GLint dstXoffset, GLint dstYoffset, GLint dstZoffset, - GLint dstRowStride, GLint dstImageStride, - GLenum srcFormat, GLenum srcType, - const GLvoid *srcAddr, - const struct gl_pixelstore_attrib *srcPacking) +static void +transfer_teximage(GLcontext *ctx, GLuint dimensions, + GLenum texDestFormat, GLvoid *texDestAddr, + GLint srcWidth, GLint srcHeight, GLint srcDepth, + GLint dstXoffset, GLint dstYoffset, GLint dstZoffset, + GLint dstRowStride, GLint dstImageStride, + GLenum srcFormat, GLenum srcType, + const GLvoid *srcAddr, + const struct gl_pixelstore_attrib *srcPacking) { GLint texComponents; @@ -382,6 +383,163 @@ _mesa_transfer_teximage(GLcontext *ctx, GLuint dimensions, /* + * Transfer a texture image from user space to <destAddr> applying all + * needed image transfer operations and storing the result in the format + * specified by <dstFormat>. <dstFormat> may be any format from texformat.h. + * Input: + * dstRowStride - stride between dest rows in bytes + * dstImagetride - stride between dest images in bytes + * + * XXX this function is a bit more complicated than it should be. If + * _mesa_convert_texsubimage[123]d could handle any dest/source formats + * or if transfer_teximage() could store in any MESA_FORMAT_* format, we + * could simplify things here. + */ +void +_mesa_transfer_teximage(GLcontext *ctx, GLuint dimensions, + const struct gl_texture_format *dstFormat, + GLvoid *dstAddr, + GLint srcWidth, GLint srcHeight, GLint srcDepth, + GLint dstXoffset, GLint dstYoffset, GLint dstZoffset, + GLint dstRowStride, GLint dstImageStride, + GLenum srcFormat, GLenum srcType, + const GLvoid *srcAddr, + const struct gl_pixelstore_attrib *srcPacking) +{ + const GLint dstRowStridePixels = dstRowStride / dstFormat->TexelBytes; + const GLint dstImageStridePixels = dstImageStride / dstFormat->TexelBytes; + GLboolean makeTemp; + + /* First, determine if need to make a temporary, intermediate image */ + if (_mesa_is_hardware_tex_format(dstFormat)) { + if (ctx->_ImageTransferState) { + makeTemp = GL_TRUE; + } + else { + if (dimensions == 1) { + makeTemp = !_mesa_convert_texsubimage1d(dstFormat->MesaFormat, + dstXoffset, + srcWidth, + srcFormat, srcType, + srcPacking, srcAddr, + dstAddr); + } + else if (dimensions == 2) { + makeTemp = !_mesa_convert_texsubimage2d(dstFormat->MesaFormat, + dstXoffset, dstYoffset, + srcWidth, srcHeight, + dstRowStridePixels, + srcFormat, srcType, + srcPacking, srcAddr, + dstAddr); + } + else { + assert(dimensions == 3); + makeTemp = !_mesa_convert_texsubimage3d(dstFormat->MesaFormat, + dstXoffset, dstYoffset, dstZoffset, + srcWidth, srcHeight, srcDepth, + dstRowStridePixels, dstImageStridePixels, + srcFormat, srcType, + srcPacking, srcAddr, dstAddr); + } + if (!makeTemp) { + /* all done! */ + return; + } + } + } + else { + /* software texture format */ + makeTemp = GL_FALSE; + } + + + if (makeTemp) { + GLint postConvWidth = srcWidth, postConvHeight = srcHeight; + GLenum tmpFormat; + GLuint tmpComps, tmpTexelSize; + GLint tmpRowStride, tmpImageStride; + GLubyte *tmpImage; + + if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) { + _mesa_adjust_image_for_convolution(ctx, dimensions, &postConvWidth, + &postConvHeight); + } + + tmpFormat = _mesa_base_tex_format(ctx, dstFormat->IntFormat); + tmpComps = _mesa_components_in_format(tmpFormat); + tmpTexelSize = tmpComps * sizeof(CHAN_TYPE); + tmpRowStride = postConvWidth * tmpTexelSize; + tmpImageStride = postConvWidth * postConvHeight * tmpTexelSize; + tmpImage = (GLubyte *) MALLOC(postConvWidth * postConvHeight * + srcDepth * tmpTexelSize); + if (!tmpImage) + return; + + transfer_teximage(ctx, dimensions, tmpFormat, tmpImage, + srcWidth, srcHeight, srcDepth, + 0, 0, 0, /* x/y/zoffset */ + tmpRowStride, tmpImageStride, + srcFormat, srcType, srcAddr, srcPacking); + + /* the temp image is our new source image */ + srcWidth = postConvWidth; + srcHeight = postConvHeight; + srcFormat = tmpFormat; + srcType = CHAN_TYPE; + srcAddr = tmpImage; + srcPacking = &_mesa_native_packing; + } + + if (_mesa_is_hardware_tex_format(dstFormat)) { + assert(makeTemp); + if (dimensions == 1) { + GLboolean b; + b = _mesa_convert_texsubimage1d(dstFormat->MesaFormat, + dstXoffset, + srcWidth, + srcFormat, srcType, + srcPacking, srcAddr, + dstAddr); + assert(b); + } + else if (dimensions == 2) { + GLboolean b; + b = _mesa_convert_texsubimage2d(dstFormat->MesaFormat, + dstXoffset, dstYoffset, + srcWidth, srcHeight, + dstRowStridePixels, + srcFormat, srcType, + srcPacking, srcAddr, + dstAddr); + assert(b); + } + else { + GLboolean b; + b = _mesa_convert_texsubimage3d(dstFormat->MesaFormat, + dstXoffset, dstYoffset, dstZoffset, + srcWidth, srcHeight, srcDepth, + dstRowStridePixels, dstImageStridePixels, + srcFormat, srcType, + 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, + srcWidth, srcHeight, srcDepth, + dstXoffset, dstYoffset, dstZoffset, + dstRowStride, dstImageStride, + srcFormat, srcType, srcAddr, srcPacking); + } +} + + +/* * This is the software fallback for Driver.TexImage1D(). * The texture image type will be GLchan. * The texture image format will be GL_COLOR_INDEX, GL_INTENSITY, @@ -404,18 +562,23 @@ _mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level, _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL); } - /* setup the teximage struct's fields */ - _mesa_init_tex_format( ctx, internalFormat, texImage ); + /* choose the texture format */ + assert(ctx->Driver.ChooseTextureFormat); + texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx, + internalFormat, format, type); + assert(texImage->TexFormat); texelBytes = texImage->TexFormat->TexelBytes; /* allocate memory */ - texImage->Data = (GLchan *) MALLOC(postConvWidth * texelBytes); - if (!texImage->Data) - return; /* out of memory */ + texImage->Data = MALLOC(postConvWidth * texelBytes); + if (!texImage->Data) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D"); + return; + } /* unpack image, apply transfer ops and store in texImage->Data */ - _mesa_transfer_teximage(ctx, 1, texImage->Format, texImage->Data, + _mesa_transfer_teximage(ctx, 1, texImage->TexFormat, texImage->Data, width, 1, 1, 0, 0, 0, 0, /* dstRowStride */ 0, /* dstImageStride */ @@ -447,19 +610,23 @@ _mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level, &postConvHeight); } - /* setup the teximage struct's fields */ - _mesa_init_tex_format( ctx, internalFormat, texImage ); + /* choose the texture format */ + assert(ctx->Driver.ChooseTextureFormat); + texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx, + internalFormat, format, type); + assert(texImage->TexFormat); texelBytes = texImage->TexFormat->TexelBytes; /* allocate memory */ - texImage->Data = (GLchan *) MALLOC(postConvWidth * postConvHeight * - texelBytes); - if (!texImage->Data) - return; /* out of memory */ + texImage->Data = MALLOC(postConvWidth * postConvHeight * texelBytes); + if (!texImage->Data) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); + return; + } /* unpack image, apply transfer ops and store in texImage->Data */ - _mesa_transfer_teximage(ctx, 2, texImage->Format, texImage->Data, + _mesa_transfer_teximage(ctx, 2, texImage->TexFormat, texImage->Data, width, height, 1, 0, 0, 0, texImage->Width * texelBytes, 0, /* dstImageStride */ @@ -486,18 +653,23 @@ _mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level, { GLint texelBytes; - /* setup the teximage struct's fields */ - _mesa_init_tex_format( ctx, internalFormat, texImage ); + /* choose the texture format */ + assert(ctx->Driver.ChooseTextureFormat); + texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx, + internalFormat, format, type); + assert(texImage->TexFormat); texelBytes = texImage->TexFormat->TexelBytes; /* allocate memory */ - texImage->Data = (GLchan *) MALLOC(width * height * depth * texelBytes); - if (!texImage->Data) - return; /* out of memory */ + texImage->Data = MALLOC(width * height * depth * texelBytes); + if (!texImage->Data) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D"); + return; + } /* unpack image, apply transfer ops and store in texImage->Data */ - _mesa_transfer_teximage(ctx, 3, texImage->Format, texImage->Data, + _mesa_transfer_teximage(ctx, 3, texImage->TexFormat, texImage->Data, width, height, depth, 0, 0, 0, texImage->Width * texelBytes, texImage->Width * texImage->Height * texelBytes, @@ -518,7 +690,7 @@ _mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { - _mesa_transfer_teximage(ctx, 1, texImage->Format, texImage->Data, + _mesa_transfer_teximage(ctx, 1, texImage->TexFormat, texImage->Data, width, 1, 1, /* src size */ xoffset, 0, 0, /* dest offsets */ 0, /* dstRowStride */ @@ -539,7 +711,7 @@ _mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage) { - _mesa_transfer_teximage(ctx, 2, texImage->Format, texImage->Data, + _mesa_transfer_teximage(ctx, 2, texImage->TexFormat, texImage->Data, width, height, 1, /* src size */ xoffset, yoffset, 0, /* dest offsets */ texImage->Width * texImage->TexFormat->TexelBytes, @@ -561,7 +733,7 @@ _mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level, struct gl_texture_image *texImage) { const GLint texelBytes = texImage->TexFormat->TexelBytes; - _mesa_transfer_teximage(ctx, 3, texImage->Format, texImage->Data, + _mesa_transfer_teximage(ctx, 3, texImage->TexFormat, texImage->Data, width, height, depth, /* src size */ xoffset, yoffset, xoffset, /* dest offsets */ texImage->Width * texelBytes, @@ -627,9 +799,6 @@ _mesa_store_compressed_teximage3d(GLcontext *ctx, GLenum target, GLint level, - - - /* * This is the fallback for Driver.TestProxyTexImage(). */ @@ -654,8 +823,11 @@ _mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level, * Drivers may have more stringent texture limits to enforce and will * have to override this function. */ - /* setup the teximage struct's fields */ - _mesa_init_tex_format( ctx, internalFormat, texImage ); + /* choose the texture format */ + assert(ctx->Driver.ChooseTextureFormat); + texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx, + internalFormat, format, type); + assert(texImage->TexFormat); return GL_TRUE; } diff --git a/src/mesa/main/texstore.h b/src/mesa/main/texstore.h index c78a32703c8..d876df54d33 100644 --- a/src/mesa/main/texstore.h +++ b/src/mesa/main/texstore.h @@ -1,4 +1,4 @@ -/* $Id: texstore.h,v 1.5 2001/03/21 16:44:08 brianp Exp $ */ +/* $Id: texstore.h,v 1.6 2001/04/04 21:54:21 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -39,7 +39,8 @@ extern void _mesa_transfer_teximage(GLcontext *ctx, GLuint dimensions, - GLenum texDestFormat, GLvoid *texDestAddr, + const struct gl_texture_format *texDestFormat, + GLvoid *texDestAddr, GLint srcWidth, GLint srcHeight, GLint srcDepth, GLint dstXoffset, GLint dstYoffset, GLint dstZoffset, GLint dstRowStride, GLint dstImageStride, |