diff options
author | Nicolai Hähnle <[email protected]> | 2009-07-12 11:18:43 +0200 |
---|---|---|
committer | Nicolai Hähnle <[email protected]> | 2009-07-12 12:50:36 +0200 |
commit | b484c71036e0d0b30ac7685ba50a9008d09f5047 (patch) | |
tree | 90cd13c1c106750ccf6e13bdb48b0980cca91d84 | |
parent | a10244453c24d62cd87f8c4d85cbe103b62db311 (diff) |
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 <[email protected]>
-rw-r--r-- | 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 4f5480b1708..a6ea8f021e4 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); } } |