radeonsi/vcn: enable multi-slice encoding

- enable h264 multiple slice encoding
- enable hevc multiple slice encoding
- enable hevc block size config options.
- enable amp, strong_intra_smmothing,
         constrained_intra_pred and deblocking filter
         disable config options for hevc encoding.

Reviewed-by: Boyuan Zhang <Boyuan.Zhang@amd.com>
Signed-off-by: Ruijing Dong <ruijing.dong@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18992>
This commit is contained in:
Ruijing Dong
2022-10-06 16:45:58 -04:00
committed by Marge Bot
parent 4bcd5ee5b2
commit c4482a3c1a
4 changed files with 99 additions and 10 deletions

View File

@@ -194,6 +194,28 @@ static void radeon_vcn_enc_h264_get_vui_param(struct radeon_encoder *enc,
enc->enc_pic.vui_info.time_scale = pic->seq.time_scale;
}
/* only checking the first slice to get num of mbs in slice to
* determine the number of slices in this frame, only fixed MB mode
* is supported now, the last slice in frame could have less number of
* MBs.
*/
static void radeon_vcn_enc_h264_get_slice_ctrl_param(struct radeon_encoder *enc,
struct pipe_h264_enc_picture_desc *pic)
{
uint32_t width_in_mb, height_in_mb, num_mbs_in_slice;
width_in_mb = PIPE_ALIGN_IN_BLOCK_SIZE(enc->base.width, PIPE_H264_MB_SIZE);
height_in_mb = PIPE_ALIGN_IN_BLOCK_SIZE(enc->base.height, PIPE_H264_MB_SIZE);
if (pic->slices_descriptors[0].num_macroblocks >= width_in_mb * height_in_mb ||
pic->slices_descriptors[0].num_macroblocks == 0)
num_mbs_in_slice = width_in_mb * height_in_mb;
else
num_mbs_in_slice = pic->slices_descriptors[0].num_macroblocks;
enc->enc_pic.slice_ctrl.num_mbs_per_slice = num_mbs_in_slice;
}
static void radeon_vcn_enc_h264_get_param(struct radeon_encoder *enc,
struct pipe_h264_enc_picture_desc *pic)
{
@@ -217,6 +239,7 @@ static void radeon_vcn_enc_h264_get_param(struct radeon_encoder *enc,
radeon_vcn_enc_h264_get_rc_param(enc, pic);
radeon_vcn_enc_h264_get_spec_misc_param(enc, pic);
radeon_vcn_enc_h264_get_vui_param(enc, pic);
radeon_vcn_enc_h264_get_slice_ctrl_param(enc, pic);
}
static void radeon_vcn_enc_hevc_get_cropping_param(struct radeon_encoder *enc,
@@ -329,6 +352,34 @@ static void radeon_vcn_enc_hevc_get_vui_param(struct radeon_encoder *enc,
enc->enc_pic.vui_info.time_scale = pic->seq.time_scale;
}
/* only checking the first slice to get num of ctbs in slice to
* determine the number of slices in this frame, only fixed CTB mode
* is supported now, the last slice in frame could have less number of
* ctbs.
*/
static void radeon_vcn_enc_hevc_get_slice_ctrl_param(struct radeon_encoder *enc,
struct pipe_h265_enc_picture_desc *pic)
{
uint32_t width_in_ctb, height_in_ctb, num_ctbs_in_slice;
width_in_ctb = PIPE_ALIGN_IN_BLOCK_SIZE(pic->seq.pic_width_in_luma_samples,
PIPE_H265_ENC_CTB_SIZE);
height_in_ctb = PIPE_ALIGN_IN_BLOCK_SIZE(pic->seq.pic_height_in_luma_samples,
PIPE_H265_ENC_CTB_SIZE);
if (pic->slices_descriptors[0].num_ctu_in_slice >= width_in_ctb * height_in_ctb ||
pic->slices_descriptors[0].num_ctu_in_slice == 0)
num_ctbs_in_slice = width_in_ctb * height_in_ctb;
else
num_ctbs_in_slice = pic->slices_descriptors[0].num_ctu_in_slice;
enc->enc_pic.hevc_slice_ctrl.fixed_ctbs_per_slice.num_ctbs_per_slice =
num_ctbs_in_slice;
enc->enc_pic.hevc_slice_ctrl.fixed_ctbs_per_slice.num_ctbs_per_slice_segment =
num_ctbs_in_slice;
}
static void radeon_vcn_enc_hevc_get_param(struct radeon_encoder *enc,
struct pipe_h265_enc_picture_desc *pic)
{
@@ -385,6 +436,7 @@ static void radeon_vcn_enc_hevc_get_param(struct radeon_encoder *enc,
radeon_vcn_enc_hevc_get_rc_param(enc, pic);
radeon_vcn_enc_hevc_get_rc_param(enc, pic);
radeon_vcn_enc_hevc_get_vui_param(enc, pic);
radeon_vcn_enc_hevc_get_slice_ctrl_param(enc, pic);
}
static void radeon_vcn_enc_get_param(struct radeon_encoder *enc, struct pipe_picture_desc *picture)

View File

@@ -135,6 +135,11 @@
#define RENCODE_MAX_NUM_TEMPORAL_LAYERS 4
#define PIPE_H265_ENC_CTB_SIZE 64
#define PIPE_H264_MB_SIZE 16
#define PIPE_ALIGN_IN_BLOCK_SIZE(value, align) (((value) + ((align) - 1))/(align))
#define RADEON_ENC_CS(value) (enc->cs.current.buf[enc->cs.current.cdw++] = (value))
#define RADEON_ENC_BEGIN(cmd) \
{ \

View File

@@ -141,8 +141,6 @@ static void radeon_enc_layer_select(struct radeon_encoder *enc)
static void radeon_enc_slice_control(struct radeon_encoder *enc)
{
enc->enc_pic.slice_ctrl.slice_control_mode = RENCODE_H264_SLICE_CONTROL_MODE_FIXED_MBS;
enc->enc_pic.slice_ctrl.num_mbs_per_slice =
align(enc->base.width, 16) / 16 * align(enc->base.height, 16) / 16;
RADEON_ENC_BEGIN(enc->cmd.slice_control_h264);
RADEON_ENC_CS(enc->enc_pic.slice_ctrl.slice_control_mode);
@@ -153,10 +151,6 @@ static void radeon_enc_slice_control(struct radeon_encoder *enc)
static void radeon_enc_slice_control_hevc(struct radeon_encoder *enc)
{
enc->enc_pic.hevc_slice_ctrl.slice_control_mode = RENCODE_HEVC_SLICE_CONTROL_MODE_FIXED_CTBS;
enc->enc_pic.hevc_slice_ctrl.fixed_ctbs_per_slice.num_ctbs_per_slice =
align(enc->base.width, 64) / 64 * align(enc->base.height, 64) / 64;
enc->enc_pic.hevc_slice_ctrl.fixed_ctbs_per_slice.num_ctbs_per_slice_segment =
enc->enc_pic.hevc_slice_ctrl.fixed_ctbs_per_slice.num_ctbs_per_slice;
RADEON_ENC_BEGIN(enc->cmd.slice_control_hevc);
RADEON_ENC_CS(enc->enc_pic.hevc_slice_ctrl.slice_control_mode);

View File

@@ -627,20 +627,58 @@ static int si_get_video_param(struct pipe_screen *screen, enum pipe_video_profil
return (sscreen->info.family >= CHIP_RAVEN) ? 1 : 0;
case PIPE_VIDEO_CAP_ENC_HEVC_FEATURE_FLAGS:
if ((sscreen->info.family >= CHIP_RENOIR) &&
(profile == PIPE_VIDEO_PROFILE_HEVC_MAIN ||
profile == PIPE_VIDEO_PROFILE_HEVC_MAIN_10)) {
if ((sscreen->info.family >= CHIP_RAVEN) &&
(profile == PIPE_VIDEO_PROFILE_HEVC_MAIN ||
profile == PIPE_VIDEO_PROFILE_HEVC_MAIN_10)) {
union pipe_h265_enc_cap_features pipe_features;
pipe_features.value = 0;
pipe_features.bits.sao = PIPE_H265_ENC_FEATURE_SUPPORTED;
pipe_features.bits.amp = PIPE_H265_ENC_FEATURE_SUPPORTED;
pipe_features.bits.strong_intra_smoothing = PIPE_H265_ENC_FEATURE_SUPPORTED;
pipe_features.bits.constrained_intra_pred = PIPE_H265_ENC_FEATURE_SUPPORTED;
pipe_features.bits.deblocking_filter_disable
= PIPE_H265_ENC_FEATURE_SUPPORTED;
if (sscreen->info.family >= CHIP_RENOIR)
pipe_features.bits.sao = PIPE_H265_ENC_FEATURE_SUPPORTED;
return pipe_features.value;
} else
return 0;
case PIPE_VIDEO_CAP_ENC_HEVC_BLOCK_SIZES:
if (profile == PIPE_VIDEO_PROFILE_HEVC_MAIN ||
profile == PIPE_VIDEO_PROFILE_HEVC_MAIN_10) {
union pipe_h265_enc_cap_block_sizes pipe_block_sizes;
pipe_block_sizes.value = 0;
pipe_block_sizes.bits.log2_max_coding_tree_block_size_minus3 = 3;
pipe_block_sizes.bits.log2_min_coding_tree_block_size_minus3 = 3;
pipe_block_sizes.bits.log2_min_luma_coding_block_size_minus3 = 0;
pipe_block_sizes.bits.log2_max_luma_transform_block_size_minus2 = 3;
pipe_block_sizes.bits.log2_min_luma_transform_block_size_minus2 = 0;
return pipe_block_sizes.value;
} else
return 0;
case PIPE_VIDEO_CAP_ENC_SUPPORTS_ASYNC_OPERATION:
return (sscreen->info.family >= CHIP_RAVEN) ? 1 : 0;
case PIPE_VIDEO_CAP_ENC_MAX_SLICES_PER_FRAME:
if (sscreen->info.family >= CHIP_RAVEN)
return 128;
else
return 1;
case PIPE_VIDEO_CAP_ENC_SLICES_STRUCTURE:
if (sscreen->info.family >= CHIP_RENOIR) {
int value = (PIPE_VIDEO_CAP_SLICE_STRUCTURE_POWER_OF_TWO_ROWS |
PIPE_VIDEO_CAP_SLICE_STRUCTURE_EQUAL_ROWS |
PIPE_VIDEO_CAP_SLICE_STRUCTURE_EQUAL_MULTI_ROWS);
return value;
} else
return 0;
default:
return 0;
}