radeonsi/vcn: add support for 10bit input and enc 8bit output
authorDavid Wu <David.Wu3@amd.com>
Mon, 12 Dec 2022 17:28:59 +0000 (12:28 -0500)
committerMarge Bot <emma+marge@anholt.net>
Wed, 14 Dec 2022 07:42:28 +0000 (07:42 +0000)
This change is to support 10bit YUV input in addition to
original H264/HEVC 8bit output case. It adds
rvcn_enc_input_format_t and rvcn_enc_output_format_t for
picture input format and output format separately.

Signed-off-by: David (Ming Qiang) Wu <David.Wu3@amd.com>
Reviewed-by: Boyuan Zhang <Boyuan.Zhang@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/20284>

src/gallium/drivers/radeonsi/radeon_vcn_enc.c
src/gallium/drivers/radeonsi/radeon_vcn_enc.h
src/gallium/drivers/radeonsi/radeon_vcn_enc_2_0.c
src/gallium/drivers/radeonsi/si_get.c

index 67fb349..80c4eb3 100644 (file)
@@ -216,6 +216,36 @@ static void radeon_vcn_enc_h264_get_slice_ctrl_param(struct radeon_encoder *enc,
    enc->enc_pic.slice_ctrl.num_mbs_per_slice = num_mbs_in_slice;
 }
 
