diff options
Diffstat (limited to 'src/mesa/drivers')
-rw-r--r-- | src/mesa/drivers/dri/r200/r200_blit.c | 16 | ||||
-rw-r--r-- | src/mesa/drivers/dri/r200/r200_blit.h | 2 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_blit.c | 16 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_blit.h | 2 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_common_context.h | 4 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_fbo.c | 132 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c | 30 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h | 7 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_pixel_read.c | 2 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_span.c | 165 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_tex_copy.c | 2 | ||||
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_texture.c | 600 | ||||
-rw-r--r-- | 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 <BaseLevel..MaxLevel> - * 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, |