diff options
Diffstat (limited to 'src/mesa/main')
-rw-r--r-- | src/mesa/main/dd.h | 59 | ||||
-rw-r--r-- | src/mesa/main/teximage.c | 246 | ||||
-rw-r--r-- | src/mesa/main/texstore.c | 415 | ||||
-rw-r--r-- | src/mesa/main/texstore.h | 31 |
4 files changed, 540 insertions, 211 deletions
diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h index 818a6143f2d..bfe3d3a50ed 100644 --- a/src/mesa/main/dd.h +++ b/src/mesa/main/dd.h @@ -1,4 +1,4 @@ -/* $Id: dd.h,v 1.52 2001/02/15 01:33:52 keithw Exp $ */ +/* $Id: dd.h,v 1.53 2001/02/19 20:02:37 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -469,7 +469,6 @@ struct dd_function_table { struct gl_texture_object *texObj, struct gl_texture_image *texImage ); /* Called by glTexImage1/2/3D. - * Will not be called if any glPixelTransfer operations are enabled. * Arguments: * <target>, <level>, <format>, <type> and <pixels> are user specified. * <packing> indicates the image packing of pixels. @@ -478,10 +477,7 @@ struct dd_function_table { * width, height, depth, border and internalFormat information. * <retainInternalCopy> is returned by this function and indicates whether * core Mesa should keep an internal copy of the texture image. - * Return GL_TRUE if operation completed, return GL_FALSE if core Mesa - * should do the job. If GL_FALSE is returned, this function will be - * called a second time after the texture image has been unpacked into - * GLubytes. It may be easier for the driver to handle then. + * Drivers should call a fallback routine from texstore.c if needed. */ void (*TexSubImage1D)( GLcontext *ctx, GLenum target, GLint level, @@ -508,7 +504,6 @@ struct dd_function_table { struct gl_texture_object *texObj, struct gl_texture_image *texImage ); /* Called by glTexSubImage1/2/3D. - * Will not be called if any glPixelTransfer operations are enabled. * Arguments: * <target>, <level>, <xoffset>, <yoffset>, <zoffset>, <width>, <height>, * <depth>, <format>, <type> and <pixels> are user specified. @@ -516,38 +511,32 @@ struct dd_function_table { * <texObj> is the target texture object. * <texImage> is the target texture image. It will have the texture * width, height, border and internalFormat information. - * Return GL_TRUE if operation completed, return GL_FALSE if core Mesa - * should do the job. If GL_FALSE is returned, then TexImage1/2/3D will - * be called with the complete texture image. + * The driver should use a fallback routine from texstore.c if needed. */ - GLboolean (*CopyTexImage1D)( GLcontext *ctx, GLenum target, GLint level, - GLenum internalFormat, GLint x, GLint y, - GLsizei width, GLint border ); - GLboolean (*CopyTexImage2D)( GLcontext *ctx, GLenum target, GLint level, - GLenum internalFormat, GLint x, GLint y, - GLsizei width, GLsizei height, GLint border ); + void (*CopyTexImage1D)( GLcontext *ctx, GLenum target, GLint level, + GLenum internalFormat, GLint x, GLint y, + GLsizei width, GLint border ); + void (*CopyTexImage2D)( GLcontext *ctx, GLenum target, GLint level, + GLenum internalFormat, GLint x, GLint y, + GLsizei width, GLsizei height, GLint border ); /* Called by glCopyTexImage1D and glCopyTexImage2D. - * Will not be called if any glPixelTransfer operations are enabled. - * Return GL_TRUE if operation completed, return GL_FALSE if core Mesa - * should do the job. - */ - - GLboolean (*CopyTexSubImage1D)( GLcontext *ctx, GLenum target, GLint level, - GLint xoffset, - GLint x, GLint y, GLsizei width ); - GLboolean (*CopyTexSubImage2D)( GLcontext *ctx, GLenum target, GLint level, - GLint xoffset, GLint yoffset, - GLint x, GLint y, - GLsizei width, GLsizei height ); - GLboolean (*CopyTexSubImage3D)( GLcontext *ctx, GLenum target, GLint level, - GLint xoffset, GLint yoffset, GLint zoffset, - GLint x, GLint y, - GLsizei width, GLsizei height ); + * Drivers should use a fallback routine from texstore.c if needed. + */ + + void (*CopyTexSubImage1D)( GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, + GLint x, GLint y, GLsizei width ); + void (*CopyTexSubImage2D)( GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint x, GLint y, + GLsizei width, GLsizei height ); + void (*CopyTexSubImage3D)( GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLint x, GLint y, + GLsizei width, GLsizei height ); /* Called by glCopyTexSubImage1/2/3D. - * Will not be called if any glPixelTransfer operations are enabled. - * Return GL_TRUE if operation completed, return GL_FALSE if core Mesa - * should do the job. + * Drivers should use a fallback routine from texstore.c if needed. */ GLboolean (*TestProxyTexImage)(GLcontext *ctx, GLenum target, diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index e534924e80c..279126f2d48 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -1,4 +1,4 @@ -/* $Id: teximage.c,v 1.77 2001/02/17 18:41:01 brianp Exp $ */ +/* $Id: teximage.c,v 1.78 2001/02/19 20:01:41 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -1628,6 +1628,9 @@ _mesa_TexSubImage1D( GLenum target, GLint level, struct gl_texture_object *texObj; struct gl_texture_image *texImage; + if (ctx->NewState & _NEW_PIXEL) + gl_update_state(ctx); + /* XXX should test internal format */ if (is_color_format(format)) { _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL); @@ -1646,9 +1649,6 @@ _mesa_TexSubImage1D( GLenum target, GLint level, if (width == 0 || !pixels) return; /* no-op, not an error */ - if (ctx->NewState & _NEW_PIXEL) - gl_update_state(ctx); - ASSERT(ctx->Driver.TexSubImage1D); (*ctx->Driver.TexSubImage1D)(ctx, target, level, xoffset, width, format, type, pixels, &ctx->Unpack, @@ -1669,6 +1669,9 @@ _mesa_TexSubImage2D( GLenum target, GLint level, struct gl_texture_object *texObj; struct gl_texture_image *texImage; + if (ctx->NewState & _NEW_PIXEL) + gl_update_state(ctx); + /* XXX should test internal format */ if (is_color_format(format)) { _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth, @@ -1688,9 +1691,6 @@ _mesa_TexSubImage2D( GLenum target, GLint level, if (width == 0 || height == 0 || !pixels) return; /* no-op, not an error */ - if (ctx->NewState & _NEW_PIXEL) - gl_update_state(ctx); - ASSERT(ctx->Driver.TexSubImage2D); (*ctx->Driver.TexSubImage2D)(ctx, target, level, xoffset, yoffset, width, height, format, type, pixels, @@ -1711,6 +1711,9 @@ _mesa_TexSubImage3D( GLenum target, GLint level, struct gl_texture_object *texObj; struct gl_texture_image *texImage; + if (ctx->NewState & _NEW_PIXEL) + gl_update_state(ctx); + if (subtexture_error_check(ctx, 3, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type)) { return; /* error was detected */ @@ -1724,9 +1727,6 @@ _mesa_TexSubImage3D( GLenum target, GLint level, if (width == 0 || height == 0 || height == 0 || !pixels) return; /* no-op, not an error */ - if (ctx->NewState & _NEW_PIXEL) - gl_update_state(ctx); - ASSERT(ctx->Driver.TexSubImage3D); (*ctx->Driver.TexSubImage3D)(ctx, target, level, xoffset, yoffset, zoffset, @@ -1737,56 +1737,15 @@ _mesa_TexSubImage3D( GLenum target, GLint level, -/* - * Read an RGBA image from the frame buffer. - * This is used by glCopyTex[Sub]Image[12]D(). - * Input: ctx - the context - * x, y - lower left corner - * width, height - size of region to read - * Return: pointer to block of GL_RGBA, GLchan data. - */ -static GLchan * -read_color_image( GLcontext *ctx, GLint x, GLint y, - GLsizei width, GLsizei height ) -{ - GLint stride, i; - GLchan *image, *dst; - - image = (GLchan *) MALLOC(width * height * 4 * sizeof(GLchan)); - if (!image) - return NULL; - - /* Select buffer to read from */ - (*ctx->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer, - ctx->Pixel.DriverReadBuffer ); - - RENDER_START(ctx); - - dst = image; - stride = width * 4; - for (i = 0; i < height; i++) { - gl_read_rgba_span( ctx, ctx->ReadBuffer, width, x, y + i, - (GLchan (*)[4]) dst ); - dst += stride; - } - - RENDER_FINISH(ctx); - - /* Read from draw buffer (the default) */ - (*ctx->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer, - ctx->Color.DriverDrawBuffer ); - - return image; -} - - - void _mesa_CopyTexImage1D( GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border ) { + struct gl_texture_unit *texUnit; + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; GLsizei postConvWidth = width; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); @@ -1802,27 +1761,35 @@ _mesa_CopyTexImage1D( GLenum target, GLint level, postConvWidth, 1, border)) return; - if (ctx->_ImageTransferState || !ctx->Driver.CopyTexImage1D - || !(*ctx->Driver.CopyTexImage1D)(ctx, target, level, - internalFormat, x, y, width, border)) { - struct gl_pixelstore_attrib unpackSave; - - /* get image from framebuffer */ - GLchan *image = read_color_image( ctx, x, y, width, 1 ); - if (!image) { - gl_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D" ); + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + texObj = _mesa_select_tex_object(ctx, texUnit, target); + texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + if (!texImage) { + texImage = _mesa_alloc_texture_image(); + set_tex_image(texObj, target, level, texImage); + if (!texImage) { + gl_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D"); return; } + } + else if (texImage->Data) { + /* free the old texture data */ + FREE(texImage->Data); + texImage->Data = NULL; + } - /* call glTexImage1D to redefine the texture */ - unpackSave = ctx->Unpack; - ctx->Unpack = _mesa_native_packing; - (*ctx->Exec->TexImage1D)( target, level, internalFormat, width, - border, GL_RGBA, GL_UNSIGNED_BYTE, image ); - ctx->Unpack = unpackSave; + clear_teximage_fields(texImage); /* not really needed, but helpful */ + init_teximage_fields(ctx, texImage, postConvWidth, 1, 1, + border, internalFormat); - FREE(image); - } + + ASSERT(ctx->Driver.CopyTexImage1D); + (*ctx->Driver.CopyTexImage1D)(ctx, target, level, internalFormat, + x, y, width, border); + + /* state update */ + texObj->Complete = GL_FALSE; + ctx->NewState |= _NEW_TEXTURE; } @@ -1832,6 +1799,9 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border ) { + struct gl_texture_unit *texUnit; + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; GLsizei postConvWidth = width, postConvHeight = height; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); @@ -1848,27 +1818,34 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat, postConvWidth, postConvHeight, border)) return; - if (ctx->_ImageTransferState || !ctx->Driver.CopyTexImage2D - || !(*ctx->Driver.CopyTexImage2D)(ctx, target, level, - internalFormat, x, y, width, height, border)) { - struct gl_pixelstore_attrib unpackSave; - - /* get image from framebuffer */ - GLchan *image = read_color_image( ctx, x, y, width, height ); - if (!image) { - gl_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D" ); + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + texObj = _mesa_select_tex_object(ctx, texUnit, target); + texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + if (!texImage) { + texImage = _mesa_alloc_texture_image(); + set_tex_image(texObj, target, level, texImage); + if (!texImage) { + gl_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D"); return; } + } + else if (texImage->Data) { + /* free the old texture data */ + FREE(texImage->Data); + texImage->Data = NULL; + } - /* call glTexImage2D to redefine the texture */ - unpackSave = ctx->Unpack; - ctx->Unpack = _mesa_native_packing; - (ctx->Exec->TexImage2D)( target, level, internalFormat, width, - height, border, GL_RGBA, GL_UNSIGNED_BYTE, image ); - ctx->Unpack = unpackSave; + clear_teximage_fields(texImage); /* not really needed, but helpful */ + init_teximage_fields(ctx, texImage, postConvWidth, postConvHeight, 1, + border, internalFormat); - FREE(image); - } + ASSERT(ctx->Driver.CopyTexImage2D); + (*ctx->Driver.CopyTexImage2D)(ctx, target, level, internalFormat, + x, y, width, height, border); + + /* state update */ + texObj->Complete = GL_FALSE; + ctx->NewState |= _NEW_TEXTURE; } @@ -1891,34 +1868,8 @@ _mesa_CopyTexSubImage1D( GLenum target, GLint level, xoffset, 0, 0, postConvWidth, 1)) return; - if (ctx->_ImageTransferState || !ctx->Driver.CopyTexSubImage1D - || !(*ctx->Driver.CopyTexSubImage1D)(ctx, target, level, - xoffset, x, y, width)) { - struct gl_texture_unit *texUnit; - struct gl_texture_image *teximage; - struct gl_pixelstore_attrib unpackSave; - GLchan *image; - - texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; - teximage = texUnit->Current1D->Image[level]; - assert(teximage); - - /* get image from frame buffer */ - image = read_color_image(ctx, x, y, width, 1); - if (!image) { - gl_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage1D" ); - return; - } - - /* now call glTexSubImage1D to do the real work */ - unpackSave = ctx->Unpack; - ctx->Unpack = _mesa_native_packing; - _mesa_TexSubImage1D(target, level, xoffset, width, - GL_RGBA, GL_UNSIGNED_BYTE, image); - ctx->Unpack = unpackSave; - - FREE(image); - } + ASSERT(ctx->Driver.CopyTexSubImage1D); + (*ctx->Driver.CopyTexSubImage1D)(ctx, target, level, xoffset, x, y, width); } @@ -1942,34 +1893,9 @@ _mesa_CopyTexSubImage2D( GLenum target, GLint level, postConvWidth, postConvHeight)) return; - if (ctx->_ImageTransferState || !ctx->Driver.CopyTexSubImage2D - || !(*ctx->Driver.CopyTexSubImage2D)(ctx, target, level, - xoffset, yoffset, x, y, width, height )) { - struct gl_texture_unit *texUnit; - struct gl_texture_image *teximage; - struct gl_pixelstore_attrib unpackSave; - GLchan *image; - - texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; - teximage = texUnit->Current2D->Image[level]; - assert(teximage); - - /* get image from frame buffer */ - image = read_color_image(ctx, x, y, width, height); - if (!image) { - gl_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage2D" ); - return; - } - - /* now call glTexSubImage2D to do the real work */ - unpackSave = ctx->Unpack; - ctx->Unpack = _mesa_native_packing; - _mesa_TexSubImage2D(target, level, xoffset, yoffset, width, height, - GL_RGBA, GL_UNSIGNED_BYTE, image); - ctx->Unpack = unpackSave; - - FREE(image); - } + ASSERT(ctx->Driver.CopyTexSubImage2D); + (*ctx->Driver.CopyTexSubImage2D)(ctx, target, level, + xoffset, yoffset, x, y, width, height); } @@ -1993,34 +1919,10 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level, zoffset, postConvWidth, postConvHeight)) return; - if (ctx->_ImageTransferState || !ctx->Driver.CopyTexSubImage3D - || !(*ctx->Driver.CopyTexSubImage3D)(ctx, target, level, - xoffset, yoffset, zoffset, x, y, width, height )) { - struct gl_texture_unit *texUnit; - struct gl_texture_image *teximage; - struct gl_pixelstore_attrib unpackSave; - GLchan *image; - - texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; - teximage = texUnit->Current3D->Image[level]; - assert(teximage); - - /* get image from frame buffer */ - image = read_color_image(ctx, x, y, width, height); - if (!image) { - gl_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage2D" ); - return; - } - - /* now call glTexSubImage2D to do the real work */ - unpackSave = ctx->Unpack; - ctx->Unpack = _mesa_native_packing; - _mesa_TexSubImage3D(target, level, xoffset, yoffset, zoffset, - width, height, 1, GL_RGBA, GL_UNSIGNED_BYTE, image); - ctx->Unpack = unpackSave; - - FREE(image); - } + ASSERT(ctx->Driver.CopyTexSubImage3D); + (*ctx->Driver.CopyTexSubImage3D)(ctx, target, level, + xoffset, yoffset, zoffset, + x, y, width, height); } diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c index 8f0f4fc64cb..1ba40c9822b 100644 --- a/src/mesa/main/texstore.c +++ b/src/mesa/main/texstore.c @@ -1,4 +1,4 @@ -/* $Id: texstore.c,v 1.6 2001/02/17 18:41:01 brianp Exp $ */ +/* $Id: texstore.c,v 1.7 2001/02/19 20:01:42 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -46,7 +46,8 @@ #include "mem.h" #include "teximage.h" #include "texstore.h" - +#include "swrast/s_depth.h" /* XXX this is kind of a cheat */ +#include "swrast/s_span.h" /* @@ -73,21 +74,37 @@ fetch_1d_texel(const struct gl_texture_image *img, rgba[RCOMP] = src[0]; rgba[GCOMP] = src[1]; rgba[BCOMP] = src[2]; + rgba[ACOMP] = CHAN_MAX; return; } case GL_ALPHA: { const GLchan *src = (GLchan *) img->Data + i; GLchan *rgba = (GLchan *) texel; + rgba[RCOMP] = 0; + rgba[GCOMP] = 0; + rgba[BCOMP] = 0; rgba[ACOMP] = src[0]; return; } case GL_LUMINANCE: + { + const GLchan *src = (GLchan *) img->Data + i; + GLchan *rgba = (GLchan *) texel; + rgba[RCOMP] = src[0]; + rgba[GCOMP] = src[0]; + rgba[BCOMP] = src[0]; + rgba[ACOMP] = CHAN_MAX; + return; + } case GL_INTENSITY: { const GLchan *src = (GLchan *) img->Data + i; GLchan *rgba = (GLchan *) texel; rgba[RCOMP] = src[0]; + rgba[GCOMP] = src[0]; + rgba[BCOMP] = src[0]; + rgba[ACOMP] = src[0]; return; } case GL_LUMINANCE_ALPHA: @@ -95,6 +112,8 @@ fetch_1d_texel(const struct gl_texture_image *img, const GLchan *src = (GLchan *) img->Data + i * 2; GLchan *rgba = (GLchan *) texel; rgba[RCOMP] = src[0]; + rgba[GCOMP] = src[0]; + rgba[BCOMP] = src[0]; rgba[ACOMP] = src[1]; return; } @@ -140,28 +159,46 @@ fetch_2d_texel(const struct gl_texture_image *img, rgba[RCOMP] = src[0]; rgba[GCOMP] = src[1]; rgba[BCOMP] = src[2]; + rgba[ACOMP] = CHAN_MAX; return; } case GL_ALPHA: { const GLchan *src = (GLchan *) img->Data + (img->Width * j + i); GLchan *rgba = (GLchan *) texel; + rgba[RCOMP] = 0; + rgba[GCOMP] = 0; + rgba[BCOMP] = 0; rgba[ACOMP] = src[0]; return; } case GL_LUMINANCE: + { + const GLchan *src = (GLchan *) img->Data + (img->Width * j + i); + GLchan *rgba = (GLchan *) texel; + rgba[RCOMP] = src[0]; + rgba[GCOMP] = src[0]; + rgba[BCOMP] = src[0]; + rgba[ACOMP] = CHAN_MAX; + return; + } case GL_INTENSITY: { const GLchan *src = (GLchan *) img->Data + (img->Width * j + i); GLchan *rgba = (GLchan *) texel; rgba[RCOMP] = src[0]; + rgba[GCOMP] = src[0]; + rgba[BCOMP] = src[0]; + rgba[ACOMP] = src[0]; return; } case GL_LUMINANCE_ALPHA: { const GLchan *src = (GLchan *) img->Data + (img->Width * j + i) * 2; GLchan *rgba = (GLchan *) texel; - rgba[RCOMP] = src[0]; + rgba[RCOMP] = 0; + rgba[GCOMP] = 0; + rgba[BCOMP] = 0; rgba[ACOMP] = src[1]; return; } @@ -212,6 +249,7 @@ fetch_3d_texel(const struct gl_texture_image *img, rgba[RCOMP] = src[0]; rgba[GCOMP] = src[1]; rgba[BCOMP] = src[2]; + rgba[ACOMP] = CHAN_MAX; return; } case GL_ALPHA: @@ -219,16 +257,32 @@ fetch_3d_texel(const struct gl_texture_image *img, const GLchan *src = (GLchan *) img->Data + (rectArea * k + width * j + i); GLchan *rgba = (GLchan *) texel; + rgba[RCOMP] = 0; + rgba[GCOMP] = 0; + rgba[BCOMP] = 0; rgba[ACOMP] = src[0]; return; } case GL_LUMINANCE: + { + const GLchan *src = (GLchan *) img->Data + + (rectArea * k + width * j + i); + GLchan *rgba = (GLchan *) texel; + rgba[RCOMP] = src[0]; + rgba[GCOMP] = src[0]; + rgba[BCOMP] = src[0]; + rgba[ACOMP] = CHAN_MAX; + return; + } case GL_INTENSITY: { const GLchan *src = (GLchan *) img->Data + (rectArea * k + width * j + i); GLchan *rgba = (GLchan *) texel; rgba[RCOMP] = src[0]; + rgba[GCOMP] = src[0]; + rgba[BCOMP] = src[0]; + rgba[ACOMP] = src[0]; return; } case GL_LUMINANCE_ALPHA: @@ -237,6 +291,8 @@ fetch_3d_texel(const struct gl_texture_image *img, + (rectArea * k + width * j + i) * 2; GLchan *rgba = (GLchan *) texel; rgba[RCOMP] = src[0]; + rgba[GCOMP] = src[0]; + rgba[BCOMP] = src[0]; rgba[ACOMP] = src[1]; return; } @@ -944,6 +1000,359 @@ _mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level, + +/* + * Read an RGBA image from the frame buffer. + * This is used by glCopyTex[Sub]Image[12]D(). + * Input: ctx - the context + * x, y - lower left corner + * width, height - size of region to read + * Return: pointer to block of GL_RGBA, GLchan data. + */ +static GLchan * +read_color_image( GLcontext *ctx, GLint x, GLint y, + GLsizei width, GLsizei height ) +{ + GLint stride, i; + GLchan *image, *dst; + + image = (GLchan *) MALLOC(width * height * 4 * sizeof(GLchan)); + if (!image) + return NULL; + + /* Select buffer to read from */ + (*ctx->Driver.SetReadBuffer)( ctx, ctx->ReadBuffer, + ctx->Pixel.DriverReadBuffer ); + + RENDER_START(ctx); + + dst = image; + stride = width * 4; + for (i = 0; i < height; i++) { + gl_read_rgba_span( ctx, ctx->ReadBuffer, width, x, y + i, + (GLchan (*)[4]) dst ); + dst += stride; + } + + RENDER_FINISH(ctx); + + /* Read from draw buffer (the default) */ + (*ctx->Driver.SetReadBuffer)( ctx, ctx->DrawBuffer, + ctx->Color.DriverDrawBuffer ); + + return image; +} + + +/* + * As above, but read data from depth buffer. + */ +static GLfloat * +read_depth_image( GLcontext *ctx, GLint x, GLint y, + GLsizei width, GLsizei height ) +{ + GLint i; + GLfloat *image, *dst; + + image = (GLfloat *) MALLOC(width * height * sizeof(GLfloat)); + if (!image) + return NULL; + + RENDER_START(ctx); + + dst = image; + for (i = 0; i < height; i++) { + _mesa_read_depth_span_float(ctx, width, x, y + i, dst); + dst += width; + } + + RENDER_FINISH(ctx); + + return image; +} + + + +static GLboolean +is_depth_format(GLenum format) +{ + switch (format) { + case GL_DEPTH_COMPONENT: + case GL_DEPTH_COMPONENT16_SGIX: + case GL_DEPTH_COMPONENT24_SGIX: + case GL_DEPTH_COMPONENT32_SGIX: + return GL_TRUE; + default: + return GL_FALSE; + } +} + + +/* + * Fallback for Driver.CopyTexImage1D(). + */ +void +_mesa_copy_teximage1d( GLcontext *ctx, GLenum target, GLint level, + GLenum internalFormat, + GLint x, GLint y, GLsizei width, GLint border ) +{ + struct gl_texture_unit *texUnit; + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + texObj = _mesa_select_tex_object(ctx, texUnit, target); + ASSERT(texObj); + texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + ASSERT(texImage); + + ASSERT(ctx->Driver.TexImage1D); + + if (is_depth_format(internalFormat)) { + /* read depth image from framebuffer */ + GLfloat *image = read_depth_image(ctx, x, y, width, 1); + if (!image) { + gl_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D"); + return; + } + + /* call glTexImage1D to redefine the texture */ + (*ctx->Driver.TexImage1D)(ctx, target, level, internalFormat, + width, border, + GL_DEPTH_COMPONENT, GL_FLOAT, image, + &_mesa_native_packing, texObj, texImage); + FREE(image); + } + else { + /* read RGBA image from framebuffer */ + GLchan *image = read_color_image(ctx, x, y, width, 1); + if (!image) { + gl_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D"); + return; + } + + /* call glTexImage1D to redefine the texture */ + (*ctx->Driver.TexImage1D)(ctx, target, level, internalFormat, + width, border, + GL_RGBA, CHAN_TYPE, image, + &_mesa_native_packing, texObj, texImage); + FREE(image); + } +} + + +/* + * Fallback for Driver.CopyTexImage2D(). + */ +void +_mesa_copy_teximage2d( GLcontext *ctx, GLenum target, GLint level, + GLenum internalFormat, + GLint x, GLint y, GLsizei width, GLsizei height, + GLint border ) +{ + struct gl_texture_unit *texUnit; + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + texObj = _mesa_select_tex_object(ctx, texUnit, target); + ASSERT(texObj); + texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + ASSERT(texImage); + + ASSERT(ctx->Driver.TexImage2D); + + if (is_depth_format(internalFormat)) { + /* read depth image from framebuffer */ + GLfloat *image = read_depth_image(ctx, x, y, width, height); + if (!image) { + gl_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D"); + return; + } + + /* call glTexImage2D to redefine the texture */ + (*ctx->Driver.TexImage2D)(ctx, target, level, internalFormat, + width, height, border, + GL_DEPTH_COMPONENT, GL_FLOAT, image, + &_mesa_native_packing, texObj, texImage); + FREE(image); + } + else { + /* read RGBA image from framebuffer */ + GLchan *image = read_color_image(ctx, x, y, width, height); + if (!image) { + gl_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D"); + return; + } + + /* call glTexImage2D to redefine the texture */ + (*ctx->Driver.TexImage2D)(ctx, target, level, internalFormat, + width, height, border, + GL_RGBA, CHAN_TYPE, image, + &_mesa_native_packing, texObj, texImage); + FREE(image); + } +} + + +/* + * Fallback for Driver.CopyTexSubImage1D(). + */ +void +_mesa_copy_texsubimage1d(GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint x, GLint y, GLsizei width) +{ + struct gl_texture_unit *texUnit; + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + texObj = _mesa_select_tex_object(ctx, texUnit, target); + ASSERT(texObj); + texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + ASSERT(texImage); + + ASSERT(ctx->Driver.TexImage1D); + + if (is_depth_format(texImage->IntFormat)) { + /* read depth image from framebuffer */ + GLfloat *image = read_depth_image(ctx, x, y, width, 1); + if (!image) { + gl_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage1D"); + return; + } + + /* call glTexImage1D to redefine the texture */ + (*ctx->Driver.TexSubImage1D)(ctx, target, level, xoffset, width, + GL_DEPTH_COMPONENT, GL_FLOAT, image, + &_mesa_native_packing, texObj, texImage); + FREE(image); + } + else { + GLchan *image = read_color_image(ctx, x, y, width, 1); + if (!image) { + gl_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage1D" ); + return; + } + + /* now call glTexSubImage1D to do the real work */ + (*ctx->Driver.TexSubImage1D)(ctx, target, level, xoffset, width, + GL_RGBA, CHAN_TYPE, image, + &_mesa_native_packing, texObj, texImage); + FREE(image); + } +} + + +/* + * Fallback for Driver.CopyTexSubImage2D(). + */ +void +_mesa_copy_texsubimage2d( GLcontext *ctx, + GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint x, GLint y, GLsizei width, GLsizei height ) +{ + struct gl_texture_unit *texUnit; + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + texObj = _mesa_select_tex_object(ctx, texUnit, target); + ASSERT(texObj); + texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + ASSERT(texImage); + + ASSERT(ctx->Driver.TexImage2D); + + if (is_depth_format(texImage->IntFormat)) { + /* read depth image from framebuffer */ + GLfloat *image = read_depth_image(ctx, x, y, width, height); + if (!image) { + gl_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage2D"); + return; + } + + /* call glTexImage1D to redefine the texture */ + (*ctx->Driver.TexSubImage2D)(ctx, target, level, + xoffset, yoffset, width, height, + GL_DEPTH_COMPONENT, GL_FLOAT, image, + &_mesa_native_packing, texObj, texImage); + FREE(image); + } + else { + /* read RGBA image from framebuffer */ + GLchan *image = read_color_image(ctx, x, y, width, height); + if (!image) { + gl_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage2D" ); + return; + } + + /* now call glTexSubImage2D to do the real work */ + (*ctx->Driver.TexSubImage2D)(ctx, target, level, + xoffset, yoffset, width, height, + GL_RGBA, CHAN_TYPE, image, + &_mesa_native_packing, texObj, texImage); + FREE(image); + } +} + + +/* + * Fallback for Driver.CopyTexSubImage3D(). + */ +void +_mesa_copy_texsubimage3d( GLcontext *ctx, + GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLint x, GLint y, GLsizei width, GLsizei height ) +{ + struct gl_texture_unit *texUnit; + struct gl_texture_object *texObj; + struct gl_texture_image *texImage; + + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + texObj = _mesa_select_tex_object(ctx, texUnit, target); + ASSERT(texObj); + texImage = _mesa_select_tex_image(ctx, texUnit, target, level); + ASSERT(texImage); + + ASSERT(ctx->Driver.TexImage3D); + + if (is_depth_format(texImage->IntFormat)) { + /* read depth image from framebuffer */ + GLfloat *image = read_depth_image(ctx, x, y, width, height); + if (!image) { + gl_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage3D"); + return; + } + + /* call glTexImage1D to redefine the texture */ + (*ctx->Driver.TexSubImage3D)(ctx, target, level, + xoffset, yoffset, zoffset, width, height, 1, + GL_DEPTH_COMPONENT, GL_FLOAT, image, + &_mesa_native_packing, texObj, texImage); + FREE(image); + } + else { + /* read RGBA image from framebuffer */ + GLchan *image = read_color_image(ctx, x, y, width, height); + if (!image) { + gl_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage3D" ); + return; + } + + /* now call glTexSubImage3D to do the real work */ + (*ctx->Driver.TexSubImage3D)(ctx, target, level, + xoffset, yoffset, zoffset, width, height, 1, + GL_RGBA, CHAN_TYPE, image, + &_mesa_native_packing, texObj, texImage); + FREE(image); + } +} + + + /* * Fallback for Driver.CompressedTexImage1D() */ diff --git a/src/mesa/main/texstore.h b/src/mesa/main/texstore.h index 96bdf09e0cf..d23940e4e74 100644 --- a/src/mesa/main/texstore.h +++ b/src/mesa/main/texstore.h @@ -1,4 +1,4 @@ -/* $Id: texstore.h,v 1.1 2001/02/06 21:42:48 brianp Exp $ */ +/* $Id: texstore.h,v 1.2 2001/02/19 20:01:42 brianp Exp $ */ /* * Mesa 3-D graphics library @@ -107,6 +107,35 @@ _mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level, struct gl_texture_image *texImage); +extern void +_mesa_copy_teximage1d(GLcontext *ctx, GLenum target, GLint level, + GLenum internalFormat, + GLint x, GLint y, GLsizei width, GLint border); + +extern void +_mesa_copy_teximage2d(GLcontext *ctx, GLenum target, GLint level, + GLenum internalFormat, + GLint x, GLint y, GLsizei width, GLsizei height, + GLint border); + + +extern void +_mesa_copy_texsubimage1d(GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, GLint x, GLint y, GLsizei width); + +extern void +_mesa_copy_texsubimage2d(GLcontext *ctx, + GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint x, GLint y, GLsizei width, GLsizei height); + +extern void +_mesa_copy_texsubimage3d(GLcontext *ctx, + GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLint zoffset, + GLint x, GLint y, GLsizei width, GLsizei height); + + extern void _mesa_store_compressed_teximage1d(GLcontext *ctx, GLenum target, GLint level, |