[Mesa-dev] [PATCH 07/18] radeon/vcn: add common encode part

boyuan.zhang at amd.com boyuan.zhang at amd.com
Wed Nov 8 18:08:12 UTC 2017


From: Boyuan Zhang <boyuan.zhang at amd.com>

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 <boyuan.zhang at amd.com>
---
 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 ++++++++
 src/gallium/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 22de129..ebb194c 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 b4d2832..ed8a49a 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 0000000..48ff8db
--- /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 <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 "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 f9fa168..fe61419 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 0000000..ffd1155
--- /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 <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 "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.7.4



More information about the mesa-dev mailing list