diff options
author | Marek Olšák <[email protected]> | 2012-08-07 03:30:43 +0200 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2012-08-16 20:44:54 +0200 |
commit | 795834432b11418d82db9a5580c916b3bee1a8f2 (patch) | |
tree | 2d4a2b5655100652c1facc453460d340ac88c744 /src/gallium | |
parent | 6fd9218bb44b8719da60ce325d4f41c4a611e871 (diff) |
r600g: fix blits of subsampled formats
Diffstat (limited to 'src/gallium')
-rw-r--r-- | src/gallium/drivers/r600/r600_blit.c | 83 |
1 files changed, 63 insertions, 20 deletions
diff --git a/src/gallium/drivers/r600/r600_blit.c b/src/gallium/drivers/r600/r600_blit.c index a577d3a9494..b14dc6bd5fe 100644 --- a/src/gallium/drivers/r600/r600_blit.c +++ b/src/gallium/drivers/r600/r600_blit.c @@ -501,6 +501,26 @@ 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_subsampled_2x1_32bpp_to_blittable(struct pipe_resource *tex, + unsigned level, + struct texture_orig_info *orig) +{ + struct r600_texture *rtex = (struct r600_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->width0 = util_format_get_nblocksx(orig->format, orig->width0); + tex->format = PIPE_FORMAT_R8G8B8A8_UINT; + rtex->surface.level[0].npix_x = util_format_get_nblocksx(orig->format, orig->npix0_x); + rtex->surface.level[level].npix_x = util_format_get_nblocksx(orig->format, orig->npix_x); +} + static void r600_change_format(struct pipe_resource *tex, unsigned level, struct texture_orig_info *orig, @@ -534,6 +554,16 @@ static void r600_reset_blittable_to_orig(struct pipe_resource *tex, rtex->surface.level[level].npix_y = orig->npix_y; } +static bool util_format_is_subsampled_2x1_32bpp(enum pipe_format format) +{ + const struct util_format_description *desc = util_format_description(format); + + return desc->layout == UTIL_FORMAT_LAYOUT_SUBSAMPLED && + desc->block.width == 2 && + desc->block.height == 1 && + desc->block.bits == 32; +} + static void r600_resource_copy_region(struct pipe_context *ctx, struct pipe_resource *dst, unsigned dst_level, @@ -584,7 +614,7 @@ static void r600_resource_copy_region(struct pipe_context *ctx, sbox.width = util_format_get_nblocksx(orig_info[0].format, src_box->width); sbox.height = util_format_get_nblocksy(orig_info[0].format, src_box->height); sbox.depth = src_box->depth; - psbox=&sbox; + psbox = &sbox; r600_compressed_to_blittable(dst, dst_level, &orig_info[1]); restore_orig[1] = TRUE; @@ -593,25 +623,38 @@ static void r600_resource_copy_region(struct pipe_context *ctx, 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); + if (util_format_is_subsampled_2x1_32bpp(src->format) && + util_format_is_subsampled_2x1_32bpp(dst->format)) { + r600_subsampled_2x1_32bpp_to_blittable(src, src_level, &orig_info[0]); + r600_subsampled_2x1_32bpp_to_blittable(dst, dst_level, &orig_info[1]); + + sbox = *src_box; + sbox.x = util_format_get_nblocksx(orig_info[0].format, src_box->x); + sbox.width = util_format_get_nblocksx(orig_info[0].format, src_box->width); + psbox = &sbox; + + dstx = util_format_get_nblocksx(orig_info[1].format, dstx); + } else { + 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; |