radeonsi: make sure copying of all texture formats is accelerated
[ Cherry-picked from r600g commit 7c371f4695
]
Signed-off-by: Michel Dänzer <michel.daenzer@amd.com>
This commit is contained in:
parent
de4e448095
commit
68cebb9a8f
|
@ -338,9 +338,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);
|
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,
|
static void r600_change_format(struct pipe_resource *tex,
|
||||||
unsigned level,
|
unsigned level,
|
||||||
struct texture_orig_info *orig)
|
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;
|
struct r600_resource_texture *rtex = (struct r600_resource_texture*)tex;
|
||||||
|
|
||||||
|
@ -365,7 +383,7 @@ static void r600_resource_copy_region(struct pipe_context *ctx,
|
||||||
struct r600_resource_texture *rsrc = (struct r600_resource_texture*)src;
|
struct r600_resource_texture *rsrc = (struct r600_resource_texture*)src;
|
||||||
struct texture_orig_info orig_info[2];
|
struct texture_orig_info orig_info[2];
|
||||||
struct pipe_box sbox;
|
struct pipe_box sbox;
|
||||||
const struct pipe_box *psbox;
|
const struct pipe_box *psbox = src_box;
|
||||||
boolean restore_orig[2];
|
boolean restore_orig[2];
|
||||||
|
|
||||||
memset(orig_info, 0, sizeof(orig_info));
|
memset(orig_info, 0, sizeof(orig_info));
|
||||||
|
@ -386,7 +404,8 @@ static void r600_resource_copy_region(struct pipe_context *ctx,
|
||||||
|
|
||||||
restore_orig[0] = restore_orig[1] = FALSE;
|
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]);
|
r600_compressed_to_blittable(src, src_level, &orig_info[0]);
|
||||||
restore_orig[0] = TRUE;
|
restore_orig[0] = TRUE;
|
||||||
sbox.x = util_format_get_nblocksx(orig_info[0].format, src_box->x);
|
sbox.x = util_format_get_nblocksx(orig_info[0].format, src_box->x);
|
||||||
|
@ -396,15 +415,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.height = util_format_get_nblocksy(orig_info[0].format, src_box->height);
|
||||||
sbox.depth = src_box->depth;
|
sbox.depth = src_box->depth;
|
||||||
psbox=&sbox;
|
psbox=&sbox;
|
||||||
} else
|
|
||||||
psbox=src_box;
|
|
||||||
|
|
||||||
if (util_format_is_compressed(dst->format)) {
|
|
||||||
r600_compressed_to_blittable(dst, dst_level, &orig_info[1]);
|
r600_compressed_to_blittable(dst, dst_level, &orig_info[1]);
|
||||||
restore_orig[1] = TRUE;
|
restore_orig[1] = TRUE;
|
||||||
/* translate the dst box as well */
|
/* translate the dst box as well */
|
||||||
dstx = util_format_get_nblocksx(orig_info[1].format, dstx);
|
dstx = util_format_get_nblocksx(orig_info[1].format, dstx);
|
||||||
dsty = util_format_get_nblocksy(orig_info[1].format, dsty);
|
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);
|
r600_blitter_begin(ctx, R600_COPY);
|
||||||
|
@ -413,10 +453,10 @@ static void r600_resource_copy_region(struct pipe_context *ctx,
|
||||||
r600_blitter_end(ctx);
|
r600_blitter_end(ctx);
|
||||||
|
|
||||||
if (restore_orig[0])
|
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])
|
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]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void si_blit(struct pipe_context *ctx,
|
static void si_blit(struct pipe_context *ctx,
|
||||||
|
|
|
@ -192,47 +192,6 @@ static int r600_setup_surface(struct pipe_screen *screen,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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;
|
|
||||||
|
|
||||||
switch (res->usage) {
|
|
||||||
case PIPE_USAGE_STREAM:
|
|
||||||
case PIPE_USAGE_STAGING:
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static boolean r600_texture_get_handle(struct pipe_screen* screen,
|
static boolean r600_texture_get_handle(struct pipe_screen* screen,
|
||||||
struct pipe_resource *ptex,
|
struct pipe_resource *ptex,
|
||||||
struct winsys_handle *whandle)
|
struct winsys_handle *whandle)
|
||||||
|
@ -310,8 +269,7 @@ static void *si_texture_transfer_map(struct pipe_context *ctx,
|
||||||
PIPE_TRANSFER_UNSYNCHRONIZED)))
|
PIPE_TRANSFER_UNSYNCHRONIZED)))
|
||||||
use_staging_texture = TRUE;
|
use_staging_texture = TRUE;
|
||||||
|
|
||||||
if (!permit_hardware_blit(ctx->screen, texture) ||
|
if (texture->flags & R600_RESOURCE_FLAG_TRANSFER)
|
||||||
(texture->flags & R600_RESOURCE_FLAG_TRANSFER))
|
|
||||||
use_staging_texture = FALSE;
|
use_staging_texture = FALSE;
|
||||||
|
|
||||||
if (use_staging_texture && (usage & PIPE_TRANSFER_MAP_DIRECTLY))
|
if (use_staging_texture && (usage & PIPE_TRANSFER_MAP_DIRECTLY))
|
||||||
|
@ -483,9 +441,8 @@ r600_texture_create_object(struct pipe_screen *screen,
|
||||||
rtex->pitch_override = pitch_in_bytes_override;
|
rtex->pitch_override = pitch_in_bytes_override;
|
||||||
rtex->real_format = base->format;
|
rtex->real_format = base->format;
|
||||||
|
|
||||||
/* only mark depth textures the HW can hit as depth textures */
|
/* don't include stencil-only formats which we don't support for rendering */
|
||||||
if (util_format_is_depth_or_stencil(rtex->real_format) && permit_hardware_blit(screen, base))
|
rtex->is_depth = util_format_has_depth(util_format_description(rtex->resource.b.b.format));
|
||||||
rtex->is_depth = 1;
|
|
||||||
|
|
||||||
rtex->surface = *surface;
|
rtex->surface = *surface;
|
||||||
r = r600_setup_surface(screen, rtex, array_mode, pitch_in_bytes_override);
|
r = r600_setup_surface(screen, rtex, array_mode, pitch_in_bytes_override);
|
||||||
|
@ -568,9 +525,7 @@ struct pipe_resource *si_texture_create(struct pipe_screen *screen,
|
||||||
|
|
||||||
if (!(templ->flags & R600_RESOURCE_FLAG_TRANSFER) &&
|
if (!(templ->flags & R600_RESOURCE_FLAG_TRANSFER) &&
|
||||||
!(templ->bind & PIPE_BIND_SCANOUT)) {
|
!(templ->bind & PIPE_BIND_SCANOUT)) {
|
||||||
if (permit_hardware_blit(screen, templ)) {
|
array_mode = V_009910_ARRAY_1D_TILED_THIN1;
|
||||||
array_mode = V_009910_ARRAY_1D_TILED_THIN1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
r = r600_init_surface(rscreen, &surface, templ, array_mode,
|
r = r600_init_surface(rscreen, &surface, templ, array_mode,
|
||||||
|
|
Loading…
Reference in New Issue