From: Brian Paul Date: Sun, 12 Dec 2004 19:03:16 +0000 (+0000) Subject: Added driver hooks for GetTexImage() and GetCompressedTexImage(). X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=68d293b03535ca50daf70650b32db780f1718a3b;p=mesa.git Added driver hooks for GetTexImage() and GetCompressedTexImage(). Added fallback _mesa_get_[compressed]_teximage() routines to texstore.c --- diff --git a/src/mesa/drivers/common/driverfuncs.c b/src/mesa/drivers/common/driverfuncs.c index df5f6ac8f03..11b4e286b6f 100644 --- a/src/mesa/drivers/common/driverfuncs.c +++ b/src/mesa/drivers/common/driverfuncs.c @@ -79,6 +79,7 @@ _mesa_init_driver_functions(struct dd_function_table *driver) driver->TexSubImage1D = _mesa_store_texsubimage1d; driver->TexSubImage2D = _mesa_store_texsubimage2d; driver->TexSubImage3D = _mesa_store_texsubimage3d; + driver->GetTexImage = _mesa_get_teximage; driver->CopyTexImage1D = _swrast_copy_teximage1d; driver->CopyTexImage2D = _swrast_copy_teximage2d; driver->CopyTexSubImage1D = _swrast_copy_texsubimage1d; @@ -91,6 +92,7 @@ _mesa_init_driver_functions(struct dd_function_table *driver) driver->CompressedTexSubImage1D = _mesa_store_compressed_texsubimage1d; driver->CompressedTexSubImage2D = _mesa_store_compressed_texsubimage2d; driver->CompressedTexSubImage3D = _mesa_store_compressed_texsubimage3d; + driver->GetCompressedTexImage = _mesa_get_compressed_teximage; driver->CompressedTextureSize = _mesa_compressed_texture_size; driver->BindTexture = NULL; driver->NewTextureObject = _mesa_new_texture_object; diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h index 23ec4587aaf..2b1131bc414 100644 --- a/src/mesa/main/dd.h +++ b/src/mesa/main/dd.h @@ -157,10 +157,9 @@ struct dd_function_table { * This function must respect all rasterization state, glPixelTransfer(), * glPixelZoom(), etc. */ - void (*CopyPixels)( GLcontext *ctx, - GLint srcx, GLint srcy, - GLsizei width, GLsizei height, - GLint dstx, GLint dsty, GLenum type ); + void (*CopyPixels)( GLcontext *ctx, GLint srcx, GLint srcy, + GLsizei width, GLsizei height, + GLint dstx, GLint dsty, GLenum type ); /** * This is called by glBitmap(). @@ -297,6 +296,14 @@ struct dd_function_table { struct gl_texture_object *texObj, struct gl_texture_image *texImage ); + /** + * Called by glGetTexImage(). + */ + void (*GetTexImage)( GLcontext *ctx, GLenum target, GLint level, + GLenum format, GLenum type, GLvoid *pixels, + const struct gl_texture_object *texObj, + const struct gl_texture_image *texImage ); + /** * Called by glCopyTexImage1D(). * @@ -454,6 +461,15 @@ struct dd_function_table { struct gl_texture_object *texObj, struct gl_texture_image *texImage); + + /** + * Called by glGetCompressedTexImage. + */ + void (*GetCompressedTexImage)(GLcontext *ctx, GLenum target, GLint level, + GLvoid *img, + const struct gl_texture_object *texObj, + const struct gl_texture_image *texImage); + /** * Called to query number of bytes of storage needed to store the * specified compressed texture. diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index 127e9bf5693..a98771311d2 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -1902,7 +1902,6 @@ _mesa_GetTexImage( GLenum target, GLint level, GLenum format, const struct gl_texture_object *texObj; const struct gl_texture_image *texImage; GLint maxLevels = 0; - GLuint dimensions; GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); @@ -1979,127 +1978,9 @@ _mesa_GetTexImage( GLenum target, GLint level, GLenum format, return; } - dimensions = (target == GL_TEXTURE_3D) ? 3 : 2; - - /* XXX - someday the rest of this function should be moved into a - * fallback routine called via ctx->Driver.GetTexImage() - */ - - if (ctx->Pack.BufferObj->Name) { - /* pack texture image into a PBO */ - GLubyte *buf; - if (!_mesa_validate_pbo_access(dimensions, &ctx->Pack, texImage->Width, - texImage->Height, texImage->Depth, - format, type, pixels)) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetTexImage(invalid PBO access)"); - return; - } - buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, - GL_WRITE_ONLY_ARB, - ctx->Pack.BufferObj); - if (!buf) { - /* buffer is already mapped - that's an error */ - _mesa_error(ctx, GL_INVALID_OPERATION,"glGetTexImage(PBO is mapped)"); - return; - } - pixels = ADD_POINTERS(buf, pixels); - } - else if (!pixels) { - /* not an error */ - return; - } - - /* - * XXX Move this code into a new driver fall-back function - */ - { - const GLint width = texImage->Width; - const GLint height = texImage->Height; - const GLint depth = texImage->Depth; - GLint img, row; - for (img = 0; img < depth; img++) { - for (row = 0; row < height; row++) { - /* compute destination address in client memory */ - GLvoid *dest = _mesa_image_address( dimensions, &ctx->Pack, pixels, - width, height, format, type, - img, row, 0); - assert(dest); - - if (format == GL_COLOR_INDEX) { - GLuint indexRow[MAX_WIDTH]; - GLint col; - /* Can't use FetchTexel here because that returns RGBA */ - if (texImage->TexFormat->IndexBits == 8) { - const GLubyte *src = (const GLubyte *) texImage->Data; - for (col = 0; col < width; col++) { - indexRow[col] = src[texImage->Width * - (img * texImage->Height + row) + col]; - } - } - else if (texImage->TexFormat->IndexBits == 16) { - const GLushort *src = (const GLushort *) texImage->Data; - for (col = 0; col < width; col++) { - indexRow[col] = src[texImage->Width * - (img * texImage->Height + row) + col]; - } - } - else { - _mesa_problem(ctx, - "Color index problem in _mesa_GetTexImage"); - } - _mesa_pack_index_span(ctx, width, type, dest, - indexRow, &ctx->Pack, - 0 /* no image transfer */); - } - else if (format == GL_DEPTH_COMPONENT) { - GLfloat depthRow[MAX_WIDTH]; - GLint col; - for (col = 0; col < width; col++) { - (*texImage->FetchTexelf)(texImage, col, row, img, - depthRow + col); - } - _mesa_pack_depth_span(ctx, width, dest, type, - depthRow, &ctx->Pack); - } - else if (format == GL_YCBCR_MESA) { - /* No pixel transfer */ - const GLint rowstride = texImage->RowStride; - MEMCPY(dest, - (const GLushort *) texImage->Data + row * rowstride, - width * sizeof(GLushort)); - /* check for byte swapping */ - if ((texImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR - && type == GL_UNSIGNED_SHORT_8_8_REV_MESA) || - (texImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR_REV - && type == GL_UNSIGNED_SHORT_8_8_MESA)) { - if (!ctx->Pack.SwapBytes) - _mesa_swap2((GLushort *) dest, width); - } - else if (ctx->Pack.SwapBytes) { - _mesa_swap2((GLushort *) dest, width); - } - } - else { - /* general case: convert row to RGBA format */ - GLfloat rgba[MAX_WIDTH][4]; - GLint col; - for (col = 0; col < width; col++) { - (*texImage->FetchTexelf)(texImage, col, row, img, rgba[col]); - } - _mesa_pack_rgba_span_float(ctx, width, - (const GLfloat (*)[4]) rgba, - format, type, dest, &ctx->Pack, - 0 /* no image transfer */); - } /* format */ - } /* row */ - } /* img */ - } - - if (ctx->Pack.BufferObj->Name) { - ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, - ctx->Pack.BufferObj); - } + /* typically, this will call _mesa_get_teximage() */ + ctx->Driver.GetTexImage(ctx, target, level, format, type, pixels, + texObj, texImage); } @@ -3394,40 +3275,6 @@ _mesa_GetCompressedTexImageARB(GLenum target, GLint level, GLvoid *img) return; } - /* XXX - someday the rest of this function should be moved into a - * fallback routine called via ctx->Driver.GetCompressedTexImage() - */ - - if (ctx->Pack.BufferObj->Name) { - /* pack texture image into a PBO */ - GLubyte *buf; - if ((const GLubyte *) img + texImage->CompressedSize > - (const GLubyte *) ctx->Pack.BufferObj->Size) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetCompressedTexImage(invalid PBO access)"); - return; - } - buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, - GL_WRITE_ONLY_ARB, - ctx->Pack.BufferObj); - if (!buf) { - /* buffer is already mapped - that's an error */ - _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetCompressedTexImage(PBO is mapped)"); - return; - } - img = ADD_POINTERS(buf, img); - } - else if (!img) { - /* not an error */ - return; - } - - /* just memcpy, no pixelstore or pixel transfer */ - MEMCPY(img, texImage->Data, texImage->CompressedSize); - - if (ctx->Pack.BufferObj->Name) { - ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, - ctx->Pack.BufferObj); - } + /* this typically calls _mesa_get_compressed_teximage() */ + ctx->Driver.GetCompressedTexImage(ctx, target, level, img, texObj,texImage); } diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c index dd1fcef0596..7356910132d 100644 --- a/src/mesa/main/texstore.c +++ b/src/mesa/main/texstore.c @@ -3597,3 +3597,177 @@ _mesa_upscale_teximage2d (GLsizei inWidth, GLsizei inHeight, } } } + + + +/** + * This is the software fallback for Driver.GetTexImage(). + * All error checking will have been done before this routine is called. + */ +void +_mesa_get_teximage(GLcontext *ctx, GLenum target, GLint level, + GLenum format, GLenum type, GLvoid *pixels, + const struct gl_texture_object *texObj, + const struct gl_texture_image *texImage) +{ + GLuint dimensions = (target == GL_TEXTURE_3D) ? 3 : 2; + + if (ctx->Pack.BufferObj->Name) { + /* pack texture image into a PBO */ + GLubyte *buf; + if (!_mesa_validate_pbo_access(dimensions, &ctx->Pack, texImage->Width, + texImage->Height, texImage->Depth, + format, type, pixels)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetTexImage(invalid PBO access)"); + return; + } + buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, + GL_WRITE_ONLY_ARB, + ctx->Pack.BufferObj); + if (!buf) { + /* buffer is already mapped - that's an error */ + _mesa_error(ctx, GL_INVALID_OPERATION,"glGetTexImage(PBO is mapped)"); + return; + } + pixels = ADD_POINTERS(buf, pixels); + } + else if (!pixels) { + /* not an error */ + return; + } + + { + const GLint width = texImage->Width; + const GLint height = texImage->Height; + const GLint depth = texImage->Depth; + GLint img, row; + for (img = 0; img < depth; img++) { + for (row = 0; row < height; row++) { + /* compute destination address in client memory */ + GLvoid *dest = _mesa_image_address( dimensions, &ctx->Pack, pixels, + width, height, format, type, + img, row, 0); + assert(dest); + + if (format == GL_COLOR_INDEX) { + GLuint indexRow[MAX_WIDTH]; + GLint col; + /* Can't use FetchTexel here because that returns RGBA */ + if (texImage->TexFormat->IndexBits == 8) { + const GLubyte *src = (const GLubyte *) texImage->Data; + for (col = 0; col < width; col++) { + indexRow[col] = src[texImage->Width * + (img * texImage->Height + row) + col]; + } + } + else if (texImage->TexFormat->IndexBits == 16) { + const GLushort *src = (const GLushort *) texImage->Data; + for (col = 0; col < width; col++) { + indexRow[col] = src[texImage->Width * + (img * texImage->Height + row) + col]; + } + } + else { + _mesa_problem(ctx, + "Color index problem in _mesa_GetTexImage"); + } + _mesa_pack_index_span(ctx, width, type, dest, + indexRow, &ctx->Pack, + 0 /* no image transfer */); + } + else if (format == GL_DEPTH_COMPONENT) { + GLfloat depthRow[MAX_WIDTH]; + GLint col; + for (col = 0; col < width; col++) { + (*texImage->FetchTexelf)(texImage, col, row, img, + depthRow + col); + } + _mesa_pack_depth_span(ctx, width, dest, type, + depthRow, &ctx->Pack); + } + else if (format == GL_YCBCR_MESA) { + /* No pixel transfer */ + const GLint rowstride = texImage->RowStride; + MEMCPY(dest, + (const GLushort *) texImage->Data + row * rowstride, + width * sizeof(GLushort)); + /* check for byte swapping */ + if ((texImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR + && type == GL_UNSIGNED_SHORT_8_8_REV_MESA) || + (texImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR_REV + && type == GL_UNSIGNED_SHORT_8_8_MESA)) { + if (!ctx->Pack.SwapBytes) + _mesa_swap2((GLushort *) dest, width); + } + else if (ctx->Pack.SwapBytes) { + _mesa_swap2((GLushort *) dest, width); + } + } + else { + /* general case: convert row to RGBA format */ + GLfloat rgba[MAX_WIDTH][4]; + GLint col; + for (col = 0; col < width; col++) { + (*texImage->FetchTexelf)(texImage, col, row, img, rgba[col]); + } + _mesa_pack_rgba_span_float(ctx, width, + (const GLfloat (*)[4]) rgba, + format, type, dest, &ctx->Pack, + 0 /* no image transfer */); + } /* format */ + } /* row */ + } /* img */ + } + + if (ctx->Pack.BufferObj->Name) { + ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, + ctx->Pack.BufferObj); + } +} + + + +/** + * This is the software fallback for Driver.GetCompressedTexImage(). + * All error checking will have been done before this routine is called. + */ +void +_mesa_get_compressed_teximage(GLcontext *ctx, GLenum target, GLint level, + GLvoid *img, + const struct gl_texture_object *texObj, + const struct gl_texture_image *texImage) +{ + if (ctx->Pack.BufferObj->Name) { + /* pack texture image into a PBO */ + GLubyte *buf; + if ((const GLubyte *) img + texImage->CompressedSize > + (const GLubyte *) ctx->Pack.BufferObj->Size) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetCompressedTexImage(invalid PBO access)"); + return; + } + buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, + GL_WRITE_ONLY_ARB, + ctx->Pack.BufferObj); + if (!buf) { + /* buffer is already mapped - that's an error */ + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetCompressedTexImage(PBO is mapped)"); + return; + } + img = ADD_POINTERS(buf, img); + } + else if (!img) { + /* not an error */ + return; + } + + /* just memcpy, no pixelstore or pixel transfer */ + MEMCPY(img, texImage->Data, texImage->CompressedSize); + + if (ctx->Pack.BufferObj->Name) { + ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, + ctx->Pack.BufferObj); + } +} diff --git a/src/mesa/main/texstore.h b/src/mesa/main/texstore.h index 89faf526698..c7cbcb0cf91 100644 --- a/src/mesa/main/texstore.h +++ b/src/mesa/main/texstore.h @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 6.1 + * Version: 6.3 * * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. * @@ -213,17 +213,32 @@ _mesa_generate_mipmap(GLcontext *ctx, GLenum target, extern void -_mesa_rescale_teximage2d (GLuint bytesPerPixel, - GLuint srcStrideInPixels, - GLuint dstRowStride, - GLint srcWidth, GLint srcHeight, - GLint dstWidth, GLint dstHeight, - const GLvoid *srcImage, GLvoid *dstImage); +_mesa_rescale_teximage2d(GLuint bytesPerPixel, + GLuint srcStrideInPixels, + GLuint dstRowStride, + GLint srcWidth, GLint srcHeight, + GLint dstWidth, GLint dstHeight, + const GLvoid *srcImage, GLvoid *dstImage); extern void -_mesa_upscale_teximage2d( GLsizei inWidth, GLsizei inHeight, - GLsizei outWidth, GLsizei outHeight, - GLint comps, const GLchan *src, GLint srcRowStride, - GLchan *dest ); +_mesa_upscale_teximage2d(GLsizei inWidth, GLsizei inHeight, + GLsizei outWidth, GLsizei outHeight, + GLint comps, const GLchan *src, GLint srcRowStride, + GLchan *dest); + + +extern void +_mesa_get_teximage(GLcontext *ctx, GLenum target, GLint level, + GLenum format, GLenum type, GLvoid *pixels, + const struct gl_texture_object *texObj, + const struct gl_texture_image *texImage); + + +extern void +_mesa_get_compressed_teximage(GLcontext *ctx, GLenum target, GLint level, + GLvoid *img, + const struct gl_texture_object *texObj, + const struct gl_texture_image *texImage); + #endif