From b665bd21cbade7bced4b623cf83150d0b4956a90 Mon Sep 17 00:00:00 2001 From: David Rosca Date: Fri, 27 Jun 2025 11:28:36 +0200 Subject: [PATCH] radeonsi/vcn: Correctly handle tile swizzle Currently tile swizzle can only be non zero for single plane formats, for multi plane formats we always set PIPE_BIND_SHARED. Luma only (Y400) JPG decode and encode with RGB input surface (EFC) are the only two cases where we can get surface with tile swizzle and ignoring it would result in corrupted output. Cc: mesa-stable Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/13346 Acked-by: Ruijing Dong Part-of: --- src/gallium/drivers/radeonsi/radeon_vcn_dec.c | 8 ++++---- src/gallium/drivers/radeonsi/radeon_vcn_dec_jpeg.c | 8 +++++--- src/gallium/drivers/radeonsi/radeon_vcn_enc_1_2.c | 10 +++++++--- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/gallium/drivers/radeonsi/radeon_vcn_dec.c b/src/gallium/drivers/radeonsi/radeon_vcn_dec.c index 7cf8e062637..b7aed7a9b7e 100644 --- a/src/gallium/drivers/radeonsi/radeon_vcn_dec.c +++ b/src/gallium/drivers/radeonsi/radeon_vcn_dec.c @@ -1770,13 +1770,13 @@ static struct pb_buffer_lean *rvcn_dec_message_decode(struct radeon_decoder *dec decode->dt_surf_tile_config = 0; decode->dt_uv_surf_tile_config = 0; - decode->dt_luma_top_offset = luma->surface.u.gfx9.surf_offset; - decode->dt_chroma_top_offset = chroma->surface.u.gfx9.surf_offset; + decode->dt_luma_top_offset = luma->surface.u.gfx9.surf_offset | (luma->surface.tile_swizzle << 8); + decode->dt_chroma_top_offset = chroma->surface.u.gfx9.surf_offset| (chroma->surface.tile_swizzle << 8); if (decode->dt_field_mode) { decode->dt_luma_bottom_offset = - luma->surface.u.gfx9.surf_offset + luma->surface.u.gfx9.surf_slice_size; + decode->dt_luma_top_offset + luma->surface.u.gfx9.surf_slice_size; decode->dt_chroma_bottom_offset = - chroma->surface.u.gfx9.surf_offset + chroma->surface.u.gfx9.surf_slice_size; + decode->dt_chroma_top_offset + chroma->surface.u.gfx9.surf_slice_size; } else { decode->dt_luma_bottom_offset = decode->dt_luma_top_offset; decode->dt_chroma_bottom_offset = decode->dt_chroma_top_offset; diff --git a/src/gallium/drivers/radeonsi/radeon_vcn_dec_jpeg.c b/src/gallium/drivers/radeonsi/radeon_vcn_dec_jpeg.c index 6a1051bc472..b2a52f84894 100644 --- a/src/gallium/drivers/radeonsi/radeon_vcn_dec_jpeg.c +++ b/src/gallium/drivers/radeonsi/radeon_vcn_dec_jpeg.c @@ -28,7 +28,7 @@ static struct pb_buffer_lean *radeon_jpeg_get_decode_param(struct radeon_decoder struct si_texture *chroma, *chromav; dec->jpg.bsd_size = align(dec->bs_size, 128); - dec->jpg.dt_luma_top_offset = luma->surface.u.gfx9.surf_offset; + dec->jpg.dt_luma_top_offset = luma->surface.u.gfx9.surf_offset | (luma->surface.tile_swizzle << 8); dec->jpg.dt_chroma_top_offset = 0; dec->jpg.dt_chromav_top_offset = 0; dec->jpg.dt_swizzle_mode = luma->surface.u.gfx9.swizzle_mode; @@ -80,12 +80,14 @@ static struct pb_buffer_lean *radeon_jpeg_get_decode_param(struct radeon_decoder chromav = (struct si_texture *)((struct vl_video_buffer *)target)->resources[2]; dec->jpg.dt_chromav_top_offset = chromav->surface.u.gfx9.surf_offset; chroma = (struct si_texture *)((struct vl_video_buffer*)target)->resources[1]; - dec->jpg.dt_chroma_top_offset = chroma->surface.u.gfx9.surf_offset; + dec->jpg.dt_chroma_top_offset = + chroma->surface.u.gfx9.surf_offset | (chroma->surface.tile_swizzle << 8); dec->jpg.dt_uv_pitch = chroma->surface.u.gfx9.surf_pitch * chroma->surface.bpe; break; case PIPE_FORMAT_NV12: chroma = (struct si_texture *)((struct vl_video_buffer*)target)->resources[1]; - dec->jpg.dt_chroma_top_offset = chroma->surface.u.gfx9.surf_offset; + dec->jpg.dt_chroma_top_offset = + chroma->surface.u.gfx9.surf_offset | (chroma->surface.tile_swizzle << 8); dec->jpg.dt_uv_pitch = chroma->surface.u.gfx9.surf_pitch * chroma->surface.bpe; break; case PIPE_FORMAT_YUYV: diff --git a/src/gallium/drivers/radeonsi/radeon_vcn_enc_1_2.c b/src/gallium/drivers/radeonsi/radeon_vcn_enc_1_2.c index 03ebd6dcb73..f02173c35a1 100644 --- a/src/gallium/drivers/radeonsi/radeon_vcn_enc_1_2.c +++ b/src/gallium/drivers/radeonsi/radeon_vcn_enc_1_2.c @@ -1050,12 +1050,16 @@ static void radeon_enc_encode_params(struct radeon_encoder *enc) enc->chroma->u.gfx9.surf_pitch : enc->luma->u.gfx9.surf_pitch; enc->enc_pic.enc_params.input_pic_swizzle_mode = enc->luma->u.gfx9.swizzle_mode; + uint32_t luma_offset = + enc->luma->u.gfx9.surf_offset | (enc->luma->tile_swizzle << 8); + uint32_t chroma_offset = + enc->chroma ? enc->chroma->u.gfx9.surf_offset | (enc->chroma->tile_swizzle << 8) : 0; + RADEON_ENC_BEGIN(enc->cmd.enc_params); RADEON_ENC_CS(enc->enc_pic.enc_params.pic_type); RADEON_ENC_CS(enc->enc_pic.enc_params.allowed_max_bitstream_size); - RADEON_ENC_READ(enc->handle, RADEON_DOMAIN_VRAM, enc->luma->u.gfx9.surf_offset); - RADEON_ENC_READ(enc->handle, RADEON_DOMAIN_VRAM, enc->chroma ? - enc->chroma->u.gfx9.surf_offset : enc->luma->u.gfx9.surf_pitch); + RADEON_ENC_READ(enc->handle, RADEON_DOMAIN_VRAM, luma_offset); + RADEON_ENC_READ(enc->handle, RADEON_DOMAIN_VRAM, chroma_offset); RADEON_ENC_CS(enc->enc_pic.enc_params.input_pic_luma_pitch); RADEON_ENC_CS(enc->enc_pic.enc_params.input_pic_chroma_pitch); RADEON_ENC_CS(enc->enc_pic.enc_params.input_pic_swizzle_mode);