From cf05f9bf016c544fe15b7ac724f78d7524ce61de Mon Sep 17 00:00:00 2001 From: Grigori Goronzy Date: Wed, 4 Jun 2014 18:54:37 +0200 Subject: [PATCH] radeonsi: add sampling of 4:2:2 subsampled textures MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This makes 4:2:2 video surfaces work in VDPAU. Reviewed-by: Marek Olšák --- src/gallium/drivers/radeon/r600_texture.c | 5 +- src/gallium/drivers/radeonsi/si_blit.c | 91 ++++++++++++++--------- src/gallium/drivers/radeonsi/si_state.c | 15 ++++ 3 files changed, 71 insertions(+), 40 deletions(-) diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c index 3a37465b13e..a20b0c8dc9b 100644 --- a/src/gallium/drivers/radeon/r600_texture.c +++ b/src/gallium/drivers/radeon/r600_texture.c @@ -737,9 +737,8 @@ static unsigned r600_choose_tiling(struct r600_common_screen *rscreen, * Compressed textures must always be tiled. */ if (!(templ->flags & R600_RESOURCE_FLAG_FORCE_TILING) && !util_format_is_compressed(templ->format)) { - /* Tiling doesn't work with the 422 (SUBSAMPLED) formats on R600-Cayman. */ - if (rscreen->chip_class <= CAYMAN && - desc->layout == UTIL_FORMAT_LAYOUT_SUBSAMPLED) + /* Tiling doesn't work with the 422 (SUBSAMPLED) formats on R600+. */ + if (desc->layout == UTIL_FORMAT_LAYOUT_SUBSAMPLED) return RADEON_SURF_MODE_LINEAR_ALIGNED; /* Cursors are linear on SI. diff --git a/src/gallium/drivers/radeonsi/si_blit.c b/src/gallium/drivers/radeonsi/si_blit.c index e02615fe6ca..8c3e1364160 100644 --- a/src/gallium/drivers/radeonsi/si_blit.c +++ b/src/gallium/drivers/radeonsi/si_blit.c @@ -548,46 +548,63 @@ static void si_resource_copy_region(struct pipe_context *ctx, 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(sctx->blitter, dst, src)) { - unsigned blocksize = util_format_get_blocksize(src->format); - - switch (blocksize) { - case 1: - si_change_format(src, src_level, &orig_info[0], - PIPE_FORMAT_R8_UNORM); - si_change_format(dst, dst_level, &orig_info[1], - PIPE_FORMAT_R8_UNORM); - break; - case 2: - si_change_format(src, src_level, &orig_info[0], - PIPE_FORMAT_R8G8_UNORM); - si_change_format(dst, dst_level, &orig_info[1], - PIPE_FORMAT_R8G8_UNORM); - break; - case 4: - si_change_format(src, src_level, &orig_info[0], - PIPE_FORMAT_R8G8B8A8_UNORM); - si_change_format(dst, dst_level, &orig_info[1], - PIPE_FORMAT_R8G8B8A8_UNORM); - break; - case 8: - si_change_format(src, src_level, &orig_info[0], - PIPE_FORMAT_R16G16B16A16_UINT); - si_change_format(dst, dst_level, &orig_info[1], - PIPE_FORMAT_R16G16B16A16_UINT); - break; - case 16: + if (util_format_is_subsampled_422(src->format)) { + /* XXX untested */ si_change_format(src, src_level, &orig_info[0], - PIPE_FORMAT_R32G32B32A32_UINT); + PIPE_FORMAT_R8G8B8A8_UINT); si_change_format(dst, dst_level, &orig_info[1], - PIPE_FORMAT_R32G32B32A32_UINT); - break; - default: - fprintf(stderr, "Unhandled format %s with blocksize %u\n", - util_format_short_name(src->format), blocksize); - assert(0); + PIPE_FORMAT_R8G8B8A8_UINT); + + 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); + src_box = &sbox; + dstx = util_format_get_nblocksx(orig_info[1].format, dstx); + + restore_orig[0] = TRUE; + restore_orig[1] = TRUE; + } else { + unsigned blocksize = util_format_get_blocksize(src->format); + + switch (blocksize) { + case 1: + si_change_format(src, src_level, &orig_info[0], + PIPE_FORMAT_R8_UNORM); + si_change_format(dst, dst_level, &orig_info[1], + PIPE_FORMAT_R8_UNORM); + break; + case 2: + si_change_format(src, src_level, &orig_info[0], + PIPE_FORMAT_R8G8_UNORM); + si_change_format(dst, dst_level, &orig_info[1], + PIPE_FORMAT_R8G8_UNORM); + break; + case 4: + si_change_format(src, src_level, &orig_info[0], + PIPE_FORMAT_R8G8B8A8_UNORM); + si_change_format(dst, dst_level, &orig_info[1], + PIPE_FORMAT_R8G8B8A8_UNORM); + break; + case 8: + si_change_format(src, src_level, &orig_info[0], + PIPE_FORMAT_R16G16B16A16_UINT); + si_change_format(dst, dst_level, &orig_info[1], + PIPE_FORMAT_R16G16B16A16_UINT); + break; + case 16: + si_change_format(src, src_level, &orig_info[0], + PIPE_FORMAT_R32G32B32A32_UINT); + si_change_format(dst, dst_level, &orig_info[1], + PIPE_FORMAT_R32G32B32A32_UINT); + 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; } - restore_orig[0] = TRUE; - restore_orig[1] = TRUE; } /* Initialize the surface. */ diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c index 19d2b553a22..cbd51ad3d1d 100644 --- a/src/gallium/drivers/radeonsi/si_state.c +++ b/src/gallium/drivers/radeonsi/si_state.c @@ -1102,6 +1102,19 @@ static uint32_t si_translate_texformat(struct pipe_screen *screen, } } + if (desc->layout == UTIL_FORMAT_LAYOUT_SUBSAMPLED) { + switch (format) { + case PIPE_FORMAT_R8G8_B8G8_UNORM: + case PIPE_FORMAT_G8R8_B8R8_UNORM: + return V_008F14_IMG_DATA_FORMAT_GB_GR; + case PIPE_FORMAT_G8R8_G8B8_UNORM: + case PIPE_FORMAT_R8G8_R8B8_UNORM: + return V_008F14_IMG_DATA_FORMAT_BG_RG; + default: + goto out_unknown; + } + } + if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC) { if (!enable_s3tc) @@ -2481,6 +2494,8 @@ static struct pipe_sampler_view *si_create_sampler_view(struct pipe_context *ctx num_format = V_008F14_IMG_NUM_FORMAT_UNORM; break; } + } else if (desc->layout == UTIL_FORMAT_LAYOUT_SUBSAMPLED) { + num_format = V_008F14_IMG_NUM_FORMAT_UNORM; } else { num_format = V_008F14_IMG_NUM_FORMAT_FLOAT; } -- 2.30.2