From b2596c36c8f73e8bb7a0b1679b491662aeb2f9d9 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 11 Nov 2011 16:13:06 +0000 Subject: radeon: texture/renderbuffer overhaul. This could have been split up better, but the driver is just broken now, so bisecting the brokenness is going to be painful no matter what. This adds renderbuffer mapping/unmapping along with texture image allocation. It drops all the old texture upload paths, some of which could possible be reimplemented with the blitter later. It also redoes the span code paths to use its own set of image mapping handlers, along with removing the tiling decode paths for the color buffers, since we now hope to use the blitter for this. Signed-off-by: Dave Airlie --- src/mesa/drivers/dri/r200/r200_blit.c | 16 +- src/mesa/drivers/dri/r200/r200_blit.h | 2 +- src/mesa/drivers/dri/radeon/radeon_blit.c | 16 +- src/mesa/drivers/dri/radeon/radeon_blit.h | 2 +- .../drivers/dri/radeon/radeon_common_context.h | 4 +- src/mesa/drivers/dri/radeon/radeon_fbo.c | 132 +++-- src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c | 30 +- src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h | 7 +- src/mesa/drivers/dri/radeon/radeon_pixel_read.c | 2 +- src/mesa/drivers/dri/radeon/radeon_span.c | 165 +++--- src/mesa/drivers/dri/radeon/radeon_tex_copy.c | 2 +- src/mesa/drivers/dri/radeon/radeon_texture.c | 600 +++++++-------------- src/mesa/drivers/dri/radeon/radeon_texture.h | 6 +- 13 files changed, 385 insertions(+), 599 deletions(-) diff --git a/src/mesa/drivers/dri/r200/r200_blit.c b/src/mesa/drivers/dri/r200/r200_blit.c index 487bb5b78e1..04ab6d07def 100644 --- a/src/mesa/drivers/dri/r200/r200_blit.c +++ b/src/mesa/drivers/dri/r200/r200_blit.c @@ -38,7 +38,7 @@ static inline uint32_t cmdpacket0(struct radeon_screen *rscrn, } /* common formats supported as both textures and render targets */ -unsigned r200_check_blit(gl_format mesa_format) +unsigned r200_check_blit(gl_format mesa_format, uint32_t dst_pitch) { /* XXX others? BE/LE? */ switch (mesa_format) { @@ -58,6 +58,12 @@ unsigned r200_check_blit(gl_format mesa_format) return 0; } + /* Rendering to small buffer doesn't work. + * Looks like a hw limitation. + */ + if (dst_pitch < 32) + return 0; + /* ??? */ if (_mesa_get_format_bits(mesa_format, GL_DEPTH_BITS) > 0) return 0; @@ -467,19 +473,13 @@ unsigned r200_blit(struct gl_context *ctx, { struct r200_context *r200 = R200_CONTEXT(ctx); - if (!r200_check_blit(dst_mesaformat)) + if (!r200_check_blit(dst_mesaformat, dst_pitch)) return GL_FALSE; /* Make sure that colorbuffer has even width - hw limitation */ if (dst_pitch % 2 > 0) ++dst_pitch; - /* Rendering to small buffer doesn't work. - * Looks like a hw limitation. - */ - if (dst_pitch < 32) - return GL_FALSE; - /* Need to clamp the region size to make sure * we don't read outside of the source buffer * or write outside of the destination buffer. diff --git a/src/mesa/drivers/dri/r200/r200_blit.h b/src/mesa/drivers/dri/r200/r200_blit.h index 56018b9c0ea..fb5dacbe870 100644 --- a/src/mesa/drivers/dri/r200/r200_blit.h +++ b/src/mesa/drivers/dri/r200/r200_blit.h @@ -30,7 +30,7 @@ void r200_blit_init(struct r200_context *r200); -unsigned r200_check_blit(gl_format mesa_format); +unsigned r200_check_blit(gl_format mesa_format, uint32_t dst_pitch); unsigned r200_blit(struct gl_context *ctx, struct radeon_bo *src_bo, diff --git a/src/mesa/drivers/dri/radeon/radeon_blit.c b/src/mesa/drivers/dri/radeon/radeon_blit.c index 330e1abdfe5..b84f2fa9f2b 100644 --- a/src/mesa/drivers/dri/radeon/radeon_blit.c +++ b/src/mesa/drivers/dri/radeon/radeon_blit.c @@ -38,7 +38,7 @@ static inline uint32_t cmdpacket0(struct radeon_screen *rscrn, } /* common formats supported as both textures and render targets */ -unsigned r100_check_blit(gl_format mesa_format) +unsigned r100_check_blit(gl_format mesa_format, uint32_t dst_pitch) { /* XXX others? BE/LE? */ switch (mesa_format) { @@ -55,6 +55,12 @@ unsigned r100_check_blit(gl_format mesa_format) return 0; } + /* Rendering to small buffer doesn't work. + * Looks like a hw limitation. + */ + if (dst_pitch < 32) + return 0; + /* ??? */ if (_mesa_get_format_bits(mesa_format, GL_DEPTH_BITS) > 0) return 0; @@ -344,19 +350,13 @@ unsigned r100_blit(struct gl_context *ctx, { struct r100_context *r100 = R100_CONTEXT(ctx); - if (!r100_check_blit(dst_mesaformat)) + if (!r100_check_blit(dst_mesaformat, dst_pitch)) return GL_FALSE; /* Make sure that colorbuffer has even width - hw limitation */ if (dst_pitch % 2 > 0) ++dst_pitch; - /* Rendering to small buffer doesn't work. - * Looks like a hw limitation. - */ - if (dst_pitch < 32) - return GL_FALSE; - /* Need to clamp the region size to make sure * we don't read outside of the source buffer * or write outside of the destination buffer. diff --git a/src/mesa/drivers/dri/radeon/radeon_blit.h b/src/mesa/drivers/dri/radeon/radeon_blit.h index 5e5c73481a6..4fac4afe889 100644 --- a/src/mesa/drivers/dri/radeon/radeon_blit.h +++ b/src/mesa/drivers/dri/radeon/radeon_blit.h @@ -30,7 +30,7 @@ void r100_blit_init(struct r100_context *r100); -unsigned r100_check_blit(gl_format mesa_format); +unsigned r100_check_blit(gl_format mesa_format, uint32_t dst_pitch); unsigned r100_blit(struct gl_context *ctx, struct radeon_bo *src_bo, diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.h b/src/mesa/drivers/dri/radeon/radeon_common_context.h index 6de9f8a37b5..b8c6bf00ebc 100644 --- a/src/mesa/drivers/dri/radeon/radeon_common_context.h +++ b/src/mesa/drivers/dri/radeon/radeon_common_context.h @@ -89,6 +89,7 @@ struct radeon_renderbuffer struct radeon_bo *map_bo; GLbitfield map_mode; int map_x, map_y, map_w, map_h; + int map_pitch; uint32_t draw_offset; /* FBO */ /* boo Xorg 6.8.2 compat */ @@ -174,6 +175,7 @@ struct _radeon_texture_image { */ struct _radeon_mipmap_tree *mt; struct radeon_bo *bo; + GLboolean used_as_render_target; }; @@ -481,7 +483,7 @@ struct radeon_context { void (*free_context)(struct gl_context *ctx); void (*emit_query_finish)(radeonContextPtr radeon); void (*update_scissor)(struct gl_context *ctx); - unsigned (*check_blit)(gl_format mesa_format); + unsigned (*check_blit)(gl_format mesa_format, uint32_t dst_pitch); unsigned (*blit)(struct gl_context *ctx, struct radeon_bo *src_bo, intptr_t src_offset, diff --git a/src/mesa/drivers/dri/radeon/radeon_fbo.c b/src/mesa/drivers/dri/radeon/radeon_fbo.c index 9967fe5139e..5aad67f1a75 100644 --- a/src/mesa/drivers/dri/radeon/radeon_fbo.c +++ b/src/mesa/drivers/dri/radeon/radeon_fbo.c @@ -82,56 +82,96 @@ radeon_map_renderbuffer(struct gl_context *ctx, struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb); GLubyte *map; GLboolean ok; - int stride, ret; - - assert(rrb && rrb->bo); - - /* Make a temporary buffer and blit the current contents of the renderbuffer - * out to it. This gives us linear access to the buffer, instead of having - * to do detiling in software. - */ - assert(!rrb->map_bo); - rrb->map_bo = radeon_bo_open(rmesa->radeonScreen->bom, 0, - rrb->pitch * h, 4, - RADEON_GEM_DOMAIN_GTT, 0); + int stride, flip_stride; + int ret; + int src_x, src_y; + + if (!rrb || !rrb->bo) { + *out_map = NULL; + *out_stride = 0; + return; + } + rrb->map_mode = mode; rrb->map_x = x; rrb->map_y = y; rrb->map_w = w; rrb->map_h = h; + rrb->map_pitch = rrb->pitch; + + ok = rmesa->vtbl.check_blit(rb->Format, rrb->pitch / rrb->cpp); + if (ok) { + if (rb->Name) { + src_x = x; + src_y = y; + } else { + src_x = x; + src_y = rrb->base.Height - y - h; + } + + /* Make a temporary buffer and blit the current contents of the renderbuffer + * out to it. This gives us linear access to the buffer, instead of having + * to do detiling in software. + */ + + rrb->map_pitch = rrb->pitch; + + assert(!rrb->map_bo); + rrb->map_bo = radeon_bo_open(rmesa->radeonScreen->bom, 0, + rrb->map_pitch * h, 4, + RADEON_GEM_DOMAIN_GTT, 0); + + ok = rmesa->vtbl.blit(ctx, rrb->bo, rrb->draw_offset, + rb->Format, rrb->pitch / rrb->cpp, + rb->Width, rb->Height, + src_x, src_y, + rrb->map_bo, 0, + rb->Format, rrb->map_pitch / rrb->cpp, + w, h, + 0, 0, + w, h, + GL_FALSE); + assert(ok); + + ret = radeon_bo_map(rrb->map_bo, !!(mode & GL_MAP_WRITE_BIT)); + assert(!ret); + + map = rrb->map_bo->ptr; + + if (rb->Name) { + *out_map = map; + *out_stride = rrb->map_pitch; + } else { + *out_map = map + (h - 1) * rrb->map_pitch; + *out_stride = -rrb->map_pitch; + } + return; + } + + /* sw fallback flush stuff */ + if (radeon_bo_is_referenced_by_cs(rrb->bo, rmesa->cmdbuf.cs)) { + radeon_firevertices(rmesa); + } - ok = rmesa->vtbl.check_blit(rb->Format); - assert(ok); - - ok = rmesa->vtbl.blit(ctx, rrb->bo, rrb->draw_offset, - rb->Format, rrb->pitch / rrb->cpp, - rb->Width, rb->Height, - x, y, - rrb->map_bo, 0, - rb->Format, rrb->pitch / rrb->cpp, - w, h, - 0, 0, - w, h, - GL_FALSE); - assert(ok); - - radeon_bo_wait(rrb->map_bo); - ret = radeon_bo_map(rrb->map_bo, !!(mode & GL_MAP_WRITE_BIT)); + ret = radeon_bo_map(rrb->bo, !!(mode & GL_MAP_WRITE_BIT)); assert(!ret); - map = rrb->map_bo->ptr; - stride = rrb->pitch; + map = rrb->bo->ptr; + stride = rrb->map_pitch; if (rb->Name == 0) { - map += stride * (rb->Height - 1); - stride = -stride; + y = rb->Height - 1 - y; + flip_stride = -stride; + } else { + flip_stride = stride; + map += rrb->draw_offset; } - map += x * _mesa_get_format_bytes(rb->Format); + map += x * rrb->cpp; map += (int)y * stride; *out_map = map; - *out_stride = stride; + *out_stride = flip_stride; } static void @@ -142,11 +182,17 @@ radeon_unmap_renderbuffer(struct gl_context *ctx, struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb); GLboolean ok; + if (!rrb->map_bo) { + if (rrb->bo) + radeon_bo_unmap(rrb->bo); + return; + } + radeon_bo_unmap(rrb->map_bo); if (rrb->map_mode & GL_MAP_WRITE_BIT) { ok = rmesa->vtbl.blit(ctx, rrb->map_bo, 0, - rb->Format, rrb->pitch / rrb->cpp, + rb->Format, rrb->map_pitch / rrb->cpp, rrb->map_w, rrb->map_h, 0, 0, rrb->bo, rrb->draw_offset, @@ -627,7 +673,7 @@ radeon_render_texture(struct gl_context * ctx, radeon_image = (radeon_texture_image *)newImage; - if (!radeon_image->mt || newImage->Border != 0) { + if (!radeon_image->mt) { /* Fallback on drawing to a texture without a miptree. */ _mesa_reference_renderbuffer(&att->Renderbuffer, NULL); @@ -681,6 +727,7 @@ radeon_render_texture(struct gl_context * ctx, * the image we are rendering to */ rrb->draw_offset = imageOffset; rrb->pitch = radeon_image->mt->levels[att->TextureLevel].rowstride; + radeon_image->used_as_render_target = GL_TRUE; /* update drawing region, etc */ radeon_draw_buffer(ctx, fb); @@ -690,7 +737,16 @@ static void radeon_finish_render_texture(struct gl_context * ctx, struct gl_renderbuffer_attachment *att) { - + struct gl_texture_object *tex_obj = att->Texture; + struct gl_texture_image *image = + tex_obj->Image[att->CubeMapFace][att->TextureLevel]; + radeon_texture_image *radeon_image = (radeon_texture_image *)image; + + if (radeon_image) + radeon_image->used_as_render_target = GL_FALSE; + + if (ctx->Driver.Flush) + ctx->Driver.Flush(ctx); /* +r6/r7 */ } static void radeon_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb) diff --git a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c index 05daf1cec43..23af9aca6ce 100644 --- a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c +++ b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c @@ -185,9 +185,9 @@ static void calculate_miptree_layout(radeonContextPtr rmesa, radeon_mipmap_tree /** * Create a new mipmap tree, calculate its layout and allocate memory. */ -static radeon_mipmap_tree* radeon_miptree_create(radeonContextPtr rmesa, - GLenum target, gl_format mesaFormat, GLuint baseLevel, GLuint numLevels, - GLuint width0, GLuint height0, GLuint depth0, GLuint tilebits) +radeon_mipmap_tree* radeon_miptree_create(radeonContextPtr rmesa, + GLenum target, gl_format mesaFormat, GLuint baseLevel, GLuint numLevels, + GLuint width0, GLuint height0, GLuint depth0, GLuint tilebits) { radeon_mipmap_tree *mt = CALLOC_STRUCT(_radeon_mipmap_tree); @@ -298,13 +298,10 @@ static void calculate_min_max_lod(struct gl_texture_object *tObj, * given face and level. */ GLboolean radeon_miptree_matches_image(radeon_mipmap_tree *mt, - struct gl_texture_image *texImage, GLuint face, GLuint level) + struct gl_texture_image *texImage) { radeon_mipmap_level *lvl; - - if (face >= mt->faces) - return GL_FALSE; - + GLuint level = texImage->Level; if (texImage->TexFormat != mt->mesaFormat) return GL_FALSE; @@ -332,7 +329,7 @@ static GLboolean radeon_miptree_matches_texture(radeon_mipmap_tree *mt, struct g mtBaseLevel = &mt->levels[texObj->BaseLevel - mt->baseLevel]; firstImage = texObj->Image[0][texObj->BaseLevel]; - numLevels = MIN2(texObj->MaxLevel - texObj->BaseLevel + 1, firstImage->MaxLog2 + 1); + numLevels = MIN2(texObj->_MaxLevel - texObj->BaseLevel + 1, firstImage->MaxLog2 + 1); if (radeon_is_debug_enabled(RADEON_TEXTURE,RADEON_TRACE)) { fprintf(stderr, "Checking if miptree %p matches texObj %p\n", mt, texObj); @@ -372,7 +369,6 @@ void radeon_try_alloc_miptree(radeonContextPtr rmesa, radeonTexObj *t) struct gl_texture_object *texObj = &t->base; struct gl_texture_image *texImg = texObj->Image[0][texObj->BaseLevel]; GLuint numLevels; - assert(!t->mt); if (!texImg) { @@ -544,27 +540,19 @@ int radeon_validate_texture_miptree(struct gl_context * ctx, struct gl_texture_o { radeonContextPtr rmesa = RADEON_CONTEXT(ctx); radeonTexObj *t = radeon_tex_obj(texObj); + radeon_mipmap_tree *dst_miptree; if (t->validated || t->image_override) { return GL_TRUE; } - if (texObj->Image[0][texObj->BaseLevel]->Border > 0) - return GL_FALSE; - - _mesa_test_texobj_completeness(rmesa->glCtx, texObj); - if (!texObj->_Complete) { - return GL_FALSE; - } - calculate_min_max_lod(&t->base, &t->minLod, &t->maxLod); radeon_print(RADEON_TEXTURE, RADEON_NORMAL, "%s: Validating texture %p now, minLod = %d, maxLod = %d\n", __FUNCTION__, texObj ,t->minLod, t->maxLod); - radeon_mipmap_tree *dst_miptree; - dst_miptree = get_biggest_matching_miptree(t, t->base.BaseLevel, t->base.MaxLevel); + dst_miptree = get_biggest_matching_miptree(t, t->base.BaseLevel, t->base._MaxLevel); radeon_miptree_unreference(&t->mt); if (!dst_miptree) { @@ -591,7 +579,7 @@ int radeon_validate_texture_miptree(struct gl_context * ctx, struct gl_texture_o "Checking image level %d, face %d, mt %p ... ", level, face, img->mt); - if (img->mt != t->mt) { + if (img->mt != t->mt && !img->used_as_render_target) { radeon_print(RADEON_TEXTURE, RADEON_TRACE, "MIGRATING\n"); diff --git a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h index c0c52f0ff9a..74007ffdebc 100644 --- a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h +++ b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h @@ -84,7 +84,8 @@ void radeon_miptree_reference(radeon_mipmap_tree *mt, radeon_mipmap_tree **ptr); void radeon_miptree_unreference(radeon_mipmap_tree **ptr); GLboolean radeon_miptree_matches_image(radeon_mipmap_tree *mt, - struct gl_texture_image *texImage, GLuint face, GLuint level); + struct gl_texture_image *texImage); + void radeon_try_alloc_miptree(radeonContextPtr rmesa, radeonTexObj *t); GLuint radeon_miptree_image_offset(radeon_mipmap_tree *mt, GLuint face, GLuint level); @@ -98,4 +99,8 @@ unsigned get_texture_image_size( unsigned height, unsigned depth, unsigned tiling); + +radeon_mipmap_tree *radeon_miptree_create(radeonContextPtr rmesa, + GLenum target, gl_format mesaFormat, GLuint baseLevel, GLuint numLevels, + GLuint width0, GLuint height0, GLuint depth0, GLuint tilebits); #endif /* __RADEON_MIPMAP_TREE_H_ */ diff --git a/src/mesa/drivers/dri/radeon/radeon_pixel_read.c b/src/mesa/drivers/dri/radeon/radeon_pixel_read.c index 9f6124034d9..68e3114989d 100644 --- a/src/mesa/drivers/dri/radeon/radeon_pixel_read.c +++ b/src/mesa/drivers/dri/radeon/radeon_pixel_read.c @@ -105,7 +105,7 @@ do_blit_readpixels(struct gl_context * ctx, } if (dst_format == MESA_FORMAT_NONE || - !radeon->vtbl.check_blit(dst_format) || !radeon->vtbl.blit) { + !radeon->vtbl.check_blit(dst_format, rrb->pitch / rrb->cpp) || !radeon->vtbl.blit) { return GL_FALSE; } diff --git a/src/mesa/drivers/dri/radeon/radeon_span.c b/src/mesa/drivers/dri/radeon/radeon_span.c index ecc3befdbfe..b83d152091c 100644 --- a/src/mesa/drivers/dri/radeon/radeon_span.c +++ b/src/mesa/drivers/dri/radeon/radeon_span.c @@ -216,25 +216,25 @@ static GLubyte *radeon_ptr_2byte_8x2(const struct radeon_renderbuffer * rrb, */ #define LOCAL_VARS \ struct radeon_renderbuffer *rrb = (void *) rb; \ - const GLint yScale = ctx->DrawBuffer->Name ? 1 : -1; \ - const GLint yBias = ctx->DrawBuffer->Name ? 0 : rrb->base.Height - 1;\ int minx = 0, miny = 0; \ int maxx = rb->Width; \ int maxy = rb->Height; \ + void *buf = rb->Data; \ + int pitch = rb->RowStride * rrb->cpp; \ GLuint p; \ (void)p; #define LOCAL_DEPTH_VARS \ struct radeon_renderbuffer *rrb = (void *) rb; \ - const GLint yScale = ctx->DrawBuffer->Name ? 1 : -1; \ - const GLint yBias = ctx->DrawBuffer->Name ? 0 : rrb->base.Height - 1;\ int minx = 0, miny = 0; \ + const GLint yScale = ctx->DrawBuffer->Name ? 1 : -1; \ + const GLint yBias = ctx->DrawBuffer->Name ? 0 : rrb->base.Height - 1; \ int maxx = rb->Width; \ int maxy = rb->Height; #define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS -#define Y_FLIP(_y) ((_y) * yScale + yBias) +#define Y_FLIP(_y) (_y) #define HW_LOCK() #define HW_UNLOCK() @@ -249,108 +249,78 @@ static GLubyte *radeon_ptr_2byte_8x2(const struct radeon_renderbuffer * rrb, */ #define SPANTMP_PIXEL_FMT GL_RGB #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5 - #define TAG(x) radeon##x##_RGB565 #define TAG2(x,y) radeon##x##_RGB565##y -#define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X), (Y)) #include "spantmp2.h" #define SPANTMP_PIXEL_FMT GL_RGB #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5_REV - #define TAG(x) radeon##x##_RGB565_REV #define TAG2(x,y) radeon##x##_RGB565_REV##y -#define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X), (Y)) #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_ptr_2byte_8x2(rrb, (X), (Y)) #include "spantmp2.h" #define SPANTMP_PIXEL_FMT GL_BGRA #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_1_5_5_5 - #define TAG(x) radeon##x##_ARGB1555_REV #define TAG2(x,y) radeon##x##_ARGB1555_REV##y -#define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X), (Y)) #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_ptr_2byte_8x2(rrb, (X), (Y)) #include "spantmp2.h" #define SPANTMP_PIXEL_FMT GL_BGRA #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_4_4_4_4 - #define TAG(x) radeon##x##_ARGB4444_REV #define TAG2(x,y) radeon##x##_ARGB4444_REV##y -#define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X), (Y)) #include "spantmp2.h" /* 32 bit, xRGB8888 color spanline and pixel functions */ #define SPANTMP_PIXEL_FMT GL_BGRA #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV - #define TAG(x) radeon##x##_xRGB8888 #define TAG2(x,y) radeon##x##_xRGB8888##y -#define GET_VALUE(_x, _y) ((*(GLuint*)(radeon_ptr_4byte(rrb, _x, _y)) | 0xff000000)) -#define PUT_VALUE(_x, _y, d) { \ - GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x, _y ); \ - *_ptr = d; \ -} while (0) #include "spantmp2.h" /* 32 bit, ARGB8888 color spanline and pixel functions */ #define SPANTMP_PIXEL_FMT GL_BGRA #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV - #define TAG(x) radeon##x##_ARGB8888 #define TAG2(x,y) radeon##x##_ARGB8888##y -#define GET_VALUE(_x, _y) (*(GLuint*)(radeon_ptr_4byte(rrb, _x, _y))) -#define PUT_VALUE(_x, _y, d) { \ - GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x, _y ); \ - *_ptr = d; \ -} while (0) #include "spantmp2.h" /* 32 bit, BGRx8888 color spanline and pixel functions */ #define SPANTMP_PIXEL_FMT GL_BGRA #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8 - #define TAG(x) radeon##x##_BGRx8888 #define TAG2(x,y) radeon##x##_BGRx8888##y -#define GET_VALUE(_x, _y) ((*(GLuint*)(radeon_ptr_4byte(rrb, _x, _y)) | 0x000000ff)) -#define PUT_VALUE(_x, _y, d) { \ - GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x, _y ); \ - *_ptr = d; \ -} while (0) #include "spantmp2.h" /* 32 bit, BGRA8888 color spanline and pixel functions */ #define SPANTMP_PIXEL_FMT GL_BGRA #define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8 - #define TAG(x) radeon##x##_BGRA8888 #define TAG2(x,y) radeon##x##_BGRA8888##y -#define GET_PTR(X,Y) radeon_ptr_4byte(rrb, (X), (Y)) #include "spantmp2.h" +#undef Y_FLIP +#define Y_FLIP(_y) ((_y) * yScale + yBias) /* ================================================================ * Depth buffer */ @@ -509,77 +479,69 @@ do { \ #define TAG(x) radeon##x##_s8_z24 #include "stenciltmp.h" - -static void map_unmap_rb(struct gl_renderbuffer *rb, int flag) +static void +radeon_renderbuffer_map(struct gl_context *ctx, struct gl_renderbuffer *rb) { struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb); - int r; + GLubyte *map; + int stride; - if (rrb == NULL || !rrb->bo) + if (!rb || !rrb) return; - radeon_print(RADEON_MEMORY, RADEON_TRACE, - "%s( rb %p, flag %s )\n", - __func__, rb, flag ? "true":"false"); - - if (flag) { - radeon_bo_wait(rrb->bo); - r = radeon_bo_map(rrb->bo, 1); - if (r) { - fprintf(stderr, "(%s) error(%d) mapping buffer.\n", - __FUNCTION__, r); - } + ctx->Driver.MapRenderbuffer(ctx, rb, 0, 0, rb->Width, rb->Height, + GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, + &map, &stride); - radeonSetSpanFunctions(rrb); - } else { - radeon_bo_unmap(rrb->bo); - rb->GetRow = NULL; - rb->PutRow = NULL; - } + rb->Data = map; + rb->RowStride = stride / _mesa_get_format_bytes(rb->Format); + + radeonSetSpanFunctions(rrb); +} + +static void +radeon_renderbuffer_unmap(struct gl_context *ctx, struct gl_renderbuffer *rb) +{ + struct radeon_renderbuffer *rrb = radeon_renderbuffer(rb); + if (!rb || !rrb) + return; + + ctx->Driver.UnmapRenderbuffer(ctx, rb); + + rb->GetRow = NULL; + rb->PutRow = NULL; + rb->Data = NULL; + rb->RowStride = 0; } static void -radeon_map_unmap_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb, - GLboolean map) +radeon_map_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb) { GLuint i, j; radeon_print(RADEON_MEMORY, RADEON_TRACE, - "%s( %p , fb %p, map %s )\n", - __func__, ctx, fb, map ? "true":"false"); + "%s( %p , fb %p )\n", + __func__, ctx, fb); - /* color draw buffers */ - for (j = 0; j < ctx->DrawBuffer->_NumColorDrawBuffers; j++) - map_unmap_rb(fb->_ColorDrawBuffers[j], map); + /* check for render to textures */ + for (i = 0; i < BUFFER_COUNT; i++) + radeon_renderbuffer_map(ctx, fb->Attachment[i].Renderbuffer); - map_unmap_rb(fb->_ColorReadBuffer, map); + radeon_check_front_buffer_rendering(ctx); +} - /* check for render to textures */ - for (i = 0; i < BUFFER_COUNT; i++) { - struct gl_renderbuffer_attachment *att = - fb->Attachment + i; - struct gl_texture_object *tex = att->Texture; - if (tex) { - /* 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) - radeon_teximage_map(image, GL_TRUE); - else - radeon_teximage_unmap(image); - } - } - - /* depth buffer (Note wrapper!) */ - if (fb->_DepthBuffer) - map_unmap_rb(fb->_DepthBuffer->Wrapped, map); +static void +radeon_unmap_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb) +{ + GLuint i, j; - if (fb->_StencilBuffer) - map_unmap_rb(fb->_StencilBuffer->Wrapped, map); + radeon_print(RADEON_MEMORY, RADEON_TRACE, + "%s( %p , fb %p)\n", + __func__, ctx, fb); + + /* check for render to textures */ + for (i = 0; i < BUFFER_COUNT; i++) + radeon_renderbuffer_unmap(ctx, fb->Attachment[i].Renderbuffer); radeon_check_front_buffer_rendering(ctx); } @@ -591,13 +553,16 @@ static void radeonSpanRenderStart(struct gl_context * ctx) radeon_firevertices(rmesa); - for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) - if (ctx->Texture.Unit[i]._ReallyEnabled) - radeonMapTexture(ctx, ctx->Texture.Unit[i]._Current); - - radeon_map_unmap_framebuffer(ctx, ctx->DrawBuffer, GL_TRUE); + for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) { + if (ctx->Texture.Unit[i]._ReallyEnabled) { + radeon_validate_texture_miptree(ctx, ctx->Texture.Unit[i]._Current); + radeon_swrast_map_texture_images(ctx, ctx->Texture.Unit[i]._Current); + } + } + + radeon_map_framebuffer(ctx, ctx->DrawBuffer); if (ctx->ReadBuffer != ctx->DrawBuffer) - radeon_map_unmap_framebuffer(ctx, ctx->ReadBuffer, GL_TRUE); + radeon_map_framebuffer(ctx, ctx->ReadBuffer); } static void radeonSpanRenderFinish(struct gl_context * ctx) @@ -608,11 +573,11 @@ static void radeonSpanRenderFinish(struct gl_context * ctx) for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) if (ctx->Texture.Unit[i]._ReallyEnabled) - radeonUnmapTexture(ctx, ctx->Texture.Unit[i]._Current); + radeon_swrast_unmap_texture_images(ctx, ctx->Texture.Unit[i]._Current); - radeon_map_unmap_framebuffer(ctx, ctx->DrawBuffer, GL_FALSE); + radeon_unmap_framebuffer(ctx, ctx->DrawBuffer); if (ctx->ReadBuffer != ctx->DrawBuffer) - radeon_map_unmap_framebuffer(ctx, ctx->ReadBuffer, GL_FALSE); + radeon_unmap_framebuffer(ctx, ctx->ReadBuffer); } void radeonInitSpanFuncs(struct gl_context * ctx) diff --git a/src/mesa/drivers/dri/radeon/radeon_tex_copy.c b/src/mesa/drivers/dri/radeon/radeon_tex_copy.c index bc9015e574d..ca0ac161709 100644 --- a/src/mesa/drivers/dri/radeon/radeon_tex_copy.c +++ b/src/mesa/drivers/dri/radeon/radeon_tex_copy.c @@ -101,7 +101,7 @@ do_copy_texsubimage(struct gl_context *ctx, dst_mesaformat = timg->base.Base.TexFormat; src_bpp = _mesa_get_format_bytes(src_mesaformat); dst_bpp = _mesa_get_format_bytes(dst_mesaformat); - if (!radeon->vtbl.check_blit(dst_mesaformat)) { + if (!radeon->vtbl.check_blit(dst_mesaformat, rrb->pitch / rrb->cpp)) { /* depth formats tend to be special */ if (_mesa_get_format_bits(dst_mesaformat, GL_DEPTH_BITS) > 0) return GL_FALSE; diff --git a/src/mesa/drivers/dri/radeon/radeon_texture.c b/src/mesa/drivers/dri/radeon/radeon_texture.c index 178ff0925c3..71eff75cc04 100644 --- a/src/mesa/drivers/dri/radeon/radeon_texture.c +++ b/src/mesa/drivers/dri/radeon/radeon_texture.c @@ -48,6 +48,13 @@ #include "radeon_mipmap_tree.h" +static void teximage_assign_miptree(radeonContextPtr rmesa, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); + +static radeon_mipmap_tree *radeon_miptree_create_for_teximage(radeonContextPtr rmesa, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage); void copy_rows(void* dst, GLuint dststride, const void* src, GLuint srcstride, GLuint numrows, GLuint rowsize) @@ -94,6 +101,33 @@ radeonDeleteTextureImage(struct gl_context *ctx, struct gl_texture_image *img) _mesa_delete_texture_image(ctx, img); } +static GLboolean +radeonAllocTextureImageBuffer(struct gl_context *ctx, + struct gl_texture_image *timage, + gl_format format, GLsizei width, + GLsizei height, GLsizei depth) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + radeon_texture_image *image = get_radeon_texture_image(timage); + struct gl_texture_object *texobj = timage->TexObject; + int slices; + + ctx->Driver.FreeTextureImageBuffer(ctx, timage); + + switch (texobj->Target) { + case GL_TEXTURE_3D: + slices = timage->Depth; + break; + default: + slices = 1; + } + assert(!image->base.ImageOffsets); + image->base.ImageOffsets = malloc(slices * sizeof(GLuint)); + teximage_assign_miptree(rmesa, texobj, timage); + + return GL_TRUE; +} + /** * Free memory associated with this texture image. @@ -104,7 +138,6 @@ void radeonFreeTextureImageBuffer(struct gl_context *ctx, struct gl_texture_imag if (image->mt) { radeon_miptree_unreference(&image->mt); - assert(!image->base.Buffer); } else { _swrast_free_texture_image_buffer(ctx, timage); } @@ -173,91 +206,6 @@ void radeon_teximage_unmap(radeon_texture_image *image) } } -static void map_override(struct gl_context *ctx, radeonTexObj *t) -{ - radeon_texture_image *img = get_radeon_texture_image(t->base.Image[0][0]); - - radeon_bo_map(t->bo, GL_FALSE); - - img->base.Data = t->bo->ptr; -} - -static void unmap_override(struct gl_context *ctx, radeonTexObj *t) -{ - radeon_texture_image *img = get_radeon_texture_image(t->base.Image[0][0]); - - radeon_bo_unmap(t->bo); - - img->base.Data = NULL; -} - -/** - * Map a validated texture for reading during software rendering. - */ -void radeonMapTexture(struct gl_context *ctx, struct gl_texture_object *texObj) -{ - radeonTexObj* t = radeon_tex_obj(texObj); - int face, level; - - radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, - "%s(%p, tex %p)\n", - __func__, ctx, texObj); - - if (!radeon_validate_texture_miptree(ctx, texObj)) { - radeon_error("%s(%p, tex %p) Failed to validate miptree for " - "sw fallback.\n", - __func__, ctx, texObj); - return; - } - - if (t->image_override && t->bo) { - radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, - "%s(%p, tex %p) Work around for missing miptree in r100.\n", - __func__, ctx, texObj); - - map_override(ctx, t); - } - - /* for r100 3D sw fallbacks don't have mt */ - if (!t->mt) { - radeon_warning("%s(%p, tex %p) No miptree in texture.\n", - __func__, ctx, texObj); - return; - } - - radeon_bo_map(t->mt->bo, GL_FALSE); - for(face = 0; face < t->mt->faces; ++face) { - for(level = t->minLod; level <= t->maxLod; ++level) - teximage_set_map_data(get_radeon_texture_image(texObj->Image[face][level])); - } -} - -void radeonUnmapTexture(struct gl_context *ctx, struct gl_texture_object *texObj) -{ - radeonTexObj* t = radeon_tex_obj(texObj); - int face, level; - - radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, - "%s(%p, tex %p)\n", - __func__, ctx, texObj); - - if (t->image_override && t->bo) - unmap_override(ctx, t); - /* for r100 3D sw fallbacks don't have mt */ - if (!t->mt) - return; - - for(face = 0; face < t->mt->faces; ++face) { - for(level = t->minLod; level <= t->maxLod; ++level) { - radeon_texture_image *image = - get_radeon_texture_image(texObj->Image[face][level]); - image->base.Data = NULL; - } - } - radeon_bo_unmap(t->mt->bo); -} - - /** * Map texture memory/buffer into user space. * Note: the region of interest parameters are ignored here. @@ -286,7 +234,7 @@ radeon_map_texture_image(struct gl_context *ctx, _mesa_get_format_block_size(texImage->TexFormat, &bw, &bh); assert(y % bh == 0); y /= bh; - height /= bh; + texel_size /= bw; if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) { radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, @@ -302,9 +250,11 @@ radeon_map_texture_image(struct gl_context *ctx, *stride = get_texture_image_row_stride(rmesa, texImage->TexFormat, width, 0, texImage->TexObject->Target); *map = bo->ptr; } else if (likely(mt)) { - radeon_bo_map(mt->bo, write); + void *base; radeon_mipmap_level *lvl = &image->mt->levels[texImage->Level]; - void *base = mt->bo->ptr + lvl->faces[image->base.Base.Face].offset; + + radeon_bo_map(mt->bo, write); + base = mt->bo->ptr + lvl->faces[image->base.Base.Face].offset; *stride = lvl->rowstride; *map = base + (slice * height) * *stride; @@ -594,51 +544,24 @@ gl_format radeonChooseTextureFormat(struct gl_context * ctx, /** Check if given image is valid within current texture object. */ -static int image_matches_texture_obj(struct gl_texture_object *texObj, - struct gl_texture_image *texImage, - unsigned level) -{ - const struct gl_texture_image *baseImage = texObj->Image[0][texObj->BaseLevel]; - - if (!baseImage) - return 0; - - if (level < texObj->BaseLevel || level > texObj->MaxLevel) - return 0; - - const unsigned levelDiff = level - texObj->BaseLevel; - const unsigned refWidth = MAX2(baseImage->Width >> levelDiff, 1); - const unsigned refHeight = MAX2(baseImage->Height >> levelDiff, 1); - const unsigned refDepth = MAX2(baseImage->Depth >> levelDiff, 1); - - return (texImage->Width == refWidth && - texImage->Height == refHeight && - texImage->Depth == refDepth); -} - static void teximage_assign_miptree(radeonContextPtr rmesa, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage, - unsigned face, - unsigned level) + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) { radeonTexObj *t = radeon_tex_obj(texObj); radeon_texture_image* image = get_radeon_texture_image(texImage); - /* Since miptree holds only images for levels - * don't allocate the miptree if the teximage won't fit. - */ - if (!image_matches_texture_obj(texObj, texImage, level)) - return; - /* Try using current miptree, or create new if there isn't any */ - if (!t->mt || !radeon_miptree_matches_image(t->mt, texImage, face, level)) { + if (!t->mt || !radeon_miptree_matches_image(t->mt, texImage)) { radeon_miptree_unreference(&t->mt); - radeon_try_alloc_miptree(rmesa, t); + t->mt = radeon_miptree_create_for_teximage(rmesa, + texObj, + texImage); + radeon_print(RADEON_TEXTURE, RADEON_NORMAL, - "%s: texObj %p, texImage %p, face %d, level %d, " + "%s: texObj %p, texImage %p, " "texObj miptree doesn't match, allocated new miptree %p\n", - __FUNCTION__, texObj, texImage, face, level, t->mt); + __FUNCTION__, texObj, texImage, t->mt); } /* Miptree alocation may have failed, @@ -650,101 +573,6 @@ static void teximage_assign_miptree(radeonContextPtr rmesa, "%s Failed to allocate miptree.\n", __func__); } - -/** - * Update a subregion of the given texture image. - */ -static void radeon_store_teximage(struct gl_context* ctx, int dims, - GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLsizei depth, - GLsizei imageSize, - GLenum format, GLenum type, - const GLvoid * pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage, - int compressed) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeonTexObj *t = radeon_tex_obj(texObj); - radeon_texture_image* image = get_radeon_texture_image(texImage); - GLuint texel_size = _mesa_get_format_bytes(texImage->TexFormat); - - GLuint dstRowStride; - GLuint alignedWidth; - GLint i; - - radeon_print(RADEON_TEXTURE, RADEON_TRACE, - "%s(%p, tex %p, image %p) compressed %d\n", - __func__, ctx, texObj, texImage, compressed); - - if (image->mt) { - dstRowStride = image->mt->levels[image->base.Base.Level].rowstride; - } else if (t->bo) { - /* TFP case */ - dstRowStride = get_texture_image_row_stride(rmesa, texImage->TexFormat, width, 0, texObj->Target); - } else { - dstRowStride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width); - } - - assert(dstRowStride); - - /* fill in the ImageOffsets array */ - alignedWidth = dstRowStride / texel_size; - for (i = 0; i < texImage->Depth; ++i) { - image->base.ImageOffsets[i] = alignedWidth * texImage->Height * i; - } - /* and fill in RowStride (in texels) */ - image->base.RowStride = alignedWidth; - - radeon_teximage_map(image, GL_TRUE); - - if (compressed) { - uint32_t srcRowStride, bytesPerRow, rows, block_width, block_height; - GLubyte *img_start; - - _mesa_get_format_block_size(texImage->TexFormat, &block_width, &block_height); - - if (!image->mt) { - dstRowStride = _mesa_format_row_stride(texImage->TexFormat, texImage->Width); - img_start = _mesa_compressed_image_address(xoffset, yoffset, 0, - texImage->TexFormat, - texImage->Width, image->base.Data); - } - else { - uint32_t offset; - offset = dstRowStride / texel_size * yoffset / block_height + xoffset / block_width; - offset *= texel_size; - img_start = image->base.Data + offset; - } - srcRowStride = _mesa_format_row_stride(texImage->TexFormat, width); - bytesPerRow = srcRowStride; - rows = (height + block_height - 1) / block_height; - - copy_rows(img_start, dstRowStride, pixels, srcRowStride, rows, bytesPerRow); - } - else { - GLubyte *slices[512]; - GLuint i; - assert(depth <= 512); - for (i = 0; i < depth; i++) { - slices[i] = (GLubyte *) image->base.Data - + image->base.ImageOffsets[i] * texel_size; - } - if (!_mesa_texstore(ctx, dims, texImage->_BaseFormat, - texImage->TexFormat, - xoffset, yoffset, zoffset, - dstRowStride, - slices, - width, height, depth, - format, type, pixels, packing)) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage"); - } - } - - radeon_teximage_unmap(image); -} - /** * All glTexImage calls go through this function. */ @@ -760,72 +588,10 @@ static void radeon_teximage( struct gl_texture_image *texImage, int compressed) { - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeonTexObj* t = radeon_tex_obj(texObj); - radeon_texture_image* image = get_radeon_texture_image(texImage); - GLuint face = _mesa_tex_target_to_face(target); - - radeon_print(RADEON_TEXTURE, RADEON_NORMAL, - "%s %dd: texObj %p, texImage %p, face %d, level %d\n", - __func__, dims, texObj, texImage, face, level); - - t->validated = GL_FALSE; - - radeonFreeTextureImageBuffer(ctx, texImage); - - if (!t->bo) { - teximage_assign_miptree(rmesa, texObj, texImage, face, level); - if (!image->mt) { - int size = _mesa_format_image_size(texImage->TexFormat, - texImage->Width, - texImage->Height, - texImage->Depth); - image->base.Buffer = _mesa_align_malloc(size, 512); - - radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, - "%s %dd: texObj %p, texImage %p, " - " no miptree assigned, using local memory %p\n", - __func__, dims, texObj, texImage, image->base.Buffer); - } - } - - { - struct radeon_bo *bo; - bo = !image->mt ? image->bo : image->mt->bo; - if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) { - radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, - "%s Calling teximage for texture that is " - "queued for GPU processing.\n", - __func__); - radeon_firevertices(rmesa); - } - } - - image->base.ImageOffsets = - (GLuint *) malloc(texImage->Depth * sizeof(GLuint)); - - - /* Upload texture image; note that the spec allows pixels to be NULL */ - if (compressed) { - pixels = _mesa_validate_pbo_compressed_teximage( - ctx, imageSize, pixels, packing, "glCompressedTexImage"); - } else { - pixels = _mesa_validate_pbo_teximage( - ctx, dims, width, height, depth, - format, type, pixels, packing, "glTexImage"); - } - - if (pixels) { - radeon_store_teximage(ctx, dims, - 0, 0, 0, - width, height, depth, - imageSize, format, type, - pixels, packing, - texObj, texImage, - compressed); - } - - _mesa_unmap_teximage_pbo(ctx, packing); + _mesa_store_teximage3d(ctx, target, level, internalFormat, + width, height, depth, 0, + format, type, pixels, + packing, texObj, texImage); } void radeonTexImage1D(struct gl_context * ctx, GLenum target, GLint level, @@ -853,17 +619,6 @@ void radeonTexImage2D(struct gl_context * ctx, GLenum target, GLint level, 0, format, type, pixels, packing, texObj, texImage, 0); } -void radeonCompressedTexImage2D(struct gl_context * ctx, GLenum target, - GLint level, GLint internalFormat, - GLint width, GLint height, GLint border, - GLsizei imageSize, const GLvoid * data, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) -{ - radeon_teximage(ctx, 2, target, level, internalFormat, width, height, 1, - imageSize, 0, 0, data, &ctx->Unpack, texObj, texImage, 1); -} - void radeonTexImage3D(struct gl_context * ctx, GLenum target, GLint level, GLint internalFormat, GLint width, GLint height, GLint depth, @@ -877,116 +632,6 @@ void radeonTexImage3D(struct gl_context * ctx, GLenum target, GLint level, 0, format, type, pixels, packing, texObj, texImage, 0); } -/** - * All glTexSubImage calls go through this function. - */ -static void radeon_texsubimage(struct gl_context* ctx, int dims, GLenum target, int level, - GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLsizei depth, - GLsizei imageSize, - GLenum format, GLenum type, - const GLvoid * pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage, - int compressed) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeonTexObj* t = radeon_tex_obj(texObj); - radeon_texture_image* image = get_radeon_texture_image(texImage); - - radeon_print(RADEON_TEXTURE, RADEON_NORMAL, - "%s %dd: texObj %p, texImage %p, face %d, level %d\n", - __func__, dims, texObj, texImage, - _mesa_tex_target_to_face(target), level); - { - struct radeon_bo *bo; - bo = !image->mt ? image->bo : image->mt->bo; - if (bo && radeon_bo_is_referenced_by_cs(bo, rmesa->cmdbuf.cs)) { - radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, - "%s Calling texsubimage for texture that is " - "queued for GPU processing.\n", - __func__); - radeon_firevertices(rmesa); - } - } - - - t->validated = GL_FALSE; - if (compressed) { - pixels = _mesa_validate_pbo_compressed_teximage( - ctx, imageSize, pixels, packing, "glCompressedTexSubImage"); - } else { - pixels = _mesa_validate_pbo_teximage(ctx, dims, - width, height, depth, format, type, pixels, packing, "glTexSubImage"); - } - - if (pixels) { - radeon_store_teximage(ctx, dims, - xoffset, yoffset, zoffset, - width, height, depth, - imageSize, format, type, - pixels, packing, - texObj, texImage, - compressed); - } - - _mesa_unmap_teximage_pbo(ctx, packing); -} - -void radeonTexSubImage1D(struct gl_context * ctx, GLenum target, GLint level, - GLint xoffset, - GLsizei width, - GLenum format, GLenum type, - const GLvoid * pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) -{ - radeon_texsubimage(ctx, 1, target, level, xoffset, 0, 0, width, 1, 1, 0, - format, type, pixels, packing, texObj, texImage, 0); -} - -void radeonTexSubImage2D(struct gl_context * ctx, GLenum target, GLint level, - GLint xoffset, GLint yoffset, - GLsizei width, GLsizei height, - GLenum format, GLenum type, - const GLvoid * pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) -{ - radeon_texsubimage(ctx, 2, target, level, xoffset, yoffset, 0, width, height, 1, - 0, format, type, pixels, packing, texObj, texImage, - 0); -} - -void radeonCompressedTexSubImage2D(struct gl_context * ctx, GLenum target, - GLint level, GLint xoffset, - GLint yoffset, GLsizei width, - GLsizei height, GLenum format, - GLsizei imageSize, const GLvoid * data, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) -{ - radeon_texsubimage(ctx, 2, target, level, xoffset, yoffset, 0, width, height, 1, - imageSize, format, 0, data, &ctx->Unpack, texObj, texImage, 1); -} - - -void radeonTexSubImage3D(struct gl_context * ctx, GLenum target, GLint level, - GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLsizei depth, - GLenum format, GLenum type, - const GLvoid * pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) -{ - radeon_texsubimage(ctx, 3, target, level, xoffset, yoffset, zoffset, width, height, depth, 0, - format, type, pixels, packing, texObj, texImage, 0); -} - unsigned radeonIsFormatRenderable(gl_format mesa_format) { if (mesa_format == _radeon_texformat_argb8888 || mesa_format == _radeon_texformat_rgb565 || @@ -1059,8 +704,7 @@ void radeon_image_target_texture_2d(struct gl_context *ctx, GLenum target, radeon_bo_ref(image->bo); t->mt->bo = image->bo; - if (!radeon_miptree_matches_image(t->mt, &radeonImage->base.Base, - radeonImage->base.Base.Face, 0)) + if (!radeon_miptree_matches_image(t->mt, &radeonImage->base.Base)) fprintf(stderr, "miptree doesn't match image\n"); } #endif @@ -1101,9 +745,8 @@ radeon_init_common_texture_funcs(radeonContextPtr radeon, { functions->NewTextureImage = radeonNewTextureImage; functions->DeleteTextureImage = radeonDeleteTextureImage; + functions->AllocTextureImageBuffer = radeonAllocTextureImageBuffer; functions->FreeTextureImageBuffer = radeonFreeTextureImageBuffer; - functions->MapTexture = radeonMapTexture; - functions->UnmapTexture = radeonUnmapTexture; functions->MapTextureImage = radeon_map_texture_image; functions->UnmapTextureImage = radeon_unmap_texture_image; @@ -1112,11 +755,6 @@ radeon_init_common_texture_funcs(radeonContextPtr radeon, functions->TexImage1D = radeonTexImage1D; functions->TexImage2D = radeonTexImage2D; functions->TexImage3D = radeonTexImage3D; - functions->TexSubImage1D = radeonTexSubImage1D; - functions->TexSubImage2D = radeonTexSubImage2D; - functions->TexSubImage3D = radeonTexSubImage3D; - functions->CompressedTexImage2D = radeonCompressedTexImage2D; - functions->CompressedTexSubImage2D = radeonCompressedTexSubImage2D; functions->CopyTexSubImage2D = radeonCopyTexSubImage2D; @@ -1127,3 +765,133 @@ radeon_init_common_texture_funcs(radeonContextPtr radeon, radeonInitTextureFormats(); } + +static void +radeon_swrast_map_image(radeonContextPtr rmesa, + radeon_texture_image *image) +{ + GLuint level, face; + radeon_mipmap_tree *mt; + GLuint texel_size; + radeon_mipmap_level *lvl; + int rs; + + if (!image || !image->mt) + return; + + texel_size = _mesa_get_format_bytes(image->base.Base.TexFormat); + level = image->base.Base.Level; + face = image->base.Base.Face; + mt = image->mt; + + lvl = &image->mt->levels[level]; + + rs = lvl->rowstride / texel_size; + + radeon_bo_map(mt->bo, 1); + + image->base.Data = mt->bo->ptr + lvl->faces[face].offset; + if (mt->target == GL_TEXTURE_3D) { + int i; + + for (i = 0; i < mt->levels[level].depth; i++) + image->base.ImageOffsets[i] = rs * lvl->height * i; + } + image->base.RowStride = rs; +} + +static void +radeon_swrast_unmap_image(radeonContextPtr rmesa, + radeon_texture_image *image) +{ + if (image && image->mt) { + image->base.Data = NULL; + radeon_bo_unmap(image->mt->bo); + } +} + +void +radeon_swrast_map_texture_images(struct gl_context *ctx, + struct gl_texture_object *texObj) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + GLuint nr_faces = (texObj->Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; + int i, face; + + for (i = texObj->BaseLevel; i <= texObj->_MaxLevel; i++) { + for (face = 0; face < nr_faces; face++) { + radeon_texture_image *image = get_radeon_texture_image(texObj->Image[face][i]); + radeon_swrast_map_image(rmesa, image); + } + } +} + +void +radeon_swrast_unmap_texture_images(struct gl_context *ctx, + struct gl_texture_object *texObj) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + GLuint nr_faces = (texObj->Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; + int i, face; + + for (i = texObj->BaseLevel; i <= texObj->_MaxLevel; i++) { + for (face = 0; face < nr_faces; face++) { + radeon_texture_image *image = get_radeon_texture_image(texObj->Image[face][i]); + radeon_swrast_unmap_image(rmesa, image); + } + } + +} + +static radeon_mipmap_tree *radeon_miptree_create_for_teximage(radeonContextPtr rmesa, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + radeonTexObj *t = radeon_tex_obj(texObj); + GLuint firstLevel; + GLuint lastLevel; + int width, height, depth; + int i; + + width = texImage->Width; + height = texImage->Height; + depth = texImage->Depth; + + if (texImage->Level > texObj->BaseLevel && + (width == 1 || + (texObj->Target != GL_TEXTURE_1D && height == 1) || + (texObj->Target == GL_TEXTURE_3D && depth == 1))) { + /* For this combination, we're at some lower mipmap level and + * some important dimension is 1. We can't extrapolate up to a + * likely base level width/height/depth for a full mipmap stack + * from this info, so just allocate this one level. + */ + firstLevel = texImage->Level; + lastLevel = texImage->Level; + } else { + if (texImage->Level < texObj->BaseLevel) + firstLevel = 0; + else + firstLevel = texObj->BaseLevel; + + for (i = texImage->Level; i > firstLevel; i--) { + width <<= 1; + if (height != 1) + height <<= 1; + if (depth != 1) + depth <<= 1; + } + if ((texObj->Sampler.MinFilter == GL_NEAREST || + texObj->Sampler.MinFilter == GL_LINEAR) && + texImage->Level == firstLevel) { + lastLevel = firstLevel; + } else { + lastLevel = firstLevel + _mesa_logbase2(MAX2(MAX2(width, height), depth)); + } + } + + return radeon_miptree_create(rmesa, texObj->Target, + texImage->TexFormat, firstLevel, lastLevel - firstLevel + 1, + width, height, depth, + t->tile_bits); +} diff --git a/src/mesa/drivers/dri/radeon/radeon_texture.h b/src/mesa/drivers/dri/radeon/radeon_texture.h index 0fa48bd1091..f1af109707f 100644 --- a/src/mesa/drivers/dri/radeon/radeon_texture.h +++ b/src/mesa/drivers/dri/radeon/radeon_texture.h @@ -49,10 +49,12 @@ void radeonFreeTextureImageBuffer(struct gl_context *ctx, struct gl_texture_imag void radeon_teximage_map(radeon_texture_image *image, GLboolean write_enable); void radeon_teximage_unmap(radeon_texture_image *image); -void radeonMapTexture(struct gl_context *ctx, struct gl_texture_object *texObj); -void radeonUnmapTexture(struct gl_context *ctx, struct gl_texture_object *texObj); int radeon_validate_texture_miptree(struct gl_context * ctx, struct gl_texture_object *texObj); + +void radeon_swrast_map_texture_images(struct gl_context *ctx, struct gl_texture_object *texObj); +void radeon_swrast_unmap_texture_images(struct gl_context *ctx, struct gl_texture_object *texObj); + gl_format radeonChooseTextureFormat_mesa(struct gl_context * ctx, GLint internalFormat, GLenum format, -- cgit v1.2.3