[Mesa-dev] [PATCH 07/18] radeon/vcn: add common encode part
boyuan.zhang at amd.com
boyuan.zhang at amd.com
Tue Nov 7 21:59:02 UTC 2017
From: Boyuan Zhang <boyuan.zhang at amd.com>
Signed-off-by: Boyuan Zhang <boyuan.zhang at amd.com>
---
src/gallium/drivers/radeon/Makefile.sources | 3 +
src/gallium/drivers/radeon/radeon_vcn_enc.c | 166 +++++++++++++++++
src/gallium/drivers/radeon/radeon_vcn_enc.h | 82 ++++++++
src/gallium/drivers/radeon/radeon_vcn_enc_1_2.c | 237 ++++++++++++++++++++++++
4 files changed, 488 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..0871666 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.c \
+ radeon_vcn_enc_1_2.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/radeon_vcn_enc.c b/src/gallium/drivers/radeon/radeon_vcn_enc.c
new file mode 100644
index 0000000..437c2fc
--- /dev/null
+++ b/src/gallium/drivers/radeon/radeon_vcn_enc.c
@@ -0,0 +1,166 @@
+/**************************************************************************
+ *
+ * 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 a58ff6b..cbdf9c0 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
unsigned int 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