From 7f7ae47385da726c0f56787d8675be21efe49c98 Mon Sep 17 00:00:00 2001 From: Boyuan Zhang Date: Wed, 8 Nov 2017 11:17:15 -0500 Subject: [PATCH] radeon/vcn: add common encode part MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Add a skeleton pipe video interface and encode ib interface for video encode on vcn hardware. Add function defines and structures for vcn encode. Update Makefile.sources and meson.build with newly added files. Signed-off-by: Boyuan Zhang Acked-by: Christian König --- src/gallium/drivers/radeon/Makefile.sources | 3 + src/gallium/drivers/radeon/meson.build | 3 + src/gallium/drivers/radeon/radeon_vcn_enc.c | 164 ++++++++++++ src/gallium/drivers/radeon/radeon_vcn_enc.h | 82 ++++++ .../drivers/radeon/radeon_vcn_enc_1_2.c | 237 ++++++++++++++++++ 5 files changed, 489 insertions(+) create mode 100644 src/gallium/drivers/radeon/radeon_vcn_enc.c create mode 100644 src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c diff --git a/src/gallium/drivers/radeon/Makefile.sources b/src/gallium/drivers/radeon/Makefile.sources index 22de1297381..ebb194ccf97 100644 --- a/src/gallium/drivers/radeon/Makefile.sources +++ b/src/gallium/drivers/radeon/Makefile.sources @@ -13,6 +13,9 @@ C_SOURCES := \ radeon_uvd.h \ radeon_vcn_dec.c \ radeon_vcn_dec.h \ + radeon_vcn_enc_1_2.c \ + radeon_vcn_enc.c \ + radeon_vcn_enc.h \ radeon_vce_40_2_2.c \ radeon_vce_50.c \ radeon_vce_52.c \ diff --git a/src/gallium/drivers/radeon/meson.build b/src/gallium/drivers/radeon/meson.build index f378b12e8e8..561fd286319 100644 --- a/src/gallium/drivers/radeon/meson.build +++ b/src/gallium/drivers/radeon/meson.build @@ -31,6 +31,9 @@ files_libradeon = files( 'r600_texture.c', 'radeon_uvd.c', 'radeon_uvd.h', + 'radeon_vcn_enc_1_2.c', + 'radeon_vcn_enc.c', + 'radeon_vcn_enc.h', 'radeon_vcn_dec.c', 'radeon_vcn_dec.h', 'radeon_vce_40_2_2.c', diff --git a/src/gallium/drivers/radeon/radeon_vcn_enc.c b/src/gallium/drivers/radeon/radeon_vcn_enc.c new file mode 100644 index 00000000000..48ff8db6714 --- /dev/null +++ b/src/gallium/drivers/radeon/radeon_vcn_enc.c @@ -0,0 +1,164 @@ +/************************************************************************** + * + * Copyright 2017 Advanced Micro Devices, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include + +#include "pipe/p_video_codec.h" + +#include "util/u_video.h" +#include "util/u_memory.h" + +#include "vl/vl_video_buffer.h" + +#include "r600_pipe_common.h" +#include "radeon_video.h" +#include "radeon_vcn_enc.h" + +static void radeon_vcn_enc_get_param(struct radeon_encoder *enc, struct pipe_h264_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.ref_idx_l0 = pic->ref_idx_l0; + enc->enc_pic.ref_idx_l1 = pic->ref_idx_l1; + enc->enc_pic.not_referenced = pic->not_referenced; + enc->enc_pic.is_idr = pic->is_idr; + 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; +} + +static void flush(struct radeon_encoder *enc) +{ + enc->ws->cs_flush(enc->cs, RADEON_FLUSH_ASYNC, NULL); +} + +static void radeon_enc_flush(struct pipe_video_codec *encoder) +{ + 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) +{ + // 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; + + 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); +} + +static void radeon_enc_begin_frame(struct pipe_video_codec *encoder, + struct pipe_video_buffer *source, + struct pipe_picture_desc *picture) +{ + /* TODO*/ +} + +static void radeon_enc_encode_bitstream(struct pipe_video_codec *encoder, + struct pipe_video_buffer *source, + struct pipe_resource *destination, + void **fb) +{ + /* TODO*/ +} + +static void radeon_enc_end_frame(struct pipe_video_codec *encoder, + struct pipe_video_buffer *source, + struct pipe_picture_desc *picture) +{ + /* TODO*/ +} + +static void radeon_enc_destroy(struct pipe_video_codec *encoder) +{ + /* TODO*/ +} + +static void radeon_enc_get_feedback(struct pipe_video_codec *encoder, + void *feedback, unsigned *size) +{ + /* TODO*/ +} + +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) +{ + /* TODO*/ +} diff --git a/src/gallium/drivers/radeon/radeon_vcn_enc.h b/src/gallium/drivers/radeon/radeon_vcn_enc.h index f9fa16877d4..fe61419e301 100644 --- a/src/gallium/drivers/radeon/radeon_vcn_enc.h +++ b/src/gallium/drivers/radeon/radeon_vcn_enc.h @@ -322,4 +322,86 @@ typedef struct rvcn_enc_feedback_buffer_s uint32_t feedback_data_size; } rvcn_enc_feedback_buffer_t; +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); + +struct radeon_enc_h264_enc_pic { + 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; + + bool not_referenced; + bool is_idr; + + 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_h264_spec_misc_t 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_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; + + void (*begin)(struct radeon_encoder *enc, struct pipe_h264_enc_picture_desc *pic); + void (*encode)(struct radeon_encoder *enc); + void (*destroy)(struct radeon_encoder *enc); + + unsigned stream_handle; + + struct pipe_screen *screen; + struct radeon_winsys* ws; + struct radeon_winsys_cs* cs; + + radeon_enc_get_buffer get_buffer; + + struct pb_buffer* handle; + struct radeon_surf* luma; + struct radeon_surf* chroma; + + struct pb_buffer* bs_handle; + unsigned bs_size; + + unsigned cpb_num; + + struct rvid_buffer *si; + struct rvid_buffer *fb; + struct rvid_buffer cpb; + struct radeon_enc_h264_enc_pic enc_pic; + + unsigned alignment; + uint32_t total_task_size; + uint32_t* p_task_size; + + bool need_feedback; +}; + +void radeon_enc_1_2_init(struct radeon_encoder *enc); + #endif // _RADEON_VCN_ENC_H diff --git a/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c b/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c new file mode 100644 index 00000000000..ffd1155aeb8 --- /dev/null +++ b/src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c @@ -0,0 +1,237 @@ +/************************************************************************** + * + * Copyright 2017 Advanced Micro Devices, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include + +#include "pipe/p_video_codec.h" + +#include "util/u_video.h" +#include "util/u_memory.h" + +#include "vl/vl_video_buffer.h" + +#include "r600_pipe_common.h" +#include "radeon_video.h" +#include "radeon_vcn_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_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;} + +static const unsigned profiles[7] = { 66, 77, 88, 100, 110, 122, 244 }; + +static 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) +{ + enc->ws->cs_add_buffer(enc->cs, buf, usage | RADEON_USAGE_SYNCHRONIZED, + domain, RADEON_PRIO_VCE); + uint64_t addr; + addr = enc->ws->buffer_get_virtual_address(buf); + addr = addr + offset; + RADEON_ENC_CS(addr >> 32); + RADEON_ENC_CS(addr); +} + +static void radeon_enc_session_info(struct radeon_encoder *enc) +{ + /* TODO*/ +} + +static void radeon_enc_task_info(struct radeon_encoder *enc, bool need_feedback) +{ + /* TODO*/ +} + +static void radeon_enc_session_init(struct radeon_encoder *enc) +{ + /* TODO*/ +} + +static void radeon_enc_layer_control(struct radeon_encoder *enc) +{ + /* TODO*/ +} + +static void radeon_enc_layer_select(struct radeon_encoder *enc) +{ + /* TODO*/ +} + +static void radeon_enc_slice_control(struct radeon_encoder *enc) +{ + /* TODO*/ +} + +static void radeon_enc_spec_misc(struct radeon_encoder *enc) +{ + /* TODO*/ +} + +static void radeon_enc_rc_session_init(struct radeon_encoder *enc, struct pipe_h264_enc_picture_desc *pic) +{ + /* TODO*/ +} + +static void radeon_enc_rc_layer_init(struct radeon_encoder *enc, struct pipe_h264_enc_picture_desc *pic) +{ + /* TODO*/ +} + +static void radeon_enc_deblocking_filter_h264(struct radeon_encoder *enc) +{ + /* TODO*/ +} + +static void radeon_enc_quality_params(struct radeon_encoder *enc) +{ + /* TODO*/ +} + +static void radeon_enc_ctx(struct radeon_encoder *enc) +{ + /* TODO*/ +} + +static void radeon_enc_bitstream(struct radeon_encoder *enc) +{ + /* TODO*/ +} + +static void radeon_enc_feedback(struct radeon_encoder *enc) +{ + /* TODO*/ +} + +static void radeon_enc_intra_refresh(struct radeon_encoder *enc) +{ + /* TODO*/ +} + +static void radeon_enc_rc_per_pic(struct radeon_encoder *enc, struct pipe_h264_enc_picture_desc *pic) +{ + /* TODO*/ +} + +static void radeon_enc_encode_params(struct radeon_encoder *enc) +{ + /* TODO*/ +} +static void radeon_enc_encode_params_h264(struct radeon_encoder *enc) +{ + /* TODO*/ +} + +static void radeon_enc_op_init(struct radeon_encoder *enc) +{ + /* TODO*/ +} + +static void radeon_enc_op_close(struct radeon_encoder *enc) +{ + /* TODO*/ +} + +static void radeon_enc_op_enc(struct radeon_encoder *enc) +{ + /* TODO*/ +} + +static void radeon_enc_op_init_rc(struct radeon_encoder *enc) +{ + /* TODO*/ +} + +static void radeon_enc_op_init_rc_vbv(struct radeon_encoder *enc) +{ + /* TODO*/ +} + +static void radeon_enc_op_speed(struct radeon_encoder *enc) +{ + /* TODO*/ +} + +static void begin(struct radeon_encoder *enc, struct pipe_h264_enc_picture_desc *pic) +{ + radeon_enc_session_info(enc); + enc->total_task_size = 0; + radeon_enc_task_info(enc, enc->need_feedback); + radeon_enc_op_init(enc); + radeon_enc_session_init(enc); + radeon_enc_layer_control(enc); + radeon_enc_slice_control(enc); + radeon_enc_spec_misc(enc); + radeon_enc_rc_session_init(enc, pic); + radeon_enc_deblocking_filter_h264(enc); + radeon_enc_quality_params(enc); + radeon_enc_layer_select(enc); + radeon_enc_rc_layer_init(enc, pic); + radeon_enc_layer_select(enc); + radeon_enc_rc_per_pic(enc, pic); + radeon_enc_op_init_rc(enc); + radeon_enc_op_init_rc_vbv(enc); + *enc->p_task_size = (enc->total_task_size); +} + +static void encode(struct radeon_encoder *enc) +{ + radeon_enc_session_info(enc); + enc->total_task_size = 0; + radeon_enc_task_info(enc, enc->need_feedback); + radeon_enc_ctx(enc); + radeon_enc_bitstream(enc); + radeon_enc_feedback(enc); + radeon_enc_intra_refresh(enc); + radeon_enc_encode_params(enc); + radeon_enc_encode_params_h264(enc); + radeon_enc_op_speed(enc); + radeon_enc_op_enc(enc); + *enc->p_task_size = (enc->total_task_size); +} + +static void destroy(struct radeon_encoder *enc) +{ + radeon_enc_session_info(enc); + enc->total_task_size = 0; + radeon_enc_task_info(enc, enc->need_feedback); + radeon_enc_op_close(enc); + *enc->p_task_size = (enc->total_task_size); +} + +void radeon_enc_1_2_init(struct radeon_encoder *enc) +{ + enc->begin = begin; + enc->encode = encode; + enc->destroy = destroy; +} -- 2.30.2