From 7d19d2768491f4de3b674106e93c24d29712404f Mon Sep 17 00:00:00 2001 From: Nicolai Haehnle Date: Sat, 14 Feb 2009 21:43:30 +0100 Subject: [PATCH] radeon-common: Fix crash in glGetTexImage Since texture images are now stored in miptrees, we cannot usually access them directly via the Data pointer. So we wrap Mesa's implementation by map/unmap calls. This crash was triggered by Sauerbraten, Piglit now contains a regression test. Signed-off-by: Nicolai Haehnle --- src/mesa/drivers/dri/r200/r200_tex.c | 2 + src/mesa/drivers/dri/r300/r300_tex.c | 2 + src/mesa/drivers/dri/radeon/radeon_tex.c | 2 + src/mesa/drivers/dri/radeon/radeon_texture.c | 53 ++++++++++++++++++++ src/mesa/drivers/dri/radeon/radeon_texture.h | 10 ++++ 5 files changed, 69 insertions(+) diff --git a/src/mesa/drivers/dri/r200/r200_tex.c b/src/mesa/drivers/dri/r200/r200_tex.c index c0d1723c77c..5daacb8c95a 100644 --- a/src/mesa/drivers/dri/r200/r200_tex.c +++ b/src/mesa/drivers/dri/r200/r200_tex.c @@ -512,6 +512,8 @@ void r200InitTextureFuncs( struct dd_function_table *functions ) #else functions->TexSubImage3D = _mesa_store_texsubimage3d; #endif + functions->GetTexImage = radeonGetTexImage; + functions->GetCompressedTexImage = radeonGetCompressedTexImage; functions->NewTextureObject = r200NewTextureObject; // functions->BindTexture = r200BindTexture; functions->DeleteTexture = r200DeleteTexture; diff --git a/src/mesa/drivers/dri/r300/r300_tex.c b/src/mesa/drivers/dri/r300/r300_tex.c index e316e2d822b..27b907019e3 100644 --- a/src/mesa/drivers/dri/r300/r300_tex.c +++ b/src/mesa/drivers/dri/r300/r300_tex.c @@ -325,6 +325,8 @@ void r300InitTextureFuncs(struct dd_function_table *functions) functions->TexSubImage1D = radeonTexSubImage1D; functions->TexSubImage2D = radeonTexSubImage2D; functions->TexSubImage3D = radeonTexSubImage3D; + functions->GetTexImage = radeonGetTexImage; + functions->GetCompressedTexImage = radeonGetCompressedTexImage; functions->NewTextureObject = r300NewTextureObject; functions->DeleteTexture = r300DeleteTexture; functions->IsTextureResident = driIsTextureResident; diff --git a/src/mesa/drivers/dri/radeon/radeon_tex.c b/src/mesa/drivers/dri/radeon/radeon_tex.c index e1b988bf4dc..4d98b72612b 100644 --- a/src/mesa/drivers/dri/radeon/radeon_tex.c +++ b/src/mesa/drivers/dri/radeon/radeon_tex.c @@ -456,6 +456,8 @@ void radeonInitTextureFuncs( struct dd_function_table *functions ) functions->TexImage2D = radeonTexImage2D; functions->TexSubImage1D = radeonTexSubImage1D; functions->TexSubImage2D = radeonTexSubImage2D; + functions->GetTexImage = radeonGetTexImage; + functions->GetCompressedTexImage = radeonGetCompressedTexImage; functions->NewTextureObject = radeonNewTextureObject; // functions->BindTexture = radeonBindTexture; diff --git a/src/mesa/drivers/dri/radeon/radeon_texture.c b/src/mesa/drivers/dri/radeon/radeon_texture.c index 55dda29eaf9..93ab5f72604 100644 --- a/src/mesa/drivers/dri/radeon/radeon_texture.c +++ b/src/mesa/drivers/dri/radeon/radeon_texture.c @@ -883,3 +883,56 @@ int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *t return GL_TRUE; } + +/** + * Need to map texture image into memory before copying image data, + * then unmap it. + */ +static void +radeon_get_tex_image(GLcontext * ctx, GLenum target, GLint level, + GLenum format, GLenum type, GLvoid * pixels, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage, int compressed) +{ + radeon_texture_image *image = get_radeon_texture_image(texImage); + + if (image->mt) { + /* Map the texture image read-only */ + radeon_teximage_map(image, GL_FALSE); + } else { + /* Image hasn't been uploaded to a miptree yet */ + assert(image->base.Data); + } + + if (compressed) { + _mesa_get_compressed_teximage(ctx, target, level, pixels, + texObj, texImage); + } else { + _mesa_get_teximage(ctx, target, level, format, type, pixels, + texObj, texImage); + } + + if (image->mt) { + radeon_teximage_unmap(image); + } +} + +void +radeonGetTexImage(GLcontext * ctx, GLenum target, GLint level, + GLenum format, GLenum type, GLvoid * pixels, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + radeon_get_tex_image(ctx, target, level, format, type, pixels, + texObj, texImage, 0); +} + +void +radeonGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level, + GLvoid *pixels, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + radeon_get_tex_image(ctx, target, level, 0, 0, pixels, + texObj, texImage, 1); +} diff --git a/src/mesa/drivers/dri/radeon/radeon_texture.h b/src/mesa/drivers/dri/radeon/radeon_texture.h index ff0e1d061ed..d90fda7868f 100644 --- a/src/mesa/drivers/dri/radeon/radeon_texture.h +++ b/src/mesa/drivers/dri/radeon/radeon_texture.h @@ -105,4 +105,14 @@ void radeonTexSubImage3D(GLcontext * ctx, GLenum target, GLint level, const struct gl_pixelstore_attrib *packing, struct gl_texture_object *texObj, struct gl_texture_image *texImage); + +void radeonGetTexImage(GLcontext * ctx, GLenum target, GLint level, + GLenum format, GLenum type, GLvoid * pixels, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); +void radeonGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level, + GLvoid *pixels, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); + #endif -- 2.30.2