From a5ade6f8144ff5a3304ca3bafbc37c821f007818 Mon Sep 17 00:00:00 2001 From: Benjamin Cheng Date: Tue, 26 May 2026 10:10:52 -0400 Subject: [PATCH] radeonsi/mm: Disable variable slices when bad input is found If the slice configuration from the app is not valid, we can override it by falling back to the FIXED slices mode. This fixes Steam Game Recording in HEVC because it does stuff like send num_ctu_in_slice = 3600 for a single slice 2560x1444 encoding (it seems like it's assuming 32x32 CTBs). Closes: https://gitlab.freedesktop.org/mesa/mesa/-/work_items/15526 Closes: https://gitlab.freedesktop.org/mesa/mesa/-/work_items/15454 Cc: mesa-stable Signed-off-by: Benjamin Cheng Reviewed-by: David Rosca Part-of: --- src/gallium/drivers/radeonsi/mm/radeon_vcn_enc.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/gallium/drivers/radeonsi/mm/radeon_vcn_enc.c b/src/gallium/drivers/radeonsi/mm/radeon_vcn_enc.c index e945d9f44d7..ae88f5874fe 100644 --- a/src/gallium/drivers/radeonsi/mm/radeon_vcn_enc.c +++ b/src/gallium/drivers/radeonsi/mm/radeon_vcn_enc.c @@ -444,12 +444,18 @@ static void radeon_vcn_enc_h264_get_slice_ctrl_param(struct radeon_encoder *enc, enc->enc_pic.quality_modes.pre_encode_mode) && pic->num_slice_descriptors <= RENCODE_MAX_NUM_SLICES) { - enc->enc_pic.slice_ctrl.slice_control_mode = RENCODE_H264_SLICE_CONTROL_MODE_VARIABLE_MBS; + uint32_t cumulative_mbs = 0; enc->enc_pic.h264_slice_info_var.num_slices = pic->num_slice_descriptors; for (unsigned i = 0; i < pic->num_slice_descriptors; i++) { enc->enc_pic.h264_slice_info_var.slice_info[i].num_mbs_per_slice = pic->slices_descriptors[i].num_macroblocks; + cumulative_mbs += pic->slices_descriptors[i].num_macroblocks; } + + /* If the app input does not fill the frame, override it by not using + * variable slice mode. */ + if (cumulative_mbs == num_mbs_total) + enc->enc_pic.slice_ctrl.slice_control_mode = RENCODE_H264_SLICE_CONTROL_MODE_VARIABLE_MBS; } } @@ -828,13 +834,19 @@ static void radeon_vcn_enc_hevc_get_slice_ctrl_param(struct radeon_encoder *enc, enc->enc_pic.quality_modes.pre_encode_mode) && pic->num_slice_descriptors <= RENCODE_MAX_NUM_SLICES) { - enc->enc_pic.hevc_slice_ctrl.slice_control_mode = RENCODE_HEVC_SLICE_CONTROL_MODE_VARIABLE_CTBS; + uint32_t cumulative_ctbs = 0; enc->enc_pic.hevc_slice_info_var.num_slice_segments = pic->num_slice_descriptors; for (unsigned i = 0; i < pic->num_slice_descriptors; i++) { enc->enc_pic.hevc_slice_info_var.slice_segment_info[i].num_ctbs_per_segment = pic->slices_descriptors[i].num_ctu_in_slice; enc->enc_pic.hevc_slice_info_var.slice_segment_info[i].is_independent = 1; + cumulative_ctbs += pic->slices_descriptors[i].num_ctu_in_slice; } + + /* If the app input does not fill the frame, override it by not using + * variable slice mode. */ + if (cumulative_ctbs == num_ctbs_total) + enc->enc_pic.slice_ctrl.slice_control_mode = RENCODE_HEVC_SLICE_CONTROL_MODE_VARIABLE_CTBS; } }