r600g: make sure copying of all texture formats is accelerated

This commit is contained in:
Marek Olšák 2012-07-28 00:38:42 +02:00
parent 84645fa613
commit 7c371f4695
2 changed files with 54 additions and 52 deletions

View File

@ -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)

View File

@ -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;
}