Mesa (master): radeon: Fix crash when rendering to incomplete texture and other formats

Nicolai Hähnle nh at kemper.freedesktop.org
Sun Jul 12 10:51:12 UTC 2009


Module: Mesa
Branch: master
Commit: b484c71036e0d0b30ac7685ba50a9008d09f5047
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=b484c71036e0d0b30ac7685ba50a9008d09f5047

Author: Nicolai Hähnle <nhaehnle at gmail.com>
Date:   Sun Jul 12 11:18:43 2009 +0200

radeon: Fix crash when rendering to incomplete texture and other formats

It is possible to bind texture images of an incomplete mipmapped texture.
Software fallbacks in this case incorrectly tried to mmap the entire texture.

Additionally, add span functions for 1555 and 4444 formats.

This fixes crashes in piglit's fbo-readpixels test; unfortunately, the test
itself still fails - this needs to be investigated.

Signed-off-by: Nicolai Hähnle <nhaehnle at gmail.com>

---

 src/mesa/drivers/dri/radeon/radeon_span.c |   51 ++++++++++++++++++++++------
 1 files changed, 40 insertions(+), 11 deletions(-)

diff --git a/src/mesa/drivers/dri/radeon/radeon_span.c b/src/mesa/drivers/dri/radeon/radeon_span.c
index 4f5480b..a6ea8f0 100644
--- a/src/mesa/drivers/dri/radeon/radeon_span.c
+++ b/src/mesa/drivers/dri/radeon/radeon_span.c
@@ -239,7 +239,7 @@ s8z24_to_z24s8(uint32_t val)
 	 int miny = cliprects[_nc].y1 - y_off;				\
 	 int maxx = cliprects[_nc].x2 - x_off;				\
 	 int maxy = cliprects[_nc].y2 - y_off;
-	
+
 /* ================================================================
  * Color buffer
  */
@@ -254,6 +254,26 @@ s8z24_to_z24s8(uint32_t val)
 #define GET_PTR(X,Y) radeon_ptr16(rrb, (X) + x_off, (Y) + y_off)
 #include "spantmp2.h"
 
+/* 16 bit, ARGB1555 color spanline and pixel functions
+ */
+#define SPANTMP_PIXEL_FMT GL_BGRA
+#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_1_5_5_5_REV
+
+#define TAG(x)    radeon##x##_ARGB1555
+#define TAG2(x,y) radeon##x##_ARGB1555##y
+#define GET_PTR(X,Y) radeon_ptr16(rrb, (X) + x_off, (Y) + y_off)
+#include "spantmp2.h"
+
+/* 16 bit, RGBA4 color spanline and pixel functions
+ */
+#define SPANTMP_PIXEL_FMT GL_BGRA
+#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_4_4_4_4_REV
+
+#define TAG(x)    radeon##x##_ARGB4444
+#define TAG2(x,y) radeon##x##_ARGB4444##y
+#define GET_PTR(X,Y) radeon_ptr16(rrb, (X) + x_off, (Y) + y_off)
+#include "spantmp2.h"
+
 /* 32 bit, xRGB8888 color spanline and pixel functions
  */
 #define SPANTMP_PIXEL_FMT GL_BGRA
@@ -438,7 +458,7 @@ static void map_unmap_rb(struct gl_renderbuffer *rb, int flag)
 {
 	struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb);
 	int r;
-	
+
 	if (rrb == NULL || !rrb->bo)
 		return;
 
@@ -474,25 +494,30 @@ radeon_map_unmap_buffers(GLcontext *ctx, GLboolean map)
 			ctx->DrawBuffer->Attachment + i;
 		struct gl_texture_object *tex = att->Texture;
 		if (tex) {
-			/* render to texture */
+			/* Render to texture. Note that a mipmapped texture need not
+			 * be complete for render to texture, so we must restrict to
+			 * mapping only the attached image.
+			 */
+			radeon_texture_image *image = get_radeon_texture_image(tex->Image[att->CubeMapFace][att->TextureLevel]);
 			ASSERT(att->Renderbuffer);
+
 			if (map)
-				ctx->Driver.MapTexture(ctx, tex);
+				radeon_teximage_map(image, GL_TRUE);
 			else
-				ctx->Driver.UnmapTexture(ctx, tex);
+				radeon_teximage_unmap(image);
 		}
 	}
-	
+
 	map_unmap_rb(ctx->ReadBuffer->_ColorReadBuffer, map);
 
 	/* depth buffer (Note wrapper!) */
 	if (ctx->DrawBuffer->_DepthBuffer)
 		map_unmap_rb(ctx->DrawBuffer->_DepthBuffer->Wrapped, map);
-	
+
 	if (ctx->DrawBuffer->_StencilBuffer)
 		map_unmap_rb(ctx->DrawBuffer->_StencilBuffer->Wrapped, map);
-
 }
+
 static void radeonSpanRenderStart(GLcontext * ctx)
 {
 	radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
@@ -509,15 +534,13 @@ static void radeonSpanRenderStart(GLcontext * ctx)
 		LOCK_HARDWARE(rmesa);
 		radeonWaitForIdleLocked(rmesa);
 	}
+
 	for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
 		if (ctx->Texture.Unit[i]._ReallyEnabled)
 			ctx->Driver.MapTexture(ctx, ctx->Texture.Unit[i]._Current);
 	}
 
 	radeon_map_unmap_buffers(ctx, 1);
-
-
-
 }
 
 static void radeonSpanRenderFinish(GLcontext * ctx)
@@ -555,6 +578,10 @@ static void radeonSetSpanFunctions(struct radeon_renderbuffer *rrb)
 		radeonInitPointers_xRGB8888(&rrb->base);
 	} else if (rrb->base._ActualFormat == GL_RGBA8) {
 		radeonInitPointers_ARGB8888(&rrb->base);
+	} else if (rrb->base._ActualFormat == GL_RGBA4) {
+		radeonInitPointers_ARGB4444(&rrb->base);
+	} else if (rrb->base._ActualFormat == GL_RGB5_A1) {
+		radeonInitPointers_ARGB1555(&rrb->base);
 	} else if (rrb->base._ActualFormat == GL_DEPTH_COMPONENT16) {
 		radeonInitDepthPointers_z16(&rrb->base);
 	} else if (rrb->base._ActualFormat == GL_DEPTH_COMPONENT24) {
@@ -563,5 +590,7 @@ static void radeonSetSpanFunctions(struct radeon_renderbuffer *rrb)
 		radeonInitDepthPointers_z24_s8(&rrb->base);
 	} else if (rrb->base._ActualFormat == GL_STENCIL_INDEX8_EXT) {
 		radeonInitStencilPointers_z24_s8(&rrb->base);
+	} else {
+		fprintf(stderr, "radeonSetSpanFunctions: bad actual format: 0x%04X\n", rrb->base._ActualFormat);
 	}
 }




More information about the mesa-commit mailing list