1bf215546Sopenharmony_ci/************************************************************************** 2bf215546Sopenharmony_ci * 3bf215546Sopenharmony_ci * Copyright 2018 Advanced Micro Devices, Inc. 4bf215546Sopenharmony_ci * All Rights Reserved. 5bf215546Sopenharmony_ci * 6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the 8bf215546Sopenharmony_ci * "Software"), to deal in the Software without restriction, including 9bf215546Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish, 10bf215546Sopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to 11bf215546Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to 12bf215546Sopenharmony_ci * the following conditions: 13bf215546Sopenharmony_ci * 14bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the 15bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions 16bf215546Sopenharmony_ci * of the Software. 17bf215546Sopenharmony_ci * 18bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21bf215546Sopenharmony_ci * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR 22bf215546Sopenharmony_ci * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23bf215546Sopenharmony_ci * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24bf215546Sopenharmony_ci * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25bf215546Sopenharmony_ci * 26bf215546Sopenharmony_ci **************************************************************************/ 27bf215546Sopenharmony_ci 28bf215546Sopenharmony_ci#include "radeon_uvd_enc.h" 29bf215546Sopenharmony_ci 30bf215546Sopenharmony_ci#include "pipe/p_video_codec.h" 31bf215546Sopenharmony_ci#include "radeon_video.h" 32bf215546Sopenharmony_ci#include "radeonsi/si_pipe.h" 33bf215546Sopenharmony_ci#include "util/u_memory.h" 34bf215546Sopenharmony_ci#include "util/u_video.h" 35bf215546Sopenharmony_ci#include "vl/vl_video_buffer.h" 36bf215546Sopenharmony_ci 37bf215546Sopenharmony_ci#include <stdio.h> 38bf215546Sopenharmony_ci 39bf215546Sopenharmony_ci#define UVD_HEVC_LEVEL_1 30 40bf215546Sopenharmony_ci#define UVD_HEVC_LEVEL_2 60 41bf215546Sopenharmony_ci#define UVD_HEVC_LEVEL_2_1 63 42bf215546Sopenharmony_ci#define UVD_HEVC_LEVEL_3 90 43bf215546Sopenharmony_ci#define UVD_HEVC_LEVEL_3_1 93 44bf215546Sopenharmony_ci#define UVD_HEVC_LEVEL_4 120 45bf215546Sopenharmony_ci#define UVD_HEVC_LEVEL_4_1 123 46bf215546Sopenharmony_ci#define UVD_HEVC_LEVEL_5 150 47bf215546Sopenharmony_ci#define UVD_HEVC_LEVEL_5_1 153 48bf215546Sopenharmony_ci#define UVD_HEVC_LEVEL_5_2 156 49bf215546Sopenharmony_ci#define UVD_HEVC_LEVEL_6 180 50bf215546Sopenharmony_ci#define UVD_HEVC_LEVEL_6_1 183 51bf215546Sopenharmony_ci#define UVD_HEVC_LEVEL_6_2 186 52bf215546Sopenharmony_ci 53bf215546Sopenharmony_cistatic void radeon_uvd_enc_get_param(struct radeon_uvd_encoder *enc, 54bf215546Sopenharmony_ci struct pipe_h265_enc_picture_desc *pic) 55bf215546Sopenharmony_ci{ 56bf215546Sopenharmony_ci enc->enc_pic.picture_type = pic->picture_type; 57bf215546Sopenharmony_ci enc->enc_pic.frame_num = pic->frame_num; 58bf215546Sopenharmony_ci enc->enc_pic.pic_order_cnt = pic->pic_order_cnt; 59bf215546Sopenharmony_ci enc->enc_pic.pic_order_cnt_type = pic->pic_order_cnt_type; 60bf215546Sopenharmony_ci enc->enc_pic.not_referenced = pic->not_referenced; 61bf215546Sopenharmony_ci enc->enc_pic.is_iframe = (pic->picture_type == PIPE_H2645_ENC_PICTURE_TYPE_IDR) || 62bf215546Sopenharmony_ci (pic->picture_type == PIPE_H2645_ENC_PICTURE_TYPE_I); 63bf215546Sopenharmony_ci 64bf215546Sopenharmony_ci if (pic->seq.conformance_window_flag) { 65bf215546Sopenharmony_ci enc->enc_pic.crop_left = pic->seq.conf_win_left_offset; 66bf215546Sopenharmony_ci enc->enc_pic.crop_right = pic->seq.conf_win_right_offset; 67bf215546Sopenharmony_ci enc->enc_pic.crop_top = pic->seq.conf_win_top_offset; 68bf215546Sopenharmony_ci enc->enc_pic.crop_bottom = pic->seq.conf_win_bottom_offset; 69bf215546Sopenharmony_ci } else { 70bf215546Sopenharmony_ci enc->enc_pic.crop_left = 0; 71bf215546Sopenharmony_ci enc->enc_pic.crop_right = (align(enc->base.width, 16) - enc->base.width) / 2; 72bf215546Sopenharmony_ci enc->enc_pic.crop_top = 0; 73bf215546Sopenharmony_ci enc->enc_pic.crop_bottom = (align(enc->base.height, 16) - enc->base.height) / 2; 74bf215546Sopenharmony_ci } 75bf215546Sopenharmony_ci 76bf215546Sopenharmony_ci enc->enc_pic.general_tier_flag = pic->seq.general_tier_flag; 77bf215546Sopenharmony_ci enc->enc_pic.general_profile_idc = pic->seq.general_profile_idc; 78bf215546Sopenharmony_ci enc->enc_pic.general_level_idc = pic->seq.general_level_idc; 79bf215546Sopenharmony_ci enc->enc_pic.max_poc = MAX2(16, util_next_power_of_two(pic->seq.intra_period)); 80bf215546Sopenharmony_ci enc->enc_pic.log2_max_poc = 0; 81bf215546Sopenharmony_ci for (int i = enc->enc_pic.max_poc; i != 0; enc->enc_pic.log2_max_poc++) 82bf215546Sopenharmony_ci i = (i >> 1); 83bf215546Sopenharmony_ci enc->enc_pic.chroma_format_idc = pic->seq.chroma_format_idc; 84bf215546Sopenharmony_ci enc->enc_pic.pic_width_in_luma_samples = pic->seq.pic_width_in_luma_samples; 85bf215546Sopenharmony_ci enc->enc_pic.pic_height_in_luma_samples = pic->seq.pic_height_in_luma_samples; 86bf215546Sopenharmony_ci enc->enc_pic.log2_diff_max_min_luma_coding_block_size = 87bf215546Sopenharmony_ci pic->seq.log2_diff_max_min_luma_coding_block_size; 88bf215546Sopenharmony_ci enc->enc_pic.log2_min_transform_block_size_minus2 = 89bf215546Sopenharmony_ci pic->seq.log2_min_transform_block_size_minus2; 90bf215546Sopenharmony_ci enc->enc_pic.log2_diff_max_min_transform_block_size = 91bf215546Sopenharmony_ci pic->seq.log2_diff_max_min_transform_block_size; 92bf215546Sopenharmony_ci enc->enc_pic.max_transform_hierarchy_depth_inter = pic->seq.max_transform_hierarchy_depth_inter; 93bf215546Sopenharmony_ci enc->enc_pic.max_transform_hierarchy_depth_intra = pic->seq.max_transform_hierarchy_depth_intra; 94bf215546Sopenharmony_ci enc->enc_pic.log2_parallel_merge_level_minus2 = pic->pic.log2_parallel_merge_level_minus2; 95bf215546Sopenharmony_ci enc->enc_pic.bit_depth_luma_minus8 = pic->seq.bit_depth_luma_minus8; 96bf215546Sopenharmony_ci enc->enc_pic.bit_depth_chroma_minus8 = pic->seq.bit_depth_chroma_minus8; 97bf215546Sopenharmony_ci enc->enc_pic.nal_unit_type = pic->pic.nal_unit_type; 98bf215546Sopenharmony_ci enc->enc_pic.max_num_merge_cand = pic->slice.max_num_merge_cand; 99bf215546Sopenharmony_ci enc->enc_pic.sample_adaptive_offset_enabled_flag = pic->seq.sample_adaptive_offset_enabled_flag; 100bf215546Sopenharmony_ci enc->enc_pic.pcm_enabled_flag = 0; /*HW not support PCM */ 101bf215546Sopenharmony_ci enc->enc_pic.sps_temporal_mvp_enabled_flag = pic->seq.sps_temporal_mvp_enabled_flag; 102bf215546Sopenharmony_ci} 103bf215546Sopenharmony_ci 104bf215546Sopenharmony_cistatic void flush(struct radeon_uvd_encoder *enc) 105bf215546Sopenharmony_ci{ 106bf215546Sopenharmony_ci enc->ws->cs_flush(&enc->cs, PIPE_FLUSH_ASYNC, NULL); 107bf215546Sopenharmony_ci} 108bf215546Sopenharmony_ci 109bf215546Sopenharmony_cistatic void radeon_uvd_enc_flush(struct pipe_video_codec *encoder) 110bf215546Sopenharmony_ci{ 111bf215546Sopenharmony_ci struct radeon_uvd_encoder *enc = (struct radeon_uvd_encoder *)encoder; 112bf215546Sopenharmony_ci flush(enc); 113bf215546Sopenharmony_ci} 114bf215546Sopenharmony_ci 115bf215546Sopenharmony_cistatic void radeon_uvd_enc_cs_flush(void *ctx, unsigned flags, struct pipe_fence_handle **fence) 116bf215546Sopenharmony_ci{ 117bf215546Sopenharmony_ci // just ignored 118bf215546Sopenharmony_ci} 119bf215546Sopenharmony_ci 120bf215546Sopenharmony_cistatic unsigned get_cpb_num(struct radeon_uvd_encoder *enc) 121bf215546Sopenharmony_ci{ 122bf215546Sopenharmony_ci unsigned w = align(enc->base.width, 16) / 16; 123bf215546Sopenharmony_ci unsigned h = align(enc->base.height, 16) / 16; 124bf215546Sopenharmony_ci unsigned dpb; 125bf215546Sopenharmony_ci 126bf215546Sopenharmony_ci switch (enc->base.level) { 127bf215546Sopenharmony_ci case UVD_HEVC_LEVEL_1: 128bf215546Sopenharmony_ci dpb = 36864; 129bf215546Sopenharmony_ci break; 130bf215546Sopenharmony_ci 131bf215546Sopenharmony_ci case UVD_HEVC_LEVEL_2: 132bf215546Sopenharmony_ci dpb = 122880; 133bf215546Sopenharmony_ci break; 134bf215546Sopenharmony_ci 135bf215546Sopenharmony_ci case UVD_HEVC_LEVEL_2_1: 136bf215546Sopenharmony_ci dpb = 245760; 137bf215546Sopenharmony_ci break; 138bf215546Sopenharmony_ci 139bf215546Sopenharmony_ci case UVD_HEVC_LEVEL_3: 140bf215546Sopenharmony_ci dpb = 552960; 141bf215546Sopenharmony_ci break; 142bf215546Sopenharmony_ci 143bf215546Sopenharmony_ci case UVD_HEVC_LEVEL_3_1: 144bf215546Sopenharmony_ci dpb = 983040; 145bf215546Sopenharmony_ci break; 146bf215546Sopenharmony_ci 147bf215546Sopenharmony_ci case UVD_HEVC_LEVEL_4: 148bf215546Sopenharmony_ci case UVD_HEVC_LEVEL_4_1: 149bf215546Sopenharmony_ci dpb = 2228224; 150bf215546Sopenharmony_ci break; 151bf215546Sopenharmony_ci 152bf215546Sopenharmony_ci case UVD_HEVC_LEVEL_5: 153bf215546Sopenharmony_ci case UVD_HEVC_LEVEL_5_1: 154bf215546Sopenharmony_ci case UVD_HEVC_LEVEL_5_2: 155bf215546Sopenharmony_ci dpb = 8912896; 156bf215546Sopenharmony_ci break; 157bf215546Sopenharmony_ci 158bf215546Sopenharmony_ci case UVD_HEVC_LEVEL_6: 159bf215546Sopenharmony_ci case UVD_HEVC_LEVEL_6_1: 160bf215546Sopenharmony_ci case UVD_HEVC_LEVEL_6_2: 161bf215546Sopenharmony_ci default: 162bf215546Sopenharmony_ci dpb = 35651584; 163bf215546Sopenharmony_ci break; 164bf215546Sopenharmony_ci } 165bf215546Sopenharmony_ci 166bf215546Sopenharmony_ci return MIN2(dpb / (w * h), 16); 167bf215546Sopenharmony_ci} 168bf215546Sopenharmony_ci 169bf215546Sopenharmony_cistatic void radeon_uvd_enc_begin_frame(struct pipe_video_codec *encoder, 170bf215546Sopenharmony_ci struct pipe_video_buffer *source, 171bf215546Sopenharmony_ci struct pipe_picture_desc *picture) 172bf215546Sopenharmony_ci{ 173bf215546Sopenharmony_ci struct radeon_uvd_encoder *enc = (struct radeon_uvd_encoder *)encoder; 174bf215546Sopenharmony_ci struct vl_video_buffer *vid_buf = (struct vl_video_buffer *)source; 175bf215546Sopenharmony_ci 176bf215546Sopenharmony_ci radeon_uvd_enc_get_param(enc, (struct pipe_h265_enc_picture_desc *)picture); 177bf215546Sopenharmony_ci 178bf215546Sopenharmony_ci enc->get_buffer(vid_buf->resources[0], &enc->handle, &enc->luma); 179bf215546Sopenharmony_ci enc->get_buffer(vid_buf->resources[1], NULL, &enc->chroma); 180bf215546Sopenharmony_ci 181bf215546Sopenharmony_ci enc->need_feedback = false; 182bf215546Sopenharmony_ci 183bf215546Sopenharmony_ci if (!enc->stream_handle) { 184bf215546Sopenharmony_ci struct rvid_buffer fb; 185bf215546Sopenharmony_ci enc->stream_handle = si_vid_alloc_stream_handle(); 186bf215546Sopenharmony_ci enc->si = CALLOC_STRUCT(rvid_buffer); 187bf215546Sopenharmony_ci si_vid_create_buffer(enc->screen, enc->si, 128 * 1024, PIPE_USAGE_STAGING); 188bf215546Sopenharmony_ci si_vid_create_buffer(enc->screen, &fb, 4096, PIPE_USAGE_STAGING); 189bf215546Sopenharmony_ci enc->fb = &fb; 190bf215546Sopenharmony_ci enc->begin(enc, picture); 191bf215546Sopenharmony_ci flush(enc); 192bf215546Sopenharmony_ci si_vid_destroy_buffer(&fb); 193bf215546Sopenharmony_ci } 194bf215546Sopenharmony_ci} 195bf215546Sopenharmony_ci 196bf215546Sopenharmony_cistatic void radeon_uvd_enc_encode_bitstream(struct pipe_video_codec *encoder, 197bf215546Sopenharmony_ci struct pipe_video_buffer *source, 198bf215546Sopenharmony_ci struct pipe_resource *destination, void **fb) 199bf215546Sopenharmony_ci{ 200bf215546Sopenharmony_ci struct radeon_uvd_encoder *enc = (struct radeon_uvd_encoder *)encoder; 201bf215546Sopenharmony_ci enc->get_buffer(destination, &enc->bs_handle, NULL); 202bf215546Sopenharmony_ci enc->bs_size = destination->width0; 203bf215546Sopenharmony_ci 204bf215546Sopenharmony_ci *fb = enc->fb = CALLOC_STRUCT(rvid_buffer); 205bf215546Sopenharmony_ci 206bf215546Sopenharmony_ci if (!si_vid_create_buffer(enc->screen, enc->fb, 4096, PIPE_USAGE_STAGING)) { 207bf215546Sopenharmony_ci RVID_ERR("Can't create feedback buffer.\n"); 208bf215546Sopenharmony_ci return; 209bf215546Sopenharmony_ci } 210bf215546Sopenharmony_ci 211bf215546Sopenharmony_ci enc->need_feedback = true; 212bf215546Sopenharmony_ci enc->encode(enc); 213bf215546Sopenharmony_ci} 214bf215546Sopenharmony_ci 215bf215546Sopenharmony_cistatic void radeon_uvd_enc_end_frame(struct pipe_video_codec *encoder, 216bf215546Sopenharmony_ci struct pipe_video_buffer *source, 217bf215546Sopenharmony_ci struct pipe_picture_desc *picture) 218bf215546Sopenharmony_ci{ 219bf215546Sopenharmony_ci struct radeon_uvd_encoder *enc = (struct radeon_uvd_encoder *)encoder; 220bf215546Sopenharmony_ci flush(enc); 221bf215546Sopenharmony_ci} 222bf215546Sopenharmony_ci 223bf215546Sopenharmony_cistatic void radeon_uvd_enc_destroy(struct pipe_video_codec *encoder) 224bf215546Sopenharmony_ci{ 225bf215546Sopenharmony_ci struct radeon_uvd_encoder *enc = (struct radeon_uvd_encoder *)encoder; 226bf215546Sopenharmony_ci 227bf215546Sopenharmony_ci if (enc->stream_handle) { 228bf215546Sopenharmony_ci struct rvid_buffer fb; 229bf215546Sopenharmony_ci enc->need_feedback = false; 230bf215546Sopenharmony_ci si_vid_create_buffer(enc->screen, &fb, 512, PIPE_USAGE_STAGING); 231bf215546Sopenharmony_ci enc->fb = &fb; 232bf215546Sopenharmony_ci enc->destroy(enc); 233bf215546Sopenharmony_ci flush(enc); 234bf215546Sopenharmony_ci si_vid_destroy_buffer(&fb); 235bf215546Sopenharmony_ci } 236bf215546Sopenharmony_ci 237bf215546Sopenharmony_ci si_vid_destroy_buffer(&enc->cpb); 238bf215546Sopenharmony_ci enc->ws->cs_destroy(&enc->cs); 239bf215546Sopenharmony_ci FREE(enc); 240bf215546Sopenharmony_ci} 241bf215546Sopenharmony_ci 242bf215546Sopenharmony_cistatic void radeon_uvd_enc_get_feedback(struct pipe_video_codec *encoder, void *feedback, 243bf215546Sopenharmony_ci unsigned *size) 244bf215546Sopenharmony_ci{ 245bf215546Sopenharmony_ci struct radeon_uvd_encoder *enc = (struct radeon_uvd_encoder *)encoder; 246bf215546Sopenharmony_ci struct rvid_buffer *fb = feedback; 247bf215546Sopenharmony_ci 248bf215546Sopenharmony_ci if (NULL != size) { 249bf215546Sopenharmony_ci radeon_uvd_enc_feedback_t *fb_data = (radeon_uvd_enc_feedback_t *)enc->ws->buffer_map( 250bf215546Sopenharmony_ci enc->ws, fb->res->buf, &enc->cs, PIPE_MAP_READ_WRITE | RADEON_MAP_TEMPORARY); 251bf215546Sopenharmony_ci 252bf215546Sopenharmony_ci if (!fb_data->status) 253bf215546Sopenharmony_ci *size = fb_data->bitstream_size; 254bf215546Sopenharmony_ci else 255bf215546Sopenharmony_ci *size = 0; 256bf215546Sopenharmony_ci enc->ws->buffer_unmap(enc->ws, fb->res->buf); 257bf215546Sopenharmony_ci } 258bf215546Sopenharmony_ci 259bf215546Sopenharmony_ci si_vid_destroy_buffer(fb); 260bf215546Sopenharmony_ci FREE(fb); 261bf215546Sopenharmony_ci} 262bf215546Sopenharmony_ci 263bf215546Sopenharmony_cistruct pipe_video_codec *radeon_uvd_create_encoder(struct pipe_context *context, 264bf215546Sopenharmony_ci const struct pipe_video_codec *templ, 265bf215546Sopenharmony_ci struct radeon_winsys *ws, 266bf215546Sopenharmony_ci radeon_uvd_enc_get_buffer get_buffer) 267bf215546Sopenharmony_ci{ 268bf215546Sopenharmony_ci struct si_screen *sscreen = (struct si_screen *)context->screen; 269bf215546Sopenharmony_ci struct si_context *sctx = (struct si_context *)context; 270bf215546Sopenharmony_ci struct radeon_uvd_encoder *enc; 271bf215546Sopenharmony_ci struct pipe_video_buffer *tmp_buf, templat = {}; 272bf215546Sopenharmony_ci struct radeon_surf *tmp_surf; 273bf215546Sopenharmony_ci unsigned cpb_size; 274bf215546Sopenharmony_ci 275bf215546Sopenharmony_ci if (!si_radeon_uvd_enc_supported(sscreen)) { 276bf215546Sopenharmony_ci RVID_ERR("Unsupported UVD ENC fw version loaded!\n"); 277bf215546Sopenharmony_ci return NULL; 278bf215546Sopenharmony_ci } 279bf215546Sopenharmony_ci 280bf215546Sopenharmony_ci enc = CALLOC_STRUCT(radeon_uvd_encoder); 281bf215546Sopenharmony_ci 282bf215546Sopenharmony_ci if (!enc) 283bf215546Sopenharmony_ci return NULL; 284bf215546Sopenharmony_ci 285bf215546Sopenharmony_ci enc->base = *templ; 286bf215546Sopenharmony_ci enc->base.context = context; 287bf215546Sopenharmony_ci enc->base.destroy = radeon_uvd_enc_destroy; 288bf215546Sopenharmony_ci enc->base.begin_frame = radeon_uvd_enc_begin_frame; 289bf215546Sopenharmony_ci enc->base.encode_bitstream = radeon_uvd_enc_encode_bitstream; 290bf215546Sopenharmony_ci enc->base.end_frame = radeon_uvd_enc_end_frame; 291bf215546Sopenharmony_ci enc->base.flush = radeon_uvd_enc_flush; 292bf215546Sopenharmony_ci enc->base.get_feedback = radeon_uvd_enc_get_feedback; 293bf215546Sopenharmony_ci enc->get_buffer = get_buffer; 294bf215546Sopenharmony_ci enc->bits_in_shifter = 0; 295bf215546Sopenharmony_ci enc->screen = context->screen; 296bf215546Sopenharmony_ci enc->ws = ws; 297bf215546Sopenharmony_ci 298bf215546Sopenharmony_ci if (!ws->cs_create(&enc->cs, sctx->ctx, AMD_IP_UVD_ENC, radeon_uvd_enc_cs_flush, enc, false)) { 299bf215546Sopenharmony_ci RVID_ERR("Can't get command submission context.\n"); 300bf215546Sopenharmony_ci goto error; 301bf215546Sopenharmony_ci } 302bf215546Sopenharmony_ci 303bf215546Sopenharmony_ci struct rvid_buffer si; 304bf215546Sopenharmony_ci si_vid_create_buffer(enc->screen, &si, 128 * 1024, PIPE_USAGE_STAGING); 305bf215546Sopenharmony_ci enc->si = &si; 306bf215546Sopenharmony_ci 307bf215546Sopenharmony_ci templat.buffer_format = PIPE_FORMAT_NV12; 308bf215546Sopenharmony_ci templat.width = enc->base.width; 309bf215546Sopenharmony_ci templat.height = enc->base.height; 310bf215546Sopenharmony_ci templat.interlaced = false; 311bf215546Sopenharmony_ci 312bf215546Sopenharmony_ci if (!(tmp_buf = context->create_video_buffer(context, &templat))) { 313bf215546Sopenharmony_ci RVID_ERR("Can't create video buffer.\n"); 314bf215546Sopenharmony_ci goto error; 315bf215546Sopenharmony_ci } 316bf215546Sopenharmony_ci 317bf215546Sopenharmony_ci enc->cpb_num = get_cpb_num(enc); 318bf215546Sopenharmony_ci 319bf215546Sopenharmony_ci if (!enc->cpb_num) 320bf215546Sopenharmony_ci goto error; 321bf215546Sopenharmony_ci 322bf215546Sopenharmony_ci get_buffer(((struct vl_video_buffer *)tmp_buf)->resources[0], NULL, &tmp_surf); 323bf215546Sopenharmony_ci 324bf215546Sopenharmony_ci cpb_size = (sscreen->info.gfx_level < GFX9) 325bf215546Sopenharmony_ci ? align(tmp_surf->u.legacy.level[0].nblk_x * tmp_surf->bpe, 128) * 326bf215546Sopenharmony_ci align(tmp_surf->u.legacy.level[0].nblk_y, 32) 327bf215546Sopenharmony_ci : align(tmp_surf->u.gfx9.surf_pitch * tmp_surf->bpe, 256) * 328bf215546Sopenharmony_ci align(tmp_surf->u.gfx9.surf_height, 32); 329bf215546Sopenharmony_ci 330bf215546Sopenharmony_ci cpb_size = cpb_size * 3 / 2; 331bf215546Sopenharmony_ci cpb_size = cpb_size * enc->cpb_num; 332bf215546Sopenharmony_ci tmp_buf->destroy(tmp_buf); 333bf215546Sopenharmony_ci 334bf215546Sopenharmony_ci if (!si_vid_create_buffer(enc->screen, &enc->cpb, cpb_size, PIPE_USAGE_DEFAULT)) { 335bf215546Sopenharmony_ci RVID_ERR("Can't create CPB buffer.\n"); 336bf215546Sopenharmony_ci goto error; 337bf215546Sopenharmony_ci } 338bf215546Sopenharmony_ci 339bf215546Sopenharmony_ci radeon_uvd_enc_1_1_init(enc); 340bf215546Sopenharmony_ci 341bf215546Sopenharmony_ci return &enc->base; 342bf215546Sopenharmony_ci 343bf215546Sopenharmony_cierror: 344bf215546Sopenharmony_ci enc->ws->cs_destroy(&enc->cs); 345bf215546Sopenharmony_ci 346bf215546Sopenharmony_ci si_vid_destroy_buffer(&enc->cpb); 347bf215546Sopenharmony_ci 348bf215546Sopenharmony_ci FREE(enc); 349bf215546Sopenharmony_ci return NULL; 350bf215546Sopenharmony_ci} 351bf215546Sopenharmony_ci 352bf215546Sopenharmony_cibool si_radeon_uvd_enc_supported(struct si_screen *sscreen) 353bf215546Sopenharmony_ci{ 354bf215546Sopenharmony_ci return sscreen->info.ip[AMD_IP_UVD_ENC].num_queues; 355bf215546Sopenharmony_ci} 356