1 /**************************************************************************
3 * Copyright 2017 Advanced Micro Devices, Inc.
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21 * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
31 #include "pipe/p_video_codec.h"
33 #include "util/u_memory.h"
34 #include "util/u_video.h"
36 #include "vl/vl_mpeg12_decoder.h"
38 #include "radeonsi/si_pipe.h"
39 #include "radeon_video.h"
40 #include "radeon_vcn_dec.h"
41 #include "vl/vl_probs_table.h"
43 #define FB_BUFFER_OFFSET 0x1000
44 #define FB_BUFFER_SIZE 2048
45 #define IT_SCALING_TABLE_SIZE 992
46 #define VP9_PROBS_TABLE_SIZE (RDECODE_VP9_PROBS_DATA_SIZE + 256)
47 #define RDECODE_SESSION_CONTEXT_SIZE (128 * 1024)
49 #define RDECODE_GPCOM_VCPU_CMD 0x2070c
50 #define RDECODE_GPCOM_VCPU_DATA0 0x20710
51 #define RDECODE_GPCOM_VCPU_DATA1 0x20714
52 #define RDECODE_ENGINE_CNTL 0x20718
55 #define NUM_MPEG2_REFS 6
56 #define NUM_H264_REFS 17
57 #define NUM_VC1_REFS 5
59 struct radeon_decoder
{
60 struct pipe_video_codec base
;
62 unsigned stream_handle
;
64 unsigned frame_number
;
66 struct pipe_screen
*screen
;
67 struct radeon_winsys
*ws
;
68 struct radeon_winsys_cs
*cs
;
76 struct rvid_buffer msg_fb_it_probs_buffers
[NUM_BUFFERS
];
77 struct rvid_buffer bs_buffers
[NUM_BUFFERS
];
78 struct rvid_buffer dpb
;
79 struct rvid_buffer ctx
;
80 struct rvid_buffer sessionctx
;
84 void *render_pic_list
[16];
87 static rvcn_dec_message_avc_t
get_h264_msg(struct radeon_decoder
*dec
,
88 struct pipe_h264_picture_desc
*pic
)
90 rvcn_dec_message_avc_t result
;
92 memset(&result
, 0, sizeof(result
));
93 switch (pic
->base
.profile
) {
94 case PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE
:
95 result
.profile
= RDECODE_H264_PROFILE_BASELINE
;
98 case PIPE_VIDEO_PROFILE_MPEG4_AVC_MAIN
:
99 result
.profile
= RDECODE_H264_PROFILE_MAIN
;
102 case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH
:
103 result
.profile
= RDECODE_H264_PROFILE_HIGH
;
111 result
.level
= dec
->base
.level
;
113 result
.sps_info_flags
= 0;
114 result
.sps_info_flags
|= pic
->pps
->sps
->direct_8x8_inference_flag
<< 0;
115 result
.sps_info_flags
|= pic
->pps
->sps
->mb_adaptive_frame_field_flag
<< 1;
116 result
.sps_info_flags
|= pic
->pps
->sps
->frame_mbs_only_flag
<< 2;
117 result
.sps_info_flags
|= pic
->pps
->sps
->delta_pic_order_always_zero_flag
<< 3;
118 result
.sps_info_flags
|= 1 << RDECODE_SPS_INFO_H264_EXTENSION_SUPPORT_FLAG_SHIFT
;
120 result
.bit_depth_luma_minus8
= pic
->pps
->sps
->bit_depth_luma_minus8
;
121 result
.bit_depth_chroma_minus8
= pic
->pps
->sps
->bit_depth_chroma_minus8
;
122 result
.log2_max_frame_num_minus4
= pic
->pps
->sps
->log2_max_frame_num_minus4
;
123 result
.pic_order_cnt_type
= pic
->pps
->sps
->pic_order_cnt_type
;
124 result
.log2_max_pic_order_cnt_lsb_minus4
=
125 pic
->pps
->sps
->log2_max_pic_order_cnt_lsb_minus4
;
127 switch (dec
->base
.chroma_format
) {
128 case PIPE_VIDEO_CHROMA_FORMAT_NONE
:
130 case PIPE_VIDEO_CHROMA_FORMAT_400
:
131 result
.chroma_format
= 0;
133 case PIPE_VIDEO_CHROMA_FORMAT_420
:
134 result
.chroma_format
= 1;
136 case PIPE_VIDEO_CHROMA_FORMAT_422
:
137 result
.chroma_format
= 2;
139 case PIPE_VIDEO_CHROMA_FORMAT_444
:
140 result
.chroma_format
= 3;
144 result
.pps_info_flags
= 0;
145 result
.pps_info_flags
|= pic
->pps
->transform_8x8_mode_flag
<< 0;
146 result
.pps_info_flags
|= pic
->pps
->redundant_pic_cnt_present_flag
<< 1;
147 result
.pps_info_flags
|= pic
->pps
->constrained_intra_pred_flag
<< 2;
148 result
.pps_info_flags
|= pic
->pps
->deblocking_filter_control_present_flag
<< 3;
149 result
.pps_info_flags
|= pic
->pps
->weighted_bipred_idc
<< 4;
150 result
.pps_info_flags
|= pic
->pps
->weighted_pred_flag
<< 6;
151 result
.pps_info_flags
|= pic
->pps
->bottom_field_pic_order_in_frame_present_flag
<< 7;
152 result
.pps_info_flags
|= pic
->pps
->entropy_coding_mode_flag
<< 8;
154 result
.num_slice_groups_minus1
= pic
->pps
->num_slice_groups_minus1
;
155 result
.slice_group_map_type
= pic
->pps
->slice_group_map_type
;
156 result
.slice_group_change_rate_minus1
= pic
->pps
->slice_group_change_rate_minus1
;
157 result
.pic_init_qp_minus26
= pic
->pps
->pic_init_qp_minus26
;
158 result
.chroma_qp_index_offset
= pic
->pps
->chroma_qp_index_offset
;
159 result
.second_chroma_qp_index_offset
= pic
->pps
->second_chroma_qp_index_offset
;
161 memcpy(result
.scaling_list_4x4
, pic
->pps
->ScalingList4x4
, 6*16);
162 memcpy(result
.scaling_list_8x8
, pic
->pps
->ScalingList8x8
, 2*64);
164 memcpy(dec
->it
, result
.scaling_list_4x4
, 6*16);
165 memcpy((dec
->it
+ 96), result
.scaling_list_8x8
, 2*64);
167 result
.num_ref_frames
= pic
->num_ref_frames
;
169 result
.num_ref_idx_l0_active_minus1
= pic
->num_ref_idx_l0_active_minus1
;
170 result
.num_ref_idx_l1_active_minus1
= pic
->num_ref_idx_l1_active_minus1
;
172 result
.frame_num
= pic
->frame_num
;
173 memcpy(result
.frame_num_list
, pic
->frame_num_list
, 4*16);
174 result
.curr_field_order_cnt_list
[0] = pic
->field_order_cnt
[0];
175 result
.curr_field_order_cnt_list
[1] = pic
->field_order_cnt
[1];
176 memcpy(result
.field_order_cnt_list
, pic
->field_order_cnt_list
, 4*16*2);
178 result
.decoded_pic_idx
= pic
->frame_num
;
183 static void radeon_dec_destroy_associated_data(void *data
)
185 /* NOOP, since we only use an intptr */
188 static rvcn_dec_message_hevc_t
get_h265_msg(struct radeon_decoder
*dec
,
189 struct pipe_video_buffer
*target
,
190 struct pipe_h265_picture_desc
*pic
)
192 rvcn_dec_message_hevc_t result
;
195 memset(&result
, 0, sizeof(result
));
196 result
.sps_info_flags
= 0;
197 result
.sps_info_flags
|= pic
->pps
->sps
->scaling_list_enabled_flag
<< 0;
198 result
.sps_info_flags
|= pic
->pps
->sps
->amp_enabled_flag
<< 1;
199 result
.sps_info_flags
|= pic
->pps
->sps
->sample_adaptive_offset_enabled_flag
<< 2;
200 result
.sps_info_flags
|= pic
->pps
->sps
->pcm_enabled_flag
<< 3;
201 result
.sps_info_flags
|= pic
->pps
->sps
->pcm_loop_filter_disabled_flag
<< 4;
202 result
.sps_info_flags
|= pic
->pps
->sps
->long_term_ref_pics_present_flag
<< 5;
203 result
.sps_info_flags
|= pic
->pps
->sps
->sps_temporal_mvp_enabled_flag
<< 6;
204 result
.sps_info_flags
|= pic
->pps
->sps
->strong_intra_smoothing_enabled_flag
<< 7;
205 result
.sps_info_flags
|= pic
->pps
->sps
->separate_colour_plane_flag
<< 8;
206 if (((struct si_screen
*)dec
->screen
)->info
.family
== CHIP_CARRIZO
)
207 result
.sps_info_flags
|= 1 << 9;
208 if (pic
->UseRefPicList
== true)
209 result
.sps_info_flags
|= 1 << 10;
211 result
.chroma_format
= pic
->pps
->sps
->chroma_format_idc
;
212 result
.bit_depth_luma_minus8
= pic
->pps
->sps
->bit_depth_luma_minus8
;
213 result
.bit_depth_chroma_minus8
= pic
->pps
->sps
->bit_depth_chroma_minus8
;
214 result
.log2_max_pic_order_cnt_lsb_minus4
= pic
->pps
->sps
->log2_max_pic_order_cnt_lsb_minus4
;
215 result
.sps_max_dec_pic_buffering_minus1
= pic
->pps
->sps
->sps_max_dec_pic_buffering_minus1
;
216 result
.log2_min_luma_coding_block_size_minus3
=
217 pic
->pps
->sps
->log2_min_luma_coding_block_size_minus3
;
218 result
.log2_diff_max_min_luma_coding_block_size
=
219 pic
->pps
->sps
->log2_diff_max_min_luma_coding_block_size
;
220 result
.log2_min_transform_block_size_minus2
=
221 pic
->pps
->sps
->log2_min_transform_block_size_minus2
;
222 result
.log2_diff_max_min_transform_block_size
=
223 pic
->pps
->sps
->log2_diff_max_min_transform_block_size
;
224 result
.max_transform_hierarchy_depth_inter
=
225 pic
->pps
->sps
->max_transform_hierarchy_depth_inter
;
226 result
.max_transform_hierarchy_depth_intra
=
227 pic
->pps
->sps
->max_transform_hierarchy_depth_intra
;
228 result
.pcm_sample_bit_depth_luma_minus1
= pic
->pps
->sps
->pcm_sample_bit_depth_luma_minus1
;
229 result
.pcm_sample_bit_depth_chroma_minus1
=
230 pic
->pps
->sps
->pcm_sample_bit_depth_chroma_minus1
;
231 result
.log2_min_pcm_luma_coding_block_size_minus3
=
232 pic
->pps
->sps
->log2_min_pcm_luma_coding_block_size_minus3
;
233 result
.log2_diff_max_min_pcm_luma_coding_block_size
=
234 pic
->pps
->sps
->log2_diff_max_min_pcm_luma_coding_block_size
;
235 result
.num_short_term_ref_pic_sets
= pic
->pps
->sps
->num_short_term_ref_pic_sets
;
237 result
.pps_info_flags
= 0;
238 result
.pps_info_flags
|= pic
->pps
->dependent_slice_segments_enabled_flag
<< 0;
239 result
.pps_info_flags
|= pic
->pps
->output_flag_present_flag
<< 1;
240 result
.pps_info_flags
|= pic
->pps
->sign_data_hiding_enabled_flag
<< 2;
241 result
.pps_info_flags
|= pic
->pps
->cabac_init_present_flag
<< 3;
242 result
.pps_info_flags
|= pic
->pps
->constrained_intra_pred_flag
<< 4;
243 result
.pps_info_flags
|= pic
->pps
->transform_skip_enabled_flag
<< 5;
244 result
.pps_info_flags
|= pic
->pps
->cu_qp_delta_enabled_flag
<< 6;
245 result
.pps_info_flags
|= pic
->pps
->pps_slice_chroma_qp_offsets_present_flag
<< 7;
246 result
.pps_info_flags
|= pic
->pps
->weighted_pred_flag
<< 8;
247 result
.pps_info_flags
|= pic
->pps
->weighted_bipred_flag
<< 9;
248 result
.pps_info_flags
|= pic
->pps
->transquant_bypass_enabled_flag
<< 10;
249 result
.pps_info_flags
|= pic
->pps
->tiles_enabled_flag
<< 11;
250 result
.pps_info_flags
|= pic
->pps
->entropy_coding_sync_enabled_flag
<< 12;
251 result
.pps_info_flags
|= pic
->pps
->uniform_spacing_flag
<< 13;
252 result
.pps_info_flags
|= pic
->pps
->loop_filter_across_tiles_enabled_flag
<< 14;
253 result
.pps_info_flags
|= pic
->pps
->pps_loop_filter_across_slices_enabled_flag
<< 15;
254 result
.pps_info_flags
|= pic
->pps
->deblocking_filter_override_enabled_flag
<< 16;
255 result
.pps_info_flags
|= pic
->pps
->pps_deblocking_filter_disabled_flag
<< 17;
256 result
.pps_info_flags
|= pic
->pps
->lists_modification_present_flag
<< 18;
257 result
.pps_info_flags
|= pic
->pps
->slice_segment_header_extension_present_flag
<< 19;
259 result
.num_extra_slice_header_bits
= pic
->pps
->num_extra_slice_header_bits
;
260 result
.num_long_term_ref_pic_sps
= pic
->pps
->sps
->num_long_term_ref_pics_sps
;
261 result
.num_ref_idx_l0_default_active_minus1
= pic
->pps
->num_ref_idx_l0_default_active_minus1
;
262 result
.num_ref_idx_l1_default_active_minus1
= pic
->pps
->num_ref_idx_l1_default_active_minus1
;
263 result
.pps_cb_qp_offset
= pic
->pps
->pps_cb_qp_offset
;
264 result
.pps_cr_qp_offset
= pic
->pps
->pps_cr_qp_offset
;
265 result
.pps_beta_offset_div2
= pic
->pps
->pps_beta_offset_div2
;
266 result
.pps_tc_offset_div2
= pic
->pps
->pps_tc_offset_div2
;
267 result
.diff_cu_qp_delta_depth
= pic
->pps
->diff_cu_qp_delta_depth
;
268 result
.num_tile_columns_minus1
= pic
->pps
->num_tile_columns_minus1
;
269 result
.num_tile_rows_minus1
= pic
->pps
->num_tile_rows_minus1
;
270 result
.log2_parallel_merge_level_minus2
= pic
->pps
->log2_parallel_merge_level_minus2
;
271 result
.init_qp_minus26
= pic
->pps
->init_qp_minus26
;
273 for (i
= 0; i
< 19; ++i
)
274 result
.column_width_minus1
[i
] = pic
->pps
->column_width_minus1
[i
];
276 for (i
= 0; i
< 21; ++i
)
277 result
.row_height_minus1
[i
] = pic
->pps
->row_height_minus1
[i
];
279 result
.num_delta_pocs_ref_rps_idx
= pic
->NumDeltaPocsOfRefRpsIdx
;
280 result
.curr_poc
= pic
->CurrPicOrderCntVal
;
282 for (i
= 0 ; i
< 16 ; i
++) {
283 for (j
= 0; (pic
->ref
[j
] != NULL
) && (j
< 16) ; j
++) {
284 if (dec
->render_pic_list
[i
] == pic
->ref
[j
])
287 dec
->render_pic_list
[i
] = NULL
;
288 else if (pic
->ref
[j
+1] == NULL
)
289 dec
->render_pic_list
[i
] = NULL
;
292 for (i
= 0 ; i
< 16 ; i
++) {
293 if (dec
->render_pic_list
[i
] == NULL
) {
294 dec
->render_pic_list
[i
] = target
;
300 vl_video_buffer_set_associated_data(target
, &dec
->base
,
301 (void *)(uintptr_t)result
.curr_idx
,
302 &radeon_dec_destroy_associated_data
);
304 for (i
= 0; i
< 16; ++i
) {
305 struct pipe_video_buffer
*ref
= pic
->ref
[i
];
306 uintptr_t ref_pic
= 0;
308 result
.poc_list
[i
] = pic
->PicOrderCntVal
[i
];
311 ref_pic
= (uintptr_t)vl_video_buffer_get_associated_data(ref
, &dec
->base
);
314 result
.ref_pic_list
[i
] = ref_pic
;
317 for (i
= 0; i
< 8; ++i
) {
318 result
.ref_pic_set_st_curr_before
[i
] = 0xFF;
319 result
.ref_pic_set_st_curr_after
[i
] = 0xFF;
320 result
.ref_pic_set_lt_curr
[i
] = 0xFF;
323 for (i
= 0; i
< pic
->NumPocStCurrBefore
; ++i
)
324 result
.ref_pic_set_st_curr_before
[i
] = pic
->RefPicSetStCurrBefore
[i
];
326 for (i
= 0; i
< pic
->NumPocStCurrAfter
; ++i
)
327 result
.ref_pic_set_st_curr_after
[i
] = pic
->RefPicSetStCurrAfter
[i
];
329 for (i
= 0; i
< pic
->NumPocLtCurr
; ++i
)
330 result
.ref_pic_set_lt_curr
[i
] = pic
->RefPicSetLtCurr
[i
];
332 for (i
= 0; i
< 6; ++i
)
333 result
.ucScalingListDCCoefSizeID2
[i
] = pic
->pps
->sps
->ScalingListDCCoeff16x16
[i
];
335 for (i
= 0; i
< 2; ++i
)
336 result
.ucScalingListDCCoefSizeID3
[i
] = pic
->pps
->sps
->ScalingListDCCoeff32x32
[i
];
338 memcpy(dec
->it
, pic
->pps
->sps
->ScalingList4x4
, 6 * 16);
339 memcpy(dec
->it
+ 96, pic
->pps
->sps
->ScalingList8x8
, 6 * 64);
340 memcpy(dec
->it
+ 480, pic
->pps
->sps
->ScalingList16x16
, 6 * 64);
341 memcpy(dec
->it
+ 864, pic
->pps
->sps
->ScalingList32x32
, 2 * 64);
343 for (i
= 0 ; i
< 2 ; i
++) {
344 for (j
= 0 ; j
< 15 ; j
++)
345 result
.direct_reflist
[i
][j
] = pic
->RefPicList
[i
][j
];
348 if (pic
->base
.profile
== PIPE_VIDEO_PROFILE_HEVC_MAIN_10
) {
349 if (target
->buffer_format
== PIPE_FORMAT_P016
) {
350 result
.p010_mode
= 1;
353 result
.p010_mode
= 0;
354 result
.luma_10to8
= 5;
355 result
.chroma_10to8
= 5;
356 result
.hevc_reserved
[0] = 4; /* sclr_luma10to8 */
357 result
.hevc_reserved
[1] = 4; /* sclr_chroma10to8 */
364 static void fill_probs_table(void *ptr
)
366 rvcn_dec_vp9_probs_t
*probs
= (rvcn_dec_vp9_probs_t
*)ptr
;
368 memcpy(&probs
->coef_probs
[0], default_coef_probs_4x4
, sizeof(default_coef_probs_4x4
));
369 memcpy(&probs
->coef_probs
[1], default_coef_probs_8x8
, sizeof(default_coef_probs_8x8
));
370 memcpy(&probs
->coef_probs
[2], default_coef_probs_16x16
, sizeof(default_coef_probs_16x16
));
371 memcpy(&probs
->coef_probs
[3], default_coef_probs_32x32
, sizeof(default_coef_probs_32x32
));
372 memcpy(probs
->y_mode_prob
, default_if_y_probs
, sizeof(default_if_y_probs
));
373 memcpy(probs
->uv_mode_prob
, default_if_uv_probs
, sizeof(default_if_uv_probs
));
374 memcpy(probs
->single_ref_prob
, default_single_ref_p
, sizeof(default_single_ref_p
));
375 memcpy(probs
->switchable_interp_prob
, default_switchable_interp_prob
, sizeof(default_switchable_interp_prob
));
376 memcpy(probs
->partition_prob
, default_partition_probs
, sizeof(default_partition_probs
));
377 memcpy(probs
->inter_mode_probs
, default_inter_mode_probs
, sizeof(default_inter_mode_probs
));
378 memcpy(probs
->mbskip_probs
, default_skip_probs
, sizeof(default_skip_probs
));
379 memcpy(probs
->intra_inter_prob
, default_intra_inter_p
, sizeof(default_intra_inter_p
));
380 memcpy(probs
->comp_inter_prob
, default_comp_inter_p
, sizeof(default_comp_inter_p
));
381 memcpy(probs
->comp_ref_prob
, default_comp_ref_p
, sizeof(default_comp_ref_p
));
382 memcpy(probs
->tx_probs_32x32
, default_tx_probs_32x32
, sizeof(default_tx_probs_32x32
));
383 memcpy(probs
->tx_probs_16x16
, default_tx_probs_16x16
, sizeof(default_tx_probs_16x16
));
384 memcpy(probs
->tx_probs_8x8
, default_tx_probs_8x8
, sizeof(default_tx_probs_8x8
));
385 memcpy(probs
->mv_joints
, default_nmv_joints
, sizeof(default_nmv_joints
));
386 memcpy(&probs
->mv_comps
[0], default_nmv_components
, sizeof(default_nmv_components
));
387 memset(&probs
->nmvc_mask
, 0, sizeof(rvcn_dec_vp9_nmv_ctx_mask_t
));
390 static unsigned calc_ctx_size_h265_main(struct radeon_decoder
*dec
)
392 unsigned width
= align(dec
->base
.width
, VL_MACROBLOCK_WIDTH
);
393 unsigned height
= align(dec
->base
.height
, VL_MACROBLOCK_HEIGHT
);
395 unsigned max_references
= dec
->base
.max_references
+ 1;
397 if (dec
->base
.width
* dec
->base
.height
>= 4096*2000)
398 max_references
= MAX2(max_references
, 8);
400 max_references
= MAX2(max_references
, 17);
402 width
= align (width
, 16);
403 height
= align (height
, 16);
404 return ((width
+ 255) / 16) * ((height
+ 255) / 16) * 16 * max_references
+ 52 * 1024;
407 static unsigned calc_ctx_size_h265_main10(struct radeon_decoder
*dec
, struct pipe_h265_picture_desc
*pic
)
409 unsigned block_size
, log2_ctb_size
, width_in_ctb
, height_in_ctb
, num_16x16_block_per_ctb
;
410 unsigned context_buffer_size_per_ctb_row
, cm_buffer_size
, max_mb_address
, db_left_tile_pxl_size
;
411 unsigned db_left_tile_ctx_size
= 4096 / 16 * (32 + 16 * 4);
413 unsigned width
= align(dec
->base
.width
, VL_MACROBLOCK_WIDTH
);
414 unsigned height
= align(dec
->base
.height
, VL_MACROBLOCK_HEIGHT
);
415 unsigned coeff_10bit
= (pic
->pps
->sps
->bit_depth_luma_minus8
||
416 pic
->pps
->sps
->bit_depth_chroma_minus8
) ? 2 : 1;
418 unsigned max_references
= dec
->base
.max_references
+ 1;
420 if (dec
->base
.width
* dec
->base
.height
>= 4096*2000)
421 max_references
= MAX2(max_references
, 8);
423 max_references
= MAX2(max_references
, 17);
425 block_size
= (1 << (pic
->pps
->sps
->log2_min_luma_coding_block_size_minus3
+ 3));
426 log2_ctb_size
= block_size
+ pic
->pps
->sps
->log2_diff_max_min_luma_coding_block_size
;
428 width_in_ctb
= (width
+ ((1 << log2_ctb_size
) - 1)) >> log2_ctb_size
;
429 height_in_ctb
= (height
+ ((1 << log2_ctb_size
) - 1)) >> log2_ctb_size
;
431 num_16x16_block_per_ctb
= ((1 << log2_ctb_size
) >> 4) * ((1 << log2_ctb_size
) >> 4);
432 context_buffer_size_per_ctb_row
= align(width_in_ctb
* num_16x16_block_per_ctb
* 16, 256);
433 max_mb_address
= (unsigned) ceil(height
* 8 / 2048.0);
435 cm_buffer_size
= max_references
* context_buffer_size_per_ctb_row
* height_in_ctb
;
436 db_left_tile_pxl_size
= coeff_10bit
* (max_mb_address
* 2 * 2048 + 1024);
438 return cm_buffer_size
+ db_left_tile_ctx_size
+ db_left_tile_pxl_size
;
441 static rvcn_dec_message_vc1_t
get_vc1_msg(struct pipe_vc1_picture_desc
*pic
)
443 rvcn_dec_message_vc1_t result
;
445 memset(&result
, 0, sizeof(result
));
446 switch(pic
->base
.profile
) {
447 case PIPE_VIDEO_PROFILE_VC1_SIMPLE
:
448 result
.profile
= RDECODE_VC1_PROFILE_SIMPLE
;
452 case PIPE_VIDEO_PROFILE_VC1_MAIN
:
453 result
.profile
= RDECODE_VC1_PROFILE_MAIN
;
457 case PIPE_VIDEO_PROFILE_VC1_ADVANCED
:
458 result
.profile
= RDECODE_VC1_PROFILE_ADVANCED
;
466 result
.sps_info_flags
|= pic
->postprocflag
<< 7;
467 result
.sps_info_flags
|= pic
->pulldown
<< 6;
468 result
.sps_info_flags
|= pic
->interlace
<< 5;
469 result
.sps_info_flags
|= pic
->tfcntrflag
<< 4;
470 result
.sps_info_flags
|= pic
->finterpflag
<< 3;
471 result
.sps_info_flags
|= pic
->psf
<< 1;
473 result
.pps_info_flags
|= pic
->range_mapy_flag
<< 31;
474 result
.pps_info_flags
|= pic
->range_mapy
<< 28;
475 result
.pps_info_flags
|= pic
->range_mapuv_flag
<< 27;
476 result
.pps_info_flags
|= pic
->range_mapuv
<< 24;
477 result
.pps_info_flags
|= pic
->multires
<< 21;
478 result
.pps_info_flags
|= pic
->maxbframes
<< 16;
479 result
.pps_info_flags
|= pic
->overlap
<< 11;
480 result
.pps_info_flags
|= pic
->quantizer
<< 9;
481 result
.pps_info_flags
|= pic
->panscan_flag
<< 7;
482 result
.pps_info_flags
|= pic
->refdist_flag
<< 6;
483 result
.pps_info_flags
|= pic
->vstransform
<< 0;
485 if (pic
->base
.profile
!= PIPE_VIDEO_PROFILE_VC1_SIMPLE
) {
486 result
.pps_info_flags
|= pic
->syncmarker
<< 20;
487 result
.pps_info_flags
|= pic
->rangered
<< 19;
488 result
.pps_info_flags
|= pic
->loopfilter
<< 5;
489 result
.pps_info_flags
|= pic
->fastuvmc
<< 4;
490 result
.pps_info_flags
|= pic
->extended_mv
<< 3;
491 result
.pps_info_flags
|= pic
->extended_dmv
<< 8;
492 result
.pps_info_flags
|= pic
->dquant
<< 1;
495 result
.chroma_format
= 1;
500 static uint32_t get_ref_pic_idx(struct radeon_decoder
*dec
, struct pipe_video_buffer
*ref
)
502 uint32_t min
= MAX2(dec
->frame_number
, NUM_MPEG2_REFS
) - NUM_MPEG2_REFS
;
503 uint32_t max
= MAX2(dec
->frame_number
, 1) - 1;
506 /* seems to be the most sane fallback */
510 /* get the frame number from the associated data */
511 frame
= (uintptr_t)vl_video_buffer_get_associated_data(ref
, &dec
->base
);
513 /* limit the frame number to a valid range */
514 return MAX2(MIN2(frame
, max
), min
);
517 static rvcn_dec_message_mpeg2_vld_t
get_mpeg2_msg(struct radeon_decoder
*dec
,
518 struct pipe_mpeg12_picture_desc
*pic
)
520 const int *zscan
= pic
->alternate_scan
? vl_zscan_alternate
: vl_zscan_normal
;
521 rvcn_dec_message_mpeg2_vld_t result
;
524 memset(&result
, 0, sizeof(result
));
525 result
.decoded_pic_idx
= dec
->frame_number
;
527 result
.forward_ref_pic_idx
= get_ref_pic_idx(dec
, pic
->ref
[0]);
528 result
.backward_ref_pic_idx
= get_ref_pic_idx(dec
, pic
->ref
[1]);
530 if(pic
->intra_matrix
) {
531 result
.load_intra_quantiser_matrix
= 1;
532 for (i
= 0; i
< 64; ++i
) {
533 result
.intra_quantiser_matrix
[i
] = pic
->intra_matrix
[zscan
[i
]];
536 if(pic
->non_intra_matrix
) {
537 result
.load_nonintra_quantiser_matrix
= 1;
538 for (i
= 0; i
< 64; ++i
) {
539 result
.nonintra_quantiser_matrix
[i
] = pic
->non_intra_matrix
[zscan
[i
]];
543 result
.profile_and_level_indication
= 0;
544 result
.chroma_format
= 0x1;
546 result
.picture_coding_type
= pic
->picture_coding_type
;
547 result
.f_code
[0][0] = pic
->f_code
[0][0] + 1;
548 result
.f_code
[0][1] = pic
->f_code
[0][1] + 1;
549 result
.f_code
[1][0] = pic
->f_code
[1][0] + 1;
550 result
.f_code
[1][1] = pic
->f_code
[1][1] + 1;
551 result
.intra_dc_precision
= pic
->intra_dc_precision
;
552 result
.pic_structure
= pic
->picture_structure
;
553 result
.top_field_first
= pic
->top_field_first
;
554 result
.frame_pred_frame_dct
= pic
->frame_pred_frame_dct
;
555 result
.concealment_motion_vectors
= pic
->concealment_motion_vectors
;
556 result
.q_scale_type
= pic
->q_scale_type
;
557 result
.intra_vlc_format
= pic
->intra_vlc_format
;
558 result
.alternate_scan
= pic
->alternate_scan
;
563 static rvcn_dec_message_mpeg4_asp_vld_t
get_mpeg4_msg(struct radeon_decoder
*dec
,
564 struct pipe_mpeg4_picture_desc
*pic
)
566 rvcn_dec_message_mpeg4_asp_vld_t result
;
569 memset(&result
, 0, sizeof(result
));
570 result
.decoded_pic_idx
= dec
->frame_number
;
572 result
.forward_ref_pic_idx
= get_ref_pic_idx(dec
, pic
->ref
[0]);
573 result
.backward_ref_pic_idx
= get_ref_pic_idx(dec
, pic
->ref
[1]);
575 result
.variant_type
= 0;
576 result
.profile_and_level_indication
= 0xF0;
578 result
.video_object_layer_verid
= 0x5;
579 result
.video_object_layer_shape
= 0x0;
581 result
.video_object_layer_width
= dec
->base
.width
;
582 result
.video_object_layer_height
= dec
->base
.height
;
584 result
.vop_time_increment_resolution
= pic
->vop_time_increment_resolution
;
586 result
.short_video_header
|= pic
->short_video_header
<< 0;
587 result
.interlaced
|= pic
->interlaced
<< 2;
588 result
.load_intra_quant_mat
|= 1 << 3;
589 result
.load_nonintra_quant_mat
|= 1 << 4;
590 result
.quarter_sample
|= pic
->quarter_sample
<< 5;
591 result
.complexity_estimation_disable
|= 1 << 6;
592 result
.resync_marker_disable
|= pic
->resync_marker_disable
<< 7;
593 result
.newpred_enable
|= 0 << 10; //
594 result
.reduced_resolution_vop_enable
|= 0 << 11;
596 result
.quant_type
= pic
->quant_type
;
598 for (i
= 0; i
< 64; ++i
) {
599 result
.intra_quant_mat
[i
] = pic
->intra_matrix
[vl_zscan_normal
[i
]];
600 result
.nonintra_quant_mat
[i
] = pic
->non_intra_matrix
[vl_zscan_normal
[i
]];
606 static void rvcn_dec_message_create(struct radeon_decoder
*dec
)
608 rvcn_dec_message_header_t
*header
= dec
->msg
;
609 rvcn_dec_message_create_t
*create
= dec
->msg
+ sizeof(rvcn_dec_message_header_t
);
610 unsigned sizes
= sizeof(rvcn_dec_message_header_t
) + sizeof(rvcn_dec_message_create_t
);
612 memset(dec
->msg
, 0, sizes
);
613 header
->header_size
= sizeof(rvcn_dec_message_header_t
);
614 header
->total_size
= sizes
;
615 header
->num_buffers
= 1;
616 header
->msg_type
= RDECODE_MSG_CREATE
;
617 header
->stream_handle
= dec
->stream_handle
;
618 header
->status_report_feedback_number
= 0;
620 header
->index
[0].message_id
= RDECODE_MESSAGE_CREATE
;
621 header
->index
[0].offset
= sizeof(rvcn_dec_message_header_t
);
622 header
->index
[0].size
= sizeof(rvcn_dec_message_create_t
);
623 header
->index
[0].filled
= 0;
625 create
->stream_type
= dec
->stream_type
;
626 create
->session_flags
= 0;
627 create
->width_in_samples
= dec
->base
.width
;
628 create
->height_in_samples
= dec
->base
.height
;
631 static struct pb_buffer
*rvcn_dec_message_decode(struct radeon_decoder
*dec
,
632 struct pipe_video_buffer
*target
,
633 struct pipe_picture_desc
*picture
)
635 struct r600_texture
*luma
= (struct r600_texture
*)
636 ((struct vl_video_buffer
*)target
)->resources
[0];
637 struct r600_texture
*chroma
= (struct r600_texture
*)
638 ((struct vl_video_buffer
*)target
)->resources
[1];
639 rvcn_dec_message_header_t
*header
;
640 rvcn_dec_message_index_t
*index
;
641 rvcn_dec_message_decode_t
*decode
;
642 unsigned sizes
= 0, offset_decode
, offset_codec
;
646 sizes
+= sizeof(rvcn_dec_message_header_t
);
647 index
= (void*)header
+ sizeof(rvcn_dec_message_header_t
);
648 sizes
+= sizeof(rvcn_dec_message_index_t
);
649 offset_decode
= sizes
;
650 decode
= (void*)index
+ sizeof(rvcn_dec_message_index_t
);
651 sizes
+= sizeof(rvcn_dec_message_decode_t
);
652 offset_codec
= sizes
;
653 codec
= (void*)decode
+ sizeof(rvcn_dec_message_decode_t
);
655 memset(dec
->msg
, 0, sizes
);
656 header
->header_size
= sizeof(rvcn_dec_message_header_t
);
657 header
->total_size
= sizes
;
658 header
->num_buffers
= 2;
659 header
->msg_type
= RDECODE_MSG_DECODE
;
660 header
->stream_handle
= dec
->stream_handle
;
661 header
->status_report_feedback_number
= dec
->frame_number
;
663 header
->index
[0].message_id
= RDECODE_MESSAGE_DECODE
;
664 header
->index
[0].offset
= offset_decode
;
665 header
->index
[0].size
= sizeof(rvcn_dec_message_decode_t
);
666 header
->index
[0].filled
= 0;
668 index
->offset
= offset_codec
;
669 index
->size
= sizeof(rvcn_dec_message_avc_t
);
672 decode
->stream_type
= dec
->stream_type
;
673 decode
->decode_flags
= 0x1;
674 decode
->width_in_samples
= dec
->base
.width
;
675 decode
->height_in_samples
= dec
->base
.height
;
677 decode
->bsd_size
= align(dec
->bs_size
, 128);
678 decode
->dpb_size
= dec
->dpb
.res
->buf
->size
;
680 ((struct r600_resource
*)((struct vl_video_buffer
*)target
)->resources
[0])->buf
->size
+
681 ((struct r600_resource
*)((struct vl_video_buffer
*)target
)->resources
[1])->buf
->size
;
683 decode
->sct_size
= 0;
684 decode
->sc_coeff_size
= 0;
686 decode
->sw_ctxt_size
= RDECODE_SESSION_CONTEXT_SIZE
;
687 decode
->db_pitch
= align(dec
->base
.width
, 32);
688 decode
->db_surf_tile_config
= 0;
690 decode
->dt_pitch
= luma
->surface
.u
.gfx9
.surf_pitch
* luma
->surface
.blk_w
;
691 decode
->dt_uv_pitch
= decode
->dt_pitch
/ 2;
693 decode
->dt_tiling_mode
= 0;
694 decode
->dt_swizzle_mode
= RDECODE_SW_MODE_LINEAR
;
695 decode
->dt_array_mode
= RDECODE_ARRAY_MODE_LINEAR
;
696 decode
->dt_field_mode
= ((struct vl_video_buffer
*)target
)->base
.interlaced
;
697 decode
->dt_surf_tile_config
= 0;
698 decode
->dt_uv_surf_tile_config
= 0;
700 decode
->dt_luma_top_offset
= luma
->surface
.u
.gfx9
.surf_offset
;
701 decode
->dt_chroma_top_offset
= chroma
->surface
.u
.gfx9
.surf_offset
;
702 if (decode
->dt_field_mode
) {
703 decode
->dt_luma_bottom_offset
= luma
->surface
.u
.gfx9
.surf_offset
+
704 luma
->surface
.u
.gfx9
.surf_slice_size
;
705 decode
->dt_chroma_bottom_offset
= chroma
->surface
.u
.gfx9
.surf_offset
+
706 chroma
->surface
.u
.gfx9
.surf_slice_size
;
708 decode
->dt_luma_bottom_offset
= decode
->dt_luma_top_offset
;
709 decode
->dt_chroma_bottom_offset
= decode
->dt_chroma_top_offset
;
712 switch (u_reduce_video_profile(picture
->profile
)) {
713 case PIPE_VIDEO_FORMAT_MPEG4_AVC
: {
714 rvcn_dec_message_avc_t avc
=
715 get_h264_msg(dec
, (struct pipe_h264_picture_desc
*)picture
);
716 memcpy(codec
, (void*)&avc
, sizeof(rvcn_dec_message_avc_t
));
717 index
->message_id
= RDECODE_MESSAGE_AVC
;
720 case PIPE_VIDEO_FORMAT_HEVC
: {
721 rvcn_dec_message_hevc_t hevc
=
722 get_h265_msg(dec
, target
, (struct pipe_h265_picture_desc
*)picture
);
724 memcpy(codec
, (void*)&hevc
, sizeof(rvcn_dec_message_hevc_t
));
725 index
->message_id
= RDECODE_MESSAGE_HEVC
;
726 if (dec
->ctx
.res
== NULL
) {
728 if (dec
->base
.profile
== PIPE_VIDEO_PROFILE_HEVC_MAIN_10
)
729 ctx_size
= calc_ctx_size_h265_main10(dec
,
730 (struct pipe_h265_picture_desc
*)picture
);
732 ctx_size
= calc_ctx_size_h265_main(dec
);
733 if (!si_vid_create_buffer(dec
->screen
, &dec
->ctx
, ctx_size
, PIPE_USAGE_DEFAULT
))
734 RVID_ERR("Can't allocated context buffer.\n");
735 si_vid_clear_buffer(dec
->base
.context
, &dec
->ctx
);
739 case PIPE_VIDEO_FORMAT_VC1
: {
740 rvcn_dec_message_vc1_t vc1
= get_vc1_msg((struct pipe_vc1_picture_desc
*)picture
);
742 memcpy(codec
, (void*)&vc1
, sizeof(rvcn_dec_message_vc1_t
));
743 if ((picture
->profile
== PIPE_VIDEO_PROFILE_VC1_SIMPLE
) ||
744 (picture
->profile
== PIPE_VIDEO_PROFILE_VC1_MAIN
)) {
745 decode
->width_in_samples
= align(decode
->width_in_samples
, 16) / 16;
746 decode
->height_in_samples
= align(decode
->height_in_samples
, 16) / 16;
748 index
->message_id
= RDECODE_MESSAGE_VC1
;
752 case PIPE_VIDEO_FORMAT_MPEG12
: {
753 rvcn_dec_message_mpeg2_vld_t mpeg2
=
754 get_mpeg2_msg(dec
, (struct pipe_mpeg12_picture_desc
*)picture
);
756 memcpy(codec
, (void*)&mpeg2
, sizeof(rvcn_dec_message_mpeg2_vld_t
));
757 index
->message_id
= RDECODE_MESSAGE_MPEG2_VLD
;
760 case PIPE_VIDEO_FORMAT_MPEG4
: {
761 rvcn_dec_message_mpeg4_asp_vld_t mpeg4
=
762 get_mpeg4_msg(dec
, (struct pipe_mpeg4_picture_desc
*)picture
);
764 memcpy(codec
, (void*)&mpeg4
, sizeof(rvcn_dec_message_mpeg4_asp_vld_t
));
765 index
->message_id
= RDECODE_MESSAGE_MPEG4_ASP_VLD
;
774 decode
->hw_ctxt_size
= dec
->ctx
.res
->buf
->size
;
776 return luma
->resource
.buf
;
779 static void rvcn_dec_message_destroy(struct radeon_decoder
*dec
)
781 rvcn_dec_message_header_t
*header
= dec
->msg
;
783 memset(dec
->msg
, 0, sizeof(rvcn_dec_message_header_t
));
784 header
->header_size
= sizeof(rvcn_dec_message_header_t
);
785 header
->total_size
= sizeof(rvcn_dec_message_header_t
) -
786 sizeof(rvcn_dec_message_index_t
);
787 header
->num_buffers
= 0;
788 header
->msg_type
= RDECODE_MSG_DESTROY
;
789 header
->stream_handle
= dec
->stream_handle
;
790 header
->status_report_feedback_number
= 0;
793 static void rvcn_dec_message_feedback(struct radeon_decoder
*dec
)
795 rvcn_dec_feedback_header_t
*header
= (void*)dec
->fb
;
797 header
->header_size
= sizeof(rvcn_dec_feedback_header_t
);
798 header
->total_size
= sizeof(rvcn_dec_feedback_header_t
);
799 header
->num_buffers
= 0;
802 /* flush IB to the hardware */
803 static int flush(struct radeon_decoder
*dec
, unsigned flags
)
805 return dec
->ws
->cs_flush(dec
->cs
, flags
, NULL
);
808 /* add a new set register command to the IB */
809 static void set_reg(struct radeon_decoder
*dec
, unsigned reg
, uint32_t val
)
811 radeon_emit(dec
->cs
, RDECODE_PKT0(reg
>> 2, 0));
812 radeon_emit(dec
->cs
, val
);
815 /* send a command to the VCPU through the GPCOM registers */
816 static void send_cmd(struct radeon_decoder
*dec
, unsigned cmd
,
817 struct pb_buffer
* buf
, uint32_t off
,
818 enum radeon_bo_usage usage
, enum radeon_bo_domain domain
)
822 dec
->ws
->cs_add_buffer(dec
->cs
, buf
, usage
| RADEON_USAGE_SYNCHRONIZED
,
823 domain
, RADEON_PRIO_UVD
);
824 addr
= dec
->ws
->buffer_get_virtual_address(buf
);
827 set_reg(dec
, RDECODE_GPCOM_VCPU_DATA0
, addr
);
828 set_reg(dec
, RDECODE_GPCOM_VCPU_DATA1
, addr
>> 32);
829 set_reg(dec
, RDECODE_GPCOM_VCPU_CMD
, cmd
<< 1);
832 /* do the codec needs an IT buffer ?*/
833 static bool have_it(struct radeon_decoder
*dec
)
835 return dec
->stream_type
== RDECODE_CODEC_H264_PERF
||
836 dec
->stream_type
== RDECODE_CODEC_H265
;
839 /* do the codec needs an probs buffer? */
840 static bool have_probs(struct radeon_decoder
*dec
)
842 return dec
->stream_type
== RDECODE_CODEC_VP9
;
845 /* map the next available message/feedback/itscaling buffer */
846 static void map_msg_fb_it_probs_buf(struct radeon_decoder
*dec
)
848 struct rvid_buffer
* buf
;
851 /* grab the current message/feedback buffer */
852 buf
= &dec
->msg_fb_it_probs_buffers
[dec
->cur_buffer
];
854 /* and map it for CPU access */
855 ptr
= dec
->ws
->buffer_map(buf
->res
->buf
, dec
->cs
, PIPE_TRANSFER_WRITE
);
857 /* calc buffer offsets */
860 dec
->fb
= (uint32_t *)(ptr
+ FB_BUFFER_OFFSET
);
862 dec
->it
= (uint8_t *)(ptr
+ FB_BUFFER_OFFSET
+ FB_BUFFER_SIZE
);
863 else if (have_probs(dec
))
864 dec
->probs
= (uint8_t *)(ptr
+ FB_BUFFER_OFFSET
+ FB_BUFFER_SIZE
);
867 /* unmap and send a message command to the VCPU */
868 static void send_msg_buf(struct radeon_decoder
*dec
)
870 struct rvid_buffer
* buf
;
872 /* ignore the request if message/feedback buffer isn't mapped */
873 if (!dec
->msg
|| !dec
->fb
)
876 /* grab the current message buffer */
877 buf
= &dec
->msg_fb_it_probs_buffers
[dec
->cur_buffer
];
879 /* unmap the buffer */
880 dec
->ws
->buffer_unmap(buf
->res
->buf
);
886 if (dec
->sessionctx
.res
)
887 send_cmd(dec
, RDECODE_CMD_SESSION_CONTEXT_BUFFER
,
888 dec
->sessionctx
.res
->buf
, 0, RADEON_USAGE_READWRITE
,
891 /* and send it to the hardware */
892 send_cmd(dec
, RDECODE_CMD_MSG_BUFFER
, buf
->res
->buf
, 0,
893 RADEON_USAGE_READ
, RADEON_DOMAIN_GTT
);
896 /* cycle to the next set of buffers */
897 static void next_buffer(struct radeon_decoder
*dec
)
900 dec
->cur_buffer
%= NUM_BUFFERS
;
903 static unsigned calc_ctx_size_h264_perf(struct radeon_decoder
*dec
)
905 unsigned width_in_mb
, height_in_mb
, ctx_size
;
906 unsigned width
= align(dec
->base
.width
, VL_MACROBLOCK_WIDTH
);
907 unsigned height
= align(dec
->base
.height
, VL_MACROBLOCK_HEIGHT
);
909 unsigned max_references
= dec
->base
.max_references
+ 1;
911 // picture width & height in 16 pixel units
912 width_in_mb
= width
/ VL_MACROBLOCK_WIDTH
;
913 height_in_mb
= align(height
/ VL_MACROBLOCK_HEIGHT
, 2);
915 unsigned fs_in_mb
= width_in_mb
* height_in_mb
;
916 unsigned num_dpb_buffer
;
917 switch(dec
->base
.level
) {
919 num_dpb_buffer
= 8100 / fs_in_mb
;
922 num_dpb_buffer
= 18000 / fs_in_mb
;
925 num_dpb_buffer
= 20480 / fs_in_mb
;
928 num_dpb_buffer
= 32768 / fs_in_mb
;
931 num_dpb_buffer
= 34816 / fs_in_mb
;
934 num_dpb_buffer
= 110400 / fs_in_mb
;
937 num_dpb_buffer
= 184320 / fs_in_mb
;
940 num_dpb_buffer
= 184320 / fs_in_mb
;
944 max_references
= MAX2(MIN2(NUM_H264_REFS
, num_dpb_buffer
), max_references
);
945 ctx_size
= max_references
* align(width_in_mb
* height_in_mb
* 192, 256);
950 /* calculate size of reference picture buffer */
951 static unsigned calc_dpb_size(struct radeon_decoder
*dec
)
953 unsigned width_in_mb
, height_in_mb
, image_size
, dpb_size
;
955 // always align them to MB size for dpb calculation
956 unsigned width
= align(dec
->base
.width
, VL_MACROBLOCK_WIDTH
);
957 unsigned height
= align(dec
->base
.height
, VL_MACROBLOCK_HEIGHT
);
959 // always one more for currently decoded picture
960 unsigned max_references
= dec
->base
.max_references
+ 1;
962 // aligned size of a single frame
963 image_size
= align(width
, 32) * height
;
964 image_size
+= image_size
/ 2;
965 image_size
= align(image_size
, 1024);
967 // picture width & height in 16 pixel units
968 width_in_mb
= width
/ VL_MACROBLOCK_WIDTH
;
969 height_in_mb
= align(height
/ VL_MACROBLOCK_HEIGHT
, 2);
971 switch (u_reduce_video_profile(dec
->base
.profile
)) {
972 case PIPE_VIDEO_FORMAT_MPEG4_AVC
: {
973 unsigned fs_in_mb
= width_in_mb
* height_in_mb
;
974 unsigned num_dpb_buffer
;
976 switch(dec
->base
.level
) {
978 num_dpb_buffer
= 8100 / fs_in_mb
;
981 num_dpb_buffer
= 18000 / fs_in_mb
;
984 num_dpb_buffer
= 20480 / fs_in_mb
;
987 num_dpb_buffer
= 32768 / fs_in_mb
;
990 num_dpb_buffer
= 34816 / fs_in_mb
;
993 num_dpb_buffer
= 110400 / fs_in_mb
;
996 num_dpb_buffer
= 184320 / fs_in_mb
;
999 num_dpb_buffer
= 184320 / fs_in_mb
;
1003 max_references
= MAX2(MIN2(NUM_H264_REFS
, num_dpb_buffer
), max_references
);
1004 dpb_size
= image_size
* max_references
;
1008 case PIPE_VIDEO_FORMAT_HEVC
:
1009 if (dec
->base
.width
* dec
->base
.height
>= 4096*2000)
1010 max_references
= MAX2(max_references
, 8);
1012 max_references
= MAX2(max_references
, 17);
1014 width
= align (width
, 16);
1015 height
= align (height
, 16);
1016 if (dec
->base
.profile
== PIPE_VIDEO_PROFILE_HEVC_MAIN_10
)
1017 dpb_size
= align((align(width
, 32) * height
* 9) / 4, 256) * max_references
;
1019 dpb_size
= align((align(width
, 32) * height
* 3) / 2, 256) * max_references
;
1022 case PIPE_VIDEO_FORMAT_VC1
:
1023 // the firmware seems to allways assume a minimum of ref frames
1024 max_references
= MAX2(NUM_VC1_REFS
, max_references
);
1026 // reference picture buffer
1027 dpb_size
= image_size
* max_references
;
1030 dpb_size
+= width_in_mb
* height_in_mb
* 128;
1032 // IT surface buffer
1033 dpb_size
+= width_in_mb
* 64;
1035 // DB surface buffer
1036 dpb_size
+= width_in_mb
* 128;
1039 dpb_size
+= align(MAX2(width_in_mb
, height_in_mb
) * 7 * 16, 64);
1042 case PIPE_VIDEO_FORMAT_MPEG12
:
1043 // reference picture buffer, must be big enough for all frames
1044 dpb_size
= image_size
* NUM_MPEG2_REFS
;
1047 case PIPE_VIDEO_FORMAT_MPEG4
:
1048 // reference picture buffer
1049 dpb_size
= image_size
* max_references
;
1052 dpb_size
+= width_in_mb
* height_in_mb
* 64;
1054 // IT surface buffer
1055 dpb_size
+= align(width_in_mb
* height_in_mb
* 32, 64);
1057 dpb_size
= MAX2(dpb_size
, 30 * 1024 * 1024);
1060 case PIPE_VIDEO_FORMAT_VP9
:
1061 max_references
= MAX2(max_references
, 9);
1063 dpb_size
= (4096 * 3000 * 3 / 2) * max_references
;
1067 // something is missing here
1070 // at least use a sane default value
1071 dpb_size
= 32 * 1024 * 1024;
1078 * destroy this video decoder
1080 static void radeon_dec_destroy(struct pipe_video_codec
*decoder
)
1082 struct radeon_decoder
*dec
= (struct radeon_decoder
*)decoder
;
1087 map_msg_fb_it_probs_buf(dec
);
1088 rvcn_dec_message_destroy(dec
);
1093 dec
->ws
->cs_destroy(dec
->cs
);
1095 for (i
= 0; i
< NUM_BUFFERS
; ++i
) {
1096 si_vid_destroy_buffer(&dec
->msg_fb_it_probs_buffers
[i
]);
1097 si_vid_destroy_buffer(&dec
->bs_buffers
[i
]);
1100 si_vid_destroy_buffer(&dec
->dpb
);
1101 si_vid_destroy_buffer(&dec
->ctx
);
1102 si_vid_destroy_buffer(&dec
->sessionctx
);
1108 * start decoding of a new frame
1110 static void radeon_dec_begin_frame(struct pipe_video_codec
*decoder
,
1111 struct pipe_video_buffer
*target
,
1112 struct pipe_picture_desc
*picture
)
1114 struct radeon_decoder
*dec
= (struct radeon_decoder
*)decoder
;
1119 frame
= ++dec
->frame_number
;
1120 vl_video_buffer_set_associated_data(target
, decoder
, (void *)frame
,
1121 &radeon_dec_destroy_associated_data
);
1124 dec
->bs_ptr
= dec
->ws
->buffer_map(
1125 dec
->bs_buffers
[dec
->cur_buffer
].res
->buf
,
1126 dec
->cs
, PIPE_TRANSFER_WRITE
);
1130 * decode a macroblock
1132 static void radeon_dec_decode_macroblock(struct pipe_video_codec
*decoder
,
1133 struct pipe_video_buffer
*target
,
1134 struct pipe_picture_desc
*picture
,
1135 const struct pipe_macroblock
*macroblocks
,
1136 unsigned num_macroblocks
)
1138 /* not supported (yet) */
1143 * decode a bitstream
1145 static void radeon_dec_decode_bitstream(struct pipe_video_codec
*decoder
,
1146 struct pipe_video_buffer
*target
,
1147 struct pipe_picture_desc
*picture
,
1148 unsigned num_buffers
,
1149 const void * const *buffers
,
1150 const unsigned *sizes
)
1152 struct radeon_decoder
*dec
= (struct radeon_decoder
*)decoder
;
1160 for (i
= 0; i
< num_buffers
; ++i
) {
1161 struct rvid_buffer
*buf
= &dec
->bs_buffers
[dec
->cur_buffer
];
1162 unsigned new_size
= dec
->bs_size
+ sizes
[i
];
1164 if (new_size
> buf
->res
->buf
->size
) {
1165 dec
->ws
->buffer_unmap(buf
->res
->buf
);
1166 if (!si_vid_resize_buffer(dec
->screen
, dec
->cs
, buf
, new_size
)) {
1167 RVID_ERR("Can't resize bitstream buffer!");
1171 dec
->bs_ptr
= dec
->ws
->buffer_map(buf
->res
->buf
, dec
->cs
,
1172 PIPE_TRANSFER_WRITE
);
1176 dec
->bs_ptr
+= dec
->bs_size
;
1179 memcpy(dec
->bs_ptr
, buffers
[i
], sizes
[i
]);
1180 dec
->bs_size
+= sizes
[i
];
1181 dec
->bs_ptr
+= sizes
[i
];
1186 * end decoding of the current frame
1188 static void radeon_dec_end_frame(struct pipe_video_codec
*decoder
,
1189 struct pipe_video_buffer
*target
,
1190 struct pipe_picture_desc
*picture
)
1192 struct radeon_decoder
*dec
= (struct radeon_decoder
*)decoder
;
1193 struct pb_buffer
*dt
;
1194 struct rvid_buffer
*msg_fb_it_probs_buf
, *bs_buf
;
1201 msg_fb_it_probs_buf
= &dec
->msg_fb_it_probs_buffers
[dec
->cur_buffer
];
1202 bs_buf
= &dec
->bs_buffers
[dec
->cur_buffer
];
1204 memset(dec
->bs_ptr
, 0, align(dec
->bs_size
, 128) - dec
->bs_size
);
1205 dec
->ws
->buffer_unmap(bs_buf
->res
->buf
);
1207 map_msg_fb_it_probs_buf(dec
);
1208 dt
= rvcn_dec_message_decode(dec
, target
, picture
);
1209 rvcn_dec_message_feedback(dec
);
1212 send_cmd(dec
, RDECODE_CMD_DPB_BUFFER
, dec
->dpb
.res
->buf
, 0,
1213 RADEON_USAGE_READWRITE
, RADEON_DOMAIN_VRAM
);
1215 send_cmd(dec
, RDECODE_CMD_CONTEXT_BUFFER
, dec
->ctx
.res
->buf
, 0,
1216 RADEON_USAGE_READWRITE
, RADEON_DOMAIN_VRAM
);
1217 send_cmd(dec
, RDECODE_CMD_BITSTREAM_BUFFER
, bs_buf
->res
->buf
,
1218 0, RADEON_USAGE_READ
, RADEON_DOMAIN_GTT
);
1219 send_cmd(dec
, RDECODE_CMD_DECODING_TARGET_BUFFER
, dt
, 0,
1220 RADEON_USAGE_WRITE
, RADEON_DOMAIN_VRAM
);
1221 send_cmd(dec
, RDECODE_CMD_FEEDBACK_BUFFER
, msg_fb_it_probs_buf
->res
->buf
,
1222 FB_BUFFER_OFFSET
, RADEON_USAGE_WRITE
, RADEON_DOMAIN_GTT
);
1224 send_cmd(dec
, RDECODE_CMD_IT_SCALING_TABLE_BUFFER
, msg_fb_it_probs_buf
->res
->buf
,
1225 FB_BUFFER_OFFSET
+ FB_BUFFER_SIZE
, RADEON_USAGE_READ
, RADEON_DOMAIN_GTT
);
1226 else if (have_probs(dec
))
1227 send_cmd(dec
, RDECODE_CMD_PROB_TBL_BUFFER
, msg_fb_it_probs_buf
->res
->buf
,
1228 FB_BUFFER_OFFSET
+ FB_BUFFER_SIZE
, RADEON_USAGE_READ
, RADEON_DOMAIN_GTT
);
1229 set_reg(dec
, RDECODE_ENGINE_CNTL
, 1);
1231 flush(dec
, PIPE_FLUSH_ASYNC
);
1236 * flush any outstanding command buffers to the hardware
1238 static void radeon_dec_flush(struct pipe_video_codec
*decoder
)
1243 * create and HW decoder
1245 struct pipe_video_codec
*radeon_create_decoder(struct pipe_context
*context
,
1246 const struct pipe_video_codec
*templ
)
1248 struct si_context
*sctx
= (struct si_context
*)context
;
1249 struct radeon_winsys
*ws
= sctx
->ws
;
1250 unsigned width
= templ
->width
, height
= templ
->height
;
1251 unsigned dpb_size
, bs_buf_size
, stream_type
= 0;
1252 struct radeon_decoder
*dec
;
1255 switch(u_reduce_video_profile(templ
->profile
)) {
1256 case PIPE_VIDEO_FORMAT_MPEG12
:
1257 if (templ
->entrypoint
> PIPE_VIDEO_ENTRYPOINT_BITSTREAM
)
1258 return vl_create_mpeg12_decoder(context
, templ
);
1259 stream_type
= RDECODE_CODEC_MPEG2_VLD
;
1261 case PIPE_VIDEO_FORMAT_MPEG4
:
1262 width
= align(width
, VL_MACROBLOCK_WIDTH
);
1263 height
= align(height
, VL_MACROBLOCK_HEIGHT
);
1264 stream_type
= RDECODE_CODEC_MPEG4
;
1266 case PIPE_VIDEO_FORMAT_VC1
:
1267 stream_type
= RDECODE_CODEC_VC1
;
1269 case PIPE_VIDEO_FORMAT_MPEG4_AVC
:
1270 width
= align(width
, VL_MACROBLOCK_WIDTH
);
1271 height
= align(height
, VL_MACROBLOCK_HEIGHT
);
1272 stream_type
= RDECODE_CODEC_H264_PERF
;
1274 case PIPE_VIDEO_FORMAT_HEVC
:
1275 stream_type
= RDECODE_CODEC_H265
;
1277 case PIPE_VIDEO_FORMAT_VP9
:
1278 stream_type
= RDECODE_CODEC_VP9
;
1285 dec
= CALLOC_STRUCT(radeon_decoder
);
1291 dec
->base
.context
= context
;
1292 dec
->base
.width
= width
;
1293 dec
->base
.height
= height
;
1295 dec
->base
.destroy
= radeon_dec_destroy
;
1296 dec
->base
.begin_frame
= radeon_dec_begin_frame
;
1297 dec
->base
.decode_macroblock
= radeon_dec_decode_macroblock
;
1298 dec
->base
.decode_bitstream
= radeon_dec_decode_bitstream
;
1299 dec
->base
.end_frame
= radeon_dec_end_frame
;
1300 dec
->base
.flush
= radeon_dec_flush
;
1302 dec
->stream_type
= stream_type
;
1303 dec
->stream_handle
= si_vid_alloc_stream_handle();
1304 dec
->screen
= context
->screen
;
1306 dec
->cs
= ws
->cs_create(sctx
->ctx
, RING_VCN_DEC
, NULL
, NULL
);
1308 RVID_ERR("Can't get command submission context.\n");
1312 for (i
= 0; i
< 16; i
++)
1313 dec
->render_pic_list
[i
] = NULL
;
1314 bs_buf_size
= width
* height
* (512 / (16 * 16));
1315 for (i
= 0; i
< NUM_BUFFERS
; ++i
) {
1316 unsigned msg_fb_it_probs_size
= FB_BUFFER_OFFSET
+ FB_BUFFER_SIZE
;
1318 msg_fb_it_probs_size
+= IT_SCALING_TABLE_SIZE
;
1319 else if (have_probs(dec
))
1320 msg_fb_it_probs_size
+= VP9_PROBS_TABLE_SIZE
;
1321 /* use vram to improve performance, workaround an unknown bug */
1322 if (!si_vid_create_buffer(dec
->screen
, &dec
->msg_fb_it_probs_buffers
[i
],
1323 msg_fb_it_probs_size
, PIPE_USAGE_DEFAULT
)) {
1324 RVID_ERR("Can't allocated message buffers.\n");
1328 if (!si_vid_create_buffer(dec
->screen
, &dec
->bs_buffers
[i
],
1329 bs_buf_size
, PIPE_USAGE_STAGING
)) {
1330 RVID_ERR("Can't allocated bitstream buffers.\n");
1334 si_vid_clear_buffer(context
, &dec
->msg_fb_it_probs_buffers
[i
]);
1335 si_vid_clear_buffer(context
, &dec
->bs_buffers
[i
]);
1337 if (have_probs(dec
)) {
1338 struct rvid_buffer
* buf
;
1341 buf
= &dec
->msg_fb_it_probs_buffers
[i
];
1342 ptr
= dec
->ws
->buffer_map(buf
->res
->buf
, dec
->cs
, PIPE_TRANSFER_WRITE
);
1343 ptr
+= FB_BUFFER_OFFSET
+ FB_BUFFER_SIZE
;
1344 fill_probs_table(ptr
);
1345 dec
->ws
->buffer_unmap(buf
->res
->buf
);
1349 dpb_size
= calc_dpb_size(dec
);
1351 if (!si_vid_create_buffer(dec
->screen
, &dec
->dpb
, dpb_size
, PIPE_USAGE_DEFAULT
)) {
1352 RVID_ERR("Can't allocated dpb.\n");
1356 si_vid_clear_buffer(context
, &dec
->dpb
);
1358 if (dec
->stream_type
== RDECODE_CODEC_H264_PERF
) {
1359 unsigned ctx_size
= calc_ctx_size_h264_perf(dec
);
1360 if (!si_vid_create_buffer(dec
->screen
, &dec
->ctx
, ctx_size
, PIPE_USAGE_DEFAULT
)) {
1361 RVID_ERR("Can't allocated context buffer.\n");
1364 si_vid_clear_buffer(context
, &dec
->ctx
);
1367 if (!si_vid_create_buffer(dec
->screen
, &dec
->sessionctx
,
1368 RDECODE_SESSION_CONTEXT_SIZE
,
1369 PIPE_USAGE_DEFAULT
)) {
1370 RVID_ERR("Can't allocated session ctx.\n");
1373 si_vid_clear_buffer(context
, &dec
->sessionctx
);
1375 map_msg_fb_it_probs_buf(dec
);
1376 rvcn_dec_message_create(dec
);
1387 if (dec
->cs
) dec
->ws
->cs_destroy(dec
->cs
);
1389 for (i
= 0; i
< NUM_BUFFERS
; ++i
) {
1390 si_vid_destroy_buffer(&dec
->msg_fb_it_probs_buffers
[i
]);
1391 si_vid_destroy_buffer(&dec
->bs_buffers
[i
]);
1394 si_vid_destroy_buffer(&dec
->dpb
);
1395 si_vid_destroy_buffer(&dec
->ctx
);
1396 si_vid_destroy_buffer(&dec
->sessionctx
);