radeon: switch to 3-spaces style

For clang-format config see the previous commit.

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Tested-by: Marge Bot <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4319>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4319>
This commit is contained in:
Pierre-Eric Pelloux-Prayer 2020-03-27 20:42:29 +01:00 committed by Marge Bot
parent d7008fe46a
commit 716a065ac0
21 changed files with 8125 additions and 8441 deletions

View File

@ -1,2 +0,0 @@
[*.{c,h}]
indent_style = tab

File diff suppressed because it is too large Load Diff

View File

@ -32,410 +32,410 @@
#include "vl/vl_video_buffer.h"
/* UVD uses PM4 packet type 0 and 2 */
#define RUVD_PKT_TYPE_S(x) (((unsigned)(x) & 0x3) << 30)
#define RUVD_PKT_TYPE_G(x) (((x) >> 30) & 0x3)
#define RUVD_PKT_TYPE_C 0x3FFFFFFF
#define RUVD_PKT_COUNT_S(x) (((unsigned)(x) & 0x3FFF) << 16)
#define RUVD_PKT_COUNT_G(x) (((x) >> 16) & 0x3FFF)
#define RUVD_PKT_COUNT_C 0xC000FFFF
#define RUVD_PKT0_BASE_INDEX_S(x) (((unsigned)(x) & 0xFFFF) << 0)
#define RUVD_PKT0_BASE_INDEX_G(x) (((x) >> 0) & 0xFFFF)
#define RUVD_PKT0_BASE_INDEX_C 0xFFFF0000
#define RUVD_PKT0(index, count) (RUVD_PKT_TYPE_S(0) | RUVD_PKT0_BASE_INDEX_S(index) | RUVD_PKT_COUNT_S(count))
#define RUVD_PKT2() (RUVD_PKT_TYPE_S(2))
#define RUVD_PKT_TYPE_S(x) (((unsigned)(x)&0x3) << 30)
#define RUVD_PKT_TYPE_G(x) (((x) >> 30) & 0x3)
#define RUVD_PKT_TYPE_C 0x3FFFFFFF
#define RUVD_PKT_COUNT_S(x) (((unsigned)(x)&0x3FFF) << 16)
#define RUVD_PKT_COUNT_G(x) (((x) >> 16) & 0x3FFF)
#define RUVD_PKT_COUNT_C 0xC000FFFF
#define RUVD_PKT0_BASE_INDEX_S(x) (((unsigned)(x)&0xFFFF) << 0)
#define RUVD_PKT0_BASE_INDEX_G(x) (((x) >> 0) & 0xFFFF)
#define RUVD_PKT0_BASE_INDEX_C 0xFFFF0000
#define RUVD_PKT0(index, count) \
(RUVD_PKT_TYPE_S(0) | RUVD_PKT0_BASE_INDEX_S(index) | RUVD_PKT_COUNT_S(count))
#define RUVD_PKT2() (RUVD_PKT_TYPE_S(2))
/* registers involved with UVD */
#define RUVD_GPCOM_VCPU_CMD 0xEF0C
#define RUVD_GPCOM_VCPU_DATA0 0xEF10
#define RUVD_GPCOM_VCPU_DATA1 0xEF14
#define RUVD_ENGINE_CNTL 0xEF18
#define RUVD_GPCOM_VCPU_CMD 0xEF0C
#define RUVD_GPCOM_VCPU_DATA0 0xEF10
#define RUVD_GPCOM_VCPU_DATA1 0xEF14
#define RUVD_ENGINE_CNTL 0xEF18
#define RUVD_GPCOM_VCPU_CMD_SOC15 0x2070c
#define RUVD_GPCOM_VCPU_DATA0_SOC15 0x20710
#define RUVD_GPCOM_VCPU_DATA1_SOC15 0x20714
#define RUVD_ENGINE_CNTL_SOC15 0x20718
#define RUVD_GPCOM_VCPU_CMD_SOC15 0x2070c
#define RUVD_GPCOM_VCPU_DATA0_SOC15 0x20710
#define RUVD_GPCOM_VCPU_DATA1_SOC15 0x20714
#define RUVD_ENGINE_CNTL_SOC15 0x20718
/* UVD commands to VCPU */
#define RUVD_CMD_MSG_BUFFER 0x00000000
#define RUVD_CMD_DPB_BUFFER 0x00000001
#define RUVD_CMD_DECODING_TARGET_BUFFER 0x00000002
#define RUVD_CMD_FEEDBACK_BUFFER 0x00000003
#define RUVD_CMD_SESSION_CONTEXT_BUFFER 0x00000005
#define RUVD_CMD_BITSTREAM_BUFFER 0x00000100
#define RUVD_CMD_ITSCALING_TABLE_BUFFER 0x00000204
#define RUVD_CMD_CONTEXT_BUFFER 0x00000206
#define RUVD_CMD_MSG_BUFFER 0x00000000
#define RUVD_CMD_DPB_BUFFER 0x00000001
#define RUVD_CMD_DECODING_TARGET_BUFFER 0x00000002
#define RUVD_CMD_FEEDBACK_BUFFER 0x00000003
#define RUVD_CMD_SESSION_CONTEXT_BUFFER 0x00000005
#define RUVD_CMD_BITSTREAM_BUFFER 0x00000100
#define RUVD_CMD_ITSCALING_TABLE_BUFFER 0x00000204
#define RUVD_CMD_CONTEXT_BUFFER 0x00000206
/* UVD message types */
#define RUVD_MSG_CREATE 0
#define RUVD_MSG_DECODE 1
#define RUVD_MSG_DESTROY 2
#define RUVD_MSG_CREATE 0
#define RUVD_MSG_DECODE 1
#define RUVD_MSG_DESTROY 2
/* UVD stream types */
#define RUVD_CODEC_H264 0x00000000
#define RUVD_CODEC_VC1 0x00000001
#define RUVD_CODEC_MPEG2 0x00000003
#define RUVD_CODEC_MPEG4 0x00000004
#define RUVD_CODEC_H264_PERF 0x00000007
#define RUVD_CODEC_MJPEG 0x00000008
#define RUVD_CODEC_H265 0x00000010
#define RUVD_CODEC_H264 0x00000000
#define RUVD_CODEC_VC1 0x00000001
#define RUVD_CODEC_MPEG2 0x00000003
#define RUVD_CODEC_MPEG4 0x00000004
#define RUVD_CODEC_H264_PERF 0x00000007
#define RUVD_CODEC_MJPEG 0x00000008
#define RUVD_CODEC_H265 0x00000010
/* UVD decode target buffer tiling mode */
#define RUVD_TILE_LINEAR 0x00000000
#define RUVD_TILE_8X4 0x00000001
#define RUVD_TILE_8X8 0x00000002
#define RUVD_TILE_32AS8 0x00000003
#define RUVD_TILE_LINEAR 0x00000000
#define RUVD_TILE_8X4 0x00000001
#define RUVD_TILE_8X8 0x00000002
#define RUVD_TILE_32AS8 0x00000003
/* UVD decode target buffer array mode */
#define RUVD_ARRAY_MODE_LINEAR 0x00000000
#define RUVD_ARRAY_MODE_MACRO_LINEAR_MICRO_TILED 0x00000001
#define RUVD_ARRAY_MODE_1D_THIN 0x00000002
#define RUVD_ARRAY_MODE_2D_THIN 0x00000004
#define RUVD_ARRAY_MODE_MACRO_TILED_MICRO_LINEAR 0x00000004
#define RUVD_ARRAY_MODE_MACRO_TILED_MICRO_TILED 0x00000005
#define RUVD_ARRAY_MODE_LINEAR 0x00000000
#define RUVD_ARRAY_MODE_MACRO_LINEAR_MICRO_TILED 0x00000001
#define RUVD_ARRAY_MODE_1D_THIN 0x00000002
#define RUVD_ARRAY_MODE_2D_THIN 0x00000004
#define RUVD_ARRAY_MODE_MACRO_TILED_MICRO_LINEAR 0x00000004
#define RUVD_ARRAY_MODE_MACRO_TILED_MICRO_TILED 0x00000005
/* UVD tile config */
#define RUVD_BANK_WIDTH(x) ((x) << 0)
#define RUVD_BANK_HEIGHT(x) ((x) << 3)
#define RUVD_MACRO_TILE_ASPECT_RATIO(x) ((x) << 6)
#define RUVD_NUM_BANKS(x) ((x) << 9)
#define RUVD_BANK_WIDTH(x) ((x) << 0)
#define RUVD_BANK_HEIGHT(x) ((x) << 3)
#define RUVD_MACRO_TILE_ASPECT_RATIO(x) ((x) << 6)
#define RUVD_NUM_BANKS(x) ((x) << 9)
/* H.264 profile definitions */
#define RUVD_H264_PROFILE_BASELINE 0x00000000
#define RUVD_H264_PROFILE_MAIN 0x00000001
#define RUVD_H264_PROFILE_HIGH 0x00000002
#define RUVD_H264_PROFILE_STEREO_HIGH 0x00000003
#define RUVD_H264_PROFILE_MVC 0x00000004
#define RUVD_H264_PROFILE_BASELINE 0x00000000
#define RUVD_H264_PROFILE_MAIN 0x00000001
#define RUVD_H264_PROFILE_HIGH 0x00000002
#define RUVD_H264_PROFILE_STEREO_HIGH 0x00000003
#define RUVD_H264_PROFILE_MVC 0x00000004
/* VC-1 profile definitions */
#define RUVD_VC1_PROFILE_SIMPLE 0x00000000
#define RUVD_VC1_PROFILE_MAIN 0x00000001
#define RUVD_VC1_PROFILE_ADVANCED 0x00000002
#define RUVD_VC1_PROFILE_SIMPLE 0x00000000
#define RUVD_VC1_PROFILE_MAIN 0x00000001
#define RUVD_VC1_PROFILE_ADVANCED 0x00000002
enum ruvd_surface_type {
RUVD_SURFACE_TYPE_LEGACY = 0,
RUVD_SURFACE_TYPE_GFX9
enum ruvd_surface_type
{
RUVD_SURFACE_TYPE_LEGACY = 0,
RUVD_SURFACE_TYPE_GFX9
};
struct ruvd_mvc_element {
uint16_t viewOrderIndex;
uint16_t viewId;
uint16_t numOfAnchorRefsInL0;
uint16_t viewIdOfAnchorRefsInL0[15];
uint16_t numOfAnchorRefsInL1;
uint16_t viewIdOfAnchorRefsInL1[15];
uint16_t numOfNonAnchorRefsInL0;
uint16_t viewIdOfNonAnchorRefsInL0[15];
uint16_t numOfNonAnchorRefsInL1;
uint16_t viewIdOfNonAnchorRefsInL1[15];
uint16_t viewOrderIndex;
uint16_t viewId;
uint16_t numOfAnchorRefsInL0;
uint16_t viewIdOfAnchorRefsInL0[15];
uint16_t numOfAnchorRefsInL1;
uint16_t viewIdOfAnchorRefsInL1[15];
uint16_t numOfNonAnchorRefsInL0;
uint16_t viewIdOfNonAnchorRefsInL0[15];
uint16_t numOfNonAnchorRefsInL1;
uint16_t viewIdOfNonAnchorRefsInL1[15];
};
struct ruvd_h264 {
uint32_t profile;
uint32_t level;
uint32_t profile;
uint32_t level;
uint32_t sps_info_flags;
uint32_t pps_info_flags;
uint8_t chroma_format;
uint8_t bit_depth_luma_minus8;
uint8_t bit_depth_chroma_minus8;
uint8_t log2_max_frame_num_minus4;
uint32_t sps_info_flags;
uint32_t pps_info_flags;
uint8_t chroma_format;
uint8_t bit_depth_luma_minus8;
uint8_t bit_depth_chroma_minus8;
uint8_t log2_max_frame_num_minus4;
uint8_t pic_order_cnt_type;
uint8_t log2_max_pic_order_cnt_lsb_minus4;
uint8_t num_ref_frames;
uint8_t reserved_8bit;
uint8_t pic_order_cnt_type;
uint8_t log2_max_pic_order_cnt_lsb_minus4;
uint8_t num_ref_frames;
uint8_t reserved_8bit;
int8_t pic_init_qp_minus26;
int8_t pic_init_qs_minus26;
int8_t chroma_qp_index_offset;
int8_t second_chroma_qp_index_offset;
int8_t pic_init_qp_minus26;
int8_t pic_init_qs_minus26;
int8_t chroma_qp_index_offset;
int8_t second_chroma_qp_index_offset;
uint8_t num_slice_groups_minus1;
uint8_t slice_group_map_type;
uint8_t num_ref_idx_l0_active_minus1;
uint8_t num_ref_idx_l1_active_minus1;
uint8_t num_slice_groups_minus1;
uint8_t slice_group_map_type;
uint8_t num_ref_idx_l0_active_minus1;
uint8_t num_ref_idx_l1_active_minus1;
uint16_t slice_group_change_rate_minus1;
uint16_t reserved_16bit_1;
uint16_t slice_group_change_rate_minus1;
uint16_t reserved_16bit_1;
uint8_t scaling_list_4x4[6][16];
uint8_t scaling_list_8x8[2][64];
uint8_t scaling_list_4x4[6][16];
uint8_t scaling_list_8x8[2][64];
uint32_t frame_num;
uint32_t frame_num_list[16];
int32_t curr_field_order_cnt_list[2];
int32_t field_order_cnt_list[16][2];
uint32_t frame_num;
uint32_t frame_num_list[16];
int32_t curr_field_order_cnt_list[2];
int32_t field_order_cnt_list[16][2];
uint32_t decoded_pic_idx;
uint32_t decoded_pic_idx;
uint32_t curr_pic_ref_frame_num;
uint32_t curr_pic_ref_frame_num;
uint8_t ref_frame_list[16];
uint8_t ref_frame_list[16];
uint32_t reserved[122];
uint32_t reserved[122];
struct {
uint32_t numViews;
uint32_t viewId0;
struct ruvd_mvc_element mvcElements[1];
} mvc;
struct {
uint32_t numViews;
uint32_t viewId0;
struct ruvd_mvc_element mvcElements[1];
} mvc;
};
struct ruvd_h265 {
uint32_t sps_info_flags;
uint32_t pps_info_flags;
uint32_t sps_info_flags;
uint32_t pps_info_flags;
uint8_t chroma_format;
uint8_t bit_depth_luma_minus8;
uint8_t bit_depth_chroma_minus8;
uint8_t log2_max_pic_order_cnt_lsb_minus4;
uint8_t chroma_format;
uint8_t bit_depth_luma_minus8;
uint8_t bit_depth_chroma_minus8;
uint8_t log2_max_pic_order_cnt_lsb_minus4;
uint8_t sps_max_dec_pic_buffering_minus1;
uint8_t log2_min_luma_coding_block_size_minus3;
uint8_t log2_diff_max_min_luma_coding_block_size;
uint8_t log2_min_transform_block_size_minus2;
uint8_t sps_max_dec_pic_buffering_minus1;
uint8_t log2_min_luma_coding_block_size_minus3;
uint8_t log2_diff_max_min_luma_coding_block_size;
uint8_t log2_min_transform_block_size_minus2;
uint8_t log2_diff_max_min_transform_block_size;
uint8_t max_transform_hierarchy_depth_inter;
uint8_t max_transform_hierarchy_depth_intra;
uint8_t pcm_sample_bit_depth_luma_minus1;
uint8_t log2_diff_max_min_transform_block_size;
uint8_t max_transform_hierarchy_depth_inter;
uint8_t max_transform_hierarchy_depth_intra;
uint8_t pcm_sample_bit_depth_luma_minus1;
uint8_t pcm_sample_bit_depth_chroma_minus1;
uint8_t log2_min_pcm_luma_coding_block_size_minus3;
uint8_t log2_diff_max_min_pcm_luma_coding_block_size;
uint8_t num_extra_slice_header_bits;
uint8_t pcm_sample_bit_depth_chroma_minus1;
uint8_t log2_min_pcm_luma_coding_block_size_minus3;
uint8_t log2_diff_max_min_pcm_luma_coding_block_size;
uint8_t num_extra_slice_header_bits;
uint8_t num_short_term_ref_pic_sets;
uint8_t num_long_term_ref_pic_sps;
uint8_t num_ref_idx_l0_default_active_minus1;
uint8_t num_ref_idx_l1_default_active_minus1;
uint8_t num_short_term_ref_pic_sets;
uint8_t num_long_term_ref_pic_sps;
uint8_t num_ref_idx_l0_default_active_minus1;
uint8_t num_ref_idx_l1_default_active_minus1;
int8_t pps_cb_qp_offset;
int8_t pps_cr_qp_offset;
int8_t pps_beta_offset_div2;
int8_t pps_tc_offset_div2;
int8_t pps_cb_qp_offset;
int8_t pps_cr_qp_offset;
int8_t pps_beta_offset_div2;
int8_t pps_tc_offset_div2;
uint8_t diff_cu_qp_delta_depth;
uint8_t num_tile_columns_minus1;
uint8_t num_tile_rows_minus1;
uint8_t log2_parallel_merge_level_minus2;
uint8_t diff_cu_qp_delta_depth;
uint8_t num_tile_columns_minus1;
uint8_t num_tile_rows_minus1;
uint8_t log2_parallel_merge_level_minus2;
uint16_t column_width_minus1[19];
uint16_t row_height_minus1[21];
uint16_t column_width_minus1[19];
uint16_t row_height_minus1[21];
int8_t init_qp_minus26;
uint8_t num_delta_pocs_ref_rps_idx;
uint8_t curr_idx;
uint8_t reserved1;
int32_t curr_poc;
uint8_t ref_pic_list[16];
int32_t poc_list[16];
uint8_t ref_pic_set_st_curr_before[8];
uint8_t ref_pic_set_st_curr_after[8];
uint8_t ref_pic_set_lt_curr[8];
int8_t init_qp_minus26;
uint8_t num_delta_pocs_ref_rps_idx;
uint8_t curr_idx;
uint8_t reserved1;
int32_t curr_poc;
uint8_t ref_pic_list[16];
int32_t poc_list[16];
uint8_t ref_pic_set_st_curr_before[8];
uint8_t ref_pic_set_st_curr_after[8];
uint8_t ref_pic_set_lt_curr[8];
uint8_t ucScalingListDCCoefSizeID2[6];
uint8_t ucScalingListDCCoefSizeID3[2];
uint8_t ucScalingListDCCoefSizeID2[6];
uint8_t ucScalingListDCCoefSizeID3[2];
uint8_t highestTid;
uint8_t isNonRef;
uint8_t highestTid;
uint8_t isNonRef;
uint8_t p010_mode;
uint8_t msb_mode;
uint8_t luma_10to8;
uint8_t chroma_10to8;
uint8_t sclr_luma10to8;
uint8_t sclr_chroma10to8;
uint8_t p010_mode;
uint8_t msb_mode;
uint8_t luma_10to8;
uint8_t chroma_10to8;
uint8_t sclr_luma10to8;
uint8_t sclr_chroma10to8;
uint8_t direct_reflist[2][15];
uint8_t direct_reflist[2][15];
};
struct ruvd_vc1 {
uint32_t profile;
uint32_t level;
uint32_t sps_info_flags;
uint32_t pps_info_flags;
uint32_t pic_structure;
uint32_t chroma_format;
uint32_t profile;
uint32_t level;
uint32_t sps_info_flags;
uint32_t pps_info_flags;
uint32_t pic_structure;
uint32_t chroma_format;
};
struct ruvd_mpeg2 {
uint32_t decoded_pic_idx;
uint32_t ref_pic_idx[2];
uint32_t decoded_pic_idx;
uint32_t ref_pic_idx[2];
uint8_t load_intra_quantiser_matrix;
uint8_t load_nonintra_quantiser_matrix;
uint8_t reserved_quantiser_alignement[2];
uint8_t intra_quantiser_matrix[64];
uint8_t nonintra_quantiser_matrix[64];
uint8_t load_intra_quantiser_matrix;
uint8_t load_nonintra_quantiser_matrix;
uint8_t reserved_quantiser_alignement[2];
uint8_t intra_quantiser_matrix[64];
uint8_t nonintra_quantiser_matrix[64];
uint8_t profile_and_level_indication;
uint8_t chroma_format;
uint8_t profile_and_level_indication;
uint8_t chroma_format;
uint8_t picture_coding_type;
uint8_t picture_coding_type;
uint8_t reserved_1;
uint8_t reserved_1;
uint8_t f_code[2][2];
uint8_t intra_dc_precision;
uint8_t pic_structure;
uint8_t top_field_first;
uint8_t frame_pred_frame_dct;
uint8_t concealment_motion_vectors;
uint8_t q_scale_type;
uint8_t intra_vlc_format;
uint8_t alternate_scan;
uint8_t f_code[2][2];
uint8_t intra_dc_precision;
uint8_t pic_structure;
uint8_t top_field_first;
uint8_t frame_pred_frame_dct;
uint8_t concealment_motion_vectors;
uint8_t q_scale_type;
uint8_t intra_vlc_format;
uint8_t alternate_scan;
};
struct ruvd_mpeg4
{
uint32_t decoded_pic_idx;
uint32_t ref_pic_idx[2];
struct ruvd_mpeg4 {
uint32_t decoded_pic_idx;
uint32_t ref_pic_idx[2];
uint32_t variant_type;
uint8_t profile_and_level_indication;
uint32_t variant_type;
uint8_t profile_and_level_indication;
uint8_t video_object_layer_verid;
uint8_t video_object_layer_shape;
uint8_t video_object_layer_verid;
uint8_t video_object_layer_shape;
uint8_t reserved_1;
uint8_t reserved_1;
uint16_t video_object_layer_width;
uint16_t video_object_layer_height;
uint16_t video_object_layer_width;
uint16_t video_object_layer_height;
uint16_t vop_time_increment_resolution;
uint16_t vop_time_increment_resolution;
uint16_t reserved_2;
uint16_t reserved_2;
uint32_t flags;
uint32_t flags;
uint8_t quant_type;
uint8_t quant_type;
uint8_t reserved_3[3];
uint8_t reserved_3[3];
uint8_t intra_quant_mat[64];
uint8_t nonintra_quant_mat[64];
uint8_t intra_quant_mat[64];
uint8_t nonintra_quant_mat[64];
struct {
uint8_t sprite_enable;
struct {
uint8_t sprite_enable;
uint8_t reserved_4[3];
uint8_t reserved_4[3];
uint16_t sprite_width;
uint16_t sprite_height;
int16_t sprite_left_coordinate;
int16_t sprite_top_coordinate;
uint16_t sprite_width;
uint16_t sprite_height;
int16_t sprite_left_coordinate;
int16_t sprite_top_coordinate;
uint8_t no_of_sprite_warping_points;
uint8_t sprite_warping_accuracy;
uint8_t sprite_brightness_change;
uint8_t low_latency_sprite_enable;
} sprite_config;
uint8_t no_of_sprite_warping_points;
uint8_t sprite_warping_accuracy;
uint8_t sprite_brightness_change;
uint8_t low_latency_sprite_enable;
} sprite_config;
struct {
uint32_t flags;
uint8_t vol_mode;
uint8_t reserved_5[3];
} divx_311_config;
struct {
uint32_t flags;
uint8_t vol_mode;
uint8_t reserved_5[3];
} divx_311_config;
};
/* message between driver and hardware */
struct ruvd_msg {
uint32_t size;
uint32_t msg_type;
uint32_t stream_handle;
uint32_t status_report_feedback_number;
uint32_t size;
uint32_t msg_type;
uint32_t stream_handle;
uint32_t status_report_feedback_number;
union {
struct {
uint32_t stream_type;
uint32_t session_flags;
uint32_t asic_id;
uint32_t width_in_samples;
uint32_t height_in_samples;
uint32_t dpb_buffer;
uint32_t dpb_size;
uint32_t dpb_model;
uint32_t version_info;
} create;
union {
struct {
uint32_t stream_type;
uint32_t session_flags;
uint32_t asic_id;
uint32_t width_in_samples;
uint32_t height_in_samples;
uint32_t dpb_buffer;
uint32_t dpb_size;
uint32_t dpb_model;
uint32_t version_info;
} create;
struct {
uint32_t stream_type;
uint32_t decode_flags;
uint32_t width_in_samples;
uint32_t height_in_samples;
struct {
uint32_t stream_type;
uint32_t decode_flags;
uint32_t width_in_samples;
uint32_t height_in_samples;
uint32_t dpb_buffer;
uint32_t dpb_size;
uint32_t dpb_model;
uint32_t dpb_reserved;
uint32_t dpb_buffer;
uint32_t dpb_size;
uint32_t dpb_model;
uint32_t dpb_reserved;
uint32_t db_offset_alignment;
uint32_t db_pitch;
uint32_t db_tiling_mode;
uint32_t db_array_mode;
uint32_t db_field_mode;
uint32_t db_surf_tile_config;
uint32_t db_aligned_height;
uint32_t db_reserved;
uint32_t db_offset_alignment;
uint32_t db_pitch;
uint32_t db_tiling_mode;
uint32_t db_array_mode;
uint32_t db_field_mode;
uint32_t db_surf_tile_config;
uint32_t db_aligned_height;
uint32_t db_reserved;
uint32_t use_addr_macro;
uint32_t use_addr_macro;
uint32_t bsd_buffer;
uint32_t bsd_size;
uint32_t bsd_buffer;
uint32_t bsd_size;
uint32_t pic_param_buffer;
uint32_t pic_param_size;
uint32_t mb_cntl_buffer;
uint32_t mb_cntl_size;
uint32_t pic_param_buffer;
uint32_t pic_param_size;
uint32_t mb_cntl_buffer;
uint32_t mb_cntl_size;
uint32_t dt_buffer;
uint32_t dt_pitch;
uint32_t dt_tiling_mode;
uint32_t dt_array_mode;
uint32_t dt_field_mode;
uint32_t dt_luma_top_offset;
uint32_t dt_luma_bottom_offset;
uint32_t dt_chroma_top_offset;
uint32_t dt_chroma_bottom_offset;
uint32_t dt_surf_tile_config;
uint32_t dt_uv_surf_tile_config;
// re-use dt_wa_chroma_top_offset as dt_ext_info for UV pitch in stoney
uint32_t dt_wa_chroma_top_offset;
uint32_t dt_wa_chroma_bottom_offset;
uint32_t dt_buffer;
uint32_t dt_pitch;
uint32_t dt_tiling_mode;
uint32_t dt_array_mode;
uint32_t dt_field_mode;
uint32_t dt_luma_top_offset;
uint32_t dt_luma_bottom_offset;
uint32_t dt_chroma_top_offset;
uint32_t dt_chroma_bottom_offset;
uint32_t dt_surf_tile_config;
uint32_t dt_uv_surf_tile_config;
// re-use dt_wa_chroma_top_offset as dt_ext_info for UV pitch in stoney
uint32_t dt_wa_chroma_top_offset;
uint32_t dt_wa_chroma_bottom_offset;
uint32_t reserved[16];
uint32_t reserved[16];
union {
struct ruvd_h264 h264;
struct ruvd_h265 h265;
struct ruvd_vc1 vc1;
struct ruvd_mpeg2 mpeg2;
struct ruvd_mpeg4 mpeg4;
union {
struct ruvd_h264 h264;
struct ruvd_h265 h265;
struct ruvd_vc1 vc1;
struct ruvd_mpeg2 mpeg2;
struct ruvd_mpeg4 mpeg4;
uint32_t info[768];
} codec;
uint32_t info[768];
} codec;
uint8_t extension_support;
uint8_t reserved_8bit_1;
uint8_t reserved_8bit_2;
uint8_t reserved_8bit_3;
uint32_t extension_reserved[64];
} decode;
} body;
uint8_t extension_support;
uint8_t reserved_8bit_1;
uint8_t reserved_8bit_2;
uint8_t reserved_8bit_3;
uint32_t extension_reserved[64];
} decode;
} body;
};
/* driver dependent callback */
typedef struct pb_buffer* (*ruvd_set_dtb)
(struct ruvd_msg* msg, struct vl_video_buffer *vb);
typedef struct pb_buffer *(*ruvd_set_dtb)(struct ruvd_msg *msg, struct vl_video_buffer *vb);
/* create an UVD decode */
struct pipe_video_codec *si_common_uvd_create_decoder(struct pipe_context *context,
const struct pipe_video_codec *templat,
ruvd_set_dtb set_dtb);
const struct pipe_video_codec *templat,
ruvd_set_dtb set_dtb);
/* fill decoding target field from the luma and chroma surfaces */
void si_uvd_set_dt_surfaces(struct ruvd_msg *msg, struct radeon_surf *luma,
struct radeon_surf *chroma, enum ruvd_surface_type type);
struct radeon_surf *chroma, enum ruvd_surface_type type);
#endif

View File

@ -25,109 +25,90 @@
*
**************************************************************************/
#include <stdio.h>
#include "pipe/p_video_codec.h"
#include "util/u_video.h"
#include "util/u_memory.h"
#include "vl/vl_video_buffer.h"
#include "radeonsi/si_pipe.h"
#include "radeon_video.h"
#include "radeon_uvd_enc.h"
#define UVD_HEVC_LEVEL_1 30
#define UVD_HEVC_LEVEL_2 60
#define UVD_HEVC_LEVEL_2_1 63
#define UVD_HEVC_LEVEL_3 90
#define UVD_HEVC_LEVEL_3_1 93
#define UVD_HEVC_LEVEL_4 120
#define UVD_HEVC_LEVEL_4_1 123
#define UVD_HEVC_LEVEL_5 150
#define UVD_HEVC_LEVEL_5_1 153
#define UVD_HEVC_LEVEL_5_2 156
#define UVD_HEVC_LEVEL_6 180
#define UVD_HEVC_LEVEL_6_1 183
#define UVD_HEVC_LEVEL_6_2 186
#include "pipe/p_video_codec.h"
#include "radeon_video.h"
#include "radeonsi/si_pipe.h"
#include "util/u_memory.h"
#include "util/u_video.h"
#include "vl/vl_video_buffer.h"
static void
radeon_uvd_enc_get_param(struct radeon_uvd_encoder *enc,
struct pipe_h265_enc_picture_desc *pic)
#include <stdio.h>
#define UVD_HEVC_LEVEL_1 30
#define UVD_HEVC_LEVEL_2 60
#define UVD_HEVC_LEVEL_2_1 63
#define UVD_HEVC_LEVEL_3 90
#define UVD_HEVC_LEVEL_3_1 93
#define UVD_HEVC_LEVEL_4 120
#define UVD_HEVC_LEVEL_4_1 123
#define UVD_HEVC_LEVEL_5 150
#define UVD_HEVC_LEVEL_5_1 153
#define UVD_HEVC_LEVEL_5_2 156
#define UVD_HEVC_LEVEL_6 180
#define UVD_HEVC_LEVEL_6_1 183
#define UVD_HEVC_LEVEL_6_2 186
static void radeon_uvd_enc_get_param(struct radeon_uvd_encoder *enc,
struct pipe_h265_enc_picture_desc *pic)
{
enc->enc_pic.picture_type = pic->picture_type;
enc->enc_pic.frame_num = pic->frame_num;
enc->enc_pic.pic_order_cnt = pic->pic_order_cnt;
enc->enc_pic.pic_order_cnt_type = pic->pic_order_cnt_type;
enc->enc_pic.not_referenced = pic->not_referenced;
enc->enc_pic.is_iframe =
(pic->picture_type == PIPE_H265_ENC_PICTURE_TYPE_IDR)
|| (pic->picture_type == PIPE_H265_ENC_PICTURE_TYPE_I);
enc->enc_pic.is_iframe = (pic->picture_type == PIPE_H265_ENC_PICTURE_TYPE_IDR) ||
(pic->picture_type == PIPE_H265_ENC_PICTURE_TYPE_I);
enc->enc_pic.crop_left = 0;
enc->enc_pic.crop_right =
(align(enc->base.width, 16) - enc->base.width) / 2;
enc->enc_pic.crop_right = (align(enc->base.width, 16) - enc->base.width) / 2;
enc->enc_pic.crop_top = 0;
enc->enc_pic.crop_bottom =
(align(enc->base.height, 16) - enc->base.height) / 2;
enc->enc_pic.crop_bottom = (align(enc->base.height, 16) - enc->base.height) / 2;
enc->enc_pic.general_tier_flag = pic->seq.general_tier_flag;
enc->enc_pic.general_profile_idc = pic->seq.general_profile_idc;
enc->enc_pic.general_level_idc = pic->seq.general_level_idc;
enc->enc_pic.max_poc =
MAX2(16, util_next_power_of_two(pic->seq.intra_period));
enc->enc_pic.max_poc = MAX2(16, util_next_power_of_two(pic->seq.intra_period));
enc->enc_pic.log2_max_poc = 0;
for (int i = enc->enc_pic.max_poc; i != 0; enc->enc_pic.log2_max_poc++)
i = (i >> 1);
enc->enc_pic.chroma_format_idc = pic->seq.chroma_format_idc;
enc->enc_pic.pic_width_in_luma_samples =
pic->seq.pic_width_in_luma_samples;
enc->enc_pic.pic_height_in_luma_samples =
pic->seq.pic_height_in_luma_samples;
enc->enc_pic.pic_width_in_luma_samples = pic->seq.pic_width_in_luma_samples;
enc->enc_pic.pic_height_in_luma_samples = pic->seq.pic_height_in_luma_samples;
enc->enc_pic.log2_diff_max_min_luma_coding_block_size =
pic->seq.log2_diff_max_min_luma_coding_block_size;
enc->enc_pic.log2_min_transform_block_size_minus2 =
pic->seq.log2_min_transform_block_size_minus2;
enc->enc_pic.log2_diff_max_min_transform_block_size =
pic->seq.log2_diff_max_min_transform_block_size;
enc->enc_pic.max_transform_hierarchy_depth_inter =
pic->seq.max_transform_hierarchy_depth_inter;
enc->enc_pic.max_transform_hierarchy_depth_intra =
pic->seq.max_transform_hierarchy_depth_intra;
enc->enc_pic.log2_parallel_merge_level_minus2 =
pic->pic.log2_parallel_merge_level_minus2;
enc->enc_pic.max_transform_hierarchy_depth_inter = pic->seq.max_transform_hierarchy_depth_inter;
enc->enc_pic.max_transform_hierarchy_depth_intra = pic->seq.max_transform_hierarchy_depth_intra;
enc->enc_pic.log2_parallel_merge_level_minus2 = pic->pic.log2_parallel_merge_level_minus2;
enc->enc_pic.bit_depth_luma_minus8 = pic->seq.bit_depth_luma_minus8;
enc->enc_pic.bit_depth_chroma_minus8 = pic->seq.bit_depth_chroma_minus8;
enc->enc_pic.nal_unit_type = pic->pic.nal_unit_type;
enc->enc_pic.max_num_merge_cand = pic->slice.max_num_merge_cand;
enc->enc_pic.sample_adaptive_offset_enabled_flag =
pic->seq.sample_adaptive_offset_enabled_flag;
enc->enc_pic.pcm_enabled_flag = 0; /*HW not support PCM */
enc->enc_pic.sps_temporal_mvp_enabled_flag =
pic->seq.sps_temporal_mvp_enabled_flag;
enc->enc_pic.sample_adaptive_offset_enabled_flag = pic->seq.sample_adaptive_offset_enabled_flag;
enc->enc_pic.pcm_enabled_flag = 0; /*HW not support PCM */
enc->enc_pic.sps_temporal_mvp_enabled_flag = pic->seq.sps_temporal_mvp_enabled_flag;
}
static void
flush(struct radeon_uvd_encoder *enc)
static void flush(struct radeon_uvd_encoder *enc)
{
enc->ws->cs_flush(enc->cs, PIPE_FLUSH_ASYNC, NULL);
}
static void
radeon_uvd_enc_flush(struct pipe_video_codec *encoder)
static void radeon_uvd_enc_flush(struct pipe_video_codec *encoder)
{
struct radeon_uvd_encoder *enc = (struct radeon_uvd_encoder *) encoder;
struct radeon_uvd_encoder *enc = (struct radeon_uvd_encoder *)encoder;
flush(enc);
}
static void
radeon_uvd_enc_cs_flush(void *ctx, unsigned flags,
struct pipe_fence_handle **fence)
static void radeon_uvd_enc_cs_flush(void *ctx, unsigned flags, struct pipe_fence_handle **fence)
{
// just ignored
}
static unsigned
get_cpb_num(struct radeon_uvd_encoder *enc)
static unsigned get_cpb_num(struct radeon_uvd_encoder *enc)
{
unsigned w = align(enc->base.width, 16) / 16;
unsigned h = align(enc->base.height, 16) / 16;
@ -176,16 +157,14 @@ get_cpb_num(struct radeon_uvd_encoder *enc)
return MIN2(dpb / (w * h), 16);
}
static void
radeon_uvd_enc_begin_frame(struct pipe_video_codec *encoder,
struct pipe_video_buffer *source,
struct pipe_picture_desc *picture)
static void radeon_uvd_enc_begin_frame(struct pipe_video_codec *encoder,
struct pipe_video_buffer *source,
struct pipe_picture_desc *picture)
{
struct radeon_uvd_encoder *enc = (struct radeon_uvd_encoder *) encoder;
struct vl_video_buffer *vid_buf = (struct vl_video_buffer *) source;
struct radeon_uvd_encoder *enc = (struct radeon_uvd_encoder *)encoder;
struct vl_video_buffer *vid_buf = (struct vl_video_buffer *)source;
radeon_uvd_enc_get_param(enc,
(struct pipe_h265_enc_picture_desc *) picture);
radeon_uvd_enc_get_param(enc, (struct pipe_h265_enc_picture_desc *)picture);
enc->get_buffer(vid_buf->resources[0], &enc->handle, &enc->luma);
enc->get_buffer(vid_buf->resources[1], NULL, &enc->chroma);
@ -196,8 +175,7 @@ radeon_uvd_enc_begin_frame(struct pipe_video_codec *encoder,
struct rvid_buffer fb;
enc->stream_handle = si_vid_alloc_stream_handle();
enc->si = CALLOC_STRUCT(rvid_buffer);
si_vid_create_buffer(enc->screen, enc->si, 128 * 1024,
PIPE_USAGE_STAGING);
si_vid_create_buffer(enc->screen, enc->si, 128 * 1024, PIPE_USAGE_STAGING);
si_vid_create_buffer(enc->screen, &fb, 4096, PIPE_USAGE_STAGING);
enc->fb = &fb;
enc->begin(enc, picture);
@ -206,12 +184,11 @@ radeon_uvd_enc_begin_frame(struct pipe_video_codec *encoder,
}
}
static void
radeon_uvd_enc_encode_bitstream(struct pipe_video_codec *encoder,
struct pipe_video_buffer *source,
struct pipe_resource *destination, void **fb)
static void radeon_uvd_enc_encode_bitstream(struct pipe_video_codec *encoder,
struct pipe_video_buffer *source,
struct pipe_resource *destination, void **fb)
{
struct radeon_uvd_encoder *enc = (struct radeon_uvd_encoder *) encoder;
struct radeon_uvd_encoder *enc = (struct radeon_uvd_encoder *)encoder;
enc->get_buffer(destination, &enc->bs_handle, NULL);
enc->bs_size = destination->width0;
@ -226,19 +203,17 @@ radeon_uvd_enc_encode_bitstream(struct pipe_video_codec *encoder,
enc->encode(enc);
}
static void
radeon_uvd_enc_end_frame(struct pipe_video_codec *encoder,
struct pipe_video_buffer *source,
struct pipe_picture_desc *picture)
static void radeon_uvd_enc_end_frame(struct pipe_video_codec *encoder,
struct pipe_video_buffer *source,
struct pipe_picture_desc *picture)
{
struct radeon_uvd_encoder *enc = (struct radeon_uvd_encoder *) encoder;
struct radeon_uvd_encoder *enc = (struct radeon_uvd_encoder *)encoder;
flush(enc);
}
static void
radeon_uvd_enc_destroy(struct pipe_video_codec *encoder)
static void radeon_uvd_enc_destroy(struct pipe_video_codec *encoder)
{
struct radeon_uvd_encoder *enc = (struct radeon_uvd_encoder *) encoder;
struct radeon_uvd_encoder *enc = (struct radeon_uvd_encoder *)encoder;
if (enc->stream_handle) {
struct rvid_buffer fb;
@ -255,18 +230,15 @@ radeon_uvd_enc_destroy(struct pipe_video_codec *encoder)
FREE(enc);
}
static void
radeon_uvd_enc_get_feedback(struct pipe_video_codec *encoder,
void *feedback, unsigned *size)
static void radeon_uvd_enc_get_feedback(struct pipe_video_codec *encoder, void *feedback,
unsigned *size)
{
struct radeon_uvd_encoder *enc = (struct radeon_uvd_encoder *) encoder;
struct radeon_uvd_encoder *enc = (struct radeon_uvd_encoder *)encoder;
struct rvid_buffer *fb = feedback;
if (NULL != size) {
radeon_uvd_enc_feedback_t *fb_data =
(radeon_uvd_enc_feedback_t *) enc->ws->buffer_map(
fb->res->buf, enc->cs,
PIPE_TRANSFER_READ_WRITE | RADEON_TRANSFER_TEMPORARY);
radeon_uvd_enc_feedback_t *fb_data = (radeon_uvd_enc_feedback_t *)enc->ws->buffer_map(
fb->res->buf, enc->cs, PIPE_TRANSFER_READ_WRITE | RADEON_TRANSFER_TEMPORARY);
if (!fb_data->status)
*size = fb_data->bitstream_size;
@ -279,16 +251,15 @@ radeon_uvd_enc_get_feedback(struct pipe_video_codec *encoder,
FREE(fb);
}
struct pipe_video_codec *
radeon_uvd_create_encoder(struct pipe_context *context,
const struct pipe_video_codec *templ,
struct radeon_winsys *ws,
radeon_uvd_enc_get_buffer get_buffer)
struct pipe_video_codec *radeon_uvd_create_encoder(struct pipe_context *context,
const struct pipe_video_codec *templ,
struct radeon_winsys *ws,
radeon_uvd_enc_get_buffer get_buffer)
{
struct si_screen *sscreen = (struct si_screen *) context->screen;
struct si_context *sctx = (struct si_context *) context;
struct si_screen *sscreen = (struct si_screen *)context->screen;
struct si_context *sctx = (struct si_context *)context;
struct radeon_uvd_encoder *enc;
struct pipe_video_buffer *tmp_buf, templat = { };
struct pipe_video_buffer *tmp_buf, templat = {};
struct radeon_surf *tmp_surf;
unsigned cpb_size;
@ -314,8 +285,7 @@ radeon_uvd_create_encoder(struct pipe_context *context,
enc->bits_in_shifter = 0;
enc->screen = context->screen;
enc->ws = ws;
enc->cs =
ws->cs_create(sctx->ctx, RING_UVD_ENC, radeon_uvd_enc_cs_flush, enc, false);
enc->cs = ws->cs_create(sctx->ctx, RING_UVD_ENC, radeon_uvd_enc_cs_flush, enc, false);
if (!enc->cs) {
RVID_ERR("Can't get command submission context.\n");
@ -341,21 +311,19 @@ radeon_uvd_create_encoder(struct pipe_context *context,
if (!enc->cpb_num)
goto error;
get_buffer(((struct vl_video_buffer *) tmp_buf)->resources[0], NULL,
&tmp_surf);
get_buffer(((struct vl_video_buffer *)tmp_buf)->resources[0], NULL, &tmp_surf);
cpb_size = (sscreen->info.chip_class < GFX9) ?
align(tmp_surf->u.legacy.level[0].nblk_x * tmp_surf->bpe, 128) *
align(tmp_surf->u.legacy.level[0].nblk_y, 32) :
align(tmp_surf->u.gfx9.surf_pitch * tmp_surf->bpe, 256) *
align(tmp_surf->u.gfx9.surf_height, 32);
cpb_size = (sscreen->info.chip_class < GFX9)
? align(tmp_surf->u.legacy.level[0].nblk_x * tmp_surf->bpe, 128) *
align(tmp_surf->u.legacy.level[0].nblk_y, 32)
: align(tmp_surf->u.gfx9.surf_pitch * tmp_surf->bpe, 256) *
align(tmp_surf->u.gfx9.surf_height, 32);
cpb_size = cpb_size * 3 / 2;
cpb_size = cpb_size * enc->cpb_num;
tmp_buf->destroy(tmp_buf);
if (!si_vid_create_buffer
(enc->screen, &enc->cpb, cpb_size, PIPE_USAGE_DEFAULT)) {
if (!si_vid_create_buffer(enc->screen, &enc->cpb, cpb_size, PIPE_USAGE_DEFAULT)) {
RVID_ERR("Can't create CPB buffer.\n");
goto error;
}
@ -364,7 +332,7 @@ radeon_uvd_create_encoder(struct pipe_context *context,
return &enc->base;
error:
error:
if (enc->cs)
enc->ws->cs_destroy(enc->cs);
@ -374,8 +342,7 @@ radeon_uvd_create_encoder(struct pipe_context *context,
return NULL;
}
bool
si_radeon_uvd_enc_supported(struct si_screen * sscreen)
bool si_radeon_uvd_enc_supported(struct si_screen *sscreen)
{
return (sscreen->info.uvd_enc_supported);
}

View File

@ -30,106 +30,105 @@
#include "radeon_video.h"
#define RENC_UVD_FW_INTERFACE_MAJOR_VERSION 1
#define RENC_UVD_FW_INTERFACE_MINOR_VERSION 1
#define RENC_UVD_FW_INTERFACE_MAJOR_VERSION 1
#define RENC_UVD_FW_INTERFACE_MINOR_VERSION 1
#define RENC_UVD_IB_PARAM_SESSION_INFO 0x00000001
#define RENC_UVD_IB_PARAM_TASK_INFO 0x00000002
#define RENC_UVD_IB_PARAM_SESSION_INIT 0x00000003
#define RENC_UVD_IB_PARAM_LAYER_CONTROL 0x00000004
#define RENC_UVD_IB_PARAM_LAYER_SELECT 0x00000005
#define RENC_UVD_IB_PARAM_SLICE_CONTROL 0x00000006
#define RENC_UVD_IB_PARAM_SPEC_MISC 0x00000007
#define RENC_UVD_IB_PARAM_RATE_CONTROL_SESSION_INIT 0x00000008
#define RENC_UVD_IB_PARAM_RATE_CONTROL_LAYER_INIT 0x00000009
#define RENC_UVD_IB_PARAM_RATE_CONTROL_PER_PICTURE 0x0000000a
#define RENC_UVD_IB_PARAM_SLICE_HEADER 0x0000000b
#define RENC_UVD_IB_PARAM_ENCODE_PARAMS 0x0000000c
#define RENC_UVD_IB_PARAM_QUALITY_PARAMS 0x0000000d
#define RENC_UVD_IB_PARAM_DEBLOCKING_FILTER 0x0000000e
#define RENC_UVD_IB_PARAM_INTRA_REFRESH 0x0000000f
#define RENC_UVD_IB_PARAM_ENCODE_CONTEXT_BUFFER 0x00000010
#define RENC_UVD_IB_PARAM_VIDEO_BITSTREAM_BUFFER 0x00000011
#define RENC_UVD_IB_PARAM_FEEDBACK_BUFFER 0x00000012
#define RENC_UVD_IB_PARAM_INSERT_NALU_BUFFER 0x00000013
#define RENC_UVD_IB_PARAM_FEEDBACK_BUFFER_ADDITIONAL 0x00000014
#define RENC_UVD_IB_PARAM_SESSION_INFO 0x00000001
#define RENC_UVD_IB_PARAM_TASK_INFO 0x00000002
#define RENC_UVD_IB_PARAM_SESSION_INIT 0x00000003
#define RENC_UVD_IB_PARAM_LAYER_CONTROL 0x00000004
#define RENC_UVD_IB_PARAM_LAYER_SELECT 0x00000005
#define RENC_UVD_IB_PARAM_SLICE_CONTROL 0x00000006
#define RENC_UVD_IB_PARAM_SPEC_MISC 0x00000007
#define RENC_UVD_IB_PARAM_RATE_CONTROL_SESSION_INIT 0x00000008
#define RENC_UVD_IB_PARAM_RATE_CONTROL_LAYER_INIT 0x00000009
#define RENC_UVD_IB_PARAM_RATE_CONTROL_PER_PICTURE 0x0000000a
#define RENC_UVD_IB_PARAM_SLICE_HEADER 0x0000000b
#define RENC_UVD_IB_PARAM_ENCODE_PARAMS 0x0000000c
#define RENC_UVD_IB_PARAM_QUALITY_PARAMS 0x0000000d
#define RENC_UVD_IB_PARAM_DEBLOCKING_FILTER 0x0000000e
#define RENC_UVD_IB_PARAM_INTRA_REFRESH 0x0000000f
#define RENC_UVD_IB_PARAM_ENCODE_CONTEXT_BUFFER 0x00000010
#define RENC_UVD_IB_PARAM_VIDEO_BITSTREAM_BUFFER 0x00000011
#define RENC_UVD_IB_PARAM_FEEDBACK_BUFFER 0x00000012
#define RENC_UVD_IB_PARAM_INSERT_NALU_BUFFER 0x00000013
#define RENC_UVD_IB_PARAM_FEEDBACK_BUFFER_ADDITIONAL 0x00000014
#define RENC_UVD_IB_OP_INITIALIZE 0x08000001
#define RENC_UVD_IB_OP_CLOSE_SESSION 0x08000002
#define RENC_UVD_IB_OP_ENCODE 0x08000003
#define RENC_UVD_IB_OP_INIT_RC 0x08000004
#define RENC_UVD_IB_OP_INIT_RC_VBV_BUFFER_LEVEL 0x08000005
#define RENC_UVD_IB_OP_SET_SPEED_ENCODING_MODE 0x08000006
#define RENC_UVD_IB_OP_SET_BALANCE_ENCODING_MODE 0x08000007
#define RENC_UVD_IB_OP_SET_QUALITY_ENCODING_MODE 0x08000008
#define RENC_UVD_IB_OP_INITIALIZE 0x08000001
#define RENC_UVD_IB_OP_CLOSE_SESSION 0x08000002
#define RENC_UVD_IB_OP_ENCODE 0x08000003
#define RENC_UVD_IB_OP_INIT_RC 0x08000004
#define RENC_UVD_IB_OP_INIT_RC_VBV_BUFFER_LEVEL 0x08000005
#define RENC_UVD_IB_OP_SET_SPEED_ENCODING_MODE 0x08000006
#define RENC_UVD_IB_OP_SET_BALANCE_ENCODING_MODE 0x08000007
#define RENC_UVD_IB_OP_SET_QUALITY_ENCODING_MODE 0x08000008
#define RENC_UVD_IF_MAJOR_VERSION_MASK 0xFFFF0000
#define RENC_UVD_IF_MAJOR_VERSION_SHIFT 16
#define RENC_UVD_IF_MINOR_VERSION_MASK 0x0000FFFF
#define RENC_UVD_IF_MINOR_VERSION_SHIFT 0
#define RENC_UVD_IF_MAJOR_VERSION_MASK 0xFFFF0000
#define RENC_UVD_IF_MAJOR_VERSION_SHIFT 16
#define RENC_UVD_IF_MINOR_VERSION_MASK 0x0000FFFF
#define RENC_UVD_IF_MINOR_VERSION_SHIFT 0
#define RENC_UVD_PREENCODE_MODE_NONE 0x00000000
#define RENC_UVD_PREENCODE_MODE_1X 0x00000001
#define RENC_UVD_PREENCODE_MODE_2X 0x00000002
#define RENC_UVD_PREENCODE_MODE_4X 0x00000004
#define RENC_UVD_PREENCODE_MODE_NONE 0x00000000
#define RENC_UVD_PREENCODE_MODE_1X 0x00000001
#define RENC_UVD_PREENCODE_MODE_2X 0x00000002
#define RENC_UVD_PREENCODE_MODE_4X 0x00000004
#define RENC_UVD_SLICE_CONTROL_MODE_FIXED_CTBS 0x00000000
#define RENC_UVD_SLICE_CONTROL_MODE_FIXED_BITS 0x00000001
#define RENC_UVD_SLICE_CONTROL_MODE_FIXED_CTBS 0x00000000
#define RENC_UVD_SLICE_CONTROL_MODE_FIXED_BITS 0x00000001
#define RENC_UVD_RATE_CONTROL_METHOD_NONE 0x00000000
#define RENC_UVD_RATE_CONTROL_METHOD_LATENCY_CONSTRAINED_VBR 0x00000001
#define RENC_UVD_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR 0x00000002
#define RENC_UVD_RATE_CONTROL_METHOD_CBR 0x00000003
#define RENC_UVD_RATE_CONTROL_METHOD_NONE 0x00000000
#define RENC_UVD_RATE_CONTROL_METHOD_LATENCY_CONSTRAINED_VBR 0x00000001
#define RENC_UVD_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR 0x00000002
#define RENC_UVD_RATE_CONTROL_METHOD_CBR 0x00000003
#define RENC_UVD_NALU_TYPE_AUD 0x00000001
#define RENC_UVD_NALU_TYPE_VPS 0x00000002
#define RENC_UVD_NALU_TYPE_SPS 0x00000003
#define RENC_UVD_NALU_TYPE_PPS 0x00000004
#define RENC_UVD_NALU_TYPE_END_OF_SEQUENCE 0x00000005
#define RENC_UVD_NALU_TYPE_AUD 0x00000001
#define RENC_UVD_NALU_TYPE_VPS 0x00000002
#define RENC_UVD_NALU_TYPE_SPS 0x00000003
#define RENC_UVD_NALU_TYPE_PPS 0x00000004
#define RENC_UVD_NALU_TYPE_END_OF_SEQUENCE 0x00000005
#define RENC_UVD_SLICE_HEADER_TEMPLATE_MAX_TEMPLATE_SIZE_IN_DWORDS 16
#define RENC_UVD_SLICE_HEADER_TEMPLATE_MAX_NUM_INSTRUCTIONS 16
#define RENC_UVD_SLICE_HEADER_TEMPLATE_MAX_TEMPLATE_SIZE_IN_DWORDS 16
#define RENC_UVD_SLICE_HEADER_TEMPLATE_MAX_NUM_INSTRUCTIONS 16
#define RENC_UVD_HEADER_INSTRUCTION_END 0
#define RENC_UVD_HEADER_INSTRUCTION_DEPENDENT_SLICE_END 1
#define RENC_UVD_HEADER_INSTRUCTION_COPY 2
#define RENC_UVD_HEADER_INSTRUCTION_FIRST_SLICE 3
#define RENC_UVD_HEADER_INSTRUCTION_SLICE_SEGMENT 4
#define RENC_UVD_HEADER_INSTRUCTION_SLICE_QP_DELTA 5
#define RENC_UVD_HEADER_INSTRUCTION_END 0
#define RENC_UVD_HEADER_INSTRUCTION_DEPENDENT_SLICE_END 1
#define RENC_UVD_HEADER_INSTRUCTION_COPY 2
#define RENC_UVD_HEADER_INSTRUCTION_FIRST_SLICE 3
#define RENC_UVD_HEADER_INSTRUCTION_SLICE_SEGMENT 4
#define RENC_UVD_HEADER_INSTRUCTION_SLICE_QP_DELTA 5
#define RENC_UVD_PICTURE_TYPE_B 0
#define RENC_UVD_PICTURE_TYPE_P 1
#define RENC_UVD_PICTURE_TYPE_I 2
#define RENC_UVD_PICTURE_TYPE_P_SKIP 3
#define RENC_UVD_PICTURE_TYPE_B 0
#define RENC_UVD_PICTURE_TYPE_P 1
#define RENC_UVD_PICTURE_TYPE_I 2
#define RENC_UVD_PICTURE_TYPE_P_SKIP 3
#define RENC_UVD_SWIZZLE_MODE_LINEAR 0
#define RENC_UVD_SWIZZLE_MODE_256B_D 2
#define RENC_UVD_SWIZZLE_MODE_4kB_D 6
#define RENC_UVD_SWIZZLE_MODE_64kB_D 10
#define RENC_UVD_INTRA_REFRESH_MODE_NONE 0
#define RENC_UVD_INTRA_REFRESH_MODE_CTB_MB_ROWS 1
#define RENC_UVD_INTRA_REFRESH_MODE_CTB_MB_COLUMNS 2
#define RENC_UVD_SWIZZLE_MODE_LINEAR 0
#define RENC_UVD_SWIZZLE_MODE_256B_D 2
#define RENC_UVD_SWIZZLE_MODE_4kB_D 6
#define RENC_UVD_SWIZZLE_MODE_64kB_D 10
#define RENC_UVD_INTRA_REFRESH_MODE_NONE 0
#define RENC_UVD_INTRA_REFRESH_MODE_CTB_MB_ROWS 1
#define RENC_UVD_INTRA_REFRESH_MODE_CTB_MB_COLUMNS 2
#define RENC_UVD_MAX_NUM_RECONSTRUCTED_PICTURES 34
#define RENC_UVD_ADDR_MODE_LINEAR 0
#define RENC_UVD_ADDR_MODE_PELE_8X8_1D 1
#define RENC_UVD_ADDR_MODE_32AS8_88 2
#define RENC_UVD_MAX_NUM_RECONSTRUCTED_PICTURES 34
#define RENC_UVD_ADDR_MODE_LINEAR 0
#define RENC_UVD_ADDR_MODE_PELE_8X8_1D 1
#define RENC_UVD_ADDR_MODE_32AS8_88 2
#define RENC_UVD_ARRAY_MODE_LINEAR 0
#define RENC_UVD_ARRAY_MODE_PELE_8X8_1D 2
#define RENC_UVD_ARRAY_MODE_2D_TILED_THIN1 4
#define RENC_UVD_ARRAY_MODE_LINEAR 0
#define RENC_UVD_ARRAY_MODE_PELE_8X8_1D 2
#define RENC_UVD_ARRAY_MODE_2D_TILED_THIN1 4
#define RENC_UVD_VIDEO_BITSTREAM_BUFFER_MODE_LINEAR 0
#define RENC_UVD_VIDEO_BITSTREAM_BUFFER_MODE_CIRCULAR 1
#define RENC_UVD_VIDEO_BITSTREAM_BUFFER_MODE_LINEAR 0
#define RENC_UVD_VIDEO_BITSTREAM_BUFFER_MODE_CIRCULAR 1
#define RENC_UVD_FEEDBACK_BUFFER_MODE_LINEAR 0
#define RENC_UVD_FEEDBACK_BUFFER_MODE_CIRCULAR 1
#define RENC_UVD_FEEDBACK_BUFFER_MODE_LINEAR 0
#define RENC_UVD_FEEDBACK_BUFFER_MODE_CIRCULAR 1
#define RENC_UVD_FEEDBACK_STATUS_OK 0x00000000
#define RENC_UVD_FEEDBACK_STATUS_NOT_ENCODED 0x10000001
#define RENC_UVD_FEEDBACK_STATUS_OK 0x00000000
#define RENC_UVD_FEEDBACK_STATUS_NOT_ENCODED 0x10000001
typedef struct radeon_uvd_enc_feedback_s
{
typedef struct radeon_uvd_enc_feedback_s {
uint32_t task_id;
uint32_t first_in_task;
uint32_t last_in_task;
@ -142,23 +141,20 @@ typedef struct radeon_uvd_enc_feedback_s
uint32_t extra_bytes;
} radeon_uvd_enc_feedback_t;
typedef struct ruvd_enc_session_info_s
{
typedef struct ruvd_enc_session_info_s {
uint32_t reserved;
uint32_t interface_version;
uint32_t sw_context_address_hi;
uint32_t sw_context_address_lo;
} ruvd_enc_session_info_t;
typedef struct ruvd_enc_task_info_s
{
typedef struct ruvd_enc_task_info_s {
uint32_t total_size_of_all_packages;
uint32_t task_id;
uint32_t allowed_max_num_feedbacks;
} ruvd_enc_task_info_t;
typedef struct ruvd_enc_session_init_s
{
typedef struct ruvd_enc_session_init_s {
uint32_t aligned_picture_width;
uint32_t aligned_picture_height;
uint32_t padding_width;
@ -167,38 +163,31 @@ typedef struct ruvd_enc_session_init_s
uint32_t pre_encode_chroma_enabled;
} ruvd_enc_session_init_t;
typedef struct ruvd_enc_layer_control_s
{
typedef struct ruvd_enc_layer_control_s {
uint32_t max_num_temporal_layers;
uint32_t num_temporal_layers;
} ruvd_enc_layer_control_t;
typedef struct ruvd_enc_layer_select_s
{
typedef struct ruvd_enc_layer_select_s {
uint32_t temporal_layer_index;
} ruvd_enc_layer_select_t;
typedef struct ruvd_enc_hevc_slice_control_s
{
typedef struct ruvd_enc_hevc_slice_control_s {
uint32_t slice_control_mode;
union
{
struct
{
union {
struct {
uint32_t num_ctbs_per_slice;
uint32_t num_ctbs_per_slice_segment;
} fixed_ctbs_per_slice;
struct
{
struct {
uint32_t num_bits_per_slice;
uint32_t num_bits_per_slice_segment;
} fixed_bits_per_slice;
};
} ruvd_enc_hevc_slice_control_t;
typedef struct ruvd_enc_hevc_spec_misc_s
{
typedef struct ruvd_enc_hevc_spec_misc_s {
uint32_t log2_min_luma_coding_block_size_minus3;
uint32_t amp_disabled;
uint32_t strong_intra_smoothing_enabled;
@ -208,14 +197,12 @@ typedef struct ruvd_enc_hevc_spec_misc_s
uint32_t quarter_pel_enabled;
} ruvd_enc_hevc_spec_misc_t;
typedef struct ruvd_enc_rate_ctl_session_init_s
{
typedef struct ruvd_enc_rate_ctl_session_init_s {
uint32_t rate_control_method;
uint32_t vbv_buffer_level;
} ruvd_enc_rate_ctl_session_init_t;
typedef struct ruvd_enc_rate_ctl_layer_init_s
{
typedef struct ruvd_enc_rate_ctl_layer_init_s {
uint32_t target_bit_rate;
uint32_t peak_bit_rate;
uint32_t frame_rate_num;
@ -226,8 +213,7 @@ typedef struct ruvd_enc_rate_ctl_layer_init_s
uint32_t peak_bits_per_picture_fractional;
} ruvd_enc_rate_ctl_layer_init_t;
typedef struct ruvd_enc_rate_ctl_per_picture_s
{
typedef struct ruvd_enc_rate_ctl_per_picture_s {
uint32_t qp;
uint32_t min_qp_app;
uint32_t max_qp_app;
@ -237,34 +223,27 @@ typedef struct ruvd_enc_rate_ctl_per_picture_s
uint32_t enforce_hrd;
} ruvd_enc_rate_ctl_per_picture_t;
typedef struct ruvd_enc_quality_params_s
{
typedef struct ruvd_enc_quality_params_s {
uint32_t vbaq_mode;
uint32_t scene_change_sensitivity;
uint32_t scene_change_min_idr_interval;
} ruvd_enc_quality_params_t;
typedef struct ruvd_enc_direct_output_nalu_s
{
typedef struct ruvd_enc_direct_output_nalu_s {
uint32_t type;
uint32_t size;
uint32_t data[1];
} ruvd_enc_direct_output_nalu_t;
typedef struct ruvd_enc_slice_header_s
{
uint32_t
bitstream_template
[RENC_UVD_SLICE_HEADER_TEMPLATE_MAX_TEMPLATE_SIZE_IN_DWORDS];
struct
{
typedef struct ruvd_enc_slice_header_s {
uint32_t bitstream_template[RENC_UVD_SLICE_HEADER_TEMPLATE_MAX_TEMPLATE_SIZE_IN_DWORDS];
struct {
uint32_t instruction;
uint32_t num_bits;
} instructions[RENC_UVD_SLICE_HEADER_TEMPLATE_MAX_NUM_INSTRUCTIONS];
} ruvd_enc_slice_header_t;
typedef struct ruvd_enc_encode_params_s
{
typedef struct ruvd_enc_encode_params_s {
uint32_t pic_type;
uint32_t allowed_max_bitstream_size;
uint32_t input_picture_luma_address_hi;
@ -273,13 +252,11 @@ typedef struct ruvd_enc_encode_params_s
uint32_t input_picture_chroma_address_lo;
uint32_t input_pic_luma_pitch;
uint32_t input_pic_chroma_pitch;
union
{
union {
uint32_t input_pic_addr_mode;
uint32_t reserved;
};
union
{
union {
uint32_t input_pic_array_mode;
uint32_t input_pic_swizzle_mode;
};
@ -287,8 +264,7 @@ typedef struct ruvd_enc_encode_params_s
uint32_t reconstructed_picture_index;
} ruvd_enc_encode_params_t;
typedef struct ruvd_enc_hevc_deblocking_filter_s
{
typedef struct ruvd_enc_hevc_deblocking_filter_s {
uint32_t loop_filter_across_slices_enabled;
int32_t deblocking_filter_disabled;
int32_t beta_offset_div2;
@ -297,48 +273,40 @@ typedef struct ruvd_enc_hevc_deblocking_filter_s
int32_t cr_qp_offset;
} ruvd_enc_hevc_deblocking_filter_t;
typedef struct ruvd_enc_intra_refresh_s
{
typedef struct ruvd_enc_intra_refresh_s {
uint32_t intra_refresh_mode;
uint32_t offset;
uint32_t region_size;
} ruvd_enc_intra_refresh_t;
typedef struct ruvd_enc_reconstructed_picture_s
{
typedef struct ruvd_enc_reconstructed_picture_s {
uint32_t luma_offset;
uint32_t chroma_offset;
} ruvd_enc_reconstructed_picture_t;
typedef struct ruvd_enc_encode_context_buffer_s
{
typedef struct ruvd_enc_encode_context_buffer_s {
uint32_t encode_context_address_hi;
uint32_t encode_context_address_lo;
union
{
union {
uint32_t addr_mode;
uint32_t reserved;
};
union
{
union {
uint32_t array_mode;
uint32_t swizzle_mode;
};
uint32_t rec_luma_pitch;
uint32_t rec_chroma_pitch;
uint32_t num_reconstructed_pictures;
ruvd_enc_reconstructed_picture_t
reconstructed_pictures[RENC_UVD_MAX_NUM_RECONSTRUCTED_PICTURES];
ruvd_enc_reconstructed_picture_t reconstructed_pictures[RENC_UVD_MAX_NUM_RECONSTRUCTED_PICTURES];
uint32_t pre_encode_picture_luma_pitch;
uint32_t pre_encode_picture_chroma_pitch;
ruvd_enc_reconstructed_picture_t
pre_encode_reconstructed_pictures
[RENC_UVD_MAX_NUM_RECONSTRUCTED_PICTURES];
pre_encode_reconstructed_pictures[RENC_UVD_MAX_NUM_RECONSTRUCTED_PICTURES];
ruvd_enc_reconstructed_picture_t pre_encode_input_picture;
} ruvd_enc_encode_context_buffer_t;
typedef struct ruvd_enc_video_bitstream_buffer_s
{
typedef struct ruvd_enc_video_bitstream_buffer_s {
uint32_t mode;
uint32_t video_bitstream_buffer_address_hi;
uint32_t video_bitstream_buffer_address_lo;
@ -346,8 +314,7 @@ typedef struct ruvd_enc_video_bitstream_buffer_s
uint32_t video_bitstream_data_offset;
} ruvd_enc_video_bitstream_buffer_t;
typedef struct ruvd_enc_feedback_buffer_s
{
typedef struct ruvd_enc_feedback_buffer_s {
uint32_t mode;
uint32_t feedback_buffer_address_hi;
uint32_t feedback_buffer_address_lo;
@ -355,20 +322,15 @@ typedef struct ruvd_enc_feedback_buffer_s
uint32_t feedback_data_size;
} ruvd_enc_feedback_buffer_t;
typedef void (*radeon_uvd_enc_get_buffer) (struct pipe_resource * resource,
struct pb_buffer ** handle,
struct radeon_surf ** surface);
typedef void (*radeon_uvd_enc_get_buffer)(struct pipe_resource *resource, struct pb_buffer **handle,
struct radeon_surf **surface);
struct pipe_video_codec *radeon_uvd_create_encoder(struct pipe_context
*context,
const struct
pipe_video_codec *templat,
struct pipe_video_codec *radeon_uvd_create_encoder(struct pipe_context *context,
const struct pipe_video_codec *templat,
struct radeon_winsys *ws,
radeon_uvd_enc_get_buffer
get_buffer);
radeon_uvd_enc_get_buffer get_buffer);
struct radeon_uvd_enc_pic
{
struct radeon_uvd_enc_pic {
enum pipe_h265_enc_picture_type picture_type;
unsigned frame_num;
@ -422,14 +384,12 @@ struct radeon_uvd_enc_pic
ruvd_enc_encode_params_t enc_params;
};
struct radeon_uvd_encoder
{
struct radeon_uvd_encoder {
struct pipe_video_codec base;
void (*begin) (struct radeon_uvd_encoder * enc,
struct pipe_picture_desc * pic);
void (*encode) (struct radeon_uvd_encoder * enc);
void (*destroy) (struct radeon_uvd_encoder * enc);
void (*begin)(struct radeon_uvd_encoder *enc, struct pipe_picture_desc *pic);
void (*encode)(struct radeon_uvd_encoder *enc);
void (*destroy)(struct radeon_uvd_encoder *enc);
unsigned stream_handle;

View File

@ -25,37 +25,39 @@
*
**************************************************************************/
#include "pipe/p_video_codec.h"
#include "radeon_uvd_enc.h"
#include "radeon_video.h"
#include "radeonsi/si_pipe.h"
#include "util/u_memory.h"
#include "util/u_video.h"
#include "vl/vl_video_buffer.h"
#include <stdio.h>
#include "pipe/p_video_codec.h"
#include "util/u_video.h"
#include "util/u_memory.h"
#include "vl/vl_video_buffer.h"
#include "radeonsi/si_pipe.h"
#include "radeon_video.h"
#include "radeon_uvd_enc.h"
#define RADEON_ENC_CS(value) (enc->cs->current.buf[enc->cs->current.cdw++] = (value))
#define RADEON_ENC_BEGIN(cmd) { \
uint32_t *begin = &enc->cs->current.buf[enc->cs->current.cdw++]; \
RADEON_ENC_CS(cmd)
#define RADEON_ENC_READ(buf, domain, off) radeon_uvd_enc_add_buffer(enc, (buf), RADEON_USAGE_READ, (domain), (off))
#define RADEON_ENC_WRITE(buf, domain, off) radeon_uvd_enc_add_buffer(enc, (buf), RADEON_USAGE_WRITE, (domain), (off))
#define RADEON_ENC_READWRITE(buf, domain, off) radeon_uvd_enc_add_buffer(enc, (buf), RADEON_USAGE_READWRITE, (domain), (off))
#define RADEON_ENC_END() *begin = (&enc->cs->current.buf[enc->cs->current.cdw] - begin) * 4; \
enc->total_task_size += *begin;}
#define RADEON_ENC_BEGIN(cmd) \
{ \
uint32_t *begin = &enc->cs->current.buf[enc->cs->current.cdw++]; \
RADEON_ENC_CS(cmd)
#define RADEON_ENC_READ(buf, domain, off) \
radeon_uvd_enc_add_buffer(enc, (buf), RADEON_USAGE_READ, (domain), (off))
#define RADEON_ENC_WRITE(buf, domain, off) \
radeon_uvd_enc_add_buffer(enc, (buf), RADEON_USAGE_WRITE, (domain), (off))
#define RADEON_ENC_READWRITE(buf, domain, off) \
radeon_uvd_enc_add_buffer(enc, (buf), RADEON_USAGE_READWRITE, (domain), (off))
#define RADEON_ENC_END() \
*begin = (&enc->cs->current.buf[enc->cs->current.cdw] - begin) * 4; \
enc->total_task_size += *begin; \
}
static const unsigned index_to_shifts[4] = { 24, 16, 8, 0 };
static const unsigned index_to_shifts[4] = {24, 16, 8, 0};
static void
radeon_uvd_enc_add_buffer(struct radeon_uvd_encoder *enc,
struct pb_buffer *buf, enum radeon_bo_usage usage,
enum radeon_bo_domain domain, signed offset)
static void radeon_uvd_enc_add_buffer(struct radeon_uvd_encoder *enc, struct pb_buffer *buf,
enum radeon_bo_usage usage, enum radeon_bo_domain domain,
signed offset)
{
enc->ws->cs_add_buffer(enc->cs, buf, usage | RADEON_USAGE_SYNCHRONIZED,
domain, 0);
enc->ws->cs_add_buffer(enc->cs, buf, usage | RADEON_USAGE_SYNCHRONIZED, domain, 0);
uint64_t addr;
addr = enc->ws->buffer_get_virtual_address(buf);
addr = addr + offset;
@ -63,9 +65,7 @@ radeon_uvd_enc_add_buffer(struct radeon_uvd_encoder *enc,
RADEON_ENC_CS(addr);
}
static void
radeon_uvd_enc_set_emulation_prevention(struct radeon_uvd_encoder *enc,
bool set)
static void radeon_uvd_enc_set_emulation_prevention(struct radeon_uvd_encoder *enc, bool set)
{
if (set != enc->emulation_prevention) {
enc->emulation_prevention = set;
@ -73,14 +73,12 @@ radeon_uvd_enc_set_emulation_prevention(struct radeon_uvd_encoder *enc,
}
}
static void
radeon_uvd_enc_output_one_byte(struct radeon_uvd_encoder *enc,
unsigned char byte)
static void radeon_uvd_enc_output_one_byte(struct radeon_uvd_encoder *enc, unsigned char byte)
{
if (enc->byte_index == 0)
enc->cs->current.buf[enc->cs->current.cdw] = 0;
enc->cs->current.buf[enc->cs->current.cdw] |=
((unsigned int) (byte) << index_to_shifts[enc->byte_index]);
((unsigned int)(byte) << index_to_shifts[enc->byte_index]);
enc->byte_index++;
if (enc->byte_index >= 4) {
@ -89,14 +87,11 @@ radeon_uvd_enc_output_one_byte(struct radeon_uvd_encoder *enc,
}
}
static void
radeon_uvd_enc_emulation_prevention(struct radeon_uvd_encoder *enc,
unsigned char byte)
static void radeon_uvd_enc_emulation_prevention(struct radeon_uvd_encoder *enc, unsigned char byte)
{
if (enc->emulation_prevention) {
if ((enc->num_zeros >= 2)
&& ((byte == 0x00) || (byte == 0x01)
|| (byte == 0x02) || (byte == 0x03))) {
if ((enc->num_zeros >= 2) &&
((byte == 0x00) || (byte == 0x01) || (byte == 0x02) || (byte == 0x03))) {
radeon_uvd_enc_output_one_byte(enc, 0x03);
enc->bits_output += 8;
enc->num_zeros = 0;
@ -105,28 +100,25 @@ radeon_uvd_enc_emulation_prevention(struct radeon_uvd_encoder *enc,
}
}
static void
radeon_uvd_enc_code_fixed_bits(struct radeon_uvd_encoder *enc,
unsigned int value, unsigned int num_bits)
static void radeon_uvd_enc_code_fixed_bits(struct radeon_uvd_encoder *enc, unsigned int value,
unsigned int num_bits)
{
unsigned int bits_to_pack = 0;
while (num_bits > 0) {
unsigned int value_to_pack = value & (0xffffffff >> (32 - num_bits));
bits_to_pack =
num_bits >
(32 - enc->bits_in_shifter) ? (32 - enc->bits_in_shifter) : num_bits;
num_bits > (32 - enc->bits_in_shifter) ? (32 - enc->bits_in_shifter) : num_bits;
if (bits_to_pack < num_bits)
value_to_pack = value_to_pack >> (num_bits - bits_to_pack);
enc->shifter |=
value_to_pack << (32 - enc->bits_in_shifter - bits_to_pack);
enc->shifter |= value_to_pack << (32 - enc->bits_in_shifter - bits_to_pack);
num_bits -= bits_to_pack;
enc->bits_in_shifter += bits_to_pack;
while (enc->bits_in_shifter >= 8) {
unsigned char output_byte = (unsigned char) (enc->shifter >> 24);
unsigned char output_byte = (unsigned char)(enc->shifter >> 24);
enc->shifter <<= 8;
radeon_uvd_enc_emulation_prevention(enc, output_byte);
radeon_uvd_enc_output_one_byte(enc, output_byte);
@ -136,8 +128,7 @@ radeon_uvd_enc_code_fixed_bits(struct radeon_uvd_encoder *enc,
}
}
static void
radeon_uvd_enc_reset(struct radeon_uvd_encoder *enc)
static void radeon_uvd_enc_reset(struct radeon_uvd_encoder *enc)
{
enc->emulation_prevention = false;
enc->shifter = 0;
@ -147,8 +138,7 @@ radeon_uvd_enc_reset(struct radeon_uvd_encoder *enc)
enc->byte_index = 0;
}
static void
radeon_uvd_enc_byte_align(struct radeon_uvd_encoder *enc)
static void radeon_uvd_enc_byte_align(struct radeon_uvd_encoder *enc)
{
unsigned int num_padding_zeros = (32 - enc->bits_in_shifter) % 8;
@ -156,11 +146,10 @@ radeon_uvd_enc_byte_align(struct radeon_uvd_encoder *enc)
radeon_uvd_enc_code_fixed_bits(enc, 0, num_padding_zeros);
}
static void
radeon_uvd_enc_flush_headers(struct radeon_uvd_encoder *enc)
static void radeon_uvd_enc_flush_headers(struct radeon_uvd_encoder *enc)
{
if (enc->bits_in_shifter != 0) {
unsigned char output_byte = (unsigned char) (enc->shifter >> 24);
unsigned char output_byte = (unsigned char)(enc->shifter >> 24);
radeon_uvd_enc_emulation_prevention(enc, output_byte);
radeon_uvd_enc_output_one_byte(enc, output_byte);
enc->bits_output += enc->bits_in_shifter;
@ -175,8 +164,7 @@ radeon_uvd_enc_flush_headers(struct radeon_uvd_encoder *enc)
}
}
static void
radeon_uvd_enc_code_ue(struct radeon_uvd_encoder *enc, unsigned int value)
static void radeon_uvd_enc_code_ue(struct radeon_uvd_encoder *enc, unsigned int value)
{
int x = -1;
unsigned int ue_code = value + 1;
@ -191,35 +179,29 @@ radeon_uvd_enc_code_ue(struct radeon_uvd_encoder *enc, unsigned int value)
radeon_uvd_enc_code_fixed_bits(enc, ue_code, ue_length);
}
static void
radeon_uvd_enc_code_se(struct radeon_uvd_encoder *enc, int value)
static void radeon_uvd_enc_code_se(struct radeon_uvd_encoder *enc, int value)
{
unsigned int v = 0;
if (value != 0)
v = (value < 0 ? ((unsigned int) (0 - value) << 1)
: (((unsigned int) (value) << 1) - 1));
v = (value < 0 ? ((unsigned int)(0 - value) << 1) : (((unsigned int)(value) << 1) - 1));
radeon_uvd_enc_code_ue(enc, v);
}
static void
radeon_uvd_enc_session_info(struct radeon_uvd_encoder *enc)
static void radeon_uvd_enc_session_info(struct radeon_uvd_encoder *enc)
{
unsigned int interface_version =
((RENC_UVD_FW_INTERFACE_MAJOR_VERSION <<
RENC_UVD_IF_MAJOR_VERSION_SHIFT) |
(RENC_UVD_FW_INTERFACE_MINOR_VERSION <<
RENC_UVD_IF_MINOR_VERSION_SHIFT));
((RENC_UVD_FW_INTERFACE_MAJOR_VERSION << RENC_UVD_IF_MAJOR_VERSION_SHIFT) |
(RENC_UVD_FW_INTERFACE_MINOR_VERSION << RENC_UVD_IF_MINOR_VERSION_SHIFT));
RADEON_ENC_BEGIN(RENC_UVD_IB_PARAM_SESSION_INFO);
RADEON_ENC_CS(0x00000000); // reserved
RADEON_ENC_CS(0x00000000); // reserved
RADEON_ENC_CS(interface_version);
RADEON_ENC_READWRITE(enc->si->res->buf, enc->si->res->domains, 0x0);
RADEON_ENC_END();
}
static void
radeon_uvd_enc_task_info(struct radeon_uvd_encoder *enc, bool need_feedback)
static void radeon_uvd_enc_task_info(struct radeon_uvd_encoder *enc, bool need_feedback)
{
enc->enc_pic.task_info.task_id++;
@ -235,13 +217,10 @@ radeon_uvd_enc_task_info(struct radeon_uvd_encoder *enc, bool need_feedback)
RADEON_ENC_END();
}
static void
radeon_uvd_enc_session_init_hevc(struct radeon_uvd_encoder *enc)
static void radeon_uvd_enc_session_init_hevc(struct radeon_uvd_encoder *enc)
{
enc->enc_pic.session_init.aligned_picture_width =
align(enc->base.width, 64);
enc->enc_pic.session_init.aligned_picture_height =
align(enc->base.height, 16);
enc->enc_pic.session_init.aligned_picture_width = align(enc->base.width, 64);
enc->enc_pic.session_init.aligned_picture_height = align(enc->base.height, 16);
enc->enc_pic.session_init.padding_width =
enc->enc_pic.session_init.aligned_picture_width - enc->base.width;
enc->enc_pic.session_init.padding_height =
@ -259,8 +238,7 @@ radeon_uvd_enc_session_init_hevc(struct radeon_uvd_encoder *enc)
RADEON_ENC_END();
}
static void
radeon_uvd_enc_layer_control(struct radeon_uvd_encoder *enc)
static void radeon_uvd_enc_layer_control(struct radeon_uvd_encoder *enc)
{
enc->enc_pic.layer_ctrl.max_num_temporal_layers = 1;
enc->enc_pic.layer_ctrl.num_temporal_layers = 1;
@ -271,8 +249,7 @@ radeon_uvd_enc_layer_control(struct radeon_uvd_encoder *enc)
RADEON_ENC_END();
}
static void
radeon_uvd_enc_layer_select(struct radeon_uvd_encoder *enc)
static void radeon_uvd_enc_layer_select(struct radeon_uvd_encoder *enc)
{
enc->enc_pic.layer_sel.temporal_layer_index = 0;
@ -281,46 +258,37 @@ radeon_uvd_enc_layer_select(struct radeon_uvd_encoder *enc)
RADEON_ENC_END();
}
static void
radeon_uvd_enc_slice_control_hevc(struct radeon_uvd_encoder *enc)
static void radeon_uvd_enc_slice_control_hevc(struct radeon_uvd_encoder *enc)
{
enc->enc_pic.hevc_slice_ctrl.slice_control_mode =
RENC_UVD_SLICE_CONTROL_MODE_FIXED_CTBS;
enc->enc_pic.hevc_slice_ctrl.slice_control_mode = RENC_UVD_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_segment =
enc->enc_pic.hevc_slice_ctrl.fixed_ctbs_per_slice.num_ctbs_per_slice;
RADEON_ENC_BEGIN(RENC_UVD_IB_PARAM_SLICE_CONTROL);
RADEON_ENC_CS(enc->enc_pic.hevc_slice_ctrl.slice_control_mode);
RADEON_ENC_CS(enc->enc_pic.hevc_slice_ctrl.
fixed_ctbs_per_slice.num_ctbs_per_slice);
RADEON_ENC_CS(enc->enc_pic.hevc_slice_ctrl.
fixed_ctbs_per_slice.num_ctbs_per_slice_segment);
RADEON_ENC_CS(enc->enc_pic.hevc_slice_ctrl.fixed_ctbs_per_slice.num_ctbs_per_slice);
RADEON_ENC_CS(enc->enc_pic.hevc_slice_ctrl.fixed_ctbs_per_slice.num_ctbs_per_slice_segment);
RADEON_ENC_END();
}
static void
radeon_uvd_enc_spec_misc_hevc(struct radeon_uvd_encoder *enc,
struct pipe_picture_desc *picture)
static void radeon_uvd_enc_spec_misc_hevc(struct radeon_uvd_encoder *enc,
struct pipe_picture_desc *picture)
{
struct pipe_h265_enc_picture_desc *pic =
(struct pipe_h265_enc_picture_desc *) picture;
struct pipe_h265_enc_picture_desc *pic = (struct pipe_h265_enc_picture_desc *)picture;
enc->enc_pic.hevc_spec_misc.log2_min_luma_coding_block_size_minus3 =
pic->seq.log2_min_luma_coding_block_size_minus3;
enc->enc_pic.hevc_spec_misc.amp_disabled = !pic->seq.amp_enabled_flag;
enc->enc_pic.hevc_spec_misc.strong_intra_smoothing_enabled =
pic->seq.strong_intra_smoothing_enabled_flag;
enc->enc_pic.hevc_spec_misc.constrained_intra_pred_flag =
pic->pic.constrained_intra_pred_flag;
enc->enc_pic.hevc_spec_misc.constrained_intra_pred_flag = pic->pic.constrained_intra_pred_flag;
enc->enc_pic.hevc_spec_misc.cabac_init_flag = pic->slice.cabac_init_flag;
enc->enc_pic.hevc_spec_misc.half_pel_enabled = 1;
enc->enc_pic.hevc_spec_misc.quarter_pel_enabled = 1;
RADEON_ENC_BEGIN(RENC_UVD_IB_PARAM_SPEC_MISC);
RADEON_ENC_CS(enc->enc_pic.
hevc_spec_misc.log2_min_luma_coding_block_size_minus3);
RADEON_ENC_CS(enc->enc_pic.hevc_spec_misc.log2_min_luma_coding_block_size_minus3);
RADEON_ENC_CS(enc->enc_pic.hevc_spec_misc.amp_disabled);
RADEON_ENC_CS(enc->enc_pic.hevc_spec_misc.strong_intra_smoothing_enabled);
RADEON_ENC_CS(enc->enc_pic.hevc_spec_misc.constrained_intra_pred_flag);
@ -330,22 +298,18 @@ radeon_uvd_enc_spec_misc_hevc(struct radeon_uvd_encoder *enc,
RADEON_ENC_END();
}
static void
radeon_uvd_enc_rc_session_init(struct radeon_uvd_encoder *enc,
struct pipe_picture_desc *picture)
static void radeon_uvd_enc_rc_session_init(struct radeon_uvd_encoder *enc,
struct pipe_picture_desc *picture)
{
struct pipe_h265_enc_picture_desc *pic =
(struct pipe_h265_enc_picture_desc *) picture;
struct pipe_h265_enc_picture_desc *pic = (struct pipe_h265_enc_picture_desc *)picture;
enc->enc_pic.rc_session_init.vbv_buffer_level = pic->rc.vbv_buf_lv;
switch (pic->rc.rate_ctrl_method) {
case PIPE_H265_ENC_RATE_CONTROL_METHOD_DISABLE:
enc->enc_pic.rc_session_init.rate_control_method =
RENC_UVD_RATE_CONTROL_METHOD_NONE;
enc->enc_pic.rc_session_init.rate_control_method = RENC_UVD_RATE_CONTROL_METHOD_NONE;
break;
case PIPE_H265_ENC_RATE_CONTROL_METHOD_CONSTANT_SKIP:
case PIPE_H265_ENC_RATE_CONTROL_METHOD_CONSTANT:
enc->enc_pic.rc_session_init.rate_control_method =
RENC_UVD_RATE_CONTROL_METHOD_CBR;
enc->enc_pic.rc_session_init.rate_control_method = RENC_UVD_RATE_CONTROL_METHOD_CBR;
break;
case PIPE_H265_ENC_RATE_CONTROL_METHOD_VARIABLE_SKIP:
case PIPE_H265_ENC_RATE_CONTROL_METHOD_VARIABLE:
@ -353,8 +317,7 @@ radeon_uvd_enc_rc_session_init(struct radeon_uvd_encoder *enc,
RENC_UVD_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR;
break;
default:
enc->enc_pic.rc_session_init.rate_control_method =
RENC_UVD_RATE_CONTROL_METHOD_NONE;
enc->enc_pic.rc_session_init.rate_control_method = RENC_UVD_RATE_CONTROL_METHOD_NONE;
}
RADEON_ENC_BEGIN(RENC_UVD_IB_PARAM_RATE_CONTROL_SESSION_INIT);
@ -363,23 +326,18 @@ radeon_uvd_enc_rc_session_init(struct radeon_uvd_encoder *enc,
RADEON_ENC_END();
}
static void
radeon_uvd_enc_rc_layer_init(struct radeon_uvd_encoder *enc,
struct pipe_picture_desc *picture)
static void radeon_uvd_enc_rc_layer_init(struct radeon_uvd_encoder *enc,
struct pipe_picture_desc *picture)
{
struct pipe_h265_enc_picture_desc *pic =
(struct pipe_h265_enc_picture_desc *) picture;
struct pipe_h265_enc_picture_desc *pic = (struct pipe_h265_enc_picture_desc *)picture;
enc->enc_pic.rc_layer_init.target_bit_rate = pic->rc.target_bitrate;
enc->enc_pic.rc_layer_init.peak_bit_rate = pic->rc.peak_bitrate;
enc->enc_pic.rc_layer_init.frame_rate_num = pic->rc.frame_rate_num;
enc->enc_pic.rc_layer_init.frame_rate_den = pic->rc.frame_rate_den;
enc->enc_pic.rc_layer_init.vbv_buffer_size = pic->rc.vbv_buffer_size;
enc->enc_pic.rc_layer_init.avg_target_bits_per_picture =
pic->rc.target_bits_picture;
enc->enc_pic.rc_layer_init.peak_bits_per_picture_integer =
pic->rc.peak_bits_picture_integer;
enc->enc_pic.rc_layer_init.peak_bits_per_picture_fractional =
pic->rc.peak_bits_picture_fraction;
enc->enc_pic.rc_layer_init.avg_target_bits_per_picture = pic->rc.target_bits_picture;
enc->enc_pic.rc_layer_init.peak_bits_per_picture_integer = pic->rc.peak_bits_picture_integer;
enc->enc_pic.rc_layer_init.peak_bits_per_picture_fractional = pic->rc.peak_bits_picture_fraction;
RADEON_ENC_BEGIN(RENC_UVD_IB_PARAM_RATE_CONTROL_LAYER_INIT);
RADEON_ENC_CS(enc->enc_pic.rc_layer_init.target_bit_rate);
@ -393,18 +351,15 @@ radeon_uvd_enc_rc_layer_init(struct radeon_uvd_encoder *enc,
RADEON_ENC_END();
}
static void
radeon_uvd_enc_deblocking_filter_hevc(struct radeon_uvd_encoder *enc,
struct pipe_picture_desc *picture)
static void radeon_uvd_enc_deblocking_filter_hevc(struct radeon_uvd_encoder *enc,
struct pipe_picture_desc *picture)
{
struct pipe_h265_enc_picture_desc *pic =
(struct pipe_h265_enc_picture_desc *) picture;
struct pipe_h265_enc_picture_desc *pic = (struct pipe_h265_enc_picture_desc *)picture;
enc->enc_pic.hevc_deblock.loop_filter_across_slices_enabled =
pic->slice.slice_loop_filter_across_slices_enabled_flag;
enc->enc_pic.hevc_deblock.deblocking_filter_disabled =
pic->slice.slice_deblocking_filter_disabled_flag;
enc->enc_pic.hevc_deblock.beta_offset_div2 =
pic->slice.slice_beta_offset_div2;
enc->enc_pic.hevc_deblock.beta_offset_div2 = pic->slice.slice_beta_offset_div2;
enc->enc_pic.hevc_deblock.tc_offset_div2 = pic->slice.slice_tc_offset_div2;
enc->enc_pic.hevc_deblock.cb_qp_offset = pic->slice.slice_cb_qp_offset;
enc->enc_pic.hevc_deblock.cr_qp_offset = pic->slice.slice_cr_qp_offset;
@ -419,8 +374,7 @@ radeon_uvd_enc_deblocking_filter_hevc(struct radeon_uvd_encoder *enc,
RADEON_ENC_END();
}
static void
radeon_uvd_enc_quality_params(struct radeon_uvd_encoder *enc)
static void radeon_uvd_enc_quality_params(struct radeon_uvd_encoder *enc)
{
enc->enc_pic.quality_params.vbaq_mode = 0;
enc->enc_pic.quality_params.scene_change_sensitivity = 0;
@ -433,8 +387,7 @@ radeon_uvd_enc_quality_params(struct radeon_uvd_encoder *enc)
RADEON_ENC_END();
}
static void
radeon_uvd_enc_nalu_sps_hevc(struct radeon_uvd_encoder *enc)
static void radeon_uvd_enc_nalu_sps_hevc(struct radeon_uvd_encoder *enc)
{
RADEON_ENC_BEGIN(RENC_UVD_IB_PARAM_INSERT_NALU_BUFFER);
RADEON_ENC_CS(RENC_UVD_NALU_TYPE_SPS);
@ -448,9 +401,7 @@ radeon_uvd_enc_nalu_sps_hevc(struct radeon_uvd_encoder *enc)
radeon_uvd_enc_byte_align(enc);
radeon_uvd_enc_set_emulation_prevention(enc, true);
radeon_uvd_enc_code_fixed_bits(enc, 0x0, 4);
radeon_uvd_enc_code_fixed_bits(enc,
enc->enc_pic.
layer_ctrl.max_num_temporal_layers - 1, 3);
radeon_uvd_enc_code_fixed_bits(enc, enc->enc_pic.layer_ctrl.max_num_temporal_layers - 1, 3);
radeon_uvd_enc_code_fixed_bits(enc, 0x1, 1);
radeon_uvd_enc_code_fixed_bits(enc, 0x0, 2);
radeon_uvd_enc_code_fixed_bits(enc, enc->enc_pic.general_tier_flag, 1);
@ -470,16 +421,13 @@ radeon_uvd_enc_nalu_sps_hevc(struct radeon_uvd_encoder *enc)
radeon_uvd_enc_code_ue(enc, 0x0);
radeon_uvd_enc_code_ue(enc, enc->enc_pic.chroma_format_idc);
radeon_uvd_enc_code_ue(enc,
enc->enc_pic.session_init.aligned_picture_width);
radeon_uvd_enc_code_ue(enc,
enc->enc_pic.session_init.aligned_picture_height);
radeon_uvd_enc_code_ue(enc, enc->enc_pic.session_init.aligned_picture_width);
radeon_uvd_enc_code_ue(enc, enc->enc_pic.session_init.aligned_picture_height);
int conformance_window_flag =
(enc->enc_pic.crop_top > 0) ||
(enc->enc_pic.crop_bottom > 0) ||
(enc->enc_pic.crop_left > 0) ||
(enc->enc_pic.crop_right > 0) ? 0x1 : 0x0;
int conformance_window_flag = (enc->enc_pic.crop_top > 0) || (enc->enc_pic.crop_bottom > 0) ||
(enc->enc_pic.crop_left > 0) || (enc->enc_pic.crop_right > 0)
? 0x1
: 0x0;
radeon_uvd_enc_code_fixed_bits(enc, conformance_window_flag, 1);
if (conformance_window_flag == 1) {
radeon_uvd_enc_code_ue(enc, enc->enc_pic.crop_left);
@ -495,31 +443,18 @@ radeon_uvd_enc_nalu_sps_hevc(struct radeon_uvd_encoder *enc)
radeon_uvd_enc_code_ue(enc, 1);
radeon_uvd_enc_code_ue(enc, 0x0);
radeon_uvd_enc_code_ue(enc, 0x0);
radeon_uvd_enc_code_ue(enc,
enc->enc_pic.hevc_spec_misc.
log2_min_luma_coding_block_size_minus3);
radeon_uvd_enc_code_ue(enc, enc->enc_pic.hevc_spec_misc.log2_min_luma_coding_block_size_minus3);
/* Only support CTBSize 64 */
radeon_uvd_enc_code_ue(enc,
6 -
(enc->enc_pic.hevc_spec_misc.
log2_min_luma_coding_block_size_minus3 + 3));
radeon_uvd_enc_code_ue(enc,
enc->enc_pic.log2_min_transform_block_size_minus2);
radeon_uvd_enc_code_ue(enc,
enc->enc_pic.
log2_diff_max_min_transform_block_size);
radeon_uvd_enc_code_ue(enc,
enc->enc_pic.max_transform_hierarchy_depth_inter);
radeon_uvd_enc_code_ue(enc,
enc->enc_pic.max_transform_hierarchy_depth_intra);
radeon_uvd_enc_code_ue(
enc, 6 - (enc->enc_pic.hevc_spec_misc.log2_min_luma_coding_block_size_minus3 + 3));
radeon_uvd_enc_code_ue(enc, enc->enc_pic.log2_min_transform_block_size_minus2);
radeon_uvd_enc_code_ue(enc, enc->enc_pic.log2_diff_max_min_transform_block_size);
radeon_uvd_enc_code_ue(enc, enc->enc_pic.max_transform_hierarchy_depth_inter);
radeon_uvd_enc_code_ue(enc, enc->enc_pic.max_transform_hierarchy_depth_intra);
radeon_uvd_enc_code_fixed_bits(enc, 0x0, 1);
radeon_uvd_enc_code_fixed_bits(enc,
!enc->enc_pic.hevc_spec_misc.amp_disabled,
1);
radeon_uvd_enc_code_fixed_bits(enc,
enc->enc_pic.
sample_adaptive_offset_enabled_flag, 1);
radeon_uvd_enc_code_fixed_bits(enc, !enc->enc_pic.hevc_spec_misc.amp_disabled, 1);
radeon_uvd_enc_code_fixed_bits(enc, enc->enc_pic.sample_adaptive_offset_enabled_flag, 1);
radeon_uvd_enc_code_fixed_bits(enc, enc->enc_pic.pcm_enabled_flag, 1);
radeon_uvd_enc_code_ue(enc, 1);
@ -531,9 +466,8 @@ radeon_uvd_enc_nalu_sps_hevc(struct radeon_uvd_encoder *enc)
radeon_uvd_enc_code_fixed_bits(enc, 0x0, 1);
radeon_uvd_enc_code_fixed_bits(enc, 0, 1);
radeon_uvd_enc_code_fixed_bits(enc,
enc->enc_pic.hevc_spec_misc.
strong_intra_smoothing_enabled, 1);
radeon_uvd_enc_code_fixed_bits(enc, enc->enc_pic.hevc_spec_misc.strong_intra_smoothing_enabled,
1);
radeon_uvd_enc_code_fixed_bits(enc, 0x0, 1);
@ -547,8 +481,7 @@ radeon_uvd_enc_nalu_sps_hevc(struct radeon_uvd_encoder *enc)
RADEON_ENC_END();
}
static void
radeon_uvd_enc_nalu_pps_hevc(struct radeon_uvd_encoder *enc)
static void radeon_uvd_enc_nalu_pps_hevc(struct radeon_uvd_encoder *enc)
{
RADEON_ENC_BEGIN(RENC_UVD_IB_PARAM_INSERT_NALU_BUFFER);
RADEON_ENC_CS(RENC_UVD_NALU_TYPE_PPS);
@ -569,12 +502,9 @@ radeon_uvd_enc_nalu_pps_hevc(struct radeon_uvd_encoder *enc)
radeon_uvd_enc_code_ue(enc, 0x0);
radeon_uvd_enc_code_ue(enc, 0x0);
radeon_uvd_enc_code_se(enc, 0x0);
radeon_uvd_enc_code_fixed_bits(enc,
enc->enc_pic.hevc_spec_misc.
constrained_intra_pred_flag, 1);
radeon_uvd_enc_code_fixed_bits(enc, enc->enc_pic.hevc_spec_misc.constrained_intra_pred_flag, 1);
radeon_uvd_enc_code_fixed_bits(enc, 0x0, 1);
if (enc->enc_pic.rc_session_init.rate_control_method ==
RENC_UVD_RATE_CONTROL_METHOD_NONE)
if (enc->enc_pic.rc_session_init.rate_control_method == RENC_UVD_RATE_CONTROL_METHOD_NONE)
radeon_uvd_enc_code_fixed_bits(enc, 0x0, 1);
else {
radeon_uvd_enc_code_fixed_bits(enc, 0x1, 1);
@ -587,14 +517,11 @@ radeon_uvd_enc_nalu_pps_hevc(struct radeon_uvd_encoder *enc)
radeon_uvd_enc_code_fixed_bits(enc, 0x0, 1);
radeon_uvd_enc_code_fixed_bits(enc, 0x0, 1);
radeon_uvd_enc_code_fixed_bits(enc, 0x0, 1);
radeon_uvd_enc_code_fixed_bits(enc,
enc->enc_pic.hevc_deblock.
loop_filter_across_slices_enabled, 1);
radeon_uvd_enc_code_fixed_bits(enc, enc->enc_pic.hevc_deblock.loop_filter_across_slices_enabled,
1);
radeon_uvd_enc_code_fixed_bits(enc, 0x1, 1);
radeon_uvd_enc_code_fixed_bits(enc, 0x0, 1);
radeon_uvd_enc_code_fixed_bits(enc,
enc->enc_pic.hevc_deblock.
deblocking_filter_disabled, 1);
radeon_uvd_enc_code_fixed_bits(enc, enc->enc_pic.hevc_deblock.deblocking_filter_disabled, 1);
if (!enc->enc_pic.hevc_deblock.deblocking_filter_disabled) {
radeon_uvd_enc_code_se(enc, enc->enc_pic.hevc_deblock.beta_offset_div2);
@ -614,8 +541,7 @@ radeon_uvd_enc_nalu_pps_hevc(struct radeon_uvd_encoder *enc)
RADEON_ENC_END();
}
static void
radeon_uvd_enc_nalu_vps_hevc(struct radeon_uvd_encoder *enc)
static void radeon_uvd_enc_nalu_vps_hevc(struct radeon_uvd_encoder *enc)
{
RADEON_ENC_BEGIN(RENC_UVD_IB_PARAM_INSERT_NALU_BUFFER);
RADEON_ENC_CS(RENC_UVD_NALU_TYPE_VPS);
@ -632,9 +558,7 @@ radeon_uvd_enc_nalu_vps_hevc(struct radeon_uvd_encoder *enc)
radeon_uvd_enc_code_fixed_bits(enc, 0x0, 4);
radeon_uvd_enc_code_fixed_bits(enc, 0x3, 2);
radeon_uvd_enc_code_fixed_bits(enc, 0x0, 6);
radeon_uvd_enc_code_fixed_bits(enc,
enc->enc_pic.layer_ctrl.
max_num_temporal_layers - 1, 3);
radeon_uvd_enc_code_fixed_bits(enc, enc->enc_pic.layer_ctrl.max_num_temporal_layers - 1, 3);
radeon_uvd_enc_code_fixed_bits(enc, 0x1, 1);
radeon_uvd_enc_code_fixed_bits(enc, 0xffff, 16);
radeon_uvd_enc_code_fixed_bits(enc, 0x0, 2);
@ -671,8 +595,7 @@ radeon_uvd_enc_nalu_vps_hevc(struct radeon_uvd_encoder *enc)
RADEON_ENC_END();
}
static void
radeon_uvd_enc_nalu_aud_hevc(struct radeon_uvd_encoder *enc)
static void radeon_uvd_enc_nalu_aud_hevc(struct radeon_uvd_encoder *enc)
{
RADEON_ENC_BEGIN(RENC_UVD_IB_PARAM_INSERT_NALU_BUFFER);
RADEON_ENC_CS(RENC_UVD_NALU_TYPE_AUD);
@ -709,11 +632,10 @@ radeon_uvd_enc_nalu_aud_hevc(struct radeon_uvd_encoder *enc)
RADEON_ENC_END();
}
static void
radeon_uvd_enc_slice_header_hevc(struct radeon_uvd_encoder *enc)
static void radeon_uvd_enc_slice_header_hevc(struct radeon_uvd_encoder *enc)
{
uint32_t instruction[RENC_UVD_SLICE_HEADER_TEMPLATE_MAX_NUM_INSTRUCTIONS] = { 0 };
uint32_t num_bits[RENC_UVD_SLICE_HEADER_TEMPLATE_MAX_NUM_INSTRUCTIONS] = { 0 };
uint32_t instruction[RENC_UVD_SLICE_HEADER_TEMPLATE_MAX_NUM_INSTRUCTIONS] = {0};
uint32_t num_bits[RENC_UVD_SLICE_HEADER_TEMPLATE_MAX_NUM_INSTRUCTIONS] = {0};
unsigned int inst_index = 0;
unsigned int bit_index = 0;
unsigned int bits_copied = 0;
@ -736,8 +658,7 @@ radeon_uvd_enc_slice_header_hevc(struct radeon_uvd_encoder *enc)
instruction[inst_index] = RENC_UVD_HEADER_INSTRUCTION_FIRST_SLICE;
inst_index++;
if ((enc->enc_pic.nal_unit_type >= 16)
&& (enc->enc_pic.nal_unit_type <= 23))
if ((enc->enc_pic.nal_unit_type >= 16) && (enc->enc_pic.nal_unit_type <= 23))
radeon_uvd_enc_code_fixed_bits(enc, 0x0, 1);
radeon_uvd_enc_code_ue(enc, 0x0);
@ -771,11 +692,8 @@ radeon_uvd_enc_slice_header_hevc(struct radeon_uvd_encoder *enc)
radeon_uvd_enc_code_ue(enc, 0x1);
}
if ((enc->enc_pic.nal_unit_type != 19)
&& (enc->enc_pic.nal_unit_type != 20)) {
radeon_uvd_enc_code_fixed_bits(enc,
enc->enc_pic.pic_order_cnt,
enc->enc_pic.log2_max_poc);
if ((enc->enc_pic.nal_unit_type != 19) && (enc->enc_pic.nal_unit_type != 20)) {
radeon_uvd_enc_code_fixed_bits(enc, enc->enc_pic.pic_order_cnt, enc->enc_pic.log2_max_poc);
if (enc->enc_pic.picture_type == PIPE_H265_ENC_PICTURE_TYPE_P)
radeon_uvd_enc_code_fixed_bits(enc, 0x1, 1);
else {
@ -787,14 +705,12 @@ radeon_uvd_enc_slice_header_hevc(struct radeon_uvd_encoder *enc)
}
if (enc->enc_pic.sample_adaptive_offset_enabled_flag)
radeon_uvd_enc_code_fixed_bits(enc, 0x0, 1); /* slice_sao_luma_flag */
radeon_uvd_enc_code_fixed_bits(enc, 0x0, 1); /* slice_sao_luma_flag */
if ((enc->enc_pic.picture_type == PIPE_H265_ENC_PICTURE_TYPE_P) ||
(enc->enc_pic.picture_type == PIPE_H265_ENC_PICTURE_TYPE_B)) {
radeon_uvd_enc_code_fixed_bits(enc, 0x0, 1);
radeon_uvd_enc_code_fixed_bits(enc,
enc->enc_pic.hevc_spec_misc.
cabac_init_flag, 1);
radeon_uvd_enc_code_fixed_bits(enc, enc->enc_pic.hevc_spec_misc.cabac_init_flag, 1);
radeon_uvd_enc_code_ue(enc, 5 - enc->enc_pic.max_num_merge_cand);
}
@ -810,9 +726,8 @@ radeon_uvd_enc_slice_header_hevc(struct radeon_uvd_encoder *enc)
if ((enc->enc_pic.hevc_deblock.loop_filter_across_slices_enabled) &&
(!enc->enc_pic.hevc_deblock.deblocking_filter_disabled)) {
radeon_uvd_enc_code_fixed_bits(enc,
enc->enc_pic.hevc_deblock.
loop_filter_across_slices_enabled, 1);
radeon_uvd_enc_code_fixed_bits(
enc, enc->enc_pic.hevc_deblock.loop_filter_across_slices_enabled, 1);
radeon_uvd_enc_flush_headers(enc);
bit_index++;
@ -824,12 +739,10 @@ radeon_uvd_enc_slice_header_hevc(struct radeon_uvd_encoder *enc)
instruction[inst_index] = RENC_UVD_HEADER_INSTRUCTION_END;
for (int i = bit_index;
i < RENC_UVD_SLICE_HEADER_TEMPLATE_MAX_TEMPLATE_SIZE_IN_DWORDS; i++)
for (int i = bit_index; i < RENC_UVD_SLICE_HEADER_TEMPLATE_MAX_TEMPLATE_SIZE_IN_DWORDS; i++)
RADEON_ENC_CS(0x00000000);
for (int j = 0; j < RENC_UVD_SLICE_HEADER_TEMPLATE_MAX_NUM_INSTRUCTIONS;
j++) {
for (int j = 0; j < RENC_UVD_SLICE_HEADER_TEMPLATE_MAX_NUM_INSTRUCTIONS; j++) {
RADEON_ENC_CS(instruction[j]);
RADEON_ENC_CS(num_bits[j]);
}
@ -837,29 +750,24 @@ radeon_uvd_enc_slice_header_hevc(struct radeon_uvd_encoder *enc)
RADEON_ENC_END();
}
static void
radeon_uvd_enc_ctx(struct radeon_uvd_encoder *enc)
static void radeon_uvd_enc_ctx(struct radeon_uvd_encoder *enc)
{
struct si_screen *sscreen = (struct si_screen *) enc->screen;
struct si_screen *sscreen = (struct si_screen *)enc->screen;
enc->enc_pic.ctx_buf.swizzle_mode = 0;
if (sscreen->info.chip_class < GFX9) {
enc->enc_pic.ctx_buf.rec_luma_pitch =
(enc->luma->u.legacy.level[0].nblk_x * enc->luma->bpe);
enc->enc_pic.ctx_buf.rec_luma_pitch = (enc->luma->u.legacy.level[0].nblk_x * enc->luma->bpe);
enc->enc_pic.ctx_buf.rec_chroma_pitch =
(enc->chroma->u.legacy.level[0].nblk_x * enc->chroma->bpe);
}
else {
enc->enc_pic.ctx_buf.rec_luma_pitch =
enc->luma->u.gfx9.surf_pitch * enc->luma->bpe;
enc->enc_pic.ctx_buf.rec_chroma_pitch =
enc->chroma->u.gfx9.surf_pitch * enc->chroma->bpe;
} else {
enc->enc_pic.ctx_buf.rec_luma_pitch = enc->luma->u.gfx9.surf_pitch * enc->luma->bpe;
enc->enc_pic.ctx_buf.rec_chroma_pitch = enc->chroma->u.gfx9.surf_pitch * enc->chroma->bpe;
}
enc->enc_pic.ctx_buf.num_reconstructed_pictures = 2;
RADEON_ENC_BEGIN(RENC_UVD_IB_PARAM_ENCODE_CONTEXT_BUFFER);
RADEON_ENC_READWRITE(enc->cpb.res->buf, enc->cpb.res->domains, 0);
RADEON_ENC_CS(0x00000000); // reserved
RADEON_ENC_CS(0x00000000); // reserved
RADEON_ENC_CS(enc->enc_pic.ctx_buf.swizzle_mode);
RADEON_ENC_CS(enc->enc_pic.ctx_buf.rec_luma_pitch);
RADEON_ENC_CS(enc->enc_pic.ctx_buf.rec_chroma_pitch);
@ -867,14 +775,11 @@ radeon_uvd_enc_ctx(struct radeon_uvd_encoder *enc)
/* reconstructed_picture_1_luma_offset */
RADEON_ENC_CS(0x00000000);
/* reconstructed_picture_1_chroma_offset */
RADEON_ENC_CS(enc->enc_pic.ctx_buf.rec_chroma_pitch *
align(enc->base.height, 16));
RADEON_ENC_CS(enc->enc_pic.ctx_buf.rec_chroma_pitch * align(enc->base.height, 16));
/* reconstructed_picture_2_luma_offset */
RADEON_ENC_CS(enc->enc_pic.ctx_buf.rec_luma_pitch *
align(enc->base.height, 16) * 3 / 2);
RADEON_ENC_CS(enc->enc_pic.ctx_buf.rec_luma_pitch * align(enc->base.height, 16) * 3 / 2);
/* reconstructed_picture_2_chroma_offset */
RADEON_ENC_CS(enc->enc_pic.ctx_buf.rec_chroma_pitch *
align(enc->base.height, 16) * 5 / 2);
RADEON_ENC_CS(enc->enc_pic.ctx_buf.rec_chroma_pitch * align(enc->base.height, 16) * 5 / 2);
for (int i = 0; i < 136; i++)
RADEON_ENC_CS(0x00000000);
@ -882,8 +787,7 @@ radeon_uvd_enc_ctx(struct radeon_uvd_encoder *enc)
RADEON_ENC_END();
}
static void
radeon_uvd_enc_bitstream(struct radeon_uvd_encoder *enc)
static void radeon_uvd_enc_bitstream(struct radeon_uvd_encoder *enc)
{
enc->enc_pic.bit_buf.mode = RENC_UVD_SWIZZLE_MODE_LINEAR;
enc->enc_pic.bit_buf.video_bitstream_buffer_size = enc->bs_size;
@ -897,8 +801,7 @@ radeon_uvd_enc_bitstream(struct radeon_uvd_encoder *enc)
RADEON_ENC_END();
}
static void
radeon_uvd_enc_feedback(struct radeon_uvd_encoder *enc)
static void radeon_uvd_enc_feedback(struct radeon_uvd_encoder *enc)
{
enc->enc_pic.fb_buf.mode = RENC_UVD_FEEDBACK_BUFFER_MODE_LINEAR;
enc->enc_pic.fb_buf.feedback_buffer_size = 16;
@ -912,11 +815,9 @@ radeon_uvd_enc_feedback(struct radeon_uvd_encoder *enc)
RADEON_ENC_END();
}
static void
radeon_uvd_enc_intra_refresh(struct radeon_uvd_encoder *enc)
static void radeon_uvd_enc_intra_refresh(struct radeon_uvd_encoder *enc)
{
enc->enc_pic.intra_ref.intra_refresh_mode =
RENC_UVD_INTRA_REFRESH_MODE_NONE;
enc->enc_pic.intra_ref.intra_refresh_mode = RENC_UVD_INTRA_REFRESH_MODE_NONE;
enc->enc_pic.intra_ref.offset = 0;
enc->enc_pic.intra_ref.region_size = 0;
@ -927,12 +828,10 @@ radeon_uvd_enc_intra_refresh(struct radeon_uvd_encoder *enc)
RADEON_ENC_END();
}
static void
radeon_uvd_enc_rc_per_pic(struct radeon_uvd_encoder *enc,
struct pipe_picture_desc *picture)
static void radeon_uvd_enc_rc_per_pic(struct radeon_uvd_encoder *enc,
struct pipe_picture_desc *picture)
{
struct pipe_h265_enc_picture_desc *pic =
(struct pipe_h265_enc_picture_desc *) picture;
struct pipe_h265_enc_picture_desc *pic = (struct pipe_h265_enc_picture_desc *)picture;
enc->enc_pic.rc_per_pic.qp = pic->rc.quant_i_frames;
enc->enc_pic.rc_per_pic.min_qp_app = 0;
enc->enc_pic.rc_per_pic.max_qp_app = 51;
@ -952,10 +851,9 @@ radeon_uvd_enc_rc_per_pic(struct radeon_uvd_encoder *enc,
RADEON_ENC_END();
}
static void
radeon_uvd_enc_encode_params_hevc(struct radeon_uvd_encoder *enc)
static void radeon_uvd_enc_encode_params_hevc(struct radeon_uvd_encoder *enc)
{
struct si_screen *sscreen = (struct si_screen *) enc->screen;
struct si_screen *sscreen = (struct si_screen *)enc->screen;
switch (enc->enc_pic.picture_type) {
case PIPE_H265_ENC_PICTURE_TYPE_I:
case PIPE_H265_ENC_PICTURE_TYPE_IDR:
@ -980,94 +878,77 @@ radeon_uvd_enc_encode_params_hevc(struct radeon_uvd_encoder *enc)
(enc->luma->u.legacy.level[0].nblk_x * enc->luma->bpe);
enc->enc_pic.enc_params.input_pic_chroma_pitch =
(enc->chroma->u.legacy.level[0].nblk_x * enc->chroma->bpe);
}
else {
enc->enc_pic.enc_params.input_pic_luma_pitch =
enc->luma->u.gfx9.surf_pitch * enc->luma->bpe;
} else {
enc->enc_pic.enc_params.input_pic_luma_pitch = enc->luma->u.gfx9.surf_pitch * enc->luma->bpe;
enc->enc_pic.enc_params.input_pic_chroma_pitch =
enc->chroma->u.gfx9.surf_pitch * enc->chroma->bpe;
}
enc->enc_pic.enc_params.input_pic_swizzle_mode =
RENC_UVD_SWIZZLE_MODE_LINEAR;
enc->enc_pic.enc_params.input_pic_swizzle_mode = RENC_UVD_SWIZZLE_MODE_LINEAR;
if (enc->enc_pic.enc_params.pic_type == RENC_UVD_PICTURE_TYPE_I)
enc->enc_pic.enc_params.reference_picture_index = 0xFFFFFFFF;
else
enc->enc_pic.enc_params.reference_picture_index =
(enc->enc_pic.frame_num - 1) % 2;
enc->enc_pic.enc_params.reference_picture_index = (enc->enc_pic.frame_num - 1) % 2;
enc->enc_pic.enc_params.reconstructed_picture_index =
enc->enc_pic.frame_num % 2;
enc->enc_pic.enc_params.reconstructed_picture_index = enc->enc_pic.frame_num % 2;
RADEON_ENC_BEGIN(RENC_UVD_IB_PARAM_ENCODE_PARAMS);
RADEON_ENC_CS(enc->enc_pic.enc_params.pic_type);
RADEON_ENC_CS(enc->enc_pic.enc_params.allowed_max_bitstream_size);
if (sscreen->info.chip_class < GFX9) {
RADEON_ENC_READ(enc->handle, RADEON_DOMAIN_VRAM,
enc->luma->u.legacy.level[0].offset);
RADEON_ENC_READ(enc->handle, RADEON_DOMAIN_VRAM,
enc->chroma->u.legacy.level[0].offset);
}
else {
RADEON_ENC_READ(enc->handle, RADEON_DOMAIN_VRAM,
enc->luma->u.gfx9.surf_offset);
RADEON_ENC_READ(enc->handle, RADEON_DOMAIN_VRAM,
enc->chroma->u.gfx9.surf_offset);
RADEON_ENC_READ(enc->handle, RADEON_DOMAIN_VRAM, enc->luma->u.legacy.level[0].offset);
RADEON_ENC_READ(enc->handle, RADEON_DOMAIN_VRAM, enc->chroma->u.legacy.level[0].offset);
} else {
RADEON_ENC_READ(enc->handle, RADEON_DOMAIN_VRAM, enc->luma->u.gfx9.surf_offset);
RADEON_ENC_READ(enc->handle, RADEON_DOMAIN_VRAM, enc->chroma->u.gfx9.surf_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(0x00000000); // reserved
RADEON_ENC_CS(0x00000000); // reserved
RADEON_ENC_CS(enc->enc_pic.enc_params.input_pic_swizzle_mode);
RADEON_ENC_CS(enc->enc_pic.enc_params.reference_picture_index);
RADEON_ENC_CS(enc->enc_pic.enc_params.reconstructed_picture_index);
RADEON_ENC_END();
}
static void
radeon_uvd_enc_op_init(struct radeon_uvd_encoder *enc)
static void radeon_uvd_enc_op_init(struct radeon_uvd_encoder *enc)
{
RADEON_ENC_BEGIN(RENC_UVD_IB_OP_INITIALIZE);
RADEON_ENC_END();
}
static void
radeon_uvd_enc_op_close(struct radeon_uvd_encoder *enc)
static void radeon_uvd_enc_op_close(struct radeon_uvd_encoder *enc)
{
RADEON_ENC_BEGIN(RENC_UVD_IB_OP_CLOSE_SESSION);
RADEON_ENC_END();
}
static void
radeon_uvd_enc_op_enc(struct radeon_uvd_encoder *enc)
static void radeon_uvd_enc_op_enc(struct radeon_uvd_encoder *enc)
{
RADEON_ENC_BEGIN(RENC_UVD_IB_OP_ENCODE);
RADEON_ENC_END();
}
static void
radeon_uvd_enc_op_init_rc(struct radeon_uvd_encoder *enc)
static void radeon_uvd_enc_op_init_rc(struct radeon_uvd_encoder *enc)
{
RADEON_ENC_BEGIN(RENC_UVD_IB_OP_INIT_RC);
RADEON_ENC_END();
}
static void
radeon_uvd_enc_op_init_rc_vbv(struct radeon_uvd_encoder *enc)
static void radeon_uvd_enc_op_init_rc_vbv(struct radeon_uvd_encoder *enc)
{
RADEON_ENC_BEGIN(RENC_UVD_IB_OP_INIT_RC_VBV_BUFFER_LEVEL);
RADEON_ENC_END();
}
static void
radeon_uvd_enc_op_speed(struct radeon_uvd_encoder *enc)
static void radeon_uvd_enc_op_speed(struct radeon_uvd_encoder *enc)
{
RADEON_ENC_BEGIN(RENC_UVD_IB_OP_SET_SPEED_ENCODING_MODE);
RADEON_ENC_END();
}
static void
begin(struct radeon_uvd_encoder *enc, struct pipe_picture_desc *pic)
static void begin(struct radeon_uvd_encoder *enc, struct pipe_picture_desc *pic)
{
radeon_uvd_enc_session_info(enc);
enc->total_task_size = 0;
@ -1091,8 +972,7 @@ begin(struct radeon_uvd_encoder *enc, struct pipe_picture_desc *pic)
*enc->p_task_size = (enc->total_task_size);
}
static void
encode(struct radeon_uvd_encoder *enc)
static void encode(struct radeon_uvd_encoder *enc)
{
radeon_uvd_enc_session_info(enc);
enc->total_task_size = 0;
@ -1118,8 +998,7 @@ encode(struct radeon_uvd_encoder *enc)
*enc->p_task_size = (enc->total_task_size);
}
static void
destroy(struct radeon_uvd_encoder *enc)
static void destroy(struct radeon_uvd_encoder *enc)
{
radeon_uvd_enc_session_info(enc);
enc->total_task_size = 0;
@ -1128,8 +1007,7 @@ destroy(struct radeon_uvd_encoder *enc)
*enc->p_task_size = (enc->total_task_size);
}
void
radeon_uvd_enc_1_1_init(struct radeon_uvd_encoder *enc)
void radeon_uvd_enc_1_1_init(struct radeon_uvd_encoder *enc)
{
enc->begin = begin;
enc->encode = encode;

View File

@ -25,37 +25,35 @@
*
**************************************************************************/
#include <stdio.h>
#include "pipe/p_video_codec.h"
#include "util/u_video.h"
#include "util/u_memory.h"
#include "vl/vl_video_buffer.h"
#include "radeonsi/si_pipe.h"
#include "radeon_video.h"
#include "radeon_vce.h"
#define FW_40_2_2 ((40 << 24) | (2 << 16) | (2 << 8))
#define FW_50_0_1 ((50 << 24) | (0 << 16) | (1 << 8))
#define FW_50_1_2 ((50 << 24) | (1 << 16) | (2 << 8))
#include "pipe/p_video_codec.h"
#include "radeon_video.h"
#include "radeonsi/si_pipe.h"
#include "util/u_memory.h"
#include "util/u_video.h"
#include "vl/vl_video_buffer.h"
#include <stdio.h>
#define FW_40_2_2 ((40 << 24) | (2 << 16) | (2 << 8))
#define FW_50_0_1 ((50 << 24) | (0 << 16) | (1 << 8))
#define FW_50_1_2 ((50 << 24) | (1 << 16) | (2 << 8))
#define FW_50_10_2 ((50 << 24) | (10 << 16) | (2 << 8))
#define FW_50_17_3 ((50 << 24) | (17 << 16) | (3 << 8))
#define FW_52_0_3 ((52 << 24) | (0 << 16) | (3 << 8))
#define FW_52_4_3 ((52 << 24) | (4 << 16) | (3 << 8))
#define FW_52_8_3 ((52 << 24) | (8 << 16) | (3 << 8))
#define FW_53 (53 << 24)
#define FW_52_0_3 ((52 << 24) | (0 << 16) | (3 << 8))
#define FW_52_4_3 ((52 << 24) | (4 << 16) | (3 << 8))
#define FW_52_8_3 ((52 << 24) | (8 << 16) | (3 << 8))
#define FW_53 (53 << 24)
/**
* flush commands to the hardware
*/
static void flush(struct rvce_encoder *enc)
{
enc->ws->cs_flush(enc->cs, PIPE_FLUSH_ASYNC, NULL);
enc->task_info_idx = 0;
enc->bs_idx = 0;
enc->ws->cs_flush(enc->cs, PIPE_FLUSH_ASYNC, NULL);
enc->task_info_idx = 0;
enc->bs_idx = 0;
}
#if 0
@ -89,17 +87,17 @@ static void dump_feedback(struct rvce_encoder *enc, struct rvid_buffer *fb)
*/
static void reset_cpb(struct rvce_encoder *enc)
{
unsigned i;
unsigned i;
list_inithead(&enc->cpb_slots);
for (i = 0; i < enc->cpb_num; ++i) {
struct rvce_cpb_slot *slot = &enc->cpb_array[i];
slot->index = i;
slot->picture_type = PIPE_H264_ENC_PICTURE_TYPE_SKIP;
slot->frame_num = 0;
slot->pic_order_cnt = 0;
list_addtail(&slot->list, &enc->cpb_slots);
}
list_inithead(&enc->cpb_slots);
for (i = 0; i < enc->cpb_num; ++i) {
struct rvce_cpb_slot *slot = &enc->cpb_array[i];
slot->index = i;
slot->picture_type = PIPE_H264_ENC_PICTURE_TYPE_SKIP;
slot->frame_num = 0;
slot->pic_order_cnt = 0;
list_addtail(&slot->list, &enc->cpb_slots);
}
}
/**
@ -107,32 +105,31 @@ static void reset_cpb(struct rvce_encoder *enc)
*/
static void sort_cpb(struct rvce_encoder *enc)
{
struct rvce_cpb_slot *i, *l0 = NULL, *l1 = NULL;
struct rvce_cpb_slot *i, *l0 = NULL, *l1 = NULL;
LIST_FOR_EACH_ENTRY(i, &enc->cpb_slots, list) {
if (i->frame_num == enc->pic.ref_idx_l0)
l0 = i;
LIST_FOR_EACH_ENTRY (i, &enc->cpb_slots, list) {
if (i->frame_num == enc->pic.ref_idx_l0)
l0 = i;
if (i->frame_num == enc->pic.ref_idx_l1)
l1 = i;
if (i->frame_num == enc->pic.ref_idx_l1)
l1 = i;
if (enc->pic.picture_type == PIPE_H264_ENC_PICTURE_TYPE_P && l0)
break;
if (enc->pic.picture_type == PIPE_H264_ENC_PICTURE_TYPE_P && l0)
break;
if (enc->pic.picture_type == PIPE_H264_ENC_PICTURE_TYPE_B &&
l0 && l1)
break;
}
if (enc->pic.picture_type == PIPE_H264_ENC_PICTURE_TYPE_B && l0 && l1)
break;
}
if (l1) {
list_del(&l1->list);
list_add(&l1->list, &enc->cpb_slots);
}
if (l1) {
list_del(&l1->list);
list_add(&l1->list, &enc->cpb_slots);
}
if (l0) {
list_del(&l0->list);
list_add(&l0->list, &enc->cpb_slots);
}
if (l0) {
list_del(&l0->list);
list_add(&l0->list, &enc->cpb_slots);
}
}
/**
@ -140,53 +137,53 @@ static void sort_cpb(struct rvce_encoder *enc)
*/
static unsigned get_cpb_num(struct rvce_encoder *enc)
{
unsigned w = align(enc->base.width, 16) / 16;
unsigned h = align(enc->base.height, 16) / 16;
unsigned dpb;
unsigned w = align(enc->base.width, 16) / 16;
unsigned h = align(enc->base.height, 16) / 16;
unsigned dpb;
switch (enc->base.level) {
case 10:
dpb = 396;
break;
case 11:
dpb = 900;
break;
case 12:
case 13:
case 20:
dpb = 2376;
break;
case 21:
dpb = 4752;
break;
case 22:
case 30:
dpb = 8100;
break;
case 31:
dpb = 18000;
break;
case 32:
dpb = 20480;
break;
case 40:
case 41:
dpb = 32768;
break;
case 42:
dpb = 34816;
break;
case 50:
dpb = 110400;
break;
default:
case 51:
case 52:
dpb = 184320;
break;
}
switch (enc->base.level) {
case 10:
dpb = 396;
break;
case 11:
dpb = 900;
break;
case 12:
case 13:
case 20:
dpb = 2376;
break;
case 21:
dpb = 4752;
break;
case 22:
case 30:
dpb = 8100;
break;
case 31:
dpb = 18000;
break;
case 32:
dpb = 20480;
break;
case 40:
case 41:
dpb = 32768;
break;
case 42:
dpb = 34816;
break;
case 50:
dpb = 110400;
break;
default:
case 51:
case 52:
dpb = 184320;
break;
}
return MIN2(dpb / (w * h), 16);
return MIN2(dpb / (w * h), 16);
}
/**
@ -194,7 +191,7 @@ static unsigned get_cpb_num(struct rvce_encoder *enc)
*/
struct rvce_cpb_slot *si_current_slot(struct rvce_encoder *enc)
{
return LIST_ENTRY(struct rvce_cpb_slot, enc->cpb_slots.prev, list);
return LIST_ENTRY(struct rvce_cpb_slot, enc->cpb_slots.prev, list);
}
/**
@ -202,7 +199,7 @@ struct rvce_cpb_slot *si_current_slot(struct rvce_encoder *enc)
*/
struct rvce_cpb_slot *si_l0_slot(struct rvce_encoder *enc)
{
return LIST_ENTRY(struct rvce_cpb_slot, enc->cpb_slots.next, list);
return LIST_ENTRY(struct rvce_cpb_slot, enc->cpb_slots.next, list);
}
/**
@ -210,29 +207,29 @@ struct rvce_cpb_slot *si_l0_slot(struct rvce_encoder *enc)
*/
struct rvce_cpb_slot *si_l1_slot(struct rvce_encoder *enc)
{
return LIST_ENTRY(struct rvce_cpb_slot, enc->cpb_slots.next->next, list);
return LIST_ENTRY(struct rvce_cpb_slot, enc->cpb_slots.next->next, list);
}
/**
* Calculate the offsets into the CPB
*/
void si_vce_frame_offset(struct rvce_encoder *enc, struct rvce_cpb_slot *slot,
signed *luma_offset, signed *chroma_offset)
void si_vce_frame_offset(struct rvce_encoder *enc, struct rvce_cpb_slot *slot, signed *luma_offset,
signed *chroma_offset)
{
struct si_screen *sscreen = (struct si_screen *)enc->screen;
unsigned pitch, vpitch, fsize;
struct si_screen *sscreen = (struct si_screen *)enc->screen;
unsigned pitch, vpitch, fsize;
if (sscreen->info.chip_class < GFX9) {
pitch = align(enc->luma->u.legacy.level[0].nblk_x * enc->luma->bpe, 128);
vpitch = align(enc->luma->u.legacy.level[0].nblk_y, 16);
} else {
pitch = align(enc->luma->u.gfx9.surf_pitch * enc->luma->bpe, 256);
vpitch = align(enc->luma->u.gfx9.surf_height, 16);
}
fsize = pitch * (vpitch + vpitch / 2);
if (sscreen->info.chip_class < GFX9) {
pitch = align(enc->luma->u.legacy.level[0].nblk_x * enc->luma->bpe, 128);
vpitch = align(enc->luma->u.legacy.level[0].nblk_y, 16);
} else {
pitch = align(enc->luma->u.gfx9.surf_pitch * enc->luma->bpe, 256);
vpitch = align(enc->luma->u.gfx9.surf_height, 16);
}
fsize = pitch * (vpitch + vpitch / 2);
*luma_offset = slot->index * fsize;
*chroma_offset = *luma_offset + pitch * vpitch;
*luma_offset = slot->index * fsize;
*chroma_offset = *luma_offset + pitch * vpitch;
}
/**
@ -240,134 +237,128 @@ void si_vce_frame_offset(struct rvce_encoder *enc, struct rvce_cpb_slot *slot,
*/
static void rvce_destroy(struct pipe_video_codec *encoder)
{
struct rvce_encoder *enc = (struct rvce_encoder*)encoder;
if (enc->stream_handle) {
struct rvid_buffer fb;
si_vid_create_buffer(enc->screen, &fb, 512, PIPE_USAGE_STAGING);
enc->fb = &fb;
enc->session(enc);
enc->destroy(enc);
flush(enc);
si_vid_destroy_buffer(&fb);
}
si_vid_destroy_buffer(&enc->cpb);
enc->ws->cs_destroy(enc->cs);
FREE(enc->cpb_array);
FREE(enc);
struct rvce_encoder *enc = (struct rvce_encoder *)encoder;
if (enc->stream_handle) {
struct rvid_buffer fb;
si_vid_create_buffer(enc->screen, &fb, 512, PIPE_USAGE_STAGING);
enc->fb = &fb;
enc->session(enc);
enc->destroy(enc);
flush(enc);
si_vid_destroy_buffer(&fb);
}
si_vid_destroy_buffer(&enc->cpb);
enc->ws->cs_destroy(enc->cs);
FREE(enc->cpb_array);
FREE(enc);
}
static void rvce_begin_frame(struct pipe_video_codec *encoder,
struct pipe_video_buffer *source,
struct pipe_picture_desc *picture)
static void rvce_begin_frame(struct pipe_video_codec *encoder, struct pipe_video_buffer *source,
struct pipe_picture_desc *picture)
{
struct rvce_encoder *enc = (struct rvce_encoder*)encoder;
struct vl_video_buffer *vid_buf = (struct vl_video_buffer *)source;
struct pipe_h264_enc_picture_desc *pic = (struct pipe_h264_enc_picture_desc *)picture;
struct rvce_encoder *enc = (struct rvce_encoder *)encoder;
struct vl_video_buffer *vid_buf = (struct vl_video_buffer *)source;
struct pipe_h264_enc_picture_desc *pic = (struct pipe_h264_enc_picture_desc *)picture;
bool need_rate_control =
enc->pic.rate_ctrl.rate_ctrl_method != pic->rate_ctrl.rate_ctrl_method ||
enc->pic.quant_i_frames != pic->quant_i_frames ||
enc->pic.quant_p_frames != pic->quant_p_frames ||
enc->pic.quant_b_frames != pic->quant_b_frames ||
enc->pic.rate_ctrl.target_bitrate != pic->rate_ctrl.target_bitrate;
bool need_rate_control =
enc->pic.rate_ctrl.rate_ctrl_method != pic->rate_ctrl.rate_ctrl_method ||
enc->pic.quant_i_frames != pic->quant_i_frames ||
enc->pic.quant_p_frames != pic->quant_p_frames ||
enc->pic.quant_b_frames != pic->quant_b_frames ||
enc->pic.rate_ctrl.target_bitrate != pic->rate_ctrl.target_bitrate;
enc->pic = *pic;
enc->si_get_pic_param(enc, pic);
enc->pic = *pic;
enc->si_get_pic_param(enc, pic);
enc->get_buffer(vid_buf->resources[0], &enc->handle, &enc->luma);
enc->get_buffer(vid_buf->resources[1], NULL, &enc->chroma);
enc->get_buffer(vid_buf->resources[0], &enc->handle, &enc->luma);
enc->get_buffer(vid_buf->resources[1], NULL, &enc->chroma);
if (pic->picture_type == PIPE_H264_ENC_PICTURE_TYPE_IDR)
reset_cpb(enc);
else if (pic->picture_type == PIPE_H264_ENC_PICTURE_TYPE_P ||
pic->picture_type == PIPE_H264_ENC_PICTURE_TYPE_B)
sort_cpb(enc);
if (!enc->stream_handle) {
struct rvid_buffer fb;
enc->stream_handle = si_vid_alloc_stream_handle();
si_vid_create_buffer(enc->screen, &fb, 512, PIPE_USAGE_STAGING);
enc->fb = &fb;
enc->session(enc);
enc->create(enc);
enc->config(enc);
enc->feedback(enc);
flush(enc);
//dump_feedback(enc, &fb);
si_vid_destroy_buffer(&fb);
need_rate_control = false;
}
if (pic->picture_type == PIPE_H264_ENC_PICTURE_TYPE_IDR)
reset_cpb(enc);
else if (pic->picture_type == PIPE_H264_ENC_PICTURE_TYPE_P ||
pic->picture_type == PIPE_H264_ENC_PICTURE_TYPE_B)
sort_cpb(enc);
if (need_rate_control) {
enc->session(enc);
enc->config(enc);
flush(enc);
}
if (!enc->stream_handle) {
struct rvid_buffer fb;
enc->stream_handle = si_vid_alloc_stream_handle();
si_vid_create_buffer(enc->screen, &fb, 512, PIPE_USAGE_STAGING);
enc->fb = &fb;
enc->session(enc);
enc->create(enc);
enc->config(enc);
enc->feedback(enc);
flush(enc);
// dump_feedback(enc, &fb);
si_vid_destroy_buffer(&fb);
need_rate_control = false;
}
if (need_rate_control) {
enc->session(enc);
enc->config(enc);
flush(enc);
}
}
static void rvce_encode_bitstream(struct pipe_video_codec *encoder,
struct pipe_video_buffer *source,
struct pipe_resource *destination,
void **fb)
struct pipe_video_buffer *source,
struct pipe_resource *destination, void **fb)
{
struct rvce_encoder *enc = (struct rvce_encoder*)encoder;
enc->get_buffer(destination, &enc->bs_handle, NULL);
enc->bs_size = destination->width0;
struct rvce_encoder *enc = (struct rvce_encoder *)encoder;
enc->get_buffer(destination, &enc->bs_handle, NULL);
enc->bs_size = destination->width0;
*fb = enc->fb = CALLOC_STRUCT(rvid_buffer);
if (!si_vid_create_buffer(enc->screen, enc->fb, 512, PIPE_USAGE_STAGING)) {
RVID_ERR("Can't create feedback buffer.\n");
return;
}
if (!radeon_emitted(enc->cs, 0))
enc->session(enc);
enc->encode(enc);
enc->feedback(enc);
*fb = enc->fb = CALLOC_STRUCT(rvid_buffer);
if (!si_vid_create_buffer(enc->screen, enc->fb, 512, PIPE_USAGE_STAGING)) {
RVID_ERR("Can't create feedback buffer.\n");
return;
}
if (!radeon_emitted(enc->cs, 0))
enc->session(enc);
enc->encode(enc);
enc->feedback(enc);
}
static void rvce_end_frame(struct pipe_video_codec *encoder,
struct pipe_video_buffer *source,
struct pipe_picture_desc *picture)
static void rvce_end_frame(struct pipe_video_codec *encoder, struct pipe_video_buffer *source,
struct pipe_picture_desc *picture)
{
struct rvce_encoder *enc = (struct rvce_encoder*)encoder;
struct rvce_cpb_slot *slot = LIST_ENTRY(
struct rvce_cpb_slot, enc->cpb_slots.prev, list);
struct rvce_encoder *enc = (struct rvce_encoder *)encoder;
struct rvce_cpb_slot *slot = LIST_ENTRY(struct rvce_cpb_slot, enc->cpb_slots.prev, list);
if (!enc->dual_inst || enc->bs_idx > 1)
flush(enc);
if (!enc->dual_inst || enc->bs_idx > 1)
flush(enc);
/* update the CPB backtrack with the just encoded frame */
slot->picture_type = enc->pic.picture_type;
slot->frame_num = enc->pic.frame_num;
slot->pic_order_cnt = enc->pic.pic_order_cnt;
if (!enc->pic.not_referenced) {
list_del(&slot->list);
list_add(&slot->list, &enc->cpb_slots);
}
/* update the CPB backtrack with the just encoded frame */
slot->picture_type = enc->pic.picture_type;
slot->frame_num = enc->pic.frame_num;
slot->pic_order_cnt = enc->pic.pic_order_cnt;
if (!enc->pic.not_referenced) {
list_del(&slot->list);
list_add(&slot->list, &enc->cpb_slots);
}
}
static void rvce_get_feedback(struct pipe_video_codec *encoder,
void *feedback, unsigned *size)
static void rvce_get_feedback(struct pipe_video_codec *encoder, void *feedback, unsigned *size)
{
struct rvce_encoder *enc = (struct rvce_encoder*)encoder;
struct rvid_buffer *fb = feedback;
struct rvce_encoder *enc = (struct rvce_encoder *)encoder;
struct rvid_buffer *fb = feedback;
if (size) {
uint32_t *ptr = enc->ws->buffer_map(
fb->res->buf, enc->cs,
PIPE_TRANSFER_READ_WRITE | RADEON_TRANSFER_TEMPORARY);
if (size) {
uint32_t *ptr = enc->ws->buffer_map(fb->res->buf, enc->cs,
PIPE_TRANSFER_READ_WRITE | RADEON_TRANSFER_TEMPORARY);
if (ptr[1]) {
*size = ptr[4] - ptr[9];
} else {
*size = 0;
}
if (ptr[1]) {
*size = ptr[4] - ptr[9];
} else {
*size = 0;
}
enc->ws->buffer_unmap(fb->res->buf);
}
//dump_feedback(enc, fb);
si_vid_destroy_buffer(fb);
FREE(fb);
enc->ws->buffer_unmap(fb->res->buf);
}
// dump_feedback(enc, fb);
si_vid_destroy_buffer(fb);
FREE(fb);
}
/**
@ -375,153 +366,147 @@ static void rvce_get_feedback(struct pipe_video_codec *encoder,
*/
static void rvce_flush(struct pipe_video_codec *encoder)
{
struct rvce_encoder *enc = (struct rvce_encoder*)encoder;
struct rvce_encoder *enc = (struct rvce_encoder *)encoder;
flush(enc);
flush(enc);
}
static void rvce_cs_flush(void *ctx, unsigned flags,
struct pipe_fence_handle **fence)
static void rvce_cs_flush(void *ctx, unsigned flags, struct pipe_fence_handle **fence)
{
// just ignored
// just ignored
}
struct pipe_video_codec *si_vce_create_encoder(struct pipe_context *context,
const struct pipe_video_codec *templ,
struct radeon_winsys* ws,
rvce_get_buffer get_buffer)
const struct pipe_video_codec *templ,
struct radeon_winsys *ws, rvce_get_buffer get_buffer)
{
struct si_screen *sscreen = (struct si_screen *)context->screen;
struct si_context *sctx = (struct si_context*)context;
struct rvce_encoder *enc;
struct pipe_video_buffer *tmp_buf, templat = {};
struct radeon_surf *tmp_surf;
unsigned cpb_size;
struct si_screen *sscreen = (struct si_screen *)context->screen;
struct si_context *sctx = (struct si_context *)context;
struct rvce_encoder *enc;
struct pipe_video_buffer *tmp_buf, templat = {};
struct radeon_surf *tmp_surf;
unsigned cpb_size;
if (!sscreen->info.vce_fw_version) {
RVID_ERR("Kernel doesn't supports VCE!\n");
return NULL;
if (!sscreen->info.vce_fw_version) {
RVID_ERR("Kernel doesn't supports VCE!\n");
return NULL;
} else if (!si_vce_is_fw_version_supported(sscreen)) {
RVID_ERR("Unsupported VCE fw version loaded!\n");
return NULL;
}
} else if (!si_vce_is_fw_version_supported(sscreen)) {
RVID_ERR("Unsupported VCE fw version loaded!\n");
return NULL;
}
enc = CALLOC_STRUCT(rvce_encoder);
if (!enc)
return NULL;
enc = CALLOC_STRUCT(rvce_encoder);
if (!enc)
return NULL;
if (sscreen->info.is_amdgpu)
enc->use_vm = true;
if ((!sscreen->info.is_amdgpu && sscreen->info.drm_minor >= 42) ||
sscreen->info.is_amdgpu)
enc->use_vui = true;
if (sscreen->info.family >= CHIP_TONGA &&
sscreen->info.family != CHIP_STONEY &&
sscreen->info.family != CHIP_POLARIS11 &&
sscreen->info.family != CHIP_POLARIS12 &&
sscreen->info.family != CHIP_VEGAM)
enc->dual_pipe = true;
/* TODO enable B frame with dual instance */
if ((sscreen->info.family >= CHIP_TONGA) &&
(templ->max_references == 1) &&
(sscreen->info.vce_harvest_config == 0))
enc->dual_inst = true;
if (sscreen->info.is_amdgpu)
enc->use_vm = true;
if ((!sscreen->info.is_amdgpu && sscreen->info.drm_minor >= 42) || sscreen->info.is_amdgpu)
enc->use_vui = true;
if (sscreen->info.family >= CHIP_TONGA && sscreen->info.family != CHIP_STONEY &&
sscreen->info.family != CHIP_POLARIS11 && sscreen->info.family != CHIP_POLARIS12 &&
sscreen->info.family != CHIP_VEGAM)
enc->dual_pipe = true;
/* TODO enable B frame with dual instance */
if ((sscreen->info.family >= CHIP_TONGA) && (templ->max_references == 1) &&
(sscreen->info.vce_harvest_config == 0))
enc->dual_inst = true;
enc->base = *templ;
enc->base.context = context;
enc->base = *templ;
enc->base.context = context;
enc->base.destroy = rvce_destroy;
enc->base.begin_frame = rvce_begin_frame;
enc->base.encode_bitstream = rvce_encode_bitstream;
enc->base.end_frame = rvce_end_frame;
enc->base.flush = rvce_flush;
enc->base.get_feedback = rvce_get_feedback;
enc->get_buffer = get_buffer;
enc->base.destroy = rvce_destroy;
enc->base.begin_frame = rvce_begin_frame;
enc->base.encode_bitstream = rvce_encode_bitstream;
enc->base.end_frame = rvce_end_frame;
enc->base.flush = rvce_flush;
enc->base.get_feedback = rvce_get_feedback;
enc->get_buffer = get_buffer;
enc->screen = context->screen;
enc->ws = ws;
enc->cs = ws->cs_create(sctx->ctx, RING_VCE, rvce_cs_flush, enc, false);
if (!enc->cs) {
RVID_ERR("Can't get command submission context.\n");
goto error;
}
enc->screen = context->screen;
enc->ws = ws;
enc->cs = ws->cs_create(sctx->ctx, RING_VCE, rvce_cs_flush, enc, false);
if (!enc->cs) {
RVID_ERR("Can't get command submission context.\n");
goto error;
}
templat.buffer_format = PIPE_FORMAT_NV12;
templat.width = enc->base.width;
templat.height = enc->base.height;
templat.interlaced = false;
if (!(tmp_buf = context->create_video_buffer(context, &templat))) {
RVID_ERR("Can't create video buffer.\n");
goto error;
}
templat.buffer_format = PIPE_FORMAT_NV12;
templat.width = enc->base.width;
templat.height = enc->base.height;
templat.interlaced = false;
if (!(tmp_buf = context->create_video_buffer(context, &templat))) {
RVID_ERR("Can't create video buffer.\n");
goto error;
}
enc->cpb_num = get_cpb_num(enc);
if (!enc->cpb_num)
goto error;
enc->cpb_num = get_cpb_num(enc);
if (!enc->cpb_num)
goto error;
get_buffer(((struct vl_video_buffer *)tmp_buf)->resources[0], NULL, &tmp_surf);
get_buffer(((struct vl_video_buffer *)tmp_buf)->resources[0], NULL, &tmp_surf);
cpb_size = (sscreen->info.chip_class < GFX9) ?
align(tmp_surf->u.legacy.level[0].nblk_x * tmp_surf->bpe, 128) *
align(tmp_surf->u.legacy.level[0].nblk_y, 32) :
cpb_size = (sscreen->info.chip_class < GFX9)
? align(tmp_surf->u.legacy.level[0].nblk_x * tmp_surf->bpe, 128) *
align(tmp_surf->u.legacy.level[0].nblk_y, 32)
:
align(tmp_surf->u.gfx9.surf_pitch * tmp_surf->bpe, 256) *
align(tmp_surf->u.gfx9.surf_height, 32);
align(tmp_surf->u.gfx9.surf_pitch * tmp_surf->bpe, 256) *
align(tmp_surf->u.gfx9.surf_height, 32);
cpb_size = cpb_size * 3 / 2;
cpb_size = cpb_size * enc->cpb_num;
if (enc->dual_pipe)
cpb_size += RVCE_MAX_AUX_BUFFER_NUM *
RVCE_MAX_BITSTREAM_OUTPUT_ROW_SIZE * 2;
tmp_buf->destroy(tmp_buf);
if (!si_vid_create_buffer(enc->screen, &enc->cpb, cpb_size, PIPE_USAGE_DEFAULT)) {
RVID_ERR("Can't create CPB buffer.\n");
goto error;
}
cpb_size = cpb_size * 3 / 2;
cpb_size = cpb_size * enc->cpb_num;
if (enc->dual_pipe)
cpb_size += RVCE_MAX_AUX_BUFFER_NUM * RVCE_MAX_BITSTREAM_OUTPUT_ROW_SIZE * 2;
tmp_buf->destroy(tmp_buf);
if (!si_vid_create_buffer(enc->screen, &enc->cpb, cpb_size, PIPE_USAGE_DEFAULT)) {
RVID_ERR("Can't create CPB buffer.\n");
goto error;
}
enc->cpb_array = CALLOC(enc->cpb_num, sizeof(struct rvce_cpb_slot));
if (!enc->cpb_array)
goto error;
enc->cpb_array = CALLOC(enc->cpb_num, sizeof(struct rvce_cpb_slot));
if (!enc->cpb_array)
goto error;
reset_cpb(enc);
reset_cpb(enc);
switch (sscreen->info.vce_fw_version) {
case FW_40_2_2:
si_vce_40_2_2_init(enc);
break;
switch (sscreen->info.vce_fw_version) {
case FW_40_2_2:
si_vce_40_2_2_init(enc);
break;
case FW_50_0_1:
case FW_50_1_2:
case FW_50_10_2:
case FW_50_17_3:
si_vce_50_init(enc);
break;
case FW_50_0_1:
case FW_50_1_2:
case FW_50_10_2:
case FW_50_17_3:
si_vce_50_init(enc);
break;
case FW_52_0_3:
case FW_52_4_3:
case FW_52_8_3:
si_vce_52_init(enc);
break;
case FW_52_0_3:
case FW_52_4_3:
case FW_52_8_3:
si_vce_52_init(enc);
break;
default:
if ((sscreen->info.vce_fw_version & (0xff << 24)) >= FW_53) {
si_vce_52_init(enc);
} else
goto error;
}
default:
if ((sscreen->info.vce_fw_version & (0xff << 24)) >= FW_53) {
si_vce_52_init(enc);
} else
goto error;
}
return &enc->base;
return &enc->base;
error:
if (enc->cs)
enc->ws->cs_destroy(enc->cs);
if (enc->cs)
enc->ws->cs_destroy(enc->cs);
si_vid_destroy_buffer(&enc->cpb);
si_vid_destroy_buffer(&enc->cpb);
FREE(enc->cpb_array);
FREE(enc);
return NULL;
FREE(enc->cpb_array);
FREE(enc);
return NULL;
}
/**
@ -529,44 +514,42 @@ error:
*/
bool si_vce_is_fw_version_supported(struct si_screen *sscreen)
{
switch (sscreen->info.vce_fw_version) {
case FW_40_2_2:
case FW_50_0_1:
case FW_50_1_2:
case FW_50_10_2:
case FW_50_17_3:
case FW_52_0_3:
case FW_52_4_3:
case FW_52_8_3:
return true;
default:
if ((sscreen->info.vce_fw_version & (0xff << 24)) >= FW_53)
return true;
else
return false;
}
switch (sscreen->info.vce_fw_version) {
case FW_40_2_2:
case FW_50_0_1:
case FW_50_1_2:
case FW_50_10_2:
case FW_50_17_3:
case FW_52_0_3:
case FW_52_4_3:
case FW_52_8_3:
return true;
default:
if ((sscreen->info.vce_fw_version & (0xff << 24)) >= FW_53)
return true;
else
return false;
}
}
/**
* Add the buffer as relocation to the current command submission
*/
void si_vce_add_buffer(struct rvce_encoder *enc, struct pb_buffer *buf,
enum radeon_bo_usage usage, enum radeon_bo_domain domain,
signed offset)
void si_vce_add_buffer(struct rvce_encoder *enc, struct pb_buffer *buf, enum radeon_bo_usage usage,
enum radeon_bo_domain domain, signed offset)
{
int reloc_idx;
int reloc_idx;
reloc_idx = enc->ws->cs_add_buffer(enc->cs, buf, usage | RADEON_USAGE_SYNCHRONIZED,
domain, 0);
if (enc->use_vm) {
uint64_t addr;
addr = enc->ws->buffer_get_virtual_address(buf);
addr = addr + offset;
RVCE_CS(addr >> 32);
RVCE_CS(addr);
} else {
offset += enc->ws->buffer_get_reloc_offset(buf);
RVCE_CS(reloc_idx * 4);
RVCE_CS(offset);
}
reloc_idx = enc->ws->cs_add_buffer(enc->cs, buf, usage | RADEON_USAGE_SYNCHRONIZED, domain, 0);
if (enc->use_vm) {
uint64_t addr;
addr = enc->ws->buffer_get_virtual_address(buf);
addr = addr + offset;
RVCE_CS(addr >> 32);
RVCE_CS(addr);
} else {
offset += enc->ws->buffer_get_reloc_offset(buf);
RVCE_CS(reloc_idx * 4);
RVCE_CS(offset);
}
}

View File

@ -28,408 +28,412 @@
#ifndef RADEON_VCE_H
#define RADEON_VCE_H
#include "util/list.h"
#include "radeon_video.h"
#include "util/list.h"
#define RVCE_CS(value) (enc->cs->current.buf[enc->cs->current.cdw++] = (value))
#define RVCE_BEGIN(cmd) { \
uint32_t *begin = &enc->cs->current.buf[enc->cs->current.cdw++]; \
RVCE_CS(cmd)
#define RVCE_READ(buf, domain, off) si_vce_add_buffer(enc, (buf), RADEON_USAGE_READ, (domain), (off))
#define RVCE_WRITE(buf, domain, off) si_vce_add_buffer(enc, (buf), RADEON_USAGE_WRITE, (domain), (off))
#define RVCE_READWRITE(buf, domain, off) si_vce_add_buffer(enc, (buf), RADEON_USAGE_READWRITE, (domain), (off))
#define RVCE_END() *begin = (&enc->cs->current.buf[enc->cs->current.cdw] - begin) * 4; }
#define RVCE_BEGIN(cmd) \
{ \
uint32_t *begin = &enc->cs->current.buf[enc->cs->current.cdw++]; \
RVCE_CS(cmd)
#define RVCE_READ(buf, domain, off) \
si_vce_add_buffer(enc, (buf), RADEON_USAGE_READ, (domain), (off))
#define RVCE_WRITE(buf, domain, off) \
si_vce_add_buffer(enc, (buf), RADEON_USAGE_WRITE, (domain), (off))
#define RVCE_READWRITE(buf, domain, off) \
si_vce_add_buffer(enc, (buf), RADEON_USAGE_READWRITE, (domain), (off))
#define RVCE_END() \
*begin = (&enc->cs->current.buf[enc->cs->current.cdw] - begin) * 4; \
}
#define RVCE_MAX_BITSTREAM_OUTPUT_ROW_SIZE (4096 * 16 * 2.5)
#define RVCE_MAX_AUX_BUFFER_NUM 4
#define RVCE_MAX_AUX_BUFFER_NUM 4
struct si_screen;
/* driver dependent callback */
typedef void (*rvce_get_buffer)(struct pipe_resource *resource,
struct pb_buffer **handle,
struct radeon_surf **surface);
typedef void (*rvce_get_buffer)(struct pipe_resource *resource, struct pb_buffer **handle,
struct radeon_surf **surface);
/* Coded picture buffer slot */
struct rvce_cpb_slot {
struct list_head list;
struct list_head list;
unsigned index;
enum pipe_h264_enc_picture_type picture_type;
unsigned frame_num;
unsigned pic_order_cnt;
unsigned index;
enum pipe_h264_enc_picture_type picture_type;
unsigned frame_num;
unsigned pic_order_cnt;
};
struct rvce_rate_control {
uint32_t rc_method;
uint32_t target_bitrate;
uint32_t peak_bitrate;
uint32_t frame_rate_num;
uint32_t gop_size;
uint32_t quant_i_frames;
uint32_t quant_p_frames;
uint32_t quant_b_frames;
uint32_t vbv_buffer_size;
uint32_t frame_rate_den;
uint32_t vbv_buf_lv;
uint32_t max_au_size;
uint32_t qp_initial_mode;
uint32_t target_bits_picture;
uint32_t peak_bits_picture_integer;
uint32_t peak_bits_picture_fraction;
uint32_t min_qp;
uint32_t max_qp;
uint32_t skip_frame_enable;
uint32_t fill_data_enable;
uint32_t enforce_hrd;
uint32_t b_pics_delta_qp;
uint32_t ref_b_pics_delta_qp;
uint32_t rc_reinit_disable;
uint32_t enc_lcvbr_init_qp_flag;
uint32_t lcvbrsatd_based_nonlinear_bit_budget_flag;
uint32_t rc_method;
uint32_t target_bitrate;
uint32_t peak_bitrate;
uint32_t frame_rate_num;
uint32_t gop_size;
uint32_t quant_i_frames;
uint32_t quant_p_frames;
uint32_t quant_b_frames;
uint32_t vbv_buffer_size;
uint32_t frame_rate_den;
uint32_t vbv_buf_lv;
uint32_t max_au_size;
uint32_t qp_initial_mode;
uint32_t target_bits_picture;
uint32_t peak_bits_picture_integer;
uint32_t peak_bits_picture_fraction;
uint32_t min_qp;
uint32_t max_qp;
uint32_t skip_frame_enable;
uint32_t fill_data_enable;
uint32_t enforce_hrd;
uint32_t b_pics_delta_qp;
uint32_t ref_b_pics_delta_qp;
uint32_t rc_reinit_disable;
uint32_t enc_lcvbr_init_qp_flag;
uint32_t lcvbrsatd_based_nonlinear_bit_budget_flag;
};
struct rvce_motion_estimation {
uint32_t enc_ime_decimation_search;
uint32_t motion_est_half_pixel;
uint32_t motion_est_quarter_pixel;
uint32_t disable_favor_pmv_point;
uint32_t force_zero_point_center;
uint32_t lsmvert;
uint32_t enc_search_range_x;
uint32_t enc_search_range_y;
uint32_t enc_search1_range_x;
uint32_t enc_search1_range_y;
uint32_t disable_16x16_frame1;
uint32_t disable_satd;
uint32_t enable_amd;
uint32_t enc_disable_sub_mode;
uint32_t enc_ime_skip_x;
uint32_t enc_ime_skip_y;
uint32_t enc_en_ime_overw_dis_subm;
uint32_t enc_ime_overw_dis_subm_no;
uint32_t enc_ime2_search_range_x;
uint32_t enc_ime2_search_range_y;
uint32_t parallel_mode_speedup_enable;
uint32_t fme0_enc_disable_sub_mode;
uint32_t fme1_enc_disable_sub_mode;
uint32_t ime_sw_speedup_enable;
uint32_t enc_ime_decimation_search;
uint32_t motion_est_half_pixel;
uint32_t motion_est_quarter_pixel;
uint32_t disable_favor_pmv_point;
uint32_t force_zero_point_center;
uint32_t lsmvert;
uint32_t enc_search_range_x;
uint32_t enc_search_range_y;
uint32_t enc_search1_range_x;
uint32_t enc_search1_range_y;
uint32_t disable_16x16_frame1;
uint32_t disable_satd;
uint32_t enable_amd;
uint32_t enc_disable_sub_mode;
uint32_t enc_ime_skip_x;
uint32_t enc_ime_skip_y;
uint32_t enc_en_ime_overw_dis_subm;
uint32_t enc_ime_overw_dis_subm_no;
uint32_t enc_ime2_search_range_x;
uint32_t enc_ime2_search_range_y;
uint32_t parallel_mode_speedup_enable;
uint32_t fme0_enc_disable_sub_mode;
uint32_t fme1_enc_disable_sub_mode;
uint32_t ime_sw_speedup_enable;
};
struct rvce_pic_control {
uint32_t enc_use_constrained_intra_pred;
uint32_t enc_cabac_enable;
uint32_t enc_cabac_idc;
uint32_t enc_loop_filter_disable;
int32_t enc_lf_beta_offset;
int32_t enc_lf_alpha_c0_offset;
uint32_t enc_crop_left_offset;
uint32_t enc_crop_right_offset;
uint32_t enc_crop_top_offset;
uint32_t enc_crop_bottom_offset;
uint32_t enc_num_mbs_per_slice;
uint32_t enc_intra_refresh_num_mbs_per_slot;
uint32_t enc_force_intra_refresh;
uint32_t enc_force_imb_period;
uint32_t enc_pic_order_cnt_type;
uint32_t log2_max_pic_order_cnt_lsb_minus4;
uint32_t enc_sps_id;
uint32_t enc_pps_id;
uint32_t enc_constraint_set_flags;
uint32_t enc_b_pic_pattern;
uint32_t weight_pred_mode_b_picture;
uint32_t enc_number_of_reference_frames;
uint32_t enc_max_num_ref_frames;
uint32_t enc_num_default_active_ref_l0;
uint32_t enc_num_default_active_ref_l1;
uint32_t enc_slice_mode;
uint32_t enc_max_slice_size;
uint32_t enc_use_constrained_intra_pred;
uint32_t enc_cabac_enable;
uint32_t enc_cabac_idc;
uint32_t enc_loop_filter_disable;
int32_t enc_lf_beta_offset;
int32_t enc_lf_alpha_c0_offset;
uint32_t enc_crop_left_offset;
uint32_t enc_crop_right_offset;
uint32_t enc_crop_top_offset;
uint32_t enc_crop_bottom_offset;
uint32_t enc_num_mbs_per_slice;
uint32_t enc_intra_refresh_num_mbs_per_slot;
uint32_t enc_force_intra_refresh;
uint32_t enc_force_imb_period;
uint32_t enc_pic_order_cnt_type;
uint32_t log2_max_pic_order_cnt_lsb_minus4;
uint32_t enc_sps_id;
uint32_t enc_pps_id;
uint32_t enc_constraint_set_flags;
uint32_t enc_b_pic_pattern;
uint32_t weight_pred_mode_b_picture;
uint32_t enc_number_of_reference_frames;
uint32_t enc_max_num_ref_frames;
uint32_t enc_num_default_active_ref_l0;
uint32_t enc_num_default_active_ref_l1;
uint32_t enc_slice_mode;
uint32_t enc_max_slice_size;
};
struct rvce_task_info {
uint32_t offset_of_next_task_info;
uint32_t task_operation;
uint32_t reference_picture_dependency;
uint32_t collocate_flag_dependency;
uint32_t feedback_index;
uint32_t video_bitstream_ring_index;
uint32_t offset_of_next_task_info;
uint32_t task_operation;
uint32_t reference_picture_dependency;
uint32_t collocate_flag_dependency;
uint32_t feedback_index;
uint32_t video_bitstream_ring_index;
};
struct rvce_feedback_buf_pkg {
uint32_t feedback_ring_address_hi;
uint32_t feedback_ring_address_lo;
uint32_t feedback_ring_size;
uint32_t feedback_ring_address_hi;
uint32_t feedback_ring_address_lo;
uint32_t feedback_ring_size;
};
struct rvce_rdo {
uint32_t enc_disable_tbe_pred_i_frame;
uint32_t enc_disable_tbe_pred_p_frame;
uint32_t use_fme_interpol_y;
uint32_t use_fme_interpol_uv;
uint32_t use_fme_intrapol_y;
uint32_t use_fme_intrapol_uv;
uint32_t use_fme_interpol_y_1;
uint32_t use_fme_interpol_uv_1;
uint32_t use_fme_intrapol_y_1;
uint32_t use_fme_intrapol_uv_1;
uint32_t enc_16x16_cost_adj;
uint32_t enc_skip_cost_adj;
uint32_t enc_force_16x16_skip;
uint32_t enc_disable_threshold_calc_a;
uint32_t enc_luma_coeff_cost;
uint32_t enc_luma_mb_coeff_cost;
uint32_t enc_chroma_coeff_cost;
uint32_t enc_disable_tbe_pred_i_frame;
uint32_t enc_disable_tbe_pred_p_frame;
uint32_t use_fme_interpol_y;
uint32_t use_fme_interpol_uv;
uint32_t use_fme_intrapol_y;
uint32_t use_fme_intrapol_uv;
uint32_t use_fme_interpol_y_1;
uint32_t use_fme_interpol_uv_1;
uint32_t use_fme_intrapol_y_1;
uint32_t use_fme_intrapol_uv_1;
uint32_t enc_16x16_cost_adj;
uint32_t enc_skip_cost_adj;
uint32_t enc_force_16x16_skip;
uint32_t enc_disable_threshold_calc_a;
uint32_t enc_luma_coeff_cost;
uint32_t enc_luma_mb_coeff_cost;
uint32_t enc_chroma_coeff_cost;
};
struct rvce_vui {
uint32_t aspect_ratio_info_present_flag;
uint32_t aspect_ratio_idc;
uint32_t sar_width;
uint32_t sar_height;
uint32_t overscan_info_present_flag;
uint32_t overscan_Approp_flag;
uint32_t video_signal_type_present_flag;
uint32_t video_format;
uint32_t video_full_range_flag;
uint32_t color_description_present_flag;
uint32_t color_prim;
uint32_t transfer_char;
uint32_t matrix_coef;
uint32_t chroma_loc_info_present_flag;
uint32_t chroma_loc_top;
uint32_t chroma_loc_bottom;
uint32_t timing_info_present_flag;
uint32_t num_units_in_tick;
uint32_t time_scale;
uint32_t fixed_frame_rate_flag;
uint32_t nal_hrd_parameters_present_flag;
uint32_t cpb_cnt_minus1;
uint32_t bit_rate_scale;
uint32_t cpb_size_scale;
uint32_t bit_rate_value_minus;
uint32_t cpb_size_value_minus;
uint32_t cbr_flag;
uint32_t initial_cpb_removal_delay_length_minus1;
uint32_t cpb_removal_delay_length_minus1;
uint32_t dpb_output_delay_length_minus1;
uint32_t time_offset_length;
uint32_t low_delay_hrd_flag;
uint32_t pic_struct_present_flag;
uint32_t bitstream_restriction_present_flag;
uint32_t motion_vectors_over_pic_boundaries_flag;
uint32_t max_bytes_per_pic_denom;
uint32_t max_bits_per_mb_denom;
uint32_t log2_max_mv_length_hori;
uint32_t log2_max_mv_length_vert;
uint32_t num_reorder_frames;
uint32_t max_dec_frame_buffering;
uint32_t aspect_ratio_info_present_flag;
uint32_t aspect_ratio_idc;
uint32_t sar_width;
uint32_t sar_height;
uint32_t overscan_info_present_flag;
uint32_t overscan_Approp_flag;
uint32_t video_signal_type_present_flag;
uint32_t video_format;
uint32_t video_full_range_flag;
uint32_t color_description_present_flag;
uint32_t color_prim;
uint32_t transfer_char;
uint32_t matrix_coef;
uint32_t chroma_loc_info_present_flag;
uint32_t chroma_loc_top;
uint32_t chroma_loc_bottom;
uint32_t timing_info_present_flag;
uint32_t num_units_in_tick;
uint32_t time_scale;
uint32_t fixed_frame_rate_flag;
uint32_t nal_hrd_parameters_present_flag;
uint32_t cpb_cnt_minus1;
uint32_t bit_rate_scale;
uint32_t cpb_size_scale;
uint32_t bit_rate_value_minus;
uint32_t cpb_size_value_minus;
uint32_t cbr_flag;
uint32_t initial_cpb_removal_delay_length_minus1;
uint32_t cpb_removal_delay_length_minus1;
uint32_t dpb_output_delay_length_minus1;
uint32_t time_offset_length;
uint32_t low_delay_hrd_flag;
uint32_t pic_struct_present_flag;
uint32_t bitstream_restriction_present_flag;
uint32_t motion_vectors_over_pic_boundaries_flag;
uint32_t max_bytes_per_pic_denom;
uint32_t max_bits_per_mb_denom;
uint32_t log2_max_mv_length_hori;
uint32_t log2_max_mv_length_vert;
uint32_t num_reorder_frames;
uint32_t max_dec_frame_buffering;
};
struct rvce_enc_operation {
uint32_t insert_headers;
uint32_t picture_structure;
uint32_t allowed_max_bitstream_size;
uint32_t force_refresh_map;
uint32_t insert_aud;
uint32_t end_of_sequence;
uint32_t end_of_stream;
uint32_t input_picture_luma_address_hi;
uint32_t input_picture_luma_address_lo;
uint32_t input_picture_chroma_address_hi;
uint32_t input_picture_chroma_address_lo;
uint32_t enc_input_frame_y_pitch;
uint32_t enc_input_pic_luma_pitch;
uint32_t enc_input_pic_chroma_pitch;;
uint32_t enc_input_pic_addr_array;
uint32_t enc_input_pic_addr_array_disable2pipe_disablemboffload;
uint32_t enc_input_pic_tile_config;
uint32_t enc_pic_type;
uint32_t enc_idr_flag;
uint32_t enc_idr_pic_id;
uint32_t enc_mgs_key_pic;
uint32_t enc_reference_flag;
uint32_t enc_temporal_layer_index;
uint32_t num_ref_idx_active_override_flag;
uint32_t num_ref_idx_l0_active_minus1;
uint32_t num_ref_idx_l1_active_minus1;
uint32_t enc_ref_list_modification_op;
uint32_t enc_ref_list_modification_num;
uint32_t enc_decoded_picture_marking_op;
uint32_t enc_decoded_picture_marking_num;
uint32_t enc_decoded_picture_marking_idx;
uint32_t enc_decoded_ref_base_picture_marking_op;
uint32_t enc_decoded_ref_base_picture_marking_num;
uint32_t l0_picture_structure;
uint32_t l0_enc_pic_type;
uint32_t l0_frame_number;
uint32_t l0_picture_order_count;
uint32_t l0_luma_offset;
uint32_t l0_chroma_offset;
uint32_t l1_picture_structure;
uint32_t l1_enc_pic_type;
uint32_t l1_frame_number;
uint32_t l1_picture_order_count;
uint32_t l1_luma_offset;
uint32_t l1_chroma_offset;
uint32_t enc_reconstructed_luma_offset;
uint32_t enc_reconstructed_chroma_offset;;
uint32_t enc_coloc_buffer_offset;
uint32_t enc_reconstructed_ref_base_picture_luma_offset;
uint32_t enc_reconstructed_ref_base_picture_chroma_offset;
uint32_t enc_reference_ref_base_picture_luma_offset;
uint32_t enc_reference_ref_base_picture_chroma_offset;
uint32_t picture_count;
uint32_t frame_number;
uint32_t picture_order_count;
uint32_t num_i_pic_remain_in_rcgop;
uint32_t num_p_pic_remain_in_rcgop;
uint32_t num_b_pic_remain_in_rcgop;
uint32_t num_ir_pic_remain_in_rcgop;
uint32_t enable_intra_refresh;
uint32_t aq_variance_en;
uint32_t aq_block_size;
uint32_t aq_mb_variance_sel;
uint32_t aq_frame_variance_sel;
uint32_t aq_param_a;
uint32_t aq_param_b;
uint32_t aq_param_c;
uint32_t aq_param_d;
uint32_t aq_param_e;
uint32_t context_in_sfb;
uint32_t insert_headers;
uint32_t picture_structure;
uint32_t allowed_max_bitstream_size;
uint32_t force_refresh_map;
uint32_t insert_aud;
uint32_t end_of_sequence;
uint32_t end_of_stream;
uint32_t input_picture_luma_address_hi;
uint32_t input_picture_luma_address_lo;
uint32_t input_picture_chroma_address_hi;
uint32_t input_picture_chroma_address_lo;
uint32_t enc_input_frame_y_pitch;
uint32_t enc_input_pic_luma_pitch;
uint32_t enc_input_pic_chroma_pitch;
;
uint32_t enc_input_pic_addr_array;
uint32_t enc_input_pic_addr_array_disable2pipe_disablemboffload;
uint32_t enc_input_pic_tile_config;
uint32_t enc_pic_type;
uint32_t enc_idr_flag;
uint32_t enc_idr_pic_id;
uint32_t enc_mgs_key_pic;
uint32_t enc_reference_flag;
uint32_t enc_temporal_layer_index;
uint32_t num_ref_idx_active_override_flag;
uint32_t num_ref_idx_l0_active_minus1;
uint32_t num_ref_idx_l1_active_minus1;
uint32_t enc_ref_list_modification_op;
uint32_t enc_ref_list_modification_num;
uint32_t enc_decoded_picture_marking_op;
uint32_t enc_decoded_picture_marking_num;
uint32_t enc_decoded_picture_marking_idx;
uint32_t enc_decoded_ref_base_picture_marking_op;
uint32_t enc_decoded_ref_base_picture_marking_num;
uint32_t l0_picture_structure;
uint32_t l0_enc_pic_type;
uint32_t l0_frame_number;
uint32_t l0_picture_order_count;
uint32_t l0_luma_offset;
uint32_t l0_chroma_offset;
uint32_t l1_picture_structure;
uint32_t l1_enc_pic_type;
uint32_t l1_frame_number;
uint32_t l1_picture_order_count;
uint32_t l1_luma_offset;
uint32_t l1_chroma_offset;
uint32_t enc_reconstructed_luma_offset;
uint32_t enc_reconstructed_chroma_offset;
;
uint32_t enc_coloc_buffer_offset;
uint32_t enc_reconstructed_ref_base_picture_luma_offset;
uint32_t enc_reconstructed_ref_base_picture_chroma_offset;
uint32_t enc_reference_ref_base_picture_luma_offset;
uint32_t enc_reference_ref_base_picture_chroma_offset;
uint32_t picture_count;
uint32_t frame_number;
uint32_t picture_order_count;
uint32_t num_i_pic_remain_in_rcgop;
uint32_t num_p_pic_remain_in_rcgop;
uint32_t num_b_pic_remain_in_rcgop;
uint32_t num_ir_pic_remain_in_rcgop;
uint32_t enable_intra_refresh;
uint32_t aq_variance_en;
uint32_t aq_block_size;
uint32_t aq_mb_variance_sel;
uint32_t aq_frame_variance_sel;
uint32_t aq_param_a;
uint32_t aq_param_b;
uint32_t aq_param_c;
uint32_t aq_param_d;
uint32_t aq_param_e;
uint32_t context_in_sfb;
};
struct rvce_enc_create {
uint32_t enc_use_circular_buffer;
uint32_t enc_profile;
uint32_t enc_level;
uint32_t enc_pic_struct_restriction;
uint32_t enc_image_width;
uint32_t enc_image_height;
uint32_t enc_ref_pic_luma_pitch;
uint32_t enc_ref_pic_chroma_pitch;
uint32_t enc_ref_y_height_in_qw;
uint32_t enc_ref_pic_addr_array_enc_pic_struct_restriction_disable_rdo;
uint32_t enc_pre_encode_context_buffer_offset;
uint32_t enc_pre_encode_input_luma_buffer_offset;
uint32_t enc_pre_encode_input_chroma_buffer_offset;
uint32_t enc_pre_encode_mode_chromaflag_vbaqmode_scenechangesensitivity;
uint32_t enc_use_circular_buffer;
uint32_t enc_profile;
uint32_t enc_level;
uint32_t enc_pic_struct_restriction;
uint32_t enc_image_width;
uint32_t enc_image_height;
uint32_t enc_ref_pic_luma_pitch;
uint32_t enc_ref_pic_chroma_pitch;
uint32_t enc_ref_y_height_in_qw;
uint32_t enc_ref_pic_addr_array_enc_pic_struct_restriction_disable_rdo;
uint32_t enc_pre_encode_context_buffer_offset;
uint32_t enc_pre_encode_input_luma_buffer_offset;
uint32_t enc_pre_encode_input_chroma_buffer_offset;
uint32_t enc_pre_encode_mode_chromaflag_vbaqmode_scenechangesensitivity;
};
struct rvce_config_ext {
uint32_t enc_enable_perf_logging;
uint32_t enc_enable_perf_logging;
};
struct rvce_h264_enc_pic {
struct rvce_rate_control rc;
struct rvce_motion_estimation me;
struct rvce_pic_control pc;
struct rvce_task_info ti;
struct rvce_feedback_buf_pkg fb;
struct rvce_rdo rdo;
struct rvce_vui vui;
struct rvce_enc_operation eo;
struct rvce_enc_create ec;
struct rvce_config_ext ce;
struct rvce_rate_control rc;
struct rvce_motion_estimation me;
struct rvce_pic_control pc;
struct rvce_task_info ti;
struct rvce_feedback_buf_pkg fb;
struct rvce_rdo rdo;
struct rvce_vui vui;
struct rvce_enc_operation eo;
struct rvce_enc_create ec;
struct rvce_config_ext ce;
unsigned quant_i_frames;
unsigned quant_p_frames;
unsigned quant_b_frames;
unsigned quant_i_frames;
unsigned quant_p_frames;
unsigned quant_b_frames;
enum pipe_h264_enc_picture_type picture_type;
unsigned frame_num;
unsigned frame_num_cnt;
unsigned p_remain;
unsigned i_remain;
unsigned idr_pic_id;
unsigned gop_cnt;
unsigned gop_size;
unsigned pic_order_cnt;
unsigned ref_idx_l0;
unsigned ref_idx_l1;
unsigned addrmode_arraymode_disrdo_distwoinstants;
enum pipe_h264_enc_picture_type picture_type;
unsigned frame_num;
unsigned frame_num_cnt;
unsigned p_remain;
unsigned i_remain;
unsigned idr_pic_id;
unsigned gop_cnt;
unsigned gop_size;
unsigned pic_order_cnt;
unsigned ref_idx_l0;
unsigned ref_idx_l1;
unsigned addrmode_arraymode_disrdo_distwoinstants;
bool not_referenced;
bool is_idr;
bool has_ref_pic_list;
bool enable_vui;
unsigned int ref_pic_list_0[32];
unsigned int ref_pic_list_1[32];
unsigned int frame_idx[32];
bool not_referenced;
bool is_idr;
bool has_ref_pic_list;
bool enable_vui;
unsigned int ref_pic_list_0[32];
unsigned int ref_pic_list_1[32];
unsigned int frame_idx[32];
};
/* VCE encoder representation */
struct rvce_encoder {
struct pipe_video_codec base;
struct pipe_video_codec base;
/* version specific packets */
void (*session)(struct rvce_encoder *enc);
void (*create)(struct rvce_encoder *enc);
void (*feedback)(struct rvce_encoder *enc);
void (*rate_control)(struct rvce_encoder *enc);
void (*config_extension)(struct rvce_encoder *enc);
void (*pic_control)(struct rvce_encoder *enc);
void (*motion_estimation)(struct rvce_encoder *enc);
void (*rdo)(struct rvce_encoder *enc);
void (*vui)(struct rvce_encoder *enc);
void (*config)(struct rvce_encoder *enc);
void (*encode)(struct rvce_encoder *enc);
void (*destroy)(struct rvce_encoder *enc);
void (*task_info)(struct rvce_encoder *enc, uint32_t op,
uint32_t dep, uint32_t fb_idx,
uint32_t ring_idx);
void (*si_get_pic_param)(struct rvce_encoder *enc,
struct pipe_h264_enc_picture_desc *pic);
/* version specific packets */
void (*session)(struct rvce_encoder *enc);
void (*create)(struct rvce_encoder *enc);
void (*feedback)(struct rvce_encoder *enc);
void (*rate_control)(struct rvce_encoder *enc);
void (*config_extension)(struct rvce_encoder *enc);
void (*pic_control)(struct rvce_encoder *enc);
void (*motion_estimation)(struct rvce_encoder *enc);
void (*rdo)(struct rvce_encoder *enc);
void (*vui)(struct rvce_encoder *enc);
void (*config)(struct rvce_encoder *enc);
void (*encode)(struct rvce_encoder *enc);
void (*destroy)(struct rvce_encoder *enc);
void (*task_info)(struct rvce_encoder *enc, uint32_t op, uint32_t dep, uint32_t fb_idx,
uint32_t ring_idx);
void (*si_get_pic_param)(struct rvce_encoder *enc, struct pipe_h264_enc_picture_desc *pic);
unsigned stream_handle;
unsigned stream_handle;
struct pipe_screen *screen;
struct radeon_winsys* ws;
struct radeon_cmdbuf* cs;
struct pipe_screen *screen;
struct radeon_winsys *ws;
struct radeon_cmdbuf *cs;
rvce_get_buffer get_buffer;
rvce_get_buffer get_buffer;
struct pb_buffer* handle;
struct radeon_surf* luma;
struct radeon_surf* chroma;
struct pb_buffer *handle;
struct radeon_surf *luma;
struct radeon_surf *chroma;
struct pb_buffer* bs_handle;
unsigned bs_size;
struct pb_buffer *bs_handle;
unsigned bs_size;
struct rvce_cpb_slot *cpb_array;
struct list_head cpb_slots;
unsigned cpb_num;
struct rvce_cpb_slot *cpb_array;
struct list_head cpb_slots;
unsigned cpb_num;
struct rvid_buffer *fb;
struct rvid_buffer cpb;
struct pipe_h264_enc_picture_desc pic;
struct rvce_h264_enc_pic enc_pic;
struct rvid_buffer *fb;
struct rvid_buffer cpb;
struct pipe_h264_enc_picture_desc pic;
struct rvce_h264_enc_pic enc_pic;
unsigned task_info_idx;
unsigned bs_idx;
unsigned task_info_idx;
unsigned bs_idx;
bool use_vm;
bool use_vui;
bool dual_pipe;
bool dual_inst;
bool use_vm;
bool use_vui;
bool dual_pipe;
bool dual_inst;
};
/* CPB handling functions */
struct rvce_cpb_slot *si_current_slot(struct rvce_encoder *enc);
struct rvce_cpb_slot *si_l0_slot(struct rvce_encoder *enc);
struct rvce_cpb_slot *si_l1_slot(struct rvce_encoder *enc);
void si_vce_frame_offset(struct rvce_encoder *enc, struct rvce_cpb_slot *slot,
signed *luma_offset, signed *chroma_offset);
void si_vce_frame_offset(struct rvce_encoder *enc, struct rvce_cpb_slot *slot, signed *luma_offset,
signed *chroma_offset);
struct pipe_video_codec *si_vce_create_encoder(struct pipe_context *context,
const struct pipe_video_codec *templat,
struct radeon_winsys* ws,
rvce_get_buffer get_buffer);
const struct pipe_video_codec *templat,
struct radeon_winsys *ws,
rvce_get_buffer get_buffer);
bool si_vce_is_fw_version_supported(struct si_screen *sscreen);
void si_vce_add_buffer(struct rvce_encoder *enc, struct pb_buffer *buf,
enum radeon_bo_usage usage, enum radeon_bo_domain domain,
signed offset);
void si_vce_add_buffer(struct rvce_encoder *enc, struct pb_buffer *buf, enum radeon_bo_usage usage,
enum radeon_bo_domain domain, signed offset);
/* init vce fw 40.2.2 specific callbacks */
void si_vce_40_2_2_init(struct rvce_encoder *enc);
@ -441,15 +445,12 @@ void si_vce_50_init(struct rvce_encoder *enc);
void si_vce_52_init(struct rvce_encoder *enc);
/* get parameters for vce 40.2.2 */
void si_vce_40_2_2_get_param(struct rvce_encoder *enc,
struct pipe_h264_enc_picture_desc *pic);
void si_vce_40_2_2_get_param(struct rvce_encoder *enc, struct pipe_h264_enc_picture_desc *pic);
/* get parameters for vce 50 */
void si_vce_50_get_param(struct rvce_encoder *enc,
struct pipe_h264_enc_picture_desc *pic);
void si_vce_50_get_param(struct rvce_encoder *enc, struct pipe_h264_enc_picture_desc *pic);
/* get parameters for vce 52 */
void si_vce_52_get_param(struct rvce_encoder *enc,
struct pipe_h264_enc_picture_desc *pic);
void si_vce_52_get_param(struct rvce_encoder *enc, struct pipe_h264_enc_picture_desc *pic);
#endif

View File

@ -25,403 +25,400 @@
*
**************************************************************************/
#include <stdio.h>
#include "pipe/p_video_codec.h"
#include "util/u_video.h"
#include "radeon_vce.h"
#include "radeon_video.h"
#include "si_pipe.h"
#include "util/u_memory.h"
#include "util/u_video.h"
#include "vl/vl_video_buffer.h"
#include "si_pipe.h"
#include "radeon_video.h"
#include "radeon_vce.h"
#include <stdio.h>
static void session(struct rvce_encoder *enc)
{
RVCE_BEGIN(0x00000001); // session cmd
RVCE_CS(enc->stream_handle);
RVCE_END();
RVCE_BEGIN(0x00000001); // session cmd
RVCE_CS(enc->stream_handle);
RVCE_END();
}
static void task_info(struct rvce_encoder *enc, uint32_t op,
uint32_t dep, uint32_t fb_idx, uint32_t ring_idx)
static void task_info(struct rvce_encoder *enc, uint32_t op, uint32_t dep, uint32_t fb_idx,
uint32_t ring_idx)
{
RVCE_BEGIN(0x00000002); // task info
if (op == 0x3) {
if (enc->task_info_idx) {
uint32_t offs = enc->cs->current.cdw - enc->task_info_idx + 3;
// Update offsetOfNextTaskInfo
enc->cs->current.buf[enc->task_info_idx] = offs;
}
enc->task_info_idx = enc->cs->current.cdw;
}
RVCE_CS(0xffffffff); // offsetOfNextTaskInfo
RVCE_CS(op); // taskOperation
RVCE_CS(dep); // referencePictureDependency
RVCE_CS(0x00000000); // collocateFlagDependency
RVCE_CS(fb_idx); // feedbackIndex
RVCE_CS(ring_idx); // videoBitstreamRingIndex
RVCE_END();
RVCE_BEGIN(0x00000002); // task info
if (op == 0x3) {
if (enc->task_info_idx) {
uint32_t offs = enc->cs->current.cdw - enc->task_info_idx + 3;
// Update offsetOfNextTaskInfo
enc->cs->current.buf[enc->task_info_idx] = offs;
}
enc->task_info_idx = enc->cs->current.cdw;
}
RVCE_CS(0xffffffff); // offsetOfNextTaskInfo
RVCE_CS(op); // taskOperation
RVCE_CS(dep); // referencePictureDependency
RVCE_CS(0x00000000); // collocateFlagDependency
RVCE_CS(fb_idx); // feedbackIndex
RVCE_CS(ring_idx); // videoBitstreamRingIndex
RVCE_END();
}
static void feedback(struct rvce_encoder *enc)
{
RVCE_BEGIN(0x05000005); // feedback buffer
RVCE_WRITE(enc->fb->res->buf, enc->fb->res->domains, 0x0); // feedbackRingAddressHi/Lo
RVCE_CS(0x00000001); // feedbackRingSize
RVCE_END();
RVCE_BEGIN(0x05000005); // feedback buffer
RVCE_WRITE(enc->fb->res->buf, enc->fb->res->domains, 0x0); // feedbackRingAddressHi/Lo
RVCE_CS(0x00000001); // feedbackRingSize
RVCE_END();
}
static void create(struct rvce_encoder *enc)
{
enc->task_info(enc, 0x00000000, 0, 0, 0);
enc->task_info(enc, 0x00000000, 0, 0, 0);
RVCE_BEGIN(0x01000001); // create cmd
RVCE_CS(0x00000000); // encUseCircularBuffer
RVCE_CS(u_get_h264_profile_idc(enc->base.profile)); // encProfile
RVCE_CS(enc->base.level); // encLevel
RVCE_CS(0x00000000); // encPicStructRestriction
RVCE_CS(enc->base.width); // encImageWidth
RVCE_CS(enc->base.height); // encImageHeight
RVCE_CS(enc->luma->u.legacy.level[0].nblk_x * enc->luma->bpe); // encRefPicLumaPitch
RVCE_CS(enc->chroma->u.legacy.level[0].nblk_x * enc->chroma->bpe); // encRefPicChromaPitch
RVCE_CS(align(enc->luma->u.legacy.level[0].nblk_y, 16) / 8); // encRefYHeightInQw
RVCE_CS(0x00000000); // encRefPic(Addr|Array)Mode, encPicStructRestriction, disableRDO
RVCE_END();
RVCE_BEGIN(0x01000001); // create cmd
RVCE_CS(0x00000000); // encUseCircularBuffer
RVCE_CS(u_get_h264_profile_idc(enc->base.profile)); // encProfile
RVCE_CS(enc->base.level); // encLevel
RVCE_CS(0x00000000); // encPicStructRestriction
RVCE_CS(enc->base.width); // encImageWidth
RVCE_CS(enc->base.height); // encImageHeight
RVCE_CS(enc->luma->u.legacy.level[0].nblk_x * enc->luma->bpe); // encRefPicLumaPitch
RVCE_CS(enc->chroma->u.legacy.level[0].nblk_x * enc->chroma->bpe); // encRefPicChromaPitch
RVCE_CS(align(enc->luma->u.legacy.level[0].nblk_y, 16) / 8); // encRefYHeightInQw
RVCE_CS(0x00000000); // encRefPic(Addr|Array)Mode, encPicStructRestriction, disableRDO
RVCE_END();
}
static void rate_control(struct rvce_encoder *enc)
{
RVCE_BEGIN(0x04000005); // rate control
RVCE_CS(enc->pic.rate_ctrl.rate_ctrl_method); // encRateControlMethod
RVCE_CS(enc->pic.rate_ctrl.target_bitrate); // encRateControlTargetBitRate
RVCE_CS(enc->pic.rate_ctrl.peak_bitrate); // encRateControlPeakBitRate
RVCE_CS(enc->pic.rate_ctrl.frame_rate_num); // encRateControlFrameRateNum
RVCE_CS(0x00000000); // encGOPSize
RVCE_CS(enc->pic.quant_i_frames); // encQP_I
RVCE_CS(enc->pic.quant_p_frames); // encQP_P
RVCE_CS(enc->pic.quant_b_frames); // encQP_B
RVCE_CS(enc->pic.rate_ctrl.vbv_buffer_size); // encVBVBufferSize
RVCE_CS(enc->pic.rate_ctrl.frame_rate_den); // encRateControlFrameRateDen
RVCE_CS(0x00000000); // encVBVBufferLevel
RVCE_CS(0x00000000); // encMaxAUSize
RVCE_CS(0x00000000); // encQPInitialMode
RVCE_CS(enc->pic.rate_ctrl.target_bits_picture); // encTargetBitsPerPicture
RVCE_CS(enc->pic.rate_ctrl.peak_bits_picture_integer); // encPeakBitsPerPictureInteger
RVCE_CS(enc->pic.rate_ctrl.peak_bits_picture_fraction); // encPeakBitsPerPictureFractional
RVCE_CS(0x00000000); // encMinQP
RVCE_CS(0x00000033); // encMaxQP
RVCE_CS(0x00000000); // encSkipFrameEnable
RVCE_CS(0x00000000); // encFillerDataEnable
RVCE_CS(0x00000000); // encEnforceHRD
RVCE_CS(0x00000000); // encBPicsDeltaQP
RVCE_CS(0x00000000); // encReferenceBPicsDeltaQP
RVCE_CS(0x00000000); // encRateControlReInitDisable
RVCE_END();
RVCE_BEGIN(0x04000005); // rate control
RVCE_CS(enc->pic.rate_ctrl.rate_ctrl_method); // encRateControlMethod
RVCE_CS(enc->pic.rate_ctrl.target_bitrate); // encRateControlTargetBitRate
RVCE_CS(enc->pic.rate_ctrl.peak_bitrate); // encRateControlPeakBitRate
RVCE_CS(enc->pic.rate_ctrl.frame_rate_num); // encRateControlFrameRateNum
RVCE_CS(0x00000000); // encGOPSize
RVCE_CS(enc->pic.quant_i_frames); // encQP_I
RVCE_CS(enc->pic.quant_p_frames); // encQP_P
RVCE_CS(enc->pic.quant_b_frames); // encQP_B
RVCE_CS(enc->pic.rate_ctrl.vbv_buffer_size); // encVBVBufferSize
RVCE_CS(enc->pic.rate_ctrl.frame_rate_den); // encRateControlFrameRateDen
RVCE_CS(0x00000000); // encVBVBufferLevel
RVCE_CS(0x00000000); // encMaxAUSize
RVCE_CS(0x00000000); // encQPInitialMode
RVCE_CS(enc->pic.rate_ctrl.target_bits_picture); // encTargetBitsPerPicture
RVCE_CS(enc->pic.rate_ctrl.peak_bits_picture_integer); // encPeakBitsPerPictureInteger
RVCE_CS(enc->pic.rate_ctrl.peak_bits_picture_fraction); // encPeakBitsPerPictureFractional
RVCE_CS(0x00000000); // encMinQP
RVCE_CS(0x00000033); // encMaxQP
RVCE_CS(0x00000000); // encSkipFrameEnable
RVCE_CS(0x00000000); // encFillerDataEnable
RVCE_CS(0x00000000); // encEnforceHRD
RVCE_CS(0x00000000); // encBPicsDeltaQP
RVCE_CS(0x00000000); // encReferenceBPicsDeltaQP
RVCE_CS(0x00000000); // encRateControlReInitDisable
RVCE_END();
}
static void config_extension(struct rvce_encoder *enc)
{
RVCE_BEGIN(0x04000001); // config extension
RVCE_CS(0x00000003); // encEnablePerfLogging
RVCE_END();
RVCE_BEGIN(0x04000001); // config extension
RVCE_CS(0x00000003); // encEnablePerfLogging
RVCE_END();
}
static void pic_control(struct rvce_encoder *enc)
{
unsigned encNumMBsPerSlice;
unsigned encNumMBsPerSlice;
encNumMBsPerSlice = align(enc->base.width, 16) / 16;
encNumMBsPerSlice *= align(enc->base.height, 16) / 16;
encNumMBsPerSlice = align(enc->base.width, 16) / 16;
encNumMBsPerSlice *= align(enc->base.height, 16) / 16;
RVCE_BEGIN(0x04000002); // pic control
RVCE_CS(0x00000000); // encUseConstrainedIntraPred
RVCE_CS(0x00000000); // encCABACEnable
RVCE_CS(0x00000000); // encCABACIDC
RVCE_CS(0x00000000); // encLoopFilterDisable
RVCE_CS(0x00000000); // encLFBetaOffset
RVCE_CS(0x00000000); // encLFAlphaC0Offset
RVCE_CS(0x00000000); // encCropLeftOffset
RVCE_CS((align(enc->base.width, 16) - enc->base.width) >> 1); // encCropRightOffset
RVCE_CS(0x00000000); // encCropTopOffset
RVCE_CS((align(enc->base.height, 16) - enc->base.height) >> 1); // encCropBottomOffset
RVCE_CS(encNumMBsPerSlice); // encNumMBsPerSlice
RVCE_CS(0x00000000); // encIntraRefreshNumMBsPerSlot
RVCE_CS(0x00000000); // encForceIntraRefresh
RVCE_CS(0x00000000); // encForceIMBPeriod
RVCE_CS(0x00000000); // encPicOrderCntType
RVCE_CS(0x00000000); // log2_max_pic_order_cnt_lsb_minus4
RVCE_CS(0x00000000); // encSPSID
RVCE_CS(0x00000000); // encPPSID
RVCE_CS(0x00000040); // encConstraintSetFlags
RVCE_CS(MAX2(enc->base.max_references, 1) - 1); // encBPicPattern
RVCE_CS(0x00000000); // weightPredModeBPicture
RVCE_CS(MIN2(enc->base.max_references, 2)); // encNumberOfReferenceFrames
RVCE_CS(enc->base.max_references + 1); // encMaxNumRefFrames
RVCE_CS(0x00000001); // encNumDefaultActiveRefL0
RVCE_CS(0x00000001); // encNumDefaultActiveRefL1
RVCE_CS(0x00000000); // encSliceMode
RVCE_CS(0x00000000); // encMaxSliceSize
RVCE_END();
RVCE_BEGIN(0x04000002); // pic control
RVCE_CS(0x00000000); // encUseConstrainedIntraPred
RVCE_CS(0x00000000); // encCABACEnable
RVCE_CS(0x00000000); // encCABACIDC
RVCE_CS(0x00000000); // encLoopFilterDisable
RVCE_CS(0x00000000); // encLFBetaOffset
RVCE_CS(0x00000000); // encLFAlphaC0Offset
RVCE_CS(0x00000000); // encCropLeftOffset
RVCE_CS((align(enc->base.width, 16) - enc->base.width) >> 1); // encCropRightOffset
RVCE_CS(0x00000000); // encCropTopOffset
RVCE_CS((align(enc->base.height, 16) - enc->base.height) >> 1); // encCropBottomOffset
RVCE_CS(encNumMBsPerSlice); // encNumMBsPerSlice
RVCE_CS(0x00000000); // encIntraRefreshNumMBsPerSlot
RVCE_CS(0x00000000); // encForceIntraRefresh
RVCE_CS(0x00000000); // encForceIMBPeriod
RVCE_CS(0x00000000); // encPicOrderCntType
RVCE_CS(0x00000000); // log2_max_pic_order_cnt_lsb_minus4
RVCE_CS(0x00000000); // encSPSID
RVCE_CS(0x00000000); // encPPSID
RVCE_CS(0x00000040); // encConstraintSetFlags
RVCE_CS(MAX2(enc->base.max_references, 1) - 1); // encBPicPattern
RVCE_CS(0x00000000); // weightPredModeBPicture
RVCE_CS(MIN2(enc->base.max_references, 2)); // encNumberOfReferenceFrames
RVCE_CS(enc->base.max_references + 1); // encMaxNumRefFrames
RVCE_CS(0x00000001); // encNumDefaultActiveRefL0
RVCE_CS(0x00000001); // encNumDefaultActiveRefL1
RVCE_CS(0x00000000); // encSliceMode
RVCE_CS(0x00000000); // encMaxSliceSize
RVCE_END();
}
static void motion_estimation(struct rvce_encoder *enc)
{
RVCE_BEGIN(0x04000007); // motion estimation
RVCE_CS(0x00000001); // encIMEDecimationSearch
RVCE_CS(0x00000001); // motionEstHalfPixel
RVCE_CS(0x00000000); // motionEstQuarterPixel
RVCE_CS(0x00000000); // disableFavorPMVPoint
RVCE_CS(0x00000000); // forceZeroPointCenter
RVCE_CS(0x00000000); // LSMVert
RVCE_CS(0x00000010); // encSearchRangeX
RVCE_CS(0x00000010); // encSearchRangeY
RVCE_CS(0x00000010); // encSearch1RangeX
RVCE_CS(0x00000010); // encSearch1RangeY
RVCE_CS(0x00000000); // disable16x16Frame1
RVCE_CS(0x00000000); // disableSATD
RVCE_CS(0x00000000); // enableAMD
RVCE_CS(0x000000fe); // encDisableSubMode
RVCE_CS(0x00000000); // encIMESkipX
RVCE_CS(0x00000000); // encIMESkipY
RVCE_CS(0x00000000); // encEnImeOverwDisSubm
RVCE_CS(0x00000000); // encImeOverwDisSubmNo
RVCE_CS(0x00000001); // encIME2SearchRangeX
RVCE_CS(0x00000001); // encIME2SearchRangeY
RVCE_CS(0x00000000); // parallelModeSpeedupEnable
RVCE_CS(0x00000000); // fme0_encDisableSubMode
RVCE_CS(0x00000000); // fme1_encDisableSubMode
RVCE_CS(0x00000000); // imeSWSpeedupEnable
RVCE_END();
RVCE_BEGIN(0x04000007); // motion estimation
RVCE_CS(0x00000001); // encIMEDecimationSearch
RVCE_CS(0x00000001); // motionEstHalfPixel
RVCE_CS(0x00000000); // motionEstQuarterPixel
RVCE_CS(0x00000000); // disableFavorPMVPoint
RVCE_CS(0x00000000); // forceZeroPointCenter
RVCE_CS(0x00000000); // LSMVert
RVCE_CS(0x00000010); // encSearchRangeX
RVCE_CS(0x00000010); // encSearchRangeY
RVCE_CS(0x00000010); // encSearch1RangeX
RVCE_CS(0x00000010); // encSearch1RangeY
RVCE_CS(0x00000000); // disable16x16Frame1
RVCE_CS(0x00000000); // disableSATD
RVCE_CS(0x00000000); // enableAMD
RVCE_CS(0x000000fe); // encDisableSubMode
RVCE_CS(0x00000000); // encIMESkipX
RVCE_CS(0x00000000); // encIMESkipY
RVCE_CS(0x00000000); // encEnImeOverwDisSubm
RVCE_CS(0x00000000); // encImeOverwDisSubmNo
RVCE_CS(0x00000001); // encIME2SearchRangeX
RVCE_CS(0x00000001); // encIME2SearchRangeY
RVCE_CS(0x00000000); // parallelModeSpeedupEnable
RVCE_CS(0x00000000); // fme0_encDisableSubMode
RVCE_CS(0x00000000); // fme1_encDisableSubMode
RVCE_CS(0x00000000); // imeSWSpeedupEnable
RVCE_END();
}
static void rdo(struct rvce_encoder *enc)
{
RVCE_BEGIN(0x04000008); // rdo
RVCE_CS(0x00000000); // encDisableTbePredIFrame
RVCE_CS(0x00000000); // encDisableTbePredPFrame
RVCE_CS(0x00000000); // useFmeInterpolY
RVCE_CS(0x00000000); // useFmeInterpolUV
RVCE_CS(0x00000000); // useFmeIntrapolY
RVCE_CS(0x00000000); // useFmeIntrapolUV
RVCE_CS(0x00000000); // useFmeInterpolY_1
RVCE_CS(0x00000000); // useFmeInterpolUV_1
RVCE_CS(0x00000000); // useFmeIntrapolY_1
RVCE_CS(0x00000000); // useFmeIntrapolUV_1
RVCE_CS(0x00000000); // enc16x16CostAdj
RVCE_CS(0x00000000); // encSkipCostAdj
RVCE_CS(0x00000000); // encForce16x16skip
RVCE_CS(0x00000000); // encDisableThresholdCalcA
RVCE_CS(0x00000000); // encLumaCoeffCost
RVCE_CS(0x00000000); // encLumaMBCoeffCost
RVCE_CS(0x00000000); // encChromaCoeffCost
RVCE_END();
RVCE_BEGIN(0x04000008); // rdo
RVCE_CS(0x00000000); // encDisableTbePredIFrame
RVCE_CS(0x00000000); // encDisableTbePredPFrame
RVCE_CS(0x00000000); // useFmeInterpolY
RVCE_CS(0x00000000); // useFmeInterpolUV
RVCE_CS(0x00000000); // useFmeIntrapolY
RVCE_CS(0x00000000); // useFmeIntrapolUV
RVCE_CS(0x00000000); // useFmeInterpolY_1
RVCE_CS(0x00000000); // useFmeInterpolUV_1
RVCE_CS(0x00000000); // useFmeIntrapolY_1
RVCE_CS(0x00000000); // useFmeIntrapolUV_1
RVCE_CS(0x00000000); // enc16x16CostAdj
RVCE_CS(0x00000000); // encSkipCostAdj
RVCE_CS(0x00000000); // encForce16x16skip
RVCE_CS(0x00000000); // encDisableThresholdCalcA
RVCE_CS(0x00000000); // encLumaCoeffCost
RVCE_CS(0x00000000); // encLumaMBCoeffCost
RVCE_CS(0x00000000); // encChromaCoeffCost
RVCE_END();
}
static void vui(struct rvce_encoder *enc)
{
int i;
int i;
if (!enc->pic.rate_ctrl.frame_rate_num)
return;
if (!enc->pic.rate_ctrl.frame_rate_num)
return;
RVCE_BEGIN(0x04000009); // vui
RVCE_CS(0x00000000); //aspectRatioInfoPresentFlag
RVCE_CS(0x00000000); //aspectRatioInfo.aspectRatioIdc
RVCE_CS(0x00000000); //aspectRatioInfo.sarWidth
RVCE_CS(0x00000000); //aspectRatioInfo.sarHeight
RVCE_CS(0x00000000); //overscanInfoPresentFlag
RVCE_CS(0x00000000); //overScanInfo.overscanAppropFlag
RVCE_CS(0x00000000); //videoSignalTypePresentFlag
RVCE_CS(0x00000005); //videoSignalTypeInfo.videoFormat
RVCE_CS(0x00000000); //videoSignalTypeInfo.videoFullRangeFlag
RVCE_CS(0x00000000); //videoSignalTypeInfo.colorDescriptionPresentFlag
RVCE_CS(0x00000002); //videoSignalTypeInfo.colorPrim
RVCE_CS(0x00000002); //videoSignalTypeInfo.transferChar
RVCE_CS(0x00000002); //videoSignalTypeInfo.matrixCoef
RVCE_CS(0x00000000); //chromaLocInfoPresentFlag
RVCE_CS(0x00000000); //chromaLocInfo.chromaLocTop
RVCE_CS(0x00000000); //chromaLocInfo.chromaLocBottom
RVCE_CS(0x00000001); //timingInfoPresentFlag
RVCE_CS(enc->pic.rate_ctrl.frame_rate_den); //timingInfo.numUnitsInTick
RVCE_CS(enc->pic.rate_ctrl.frame_rate_num * 2); //timingInfo.timeScale;
RVCE_CS(0x00000001); //timingInfo.fixedFrameRateFlag
RVCE_CS(0x00000000); //nalHRDParametersPresentFlag
RVCE_CS(0x00000000); //hrdParam.cpbCntMinus1
RVCE_CS(0x00000004); //hrdParam.bitRateScale
RVCE_CS(0x00000006); //hrdParam.cpbSizeScale
for (i = 0; i < 32; i++) {
RVCE_CS(0x00000000); //hrdParam.bitRateValueMinus
RVCE_CS(0x00000000); //hrdParam.cpbSizeValueMinus
RVCE_CS(0x00000000); //hrdParam.cbrFlag
}
RVCE_CS(0x00000017); //hrdParam.initialCpbRemovalDelayLengthMinus1
RVCE_CS(0x00000017); //hrdParam.cpbRemovalDelayLengthMinus1
RVCE_CS(0x00000017); //hrdParam.dpbOutputDelayLengthMinus1
RVCE_CS(0x00000018); //hrdParam.timeOffsetLength
RVCE_CS(0x00000000); //lowDelayHRDFlag
RVCE_CS(0x00000000); //picStructPresentFlag
RVCE_CS(0x00000000); //bitstreamRestrictionPresentFlag
RVCE_CS(0x00000001); //bitstreamRestrictions.motionVectorsOverPicBoundariesFlag
RVCE_CS(0x00000002); //bitstreamRestrictions.maxBytesPerPicDenom
RVCE_CS(0x00000001); //bitstreamRestrictions.maxBitsPerMbDenom
RVCE_CS(0x00000010); //bitstreamRestrictions.log2MaxMvLengthHori
RVCE_CS(0x00000010); //bitstreamRestrictions.log2MaxMvLengthVert
RVCE_CS(0x00000003); //bitstreamRestrictions.numReorderFrames
RVCE_CS(0x00000003); //bitstreamRestrictions.maxDecFrameBuffering
RVCE_END();
RVCE_BEGIN(0x04000009); // vui
RVCE_CS(0x00000000); // aspectRatioInfoPresentFlag
RVCE_CS(0x00000000); // aspectRatioInfo.aspectRatioIdc
RVCE_CS(0x00000000); // aspectRatioInfo.sarWidth
RVCE_CS(0x00000000); // aspectRatioInfo.sarHeight
RVCE_CS(0x00000000); // overscanInfoPresentFlag
RVCE_CS(0x00000000); // overScanInfo.overscanAppropFlag
RVCE_CS(0x00000000); // videoSignalTypePresentFlag
RVCE_CS(0x00000005); // videoSignalTypeInfo.videoFormat
RVCE_CS(0x00000000); // videoSignalTypeInfo.videoFullRangeFlag
RVCE_CS(0x00000000); // videoSignalTypeInfo.colorDescriptionPresentFlag
RVCE_CS(0x00000002); // videoSignalTypeInfo.colorPrim
RVCE_CS(0x00000002); // videoSignalTypeInfo.transferChar
RVCE_CS(0x00000002); // videoSignalTypeInfo.matrixCoef
RVCE_CS(0x00000000); // chromaLocInfoPresentFlag
RVCE_CS(0x00000000); // chromaLocInfo.chromaLocTop
RVCE_CS(0x00000000); // chromaLocInfo.chromaLocBottom
RVCE_CS(0x00000001); // timingInfoPresentFlag
RVCE_CS(enc->pic.rate_ctrl.frame_rate_den); // timingInfo.numUnitsInTick
RVCE_CS(enc->pic.rate_ctrl.frame_rate_num * 2); // timingInfo.timeScale;
RVCE_CS(0x00000001); // timingInfo.fixedFrameRateFlag
RVCE_CS(0x00000000); // nalHRDParametersPresentFlag
RVCE_CS(0x00000000); // hrdParam.cpbCntMinus1
RVCE_CS(0x00000004); // hrdParam.bitRateScale
RVCE_CS(0x00000006); // hrdParam.cpbSizeScale
for (i = 0; i < 32; i++) {
RVCE_CS(0x00000000); // hrdParam.bitRateValueMinus
RVCE_CS(0x00000000); // hrdParam.cpbSizeValueMinus
RVCE_CS(0x00000000); // hrdParam.cbrFlag
}
RVCE_CS(0x00000017); // hrdParam.initialCpbRemovalDelayLengthMinus1
RVCE_CS(0x00000017); // hrdParam.cpbRemovalDelayLengthMinus1
RVCE_CS(0x00000017); // hrdParam.dpbOutputDelayLengthMinus1
RVCE_CS(0x00000018); // hrdParam.timeOffsetLength
RVCE_CS(0x00000000); // lowDelayHRDFlag
RVCE_CS(0x00000000); // picStructPresentFlag
RVCE_CS(0x00000000); // bitstreamRestrictionPresentFlag
RVCE_CS(0x00000001); // bitstreamRestrictions.motionVectorsOverPicBoundariesFlag
RVCE_CS(0x00000002); // bitstreamRestrictions.maxBytesPerPicDenom
RVCE_CS(0x00000001); // bitstreamRestrictions.maxBitsPerMbDenom
RVCE_CS(0x00000010); // bitstreamRestrictions.log2MaxMvLengthHori
RVCE_CS(0x00000010); // bitstreamRestrictions.log2MaxMvLengthVert
RVCE_CS(0x00000003); // bitstreamRestrictions.numReorderFrames
RVCE_CS(0x00000003); // bitstreamRestrictions.maxDecFrameBuffering
RVCE_END();
}
static void config(struct rvce_encoder *enc)
{
enc->task_info(enc, 0x00000002, 0, 0xffffffff, 0);
enc->rate_control(enc);
enc->config_extension(enc);
enc->motion_estimation(enc);
enc->rdo(enc);
if (enc->use_vui)
enc->vui(enc);
enc->pic_control(enc);
enc->task_info(enc, 0x00000002, 0, 0xffffffff, 0);
enc->rate_control(enc);
enc->config_extension(enc);
enc->motion_estimation(enc);
enc->rdo(enc);
if (enc->use_vui)
enc->vui(enc);
enc->pic_control(enc);
}
static void encode(struct rvce_encoder *enc)
{
signed luma_offset, chroma_offset;
int i;
signed luma_offset, chroma_offset;
int i;
enc->task_info(enc, 0x00000003, 0, 0, 0);
enc->task_info(enc, 0x00000003, 0, 0, 0);
RVCE_BEGIN(0x05000001); // context buffer
RVCE_READWRITE(enc->cpb.res->buf, enc->cpb.res->domains, 0x0); // encodeContextAddressHi/Lo
RVCE_END();
RVCE_BEGIN(0x05000001); // context buffer
RVCE_READWRITE(enc->cpb.res->buf, enc->cpb.res->domains, 0x0); // encodeContextAddressHi/Lo
RVCE_END();
RVCE_BEGIN(0x05000004); // video bitstream buffer
RVCE_WRITE(enc->bs_handle, RADEON_DOMAIN_GTT, 0x0); // videoBitstreamRingAddressHi/Lo
RVCE_CS(enc->bs_size); // videoBitstreamRingSize
RVCE_END();
RVCE_BEGIN(0x05000004); // video bitstream buffer
RVCE_WRITE(enc->bs_handle, RADEON_DOMAIN_GTT, 0x0); // videoBitstreamRingAddressHi/Lo
RVCE_CS(enc->bs_size); // videoBitstreamRingSize
RVCE_END();
RVCE_BEGIN(0x03000001); // encode
RVCE_CS(0x00000000); // insertHeaders
RVCE_CS(0x00000000); // pictureStructure
RVCE_CS(enc->bs_size); // allowedMaxBitstreamSize
RVCE_CS(0x00000000); // forceRefreshMap
RVCE_CS(0x00000000); // insertAUD
RVCE_CS(0x00000000); // endOfSequence
RVCE_CS(0x00000000); // endOfStream
RVCE_READ(enc->handle, RADEON_DOMAIN_VRAM,
enc->luma->u.legacy.level[0].offset); // inputPictureLumaAddressHi/Lo
RVCE_READ(enc->handle, RADEON_DOMAIN_VRAM,
enc->chroma->u.legacy.level[0].offset); // inputPictureChromaAddressHi/Lo
RVCE_CS(align(enc->luma->u.legacy.level[0].nblk_y, 16)); // encInputFrameYPitch
RVCE_CS(enc->luma->u.legacy.level[0].nblk_x * enc->luma->bpe); // encInputPicLumaPitch
RVCE_CS(enc->chroma->u.legacy.level[0].nblk_x * enc->chroma->bpe); // encInputPicChromaPitch
RVCE_CS(0x00000000); // encInputPic(Addr|Array)Mode
RVCE_CS(0x00000000); // encInputPicTileConfig
RVCE_CS(enc->pic.picture_type); // encPicType
RVCE_CS(enc->pic.picture_type == PIPE_H264_ENC_PICTURE_TYPE_IDR); // encIdrFlag
RVCE_CS(0x00000000); // encIdrPicId
RVCE_CS(0x00000000); // encMGSKeyPic
RVCE_CS(!enc->pic.not_referenced); // encReferenceFlag
RVCE_CS(0x00000000); // encTemporalLayerIndex
RVCE_CS(0x00000000); // num_ref_idx_active_override_flag
RVCE_CS(0x00000000); // num_ref_idx_l0_active_minus1
RVCE_CS(0x00000000); // num_ref_idx_l1_active_minus1
RVCE_BEGIN(0x03000001); // encode
RVCE_CS(0x00000000); // insertHeaders
RVCE_CS(0x00000000); // pictureStructure
RVCE_CS(enc->bs_size); // allowedMaxBitstreamSize
RVCE_CS(0x00000000); // forceRefreshMap
RVCE_CS(0x00000000); // insertAUD
RVCE_CS(0x00000000); // endOfSequence
RVCE_CS(0x00000000); // endOfStream
RVCE_READ(enc->handle, RADEON_DOMAIN_VRAM,
enc->luma->u.legacy.level[0].offset); // inputPictureLumaAddressHi/Lo
RVCE_READ(enc->handle, RADEON_DOMAIN_VRAM,
enc->chroma->u.legacy.level[0].offset); // inputPictureChromaAddressHi/Lo
RVCE_CS(align(enc->luma->u.legacy.level[0].nblk_y, 16)); // encInputFrameYPitch
RVCE_CS(enc->luma->u.legacy.level[0].nblk_x * enc->luma->bpe); // encInputPicLumaPitch
RVCE_CS(enc->chroma->u.legacy.level[0].nblk_x * enc->chroma->bpe); // encInputPicChromaPitch
RVCE_CS(0x00000000); // encInputPic(Addr|Array)Mode
RVCE_CS(0x00000000); // encInputPicTileConfig
RVCE_CS(enc->pic.picture_type); // encPicType
RVCE_CS(enc->pic.picture_type == PIPE_H264_ENC_PICTURE_TYPE_IDR); // encIdrFlag
RVCE_CS(0x00000000); // encIdrPicId
RVCE_CS(0x00000000); // encMGSKeyPic
RVCE_CS(!enc->pic.not_referenced); // encReferenceFlag
RVCE_CS(0x00000000); // encTemporalLayerIndex
RVCE_CS(0x00000000); // num_ref_idx_active_override_flag
RVCE_CS(0x00000000); // num_ref_idx_l0_active_minus1
RVCE_CS(0x00000000); // num_ref_idx_l1_active_minus1
i = enc->pic.frame_num - enc->pic.ref_idx_l0;
if (i > 1 && enc->pic.picture_type == PIPE_H264_ENC_PICTURE_TYPE_P) {
RVCE_CS(0x00000001); // encRefListModificationOp
RVCE_CS(i - 1); // encRefListModificationNum
} else {
RVCE_CS(0x00000000); // encRefListModificationOp
RVCE_CS(0x00000000); // encRefListModificationNum
}
i = enc->pic.frame_num - enc->pic.ref_idx_l0;
if (i > 1 && enc->pic.picture_type == PIPE_H264_ENC_PICTURE_TYPE_P) {
RVCE_CS(0x00000001); // encRefListModificationOp
RVCE_CS(i - 1); // encRefListModificationNum
} else {
RVCE_CS(0x00000000); // encRefListModificationOp
RVCE_CS(0x00000000); // encRefListModificationNum
}
for (i = 0; i < 3; ++i) {
RVCE_CS(0x00000000); // encRefListModificationOp
RVCE_CS(0x00000000); // encRefListModificationNum
}
for (i = 0; i < 4; ++i) {
RVCE_CS(0x00000000); // encDecodedPictureMarkingOp
RVCE_CS(0x00000000); // encDecodedPictureMarkingNum
RVCE_CS(0x00000000); // encDecodedPictureMarkingIdx
RVCE_CS(0x00000000); // encDecodedRefBasePictureMarkingOp
RVCE_CS(0x00000000); // encDecodedRefBasePictureMarkingNum
}
for (i = 0; i < 3; ++i) {
RVCE_CS(0x00000000); // encRefListModificationOp
RVCE_CS(0x00000000); // encRefListModificationNum
}
for (i = 0; i < 4; ++i) {
RVCE_CS(0x00000000); // encDecodedPictureMarkingOp
RVCE_CS(0x00000000); // encDecodedPictureMarkingNum
RVCE_CS(0x00000000); // encDecodedPictureMarkingIdx
RVCE_CS(0x00000000); // encDecodedRefBasePictureMarkingOp
RVCE_CS(0x00000000); // encDecodedRefBasePictureMarkingNum
}
// encReferencePictureL0[0]
RVCE_CS(0x00000000); // pictureStructure
if(enc->pic.picture_type == PIPE_H264_ENC_PICTURE_TYPE_P ||
enc->pic.picture_type == PIPE_H264_ENC_PICTURE_TYPE_B) {
struct rvce_cpb_slot *l0 = si_l0_slot(enc);
si_vce_frame_offset(enc, l0, &luma_offset, &chroma_offset);
RVCE_CS(l0->picture_type); // encPicType
RVCE_CS(l0->frame_num); // frameNumber
RVCE_CS(l0->pic_order_cnt); // pictureOrderCount
RVCE_CS(luma_offset); // lumaOffset
RVCE_CS(chroma_offset); // chromaOffset
} else {
RVCE_CS(0x00000000); // encPicType
RVCE_CS(0x00000000); // frameNumber
RVCE_CS(0x00000000); // pictureOrderCount
RVCE_CS(0xffffffff); // lumaOffset
RVCE_CS(0xffffffff); // chromaOffset
}
// encReferencePictureL0[0]
RVCE_CS(0x00000000); // pictureStructure
if (enc->pic.picture_type == PIPE_H264_ENC_PICTURE_TYPE_P ||
enc->pic.picture_type == PIPE_H264_ENC_PICTURE_TYPE_B) {
struct rvce_cpb_slot *l0 = si_l0_slot(enc);
si_vce_frame_offset(enc, l0, &luma_offset, &chroma_offset);
RVCE_CS(l0->picture_type); // encPicType
RVCE_CS(l0->frame_num); // frameNumber
RVCE_CS(l0->pic_order_cnt); // pictureOrderCount
RVCE_CS(luma_offset); // lumaOffset
RVCE_CS(chroma_offset); // chromaOffset
} else {
RVCE_CS(0x00000000); // encPicType
RVCE_CS(0x00000000); // frameNumber
RVCE_CS(0x00000000); // pictureOrderCount
RVCE_CS(0xffffffff); // lumaOffset
RVCE_CS(0xffffffff); // chromaOffset
}
// encReferencePictureL0[1]
RVCE_CS(0x00000000); // pictureStructure
RVCE_CS(0x00000000); // encPicType
RVCE_CS(0x00000000); // frameNumber
RVCE_CS(0x00000000); // pictureOrderCount
RVCE_CS(0xffffffff); // lumaOffset
RVCE_CS(0xffffffff); // chromaOffset
// encReferencePictureL0[1]
RVCE_CS(0x00000000); // pictureStructure
RVCE_CS(0x00000000); // encPicType
RVCE_CS(0x00000000); // frameNumber
RVCE_CS(0x00000000); // pictureOrderCount
RVCE_CS(0xffffffff); // lumaOffset
RVCE_CS(0xffffffff); // chromaOffset
// encReferencePictureL1[0]
RVCE_CS(0x00000000); // pictureStructure
if(enc->pic.picture_type == PIPE_H264_ENC_PICTURE_TYPE_B) {
struct rvce_cpb_slot *l1 = si_l1_slot(enc);
si_vce_frame_offset(enc, l1, &luma_offset, &chroma_offset);
RVCE_CS(l1->picture_type); // encPicType
RVCE_CS(l1->frame_num); // frameNumber
RVCE_CS(l1->pic_order_cnt); // pictureOrderCount
RVCE_CS(luma_offset); // lumaOffset
RVCE_CS(chroma_offset); // chromaOffset
} else {
RVCE_CS(0x00000000); // encPicType
RVCE_CS(0x00000000); // frameNumber
RVCE_CS(0x00000000); // pictureOrderCount
RVCE_CS(0xffffffff); // lumaOffset
RVCE_CS(0xffffffff); // chromaOffset
}
// encReferencePictureL1[0]
RVCE_CS(0x00000000); // pictureStructure
if (enc->pic.picture_type == PIPE_H264_ENC_PICTURE_TYPE_B) {
struct rvce_cpb_slot *l1 = si_l1_slot(enc);
si_vce_frame_offset(enc, l1, &luma_offset, &chroma_offset);
RVCE_CS(l1->picture_type); // encPicType
RVCE_CS(l1->frame_num); // frameNumber
RVCE_CS(l1->pic_order_cnt); // pictureOrderCount
RVCE_CS(luma_offset); // lumaOffset
RVCE_CS(chroma_offset); // chromaOffset
} else {
RVCE_CS(0x00000000); // encPicType
RVCE_CS(0x00000000); // frameNumber
RVCE_CS(0x00000000); // pictureOrderCount
RVCE_CS(0xffffffff); // lumaOffset
RVCE_CS(0xffffffff); // chromaOffset
}
si_vce_frame_offset(enc, si_current_slot(enc), &luma_offset, &chroma_offset);
RVCE_CS(luma_offset); // encReconstructedLumaOffset
RVCE_CS(chroma_offset); // encReconstructedChromaOffset
RVCE_CS(0x00000000); // encColocBufferOffset
RVCE_CS(0x00000000); // encReconstructedRefBasePictureLumaOffset
RVCE_CS(0x00000000); // encReconstructedRefBasePictureChromaOffset
RVCE_CS(0x00000000); // encReferenceRefBasePictureLumaOffset
RVCE_CS(0x00000000); // encReferenceRefBasePictureChromaOffset
RVCE_CS(0x00000000); // pictureCount
RVCE_CS(enc->pic.frame_num); // frameNumber
RVCE_CS(enc->pic.pic_order_cnt); // pictureOrderCount
RVCE_CS(0x00000000); // numIPicRemainInRCGOP
RVCE_CS(0x00000000); // numPPicRemainInRCGOP
RVCE_CS(0x00000000); // numBPicRemainInRCGOP
RVCE_CS(0x00000000); // numIRPicRemainInRCGOP
RVCE_CS(0x00000000); // enableIntraRefresh
RVCE_END();
si_vce_frame_offset(enc, si_current_slot(enc), &luma_offset, &chroma_offset);
RVCE_CS(luma_offset); // encReconstructedLumaOffset
RVCE_CS(chroma_offset); // encReconstructedChromaOffset
RVCE_CS(0x00000000); // encColocBufferOffset
RVCE_CS(0x00000000); // encReconstructedRefBasePictureLumaOffset
RVCE_CS(0x00000000); // encReconstructedRefBasePictureChromaOffset
RVCE_CS(0x00000000); // encReferenceRefBasePictureLumaOffset
RVCE_CS(0x00000000); // encReferenceRefBasePictureChromaOffset
RVCE_CS(0x00000000); // pictureCount
RVCE_CS(enc->pic.frame_num); // frameNumber
RVCE_CS(enc->pic.pic_order_cnt); // pictureOrderCount
RVCE_CS(0x00000000); // numIPicRemainInRCGOP
RVCE_CS(0x00000000); // numPPicRemainInRCGOP
RVCE_CS(0x00000000); // numBPicRemainInRCGOP
RVCE_CS(0x00000000); // numIRPicRemainInRCGOP
RVCE_CS(0x00000000); // enableIntraRefresh
RVCE_END();
}
static void destroy(struct rvce_encoder *enc)
{
enc->task_info(enc, 0x00000001, 0, 0, 0);
enc->task_info(enc, 0x00000001, 0, 0, 0);
feedback(enc);
feedback(enc);
RVCE_BEGIN(0x02000001); // destroy
RVCE_END();
RVCE_BEGIN(0x02000001); // destroy
RVCE_END();
}
void si_vce_40_2_2_get_param(struct rvce_encoder *enc, struct pipe_h264_enc_picture_desc *pic)
@ -430,18 +427,18 @@ void si_vce_40_2_2_get_param(struct rvce_encoder *enc, struct pipe_h264_enc_pict
void si_vce_40_2_2_init(struct rvce_encoder *enc)
{
enc->session = session;
enc->task_info = task_info;
enc->create = create;
enc->feedback = feedback;
enc->rate_control = rate_control;
enc->config_extension = config_extension;
enc->pic_control = pic_control;
enc->motion_estimation = motion_estimation;
enc->rdo = rdo;
enc->vui = vui;
enc->config = config;
enc->encode = encode;
enc->destroy = destroy;
enc->si_get_pic_param = si_vce_40_2_2_get_param;
enc->session = session;
enc->task_info = task_info;
enc->create = create;
enc->feedback = feedback;
enc->rate_control = rate_control;
enc->config_extension = config_extension;
enc->pic_control = pic_control;
enc->motion_estimation = motion_estimation;
enc->rdo = rdo;
enc->vui = vui;
enc->config = config;
enc->encode = encode;
enc->destroy = destroy;
enc->si_get_pic_param = si_vce_40_2_2_get_param;
}

View File

@ -25,206 +25,203 @@
*
**************************************************************************/
#include <stdio.h>
#include "pipe/p_video_codec.h"
#include "util/u_video.h"
#include "radeon_vce.h"
#include "radeon_video.h"
#include "si_pipe.h"
#include "util/u_memory.h"
#include "util/u_video.h"
#include "vl/vl_video_buffer.h"
#include "si_pipe.h"
#include "radeon_video.h"
#include "radeon_vce.h"
#include <stdio.h>
static void rate_control(struct rvce_encoder *enc)
{
RVCE_BEGIN(0x04000005); // rate control
RVCE_CS(enc->pic.rate_ctrl.rate_ctrl_method); // encRateControlMethod
RVCE_CS(enc->pic.rate_ctrl.target_bitrate); // encRateControlTargetBitRate
RVCE_CS(enc->pic.rate_ctrl.peak_bitrate); // encRateControlPeakBitRate
RVCE_CS(enc->pic.rate_ctrl.frame_rate_num); // encRateControlFrameRateNum
RVCE_CS(0x00000000); // encGOPSize
RVCE_CS(enc->pic.quant_i_frames); // encQP_I
RVCE_CS(enc->pic.quant_p_frames); // encQP_P
RVCE_CS(enc->pic.quant_b_frames); // encQP_B
RVCE_CS(enc->pic.rate_ctrl.vbv_buffer_size); // encVBVBufferSize
RVCE_CS(enc->pic.rate_ctrl.frame_rate_den); // encRateControlFrameRateDen
RVCE_CS(0x00000000); // encVBVBufferLevel
RVCE_CS(0x00000000); // encMaxAUSize
RVCE_CS(0x00000000); // encQPInitialMode
RVCE_CS(enc->pic.rate_ctrl.target_bits_picture); // encTargetBitsPerPicture
RVCE_CS(enc->pic.rate_ctrl.peak_bits_picture_integer); // encPeakBitsPerPictureInteger
RVCE_CS(enc->pic.rate_ctrl.peak_bits_picture_fraction); // encPeakBitsPerPictureFractional
RVCE_CS(0x00000000); // encMinQP
RVCE_CS(0x00000033); // encMaxQP
RVCE_CS(0x00000000); // encSkipFrameEnable
RVCE_CS(0x00000000); // encFillerDataEnable
RVCE_CS(0x00000000); // encEnforceHRD
RVCE_CS(0x00000000); // encBPicsDeltaQP
RVCE_CS(0x00000000); // encReferenceBPicsDeltaQP
RVCE_CS(0x00000000); // encRateControlReInitDisable
RVCE_CS(0x00000000); // encLCVBRInitQPFlag
RVCE_CS(0x00000000); // encLCVBRSATDBasedNonlinearBitBudgetFlag
RVCE_END();
RVCE_BEGIN(0x04000005); // rate control
RVCE_CS(enc->pic.rate_ctrl.rate_ctrl_method); // encRateControlMethod
RVCE_CS(enc->pic.rate_ctrl.target_bitrate); // encRateControlTargetBitRate
RVCE_CS(enc->pic.rate_ctrl.peak_bitrate); // encRateControlPeakBitRate
RVCE_CS(enc->pic.rate_ctrl.frame_rate_num); // encRateControlFrameRateNum
RVCE_CS(0x00000000); // encGOPSize
RVCE_CS(enc->pic.quant_i_frames); // encQP_I
RVCE_CS(enc->pic.quant_p_frames); // encQP_P
RVCE_CS(enc->pic.quant_b_frames); // encQP_B
RVCE_CS(enc->pic.rate_ctrl.vbv_buffer_size); // encVBVBufferSize
RVCE_CS(enc->pic.rate_ctrl.frame_rate_den); // encRateControlFrameRateDen
RVCE_CS(0x00000000); // encVBVBufferLevel
RVCE_CS(0x00000000); // encMaxAUSize
RVCE_CS(0x00000000); // encQPInitialMode
RVCE_CS(enc->pic.rate_ctrl.target_bits_picture); // encTargetBitsPerPicture
RVCE_CS(enc->pic.rate_ctrl.peak_bits_picture_integer); // encPeakBitsPerPictureInteger
RVCE_CS(enc->pic.rate_ctrl.peak_bits_picture_fraction); // encPeakBitsPerPictureFractional
RVCE_CS(0x00000000); // encMinQP
RVCE_CS(0x00000033); // encMaxQP
RVCE_CS(0x00000000); // encSkipFrameEnable
RVCE_CS(0x00000000); // encFillerDataEnable
RVCE_CS(0x00000000); // encEnforceHRD
RVCE_CS(0x00000000); // encBPicsDeltaQP
RVCE_CS(0x00000000); // encReferenceBPicsDeltaQP
RVCE_CS(0x00000000); // encRateControlReInitDisable
RVCE_CS(0x00000000); // encLCVBRInitQPFlag
RVCE_CS(0x00000000); // encLCVBRSATDBasedNonlinearBitBudgetFlag
RVCE_END();
}
static void encode(struct rvce_encoder *enc)
{
signed luma_offset, chroma_offset, bs_offset;
unsigned dep, bs_idx = enc->bs_idx++;
int i;
signed luma_offset, chroma_offset, bs_offset;
unsigned dep, bs_idx = enc->bs_idx++;
int i;
if (enc->dual_inst) {
if (bs_idx == 0)
dep = 1;
else if (enc->pic.picture_type == PIPE_H264_ENC_PICTURE_TYPE_IDR)
dep = 0;
else
dep = 2;
} else
dep = 0;
if (enc->dual_inst) {
if (bs_idx == 0)
dep = 1;
else if (enc->pic.picture_type == PIPE_H264_ENC_PICTURE_TYPE_IDR)
dep = 0;
else
dep = 2;
} else
dep = 0;
enc->task_info(enc, 0x00000003, dep, 0, bs_idx);
enc->task_info(enc, 0x00000003, dep, 0, bs_idx);
RVCE_BEGIN(0x05000001); // context buffer
RVCE_READWRITE(enc->cpb.res->buf, enc->cpb.res->domains, 0); // encodeContextAddressHi/Lo
RVCE_END();
RVCE_BEGIN(0x05000001); // context buffer
RVCE_READWRITE(enc->cpb.res->buf, enc->cpb.res->domains, 0); // encodeContextAddressHi/Lo
RVCE_END();
bs_offset = -(signed)(bs_idx * enc->bs_size);
bs_offset = -(signed)(bs_idx * enc->bs_size);
RVCE_BEGIN(0x05000004); // video bitstream buffer
RVCE_WRITE(enc->bs_handle, RADEON_DOMAIN_GTT, bs_offset); // videoBitstreamRingAddressHi/Lo
RVCE_CS(enc->bs_size); // videoBitstreamRingSize
RVCE_END();
RVCE_BEGIN(0x05000004); // video bitstream buffer
RVCE_WRITE(enc->bs_handle, RADEON_DOMAIN_GTT, bs_offset); // videoBitstreamRingAddressHi/Lo
RVCE_CS(enc->bs_size); // videoBitstreamRingSize
RVCE_END();
if (enc->dual_pipe) {
unsigned aux_offset = enc->cpb.res->buf->size -
RVCE_MAX_AUX_BUFFER_NUM * RVCE_MAX_BITSTREAM_OUTPUT_ROW_SIZE * 2;
RVCE_BEGIN(0x05000002); // auxiliary buffer
for (i = 0; i < 8; ++i) {
RVCE_CS(aux_offset);
aux_offset += RVCE_MAX_BITSTREAM_OUTPUT_ROW_SIZE;
}
for (i = 0; i < 8; ++i)
RVCE_CS(RVCE_MAX_BITSTREAM_OUTPUT_ROW_SIZE);
RVCE_END();
}
if (enc->dual_pipe) {
unsigned aux_offset =
enc->cpb.res->buf->size - RVCE_MAX_AUX_BUFFER_NUM * RVCE_MAX_BITSTREAM_OUTPUT_ROW_SIZE * 2;
RVCE_BEGIN(0x05000002); // auxiliary buffer
for (i = 0; i < 8; ++i) {
RVCE_CS(aux_offset);
aux_offset += RVCE_MAX_BITSTREAM_OUTPUT_ROW_SIZE;
}
for (i = 0; i < 8; ++i)
RVCE_CS(RVCE_MAX_BITSTREAM_OUTPUT_ROW_SIZE);
RVCE_END();
}
RVCE_BEGIN(0x03000001); // encode
RVCE_CS(enc->pic.frame_num ? 0x0 : 0x11); // insertHeaders
RVCE_CS(0x00000000); // pictureStructure
RVCE_CS(enc->bs_size); // allowedMaxBitstreamSize
RVCE_CS(0x00000000); // forceRefreshMap
RVCE_CS(0x00000000); // insertAUD
RVCE_CS(0x00000000); // endOfSequence
RVCE_CS(0x00000000); // endOfStream
RVCE_READ(enc->handle, RADEON_DOMAIN_VRAM,
enc->luma->u.legacy.level[0].offset); // inputPictureLumaAddressHi/Lo
RVCE_READ(enc->handle, RADEON_DOMAIN_VRAM,
enc->chroma->u.legacy.level[0].offset); // inputPictureChromaAddressHi/Lo
RVCE_CS(align(enc->luma->u.legacy.level[0].nblk_y, 16)); // encInputFrameYPitch
RVCE_CS(enc->luma->u.legacy.level[0].nblk_x * enc->luma->bpe); // encInputPicLumaPitch
RVCE_CS(enc->chroma->u.legacy.level[0].nblk_x * enc->chroma->bpe); // encInputPicChromaPitch
if (enc->dual_pipe)
RVCE_CS(0x00000000); // encInputPic(Addr|Array)Mode,encDisable(TwoPipeMode|MBOffloading)
else
RVCE_CS(0x00010000); // encInputPic(Addr|Array)Mode,encDisable(TwoPipeMode|MBOffloading)
RVCE_CS(0x00000000); // encInputPicTileConfig
RVCE_CS(enc->pic.picture_type); // encPicType
RVCE_CS(enc->pic.picture_type == PIPE_H264_ENC_PICTURE_TYPE_IDR); // encIdrFlag
RVCE_CS(0x00000000); // encIdrPicId
RVCE_CS(0x00000000); // encMGSKeyPic
RVCE_CS(!enc->pic.not_referenced); // encReferenceFlag
RVCE_CS(0x00000000); // encTemporalLayerIndex
RVCE_CS(0x00000000); // num_ref_idx_active_override_flag
RVCE_CS(0x00000000); // num_ref_idx_l0_active_minus1
RVCE_CS(0x00000000); // num_ref_idx_l1_active_minus1
RVCE_BEGIN(0x03000001); // encode
RVCE_CS(enc->pic.frame_num ? 0x0 : 0x11); // insertHeaders
RVCE_CS(0x00000000); // pictureStructure
RVCE_CS(enc->bs_size); // allowedMaxBitstreamSize
RVCE_CS(0x00000000); // forceRefreshMap
RVCE_CS(0x00000000); // insertAUD
RVCE_CS(0x00000000); // endOfSequence
RVCE_CS(0x00000000); // endOfStream
RVCE_READ(enc->handle, RADEON_DOMAIN_VRAM,
enc->luma->u.legacy.level[0].offset); // inputPictureLumaAddressHi/Lo
RVCE_READ(enc->handle, RADEON_DOMAIN_VRAM,
enc->chroma->u.legacy.level[0].offset); // inputPictureChromaAddressHi/Lo
RVCE_CS(align(enc->luma->u.legacy.level[0].nblk_y, 16)); // encInputFrameYPitch
RVCE_CS(enc->luma->u.legacy.level[0].nblk_x * enc->luma->bpe); // encInputPicLumaPitch
RVCE_CS(enc->chroma->u.legacy.level[0].nblk_x * enc->chroma->bpe); // encInputPicChromaPitch
if (enc->dual_pipe)
RVCE_CS(0x00000000); // encInputPic(Addr|Array)Mode,encDisable(TwoPipeMode|MBOffloading)
else
RVCE_CS(0x00010000); // encInputPic(Addr|Array)Mode,encDisable(TwoPipeMode|MBOffloading)
RVCE_CS(0x00000000); // encInputPicTileConfig
RVCE_CS(enc->pic.picture_type); // encPicType
RVCE_CS(enc->pic.picture_type == PIPE_H264_ENC_PICTURE_TYPE_IDR); // encIdrFlag
RVCE_CS(0x00000000); // encIdrPicId
RVCE_CS(0x00000000); // encMGSKeyPic
RVCE_CS(!enc->pic.not_referenced); // encReferenceFlag
RVCE_CS(0x00000000); // encTemporalLayerIndex
RVCE_CS(0x00000000); // num_ref_idx_active_override_flag
RVCE_CS(0x00000000); // num_ref_idx_l0_active_minus1
RVCE_CS(0x00000000); // num_ref_idx_l1_active_minus1
i = enc->pic.frame_num - enc->pic.ref_idx_l0;
if (i > 1 && enc->pic.picture_type == PIPE_H264_ENC_PICTURE_TYPE_P) {
RVCE_CS(0x00000001); // encRefListModificationOp
RVCE_CS(i - 1); // encRefListModificationNum
} else {
RVCE_CS(0x00000000); // encRefListModificationOp
RVCE_CS(0x00000000); // encRefListModificationNum
}
i = enc->pic.frame_num - enc->pic.ref_idx_l0;
if (i > 1 && enc->pic.picture_type == PIPE_H264_ENC_PICTURE_TYPE_P) {
RVCE_CS(0x00000001); // encRefListModificationOp
RVCE_CS(i - 1); // encRefListModificationNum
} else {
RVCE_CS(0x00000000); // encRefListModificationOp
RVCE_CS(0x00000000); // encRefListModificationNum
}
for (i = 0; i < 3; ++i) {
RVCE_CS(0x00000000); // encRefListModificationOp
RVCE_CS(0x00000000); // encRefListModificationNum
}
for (i = 0; i < 4; ++i) {
RVCE_CS(0x00000000); // encDecodedPictureMarkingOp
RVCE_CS(0x00000000); // encDecodedPictureMarkingNum
RVCE_CS(0x00000000); // encDecodedPictureMarkingIdx
RVCE_CS(0x00000000); // encDecodedRefBasePictureMarkingOp
RVCE_CS(0x00000000); // encDecodedRefBasePictureMarkingNum
}
for (i = 0; i < 3; ++i) {
RVCE_CS(0x00000000); // encRefListModificationOp
RVCE_CS(0x00000000); // encRefListModificationNum
}
for (i = 0; i < 4; ++i) {
RVCE_CS(0x00000000); // encDecodedPictureMarkingOp
RVCE_CS(0x00000000); // encDecodedPictureMarkingNum
RVCE_CS(0x00000000); // encDecodedPictureMarkingIdx
RVCE_CS(0x00000000); // encDecodedRefBasePictureMarkingOp
RVCE_CS(0x00000000); // encDecodedRefBasePictureMarkingNum
}
// encReferencePictureL0[0]
RVCE_CS(0x00000000); // pictureStructure
if(enc->pic.picture_type == PIPE_H264_ENC_PICTURE_TYPE_P ||
enc->pic.picture_type == PIPE_H264_ENC_PICTURE_TYPE_B) {
struct rvce_cpb_slot *l0 = si_l0_slot(enc);
si_vce_frame_offset(enc, l0, &luma_offset, &chroma_offset);
RVCE_CS(l0->picture_type); // encPicType
RVCE_CS(l0->frame_num); // frameNumber
RVCE_CS(l0->pic_order_cnt); // pictureOrderCount
RVCE_CS(luma_offset); // lumaOffset
RVCE_CS(chroma_offset); // chromaOffset
} else {
RVCE_CS(0x00000000); // encPicType
RVCE_CS(0x00000000); // frameNumber
RVCE_CS(0x00000000); // pictureOrderCount
RVCE_CS(0xffffffff); // lumaOffset
RVCE_CS(0xffffffff); // chromaOffset
}
// encReferencePictureL0[0]
RVCE_CS(0x00000000); // pictureStructure
if (enc->pic.picture_type == PIPE_H264_ENC_PICTURE_TYPE_P ||
enc->pic.picture_type == PIPE_H264_ENC_PICTURE_TYPE_B) {
struct rvce_cpb_slot *l0 = si_l0_slot(enc);
si_vce_frame_offset(enc, l0, &luma_offset, &chroma_offset);
RVCE_CS(l0->picture_type); // encPicType
RVCE_CS(l0->frame_num); // frameNumber
RVCE_CS(l0->pic_order_cnt); // pictureOrderCount
RVCE_CS(luma_offset); // lumaOffset
RVCE_CS(chroma_offset); // chromaOffset
} else {
RVCE_CS(0x00000000); // encPicType
RVCE_CS(0x00000000); // frameNumber
RVCE_CS(0x00000000); // pictureOrderCount
RVCE_CS(0xffffffff); // lumaOffset
RVCE_CS(0xffffffff); // chromaOffset
}
// encReferencePictureL0[1]
RVCE_CS(0x00000000); // pictureStructure
RVCE_CS(0x00000000); // encPicType
RVCE_CS(0x00000000); // frameNumber
RVCE_CS(0x00000000); // pictureOrderCount
RVCE_CS(0xffffffff); // lumaOffset
RVCE_CS(0xffffffff); // chromaOffset
// encReferencePictureL0[1]
RVCE_CS(0x00000000); // pictureStructure
RVCE_CS(0x00000000); // encPicType
RVCE_CS(0x00000000); // frameNumber
RVCE_CS(0x00000000); // pictureOrderCount
RVCE_CS(0xffffffff); // lumaOffset
RVCE_CS(0xffffffff); // chromaOffset
// encReferencePictureL1[0]
RVCE_CS(0x00000000); // pictureStructure
if(enc->pic.picture_type == PIPE_H264_ENC_PICTURE_TYPE_B) {
struct rvce_cpb_slot *l1 = si_l1_slot(enc);
si_vce_frame_offset(enc, l1, &luma_offset, &chroma_offset);
RVCE_CS(l1->picture_type); // encPicType
RVCE_CS(l1->frame_num); // frameNumber
RVCE_CS(l1->pic_order_cnt); // pictureOrderCount
RVCE_CS(luma_offset); // lumaOffset
RVCE_CS(chroma_offset); // chromaOffset
} else {
RVCE_CS(0x00000000); // encPicType
RVCE_CS(0x00000000); // frameNumber
RVCE_CS(0x00000000); // pictureOrderCount
RVCE_CS(0xffffffff); // lumaOffset
RVCE_CS(0xffffffff); // chromaOffset
}
// encReferencePictureL1[0]
RVCE_CS(0x00000000); // pictureStructure
if (enc->pic.picture_type == PIPE_H264_ENC_PICTURE_TYPE_B) {
struct rvce_cpb_slot *l1 = si_l1_slot(enc);
si_vce_frame_offset(enc, l1, &luma_offset, &chroma_offset);
RVCE_CS(l1->picture_type); // encPicType
RVCE_CS(l1->frame_num); // frameNumber
RVCE_CS(l1->pic_order_cnt); // pictureOrderCount
RVCE_CS(luma_offset); // lumaOffset
RVCE_CS(chroma_offset); // chromaOffset
} else {
RVCE_CS(0x00000000); // encPicType
RVCE_CS(0x00000000); // frameNumber
RVCE_CS(0x00000000); // pictureOrderCount
RVCE_CS(0xffffffff); // lumaOffset
RVCE_CS(0xffffffff); // chromaOffset
}
si_vce_frame_offset(enc, si_current_slot(enc), &luma_offset, &chroma_offset);
RVCE_CS(luma_offset); // encReconstructedLumaOffset
RVCE_CS(chroma_offset); // encReconstructedChromaOffset
RVCE_CS(0x00000000); // encColocBufferOffset
RVCE_CS(0x00000000); // encReconstructedRefBasePictureLumaOffset
RVCE_CS(0x00000000); // encReconstructedRefBasePictureChromaOffset
RVCE_CS(0x00000000); // encReferenceRefBasePictureLumaOffset
RVCE_CS(0x00000000); // encReferenceRefBasePictureChromaOffset
RVCE_CS(0x00000000); // pictureCount
RVCE_CS(enc->pic.frame_num); // frameNumber
RVCE_CS(enc->pic.pic_order_cnt); // pictureOrderCount
RVCE_CS(0x00000000); // numIPicRemainInRCGOP
RVCE_CS(0x00000000); // numPPicRemainInRCGOP
RVCE_CS(0x00000000); // numBPicRemainInRCGOP
RVCE_CS(0x00000000); // numIRPicRemainInRCGOP
RVCE_CS(0x00000000); // enableIntraRefresh
RVCE_END();
si_vce_frame_offset(enc, si_current_slot(enc), &luma_offset, &chroma_offset);
RVCE_CS(luma_offset); // encReconstructedLumaOffset
RVCE_CS(chroma_offset); // encReconstructedChromaOffset
RVCE_CS(0x00000000); // encColocBufferOffset
RVCE_CS(0x00000000); // encReconstructedRefBasePictureLumaOffset
RVCE_CS(0x00000000); // encReconstructedRefBasePictureChromaOffset
RVCE_CS(0x00000000); // encReferenceRefBasePictureLumaOffset
RVCE_CS(0x00000000); // encReferenceRefBasePictureChromaOffset
RVCE_CS(0x00000000); // pictureCount
RVCE_CS(enc->pic.frame_num); // frameNumber
RVCE_CS(enc->pic.pic_order_cnt); // pictureOrderCount
RVCE_CS(0x00000000); // numIPicRemainInRCGOP
RVCE_CS(0x00000000); // numPPicRemainInRCGOP
RVCE_CS(0x00000000); // numBPicRemainInRCGOP
RVCE_CS(0x00000000); // numIRPicRemainInRCGOP
RVCE_CS(0x00000000); // enableIntraRefresh
RVCE_END();
}
void si_vce_50_get_param(struct rvce_encoder *enc, struct pipe_h264_enc_picture_desc *pic)
@ -233,10 +230,10 @@ void si_vce_50_get_param(struct rvce_encoder *enc, struct pipe_h264_enc_picture_
void si_vce_50_init(struct rvce_encoder *enc)
{
si_vce_40_2_2_init(enc);
si_vce_40_2_2_init(enc);
/* only the two below are different */
enc->rate_control = rate_control;
enc->encode = encode;
enc->si_get_pic_param = si_vce_50_get_param;
/* only the two below are different */
enc->rate_control = rate_control;
enc->encode = encode;
enc->si_get_pic_param = si_vce_50_get_param;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -25,288 +25,277 @@
*
**************************************************************************/
#include <assert.h>
#include <stdio.h>
#include "pipe/p_video_codec.h"
#include "radeon_vcn_dec.h"
#include "radeon_video.h"
#include "radeonsi/si_pipe.h"
#include "util/u_memory.h"
#include "util/u_video.h"
#include "radeonsi/si_pipe.h"
#include "radeon_video.h"
#include "radeon_vcn_dec.h"
#include <assert.h>
#include <stdio.h>
static struct pb_buffer *radeon_jpeg_get_decode_param(struct radeon_decoder *dec,
struct pipe_video_buffer *target,
struct pipe_picture_desc *picture)
struct pipe_video_buffer *target,
struct pipe_picture_desc *picture)
{
struct si_texture *luma = (struct si_texture *)
((struct vl_video_buffer *)target)->resources[0];
struct si_texture *chroma = (struct si_texture *)
((struct vl_video_buffer *)target)->resources[1];
struct si_texture *luma = (struct si_texture *)((struct vl_video_buffer *)target)->resources[0];
struct si_texture *chroma =
(struct si_texture *)((struct vl_video_buffer *)target)->resources[1];
dec->jpg.bsd_size = align(dec->bs_size, 128);
dec->jpg.dt_luma_top_offset = luma->surface.u.gfx9.surf_offset;
if (target->buffer_format == PIPE_FORMAT_NV12)
dec->jpg.dt_chroma_top_offset = chroma->surface.u.gfx9.surf_offset;
dec->jpg.dt_pitch = luma->surface.u.gfx9.surf_pitch * luma->surface.blk_w;
dec->jpg.dt_uv_pitch = dec->jpg.dt_pitch / 2;
dec->jpg.bsd_size = align(dec->bs_size, 128);
dec->jpg.dt_luma_top_offset = luma->surface.u.gfx9.surf_offset;
if (target->buffer_format == PIPE_FORMAT_NV12)
dec->jpg.dt_chroma_top_offset = chroma->surface.u.gfx9.surf_offset;
dec->jpg.dt_pitch = luma->surface.u.gfx9.surf_pitch * luma->surface.blk_w;
dec->jpg.dt_uv_pitch = dec->jpg.dt_pitch / 2;
return luma->buffer.buf;
return luma->buffer.buf;
}
/* add a new set register command to the IB */
static void set_reg_jpeg(struct radeon_decoder *dec, unsigned reg,
unsigned cond, unsigned type, uint32_t val)
static void set_reg_jpeg(struct radeon_decoder *dec, unsigned reg, unsigned cond, unsigned type,
uint32_t val)
{
radeon_emit(dec->cs, RDECODE_PKTJ(reg, cond, type));
radeon_emit(dec->cs, val);
radeon_emit(dec->cs, RDECODE_PKTJ(reg, cond, type));
radeon_emit(dec->cs, val);
}
/* send a bitstream buffer command */
static void send_cmd_bitstream(struct radeon_decoder *dec,
struct pb_buffer* buf, uint32_t off,
enum radeon_bo_usage usage, enum radeon_bo_domain domain)
static void send_cmd_bitstream(struct radeon_decoder *dec, struct pb_buffer *buf, uint32_t off,
enum radeon_bo_usage usage, enum radeon_bo_domain domain)
{
uint64_t addr;
uint64_t addr;
// jpeg soft reset
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_CNTL), COND0, TYPE0, 1);
// jpeg soft reset
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_CNTL), COND0, TYPE0, 1);
// ensuring the Reset is asserted in SCLK domain
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_INDEX), COND0, TYPE0, 0x01C2);
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_DATA), COND0, TYPE0, 0x01400200);
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_INDEX), COND0, TYPE0, 0x01C3);
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_DATA), COND0, TYPE0, (1 << 9));
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_SOFT_RESET), COND0, TYPE3, (1 << 9));
// ensuring the Reset is asserted in SCLK domain
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_INDEX), COND0, TYPE0, 0x01C2);
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_DATA), COND0, TYPE0, 0x01400200);
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_INDEX), COND0, TYPE0, 0x01C3);
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_DATA), COND0, TYPE0, (1 << 9));
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_SOFT_RESET), COND0, TYPE3, (1 << 9));
// wait mem
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_CNTL), COND0, TYPE0, 0);
// wait mem
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_CNTL), COND0, TYPE0, 0);
// ensuring the Reset is de-asserted in SCLK domain
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_INDEX), COND0, TYPE0, 0x01C3);
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_DATA), COND0, TYPE0, (0 << 9));
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_SOFT_RESET), COND0, TYPE3, (1 << 9));
// ensuring the Reset is de-asserted in SCLK domain
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_INDEX), COND0, TYPE0, 0x01C3);
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_DATA), COND0, TYPE0, (0 << 9));
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_SOFT_RESET), COND0, TYPE3, (1 << 9));
dec->ws->cs_add_buffer(dec->cs, buf, usage | RADEON_USAGE_SYNCHRONIZED,
domain, 0);
addr = dec->ws->buffer_get_virtual_address(buf);
addr = addr + off;
dec->ws->cs_add_buffer(dec->cs, buf, usage | RADEON_USAGE_SYNCHRONIZED, domain, 0);
addr = dec->ws->buffer_get_virtual_address(buf);
addr = addr + off;
// set UVD_LMI_JPEG_READ_64BIT_BAR_LOW/HIGH based on bitstream buffer address
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_LMI_JPEG_READ_64BIT_BAR_HIGH), COND0, TYPE0, (addr >> 32));
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_LMI_JPEG_READ_64BIT_BAR_LOW), COND0, TYPE0, addr);
// set UVD_LMI_JPEG_READ_64BIT_BAR_LOW/HIGH based on bitstream buffer address
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_LMI_JPEG_READ_64BIT_BAR_HIGH), COND0, TYPE0,
(addr >> 32));
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_LMI_JPEG_READ_64BIT_BAR_LOW), COND0, TYPE0, addr);
// set jpeg_rb_base
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_RB_BASE), COND0, TYPE0, 0);
// set jpeg_rb_base
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_RB_BASE), COND0, TYPE0, 0);
// set jpeg_rb_base
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_RB_SIZE), COND0, TYPE0, 0xFFFFFFF0);
// set jpeg_rb_base
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_RB_SIZE), COND0, TYPE0, 0xFFFFFFF0);
// set jpeg_rb_wptr
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_RB_WPTR), COND0, TYPE0, (dec->jpg.bsd_size >> 2));
// set jpeg_rb_wptr
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_RB_WPTR), COND0, TYPE0, (dec->jpg.bsd_size >> 2));
}
/* send a target buffer command */
static void send_cmd_target(struct radeon_decoder *dec,
struct pb_buffer* buf, uint32_t off,
enum radeon_bo_usage usage, enum radeon_bo_domain domain)
static void send_cmd_target(struct radeon_decoder *dec, struct pb_buffer *buf, uint32_t off,
enum radeon_bo_usage usage, enum radeon_bo_domain domain)
{
uint64_t addr;
uint64_t addr;
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_PITCH), COND0, TYPE0, (dec->jpg.dt_pitch >> 4));
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_UV_PITCH), COND0, TYPE0, ((dec->jpg.dt_uv_pitch * 2) >> 4));
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_PITCH), COND0, TYPE0, (dec->jpg.dt_pitch >> 4));
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_UV_PITCH), COND0, TYPE0,
((dec->jpg.dt_uv_pitch * 2) >> 4));
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_TILING_CTRL), COND0, TYPE0, 0);
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_UV_TILING_CTRL), COND0, TYPE0, 0);
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_TILING_CTRL), COND0, TYPE0, 0);
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_UV_TILING_CTRL), COND0, TYPE0, 0);
dec->ws->cs_add_buffer(dec->cs, buf, usage | RADEON_USAGE_SYNCHRONIZED,
domain, 0);
addr = dec->ws->buffer_get_virtual_address(buf);
addr = addr + off;
dec->ws->cs_add_buffer(dec->cs, buf, usage | RADEON_USAGE_SYNCHRONIZED, domain, 0);
addr = dec->ws->buffer_get_virtual_address(buf);
addr = addr + off;
// set UVD_LMI_JPEG_WRITE_64BIT_BAR_LOW/HIGH based on target buffer address
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_LMI_JPEG_WRITE_64BIT_BAR_HIGH), COND0, TYPE0, (addr >> 32));
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_LMI_JPEG_WRITE_64BIT_BAR_LOW), COND0, TYPE0, addr);
// set UVD_LMI_JPEG_WRITE_64BIT_BAR_LOW/HIGH based on target buffer address
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_LMI_JPEG_WRITE_64BIT_BAR_HIGH), COND0, TYPE0,
(addr >> 32));
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_LMI_JPEG_WRITE_64BIT_BAR_LOW), COND0, TYPE0, addr);
// set output buffer data address
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_INDEX), COND0, TYPE0, 0);
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_DATA), COND0, TYPE0, dec->jpg.dt_luma_top_offset);
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_INDEX), COND0, TYPE0, 1);
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_DATA), COND0, TYPE0, dec->jpg.dt_chroma_top_offset);
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_TIER_CNTL2), COND0, TYPE3, 0);
// set output buffer data address
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_INDEX), COND0, TYPE0, 0);
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_DATA), COND0, TYPE0, dec->jpg.dt_luma_top_offset);
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_INDEX), COND0, TYPE0, 1);
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_DATA), COND0, TYPE0, dec->jpg.dt_chroma_top_offset);
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_TIER_CNTL2), COND0, TYPE3, 0);
// set output buffer read pointer
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_OUTBUF_RPTR), COND0, TYPE0, 0);
// set output buffer read pointer
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_OUTBUF_RPTR), COND0, TYPE0, 0);
// enable error interrupts
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_INT_EN), COND0, TYPE0, 0xFFFFFFFE);
// enable error interrupts
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_INT_EN), COND0, TYPE0, 0xFFFFFFFE);
// start engine command
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_CNTL), COND0, TYPE0, 0x6);
// start engine command
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_CNTL), COND0, TYPE0, 0x6);
// wait for job completion, wait for job JBSI fetch done
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_INDEX), COND0, TYPE0, 0x01C3);
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_DATA), COND0, TYPE0, (dec->jpg.bsd_size >> 2));
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_INDEX), COND0, TYPE0, 0x01C2);
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_DATA), COND0, TYPE0, 0x01400200);
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_RB_RPTR), COND0, TYPE3, 0xFFFFFFFF);
// wait for job completion, wait for job JBSI fetch done
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_INDEX), COND0, TYPE0, 0x01C3);
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_DATA), COND0, TYPE0, (dec->jpg.bsd_size >> 2));
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_INDEX), COND0, TYPE0, 0x01C2);
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_DATA), COND0, TYPE0, 0x01400200);
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_RB_RPTR), COND0, TYPE3, 0xFFFFFFFF);
// wait for job jpeg outbuf idle
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_INDEX), COND0, TYPE0, 0x01C3);
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_DATA), COND0, TYPE0, 0xFFFFFFFF);
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_OUTBUF_WPTR), COND0, TYPE3, 0x00000001);
// wait for job jpeg outbuf idle
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_INDEX), COND0, TYPE0, 0x01C3);
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_DATA), COND0, TYPE0, 0xFFFFFFFF);
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_OUTBUF_WPTR), COND0, TYPE3, 0x00000001);
// stop engine
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_CNTL), COND0, TYPE0, 0x4);
// stop engine
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_CNTL), COND0, TYPE0, 0x4);
// asserting jpeg lmi drop
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_INDEX), COND0, TYPE0, 0x0005);
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_DATA), COND0, TYPE0, (1 << 23 | 1 << 0));
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_DATA), COND0, TYPE1, 0);
// asserting jpeg lmi drop
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_INDEX), COND0, TYPE0, 0x0005);
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_DATA), COND0, TYPE0, (1 << 23 | 1 << 0));
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_DATA), COND0, TYPE1, 0);
// asserting jpeg reset
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_CNTL), COND0, TYPE0, 1);
// asserting jpeg reset
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_CNTL), COND0, TYPE0, 1);
// ensure reset is asserted in sclk domain
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_INDEX), COND0, TYPE0, 0x01C3);
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_DATA), COND0, TYPE0, (1 << 9));
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_SOFT_RESET), COND0, TYPE3, (1 << 9));
// ensure reset is asserted in sclk domain
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_INDEX), COND0, TYPE0, 0x01C3);
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_DATA), COND0, TYPE0, (1 << 9));
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_SOFT_RESET), COND0, TYPE3, (1 << 9));
// de-assert jpeg reset
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_CNTL), COND0, TYPE0, 0);
// de-assert jpeg reset
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_JPEG_CNTL), COND0, TYPE0, 0);
// ensure reset is de-asserted in sclk domain
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_INDEX), COND0, TYPE0, 0x01C3);
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_DATA), COND0, TYPE0, (0 << 9));
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_SOFT_RESET), COND0, TYPE3, (1 << 9));
// ensure reset is de-asserted in sclk domain
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_INDEX), COND0, TYPE0, 0x01C3);
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_DATA), COND0, TYPE0, (0 << 9));
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_SOFT_RESET), COND0, TYPE3, (1 << 9));
// de-asserting jpeg lmi drop
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_INDEX), COND0, TYPE0, 0x0005);
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_DATA), COND0, TYPE0, 0);
// de-asserting jpeg lmi drop
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_INDEX), COND0, TYPE0, 0x0005);
set_reg_jpeg(dec, SOC15_REG_ADDR(mmUVD_CTX_DATA), COND0, TYPE0, 0);
}
/* send a bitstream buffer command */
static void send_cmd_bitstream_direct(struct radeon_decoder *dec,
struct pb_buffer* buf, uint32_t off,
enum radeon_bo_usage usage, enum radeon_bo_domain domain)
static void send_cmd_bitstream_direct(struct radeon_decoder *dec, struct pb_buffer *buf,
uint32_t off, enum radeon_bo_usage usage,
enum radeon_bo_domain domain)
{
uint64_t addr;
uint64_t addr;
// jpeg soft reset
set_reg_jpeg(dec, vcnipUVD_JPEG_DEC_SOFT_RST, COND0, TYPE0, 1);
// jpeg soft reset
set_reg_jpeg(dec, vcnipUVD_JPEG_DEC_SOFT_RST, COND0, TYPE0, 1);
// ensuring the Reset is asserted in SCLK domain
set_reg_jpeg(dec, vcnipUVD_JRBC_IB_COND_RD_TIMER, COND0, TYPE0, 0x01400200);
set_reg_jpeg(dec, vcnipUVD_JRBC_IB_REF_DATA, COND0, TYPE0, (0x1 << 0x10));
set_reg_jpeg(dec, vcnipUVD_JPEG_DEC_SOFT_RST, COND3, TYPE3, (0x1 << 0x10));
// ensuring the Reset is asserted in SCLK domain
set_reg_jpeg(dec, vcnipUVD_JRBC_IB_COND_RD_TIMER, COND0, TYPE0, 0x01400200);
set_reg_jpeg(dec, vcnipUVD_JRBC_IB_REF_DATA, COND0, TYPE0, (0x1 << 0x10));
set_reg_jpeg(dec, vcnipUVD_JPEG_DEC_SOFT_RST, COND3, TYPE3, (0x1 << 0x10));
// wait mem
set_reg_jpeg(dec, vcnipUVD_JPEG_DEC_SOFT_RST, COND0, TYPE0, 0);
// wait mem
set_reg_jpeg(dec, vcnipUVD_JPEG_DEC_SOFT_RST, COND0, TYPE0, 0);
// ensuring the Reset is de-asserted in SCLK domain
set_reg_jpeg(dec, vcnipUVD_JRBC_IB_REF_DATA, COND0, TYPE0, (0 << 0x10));
set_reg_jpeg(dec, vcnipUVD_JPEG_DEC_SOFT_RST, COND3, TYPE3, (0x1 << 0x10));
// ensuring the Reset is de-asserted in SCLK domain
set_reg_jpeg(dec, vcnipUVD_JRBC_IB_REF_DATA, COND0, TYPE0, (0 << 0x10));
set_reg_jpeg(dec, vcnipUVD_JPEG_DEC_SOFT_RST, COND3, TYPE3, (0x1 << 0x10));
dec->ws->cs_add_buffer(dec->cs, buf, usage | RADEON_USAGE_SYNCHRONIZED,
domain, 0);
addr = dec->ws->buffer_get_virtual_address(buf);
addr = addr + off;
dec->ws->cs_add_buffer(dec->cs, buf, usage | RADEON_USAGE_SYNCHRONIZED, domain, 0);
addr = dec->ws->buffer_get_virtual_address(buf);
addr = addr + off;
// set UVD_LMI_JPEG_READ_64BIT_BAR_LOW/HIGH based on bitstream buffer address
set_reg_jpeg(dec, vcnipUVD_LMI_JPEG_READ_64BIT_BAR_HIGH, COND0, TYPE0, (addr >> 32));
set_reg_jpeg(dec, vcnipUVD_LMI_JPEG_READ_64BIT_BAR_LOW, COND0, TYPE0, addr);
// set UVD_LMI_JPEG_READ_64BIT_BAR_LOW/HIGH based on bitstream buffer address
set_reg_jpeg(dec, vcnipUVD_LMI_JPEG_READ_64BIT_BAR_HIGH, COND0, TYPE0, (addr >> 32));
set_reg_jpeg(dec, vcnipUVD_LMI_JPEG_READ_64BIT_BAR_LOW, COND0, TYPE0, addr);
// set jpeg_rb_base
set_reg_jpeg(dec, vcnipUVD_JPEG_RB_BASE, COND0, TYPE0, 0);
// set jpeg_rb_base
set_reg_jpeg(dec, vcnipUVD_JPEG_RB_BASE, COND0, TYPE0, 0);
// set jpeg_rb_base
set_reg_jpeg(dec, vcnipUVD_JPEG_RB_SIZE, COND0, TYPE0, 0xFFFFFFF0);
// set jpeg_rb_base
set_reg_jpeg(dec, vcnipUVD_JPEG_RB_SIZE, COND0, TYPE0, 0xFFFFFFF0);
// set jpeg_rb_wptr
set_reg_jpeg(dec, vcnipUVD_JPEG_RB_WPTR, COND0, TYPE0, (dec->jpg.bsd_size >> 2));
// set jpeg_rb_wptr
set_reg_jpeg(dec, vcnipUVD_JPEG_RB_WPTR, COND0, TYPE0, (dec->jpg.bsd_size >> 2));
}
/* send a target buffer command */
static void send_cmd_target_direct(struct radeon_decoder *dec,
struct pb_buffer* buf, uint32_t off,
enum radeon_bo_usage usage, enum radeon_bo_domain domain)
static void send_cmd_target_direct(struct radeon_decoder *dec, struct pb_buffer *buf, uint32_t off,
enum radeon_bo_usage usage, enum radeon_bo_domain domain)
{
uint64_t addr;
uint64_t addr;
set_reg_jpeg(dec, vcnipUVD_JPEG_PITCH, COND0, TYPE0, (dec->jpg.dt_pitch >> 4));
set_reg_jpeg(dec, vcnipUVD_JPEG_UV_PITCH, COND0, TYPE0, ((dec->jpg.dt_uv_pitch * 2) >> 4));
set_reg_jpeg(dec, vcnipUVD_JPEG_PITCH, COND0, TYPE0, (dec->jpg.dt_pitch >> 4));
set_reg_jpeg(dec, vcnipUVD_JPEG_UV_PITCH, COND0, TYPE0, ((dec->jpg.dt_uv_pitch * 2) >> 4));
set_reg_jpeg(dec, vcnipJPEG_DEC_ADDR_MODE, COND0, TYPE0, 0);
set_reg_jpeg(dec, vcnipJPEG_DEC_Y_GFX10_TILING_SURFACE, COND0, TYPE0, 0);
set_reg_jpeg(dec, vcnipJPEG_DEC_UV_GFX10_TILING_SURFACE, COND0, TYPE0, 0);
set_reg_jpeg(dec, vcnipJPEG_DEC_ADDR_MODE, COND0, TYPE0, 0);
set_reg_jpeg(dec, vcnipJPEG_DEC_Y_GFX10_TILING_SURFACE, COND0, TYPE0, 0);
set_reg_jpeg(dec, vcnipJPEG_DEC_UV_GFX10_TILING_SURFACE, COND0, TYPE0, 0);
dec->ws->cs_add_buffer(dec->cs, buf, usage | RADEON_USAGE_SYNCHRONIZED,
domain, 0);
addr = dec->ws->buffer_get_virtual_address(buf);
addr = addr + off;
dec->ws->cs_add_buffer(dec->cs, buf, usage | RADEON_USAGE_SYNCHRONIZED, domain, 0);
addr = dec->ws->buffer_get_virtual_address(buf);
addr = addr + off;
// set UVD_LMI_JPEG_WRITE_64BIT_BAR_LOW/HIGH based on target buffer address
set_reg_jpeg(dec, vcnipUVD_LMI_JPEG_WRITE_64BIT_BAR_HIGH, COND0, TYPE0, (addr >> 32));
set_reg_jpeg(dec, vcnipUVD_LMI_JPEG_WRITE_64BIT_BAR_LOW, COND0, TYPE0, addr);
// set UVD_LMI_JPEG_WRITE_64BIT_BAR_LOW/HIGH based on target buffer address
set_reg_jpeg(dec, vcnipUVD_LMI_JPEG_WRITE_64BIT_BAR_HIGH, COND0, TYPE0, (addr >> 32));
set_reg_jpeg(dec, vcnipUVD_LMI_JPEG_WRITE_64BIT_BAR_LOW, COND0, TYPE0, addr);
// set output buffer data address
set_reg_jpeg(dec, vcnipUVD_JPEG_INDEX, COND0, TYPE0, 0);
set_reg_jpeg(dec, vcnipUVD_JPEG_DATA, COND0, TYPE0, dec->jpg.dt_luma_top_offset);
set_reg_jpeg(dec, vcnipUVD_JPEG_INDEX, COND0, TYPE0, 1);
set_reg_jpeg(dec, vcnipUVD_JPEG_DATA, COND0, TYPE0, dec->jpg.dt_chroma_top_offset);
set_reg_jpeg(dec, vcnipUVD_JPEG_TIER_CNTL2, COND0, 0, 0);
// set output buffer data address
set_reg_jpeg(dec, vcnipUVD_JPEG_INDEX, COND0, TYPE0, 0);
set_reg_jpeg(dec, vcnipUVD_JPEG_DATA, COND0, TYPE0, dec->jpg.dt_luma_top_offset);
set_reg_jpeg(dec, vcnipUVD_JPEG_INDEX, COND0, TYPE0, 1);
set_reg_jpeg(dec, vcnipUVD_JPEG_DATA, COND0, TYPE0, dec->jpg.dt_chroma_top_offset);
set_reg_jpeg(dec, vcnipUVD_JPEG_TIER_CNTL2, COND0, 0, 0);
// set output buffer read pointer
set_reg_jpeg(dec, vcnipUVD_JPEG_OUTBUF_RPTR, COND0, TYPE0, 0);
set_reg_jpeg(dec, vcnipUVD_JPEG_OUTBUF_CNTL, COND0, TYPE0, ((0x00001587 & (~0x00000180L)) | (0x1 << 0x7) | (0x1 << 0x6)));
// set output buffer read pointer
set_reg_jpeg(dec, vcnipUVD_JPEG_OUTBUF_RPTR, COND0, TYPE0, 0);
set_reg_jpeg(dec, vcnipUVD_JPEG_OUTBUF_CNTL, COND0, TYPE0,
((0x00001587 & (~0x00000180L)) | (0x1 << 0x7) | (0x1 << 0x6)));
// enable error interrupts
set_reg_jpeg(dec, vcnipUVD_JPEG_INT_EN, COND0, TYPE0, 0xFFFFFFFE);
// enable error interrupts
set_reg_jpeg(dec, vcnipUVD_JPEG_INT_EN, COND0, TYPE0, 0xFFFFFFFE);
// start engine command
set_reg_jpeg(dec, vcnipUVD_JPEG_CNTL, COND0, TYPE0, 0xE);
// start engine command
set_reg_jpeg(dec, vcnipUVD_JPEG_CNTL, COND0, TYPE0, 0xE);
// wait for job completion, wait for job JBSI fetch done
set_reg_jpeg(dec, vcnipUVD_JRBC_IB_REF_DATA, COND0, TYPE0, (dec->jpg.bsd_size >> 2));
set_reg_jpeg(dec, vcnipUVD_JRBC_IB_COND_RD_TIMER, COND0, TYPE0, 0x01400200);
set_reg_jpeg(dec, vcnipUVD_JPEG_RB_RPTR, COND3, TYPE3, 0xFFFFFFFF);
// wait for job completion, wait for job JBSI fetch done
set_reg_jpeg(dec, vcnipUVD_JRBC_IB_REF_DATA, COND0, TYPE0, (dec->jpg.bsd_size >> 2));
set_reg_jpeg(dec, vcnipUVD_JRBC_IB_COND_RD_TIMER, COND0, TYPE0, 0x01400200);
set_reg_jpeg(dec, vcnipUVD_JPEG_RB_RPTR, COND3, TYPE3, 0xFFFFFFFF);
// wait for job jpeg outbuf idle
set_reg_jpeg(dec, vcnipUVD_JRBC_IB_REF_DATA, COND0, TYPE0, 0xFFFFFFFF);
set_reg_jpeg(dec, vcnipUVD_JPEG_OUTBUF_WPTR, COND3, TYPE3, 0x00000001);
// wait for job jpeg outbuf idle
set_reg_jpeg(dec, vcnipUVD_JRBC_IB_REF_DATA, COND0, TYPE0, 0xFFFFFFFF);
set_reg_jpeg(dec, vcnipUVD_JPEG_OUTBUF_WPTR, COND3, TYPE3, 0x00000001);
// stop engine
set_reg_jpeg(dec, vcnipUVD_JPEG_CNTL, COND0, TYPE0, 0x4);
// stop engine
set_reg_jpeg(dec, vcnipUVD_JPEG_CNTL, COND0, TYPE0, 0x4);
}
/**
* send cmd for vcn jpeg
*/
void send_cmd_jpeg(struct radeon_decoder *dec,
struct pipe_video_buffer *target,
struct pipe_picture_desc *picture)
void send_cmd_jpeg(struct radeon_decoder *dec, struct pipe_video_buffer *target,
struct pipe_picture_desc *picture)
{
struct pb_buffer *dt;
struct rvid_buffer *bs_buf;
struct pb_buffer *dt;
struct rvid_buffer *bs_buf;
bs_buf = &dec->bs_buffers[dec->cur_buffer];
bs_buf = &dec->bs_buffers[dec->cur_buffer];
memset(dec->bs_ptr, 0, align(dec->bs_size, 128) - dec->bs_size);
dec->ws->buffer_unmap(bs_buf->res->buf);
memset(dec->bs_ptr, 0, align(dec->bs_size, 128) - dec->bs_size);
dec->ws->buffer_unmap(bs_buf->res->buf);
dt = radeon_jpeg_get_decode_param(dec, target, picture);
dt = radeon_jpeg_get_decode_param(dec, target, picture);
if (dec->jpg.direct_reg == true) {
send_cmd_bitstream_direct(dec, bs_buf->res->buf,
0, RADEON_USAGE_READ, RADEON_DOMAIN_GTT);
send_cmd_target_direct(dec, dt, 0,
RADEON_USAGE_WRITE, RADEON_DOMAIN_VRAM);
} else {
send_cmd_bitstream(dec, bs_buf->res->buf,
0, RADEON_USAGE_READ, RADEON_DOMAIN_GTT);
send_cmd_target(dec, dt, 0,
RADEON_USAGE_WRITE, RADEON_DOMAIN_VRAM);
}
if (dec->jpg.direct_reg == true) {
send_cmd_bitstream_direct(dec, bs_buf->res->buf, 0, RADEON_USAGE_READ, RADEON_DOMAIN_GTT);
send_cmd_target_direct(dec, dt, 0, RADEON_USAGE_WRITE, RADEON_DOMAIN_VRAM);
} else {
send_cmd_bitstream(dec, bs_buf->res->buf, 0, RADEON_USAGE_READ, RADEON_DOMAIN_GTT);
send_cmd_target(dec, dt, 0, RADEON_USAGE_WRITE, RADEON_DOMAIN_VRAM);
}
}

View File

@ -25,18 +25,16 @@
*
**************************************************************************/
#include <stdio.h>
#include "radeon_vcn_enc.h"
#include "pipe/p_video_codec.h"
#include "util/u_video.h"
#include "radeon_video.h"
#include "radeonsi/si_pipe.h"
#include "util/u_memory.h"
#include "util/u_video.h"
#include "vl/vl_video_buffer.h"
#include "radeonsi/si_pipe.h"
#include "radeon_video.h"
#include "radeon_vcn_enc.h"
#include <stdio.h>
static const unsigned index_to_shifts[4] = {24, 16, 8, 0};
@ -53,15 +51,15 @@ static void radeon_vcn_enc_get_param(struct radeon_encoder *enc, struct pipe_pic
enc->enc_pic.not_referenced = pic->not_referenced;
enc->enc_pic.is_idr = (pic->picture_type == PIPE_H264_ENC_PICTURE_TYPE_IDR);
if (pic->pic_ctrl.enc_frame_cropping_flag) {
enc->enc_pic.crop_left = pic->pic_ctrl.enc_frame_crop_left_offset;
enc->enc_pic.crop_right = pic->pic_ctrl.enc_frame_crop_right_offset;
enc->enc_pic.crop_top = pic->pic_ctrl.enc_frame_crop_top_offset;
enc->enc_pic.crop_bottom = pic->pic_ctrl.enc_frame_crop_bottom_offset;
enc->enc_pic.crop_left = pic->pic_ctrl.enc_frame_crop_left_offset;
enc->enc_pic.crop_right = pic->pic_ctrl.enc_frame_crop_right_offset;
enc->enc_pic.crop_top = pic->pic_ctrl.enc_frame_crop_top_offset;
enc->enc_pic.crop_bottom = pic->pic_ctrl.enc_frame_crop_bottom_offset;
} else {
enc->enc_pic.crop_left = 0;
enc->enc_pic.crop_right = (align(enc->base.width, 16) - enc->base.width) / 2;
enc->enc_pic.crop_top = 0;
enc->enc_pic.crop_bottom = (align(enc->base.height, 16) - enc->base.height) / 2;
enc->enc_pic.crop_left = 0;
enc->enc_pic.crop_right = (align(enc->base.width, 16) - enc->base.width) / 2;
enc->enc_pic.crop_top = 0;
enc->enc_pic.crop_bottom = (align(enc->base.height, 16) - enc->base.height) / 2;
}
enc->enc_pic.rc_layer_init.target_bit_rate = pic->rate_ctrl.target_bitrate;
enc->enc_pic.rc_layer_init.peak_bit_rate = pic->rate_ctrl.peak_bitrate;
@ -69,8 +67,10 @@ static void radeon_vcn_enc_get_param(struct radeon_encoder *enc, struct pipe_pic
enc->enc_pic.rc_layer_init.frame_rate_den = pic->rate_ctrl.frame_rate_den;
enc->enc_pic.rc_layer_init.vbv_buffer_size = pic->rate_ctrl.vbv_buffer_size;
enc->enc_pic.rc_layer_init.avg_target_bits_per_picture = pic->rate_ctrl.target_bits_picture;
enc->enc_pic.rc_layer_init.peak_bits_per_picture_integer = pic->rate_ctrl.peak_bits_picture_integer;
enc->enc_pic.rc_layer_init.peak_bits_per_picture_fractional = pic->rate_ctrl.peak_bits_picture_fraction;
enc->enc_pic.rc_layer_init.peak_bits_per_picture_integer =
pic->rate_ctrl.peak_bits_picture_integer;
enc->enc_pic.rc_layer_init.peak_bits_per_picture_fractional =
pic->rate_ctrl.peak_bits_picture_fraction;
enc->enc_pic.rc_session_init.vbv_buffer_level = pic->rate_ctrl.vbv_buf_lv;
enc->enc_pic.rc_per_pic.qp = pic->quant_i_frames;
enc->enc_pic.rc_per_pic.min_qp_app = 0;
@ -79,20 +79,21 @@ static void radeon_vcn_enc_get_param(struct radeon_encoder *enc, struct pipe_pic
enc->enc_pic.rc_per_pic.enabled_filler_data = pic->rate_ctrl.fill_data_enable;
enc->enc_pic.rc_per_pic.skip_frame_enable = false;
enc->enc_pic.rc_per_pic.enforce_hrd = pic->rate_ctrl.enforce_hrd;
switch(pic->rate_ctrl.rate_ctrl_method) {
case PIPE_H264_ENC_RATE_CONTROL_METHOD_DISABLE:
enc->enc_pic.rc_session_init.rate_control_method = RENCODE_RATE_CONTROL_METHOD_NONE;
break;
case PIPE_H264_ENC_RATE_CONTROL_METHOD_CONSTANT_SKIP:
case PIPE_H264_ENC_RATE_CONTROL_METHOD_CONSTANT:
enc->enc_pic.rc_session_init.rate_control_method = RENCODE_RATE_CONTROL_METHOD_CBR;
break;
case PIPE_H264_ENC_RATE_CONTROL_METHOD_VARIABLE_SKIP:
case PIPE_H264_ENC_RATE_CONTROL_METHOD_VARIABLE:
enc->enc_pic.rc_session_init.rate_control_method = RENCODE_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR;
break;
default:
enc->enc_pic.rc_session_init.rate_control_method = RENCODE_RATE_CONTROL_METHOD_NONE;
switch (pic->rate_ctrl.rate_ctrl_method) {
case PIPE_H264_ENC_RATE_CONTROL_METHOD_DISABLE:
enc->enc_pic.rc_session_init.rate_control_method = RENCODE_RATE_CONTROL_METHOD_NONE;
break;
case PIPE_H264_ENC_RATE_CONTROL_METHOD_CONSTANT_SKIP:
case PIPE_H264_ENC_RATE_CONTROL_METHOD_CONSTANT:
enc->enc_pic.rc_session_init.rate_control_method = RENCODE_RATE_CONTROL_METHOD_CBR;
break;
case PIPE_H264_ENC_RATE_CONTROL_METHOD_VARIABLE_SKIP:
case PIPE_H264_ENC_RATE_CONTROL_METHOD_VARIABLE:
enc->enc_pic.rc_session_init.rate_control_method =
RENCODE_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR;
break;
default:
enc->enc_pic.rc_session_init.rate_control_method = RENCODE_RATE_CONTROL_METHOD_NONE;
}
} else if (u_reduce_video_profile(picture->profile) == PIPE_VIDEO_FORMAT_HEVC) {
struct pipe_h265_enc_picture_desc *pic = (struct pipe_h265_enc_picture_desc *)picture;
@ -112,37 +113,47 @@ static void radeon_vcn_enc_get_param(struct radeon_encoder *enc, struct pipe_pic
enc->enc_pic.general_tier_flag = pic->seq.general_tier_flag;
enc->enc_pic.general_profile_idc = pic->seq.general_profile_idc;
enc->enc_pic.general_level_idc = pic->seq.general_level_idc;
enc->enc_pic.max_poc =
MAX2(16, util_next_power_of_two(pic->seq.intra_period));
enc->enc_pic.max_poc = MAX2(16, util_next_power_of_two(pic->seq.intra_period));
enc->enc_pic.log2_max_poc = 0;
for (int i = enc->enc_pic.max_poc; i != 0; enc->enc_pic.log2_max_poc++)
i = (i >> 1);
enc->enc_pic.chroma_format_idc = pic->seq.chroma_format_idc;
enc->enc_pic.pic_width_in_luma_samples = pic->seq.pic_width_in_luma_samples;
enc->enc_pic.pic_height_in_luma_samples = pic->seq.pic_height_in_luma_samples;
enc->enc_pic.log2_diff_max_min_luma_coding_block_size = pic->seq.log2_diff_max_min_luma_coding_block_size;
enc->enc_pic.log2_min_transform_block_size_minus2 = pic->seq.log2_min_transform_block_size_minus2;
enc->enc_pic.log2_diff_max_min_transform_block_size = pic->seq.log2_diff_max_min_transform_block_size;
enc->enc_pic.max_transform_hierarchy_depth_inter = pic->seq.max_transform_hierarchy_depth_inter;
enc->enc_pic.max_transform_hierarchy_depth_intra = pic->seq.max_transform_hierarchy_depth_intra;
enc->enc_pic.log2_diff_max_min_luma_coding_block_size =
pic->seq.log2_diff_max_min_luma_coding_block_size;
enc->enc_pic.log2_min_transform_block_size_minus2 =
pic->seq.log2_min_transform_block_size_minus2;
enc->enc_pic.log2_diff_max_min_transform_block_size =
pic->seq.log2_diff_max_min_transform_block_size;
enc->enc_pic.max_transform_hierarchy_depth_inter =
pic->seq.max_transform_hierarchy_depth_inter;
enc->enc_pic.max_transform_hierarchy_depth_intra =
pic->seq.max_transform_hierarchy_depth_intra;
enc->enc_pic.log2_parallel_merge_level_minus2 = pic->pic.log2_parallel_merge_level_minus2;
enc->enc_pic.bit_depth_luma_minus8 = pic->seq.bit_depth_luma_minus8;
enc->enc_pic.bit_depth_chroma_minus8 = pic->seq.bit_depth_chroma_minus8;
enc->enc_pic.nal_unit_type = pic->pic.nal_unit_type;
enc->enc_pic.max_num_merge_cand = pic->slice.max_num_merge_cand;
enc->enc_pic.sample_adaptive_offset_enabled_flag = pic->seq.sample_adaptive_offset_enabled_flag;
enc->enc_pic.sample_adaptive_offset_enabled_flag =
pic->seq.sample_adaptive_offset_enabled_flag;
enc->enc_pic.pcm_enabled_flag = pic->seq.pcm_enabled_flag;
enc->enc_pic.sps_temporal_mvp_enabled_flag = pic->seq.sps_temporal_mvp_enabled_flag;
enc->enc_pic.hevc_deblock.loop_filter_across_slices_enabled = pic->slice.slice_loop_filter_across_slices_enabled_flag;
enc->enc_pic.hevc_deblock.deblocking_filter_disabled = pic->slice.slice_deblocking_filter_disabled_flag;
enc->enc_pic.hevc_deblock.loop_filter_across_slices_enabled =
pic->slice.slice_loop_filter_across_slices_enabled_flag;
enc->enc_pic.hevc_deblock.deblocking_filter_disabled =
pic->slice.slice_deblocking_filter_disabled_flag;
enc->enc_pic.hevc_deblock.beta_offset_div2 = pic->slice.slice_beta_offset_div2;
enc->enc_pic.hevc_deblock.tc_offset_div2 = pic->slice.slice_tc_offset_div2;
enc->enc_pic.hevc_deblock.cb_qp_offset = pic->slice.slice_cb_qp_offset;
enc->enc_pic.hevc_deblock.cr_qp_offset = pic->slice.slice_cr_qp_offset;
enc->enc_pic.hevc_spec_misc.log2_min_luma_coding_block_size_minus3 = pic->seq.log2_min_luma_coding_block_size_minus3;
enc->enc_pic.hevc_spec_misc.log2_min_luma_coding_block_size_minus3 =
pic->seq.log2_min_luma_coding_block_size_minus3;
enc->enc_pic.hevc_spec_misc.amp_disabled = !pic->seq.amp_enabled_flag;
enc->enc_pic.hevc_spec_misc.strong_intra_smoothing_enabled = pic->seq.strong_intra_smoothing_enabled_flag;
enc->enc_pic.hevc_spec_misc.constrained_intra_pred_flag = pic->pic.constrained_intra_pred_flag;
enc->enc_pic.hevc_spec_misc.strong_intra_smoothing_enabled =
pic->seq.strong_intra_smoothing_enabled_flag;
enc->enc_pic.hevc_spec_misc.constrained_intra_pred_flag =
pic->pic.constrained_intra_pred_flag;
enc->enc_pic.hevc_spec_misc.cabac_init_flag = pic->slice.cabac_init_flag;
enc->enc_pic.hevc_spec_misc.half_pel_enabled = 1;
enc->enc_pic.hevc_spec_misc.quarter_pel_enabled = 1;
@ -153,7 +164,8 @@ static void radeon_vcn_enc_get_param(struct radeon_encoder *enc, struct pipe_pic
enc->enc_pic.rc_layer_init.vbv_buffer_size = pic->rc.vbv_buffer_size;
enc->enc_pic.rc_layer_init.avg_target_bits_per_picture = pic->rc.target_bits_picture;
enc->enc_pic.rc_layer_init.peak_bits_per_picture_integer = pic->rc.peak_bits_picture_integer;
enc->enc_pic.rc_layer_init.peak_bits_per_picture_fractional = pic->rc.peak_bits_picture_fraction;
enc->enc_pic.rc_layer_init.peak_bits_per_picture_fractional =
pic->rc.peak_bits_picture_fraction;
enc->enc_pic.rc_session_init.vbv_buffer_level = pic->rc.vbv_buf_lv;
enc->enc_pic.rc_per_pic.qp = pic->rc.quant_i_frames;
enc->enc_pic.rc_per_pic.min_qp_app = 0;
@ -162,424 +174,420 @@ static void radeon_vcn_enc_get_param(struct radeon_encoder *enc, struct pipe_pic
enc->enc_pic.rc_per_pic.enabled_filler_data = pic->rc.fill_data_enable;
enc->enc_pic.rc_per_pic.skip_frame_enable = false;
enc->enc_pic.rc_per_pic.enforce_hrd = pic->rc.enforce_hrd;
switch(pic->rc.rate_ctrl_method) {
case PIPE_H265_ENC_RATE_CONTROL_METHOD_DISABLE:
switch (pic->rc.rate_ctrl_method) {
case PIPE_H265_ENC_RATE_CONTROL_METHOD_DISABLE:
enc->enc_pic.rc_session_init.rate_control_method = RENCODE_RATE_CONTROL_METHOD_NONE;
break;
case PIPE_H265_ENC_RATE_CONTROL_METHOD_CONSTANT_SKIP:
case PIPE_H265_ENC_RATE_CONTROL_METHOD_CONSTANT:
enc->enc_pic.rc_session_init.rate_control_method = RENCODE_RATE_CONTROL_METHOD_CBR;
break;
case PIPE_H265_ENC_RATE_CONTROL_METHOD_VARIABLE_SKIP:
case PIPE_H265_ENC_RATE_CONTROL_METHOD_VARIABLE:
enc->enc_pic.rc_session_init.rate_control_method =
RENCODE_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR;
break;
default:
enc->enc_pic.rc_session_init.rate_control_method = RENCODE_RATE_CONTROL_METHOD_NONE;
break;
case PIPE_H265_ENC_RATE_CONTROL_METHOD_CONSTANT_SKIP:
case PIPE_H265_ENC_RATE_CONTROL_METHOD_CONSTANT:
enc->enc_pic.rc_session_init.rate_control_method = RENCODE_RATE_CONTROL_METHOD_CBR;
break;
case PIPE_H265_ENC_RATE_CONTROL_METHOD_VARIABLE_SKIP:
case PIPE_H265_ENC_RATE_CONTROL_METHOD_VARIABLE:
enc->enc_pic.rc_session_init.rate_control_method = RENCODE_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR;
break;
default:
enc->enc_pic.rc_session_init.rate_control_method = RENCODE_RATE_CONTROL_METHOD_NONE;
}
}
}
static void flush(struct radeon_encoder *enc)
{
enc->ws->cs_flush(enc->cs, PIPE_FLUSH_ASYNC, NULL);
enc->ws->cs_flush(enc->cs, PIPE_FLUSH_ASYNC, NULL);
}
static void radeon_enc_flush(struct pipe_video_codec *encoder)
{
struct radeon_encoder *enc = (struct radeon_encoder*)encoder;
flush(enc);
struct radeon_encoder *enc = (struct radeon_encoder *)encoder;
flush(enc);
}
static void radeon_enc_cs_flush(void *ctx, unsigned flags,
struct pipe_fence_handle **fence)
static void radeon_enc_cs_flush(void *ctx, unsigned flags, struct pipe_fence_handle **fence)
{
// just ignored
// just ignored
}
static unsigned get_cpb_num(struct radeon_encoder *enc)
{
unsigned w = align(enc->base.width, 16) / 16;
unsigned h = align(enc->base.height, 16) / 16;
unsigned dpb;
unsigned w = align(enc->base.width, 16) / 16;
unsigned h = align(enc->base.height, 16) / 16;
unsigned dpb;
switch (enc->base.level) {
case 10:
dpb = 396;
break;
case 11:
dpb = 900;
break;
case 12:
case 13:
case 20:
dpb = 2376;
break;
case 21:
dpb = 4752;
break;
case 22:
case 30:
dpb = 8100;
break;
case 31:
dpb = 18000;
break;
case 32:
dpb = 20480;
break;
case 40:
case 41:
dpb = 32768;
break;
case 42:
dpb = 34816;
break;
case 50:
dpb = 110400;
break;
default:
case 51:
case 52:
dpb = 184320;
break;
}
switch (enc->base.level) {
case 10:
dpb = 396;
break;
case 11:
dpb = 900;
break;
case 12:
case 13:
case 20:
dpb = 2376;
break;
case 21:
dpb = 4752;
break;
case 22:
case 30:
dpb = 8100;
break;
case 31:
dpb = 18000;
break;
case 32:
dpb = 20480;
break;
case 40:
case 41:
dpb = 32768;
break;
case 42:
dpb = 34816;
break;
case 50:
dpb = 110400;
break;
default:
case 51:
case 52:
dpb = 184320;
break;
}
return MIN2(dpb / (w * h), 16);
return MIN2(dpb / (w * h), 16);
}
static void radeon_enc_begin_frame(struct pipe_video_codec *encoder,
struct pipe_video_buffer *source,
struct pipe_picture_desc *picture)
struct pipe_video_buffer *source,
struct pipe_picture_desc *picture)
{
struct radeon_encoder *enc = (struct radeon_encoder*)encoder;
struct vl_video_buffer *vid_buf = (struct vl_video_buffer *)source;
bool need_rate_control = false;
struct radeon_encoder *enc = (struct radeon_encoder *)encoder;
struct vl_video_buffer *vid_buf = (struct vl_video_buffer *)source;
bool need_rate_control = false;
if (u_reduce_video_profile(enc->base.profile) == PIPE_VIDEO_FORMAT_MPEG4_AVC) {
struct pipe_h264_enc_picture_desc *pic = (struct pipe_h264_enc_picture_desc *)picture;
need_rate_control =
enc->enc_pic.rc_layer_init.target_bit_rate != pic->rate_ctrl.target_bitrate;
} else if (u_reduce_video_profile(picture->profile) == PIPE_VIDEO_FORMAT_HEVC) {
struct pipe_h265_enc_picture_desc *pic = (struct pipe_h265_enc_picture_desc *)picture;
need_rate_control =
enc->enc_pic.rc_layer_init.target_bit_rate != pic->rc.target_bitrate;
}
if (u_reduce_video_profile(enc->base.profile) == PIPE_VIDEO_FORMAT_MPEG4_AVC) {
struct pipe_h264_enc_picture_desc *pic = (struct pipe_h264_enc_picture_desc *)picture;
need_rate_control =
enc->enc_pic.rc_layer_init.target_bit_rate != pic->rate_ctrl.target_bitrate;
} else if (u_reduce_video_profile(picture->profile) == PIPE_VIDEO_FORMAT_HEVC) {
struct pipe_h265_enc_picture_desc *pic = (struct pipe_h265_enc_picture_desc *)picture;
need_rate_control = enc->enc_pic.rc_layer_init.target_bit_rate != pic->rc.target_bitrate;
}
radeon_vcn_enc_get_param(enc, picture);
radeon_vcn_enc_get_param(enc, picture);
enc->get_buffer(vid_buf->resources[0], &enc->handle, &enc->luma);
enc->get_buffer(vid_buf->resources[1], NULL, &enc->chroma);
enc->get_buffer(vid_buf->resources[0], &enc->handle, &enc->luma);
enc->get_buffer(vid_buf->resources[1], NULL, &enc->chroma);
enc->need_feedback = false;
enc->need_feedback = false;
if (!enc->stream_handle) {
struct rvid_buffer fb;
enc->stream_handle = si_vid_alloc_stream_handle();
enc->si = CALLOC_STRUCT(rvid_buffer);
si_vid_create_buffer(enc->screen, enc->si, 128 * 1024, PIPE_USAGE_STAGING);
si_vid_create_buffer(enc->screen, &fb, 4096, PIPE_USAGE_STAGING);
enc->fb = &fb;
enc->begin(enc);
flush(enc);
si_vid_destroy_buffer(&fb);
}
if (need_rate_control) {
enc->begin(enc);
flush(enc);
}
if (!enc->stream_handle) {
struct rvid_buffer fb;
enc->stream_handle = si_vid_alloc_stream_handle();
enc->si = CALLOC_STRUCT(rvid_buffer);
si_vid_create_buffer(enc->screen, enc->si, 128 * 1024, PIPE_USAGE_STAGING);
si_vid_create_buffer(enc->screen, &fb, 4096, PIPE_USAGE_STAGING);
enc->fb = &fb;
enc->begin(enc);
flush(enc);
si_vid_destroy_buffer(&fb);
}
if (need_rate_control) {
enc->begin(enc);
flush(enc);
}
}
static void radeon_enc_encode_bitstream(struct pipe_video_codec *encoder,
struct pipe_video_buffer *source,
struct pipe_resource *destination,
void **fb)
struct pipe_video_buffer *source,
struct pipe_resource *destination, void **fb)
{
struct radeon_encoder *enc = (struct radeon_encoder*)encoder;
enc->get_buffer(destination, &enc->bs_handle, NULL);
enc->bs_size = destination->width0;
struct radeon_encoder *enc = (struct radeon_encoder *)encoder;
enc->get_buffer(destination, &enc->bs_handle, NULL);
enc->bs_size = destination->width0;
*fb = enc->fb = CALLOC_STRUCT(rvid_buffer);
*fb = enc->fb = CALLOC_STRUCT(rvid_buffer);
if (!si_vid_create_buffer(enc->screen, enc->fb, 4096, PIPE_USAGE_STAGING)) {
RVID_ERR("Can't create feedback buffer.\n");
return;
}
if (!si_vid_create_buffer(enc->screen, enc->fb, 4096, PIPE_USAGE_STAGING)) {
RVID_ERR("Can't create feedback buffer.\n");
return;
}
enc->need_feedback = true;
enc->encode(enc);
enc->need_feedback = true;
enc->encode(enc);
}
static void radeon_enc_end_frame(struct pipe_video_codec *encoder,
struct pipe_video_buffer *source,
struct pipe_picture_desc *picture)
static void radeon_enc_end_frame(struct pipe_video_codec *encoder, struct pipe_video_buffer *source,
struct pipe_picture_desc *picture)
{
struct radeon_encoder *enc = (struct radeon_encoder*)encoder;
flush(enc);
struct radeon_encoder *enc = (struct radeon_encoder *)encoder;
flush(enc);
}
static void radeon_enc_destroy(struct pipe_video_codec *encoder)
{
struct radeon_encoder *enc = (struct radeon_encoder*)encoder;
struct radeon_encoder *enc = (struct radeon_encoder *)encoder;
if (enc->stream_handle) {
struct rvid_buffer fb;
enc->need_feedback = false;
si_vid_create_buffer(enc->screen, &fb, 512, PIPE_USAGE_STAGING);
enc->fb = &fb;
enc->destroy(enc);
flush(enc);
si_vid_destroy_buffer(&fb);
}
if (enc->stream_handle) {
struct rvid_buffer fb;
enc->need_feedback = false;
si_vid_create_buffer(enc->screen, &fb, 512, PIPE_USAGE_STAGING);
enc->fb = &fb;
enc->destroy(enc);
flush(enc);
si_vid_destroy_buffer(&fb);
}
si_vid_destroy_buffer(&enc->cpb);
enc->ws->cs_destroy(enc->cs);
FREE(enc);
si_vid_destroy_buffer(&enc->cpb);
enc->ws->cs_destroy(enc->cs);
FREE(enc);
}
static void radeon_enc_get_feedback(struct pipe_video_codec *encoder,
void *feedback, unsigned *size)
static void radeon_enc_get_feedback(struct pipe_video_codec *encoder, void *feedback,
unsigned *size)
{
struct radeon_encoder *enc = (struct radeon_encoder*)encoder;
struct rvid_buffer *fb = feedback;
struct radeon_encoder *enc = (struct radeon_encoder *)encoder;
struct rvid_buffer *fb = feedback;
if (size) {
uint32_t *ptr = enc->ws->buffer_map(
fb->res->buf, enc->cs,
PIPE_TRANSFER_READ_WRITE | RADEON_TRANSFER_TEMPORARY);
if (ptr[1])
*size = ptr[6];
else
*size = 0;
enc->ws->buffer_unmap(fb->res->buf);
}
if (size) {
uint32_t *ptr = enc->ws->buffer_map(fb->res->buf, enc->cs,
PIPE_TRANSFER_READ_WRITE | RADEON_TRANSFER_TEMPORARY);
if (ptr[1])
*size = ptr[6];
else
*size = 0;
enc->ws->buffer_unmap(fb->res->buf);
}
si_vid_destroy_buffer(fb);
FREE(fb);
si_vid_destroy_buffer(fb);
FREE(fb);
}
struct pipe_video_codec *radeon_create_encoder(struct pipe_context *context,
const struct pipe_video_codec *templ,
struct radeon_winsys* ws,
radeon_enc_get_buffer get_buffer)
const struct pipe_video_codec *templ,
struct radeon_winsys *ws,
radeon_enc_get_buffer get_buffer)
{
struct si_screen *sscreen = (struct si_screen *)context->screen;
struct si_context *sctx = (struct si_context*)context;
struct radeon_encoder *enc;
struct pipe_video_buffer *tmp_buf, templat = {};
struct radeon_surf *tmp_surf;
unsigned cpb_size;
struct si_screen *sscreen = (struct si_screen *)context->screen;
struct si_context *sctx = (struct si_context *)context;
struct radeon_encoder *enc;
struct pipe_video_buffer *tmp_buf, templat = {};
struct radeon_surf *tmp_surf;
unsigned cpb_size;
enc = CALLOC_STRUCT(radeon_encoder);
enc = CALLOC_STRUCT(radeon_encoder);
if (!enc)
return NULL;
if (!enc)
return NULL;
enc->alignment = 256;
enc->base = *templ;
enc->base.context = context;
enc->base.destroy = radeon_enc_destroy;
enc->base.begin_frame = radeon_enc_begin_frame;
enc->base.encode_bitstream = radeon_enc_encode_bitstream;
enc->base.end_frame = radeon_enc_end_frame;
enc->base.flush = radeon_enc_flush;
enc->base.get_feedback = radeon_enc_get_feedback;
enc->get_buffer = get_buffer;
enc->bits_in_shifter = 0;
enc->screen = context->screen;
enc->ws = ws;
enc->cs = ws->cs_create(sctx->ctx, RING_VCN_ENC, radeon_enc_cs_flush,
enc, false);
enc->alignment = 256;
enc->base = *templ;
enc->base.context = context;
enc->base.destroy = radeon_enc_destroy;
enc->base.begin_frame = radeon_enc_begin_frame;
enc->base.encode_bitstream = radeon_enc_encode_bitstream;
enc->base.end_frame = radeon_enc_end_frame;
enc->base.flush = radeon_enc_flush;
enc->base.get_feedback = radeon_enc_get_feedback;
enc->get_buffer = get_buffer;
enc->bits_in_shifter = 0;
enc->screen = context->screen;
enc->ws = ws;
enc->cs = ws->cs_create(sctx->ctx, RING_VCN_ENC, radeon_enc_cs_flush, enc, false);
if (!enc->cs) {
RVID_ERR("Can't get command submission context.\n");
goto error;
}
if (!enc->cs) {
RVID_ERR("Can't get command submission context.\n");
goto error;
}
struct rvid_buffer si;
si_vid_create_buffer(enc->screen, &si, 128 * 1024, PIPE_USAGE_STAGING);
enc->si = &si;
struct rvid_buffer si;
si_vid_create_buffer(enc->screen, &si, 128 * 1024, PIPE_USAGE_STAGING);
enc->si = &si;
templat.buffer_format = PIPE_FORMAT_NV12;
if (enc->base.profile == PIPE_VIDEO_PROFILE_HEVC_MAIN_10)
templat.buffer_format = PIPE_FORMAT_P010;
templat.width = enc->base.width;
templat.height = enc->base.height;
templat.interlaced = false;
templat.buffer_format = PIPE_FORMAT_NV12;
if (enc->base.profile == PIPE_VIDEO_PROFILE_HEVC_MAIN_10)
templat.buffer_format = PIPE_FORMAT_P010;
templat.width = enc->base.width;
templat.height = enc->base.height;
templat.interlaced = false;
if (!(tmp_buf = context->create_video_buffer(context, &templat))) {
RVID_ERR("Can't create video buffer.\n");
goto error;
}
if (!(tmp_buf = context->create_video_buffer(context, &templat))) {
RVID_ERR("Can't create video buffer.\n");
goto error;
}
enc->cpb_num = get_cpb_num(enc);
enc->cpb_num = get_cpb_num(enc);
if (!enc->cpb_num)
goto error;
if (!enc->cpb_num)
goto error;
get_buffer(((struct vl_video_buffer *)tmp_buf)->resources[0], NULL, &tmp_surf);
get_buffer(((struct vl_video_buffer *)tmp_buf)->resources[0], NULL, &tmp_surf);
cpb_size = (sscreen->info.chip_class < GFX9) ?
align(tmp_surf->u.legacy.level[0].nblk_x * tmp_surf->bpe, 128) *
align(tmp_surf->u.legacy.level[0].nblk_y, 32) :
align(tmp_surf->u.gfx9.surf_pitch * tmp_surf->bpe, 256) *
align(tmp_surf->u.gfx9.surf_height, 32);
cpb_size = (sscreen->info.chip_class < GFX9)
? align(tmp_surf->u.legacy.level[0].nblk_x * tmp_surf->bpe, 128) *
align(tmp_surf->u.legacy.level[0].nblk_y, 32)
: align(tmp_surf->u.gfx9.surf_pitch * tmp_surf->bpe, 256) *
align(tmp_surf->u.gfx9.surf_height, 32);
cpb_size = cpb_size * 3 / 2;
cpb_size = cpb_size * enc->cpb_num;
tmp_buf->destroy(tmp_buf);
cpb_size = cpb_size * 3 / 2;
cpb_size = cpb_size * enc->cpb_num;
tmp_buf->destroy(tmp_buf);
if (!si_vid_create_buffer(enc->screen, &enc->cpb, cpb_size, PIPE_USAGE_DEFAULT)) {
RVID_ERR("Can't create CPB buffer.\n");
goto error;
}
if (!si_vid_create_buffer(enc->screen, &enc->cpb, cpb_size, PIPE_USAGE_DEFAULT)) {
RVID_ERR("Can't create CPB buffer.\n");
goto error;
}
if (sscreen->info.family <= CHIP_RAVEN2)
radeon_enc_1_2_init(enc);
else
radeon_enc_2_0_init(enc);
if (sscreen->info.family <= CHIP_RAVEN2)
radeon_enc_1_2_init(enc);
else
radeon_enc_2_0_init(enc);
return &enc->base;
return &enc->base;
error:
if (enc->cs)
enc->ws->cs_destroy(enc->cs);
if (enc->cs)
enc->ws->cs_destroy(enc->cs);
si_vid_destroy_buffer(&enc->cpb);
si_vid_destroy_buffer(&enc->cpb);
FREE(enc);
return NULL;
FREE(enc);
return NULL;
}
void radeon_enc_add_buffer(struct radeon_encoder *enc, struct pb_buffer *buf,
enum radeon_bo_usage usage, enum radeon_bo_domain domain,
signed offset)
enum radeon_bo_usage usage, enum radeon_bo_domain domain, signed offset)
{
enc->ws->cs_add_buffer(enc->cs, buf, usage | RADEON_USAGE_SYNCHRONIZED,
domain, 0);
uint64_t addr;
addr = enc->ws->buffer_get_virtual_address(buf);
addr = addr + offset;
RADEON_ENC_CS(addr >> 32);
RADEON_ENC_CS(addr);
enc->ws->cs_add_buffer(enc->cs, buf, usage | RADEON_USAGE_SYNCHRONIZED, domain, 0);
uint64_t addr;
addr = enc->ws->buffer_get_virtual_address(buf);
addr = addr + offset;
RADEON_ENC_CS(addr >> 32);
RADEON_ENC_CS(addr);
}
void radeon_enc_set_emulation_prevention(struct radeon_encoder *enc, bool set)
{
if (set != enc->emulation_prevention) {
enc->emulation_prevention = set;
enc->num_zeros = 0;
}
if (set != enc->emulation_prevention) {
enc->emulation_prevention = set;
enc->num_zeros = 0;
}
}
void radeon_enc_output_one_byte(struct radeon_encoder *enc, unsigned char byte)
{
if (enc->byte_index == 0)
enc->cs->current.buf[enc->cs->current.cdw] = 0;
enc->cs->current.buf[enc->cs->current.cdw] |= ((unsigned int)(byte) << index_to_shifts[enc->byte_index]);
enc->byte_index++;
if (enc->byte_index == 0)
enc->cs->current.buf[enc->cs->current.cdw] = 0;
enc->cs->current.buf[enc->cs->current.cdw] |=
((unsigned int)(byte) << index_to_shifts[enc->byte_index]);
enc->byte_index++;
if (enc->byte_index >= 4) {
enc->byte_index = 0;
enc->cs->current.cdw++;
}
if (enc->byte_index >= 4) {
enc->byte_index = 0;
enc->cs->current.cdw++;
}
}
void radeon_enc_emulation_prevention(struct radeon_encoder *enc, unsigned char byte)
{
if(enc->emulation_prevention) {
if((enc->num_zeros >= 2) && ((byte == 0x00) || (byte == 0x01) || (byte == 0x03))) {
radeon_enc_output_one_byte(enc, 0x03);
enc->bits_output += 8;
enc->num_zeros = 0;
}
enc->num_zeros = (byte == 0 ? (enc->num_zeros + 1) : 0);
}
if (enc->emulation_prevention) {
if ((enc->num_zeros >= 2) && ((byte == 0x00) || (byte == 0x01) || (byte == 0x03))) {
radeon_enc_output_one_byte(enc, 0x03);
enc->bits_output += 8;
enc->num_zeros = 0;
}
enc->num_zeros = (byte == 0 ? (enc->num_zeros + 1) : 0);
}
}
void radeon_enc_code_fixed_bits(struct radeon_encoder *enc, unsigned int value, unsigned int num_bits)
void radeon_enc_code_fixed_bits(struct radeon_encoder *enc, unsigned int value,
unsigned int num_bits)
{
unsigned int bits_to_pack = 0;
unsigned int bits_to_pack = 0;
while(num_bits > 0) {
unsigned int value_to_pack = value & (0xffffffff >> (32 - num_bits));
bits_to_pack = num_bits > (32 - enc->bits_in_shifter) ? (32 - enc->bits_in_shifter) : num_bits;
while (num_bits > 0) {
unsigned int value_to_pack = value & (0xffffffff >> (32 - num_bits));
bits_to_pack =
num_bits > (32 - enc->bits_in_shifter) ? (32 - enc->bits_in_shifter) : num_bits;
if (bits_to_pack < num_bits)
value_to_pack = value_to_pack >> (num_bits - bits_to_pack);
if (bits_to_pack < num_bits)
value_to_pack = value_to_pack >> (num_bits - bits_to_pack);
enc->shifter |= value_to_pack << (32 - enc->bits_in_shifter - bits_to_pack);
num_bits -= bits_to_pack;
enc->bits_in_shifter += bits_to_pack;
enc->shifter |= value_to_pack << (32 - enc->bits_in_shifter - bits_to_pack);
num_bits -= bits_to_pack;
enc->bits_in_shifter += bits_to_pack;
while(enc->bits_in_shifter >= 8) {
unsigned char output_byte = (unsigned char)(enc->shifter >> 24);
enc->shifter <<= 8;
radeon_enc_emulation_prevention(enc, output_byte);
radeon_enc_output_one_byte(enc, output_byte);
enc->bits_in_shifter -= 8;
enc->bits_output += 8;
}
}
while (enc->bits_in_shifter >= 8) {
unsigned char output_byte = (unsigned char)(enc->shifter >> 24);
enc->shifter <<= 8;
radeon_enc_emulation_prevention(enc, output_byte);
radeon_enc_output_one_byte(enc, output_byte);
enc->bits_in_shifter -= 8;
enc->bits_output += 8;
}
}
}
void radeon_enc_reset(struct radeon_encoder *enc)
{
enc->emulation_prevention = false;
enc->shifter = 0;
enc->bits_in_shifter = 0;
enc->bits_output = 0;
enc->num_zeros = 0;
enc->byte_index = 0;
enc->emulation_prevention = false;
enc->shifter = 0;
enc->bits_in_shifter = 0;
enc->bits_output = 0;
enc->num_zeros = 0;
enc->byte_index = 0;
}
void radeon_enc_byte_align(struct radeon_encoder *enc)
{
unsigned int num_padding_zeros = (32 - enc->bits_in_shifter) % 8;
unsigned int num_padding_zeros = (32 - enc->bits_in_shifter) % 8;
if (num_padding_zeros > 0)
radeon_enc_code_fixed_bits(enc, 0, num_padding_zeros);
if (num_padding_zeros > 0)
radeon_enc_code_fixed_bits(enc, 0, num_padding_zeros);
}
void radeon_enc_flush_headers(struct radeon_encoder *enc)
{
if (enc->bits_in_shifter != 0) {
unsigned char output_byte = (unsigned char)(enc->shifter >> 24);
radeon_enc_emulation_prevention(enc, output_byte);
radeon_enc_output_one_byte(enc, output_byte);
enc->bits_output += enc->bits_in_shifter;
enc->shifter = 0;
enc->bits_in_shifter = 0;
enc->num_zeros = 0;
}
if (enc->bits_in_shifter != 0) {
unsigned char output_byte = (unsigned char)(enc->shifter >> 24);
radeon_enc_emulation_prevention(enc, output_byte);
radeon_enc_output_one_byte(enc, output_byte);
enc->bits_output += enc->bits_in_shifter;
enc->shifter = 0;
enc->bits_in_shifter = 0;
enc->num_zeros = 0;
}
if (enc->byte_index > 0) {
enc->cs->current.cdw++;
enc->byte_index = 0;
}
if (enc->byte_index > 0) {
enc->cs->current.cdw++;
enc->byte_index = 0;
}
}
void radeon_enc_code_ue(struct radeon_encoder *enc, unsigned int value)
{
int x = -1;
unsigned int ue_code = value + 1;
value += 1;
int x = -1;
unsigned int ue_code = value + 1;
value += 1;
while (value) {
value = (value >> 1);
x += 1;
}
while (value) {
value = (value >> 1);
x += 1;
}
unsigned int ue_length = (x << 1) + 1;
radeon_enc_code_fixed_bits(enc, ue_code, ue_length);
unsigned int ue_length = (x << 1) + 1;
radeon_enc_code_fixed_bits(enc, ue_code, ue_length);
}
void radeon_enc_code_se(struct radeon_encoder *enc, int value)
{
unsigned int v = 0;
unsigned int v = 0;
if (value != 0)
v = (value < 0 ? ((unsigned int)(0 - value) << 1) : (((unsigned int)(value) << 1) - 1));
if (value != 0)
v = (value < 0 ? ((unsigned int)(0 - value) << 1) : (((unsigned int)(value) << 1) - 1));
radeon_enc_code_ue(enc, v);
radeon_enc_code_ue(enc, v);
}

View File

@ -30,525 +30,500 @@
#include "radeon_video.h"
#define RENCODE_IB_OP_INITIALIZE 0x01000001
#define RENCODE_IB_OP_CLOSE_SESSION 0x01000002
#define RENCODE_IB_OP_ENCODE 0x01000003
#define RENCODE_IB_OP_INIT_RC 0x01000004
#define RENCODE_IB_OP_INIT_RC_VBV_BUFFER_LEVEL 0x01000005
#define RENCODE_IB_OP_SET_SPEED_ENCODING_MODE 0x01000006
#define RENCODE_IB_OP_SET_BALANCE_ENCODING_MODE 0x01000007
#define RENCODE_IB_OP_SET_QUALITY_ENCODING_MODE 0x01000008
#define RENCODE_IB_OP_INITIALIZE 0x01000001
#define RENCODE_IB_OP_CLOSE_SESSION 0x01000002
#define RENCODE_IB_OP_ENCODE 0x01000003
#define RENCODE_IB_OP_INIT_RC 0x01000004
#define RENCODE_IB_OP_INIT_RC_VBV_BUFFER_LEVEL 0x01000005
#define RENCODE_IB_OP_SET_SPEED_ENCODING_MODE 0x01000006
#define RENCODE_IB_OP_SET_BALANCE_ENCODING_MODE 0x01000007
#define RENCODE_IB_OP_SET_QUALITY_ENCODING_MODE 0x01000008
#define RENCODE_IF_MAJOR_VERSION_MASK 0xFFFF0000
#define RENCODE_IF_MAJOR_VERSION_SHIFT 16
#define RENCODE_IF_MINOR_VERSION_MASK 0x0000FFFF
#define RENCODE_IF_MINOR_VERSION_SHIFT 0
#define RENCODE_IF_MAJOR_VERSION_MASK 0xFFFF0000
#define RENCODE_IF_MAJOR_VERSION_SHIFT 16
#define RENCODE_IF_MINOR_VERSION_MASK 0x0000FFFF
#define RENCODE_IF_MINOR_VERSION_SHIFT 0
#define RENCODE_ENGINE_TYPE_ENCODE 1
#define RENCODE_ENGINE_TYPE_ENCODE 1
#define RENCODE_ENCODE_STANDARD_HEVC 0
#define RENCODE_ENCODE_STANDARD_H264 1
#define RENCODE_ENCODE_STANDARD_HEVC 0
#define RENCODE_ENCODE_STANDARD_H264 1
#define RENCODE_PREENCODE_MODE_NONE 0x00000000
#define RENCODE_PREENCODE_MODE_1X 0x00000001
#define RENCODE_PREENCODE_MODE_2X 0x00000002
#define RENCODE_PREENCODE_MODE_4X 0x00000004
#define RENCODE_PREENCODE_MODE_NONE 0x00000000
#define RENCODE_PREENCODE_MODE_1X 0x00000001
#define RENCODE_PREENCODE_MODE_2X 0x00000002
#define RENCODE_PREENCODE_MODE_4X 0x00000004
#define RENCODE_H264_SLICE_CONTROL_MODE_FIXED_MBS 0x00000000
#define RENCODE_H264_SLICE_CONTROL_MODE_FIXED_BITS 0x00000001
#define RENCODE_H264_SLICE_CONTROL_MODE_FIXED_MBS 0x00000000
#define RENCODE_H264_SLICE_CONTROL_MODE_FIXED_BITS 0x00000001
#define RENCODE_HEVC_SLICE_CONTROL_MODE_FIXED_CTBS 0x00000000
#define RENCODE_HEVC_SLICE_CONTROL_MODE_FIXED_BITS 0x00000001
#define RENCODE_HEVC_SLICE_CONTROL_MODE_FIXED_CTBS 0x00000000
#define RENCODE_HEVC_SLICE_CONTROL_MODE_FIXED_BITS 0x00000001
#define RENCODE_RATE_CONTROL_METHOD_NONE 0x00000000
#define RENCODE_RATE_CONTROL_METHOD_LATENCY_CONSTRAINED_VBR 0x00000001
#define RENCODE_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR 0x00000002
#define RENCODE_RATE_CONTROL_METHOD_CBR 0x00000003
#define RENCODE_RATE_CONTROL_METHOD_NONE 0x00000000
#define RENCODE_RATE_CONTROL_METHOD_LATENCY_CONSTRAINED_VBR 0x00000001
#define RENCODE_RATE_CONTROL_METHOD_PEAK_CONSTRAINED_VBR 0x00000002
#define RENCODE_RATE_CONTROL_METHOD_CBR 0x00000003
#define RENCODE_DIRECT_OUTPUT_NALU_TYPE_AUD 0x00000000
#define RENCODE_DIRECT_OUTPUT_NALU_TYPE_VPS 0x00000001
#define RENCODE_DIRECT_OUTPUT_NALU_TYPE_SPS 0x00000002
#define RENCODE_DIRECT_OUTPUT_NALU_TYPE_PPS 0x00000003
#define RENCODE_DIRECT_OUTPUT_NALU_TYPE_PREFIX 0x00000004
#define RENCODE_DIRECT_OUTPUT_NALU_TYPE_END_OF_SEQUENCE 0x00000005
#define RENCODE_DIRECT_OUTPUT_NALU_TYPE_AUD 0x00000000
#define RENCODE_DIRECT_OUTPUT_NALU_TYPE_VPS 0x00000001
#define RENCODE_DIRECT_OUTPUT_NALU_TYPE_SPS 0x00000002
#define RENCODE_DIRECT_OUTPUT_NALU_TYPE_PPS 0x00000003
#define RENCODE_DIRECT_OUTPUT_NALU_TYPE_PREFIX 0x00000004
#define RENCODE_DIRECT_OUTPUT_NALU_TYPE_END_OF_SEQUENCE 0x00000005
#define RENCODE_SLICE_HEADER_TEMPLATE_MAX_TEMPLATE_SIZE_IN_DWORDS 16
#define RENCODE_SLICE_HEADER_TEMPLATE_MAX_NUM_INSTRUCTIONS 16
#define RENCODE_SLICE_HEADER_TEMPLATE_MAX_TEMPLATE_SIZE_IN_DWORDS 16
#define RENCODE_SLICE_HEADER_TEMPLATE_MAX_NUM_INSTRUCTIONS 16
#define RENCODE_HEADER_INSTRUCTION_END 0x00000000
#define RENCODE_HEADER_INSTRUCTION_COPY 0x00000001
#define RENCODE_HEADER_INSTRUCTION_END 0x00000000
#define RENCODE_HEADER_INSTRUCTION_COPY 0x00000001
#define RENCODE_HEVC_HEADER_INSTRUCTION_DEPENDENT_SLICE_END 0x00010000
#define RENCODE_HEVC_HEADER_INSTRUCTION_FIRST_SLICE 0x00010001
#define RENCODE_HEVC_HEADER_INSTRUCTION_SLICE_SEGMENT 0x00010002
#define RENCODE_HEVC_HEADER_INSTRUCTION_SLICE_QP_DELTA 0x00010003
#define RENCODE_HEVC_HEADER_INSTRUCTION_DEPENDENT_SLICE_END 0x00010000
#define RENCODE_HEVC_HEADER_INSTRUCTION_FIRST_SLICE 0x00010001
#define RENCODE_HEVC_HEADER_INSTRUCTION_SLICE_SEGMENT 0x00010002
#define RENCODE_HEVC_HEADER_INSTRUCTION_SLICE_QP_DELTA 0x00010003
#define RENCODE_H264_HEADER_INSTRUCTION_FIRST_MB 0x00020000
#define RENCODE_H264_HEADER_INSTRUCTION_SLICE_QP_DELTA 0x00020001
#define RENCODE_H264_HEADER_INSTRUCTION_FIRST_MB 0x00020000
#define RENCODE_H264_HEADER_INSTRUCTION_SLICE_QP_DELTA 0x00020001
#define RENCODE_PICTURE_TYPE_B 0
#define RENCODE_PICTURE_TYPE_P 1
#define RENCODE_PICTURE_TYPE_I 2
#define RENCODE_PICTURE_TYPE_P_SKIP 3
#define RENCODE_PICTURE_TYPE_B 0
#define RENCODE_PICTURE_TYPE_P 1
#define RENCODE_PICTURE_TYPE_I 2
#define RENCODE_PICTURE_TYPE_P_SKIP 3
#define RENCODE_INPUT_SWIZZLE_MODE_LINEAR 0
#define RENCODE_INPUT_SWIZZLE_MODE_256B_S 1
#define RENCODE_INPUT_SWIZZLE_MODE_4kB_S 5
#define RENCODE_INPUT_SWIZZLE_MODE_64kB_S 9
#define RENCODE_INPUT_SWIZZLE_MODE_LINEAR 0
#define RENCODE_INPUT_SWIZZLE_MODE_256B_S 1
#define RENCODE_INPUT_SWIZZLE_MODE_4kB_S 5
#define RENCODE_INPUT_SWIZZLE_MODE_64kB_S 9
#define RENCODE_H264_PICTURE_STRUCTURE_FRAME 0
#define RENCODE_H264_PICTURE_STRUCTURE_TOP_FIELD 1
#define RENCODE_H264_PICTURE_STRUCTURE_BOTTOM_FIELD 2
#define RENCODE_H264_PICTURE_STRUCTURE_FRAME 0
#define RENCODE_H264_PICTURE_STRUCTURE_TOP_FIELD 1
#define RENCODE_H264_PICTURE_STRUCTURE_BOTTOM_FIELD 2
#define RENCODE_H264_INTERLACING_MODE_PROGRESSIVE 0
#define RENCODE_H264_INTERLACING_MODE_INTERLACED_STACKED 1
#define RENCODE_H264_INTERLACING_MODE_INTERLACED_INTERLEAVED 2
#define RENCODE_H264_INTERLACING_MODE_PROGRESSIVE 0
#define RENCODE_H264_INTERLACING_MODE_INTERLACED_STACKED 1
#define RENCODE_H264_INTERLACING_MODE_INTERLACED_INTERLEAVED 2
#define RENCODE_H264_DISABLE_DEBLOCKING_FILTER_IDC_ENABLE 0
#define RENCODE_H264_DISABLE_DEBLOCKING_FILTER_IDC_DISABLE 1
#define RENCODE_H264_DISABLE_DEBLOCKING_FILTER_IDC_DISALBE_ACROSS_SLICE_BOUNDARY 2
#define RENCODE_H264_DISABLE_DEBLOCKING_FILTER_IDC_ENABLE 0
#define RENCODE_H264_DISABLE_DEBLOCKING_FILTER_IDC_DISABLE 1
#define RENCODE_H264_DISABLE_DEBLOCKING_FILTER_IDC_DISALBE_ACROSS_SLICE_BOUNDARY 2
#define RENCODE_INTRA_REFRESH_MODE_NONE 0
#define RENCODE_INTRA_REFRESH_MODE_CTB_MB_ROWS 1
#define RENCODE_INTRA_REFRESH_MODE_CTB_MB_COLUMNS 2
#define RENCODE_INTRA_REFRESH_MODE_NONE 0
#define RENCODE_INTRA_REFRESH_MODE_CTB_MB_ROWS 1
#define RENCODE_INTRA_REFRESH_MODE_CTB_MB_COLUMNS 2
#define RENCODE_MAX_NUM_RECONSTRUCTED_PICTURES 34
#define RENCODE_MAX_NUM_RECONSTRUCTED_PICTURES 34
#define RENCODE_REC_SWIZZLE_MODE_LINEAR 0
#define RENCODE_REC_SWIZZLE_MODE_256B_S 1
#define RENCODE_REC_SWIZZLE_MODE_LINEAR 0
#define RENCODE_REC_SWIZZLE_MODE_256B_S 1
#define RENCODE_VIDEO_BITSTREAM_BUFFER_MODE_LINEAR 0
#define RENCODE_VIDEO_BITSTREAM_BUFFER_MODE_CIRCULAR 1
#define RENCODE_VIDEO_BITSTREAM_BUFFER_MODE_LINEAR 0
#define RENCODE_VIDEO_BITSTREAM_BUFFER_MODE_CIRCULAR 1
#define RENCODE_FEEDBACK_BUFFER_MODE_LINEAR 0
#define RENCODE_FEEDBACK_BUFFER_MODE_CIRCULAR 1
#define RENCODE_FEEDBACK_BUFFER_MODE_LINEAR 0
#define RENCODE_FEEDBACK_BUFFER_MODE_CIRCULAR 1
#define RADEON_ENC_CS(value) (enc->cs->current.buf[enc->cs->current.cdw++] = (value))
#define RADEON_ENC_BEGIN(cmd) { \
uint32_t *begin = &enc->cs->current.buf[enc->cs->current.cdw++]; \
RADEON_ENC_CS(cmd)
#define RADEON_ENC_READ(buf, domain, off) radeon_enc_add_buffer(enc, (buf), RADEON_USAGE_READ, (domain), (off))
#define RADEON_ENC_WRITE(buf, domain, off) radeon_enc_add_buffer(enc, (buf), RADEON_USAGE_WRITE, (domain), (off))
#define RADEON_ENC_READWRITE(buf, domain, off) radeon_enc_add_buffer(enc, (buf), RADEON_USAGE_READWRITE, (domain), (off))
#define RADEON_ENC_END() *begin = (&enc->cs->current.buf[enc->cs->current.cdw] - begin) * 4; \
enc->total_task_size += *begin;}
#define RADEON_ENC_BEGIN(cmd) \
{ \
uint32_t *begin = &enc->cs->current.buf[enc->cs->current.cdw++]; \
RADEON_ENC_CS(cmd)
#define RADEON_ENC_READ(buf, domain, off) \
radeon_enc_add_buffer(enc, (buf), RADEON_USAGE_READ, (domain), (off))
#define RADEON_ENC_WRITE(buf, domain, off) \
radeon_enc_add_buffer(enc, (buf), RADEON_USAGE_WRITE, (domain), (off))
#define RADEON_ENC_READWRITE(buf, domain, off) \
radeon_enc_add_buffer(enc, (buf), RADEON_USAGE_READWRITE, (domain), (off))
#define RADEON_ENC_END() \
*begin = (&enc->cs->current.buf[enc->cs->current.cdw] - begin) * 4; \
enc->total_task_size += *begin; \
}
typedef struct rvcn_enc_session_info_s
{
uint32_t interface_version;
uint32_t sw_context_address_hi;
uint32_t sw_context_address_lo;
typedef struct rvcn_enc_session_info_s {
uint32_t interface_version;
uint32_t sw_context_address_hi;
uint32_t sw_context_address_lo;
} rvcn_enc_session_info_t;
typedef struct rvcn_enc_task_info_s
{
uint32_t total_size_of_all_packages;
uint32_t task_id;
uint32_t allowed_max_num_feedbacks;
typedef struct rvcn_enc_task_info_s {
uint32_t total_size_of_all_packages;
uint32_t task_id;
uint32_t allowed_max_num_feedbacks;
} rvcn_enc_task_info_t;
typedef struct rvcn_enc_session_init_s
{
uint32_t encode_standard;
uint32_t aligned_picture_width;
uint32_t aligned_picture_height;
uint32_t padding_width;
uint32_t padding_height;
uint32_t pre_encode_mode;
uint32_t pre_encode_chroma_enabled;
typedef struct rvcn_enc_session_init_s {
uint32_t encode_standard;
uint32_t aligned_picture_width;
uint32_t aligned_picture_height;
uint32_t padding_width;
uint32_t padding_height;
uint32_t pre_encode_mode;
uint32_t pre_encode_chroma_enabled;
} rvcn_enc_session_init_t;
typedef struct rvcn_enc_layer_control_s
{
uint32_t max_num_temporal_layers;
uint32_t num_temporal_layers;
typedef struct rvcn_enc_layer_control_s {
uint32_t max_num_temporal_layers;
uint32_t num_temporal_layers;
} rvcn_enc_layer_control_t;
typedef struct rvcn_enc_layer_select_s
{
uint32_t temporal_layer_index;
typedef struct rvcn_enc_layer_select_s {
uint32_t temporal_layer_index;
} rvcn_enc_layer_select_t;
typedef struct rvcn_enc_h264_slice_control_s
{
uint32_t slice_control_mode;
union
{
uint32_t num_mbs_per_slice;
uint32_t num_bits_per_slice;
};
typedef struct rvcn_enc_h264_slice_control_s {
uint32_t slice_control_mode;
union {
uint32_t num_mbs_per_slice;
uint32_t num_bits_per_slice;
};
} rvcn_enc_h264_slice_control_t;
typedef struct rvcn_enc_hevc_slice_control_s
{
uint32_t slice_control_mode;
union
{
struct
{
uint32_t num_ctbs_per_slice;
uint32_t num_ctbs_per_slice_segment;
} fixed_ctbs_per_slice;
typedef struct rvcn_enc_hevc_slice_control_s {
uint32_t slice_control_mode;
union {
struct {
uint32_t num_ctbs_per_slice;
uint32_t num_ctbs_per_slice_segment;
} fixed_ctbs_per_slice;
struct
{
uint32_t num_bits_per_slice;
uint32_t num_bits_per_slice_segment;
} fixed_bits_per_slice;
};
struct {
uint32_t num_bits_per_slice;
uint32_t num_bits_per_slice_segment;
} fixed_bits_per_slice;
};
} rvcn_enc_hevc_slice_control_t;
typedef struct rvcn_enc_h264_spec_misc_s
{
uint32_t constrained_intra_pred_flag;
uint32_t cabac_enable;
uint32_t cabac_init_idc;
uint32_t half_pel_enabled;
uint32_t quarter_pel_enabled;
uint32_t profile_idc;
uint32_t level_idc;
typedef struct rvcn_enc_h264_spec_misc_s {
uint32_t constrained_intra_pred_flag;
uint32_t cabac_enable;
uint32_t cabac_init_idc;
uint32_t half_pel_enabled;
uint32_t quarter_pel_enabled;
uint32_t profile_idc;
uint32_t level_idc;
} rvcn_enc_h264_spec_misc_t;
typedef struct rvcn_enc_hevc_spec_misc_s
{
uint32_t log2_min_luma_coding_block_size_minus3;
uint32_t amp_disabled;
uint32_t strong_intra_smoothing_enabled;
uint32_t constrained_intra_pred_flag;
uint32_t cabac_init_flag;
uint32_t half_pel_enabled;
uint32_t quarter_pel_enabled;
typedef struct rvcn_enc_hevc_spec_misc_s {
uint32_t log2_min_luma_coding_block_size_minus3;
uint32_t amp_disabled;
uint32_t strong_intra_smoothing_enabled;
uint32_t constrained_intra_pred_flag;
uint32_t cabac_init_flag;
uint32_t half_pel_enabled;
uint32_t quarter_pel_enabled;
} rvcn_enc_hevc_spec_misc_t;
typedef struct rvcn_enc_rate_ctl_session_init_s
{
uint32_t rate_control_method;
uint32_t vbv_buffer_level;
typedef struct rvcn_enc_rate_ctl_session_init_s {
uint32_t rate_control_method;
uint32_t vbv_buffer_level;
} rvcn_enc_rate_ctl_session_init_t;
typedef struct rvcn_enc_rate_ctl_layer_init_s
{
uint32_t target_bit_rate;
uint32_t peak_bit_rate;
uint32_t frame_rate_num;
uint32_t frame_rate_den;
uint32_t vbv_buffer_size;
uint32_t avg_target_bits_per_picture;
uint32_t peak_bits_per_picture_integer;
uint32_t peak_bits_per_picture_fractional;
typedef struct rvcn_enc_rate_ctl_layer_init_s {
uint32_t target_bit_rate;
uint32_t peak_bit_rate;
uint32_t frame_rate_num;
uint32_t frame_rate_den;
uint32_t vbv_buffer_size;
uint32_t avg_target_bits_per_picture;
uint32_t peak_bits_per_picture_integer;
uint32_t peak_bits_per_picture_fractional;
} rvcn_enc_rate_ctl_layer_init_t;
typedef struct rvcn_enc_rate_ctl_per_picture_s
{
uint32_t qp;
uint32_t min_qp_app;
uint32_t max_qp_app;
uint32_t max_au_size;
uint32_t enabled_filler_data;
uint32_t skip_frame_enable;
uint32_t enforce_hrd;
typedef struct rvcn_enc_rate_ctl_per_picture_s {
uint32_t qp;
uint32_t min_qp_app;
uint32_t max_qp_app;
uint32_t max_au_size;
uint32_t enabled_filler_data;
uint32_t skip_frame_enable;
uint32_t enforce_hrd;
} rvcn_enc_rate_ctl_per_picture_t;
typedef struct rvcn_enc_quality_params_s
{
uint32_t vbaq_mode;
uint32_t scene_change_sensitivity;
uint32_t scene_change_min_idr_interval;
uint32_t two_pass_search_center_map_mode;
typedef struct rvcn_enc_quality_params_s {
uint32_t vbaq_mode;
uint32_t scene_change_sensitivity;
uint32_t scene_change_min_idr_interval;
uint32_t two_pass_search_center_map_mode;
} rvcn_enc_quality_params_t;
typedef struct rvcn_enc_direct_output_nalu_s
{
uint32_t type;
uint32_t size;
uint32_t data[1];
typedef struct rvcn_enc_direct_output_nalu_s {
uint32_t type;
uint32_t size;
uint32_t data[1];
} rvcn_enc_direct_output_nalu_t;
typedef struct rvcn_enc_slice_header_s
{
uint32_t bitstream_template[RENCODE_SLICE_HEADER_TEMPLATE_MAX_TEMPLATE_SIZE_IN_DWORDS];
struct {
uint32_t instruction;
uint32_t num_bits;
} instructions[RENCODE_SLICE_HEADER_TEMPLATE_MAX_NUM_INSTRUCTIONS];
typedef struct rvcn_enc_slice_header_s {
uint32_t bitstream_template[RENCODE_SLICE_HEADER_TEMPLATE_MAX_TEMPLATE_SIZE_IN_DWORDS];
struct {
uint32_t instruction;
uint32_t num_bits;
} instructions[RENCODE_SLICE_HEADER_TEMPLATE_MAX_NUM_INSTRUCTIONS];
} rvcn_enc_slice_header_t;
typedef struct rvcn_enc_encode_params_s
{
uint32_t pic_type;
uint32_t allowed_max_bitstream_size;
uint32_t input_picture_luma_address_hi;
uint32_t input_picture_luma_address_lo;
uint32_t input_picture_chroma_address_hi;
uint32_t input_picture_chroma_address_lo;
uint32_t input_pic_luma_pitch;
uint32_t input_pic_chroma_pitch;
uint8_t input_pic_swizzle_mode;
uint32_t reference_picture_index;
uint32_t reconstructed_picture_index;
typedef struct rvcn_enc_encode_params_s {
uint32_t pic_type;
uint32_t allowed_max_bitstream_size;
uint32_t input_picture_luma_address_hi;
uint32_t input_picture_luma_address_lo;
uint32_t input_picture_chroma_address_hi;
uint32_t input_picture_chroma_address_lo;
uint32_t input_pic_luma_pitch;
uint32_t input_pic_chroma_pitch;
uint8_t input_pic_swizzle_mode;
uint32_t reference_picture_index;
uint32_t reconstructed_picture_index;
} rvcn_enc_encode_params_t;
typedef struct rvcn_enc_h264_encode_params_s
{
uint32_t input_picture_structure;
uint32_t interlaced_mode;
uint32_t reference_picture_structure;
uint32_t reference_picture1_index;
typedef struct rvcn_enc_h264_encode_params_s {
uint32_t input_picture_structure;
uint32_t interlaced_mode;
uint32_t reference_picture_structure;
uint32_t reference_picture1_index;
} rvcn_enc_h264_encode_params_t;
typedef struct rvcn_enc_h264_deblocking_filter_s
{
uint32_t disable_deblocking_filter_idc;
int32_t alpha_c0_offset_div2;
int32_t beta_offset_div2;
int32_t cb_qp_offset;
int32_t cr_qp_offset;
typedef struct rvcn_enc_h264_deblocking_filter_s {
uint32_t disable_deblocking_filter_idc;
int32_t alpha_c0_offset_div2;
int32_t beta_offset_div2;
int32_t cb_qp_offset;
int32_t cr_qp_offset;
} rvcn_enc_h264_deblocking_filter_t;
typedef struct rvcn_enc_hevc_deblocking_filter_s
{
uint32_t loop_filter_across_slices_enabled;
int32_t deblocking_filter_disabled;
int32_t beta_offset_div2;
int32_t tc_offset_div2;
int32_t cb_qp_offset;
int32_t cr_qp_offset;
typedef struct rvcn_enc_hevc_deblocking_filter_s {
uint32_t loop_filter_across_slices_enabled;
int32_t deblocking_filter_disabled;
int32_t beta_offset_div2;
int32_t tc_offset_div2;
int32_t cb_qp_offset;
int32_t cr_qp_offset;
} rvcn_enc_hevc_deblocking_filter_t;
typedef struct rvcn_enc_intra_refresh_s
{
uint32_t intra_refresh_mode;
uint32_t offset;
uint32_t region_size;
typedef struct rvcn_enc_intra_refresh_s {
uint32_t intra_refresh_mode;
uint32_t offset;
uint32_t region_size;
} rvcn_enc_intra_refresh_t;
typedef struct rvcn_enc_reconstructed_picture_s
{
uint32_t luma_offset;
uint32_t chroma_offset;
typedef struct rvcn_enc_reconstructed_picture_s {
uint32_t luma_offset;
uint32_t chroma_offset;
} rvcn_enc_reconstructed_picture_t;
typedef struct rvcn_enc_encode_context_buffer_s
{
uint32_t encode_context_address_hi;
uint32_t encode_context_address_lo;
uint32_t swizzle_mode;
uint32_t rec_luma_pitch;
uint32_t rec_chroma_pitch;
uint32_t num_reconstructed_pictures;
rvcn_enc_reconstructed_picture_t reconstructed_pictures[RENCODE_MAX_NUM_RECONSTRUCTED_PICTURES];
uint32_t pre_encode_picture_luma_pitch;
uint32_t pre_encode_picture_chroma_pitch;
rvcn_enc_reconstructed_picture_t pre_encode_reconstructed_pictures[RENCODE_MAX_NUM_RECONSTRUCTED_PICTURES];
rvcn_enc_reconstructed_picture_t pre_encode_input_picture;
typedef struct rvcn_enc_encode_context_buffer_s {
uint32_t encode_context_address_hi;
uint32_t encode_context_address_lo;
uint32_t swizzle_mode;
uint32_t rec_luma_pitch;
uint32_t rec_chroma_pitch;
uint32_t num_reconstructed_pictures;
rvcn_enc_reconstructed_picture_t reconstructed_pictures[RENCODE_MAX_NUM_RECONSTRUCTED_PICTURES];
uint32_t pre_encode_picture_luma_pitch;
uint32_t pre_encode_picture_chroma_pitch;
rvcn_enc_reconstructed_picture_t
pre_encode_reconstructed_pictures[RENCODE_MAX_NUM_RECONSTRUCTED_PICTURES];
rvcn_enc_reconstructed_picture_t pre_encode_input_picture;
} rvcn_enc_encode_context_buffer_t;
typedef struct rvcn_enc_video_bitstream_buffer_s
{
uint32_t mode;
uint32_t video_bitstream_buffer_address_hi;
uint32_t video_bitstream_buffer_address_lo;
uint32_t video_bitstream_buffer_size;
uint32_t video_bitstream_data_offset;
typedef struct rvcn_enc_video_bitstream_buffer_s {
uint32_t mode;
uint32_t video_bitstream_buffer_address_hi;
uint32_t video_bitstream_buffer_address_lo;
uint32_t video_bitstream_buffer_size;
uint32_t video_bitstream_data_offset;
} rvcn_enc_video_bitstream_buffer_t;
typedef struct rvcn_enc_feedback_buffer_s
{
uint32_t mode;
uint32_t feedback_buffer_address_hi;
uint32_t feedback_buffer_address_lo;
uint32_t feedback_buffer_size;
uint32_t feedback_data_size;
typedef struct rvcn_enc_feedback_buffer_s {
uint32_t mode;
uint32_t feedback_buffer_address_hi;
uint32_t feedback_buffer_address_lo;
uint32_t feedback_buffer_size;
uint32_t feedback_data_size;
} rvcn_enc_feedback_buffer_t;
typedef struct rvcn_enc_cmd_s
{
uint32_t session_info;
uint32_t task_info;
uint32_t session_init;
uint32_t layer_control;
uint32_t layer_select;
uint32_t rc_session_init;
uint32_t rc_layer_init;
uint32_t rc_per_pic;
uint32_t quality_params;
uint32_t slice_header;
uint32_t enc_params;
uint32_t intra_refresh;
uint32_t ctx;
uint32_t bitstream;
uint32_t feedback;
uint32_t nalu;
uint32_t slice_control_hevc;
uint32_t spec_misc_hevc;
uint32_t enc_params_hevc;
uint32_t deblocking_filter_hevc;
uint32_t slice_control_h264;
uint32_t spec_misc_h264;
uint32_t enc_params_h264;
uint32_t deblocking_filter_h264;
uint32_t input_format;
uint32_t output_format;
typedef struct rvcn_enc_cmd_s {
uint32_t session_info;
uint32_t task_info;
uint32_t session_init;
uint32_t layer_control;
uint32_t layer_select;
uint32_t rc_session_init;
uint32_t rc_layer_init;
uint32_t rc_per_pic;
uint32_t quality_params;
uint32_t slice_header;
uint32_t enc_params;
uint32_t intra_refresh;
uint32_t ctx;
uint32_t bitstream;
uint32_t feedback;
uint32_t nalu;
uint32_t slice_control_hevc;
uint32_t spec_misc_hevc;
uint32_t enc_params_hevc;
uint32_t deblocking_filter_hevc;
uint32_t slice_control_h264;
uint32_t spec_misc_h264;
uint32_t enc_params_h264;
uint32_t deblocking_filter_h264;
uint32_t input_format;
uint32_t output_format;
} rvcn_enc_cmd_t;
typedef void (*radeon_enc_get_buffer)(struct pipe_resource *resource,
struct pb_buffer **handle,
struct radeon_surf **surface);
typedef void (*radeon_enc_get_buffer)(struct pipe_resource *resource, struct pb_buffer **handle,
struct radeon_surf **surface);
struct pipe_video_codec *radeon_create_encoder(struct pipe_context *context,
const struct pipe_video_codec *templat,
struct radeon_winsys* ws,
radeon_enc_get_buffer get_buffer);
const struct pipe_video_codec *templat,
struct radeon_winsys *ws,
radeon_enc_get_buffer get_buffer);
struct radeon_enc_pic {
enum pipe_h264_enc_picture_type picture_type;
enum pipe_h264_enc_picture_type picture_type;
unsigned frame_num;
unsigned pic_order_cnt;
unsigned pic_order_cnt_type;
unsigned ref_idx_l0;
unsigned ref_idx_l1;
unsigned crop_left;
unsigned crop_right;
unsigned crop_top;
unsigned crop_bottom;
unsigned general_tier_flag;
unsigned general_profile_idc;
unsigned general_level_idc;
unsigned max_poc;
unsigned log2_max_poc;
unsigned chroma_format_idc;
unsigned pic_width_in_luma_samples;
unsigned pic_height_in_luma_samples;
unsigned log2_diff_max_min_luma_coding_block_size;
unsigned log2_min_transform_block_size_minus2;
unsigned log2_diff_max_min_transform_block_size;
unsigned max_transform_hierarchy_depth_inter;
unsigned max_transform_hierarchy_depth_intra;
unsigned log2_parallel_merge_level_minus2;
unsigned bit_depth_luma_minus8;
unsigned bit_depth_chroma_minus8;
unsigned nal_unit_type;
unsigned max_num_merge_cand;
unsigned frame_num;
unsigned pic_order_cnt;
unsigned pic_order_cnt_type;
unsigned ref_idx_l0;
unsigned ref_idx_l1;
unsigned crop_left;
unsigned crop_right;
unsigned crop_top;
unsigned crop_bottom;
unsigned general_tier_flag;
unsigned general_profile_idc;
unsigned general_level_idc;
unsigned max_poc;
unsigned log2_max_poc;
unsigned chroma_format_idc;
unsigned pic_width_in_luma_samples;
unsigned pic_height_in_luma_samples;
unsigned log2_diff_max_min_luma_coding_block_size;
unsigned log2_min_transform_block_size_minus2;
unsigned log2_diff_max_min_transform_block_size;
unsigned max_transform_hierarchy_depth_inter;
unsigned max_transform_hierarchy_depth_intra;
unsigned log2_parallel_merge_level_minus2;
unsigned bit_depth_luma_minus8;
unsigned bit_depth_chroma_minus8;
unsigned nal_unit_type;
unsigned max_num_merge_cand;
bool not_referenced;
bool is_idr;
bool is_even_frame;
bool sample_adaptive_offset_enabled_flag;
bool pcm_enabled_flag;
bool sps_temporal_mvp_enabled_flag;
bool not_referenced;
bool is_idr;
bool is_even_frame;
bool sample_adaptive_offset_enabled_flag;
bool pcm_enabled_flag;
bool sps_temporal_mvp_enabled_flag;
rvcn_enc_session_info_t session_info;
rvcn_enc_task_info_t task_info;
rvcn_enc_session_init_t session_init;
rvcn_enc_layer_control_t layer_ctrl;
rvcn_enc_layer_select_t layer_sel;
rvcn_enc_h264_slice_control_t slice_ctrl;
rvcn_enc_hevc_slice_control_t hevc_slice_ctrl;
rvcn_enc_h264_spec_misc_t spec_misc;
rvcn_enc_hevc_spec_misc_t hevc_spec_misc;
rvcn_enc_rate_ctl_session_init_t rc_session_init;
rvcn_enc_rate_ctl_layer_init_t rc_layer_init;
rvcn_enc_h264_encode_params_t h264_enc_params;
rvcn_enc_h264_deblocking_filter_t h264_deblock;
rvcn_enc_hevc_deblocking_filter_t hevc_deblock;
rvcn_enc_rate_ctl_per_picture_t rc_per_pic;
rvcn_enc_quality_params_t quality_params;
rvcn_enc_encode_context_buffer_t ctx_buf;
rvcn_enc_video_bitstream_buffer_t bit_buf;
rvcn_enc_feedback_buffer_t fb_buf;
rvcn_enc_intra_refresh_t intra_ref;
rvcn_enc_encode_params_t enc_params;
rvcn_enc_session_info_t session_info;
rvcn_enc_task_info_t task_info;
rvcn_enc_session_init_t session_init;
rvcn_enc_layer_control_t layer_ctrl;
rvcn_enc_layer_select_t layer_sel;
rvcn_enc_h264_slice_control_t slice_ctrl;
rvcn_enc_hevc_slice_control_t hevc_slice_ctrl;
rvcn_enc_h264_spec_misc_t spec_misc;
rvcn_enc_hevc_spec_misc_t hevc_spec_misc;
rvcn_enc_rate_ctl_session_init_t rc_session_init;
rvcn_enc_rate_ctl_layer_init_t rc_layer_init;
rvcn_enc_h264_encode_params_t h264_enc_params;
rvcn_enc_h264_deblocking_filter_t h264_deblock;
rvcn_enc_hevc_deblocking_filter_t hevc_deblock;
rvcn_enc_rate_ctl_per_picture_t rc_per_pic;
rvcn_enc_quality_params_t quality_params;
rvcn_enc_encode_context_buffer_t ctx_buf;
rvcn_enc_video_bitstream_buffer_t bit_buf;
rvcn_enc_feedback_buffer_t fb_buf;
rvcn_enc_intra_refresh_t intra_ref;
rvcn_enc_encode_params_t enc_params;
};
struct radeon_encoder {
struct pipe_video_codec base;
struct pipe_video_codec base;
void (*begin)(struct radeon_encoder *enc);
void (*encode)(struct radeon_encoder *enc);
void (*destroy)(struct radeon_encoder *enc);
void (*session_info)(struct radeon_encoder *enc);
void (*task_info)(struct radeon_encoder *enc, bool need_feedback);
void (*session_init)(struct radeon_encoder *enc);
void (*layer_control)(struct radeon_encoder *enc);
void (*layer_select)(struct radeon_encoder *enc);
void (*slice_control)(struct radeon_encoder *enc);
void (*spec_misc)(struct radeon_encoder *enc);
void (*rc_session_init)(struct radeon_encoder *enc);
void (*rc_layer_init)(struct radeon_encoder *enc);
void (*deblocking_filter)(struct radeon_encoder *enc);
void (*quality_params)(struct radeon_encoder *enc);
void (*nalu_sps)(struct radeon_encoder *enc);
void (*nalu_pps)(struct radeon_encoder *enc);
void (*nalu_vps)(struct radeon_encoder *enc);
void (*nalu_aud)(struct radeon_encoder *enc);
void (*slice_header)(struct radeon_encoder *enc);
void (*ctx)(struct radeon_encoder *enc);
void (*bitstream)(struct radeon_encoder *enc);
void (*feedback)(struct radeon_encoder *enc);
void (*intra_refresh)(struct radeon_encoder *enc);
void (*rc_per_pic)(struct radeon_encoder *enc);
void (*encode_params)(struct radeon_encoder *enc);
void (*encode_params_codec_spec)(struct radeon_encoder *enc);
void (*op_init)(struct radeon_encoder *enc);
void (*op_close)(struct radeon_encoder *enc);
void (*op_enc)(struct radeon_encoder *enc);
void (*op_init_rc)(struct radeon_encoder *enc);
void (*op_init_rc_vbv)(struct radeon_encoder *enc);
void (*op_speed)(struct radeon_encoder *enc);
void (*encode_headers)(struct radeon_encoder *enc);
void (*input_format)(struct radeon_encoder *enc);
void (*output_format)(struct radeon_encoder *enc);
void (*begin)(struct radeon_encoder *enc);
void (*encode)(struct radeon_encoder *enc);
void (*destroy)(struct radeon_encoder *enc);
void (*session_info)(struct radeon_encoder *enc);
void (*task_info)(struct radeon_encoder *enc, bool need_feedback);
void (*session_init)(struct radeon_encoder *enc);
void (*layer_control)(struct radeon_encoder *enc);
void (*layer_select)(struct radeon_encoder *enc);
void (*slice_control)(struct radeon_encoder *enc);
void (*spec_misc)(struct radeon_encoder *enc);
void (*rc_session_init)(struct radeon_encoder *enc);
void (*rc_layer_init)(struct radeon_encoder *enc);
void (*deblocking_filter)(struct radeon_encoder *enc);
void (*quality_params)(struct radeon_encoder *enc);
void (*nalu_sps)(struct radeon_encoder *enc);
void (*nalu_pps)(struct radeon_encoder *enc);
void (*nalu_vps)(struct radeon_encoder *enc);
void (*nalu_aud)(struct radeon_encoder *enc);
void (*slice_header)(struct radeon_encoder *enc);
void (*ctx)(struct radeon_encoder *enc);
void (*bitstream)(struct radeon_encoder *enc);
void (*feedback)(struct radeon_encoder *enc);
void (*intra_refresh)(struct radeon_encoder *enc);
void (*rc_per_pic)(struct radeon_encoder *enc);
void (*encode_params)(struct radeon_encoder *enc);
void (*encode_params_codec_spec)(struct radeon_encoder *enc);
void (*op_init)(struct radeon_encoder *enc);
void (*op_close)(struct radeon_encoder *enc);
void (*op_enc)(struct radeon_encoder *enc);
void (*op_init_rc)(struct radeon_encoder *enc);
void (*op_init_rc_vbv)(struct radeon_encoder *enc);
void (*op_speed)(struct radeon_encoder *enc);
void (*encode_headers)(struct radeon_encoder *enc);
void (*input_format)(struct radeon_encoder *enc);
void (*output_format)(struct radeon_encoder *enc);
unsigned stream_handle;
unsigned stream_handle;
struct pipe_screen *screen;
struct radeon_winsys* ws;
struct radeon_cmdbuf* cs;
struct pipe_screen *screen;
struct radeon_winsys *ws;
struct radeon_cmdbuf *cs;
radeon_enc_get_buffer get_buffer;
radeon_enc_get_buffer get_buffer;
struct pb_buffer* handle;
struct radeon_surf* luma;
struct radeon_surf* chroma;
struct pb_buffer *handle;
struct radeon_surf *luma;
struct radeon_surf *chroma;
struct pb_buffer* bs_handle;
unsigned bs_size;
struct pb_buffer *bs_handle;
unsigned bs_size;
unsigned cpb_num;
unsigned cpb_num;
struct rvid_buffer *si;
struct rvid_buffer *fb;
struct rvid_buffer cpb;
struct radeon_enc_pic enc_pic;
rvcn_enc_cmd_t cmd;
struct rvid_buffer *si;
struct rvid_buffer *fb;
struct rvid_buffer cpb;
struct radeon_enc_pic enc_pic;
rvcn_enc_cmd_t cmd;
unsigned alignment;
unsigned shifter;
unsigned bits_in_shifter;
unsigned num_zeros;
unsigned byte_index;
unsigned bits_output;
uint32_t total_task_size;
uint32_t* p_task_size;
unsigned alignment;
unsigned shifter;
unsigned bits_in_shifter;
unsigned num_zeros;
unsigned byte_index;
unsigned bits_output;
uint32_t total_task_size;
uint32_t *p_task_size;
bool emulation_prevention;
bool need_feedback;
bool emulation_prevention;
bool need_feedback;
};
void radeon_enc_add_buffer(struct radeon_encoder *enc, struct pb_buffer *buf,
enum radeon_bo_usage usage, enum radeon_bo_domain domain,
signed offset);
enum radeon_bo_usage usage, enum radeon_bo_domain domain, signed offset);
void radeon_enc_set_emulation_prevention(struct radeon_encoder *enc, bool set);
void radeon_enc_output_one_byte(struct radeon_encoder *enc, unsigned char byte);
void radeon_enc_emulation_prevention(struct radeon_encoder *enc,
unsigned char byte);
void radeon_enc_emulation_prevention(struct radeon_encoder *enc, unsigned char byte);
void radeon_enc_code_fixed_bits(struct radeon_encoder *enc, unsigned int value,
unsigned int num_bits);
unsigned int num_bits);
void radeon_enc_reset(struct radeon_encoder *enc);
@ -564,4 +539,4 @@ void radeon_enc_1_2_init(struct radeon_encoder *enc);
void radeon_enc_2_0_init(struct radeon_encoder *enc);
#endif // _RADEON_VCN_ENC_H
#endif // _RADEON_VCN_ENC_H

File diff suppressed because it is too large Load Diff

View File

@ -25,369 +25,364 @@
*
**************************************************************************/
#include <stdio.h>
#include "pipe/p_video_codec.h"
#include "radeon_vcn_enc.h"
#include "radeon_video.h"
#include "si_pipe.h"
#include "util/u_video.h"
#include "si_pipe.h"
#include "radeon_video.h"
#include "radeon_vcn_enc.h"
#include <stdio.h>
#define RENCODE_FW_INTERFACE_MAJOR_VERSION 1
#define RENCODE_FW_INTERFACE_MINOR_VERSION 1
#define RENCODE_FW_INTERFACE_MAJOR_VERSION 1
#define RENCODE_FW_INTERFACE_MINOR_VERSION 1
#define RENCODE_IB_PARAM_SESSION_INFO 0x00000001
#define RENCODE_IB_PARAM_TASK_INFO 0x00000002
#define RENCODE_IB_PARAM_SESSION_INIT 0x00000003
#define RENCODE_IB_PARAM_LAYER_CONTROL 0x00000004
#define RENCODE_IB_PARAM_LAYER_SELECT 0x00000005
#define RENCODE_IB_PARAM_RATE_CONTROL_SESSION_INIT 0x00000006
#define RENCODE_IB_PARAM_RATE_CONTROL_LAYER_INIT 0x00000007
#define RENCODE_IB_PARAM_RATE_CONTROL_PER_PICTURE 0x00000008
#define RENCODE_IB_PARAM_QUALITY_PARAMS 0x00000009
#define RENCODE_IB_PARAM_DIRECT_OUTPUT_NALU 0x0000000a
#define RENCODE_IB_PARAM_SLICE_HEADER 0x0000000b
#define RENCODE_IB_PARAM_INPUT_FORMAT 0x0000000c
#define RENCODE_IB_PARAM_OUTPUT_FORMAT 0x0000000d
#define RENCODE_IB_PARAM_ENCODE_PARAMS 0x0000000f
#define RENCODE_IB_PARAM_INTRA_REFRESH 0x00000010
#define RENCODE_IB_PARAM_ENCODE_CONTEXT_BUFFER 0x00000011
#define RENCODE_IB_PARAM_VIDEO_BITSTREAM_BUFFER 0x00000012
#define RENCODE_IB_PARAM_FEEDBACK_BUFFER 0x00000015
#define RENCODE_IB_PARAM_SESSION_INFO 0x00000001
#define RENCODE_IB_PARAM_TASK_INFO 0x00000002
#define RENCODE_IB_PARAM_SESSION_INIT 0x00000003
#define RENCODE_IB_PARAM_LAYER_CONTROL 0x00000004
#define RENCODE_IB_PARAM_LAYER_SELECT 0x00000005
#define RENCODE_IB_PARAM_RATE_CONTROL_SESSION_INIT 0x00000006
#define RENCODE_IB_PARAM_RATE_CONTROL_LAYER_INIT 0x00000007
#define RENCODE_IB_PARAM_RATE_CONTROL_PER_PICTURE 0x00000008
#define RENCODE_IB_PARAM_QUALITY_PARAMS 0x00000009
#define RENCODE_IB_PARAM_DIRECT_OUTPUT_NALU 0x0000000a
#define RENCODE_IB_PARAM_SLICE_HEADER 0x0000000b
#define RENCODE_IB_PARAM_INPUT_FORMAT 0x0000000c
#define RENCODE_IB_PARAM_OUTPUT_FORMAT 0x0000000d
#define RENCODE_IB_PARAM_ENCODE_PARAMS 0x0000000f
#define RENCODE_IB_PARAM_INTRA_REFRESH 0x00000010
#define RENCODE_IB_PARAM_ENCODE_CONTEXT_BUFFER 0x00000011
#define RENCODE_IB_PARAM_VIDEO_BITSTREAM_BUFFER 0x00000012
#define RENCODE_IB_PARAM_FEEDBACK_BUFFER 0x00000015
#define RENCODE_HEVC_IB_PARAM_SLICE_CONTROL 0x00100001
#define RENCODE_HEVC_IB_PARAM_SPEC_MISC 0x00100002
#define RENCODE_HEVC_IB_PARAM_LOOP_FILTER 0x00100003
#define RENCODE_HEVC_IB_PARAM_SLICE_CONTROL 0x00100001
#define RENCODE_HEVC_IB_PARAM_SPEC_MISC 0x00100002
#define RENCODE_HEVC_IB_PARAM_LOOP_FILTER 0x00100003
#define RENCODE_H264_IB_PARAM_SLICE_CONTROL 0x00200001
#define RENCODE_H264_IB_PARAM_SPEC_MISC 0x00200002
#define RENCODE_H264_IB_PARAM_ENCODE_PARAMS 0x00200003
#define RENCODE_H264_IB_PARAM_DEBLOCKING_FILTER 0x00200004
#define RENCODE_H264_IB_PARAM_SLICE_CONTROL 0x00200001
#define RENCODE_H264_IB_PARAM_SPEC_MISC 0x00200002
#define RENCODE_H264_IB_PARAM_ENCODE_PARAMS 0x00200003
#define RENCODE_H264_IB_PARAM_DEBLOCKING_FILTER 0x00200004
#define RENCODE_COLOR_VOLUME_G22_BT709 0
#define RENCODE_COLOR_VOLUME_G10_BT2020 3
#define RENCODE_COLOR_VOLUME_G22_BT709 0
#define RENCODE_COLOR_VOLUME_G10_BT2020 3
#define RENCODE_COLOR_BIT_DEPTH_8_BIT 0
#define RENCODE_COLOR_BIT_DEPTH_10_BIT 1
#define RENCODE_COLOR_PACKING_FORMAT_NV12 0
#define RENCODE_COLOR_PACKING_FORMAT_P010 1
#define RENCODE_COLOR_BIT_DEPTH_8_BIT 0
#define RENCODE_COLOR_BIT_DEPTH_10_BIT 1
#define RENCODE_COLOR_PACKING_FORMAT_NV12 0
#define RENCODE_COLOR_PACKING_FORMAT_P010 1
static void radeon_enc_quality_params(struct radeon_encoder *enc)
{
enc->enc_pic.quality_params.vbaq_mode = 0;
enc->enc_pic.quality_params.scene_change_sensitivity = 0;
enc->enc_pic.quality_params.scene_change_min_idr_interval = 0;
enc->enc_pic.quality_params.two_pass_search_center_map_mode = 0;
enc->enc_pic.quality_params.vbaq_mode = 0;
enc->enc_pic.quality_params.scene_change_sensitivity = 0;
enc->enc_pic.quality_params.scene_change_min_idr_interval = 0;
enc->enc_pic.quality_params.two_pass_search_center_map_mode = 0;
RADEON_ENC_BEGIN(enc->cmd.quality_params);
RADEON_ENC_CS(enc->enc_pic.quality_params.vbaq_mode);
RADEON_ENC_CS(enc->enc_pic.quality_params.scene_change_sensitivity);
RADEON_ENC_CS(enc->enc_pic.quality_params.scene_change_min_idr_interval);
RADEON_ENC_CS(enc->enc_pic.quality_params.two_pass_search_center_map_mode);
RADEON_ENC_END();
RADEON_ENC_BEGIN(enc->cmd.quality_params);
RADEON_ENC_CS(enc->enc_pic.quality_params.vbaq_mode);
RADEON_ENC_CS(enc->enc_pic.quality_params.scene_change_sensitivity);
RADEON_ENC_CS(enc->enc_pic.quality_params.scene_change_min_idr_interval);
RADEON_ENC_CS(enc->enc_pic.quality_params.two_pass_search_center_map_mode);
RADEON_ENC_END();
}
static void radeon_enc_loop_filter_hevc(struct radeon_encoder *enc)
{
RADEON_ENC_BEGIN(enc->cmd.deblocking_filter_hevc);
RADEON_ENC_CS(enc->enc_pic.hevc_deblock.loop_filter_across_slices_enabled);
RADEON_ENC_CS(enc->enc_pic.hevc_deblock.deblocking_filter_disabled);
RADEON_ENC_CS(enc->enc_pic.hevc_deblock.beta_offset_div2);
RADEON_ENC_CS(enc->enc_pic.hevc_deblock.tc_offset_div2);
RADEON_ENC_CS(enc->enc_pic.hevc_deblock.cb_qp_offset);
RADEON_ENC_CS(enc->enc_pic.hevc_deblock.cr_qp_offset);
RADEON_ENC_CS(1);
RADEON_ENC_END();
RADEON_ENC_BEGIN(enc->cmd.deblocking_filter_hevc);
RADEON_ENC_CS(enc->enc_pic.hevc_deblock.loop_filter_across_slices_enabled);
RADEON_ENC_CS(enc->enc_pic.hevc_deblock.deblocking_filter_disabled);
RADEON_ENC_CS(enc->enc_pic.hevc_deblock.beta_offset_div2);
RADEON_ENC_CS(enc->enc_pic.hevc_deblock.tc_offset_div2);
RADEON_ENC_CS(enc->enc_pic.hevc_deblock.cb_qp_offset);
RADEON_ENC_CS(enc->enc_pic.hevc_deblock.cr_qp_offset);
RADEON_ENC_CS(1);
RADEON_ENC_END();
}
static void radeon_enc_nalu_sps_hevc(struct radeon_encoder *enc)
{
RADEON_ENC_BEGIN(enc->cmd.nalu);
RADEON_ENC_CS(RENCODE_DIRECT_OUTPUT_NALU_TYPE_SPS);
uint32_t *size_in_bytes = &enc->cs->current.buf[enc->cs->current.cdw++];
int i;
RADEON_ENC_BEGIN(enc->cmd.nalu);
RADEON_ENC_CS(RENCODE_DIRECT_OUTPUT_NALU_TYPE_SPS);
uint32_t *size_in_bytes = &enc->cs->current.buf[enc->cs->current.cdw++];
int i;
radeon_enc_reset(enc);
radeon_enc_set_emulation_prevention(enc, false);
radeon_enc_code_fixed_bits(enc, 0x00000001, 32);
radeon_enc_code_fixed_bits(enc, 0x4201, 16);
radeon_enc_byte_align(enc);
radeon_enc_set_emulation_prevention(enc, true);
radeon_enc_code_fixed_bits(enc, 0x0, 4);
radeon_enc_code_fixed_bits(enc, enc->enc_pic.layer_ctrl.max_num_temporal_layers - 1, 3);
radeon_enc_code_fixed_bits(enc, 0x1, 1);
radeon_enc_code_fixed_bits(enc, 0x0, 2);
radeon_enc_code_fixed_bits(enc, enc->enc_pic.general_tier_flag, 1);
radeon_enc_code_fixed_bits(enc, enc->enc_pic.general_profile_idc, 5);
radeon_enc_code_fixed_bits(enc, 0x60000000, 32);
radeon_enc_code_fixed_bits(enc, 0xb0000000, 32);
radeon_enc_code_fixed_bits(enc, 0x0, 16);
radeon_enc_code_fixed_bits(enc, enc->enc_pic.general_level_idc, 8);
radeon_enc_reset(enc);
radeon_enc_set_emulation_prevention(enc, false);
radeon_enc_code_fixed_bits(enc, 0x00000001, 32);
radeon_enc_code_fixed_bits(enc, 0x4201, 16);
radeon_enc_byte_align(enc);
radeon_enc_set_emulation_prevention(enc, true);
radeon_enc_code_fixed_bits(enc, 0x0, 4);
radeon_enc_code_fixed_bits(enc, enc->enc_pic.layer_ctrl.max_num_temporal_layers - 1, 3);
radeon_enc_code_fixed_bits(enc, 0x1, 1);
radeon_enc_code_fixed_bits(enc, 0x0, 2);
radeon_enc_code_fixed_bits(enc, enc->enc_pic.general_tier_flag, 1);
radeon_enc_code_fixed_bits(enc, enc->enc_pic.general_profile_idc, 5);
radeon_enc_code_fixed_bits(enc, 0x60000000, 32);
radeon_enc_code_fixed_bits(enc, 0xb0000000, 32);
radeon_enc_code_fixed_bits(enc, 0x0, 16);
radeon_enc_code_fixed_bits(enc, enc->enc_pic.general_level_idc, 8);
for (i = 0; i < (enc->enc_pic.layer_ctrl.max_num_temporal_layers - 1) ; i++)
radeon_enc_code_fixed_bits(enc, 0x0, 2);
for (i = 0; i < (enc->enc_pic.layer_ctrl.max_num_temporal_layers - 1); i++)
radeon_enc_code_fixed_bits(enc, 0x0, 2);
if ((enc->enc_pic.layer_ctrl.max_num_temporal_layers - 1) > 0) {
for (i = (enc->enc_pic.layer_ctrl.max_num_temporal_layers - 1); i < 8; i++)
radeon_enc_code_fixed_bits(enc, 0x0, 2);
}
if ((enc->enc_pic.layer_ctrl.max_num_temporal_layers - 1) > 0) {
for (i = (enc->enc_pic.layer_ctrl.max_num_temporal_layers - 1); i < 8; i++)
radeon_enc_code_fixed_bits(enc, 0x0, 2);
}
radeon_enc_code_ue(enc, 0x0);
radeon_enc_code_ue(enc, enc->enc_pic.chroma_format_idc);
radeon_enc_code_ue(enc, enc->enc_pic.session_init.aligned_picture_width);
radeon_enc_code_ue(enc, enc->enc_pic.session_init.aligned_picture_height);
radeon_enc_code_fixed_bits(enc, 0x0, 1);
radeon_enc_code_ue(enc, enc->enc_pic.bit_depth_luma_minus8);
radeon_enc_code_ue(enc, enc->enc_pic.bit_depth_chroma_minus8);
radeon_enc_code_ue(enc, enc->enc_pic.log2_max_poc - 4);
radeon_enc_code_fixed_bits(enc, 0x0, 1);
radeon_enc_code_ue(enc, 1);
radeon_enc_code_ue(enc, 0x0);
radeon_enc_code_ue(enc, 0x0);
radeon_enc_code_ue(enc, enc->enc_pic.hevc_spec_misc.log2_min_luma_coding_block_size_minus3);
//Only support CTBSize 64
radeon_enc_code_ue(enc, 6 - (enc->enc_pic.hevc_spec_misc.log2_min_luma_coding_block_size_minus3 + 3));
radeon_enc_code_ue(enc, enc->enc_pic.log2_min_transform_block_size_minus2);
radeon_enc_code_ue(enc, enc->enc_pic.log2_diff_max_min_transform_block_size);
radeon_enc_code_ue(enc, enc->enc_pic.max_transform_hierarchy_depth_inter);
radeon_enc_code_ue(enc, enc->enc_pic.max_transform_hierarchy_depth_intra);
radeon_enc_code_ue(enc, 0x0);
radeon_enc_code_ue(enc, enc->enc_pic.chroma_format_idc);
radeon_enc_code_ue(enc, enc->enc_pic.session_init.aligned_picture_width);
radeon_enc_code_ue(enc, enc->enc_pic.session_init.aligned_picture_height);
radeon_enc_code_fixed_bits(enc, 0x0, 1);
radeon_enc_code_ue(enc, enc->enc_pic.bit_depth_luma_minus8);
radeon_enc_code_ue(enc, enc->enc_pic.bit_depth_chroma_minus8);
radeon_enc_code_ue(enc, enc->enc_pic.log2_max_poc - 4);
radeon_enc_code_fixed_bits(enc, 0x0, 1);
radeon_enc_code_ue(enc, 1);
radeon_enc_code_ue(enc, 0x0);
radeon_enc_code_ue(enc, 0x0);
radeon_enc_code_ue(enc, enc->enc_pic.hevc_spec_misc.log2_min_luma_coding_block_size_minus3);
// Only support CTBSize 64
radeon_enc_code_ue(enc,
6 - (enc->enc_pic.hevc_spec_misc.log2_min_luma_coding_block_size_minus3 + 3));
radeon_enc_code_ue(enc, enc->enc_pic.log2_min_transform_block_size_minus2);
radeon_enc_code_ue(enc, enc->enc_pic.log2_diff_max_min_transform_block_size);
radeon_enc_code_ue(enc, enc->enc_pic.max_transform_hierarchy_depth_inter);
radeon_enc_code_ue(enc, enc->enc_pic.max_transform_hierarchy_depth_intra);
radeon_enc_code_fixed_bits(enc, 0x0, 1);
radeon_enc_code_fixed_bits(enc, !enc->enc_pic.hevc_spec_misc.amp_disabled, 1);
radeon_enc_code_fixed_bits(enc, enc->enc_pic.sample_adaptive_offset_enabled_flag, 1);
radeon_enc_code_fixed_bits(enc, enc->enc_pic.pcm_enabled_flag, 1);
radeon_enc_code_fixed_bits(enc, 0x0, 1);
radeon_enc_code_fixed_bits(enc, !enc->enc_pic.hevc_spec_misc.amp_disabled, 1);
radeon_enc_code_fixed_bits(enc, enc->enc_pic.sample_adaptive_offset_enabled_flag, 1);
radeon_enc_code_fixed_bits(enc, enc->enc_pic.pcm_enabled_flag, 1);
radeon_enc_code_ue(enc, 1);
radeon_enc_code_ue(enc, 1);
radeon_enc_code_ue(enc, 0);
radeon_enc_code_ue(enc, 0);
radeon_enc_code_fixed_bits(enc, 0x1, 1);
radeon_enc_code_ue(enc, 1);
radeon_enc_code_ue(enc, 1);
radeon_enc_code_ue(enc, 0);
radeon_enc_code_ue(enc, 0);
radeon_enc_code_fixed_bits(enc, 0x1, 1);
radeon_enc_code_fixed_bits(enc, 0x0, 1);
radeon_enc_code_fixed_bits(enc, 0x0, 1);
radeon_enc_code_fixed_bits(enc, 0, 1);
radeon_enc_code_fixed_bits(enc, enc->enc_pic.hevc_spec_misc.strong_intra_smoothing_enabled, 1);
radeon_enc_code_fixed_bits(enc, 0, 1);
radeon_enc_code_fixed_bits(enc, enc->enc_pic.hevc_spec_misc.strong_intra_smoothing_enabled, 1);
radeon_enc_code_fixed_bits(enc, 0x0, 1);
radeon_enc_code_fixed_bits(enc, 0x0, 1);
radeon_enc_code_fixed_bits(enc, 0x0, 1);
radeon_enc_code_fixed_bits(enc, 0x0, 1);
radeon_enc_code_fixed_bits(enc, 0x1, 1);
radeon_enc_code_fixed_bits(enc, 0x1, 1);
radeon_enc_byte_align(enc);
radeon_enc_flush_headers(enc);
*size_in_bytes = (enc->bits_output + 7) / 8;
RADEON_ENC_END();
radeon_enc_byte_align(enc);
radeon_enc_flush_headers(enc);
*size_in_bytes = (enc->bits_output + 7) / 8;
RADEON_ENC_END();
}
static void radeon_enc_nalu_pps_hevc(struct radeon_encoder *enc)
{
RADEON_ENC_BEGIN(enc->cmd.nalu);
RADEON_ENC_CS(RENCODE_DIRECT_OUTPUT_NALU_TYPE_PPS);
uint32_t *size_in_bytes = &enc->cs->current.buf[enc->cs->current.cdw++];
radeon_enc_reset(enc);
radeon_enc_set_emulation_prevention(enc, false);
radeon_enc_code_fixed_bits(enc, 0x00000001, 32);
radeon_enc_code_fixed_bits(enc, 0x4401, 16);
radeon_enc_byte_align(enc);
radeon_enc_set_emulation_prevention(enc, true);
radeon_enc_code_ue(enc, 0x0);
radeon_enc_code_ue(enc, 0x0);
radeon_enc_code_fixed_bits(enc, 0x1, 1);
radeon_enc_code_fixed_bits(enc, 0x0, 4);
radeon_enc_code_fixed_bits(enc, 0x0, 1);
radeon_enc_code_fixed_bits(enc, 0x1, 1);
radeon_enc_code_ue(enc, 0x0);
radeon_enc_code_ue(enc, 0x0);
radeon_enc_code_se(enc, 0x0);
radeon_enc_code_fixed_bits(enc, enc->enc_pic.hevc_spec_misc.constrained_intra_pred_flag, 1);
radeon_enc_code_fixed_bits(enc, 0x0, 1);
if (enc->enc_pic.rc_session_init.rate_control_method ==
RENCODE_RATE_CONTROL_METHOD_NONE)
radeon_enc_code_fixed_bits(enc, 0x0, 1);
else {
radeon_enc_code_fixed_bits(enc, 0x1, 1);
radeon_enc_code_ue(enc, 0x0);
}
radeon_enc_code_se(enc, enc->enc_pic.hevc_deblock.cb_qp_offset);
radeon_enc_code_se(enc, enc->enc_pic.hevc_deblock.cr_qp_offset);
radeon_enc_code_fixed_bits(enc, 0x0, 1);
radeon_enc_code_fixed_bits(enc, 0x0, 2);
radeon_enc_code_fixed_bits(enc, 0x0, 1);
radeon_enc_code_fixed_bits(enc, 0x0, 1);
radeon_enc_code_fixed_bits(enc, 0x0, 1);
radeon_enc_code_fixed_bits(enc, enc->enc_pic.hevc_deblock.loop_filter_across_slices_enabled, 1);
radeon_enc_code_fixed_bits(enc, 0x1, 1);
radeon_enc_code_fixed_bits(enc, 0x0, 1);
radeon_enc_code_fixed_bits(enc, enc->enc_pic.hevc_deblock.deblocking_filter_disabled, 1);
RADEON_ENC_BEGIN(enc->cmd.nalu);
RADEON_ENC_CS(RENCODE_DIRECT_OUTPUT_NALU_TYPE_PPS);
uint32_t *size_in_bytes = &enc->cs->current.buf[enc->cs->current.cdw++];
radeon_enc_reset(enc);
radeon_enc_set_emulation_prevention(enc, false);
radeon_enc_code_fixed_bits(enc, 0x00000001, 32);
radeon_enc_code_fixed_bits(enc, 0x4401, 16);
radeon_enc_byte_align(enc);
radeon_enc_set_emulation_prevention(enc, true);
radeon_enc_code_ue(enc, 0x0);
radeon_enc_code_ue(enc, 0x0);
radeon_enc_code_fixed_bits(enc, 0x1, 1);
radeon_enc_code_fixed_bits(enc, 0x0, 4);
radeon_enc_code_fixed_bits(enc, 0x0, 1);
radeon_enc_code_fixed_bits(enc, 0x1, 1);
radeon_enc_code_ue(enc, 0x0);
radeon_enc_code_ue(enc, 0x0);
radeon_enc_code_se(enc, 0x0);
radeon_enc_code_fixed_bits(enc, enc->enc_pic.hevc_spec_misc.constrained_intra_pred_flag, 1);
radeon_enc_code_fixed_bits(enc, 0x0, 1);
if (enc->enc_pic.rc_session_init.rate_control_method == RENCODE_RATE_CONTROL_METHOD_NONE)
radeon_enc_code_fixed_bits(enc, 0x0, 1);
else {
radeon_enc_code_fixed_bits(enc, 0x1, 1);
radeon_enc_code_ue(enc, 0x0);
}
radeon_enc_code_se(enc, enc->enc_pic.hevc_deblock.cb_qp_offset);
radeon_enc_code_se(enc, enc->enc_pic.hevc_deblock.cr_qp_offset);
radeon_enc_code_fixed_bits(enc, 0x0, 1);
radeon_enc_code_fixed_bits(enc, 0x0, 2);
radeon_enc_code_fixed_bits(enc, 0x0, 1);
radeon_enc_code_fixed_bits(enc, 0x0, 1);
radeon_enc_code_fixed_bits(enc, 0x0, 1);
radeon_enc_code_fixed_bits(enc, enc->enc_pic.hevc_deblock.loop_filter_across_slices_enabled, 1);
radeon_enc_code_fixed_bits(enc, 0x1, 1);
radeon_enc_code_fixed_bits(enc, 0x0, 1);
radeon_enc_code_fixed_bits(enc, enc->enc_pic.hevc_deblock.deblocking_filter_disabled, 1);
if (!enc->enc_pic.hevc_deblock.deblocking_filter_disabled) {
radeon_enc_code_se(enc, enc->enc_pic.hevc_deblock.beta_offset_div2);
radeon_enc_code_se(enc, enc->enc_pic.hevc_deblock.tc_offset_div2);
}
if (!enc->enc_pic.hevc_deblock.deblocking_filter_disabled) {
radeon_enc_code_se(enc, enc->enc_pic.hevc_deblock.beta_offset_div2);
radeon_enc_code_se(enc, enc->enc_pic.hevc_deblock.tc_offset_div2);
}
radeon_enc_code_fixed_bits(enc, 0x0, 1);
radeon_enc_code_fixed_bits(enc, 0x0, 1);
radeon_enc_code_ue(enc, enc->enc_pic.log2_parallel_merge_level_minus2);
radeon_enc_code_fixed_bits(enc, 0x0, 2);
radeon_enc_code_fixed_bits(enc, 0x0, 1);
radeon_enc_code_fixed_bits(enc, 0x0, 1);
radeon_enc_code_ue(enc, enc->enc_pic.log2_parallel_merge_level_minus2);
radeon_enc_code_fixed_bits(enc, 0x0, 2);
radeon_enc_code_fixed_bits(enc, 0x1, 1);
radeon_enc_code_fixed_bits(enc, 0x1, 1);
radeon_enc_byte_align(enc);
radeon_enc_flush_headers(enc);
*size_in_bytes = (enc->bits_output + 7) / 8;
RADEON_ENC_END();
radeon_enc_byte_align(enc);
radeon_enc_flush_headers(enc);
*size_in_bytes = (enc->bits_output + 7) / 8;
RADEON_ENC_END();
}
static void radeon_enc_input_format(struct radeon_encoder *enc)
{
RADEON_ENC_BEGIN(enc->cmd.input_format);
if (enc->base.profile == PIPE_VIDEO_PROFILE_HEVC_MAIN_10) {
RADEON_ENC_CS(RENCODE_COLOR_VOLUME_G10_BT2020);
RADEON_ENC_CS(0);
RADEON_ENC_CS(0);
RADEON_ENC_CS(0);
RADEON_ENC_CS(0);
RADEON_ENC_CS(RENCODE_COLOR_BIT_DEPTH_10_BIT);
RADEON_ENC_CS(RENCODE_COLOR_PACKING_FORMAT_P010);
} else {
RADEON_ENC_CS(RENCODE_COLOR_VOLUME_G22_BT709);
RADEON_ENC_CS(0);
RADEON_ENC_CS(0);
RADEON_ENC_CS(0);
RADEON_ENC_CS(0);
RADEON_ENC_CS(RENCODE_COLOR_BIT_DEPTH_8_BIT);
RADEON_ENC_CS(RENCODE_COLOR_PACKING_FORMAT_NV12);
}
RADEON_ENC_END();
RADEON_ENC_BEGIN(enc->cmd.input_format);
if (enc->base.profile == PIPE_VIDEO_PROFILE_HEVC_MAIN_10) {
RADEON_ENC_CS(RENCODE_COLOR_VOLUME_G10_BT2020);
RADEON_ENC_CS(0);
RADEON_ENC_CS(0);
RADEON_ENC_CS(0);
RADEON_ENC_CS(0);
RADEON_ENC_CS(RENCODE_COLOR_BIT_DEPTH_10_BIT);
RADEON_ENC_CS(RENCODE_COLOR_PACKING_FORMAT_P010);
} else {
RADEON_ENC_CS(RENCODE_COLOR_VOLUME_G22_BT709);
RADEON_ENC_CS(0);
RADEON_ENC_CS(0);
RADEON_ENC_CS(0);
RADEON_ENC_CS(0);
RADEON_ENC_CS(RENCODE_COLOR_BIT_DEPTH_8_BIT);
RADEON_ENC_CS(RENCODE_COLOR_PACKING_FORMAT_NV12);
}
RADEON_ENC_END();
}
static void radeon_enc_output_format(struct radeon_encoder *enc)
{
RADEON_ENC_BEGIN(enc->cmd.output_format);
if (enc->base.profile == PIPE_VIDEO_PROFILE_HEVC_MAIN_10) {
RADEON_ENC_CS(RENCODE_COLOR_VOLUME_G10_BT2020);
RADEON_ENC_CS(0);
RADEON_ENC_CS(0);
RADEON_ENC_CS(RENCODE_COLOR_BIT_DEPTH_10_BIT);
} else {
RADEON_ENC_CS(RENCODE_COLOR_VOLUME_G22_BT709);
RADEON_ENC_CS(0);
RADEON_ENC_CS(0);
RADEON_ENC_CS(RENCODE_COLOR_BIT_DEPTH_8_BIT);
}
RADEON_ENC_END();
RADEON_ENC_BEGIN(enc->cmd.output_format);
if (enc->base.profile == PIPE_VIDEO_PROFILE_HEVC_MAIN_10) {
RADEON_ENC_CS(RENCODE_COLOR_VOLUME_G10_BT2020);
RADEON_ENC_CS(0);
RADEON_ENC_CS(0);
RADEON_ENC_CS(RENCODE_COLOR_BIT_DEPTH_10_BIT);
} else {
RADEON_ENC_CS(RENCODE_COLOR_VOLUME_G22_BT709);
RADEON_ENC_CS(0);
RADEON_ENC_CS(0);
RADEON_ENC_CS(RENCODE_COLOR_BIT_DEPTH_8_BIT);
}
RADEON_ENC_END();
}
static void radeon_enc_ctx(struct radeon_encoder *enc)
{
enc->enc_pic.ctx_buf.swizzle_mode = 0;
enc->enc_pic.ctx_buf.swizzle_mode = 0;
uint32_t aligned_width = enc->enc_pic.session_init.aligned_picture_width;
uint32_t aligned_height = enc->enc_pic.session_init.aligned_picture_height;
uint32_t aligned_width = enc->enc_pic.session_init.aligned_picture_width;
uint32_t aligned_height = enc->enc_pic.session_init.aligned_picture_height;
enc->enc_pic.ctx_buf.rec_luma_pitch = align(aligned_width, enc->alignment);
enc->enc_pic.ctx_buf.rec_chroma_pitch = align(aligned_width, enc->alignment);
enc->enc_pic.ctx_buf.rec_luma_pitch = align(aligned_width, enc->alignment);
enc->enc_pic.ctx_buf.rec_chroma_pitch = align(aligned_width, enc->alignment);
int luma_size = enc->enc_pic.ctx_buf.rec_luma_pitch * align(aligned_height, enc->alignment);
if (enc->enc_pic.bit_depth_luma_minus8 == 2)
luma_size *= 2;
int chroma_size = align(luma_size / 2, enc->alignment);
int offset = 0;
int luma_size = enc->enc_pic.ctx_buf.rec_luma_pitch * align(aligned_height, enc->alignment);
if (enc->enc_pic.bit_depth_luma_minus8 == 2)
luma_size *= 2;
int chroma_size = align(luma_size / 2, enc->alignment);
int offset = 0;
enc->enc_pic.ctx_buf.num_reconstructed_pictures = 2;
for (int i = 0; i < enc->enc_pic.ctx_buf.num_reconstructed_pictures; i++) {
enc->enc_pic.ctx_buf.reconstructed_pictures[i].luma_offset = offset;
offset += luma_size;
enc->enc_pic.ctx_buf.reconstructed_pictures[i].chroma_offset = offset;
offset += chroma_size;
}
enc->enc_pic.ctx_buf.num_reconstructed_pictures = 2;
for (int i = 0; i < enc->enc_pic.ctx_buf.num_reconstructed_pictures; i++) {
enc->enc_pic.ctx_buf.reconstructed_pictures[i].luma_offset = offset;
offset += luma_size;
enc->enc_pic.ctx_buf.reconstructed_pictures[i].chroma_offset = offset;
offset += chroma_size;
}
RADEON_ENC_BEGIN(enc->cmd.ctx);
RADEON_ENC_READWRITE(enc->cpb.res->buf, enc->cpb.res->domains, 0);
RADEON_ENC_CS(enc->enc_pic.ctx_buf.swizzle_mode);
RADEON_ENC_CS(enc->enc_pic.ctx_buf.rec_luma_pitch);
RADEON_ENC_CS(enc->enc_pic.ctx_buf.rec_chroma_pitch);
RADEON_ENC_CS(enc->enc_pic.ctx_buf.num_reconstructed_pictures);
RADEON_ENC_BEGIN(enc->cmd.ctx);
RADEON_ENC_READWRITE(enc->cpb.res->buf, enc->cpb.res->domains, 0);
RADEON_ENC_CS(enc->enc_pic.ctx_buf.swizzle_mode);
RADEON_ENC_CS(enc->enc_pic.ctx_buf.rec_luma_pitch);
RADEON_ENC_CS(enc->enc_pic.ctx_buf.rec_chroma_pitch);
RADEON_ENC_CS(enc->enc_pic.ctx_buf.num_reconstructed_pictures);
for (int i = 0; i < enc->enc_pic.ctx_buf.num_reconstructed_pictures; i++) {
RADEON_ENC_CS(enc->enc_pic.ctx_buf.reconstructed_pictures[i].luma_offset);
RADEON_ENC_CS(enc->enc_pic.ctx_buf.reconstructed_pictures[i].chroma_offset);
}
for (int i = 0; i < enc->enc_pic.ctx_buf.num_reconstructed_pictures; i++) {
RADEON_ENC_CS(enc->enc_pic.ctx_buf.reconstructed_pictures[i].luma_offset);
RADEON_ENC_CS(enc->enc_pic.ctx_buf.reconstructed_pictures[i].chroma_offset);
}
for (int i = 0; i < 136 ; i++)
RADEON_ENC_CS(0x00000000);
for (int i = 0; i < 136; i++)
RADEON_ENC_CS(0x00000000);
RADEON_ENC_END();
RADEON_ENC_END();
}
static void encode(struct radeon_encoder *enc)
{
enc->session_info(enc);
enc->total_task_size = 0;
enc->task_info(enc, enc->need_feedback);
enc->session_info(enc);
enc->total_task_size = 0;
enc->task_info(enc, enc->need_feedback);
enc->encode_headers(enc);
enc->ctx(enc);
enc->bitstream(enc);
enc->feedback(enc);
enc->intra_refresh(enc);
enc->input_format(enc);
enc->output_format(enc);
enc->encode_headers(enc);
enc->ctx(enc);
enc->bitstream(enc);
enc->feedback(enc);
enc->intra_refresh(enc);
enc->input_format(enc);
enc->output_format(enc);
enc->op_speed(enc);
enc->op_enc(enc);
*enc->p_task_size = (enc->total_task_size);
enc->op_speed(enc);
enc->op_enc(enc);
*enc->p_task_size = (enc->total_task_size);
}
void radeon_enc_2_0_init(struct radeon_encoder *enc)
{
radeon_enc_1_2_init(enc);
enc->encode = encode;
enc->ctx = radeon_enc_ctx;
enc->quality_params = radeon_enc_quality_params;
enc->input_format = radeon_enc_input_format;
enc->output_format = radeon_enc_output_format;
radeon_enc_1_2_init(enc);
enc->encode = encode;
enc->ctx = radeon_enc_ctx;
enc->quality_params = radeon_enc_quality_params;
enc->input_format = radeon_enc_input_format;
enc->output_format = radeon_enc_output_format;
if (u_reduce_video_profile(enc->base.profile) == PIPE_VIDEO_FORMAT_HEVC) {
enc->deblocking_filter = radeon_enc_loop_filter_hevc;
enc->nalu_sps = radeon_enc_nalu_sps_hevc;
enc->nalu_pps = radeon_enc_nalu_pps_hevc;
}
if (u_reduce_video_profile(enc->base.profile) == PIPE_VIDEO_FORMAT_HEVC) {
enc->deblocking_filter = radeon_enc_loop_filter_hevc;
enc->nalu_sps = radeon_enc_nalu_sps_hevc;
enc->nalu_pps = radeon_enc_nalu_pps_hevc;
}
enc->cmd.session_info = RENCODE_IB_PARAM_SESSION_INFO;
enc->cmd.task_info = RENCODE_IB_PARAM_TASK_INFO;
enc->cmd.session_init = RENCODE_IB_PARAM_SESSION_INIT;
enc->cmd.layer_control = RENCODE_IB_PARAM_LAYER_CONTROL;
enc->cmd.layer_select = RENCODE_IB_PARAM_LAYER_SELECT;
enc->cmd.rc_session_init = RENCODE_IB_PARAM_RATE_CONTROL_SESSION_INIT;
enc->cmd.rc_layer_init = RENCODE_IB_PARAM_RATE_CONTROL_LAYER_INIT;
enc->cmd.rc_per_pic = RENCODE_IB_PARAM_RATE_CONTROL_PER_PICTURE;
enc->cmd.quality_params = RENCODE_IB_PARAM_QUALITY_PARAMS;
enc->cmd.nalu = RENCODE_IB_PARAM_DIRECT_OUTPUT_NALU;
enc->cmd.slice_header = RENCODE_IB_PARAM_SLICE_HEADER;
enc->cmd.input_format = RENCODE_IB_PARAM_INPUT_FORMAT;
enc->cmd.output_format = RENCODE_IB_PARAM_OUTPUT_FORMAT;
enc->cmd.enc_params = RENCODE_IB_PARAM_ENCODE_PARAMS;
enc->cmd.intra_refresh = RENCODE_IB_PARAM_INTRA_REFRESH;
enc->cmd.ctx = RENCODE_IB_PARAM_ENCODE_CONTEXT_BUFFER;
enc->cmd.bitstream = RENCODE_IB_PARAM_VIDEO_BITSTREAM_BUFFER;
enc->cmd.feedback = RENCODE_IB_PARAM_FEEDBACK_BUFFER;
enc->cmd.slice_control_hevc = RENCODE_HEVC_IB_PARAM_SLICE_CONTROL;
enc->cmd.spec_misc_hevc = RENCODE_HEVC_IB_PARAM_SPEC_MISC;
enc->cmd.deblocking_filter_hevc = RENCODE_HEVC_IB_PARAM_LOOP_FILTER;
enc->cmd.slice_control_h264 = RENCODE_H264_IB_PARAM_SLICE_CONTROL;
enc->cmd.spec_misc_h264 = RENCODE_H264_IB_PARAM_SPEC_MISC;
enc->cmd.enc_params_h264 = RENCODE_H264_IB_PARAM_ENCODE_PARAMS;
enc->cmd.deblocking_filter_h264 = RENCODE_H264_IB_PARAM_DEBLOCKING_FILTER;
enc->cmd.session_info = RENCODE_IB_PARAM_SESSION_INFO;
enc->cmd.task_info = RENCODE_IB_PARAM_TASK_INFO;
enc->cmd.session_init = RENCODE_IB_PARAM_SESSION_INIT;
enc->cmd.layer_control = RENCODE_IB_PARAM_LAYER_CONTROL;
enc->cmd.layer_select = RENCODE_IB_PARAM_LAYER_SELECT;
enc->cmd.rc_session_init = RENCODE_IB_PARAM_RATE_CONTROL_SESSION_INIT;
enc->cmd.rc_layer_init = RENCODE_IB_PARAM_RATE_CONTROL_LAYER_INIT;
enc->cmd.rc_per_pic = RENCODE_IB_PARAM_RATE_CONTROL_PER_PICTURE;
enc->cmd.quality_params = RENCODE_IB_PARAM_QUALITY_PARAMS;
enc->cmd.nalu = RENCODE_IB_PARAM_DIRECT_OUTPUT_NALU;
enc->cmd.slice_header = RENCODE_IB_PARAM_SLICE_HEADER;
enc->cmd.input_format = RENCODE_IB_PARAM_INPUT_FORMAT;
enc->cmd.output_format = RENCODE_IB_PARAM_OUTPUT_FORMAT;
enc->cmd.enc_params = RENCODE_IB_PARAM_ENCODE_PARAMS;
enc->cmd.intra_refresh = RENCODE_IB_PARAM_INTRA_REFRESH;
enc->cmd.ctx = RENCODE_IB_PARAM_ENCODE_CONTEXT_BUFFER;
enc->cmd.bitstream = RENCODE_IB_PARAM_VIDEO_BITSTREAM_BUFFER;
enc->cmd.feedback = RENCODE_IB_PARAM_FEEDBACK_BUFFER;
enc->cmd.slice_control_hevc = RENCODE_HEVC_IB_PARAM_SLICE_CONTROL;
enc->cmd.spec_misc_hevc = RENCODE_HEVC_IB_PARAM_SPEC_MISC;
enc->cmd.deblocking_filter_hevc = RENCODE_HEVC_IB_PARAM_LOOP_FILTER;
enc->cmd.slice_control_h264 = RENCODE_H264_IB_PARAM_SLICE_CONTROL;
enc->cmd.spec_misc_h264 = RENCODE_H264_IB_PARAM_SPEC_MISC;
enc->cmd.enc_params_h264 = RENCODE_H264_IB_PARAM_ENCODE_PARAMS;
enc->cmd.deblocking_filter_h264 = RENCODE_H264_IB_PARAM_DEBLOCKING_FILTER;
enc->enc_pic.session_info.interface_version =
((RENCODE_FW_INTERFACE_MAJOR_VERSION << RENCODE_IF_MAJOR_VERSION_SHIFT) |
(RENCODE_FW_INTERFACE_MINOR_VERSION << RENCODE_IF_MINOR_VERSION_SHIFT));
enc->enc_pic.session_info.interface_version =
((RENCODE_FW_INTERFACE_MAJOR_VERSION << RENCODE_IF_MAJOR_VERSION_SHIFT) |
(RENCODE_FW_INTERFACE_MINOR_VERSION << RENCODE_IF_MINOR_VERSION_SHIFT));
}

View File

@ -25,103 +25,99 @@
*
**************************************************************************/
#include <unistd.h>
#include "radeon_video.h"
#include "radeon_vce.h"
#include "radeonsi/si_pipe.h"
#include "util/u_memory.h"
#include "util/u_video.h"
#include "vl/vl_defines.h"
#include "vl/vl_video_buffer.h"
#include "radeonsi/si_pipe.h"
#include "radeon_video.h"
#include "radeon_vce.h"
#include <unistd.h>
/* generate an stream handle */
unsigned si_vid_alloc_stream_handle()
{
static unsigned counter = 0;
unsigned stream_handle = 0;
unsigned pid = getpid();
int i;
static unsigned counter = 0;
unsigned stream_handle = 0;
unsigned pid = getpid();
int i;
for (i = 0; i < 32; ++i)
stream_handle |= ((pid >> i) & 1) << (31 - i);
for (i = 0; i < 32; ++i)
stream_handle |= ((pid >> i) & 1) << (31 - i);
stream_handle ^= ++counter;
return stream_handle;
stream_handle ^= ++counter;
return stream_handle;
}
/* create a buffer in the winsys */
bool si_vid_create_buffer(struct pipe_screen *screen, struct rvid_buffer *buffer,
unsigned size, unsigned usage)
bool si_vid_create_buffer(struct pipe_screen *screen, struct rvid_buffer *buffer, unsigned size,
unsigned usage)
{
memset(buffer, 0, sizeof(*buffer));
buffer->usage = usage;
memset(buffer, 0, sizeof(*buffer));
buffer->usage = usage;
/* Hardware buffer placement restrictions require the kernel to be
* able to move buffers around individually, so request a
* non-sub-allocated buffer.
*/
buffer->res = si_resource(pipe_buffer_create(screen, PIPE_BIND_SHARED,
usage, size));
/* Hardware buffer placement restrictions require the kernel to be
* able to move buffers around individually, so request a
* non-sub-allocated buffer.
*/
buffer->res = si_resource(pipe_buffer_create(screen, PIPE_BIND_SHARED, usage, size));
return buffer->res != NULL;
return buffer->res != NULL;
}
/* destroy a buffer */
void si_vid_destroy_buffer(struct rvid_buffer *buffer)
{
si_resource_reference(&buffer->res, NULL);
si_resource_reference(&buffer->res, NULL);
}
/* reallocate a buffer, preserving its content */
bool si_vid_resize_buffer(struct pipe_screen *screen, struct radeon_cmdbuf *cs,
struct rvid_buffer *new_buf, unsigned new_size)
struct rvid_buffer *new_buf, unsigned new_size)
{
struct si_screen *sscreen = (struct si_screen *)screen;
struct radeon_winsys* ws = sscreen->ws;
unsigned bytes = MIN2(new_buf->res->buf->size, new_size);
struct rvid_buffer old_buf = *new_buf;
void *src = NULL, *dst = NULL;
struct si_screen *sscreen = (struct si_screen *)screen;
struct radeon_winsys *ws = sscreen->ws;
unsigned bytes = MIN2(new_buf->res->buf->size, new_size);
struct rvid_buffer old_buf = *new_buf;
void *src = NULL, *dst = NULL;
if (!si_vid_create_buffer(screen, new_buf, new_size, new_buf->usage))
goto error;
if (!si_vid_create_buffer(screen, new_buf, new_size, new_buf->usage))
goto error;
src = ws->buffer_map(old_buf.res->buf, cs,
PIPE_TRANSFER_READ | RADEON_TRANSFER_TEMPORARY);
if (!src)
goto error;
src = ws->buffer_map(old_buf.res->buf, cs, PIPE_TRANSFER_READ | RADEON_TRANSFER_TEMPORARY);
if (!src)
goto error;
dst = ws->buffer_map(new_buf->res->buf, cs,
PIPE_TRANSFER_WRITE | RADEON_TRANSFER_TEMPORARY);
if (!dst)
goto error;
dst = ws->buffer_map(new_buf->res->buf, cs, PIPE_TRANSFER_WRITE | RADEON_TRANSFER_TEMPORARY);
if (!dst)
goto error;
memcpy(dst, src, bytes);
if (new_size > bytes) {
new_size -= bytes;
dst += bytes;
memset(dst, 0, new_size);
}
ws->buffer_unmap(new_buf->res->buf);
ws->buffer_unmap(old_buf.res->buf);
si_vid_destroy_buffer(&old_buf);
return true;
memcpy(dst, src, bytes);
if (new_size > bytes) {
new_size -= bytes;
dst += bytes;
memset(dst, 0, new_size);
}
ws->buffer_unmap(new_buf->res->buf);
ws->buffer_unmap(old_buf.res->buf);
si_vid_destroy_buffer(&old_buf);
return true;
error:
if (src)
ws->buffer_unmap(old_buf.res->buf);
si_vid_destroy_buffer(new_buf);
*new_buf = old_buf;
return false;
if (src)
ws->buffer_unmap(old_buf.res->buf);
si_vid_destroy_buffer(new_buf);
*new_buf = old_buf;
return false;
}
/* clear the buffer with zeros */
void si_vid_clear_buffer(struct pipe_context *context, struct rvid_buffer* buffer)
void si_vid_clear_buffer(struct pipe_context *context, struct rvid_buffer *buffer)
{
struct si_context *sctx = (struct si_context*)context;
struct si_context *sctx = (struct si_context *)context;
si_sdma_clear_buffer(sctx, &buffer->res->b.b, 0, buffer->res->b.b.width0, 0);
context->flush(context, NULL, 0);
si_sdma_clear_buffer(sctx, &buffer->res->b.b, 0, buffer->res->b.b.width0, 0);
context->flush(context, NULL, 0);
}

View File

@ -31,33 +31,32 @@
#include "radeon/radeon_winsys.h"
#include "vl/vl_video_buffer.h"
#define RVID_ERR(fmt, args...) \
fprintf(stderr, "EE %s:%d %s UVD - "fmt, __FILE__, __LINE__, __func__, ##args)
#define RVID_ERR(fmt, args...) \
fprintf(stderr, "EE %s:%d %s UVD - " fmt, __FILE__, __LINE__, __func__, ##args)
#define UVD_FW_1_66_16 ((1 << 24) | (66 << 16) | (16 << 8))
/* video buffer representation */
struct rvid_buffer
{
unsigned usage;
struct si_resource *res;
struct rvid_buffer {
unsigned usage;
struct si_resource *res;
};
/* generate an stream handle */
unsigned si_vid_alloc_stream_handle(void);
/* create a buffer in the winsys */
bool si_vid_create_buffer(struct pipe_screen *screen, struct rvid_buffer *buffer,
unsigned size, unsigned usage);
bool si_vid_create_buffer(struct pipe_screen *screen, struct rvid_buffer *buffer, unsigned size,
unsigned usage);
/* destroy a buffer */
void si_vid_destroy_buffer(struct rvid_buffer *buffer);
/* reallocate a buffer, preserving its content */
bool si_vid_resize_buffer(struct pipe_screen *screen, struct radeon_cmdbuf *cs,
struct rvid_buffer *new_buf, unsigned new_size);
struct rvid_buffer *new_buf, unsigned new_size);
/* clear the buffer with zeros */
void si_vid_clear_buffer(struct pipe_context *context, struct rvid_buffer* buffer);
void si_vid_clear_buffer(struct pipe_context *context, struct rvid_buffer *buffer);
#endif // RADEON_VIDEO_H

File diff suppressed because it is too large Load Diff