+static void radeon_vcn_enc_h264_get_output_format_param(struct radeon_encoder *enc,
+                                                        struct pipe_h264_enc_picture_desc *pic)
+{
+   enc->enc_pic.enc_output_format.output_color_volume = RENCODE_COLOR_VOLUME_G22_BT709;
+   enc->enc_pic.enc_output_format.output_color_range = RENCODE_COLOR_RANGE_FULL;
+   enc->enc_pic.enc_output_format.output_chroma_location = RENCODE_CHROMA_LOCATION_INTERSTITIAL;
+   enc->enc_pic.enc_output_format.output_color_bit_depth = RENCODE_COLOR_BIT_DEPTH_8_BIT;
+}
+
+static void radeon_vcn_enc_get_input_format_param(struct radeon_encoder *enc,
+                                                  struct pipe_picture_desc *pic_base)
+{
+   switch (pic_base->input_format) {
+   case PIPE_FORMAT_P010:
+      enc->enc_pic.enc_input_format.input_color_bit_depth = RENCODE_COLOR_BIT_DEPTH_10_BIT;
+      enc->enc_pic.enc_input_format.input_color_packing_format = RENCODE_COLOR_PACKING_FORMAT_P010;
+      break;
+   case PIPE_FORMAT_NV12: /* FALL THROUGH */
+   default:
+      enc->enc_pic.enc_input_format.input_color_bit_depth = RENCODE_COLOR_BIT_DEPTH_8_BIT;
+      enc->enc_pic.enc_input_format.input_color_packing_format = RENCODE_COLOR_PACKING_FORMAT_NV12;
+      break;
+   }
+   enc->enc_pic.enc_input_format.input_color_volume = RENCODE_COLOR_VOLUME_G22_BT709;
+   enc->enc_pic.enc_input_format.input_color_range = RENCODE_COLOR_RANGE_FULL;
+   enc->enc_pic.enc_input_format.input_chroma_subsampling = RENCODE_CHROMA_SUBSAMPLING_4_2_0;
+   enc->enc_pic.enc_input_format.input_chroma_location = RENCODE_CHROMA_LOCATION_INTERSTITIAL;
+   enc->enc_pic.enc_input_format.input_color_space = RENCODE_COLOR_SPACE_YUV;
+}
+
 static void radeon_vcn_enc_h264_get_param(struct radeon_encoder *enc,
                                           struct pipe_h264_enc_picture_desc *pic)
 {
@@ -240,6 +270,8 @@ static void radeon_vcn_enc_h264_get_param(struct radeon_encoder *enc,
    radeon_vcn_enc_h264_get_spec_misc_param(enc, pic);
    radeon_vcn_enc_h264_get_vui_param(enc, pic);
    radeon_vcn_enc_h264_get_slice_ctrl_param(enc, pic);
+   radeon_vcn_enc_get_input_format_param(enc, &pic->base);
+   radeon_vcn_enc_h264_get_output_format_param(enc, pic);
 }
 
 static void radeon_vcn_enc_hevc_get_cropping_param(struct radeon_encoder *enc,
@@ -380,6 +412,25 @@ static void radeon_vcn_enc_hevc_get_slice_ctrl_param(struct radeon_encoder *enc,
       num_ctbs_in_slice;
 }
 
+static void radeon_vcn_enc_hevc_get_output_format_param(struct radeon_encoder *enc,
+                                                        struct pipe_h265_enc_picture_desc *pic)
+{
+   switch (enc->enc_pic.bit_depth_luma_minus8) {
+   case 2: /* 10 bits */
+      enc->enc_pic.enc_output_format.output_color_volume = RENCODE_COLOR_VOLUME_G22_BT709;
+      enc->enc_pic.enc_output_format.output_color_range = RENCODE_COLOR_RANGE_FULL;
+      enc->enc_pic.enc_output_format.output_chroma_location = RENCODE_CHROMA_LOCATION_INTERSTITIAL;
+      enc->enc_pic.enc_output_format.output_color_bit_depth = RENCODE_COLOR_BIT_DEPTH_10_BIT;
+      break;
+   default: /* 8 bits */
+      enc->enc_pic.enc_output_format.output_color_volume = RENCODE_COLOR_VOLUME_G22_BT709;
+      enc->enc_pic.enc_output_format.output_color_range = RENCODE_COLOR_RANGE_FULL;
+      enc->enc_pic.enc_output_format.output_chroma_location = RENCODE_CHROMA_LOCATION_INTERSTITIAL;
+      enc->enc_pic.enc_output_format.output_color_bit_depth = RENCODE_COLOR_BIT_DEPTH_8_BIT;
+      break;
+   }
+}
+
 static void radeon_vcn_enc_hevc_get_param(struct radeon_encoder *enc,
                                           struct pipe_h265_enc_picture_desc *pic)
 {
@@ -437,6 +488,8 @@ static void radeon_vcn_enc_hevc_get_param(struct radeon_encoder *enc,
    radeon_vcn_enc_hevc_get_rc_param(enc, pic);
    radeon_vcn_enc_hevc_get_vui_param(enc, pic);
    radeon_vcn_enc_hevc_get_slice_ctrl_param(enc, pic);
+   radeon_vcn_enc_get_input_format_param(enc, &pic->base);
+   radeon_vcn_enc_hevc_get_output_format_param(enc, pic);
 }
 
 static void radeon_vcn_enc_get_param(struct radeon_encoder *enc, struct pipe_picture_desc *picture)
index f3c56f3..2c88939 100644 (file)
 #define PIPE_H265_ENC_CTB_SIZE                                                      64
 #define PIPE_H264_MB_SIZE                                                           16
 
+#define RENCODE_COLOR_VOLUME_G22_BT709                                               0
+
+#define RENCODE_COLOR_RANGE_FULL                                                     0
+#define RENCODE_CHROMA_LOCATION_INTERSTITIAL                                         0
+
+#define RENCODE_COLOR_BIT_DEPTH_8_BIT                                                0
+#define RENCODE_COLOR_BIT_DEPTH_10_BIT                                               1
+
+#define RENCODE_CHROMA_SUBSAMPLING_4_2_0                                             0
+
+#define RENCODE_COLOR_PACKING_FORMAT_NV12                                            0
+#define RENCODE_COLOR_PACKING_FORMAT_P010                                            1
+
+#define RENCODE_COLOR_SPACE_YUV                                                      0
+
 #define PIPE_ALIGN_IN_BLOCK_SIZE(value, align) (((value) + ((align) - 1))/(align))
 
 #define RADEON_ENC_CS(value) (enc->cs.current.buf[enc->cs.current.cdw++] = (value))
@@ -496,6 +511,25 @@ typedef struct rvcn_enc_vui_info_s
    uint32_t time_scale;
 }rvcn_enc_vui_info;
 
+typedef struct rvcn_enc_input_format_s
+{
+   uint32_t input_color_volume;
+   uint32_t input_color_space;
+   uint32_t input_color_range;
+   uint32_t input_chroma_subsampling;
+   uint32_t input_chroma_location;
+   uint32_t input_color_bit_depth;
+   uint32_t input_color_packing_format;
+} rvcn_enc_input_format_t;
+
+typedef struct rvcn_enc_output_format_s
+{
+   uint32_t output_color_volume;
+   uint32_t output_color_range;
+   uint32_t output_chroma_location;  /* chroma location to luma */
+   uint32_t output_color_bit_depth;
+} rvcn_enc_output_format_t;
+
 typedef void (*radeon_enc_get_buffer)(struct pipe_resource *resource, struct pb_buffer **handle,
                                       struct radeon_surf **surface);
 
@@ -573,6 +607,8 @@ struct radeon_enc_pic {
    rvcn_enc_intra_refresh_t intra_ref;
    rvcn_enc_encode_params_t enc_params;
    rvcn_enc_stats_t enc_statistics;
+   rvcn_enc_input_format_t enc_input_format;
+   rvcn_enc_output_format_t enc_output_format;
 };
 
 struct radeon_encoder {
index 1dc5c85..0ca223f 100644 (file)
 #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_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_op_preset(struct radeon_encoder *enc)
 {
    uint32_t preset_mode;
@@ -432,40 +423,23 @@ static void radeon_enc_nalu_pps_hevc(struct radeon_encoder *enc)
 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_CS(enc->enc_pic.enc_input_format.input_color_volume);
+   RADEON_ENC_CS(enc->enc_pic.enc_input_format.input_color_space);
+   RADEON_ENC_CS(enc->enc_pic.enc_input_format.input_color_range);
+   RADEON_ENC_CS(enc->enc_pic.enc_input_format.input_chroma_subsampling);
+   RADEON_ENC_CS(enc->enc_pic.enc_input_format.input_chroma_location);
+   RADEON_ENC_CS(enc->enc_pic.enc_input_format.input_color_bit_depth);
+   RADEON_ENC_CS(enc->enc_pic.enc_input_format.input_color_packing_format);
    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_CS(enc->enc_pic.enc_output_format.output_color_volume);
+   RADEON_ENC_CS(enc->enc_pic.enc_output_format.output_color_range);
+   RADEON_ENC_CS(enc->enc_pic.enc_output_format.output_chroma_location);
+   RADEON_ENC_CS(enc->enc_pic.enc_output_format.output_color_bit_depth);
    RADEON_ENC_END();
 }
 
index 6c6f225..a053be2 100644 (file)
@@ -870,6 +870,13 @@ static bool si_vid_is_format_supported(struct pipe_screen *screen, enum pipe_for
       }
    }
 
+   /* support 10 bit input for encoding on some of the chips with vcn 2.0 and up */
+   if (profile == PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH &&
+       entrypoint == PIPE_VIDEO_ENTRYPOINT_ENCODE &&
+       sscreen->info.family >= CHIP_RENOIR) {
+      return (format == PIPE_FORMAT_P010 || format == PIPE_FORMAT_NV12);
+   }
+
    /* we can only handle this one with UVD */
    if (profile != PIPE_VIDEO_PROFILE_UNKNOWN)
       return format == PIPE_FORMAT_NV12;