diff options
Diffstat (limited to 'src/mesa/drivers/dri/radeon/radeon_fbo.c')
-rw-r--r-- | src/mesa/drivers/dri/radeon/radeon_fbo.c | 132 |
1 files changed, 94 insertions, 38 deletions
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) |