mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-08 17:48:10 +02:00
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:
parent
4bcd5ee5b2
commit
c4482a3c1a
4 changed files with 99 additions and 10 deletions
|
|
@ -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;
|
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,
|
static void radeon_vcn_enc_h264_get_param(struct radeon_encoder *enc,
|
||||||
struct pipe_h264_enc_picture_desc *pic)
|
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_rc_param(enc, pic);
|
||||||
radeon_vcn_enc_h264_get_spec_misc_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_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,
|
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;
|
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,
|
static void radeon_vcn_enc_hevc_get_param(struct radeon_encoder *enc,
|
||||||
struct pipe_h265_enc_picture_desc *pic)
|
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_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_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)
|
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 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_CS(value) (enc->cs.current.buf[enc->cs.current.cdw++] = (value))
|
||||||
#define RADEON_ENC_BEGIN(cmd) \
|
#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)
|
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.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_BEGIN(enc->cmd.slice_control_h264);
|
||||||
RADEON_ENC_CS(enc->enc_pic.slice_ctrl.slice_control_mode);
|
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)
|
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.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_BEGIN(enc->cmd.slice_control_hevc);
|
||||||
RADEON_ENC_CS(enc->enc_pic.hevc_slice_ctrl.slice_control_mode);
|
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;
|
return (sscreen->info.family >= CHIP_RAVEN) ? 1 : 0;
|
||||||
|
|
||||||
case PIPE_VIDEO_CAP_ENC_HEVC_FEATURE_FLAGS:
|
case PIPE_VIDEO_CAP_ENC_HEVC_FEATURE_FLAGS:
|
||||||
if ((sscreen->info.family >= CHIP_RENOIR) &&
|
if ((sscreen->info.family >= CHIP_RAVEN) &&
|
||||||
(profile == PIPE_VIDEO_PROFILE_HEVC_MAIN ||
|
(profile == PIPE_VIDEO_PROFILE_HEVC_MAIN ||
|
||||||
profile == PIPE_VIDEO_PROFILE_HEVC_MAIN_10)) {
|
profile == PIPE_VIDEO_PROFILE_HEVC_MAIN_10)) {
|
||||||
union pipe_h265_enc_cap_features pipe_features;
|
union pipe_h265_enc_cap_features pipe_features;
|
||||||
pipe_features.value = 0;
|
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;
|
return pipe_features.value;
|
||||||
} else
|
} else
|
||||||
return 0;
|
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:
|
case PIPE_VIDEO_CAP_ENC_SUPPORTS_ASYNC_OPERATION:
|
||||||
return (sscreen->info.family >= CHIP_RAVEN) ? 1 : 0;
|
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:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue