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:
@@ -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)
|
||||
|
@@ -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) \
|
||||
{ \
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user