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

Alex Deucher alexdeucher at gmail.com
Tue Nov 7 22:47:54 UTC 2017


On Tue, Nov 7, 2017 at 4:59 PM,  <boyuan.zhang at amd.com> wrote:
> From: Boyuan Zhang <boyuan.zhang at amd.com>

Better patch description please.  Something like:
Fill out a skeleton interface for video encode on vcn hardware.

>
> 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
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list