From: Marek Olšák Date: Fri, 27 Jul 2012 22:38:42 +0000 (+0200) Subject: r600g: make sure copying of all texture formats is accelerated X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=7c371f46958910dd2ca9487c89af1b72bbfdada9;p=mesa.git r600g: make sure copying of all texture formats is accelerated --- diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c index 3623b2e7ae2..3121bb197ad 100644 --- a/src/gallium/drivers/r600/r600_blit.c +++ b/src/gallium/drivers/r600/r600_blit.c @@ -322,9 +322,27 @@ static void r600_compressed_to_blittable(struct pipe_resource *tex, rtex->surface.level[level].npix_y = util_format_get_nblocksy(orig->format, orig->npix_y); } -static void r600_reset_blittable_to_compressed(struct pipe_resource *tex, - unsigned level, - struct texture_orig_info *orig) +static void r600_change_format(struct pipe_resource *tex, + unsigned level, + struct texture_orig_info *orig, + enum pipe_format format) +{ + struct r600_resource_texture *rtex = (struct r600_resource_texture*)tex; + + orig->format = tex->format; + orig->width0 = tex->width0; + orig->height0 = tex->height0; + orig->npix0_x = rtex->surface.level[0].npix_x; + orig->npix0_y = rtex->surface.level[0].npix_y; + orig->npix_x = rtex->surface.level[level].npix_x; + orig->npix_y = rtex->surface.level[level].npix_y; + + tex->format = format; +} + +static void r600_reset_blittable_to_orig(struct pipe_resource *tex, + unsigned level, + struct texture_orig_info *orig) { struct r600_resource_texture *rtex = (struct r600_resource_texture*)tex; @@ -349,7 +367,7 @@ static void r600_resource_copy_region(struct pipe_context *ctx, struct r600_resource_texture *rsrc = (struct r600_resource_texture*)src; struct texture_orig_info orig_info[2]; struct pipe_box sbox; - const struct pipe_box *psbox; + const struct pipe_box *psbox = src_box; boolean restore_orig[2]; memset(orig_info, 0, sizeof(orig_info)); @@ -372,7 +390,8 @@ static void r600_resource_copy_region(struct pipe_context *ctx, restore_orig[0] = restore_orig[1] = FALSE; - if (util_format_is_compressed(src->format)) { + if (util_format_is_compressed(src->format) && + util_format_is_compressed(dst->format)) { r600_compressed_to_blittable(src, src_level, &orig_info[0]); restore_orig[0] = TRUE; sbox.x = util_format_get_nblocksx(orig_info[0].format, src_box->x); @@ -382,15 +401,36 @@ static void r600_resource_copy_region(struct pipe_context *ctx, sbox.height = util_format_get_nblocksy(orig_info[0].format, src_box->height); sbox.depth = src_box->depth; psbox=&sbox; - } else - psbox=src_box; - if (util_format_is_compressed(dst->format)) { r600_compressed_to_blittable(dst, dst_level, &orig_info[1]); restore_orig[1] = TRUE; /* translate the dst box as well */ dstx = util_format_get_nblocksx(orig_info[1].format, dstx); dsty = util_format_get_nblocksy(orig_info[1].format, dsty); + } else if (!util_blitter_is_copy_supported(rctx->blitter, dst, src, + PIPE_MASK_RGBAZS)) { + unsigned blocksize = util_format_get_blocksize(src->format); + + switch (blocksize) { + case 1: + r600_change_format(src, src_level, &orig_info[0], + PIPE_FORMAT_R8_UNORM); + r600_change_format(dst, dst_level, &orig_info[1], + PIPE_FORMAT_R8_UNORM); + break; + case 4: + r600_change_format(src, src_level, &orig_info[0], + PIPE_FORMAT_R8G8B8A8_UNORM); + r600_change_format(dst, dst_level, &orig_info[1], + PIPE_FORMAT_R8G8B8A8_UNORM); + break; + default: + fprintf(stderr, "Unhandled format %s with blocksize %u\n", + util_format_short_name(src->format), blocksize); + assert(0); + } + restore_orig[0] = TRUE; + restore_orig[1] = TRUE; } r600_blitter_begin(ctx, R600_COPY_TEXTURE); @@ -399,10 +439,10 @@ static void r600_resource_copy_region(struct pipe_context *ctx, r600_blitter_end(ctx); if (restore_orig[0]) - r600_reset_blittable_to_compressed(src, src_level, &orig_info[0]); + r600_reset_blittable_to_orig(src, src_level, &orig_info[0]); if (restore_orig[1]) - r600_reset_blittable_to_compressed(dst, dst_level, &orig_info[1]); + r600_reset_blittable_to_orig(dst, dst_level, &orig_info[1]); } void r600_init_blit_functions(struct r600_context *rctx) diff --git a/src/gallium/drivers/r600/r600_texture.c b/src/gallium/drivers/r600/r600_texture.c index 5e99a04a3eb..8fb24fd1888 100644 --- a/src/gallium/drivers/r600/r600_texture.c +++ b/src/gallium/drivers/r600/r600_texture.c @@ -419,40 +419,6 @@ static void r600_setup_miptree(struct pipe_screen *screen, rtex->size = offset; } -/* Figure out whether u_blitter will fallback to a transfer operation. - * If so, don't use a staging resource. - */ -static boolean permit_hardware_blit(struct pipe_screen *screen, - const struct pipe_resource *res) -{ - unsigned bind; - - if (util_format_is_depth_or_stencil(res->format)) - bind = PIPE_BIND_DEPTH_STENCIL; - else - bind = PIPE_BIND_RENDER_TARGET; - - /* hackaround for S3TC */ - if (util_format_is_compressed(res->format)) - return TRUE; - - if (!screen->is_format_supported(screen, - res->format, - res->target, - res->nr_samples, - bind)) - return FALSE; - - if (!screen->is_format_supported(screen, - res->format, - res->target, - res->nr_samples, - PIPE_BIND_SAMPLER_VIEW)) - return FALSE; - - return TRUE; -} - static boolean r600_texture_get_handle(struct pipe_screen* screen, struct pipe_resource *ptex, struct winsys_handle *whandle) @@ -577,10 +543,8 @@ r600_texture_create_object(struct pipe_screen *screen, /* Proceed in creating the depth buffer. */ } - /* only mark depth textures the HW can hit as depth textures */ - if (util_format_is_depth_or_stencil(rtex->real_format) && - permit_hardware_blit(screen, base)) - rtex->is_depth = true; + /* don't include stencil-only formats which we don't support for rendering */ + rtex->is_depth = util_format_has_depth(util_format_description(rtex->resource.b.b.format)); r600_setup_miptree(screen, rtex, array_mode); if (rscreen->use_surface_alloc) { @@ -648,8 +612,7 @@ struct pipe_resource *r600_texture_create(struct pipe_screen *screen, if (rscreen->use_surface_alloc && !(templ->bind & PIPE_BIND_SCANOUT) && templ->usage != PIPE_USAGE_STAGING && - templ->usage != PIPE_USAGE_STREAM && - permit_hardware_blit(screen, templ)) { + templ->usage != PIPE_USAGE_STREAM) { array_mode = V_038000_ARRAY_2D_TILED_THIN1; } else if (util_format_is_compressed(templ->format)) { array_mode = V_038000_ARRAY_1D_TILED_THIN1; @@ -824,8 +787,7 @@ struct pipe_transfer* r600_texture_get_transfer(struct pipe_context *ctx, use_staging_texture = TRUE; } - if (!permit_hardware_blit(ctx->screen, texture) || - (texture->flags & R600_RESOURCE_FLAG_TRANSFER)) { + if (texture->flags & R600_RESOURCE_FLAG_TRANSFER) { use_staging_texture = FALSE; }