From fcbf66364032743abeb41a82a5ceaf68a15d900f Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 29 Oct 2009 16:29:31 -0600 Subject: mesa: lift memcpy_get_tex_image() code from intel driver into core Mesa The code should work for any driver. --- src/mesa/main/texgetimage.c | 84 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-) (limited to 'src/mesa/main/texgetimage.c') diff --git a/src/mesa/main/texgetimage.c b/src/mesa/main/texgetimage.c index 3dff86feb1..10c6947c37 100644 --- a/src/mesa/main/texgetimage.c +++ b/src/mesa/main/texgetimage.c @@ -354,6 +354,85 @@ get_tex_rgba(GLcontext *ctx, GLuint dimensions, } +/** + * Try to do glGetTexImage() with simple memcpy(). + * \return GL_TRUE if done, GL_FALSE otherwise + */ +static GLboolean +get_tex_memcpy(GLcontext *ctx, GLenum format, GLenum type, GLvoid *pixels, + const struct gl_texture_object *texObj, + const struct gl_texture_image *texImage) +{ + GLboolean memCopy = GL_FALSE; + + /* Texture image should have been mapped already */ + assert(texImage->Data); + + /* + * Check if the src/dst formats are compatible. + * Also note that GL's pixel transfer ops don't apply to glGetTexImage() + * so we don't have to worry about those. + * XXX more format combinations could be supported here. + */ + if ((texObj->Target == GL_TEXTURE_1D || + texObj->Target == GL_TEXTURE_2D || + texObj->Target == GL_TEXTURE_RECTANGLE || + (texObj->Target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && + texObj->Target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z))) { + if (texImage->TexFormat == MESA_FORMAT_ARGB8888 && + format == GL_BGRA && + type == GL_UNSIGNED_BYTE && + !ctx->Pack.SwapBytes && + _mesa_little_endian()) { + memCopy = GL_TRUE; + } + else if (texImage->TexFormat == MESA_FORMAT_AL88 && + format == GL_LUMINANCE_ALPHA && + type == GL_UNSIGNED_BYTE && + !ctx->Pack.SwapBytes && + _mesa_little_endian()) { + memCopy = GL_TRUE; + } + else if (texImage->TexFormat == MESA_FORMAT_L8 && + format == GL_LUMINANCE && + type == GL_UNSIGNED_BYTE) { + memCopy = GL_TRUE; + } + else if (texImage->TexFormat == MESA_FORMAT_A8 && + format == GL_ALPHA && + type == GL_UNSIGNED_BYTE) { + memCopy = GL_TRUE; + } + } + + if (memCopy) { + const GLuint bpp = _mesa_get_format_bytes(texImage->TexFormat); + const GLuint bytesPerRow = texImage->Width * bpp; + GLubyte *dst = + _mesa_image_address2d(&ctx->Pack, pixels, texImage->Width, + texImage->Height, format, type, 0, 0); + const GLint dstRowStride = + _mesa_image_row_stride(&ctx->Pack, texImage->Width, format, type); + const GLubyte *src = texImage->Data; + const GLint srcRowStride = texImage->RowStride * bpp; + GLuint row; + + if (bytesPerRow == dstRowStride && bytesPerRow == srcRowStride) { + memcpy(dst, src, bytesPerRow * texImage->Height); + } + else { + for (row = 0; row < texImage->Height; row++) { + memcpy(dst, src, bytesPerRow); + dst += dstRowStride; + src += srcRowStride; + } + } + } + + return memCopy; +} + + /** * This is the software fallback for Driver.GetTexImage(). * All error checking will have been done before this routine is called. @@ -402,7 +481,10 @@ _mesa_get_teximage(GLcontext *ctx, GLenum target, GLint level, pixels = ADD_POINTERS(buf, pixels); } - if (format == GL_COLOR_INDEX) { + if (get_tex_memcpy(ctx, format, type, pixels, texObj, texImage)) { + /* all done */ + } + else if (format == GL_COLOR_INDEX) { get_tex_color_index(ctx, dimensions, format, type, pixels, texImage); } else if (format == GL_DEPTH_COMPONENT) { -- cgit v1.2.3