1 /**************************************************************************
3 * Copyright 2011 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 **************************************************************************/
30 * Christian König <christian.koenig@amd.com>
34 #include <sys/types.h>
40 #include "pipe/p_video_codec.h"
42 #include "util/u_memory.h"
43 #include "util/u_video.h"
45 #include "vl/vl_defines.h"
46 #include "vl/vl_mpeg12_decoder.h"
48 #include "r600_pipe_common.h"
49 #include "radeon_video.h"
50 #include "radeon_uvd.h"
54 #define NUM_MPEG2_REFS 6
55 #define NUM_H264_REFS 17
56 #define NUM_VC1_REFS 5
58 #define FB_BUFFER_OFFSET 0x1000
59 #define FB_BUFFER_SIZE 2048
60 #define IT_SCALING_TABLE_SIZE 992
62 /* UVD decoder representation */
64 struct pipe_video_codec base
;
68 unsigned stream_handle
;
70 unsigned frame_number
;
72 struct pipe_screen
*screen
;
73 struct radeon_winsys
* ws
;
74 struct radeon_winsys_cs
* cs
;
78 struct rvid_buffer msg_fb_it_buffers
[NUM_BUFFERS
];
83 struct rvid_buffer bs_buffers
[NUM_BUFFERS
];
87 struct rvid_buffer dpb
;
89 struct rvid_buffer ctx
;
92 /* flush IB to the hardware */
93 static void flush(struct ruvd_decoder
*dec
)
95 dec
->ws
->cs_flush(dec
->cs
, RADEON_FLUSH_ASYNC
, NULL
, 0);
98 /* add a new set register command to the IB */
99 static void set_reg(struct ruvd_decoder
*dec
, unsigned reg
, uint32_t val
)
101 uint32_t *pm4
= dec
->cs
->buf
;
102 pm4
[dec
->cs
->cdw
++] = RUVD_PKT0(reg
>> 2, 0);
103 pm4
[dec
->cs
->cdw
++] = val
;
106 /* send a command to the VCPU through the GPCOM registers */
107 static void send_cmd(struct ruvd_decoder
*dec
, unsigned cmd
,
108 struct radeon_winsys_cs_handle
* cs_buf
, uint32_t off
,
109 enum radeon_bo_usage usage
, enum radeon_bo_domain domain
)
113 reloc_idx
= dec
->ws
->cs_add_reloc(dec
->cs
, cs_buf
, usage
, domain
,
115 if (!dec
->use_legacy
) {
117 addr
= dec
->ws
->buffer_get_virtual_address(cs_buf
);
119 set_reg(dec
, RUVD_GPCOM_VCPU_DATA0
, addr
);
120 set_reg(dec
, RUVD_GPCOM_VCPU_DATA1
, addr
>> 32);
122 set_reg(dec
, RUVD_GPCOM_VCPU_DATA0
, off
);
123 set_reg(dec
, RUVD_GPCOM_VCPU_DATA1
, reloc_idx
* 4);
125 set_reg(dec
, RUVD_GPCOM_VCPU_CMD
, cmd
<< 1);
128 /* do the codec needs an IT buffer ?*/
129 static bool have_it(struct ruvd_decoder
*dec
)
131 return dec
->stream_type
== RUVD_CODEC_H264_PERF
||
132 dec
->stream_type
== RUVD_CODEC_H265
;
135 /* map the next available message/feedback/itscaling buffer */
136 static void map_msg_fb_it_buf(struct ruvd_decoder
*dec
)
138 struct rvid_buffer
* buf
;
141 /* grab the current message/feedback buffer */
142 buf
= &dec
->msg_fb_it_buffers
[dec
->cur_buffer
];
144 /* and map it for CPU access */
145 ptr
= dec
->ws
->buffer_map(buf
->res
->cs_buf
, dec
->cs
, PIPE_TRANSFER_WRITE
);
147 /* calc buffer offsets */
148 dec
->msg
= (struct ruvd_msg
*)ptr
;
149 dec
->fb
= (uint32_t *)(ptr
+ FB_BUFFER_OFFSET
);
151 dec
->it
= (uint8_t *)(ptr
+ FB_BUFFER_OFFSET
+ FB_BUFFER_SIZE
);
154 /* unmap and send a message command to the VCPU */
155 static void send_msg_buf(struct ruvd_decoder
*dec
)
157 struct rvid_buffer
* buf
;
159 /* ignore the request if message/feedback buffer isn't mapped */
160 if (!dec
->msg
|| !dec
->fb
)
163 /* grab the current message buffer */
164 buf
= &dec
->msg_fb_it_buffers
[dec
->cur_buffer
];
166 /* unmap the buffer */
167 dec
->ws
->buffer_unmap(buf
->res
->cs_buf
);
172 /* and send it to the hardware */
173 send_cmd(dec
, RUVD_CMD_MSG_BUFFER
, buf
->res
->cs_buf
, 0,
174 RADEON_USAGE_READ
, RADEON_DOMAIN_GTT
);
177 /* cycle to the next set of buffers */
178 static void next_buffer(struct ruvd_decoder
*dec
)
181 dec
->cur_buffer
%= NUM_BUFFERS
;
184 /* convert the profile into something UVD understands */
185 static uint32_t profile2stream_type(struct ruvd_decoder
*dec
, unsigned family
)
187 switch (u_reduce_video_profile(dec
->base
.profile
)) {
188 case PIPE_VIDEO_FORMAT_MPEG4_AVC
:
189 return (family
>= CHIP_TONGA
) ?
190 RUVD_CODEC_H264_PERF
: RUVD_CODEC_H264
;
192 case PIPE_VIDEO_FORMAT_VC1
:
193 return RUVD_CODEC_VC1
;
195 case PIPE_VIDEO_FORMAT_MPEG12
:
196 return RUVD_CODEC_MPEG2
;
198 case PIPE_VIDEO_FORMAT_MPEG4
:
199 return RUVD_CODEC_MPEG4
;
201 case PIPE_VIDEO_FORMAT_HEVC
:
202 return RUVD_CODEC_H265
;
210 static unsigned calc_ctx_size(struct ruvd_decoder
*dec
)
212 unsigned width_in_mb
, height_in_mb
, ctx_size
;
214 unsigned width
= align(dec
->base
.width
, VL_MACROBLOCK_WIDTH
);
215 unsigned height
= align(dec
->base
.height
, VL_MACROBLOCK_HEIGHT
);
217 unsigned max_references
= dec
->base
.max_references
+ 1;
219 if (dec
->base
.width
* dec
->base
.height
>= 4096*2000)
220 max_references
= MAX2(max_references
, 8);
222 max_references
= MAX2(max_references
, 17);
224 width
= align (width
, 16);
225 height
= align (height
, 16);
226 ctx_size
= ((width
+ 255) / 16)*((height
+ 255) / 16) * 16 * max_references
+ 52 * 1024;
230 /* calculate size of reference picture buffer */
231 static unsigned calc_dpb_size(struct ruvd_decoder
*dec
)
233 unsigned width_in_mb
, height_in_mb
, image_size
, dpb_size
;
235 // always align them to MB size for dpb calculation
236 unsigned width
= align(dec
->base
.width
, VL_MACROBLOCK_WIDTH
);
237 unsigned height
= align(dec
->base
.height
, VL_MACROBLOCK_HEIGHT
);
239 // always one more for currently decoded picture
240 unsigned max_references
= dec
->base
.max_references
+ 1;
242 // aligned size of a single frame
243 image_size
= width
* height
;
244 image_size
+= image_size
/ 2;
245 image_size
= align(image_size
, 1024);
247 // picture width & height in 16 pixel units
248 width_in_mb
= width
/ VL_MACROBLOCK_WIDTH
;
249 height_in_mb
= align(height
/ VL_MACROBLOCK_HEIGHT
, 2);
251 switch (u_reduce_video_profile(dec
->base
.profile
)) {
252 case PIPE_VIDEO_FORMAT_MPEG4_AVC
: {
253 if (!dec
->use_legacy
) {
254 unsigned fs_in_mb
= width_in_mb
* height_in_mb
;
255 unsigned alignment
= 64, num_dpb_buffer
;
257 if (dec
->stream_type
== RUVD_CODEC_H264_PERF
)
259 switch(dec
->base
.level
) {
261 num_dpb_buffer
= 8100 / fs_in_mb
;
264 num_dpb_buffer
= 18000 / fs_in_mb
;
267 num_dpb_buffer
= 20480 / fs_in_mb
;
270 num_dpb_buffer
= 32768 / fs_in_mb
;
273 num_dpb_buffer
= 34816 / fs_in_mb
;
276 num_dpb_buffer
= 110400 / fs_in_mb
;
279 num_dpb_buffer
= 184320 / fs_in_mb
;
282 num_dpb_buffer
= 184320 / fs_in_mb
;
286 max_references
= MAX2(MIN2(NUM_H264_REFS
, num_dpb_buffer
), max_references
);
287 dpb_size
= image_size
* max_references
;
288 dpb_size
+= max_references
* align(width_in_mb
* height_in_mb
* 192, alignment
);
289 dpb_size
+= align(width_in_mb
* height_in_mb
* 32, alignment
);
291 // the firmware seems to allways assume a minimum of ref frames
292 max_references
= MAX2(NUM_H264_REFS
, max_references
);
293 // reference picture buffer
294 dpb_size
= image_size
* max_references
;
295 // macroblock context buffer
296 dpb_size
+= width_in_mb
* height_in_mb
* max_references
* 192;
298 dpb_size
+= width_in_mb
* height_in_mb
* 32;
303 case PIPE_VIDEO_FORMAT_HEVC
:
304 if (dec
->base
.width
* dec
->base
.height
>= 4096*2000)
305 max_references
= MAX2(max_references
, 8);
307 max_references
= MAX2(max_references
, 17);
309 width
= align (width
, 16);
310 height
= align (height
, 16);
311 dpb_size
= align((width
* height
* 3) / 2, 256) * max_references
;
314 case PIPE_VIDEO_FORMAT_VC1
:
315 // the firmware seems to allways assume a minimum of ref frames
316 max_references
= MAX2(NUM_VC1_REFS
, max_references
);
318 // reference picture buffer
319 dpb_size
= image_size
* max_references
;
322 dpb_size
+= width_in_mb
* height_in_mb
* 128;
325 dpb_size
+= width_in_mb
* 64;
328 dpb_size
+= width_in_mb
* 128;
331 dpb_size
+= align(MAX2(width_in_mb
, height_in_mb
) * 7 * 16, 64);
334 case PIPE_VIDEO_FORMAT_MPEG12
:
335 // reference picture buffer, must be big enough for all frames
336 dpb_size
= image_size
* NUM_MPEG2_REFS
;
339 case PIPE_VIDEO_FORMAT_MPEG4
:
340 // reference picture buffer
341 dpb_size
= image_size
* max_references
;
344 dpb_size
+= width_in_mb
* height_in_mb
* 64;
347 dpb_size
+= align(width_in_mb
* height_in_mb
* 32, 64);
349 dpb_size
= MAX2(dpb_size
, 30 * 1024 * 1024);
353 // something is missing here
356 // at least use a sane default value
357 dpb_size
= 32 * 1024 * 1024;
363 /* free associated data in the video buffer callback */
364 static void ruvd_destroy_associated_data(void *data
)
366 /* NOOP, since we only use an intptr */
369 /* get h264 specific message bits */
370 static struct ruvd_h264
get_h264_msg(struct ruvd_decoder
*dec
, struct pipe_h264_picture_desc
*pic
)
372 struct ruvd_h264 result
;
374 memset(&result
, 0, sizeof(result
));
375 switch (pic
->base
.profile
) {
376 case PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE
:
377 result
.profile
= RUVD_H264_PROFILE_BASELINE
;
380 case PIPE_VIDEO_PROFILE_MPEG4_AVC_MAIN
:
381 result
.profile
= RUVD_H264_PROFILE_MAIN
;
384 case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH
:
385 result
.profile
= RUVD_H264_PROFILE_HIGH
;
393 result
.level
= dec
->base
.level
;
395 result
.sps_info_flags
= 0;
396 result
.sps_info_flags
|= pic
->pps
->sps
->direct_8x8_inference_flag
<< 0;
397 result
.sps_info_flags
|= pic
->pps
->sps
->mb_adaptive_frame_field_flag
<< 1;
398 result
.sps_info_flags
|= pic
->pps
->sps
->frame_mbs_only_flag
<< 2;
399 result
.sps_info_flags
|= pic
->pps
->sps
->delta_pic_order_always_zero_flag
<< 3;
401 result
.bit_depth_luma_minus8
= pic
->pps
->sps
->bit_depth_luma_minus8
;
402 result
.bit_depth_chroma_minus8
= pic
->pps
->sps
->bit_depth_chroma_minus8
;
403 result
.log2_max_frame_num_minus4
= pic
->pps
->sps
->log2_max_frame_num_minus4
;
404 result
.pic_order_cnt_type
= pic
->pps
->sps
->pic_order_cnt_type
;
405 result
.log2_max_pic_order_cnt_lsb_minus4
= pic
->pps
->sps
->log2_max_pic_order_cnt_lsb_minus4
;
407 switch (dec
->base
.chroma_format
) {
408 case PIPE_VIDEO_CHROMA_FORMAT_400
:
409 result
.chroma_format
= 0;
411 case PIPE_VIDEO_CHROMA_FORMAT_420
:
412 result
.chroma_format
= 1;
414 case PIPE_VIDEO_CHROMA_FORMAT_422
:
415 result
.chroma_format
= 2;
417 case PIPE_VIDEO_CHROMA_FORMAT_444
:
418 result
.chroma_format
= 3;
422 result
.pps_info_flags
= 0;
423 result
.pps_info_flags
|= pic
->pps
->transform_8x8_mode_flag
<< 0;
424 result
.pps_info_flags
|= pic
->pps
->redundant_pic_cnt_present_flag
<< 1;
425 result
.pps_info_flags
|= pic
->pps
->constrained_intra_pred_flag
<< 2;
426 result
.pps_info_flags
|= pic
->pps
->deblocking_filter_control_present_flag
<< 3;
427 result
.pps_info_flags
|= pic
->pps
->weighted_bipred_idc
<< 4;
428 result
.pps_info_flags
|= pic
->pps
->weighted_pred_flag
<< 6;
429 result
.pps_info_flags
|= pic
->pps
->bottom_field_pic_order_in_frame_present_flag
<< 7;
430 result
.pps_info_flags
|= pic
->pps
->entropy_coding_mode_flag
<< 8;
432 result
.num_slice_groups_minus1
= pic
->pps
->num_slice_groups_minus1
;
433 result
.slice_group_map_type
= pic
->pps
->slice_group_map_type
;
434 result
.slice_group_change_rate_minus1
= pic
->pps
->slice_group_change_rate_minus1
;
435 result
.pic_init_qp_minus26
= pic
->pps
->pic_init_qp_minus26
;
436 result
.chroma_qp_index_offset
= pic
->pps
->chroma_qp_index_offset
;
437 result
.second_chroma_qp_index_offset
= pic
->pps
->second_chroma_qp_index_offset
;
439 memcpy(result
.scaling_list_4x4
, pic
->pps
->ScalingList4x4
, 6*16);
440 memcpy(result
.scaling_list_8x8
, pic
->pps
->ScalingList8x8
, 2*64);
442 if (dec
->stream_type
== RUVD_CODEC_H264_PERF
) {
443 memcpy(dec
->it
, result
.scaling_list_4x4
, 6*16);
444 memcpy((dec
->it
+ 96), result
.scaling_list_8x8
, 2*64);
447 result
.num_ref_frames
= pic
->num_ref_frames
;
449 result
.num_ref_idx_l0_active_minus1
= pic
->num_ref_idx_l0_active_minus1
;
450 result
.num_ref_idx_l1_active_minus1
= pic
->num_ref_idx_l1_active_minus1
;
452 result
.frame_num
= pic
->frame_num
;
453 memcpy(result
.frame_num_list
, pic
->frame_num_list
, 4*16);
454 result
.curr_field_order_cnt_list
[0] = pic
->field_order_cnt
[0];
455 result
.curr_field_order_cnt_list
[1] = pic
->field_order_cnt
[1];
456 memcpy(result
.field_order_cnt_list
, pic
->field_order_cnt_list
, 4*16*2);
458 result
.decoded_pic_idx
= pic
->frame_num
;
463 /* get h265 specific message bits */
464 static struct ruvd_h265
get_h265_msg(struct ruvd_decoder
*dec
, struct pipe_video_buffer
*target
,
465 struct pipe_h265_picture_desc
*pic
)
467 struct ruvd_h265 result
;
470 memset(&result
, 0, sizeof(result
));
472 result
.sps_info_flags
= 0;
473 result
.sps_info_flags
|= pic
->pps
->sps
->scaling_list_enabled_flag
<< 0;
474 result
.sps_info_flags
|= pic
->pps
->sps
->amp_enabled_flag
<< 1;
475 result
.sps_info_flags
|= pic
->pps
->sps
->sample_adaptive_offset_enabled_flag
<< 2;
476 result
.sps_info_flags
|= pic
->pps
->sps
->pcm_enabled_flag
<< 3;
477 result
.sps_info_flags
|= pic
->pps
->sps
->pcm_loop_filter_disabled_flag
<< 4;
478 result
.sps_info_flags
|= pic
->pps
->sps
->long_term_ref_pics_present_flag
<< 5;
479 result
.sps_info_flags
|= pic
->pps
->sps
->sps_temporal_mvp_enabled_flag
<< 6;
480 result
.sps_info_flags
|= pic
->pps
->sps
->strong_intra_smoothing_enabled_flag
<< 7;
481 result
.sps_info_flags
|= pic
->pps
->sps
->separate_colour_plane_flag
<< 8;
482 if (((struct r600_common_screen
*)dec
->screen
)->family
== CHIP_CARRIZO
)
483 result
.sps_info_flags
|= 1 << 9;
485 result
.chroma_format
= pic
->pps
->sps
->chroma_format_idc
;
486 result
.bit_depth_luma_minus8
= pic
->pps
->sps
->bit_depth_luma_minus8
;
487 result
.bit_depth_chroma_minus8
= pic
->pps
->sps
->bit_depth_chroma_minus8
;
488 result
.log2_max_pic_order_cnt_lsb_minus4
= pic
->pps
->sps
->log2_max_pic_order_cnt_lsb_minus4
;
489 result
.sps_max_dec_pic_buffering_minus1
= pic
->pps
->sps
->sps_max_dec_pic_buffering_minus1
;
490 result
.log2_min_luma_coding_block_size_minus3
= pic
->pps
->sps
->log2_min_luma_coding_block_size_minus3
;
491 result
.log2_diff_max_min_luma_coding_block_size
= pic
->pps
->sps
->log2_diff_max_min_luma_coding_block_size
;
492 result
.log2_min_transform_block_size_minus2
= pic
->pps
->sps
->log2_min_transform_block_size_minus2
;
493 result
.log2_diff_max_min_transform_block_size
= pic
->pps
->sps
->log2_diff_max_min_transform_block_size
;
494 result
.max_transform_hierarchy_depth_inter
= pic
->pps
->sps
->max_transform_hierarchy_depth_inter
;
495 result
.max_transform_hierarchy_depth_intra
= pic
->pps
->sps
->max_transform_hierarchy_depth_intra
;
496 result
.pcm_sample_bit_depth_luma_minus1
= pic
->pps
->sps
->pcm_sample_bit_depth_luma_minus1
;
497 result
.pcm_sample_bit_depth_chroma_minus1
= pic
->pps
->sps
->pcm_sample_bit_depth_chroma_minus1
;
498 result
.log2_min_pcm_luma_coding_block_size_minus3
= pic
->pps
->sps
->log2_min_pcm_luma_coding_block_size_minus3
;
499 result
.log2_diff_max_min_pcm_luma_coding_block_size
= pic
->pps
->sps
->log2_diff_max_min_pcm_luma_coding_block_size
;
500 result
.num_short_term_ref_pic_sets
= pic
->pps
->sps
->num_short_term_ref_pic_sets
;
502 result
.pps_info_flags
= 0;
503 result
.pps_info_flags
|= pic
->pps
->dependent_slice_segments_enabled_flag
<< 0;
504 result
.pps_info_flags
|= pic
->pps
->output_flag_present_flag
<< 1;
505 result
.pps_info_flags
|= pic
->pps
->sign_data_hiding_enabled_flag
<< 2;
506 result
.pps_info_flags
|= pic
->pps
->cabac_init_present_flag
<< 3;
507 result
.pps_info_flags
|= pic
->pps
->constrained_intra_pred_flag
<< 4;
508 result
.pps_info_flags
|= pic
->pps
->transform_skip_enabled_flag
<< 5;
509 result
.pps_info_flags
|= pic
->pps
->cu_qp_delta_enabled_flag
<< 6;
510 result
.pps_info_flags
|= pic
->pps
->pps_slice_chroma_qp_offsets_present_flag
<< 7;
511 result
.pps_info_flags
|= pic
->pps
->weighted_pred_flag
<< 8;
512 result
.pps_info_flags
|= pic
->pps
->weighted_bipred_flag
<< 9;
513 result
.pps_info_flags
|= pic
->pps
->transquant_bypass_enabled_flag
<< 10;
514 result
.pps_info_flags
|= pic
->pps
->tiles_enabled_flag
<< 11;
515 result
.pps_info_flags
|= pic
->pps
->entropy_coding_sync_enabled_flag
<< 12;
516 result
.pps_info_flags
|= pic
->pps
->uniform_spacing_flag
<< 13;
517 result
.pps_info_flags
|= pic
->pps
->loop_filter_across_tiles_enabled_flag
<< 14;
518 result
.pps_info_flags
|= pic
->pps
->pps_loop_filter_across_slices_enabled_flag
<< 15;
519 result
.pps_info_flags
|= pic
->pps
->deblocking_filter_override_enabled_flag
<< 16;
520 result
.pps_info_flags
|= pic
->pps
->pps_deblocking_filter_disabled_flag
<< 17;
521 result
.pps_info_flags
|= pic
->pps
->lists_modification_present_flag
<< 18;
522 result
.pps_info_flags
|= pic
->pps
->slice_segment_header_extension_present_flag
<< 19;
523 //result.pps_info_flags |= pic->pps->deblocking_filter_control_present_flag; ???
525 result
.num_extra_slice_header_bits
= pic
->pps
->num_extra_slice_header_bits
;
526 result
.num_long_term_ref_pic_sps
= pic
->pps
->sps
->num_long_term_ref_pics_sps
;
527 result
.num_ref_idx_l0_default_active_minus1
= pic
->pps
->num_ref_idx_l0_default_active_minus1
;
528 result
.num_ref_idx_l1_default_active_minus1
= pic
->pps
->num_ref_idx_l1_default_active_minus1
;
529 result
.pps_cb_qp_offset
= pic
->pps
->pps_cb_qp_offset
;
530 result
.pps_cr_qp_offset
= pic
->pps
->pps_cr_qp_offset
;
531 result
.pps_beta_offset_div2
= pic
->pps
->pps_beta_offset_div2
;
532 result
.pps_tc_offset_div2
= pic
->pps
->pps_tc_offset_div2
;
533 result
.diff_cu_qp_delta_depth
= pic
->pps
->diff_cu_qp_delta_depth
;
534 result
.num_tile_columns_minus1
= pic
->pps
->num_tile_columns_minus1
;
535 result
.num_tile_rows_minus1
= pic
->pps
->num_tile_rows_minus1
;
536 result
.log2_parallel_merge_level_minus2
= pic
->pps
->log2_parallel_merge_level_minus2
;
537 result
.init_qp_minus26
= pic
->pps
->init_qp_minus26
;
539 for (i
= 0; i
< 19; ++i
)
540 result
.column_width_minus1
[i
] = pic
->pps
->column_width_minus1
[i
];
542 for (i
= 0; i
< 21; ++i
)
543 result
.row_height_minus1
[i
] = pic
->pps
->row_height_minus1
[i
];
545 result
.num_delta_pocs_ref_rps_idx
= pic
->NumDeltaPocsOfRefRpsIdx
;
546 result
.curr_idx
= pic
->CurrPicOrderCntVal
;
547 result
.curr_poc
= pic
->CurrPicOrderCntVal
;
549 vl_video_buffer_set_associated_data(target
, &dec
->base
,
550 (void *)(uintptr_t)pic
->CurrPicOrderCntVal
,
551 &ruvd_destroy_associated_data
);
553 for (i
= 0; i
< 16; ++i
) {
554 struct pipe_video_buffer
*ref
= pic
->ref
[i
];
555 uintptr_t ref_pic
= 0;
557 result
.poc_list
[i
] = pic
->PicOrderCntVal
[i
];
560 ref_pic
= (uintptr_t)vl_video_buffer_get_associated_data(ref
, &dec
->base
);
563 result
.ref_pic_list
[i
] = ref_pic
;
566 for (i
= 0; i
< 8; ++i
) {
567 result
.ref_pic_set_st_curr_before
[i
] = 0xFF;
568 result
.ref_pic_set_st_curr_after
[i
] = 0xFF;
569 result
.ref_pic_set_lt_curr
[i
] = 0xFF;
572 for (i
= 0; i
< pic
->NumPocStCurrBefore
; ++i
)
573 result
.ref_pic_set_st_curr_before
[i
] = pic
->RefPicSetStCurrBefore
[i
];
575 for (i
= 0; i
< pic
->NumPocStCurrAfter
; ++i
)
576 result
.ref_pic_set_st_curr_after
[i
] = pic
->RefPicSetStCurrAfter
[i
];
578 for (i
= 0; i
< pic
->NumPocLtCurr
; ++i
)
579 result
.ref_pic_set_lt_curr
[i
] = pic
->RefPicSetLtCurr
[i
];
581 for (i
= 0; i
< 6; ++i
)
582 result
.ucScalingListDCCoefSizeID2
[i
] = pic
->pps
->sps
->ScalingListDCCoeff16x16
[i
];
584 for (i
= 0; i
< 2; ++i
)
585 result
.ucScalingListDCCoefSizeID3
[i
] = pic
->pps
->sps
->ScalingListDCCoeff32x32
[i
];
587 memcpy(dec
->it
, pic
->pps
->sps
->ScalingList4x4
, 6 * 16);
588 memcpy(dec
->it
+ 96, pic
->pps
->sps
->ScalingList8x8
, 6 * 64);
589 memcpy(dec
->it
+ 480, pic
->pps
->sps
->ScalingList16x16
, 6 * 64);
590 memcpy(dec
->it
+ 864, pic
->pps
->sps
->ScalingList32x32
, 2 * 64);
599 NumShortTermPictureSliceHeaderBits;
600 NumLongTermPictureSliceHeaderBits;
608 /* get vc1 specific message bits */
609 static struct ruvd_vc1
get_vc1_msg(struct pipe_vc1_picture_desc
*pic
)
611 struct ruvd_vc1 result
;
613 memset(&result
, 0, sizeof(result
));
615 switch(pic
->base
.profile
) {
616 case PIPE_VIDEO_PROFILE_VC1_SIMPLE
:
617 result
.profile
= RUVD_VC1_PROFILE_SIMPLE
;
621 case PIPE_VIDEO_PROFILE_VC1_MAIN
:
622 result
.profile
= RUVD_VC1_PROFILE_MAIN
;
626 case PIPE_VIDEO_PROFILE_VC1_ADVANCED
:
627 result
.profile
= RUVD_VC1_PROFILE_ADVANCED
;
635 /* fields common for all profiles */
636 result
.sps_info_flags
|= pic
->postprocflag
<< 7;
637 result
.sps_info_flags
|= pic
->pulldown
<< 6;
638 result
.sps_info_flags
|= pic
->interlace
<< 5;
639 result
.sps_info_flags
|= pic
->tfcntrflag
<< 4;
640 result
.sps_info_flags
|= pic
->finterpflag
<< 3;
641 result
.sps_info_flags
|= pic
->psf
<< 1;
643 result
.pps_info_flags
|= pic
->range_mapy_flag
<< 31;
644 result
.pps_info_flags
|= pic
->range_mapy
<< 28;
645 result
.pps_info_flags
|= pic
->range_mapuv_flag
<< 27;
646 result
.pps_info_flags
|= pic
->range_mapuv
<< 24;
647 result
.pps_info_flags
|= pic
->multires
<< 21;
648 result
.pps_info_flags
|= pic
->maxbframes
<< 16;
649 result
.pps_info_flags
|= pic
->overlap
<< 11;
650 result
.pps_info_flags
|= pic
->quantizer
<< 9;
651 result
.pps_info_flags
|= pic
->panscan_flag
<< 7;
652 result
.pps_info_flags
|= pic
->refdist_flag
<< 6;
653 result
.pps_info_flags
|= pic
->vstransform
<< 0;
655 /* some fields only apply to main/advanced profile */
656 if (pic
->base
.profile
!= PIPE_VIDEO_PROFILE_VC1_SIMPLE
) {
657 result
.pps_info_flags
|= pic
->syncmarker
<< 20;
658 result
.pps_info_flags
|= pic
->rangered
<< 19;
659 result
.pps_info_flags
|= pic
->loopfilter
<< 5;
660 result
.pps_info_flags
|= pic
->fastuvmc
<< 4;
661 result
.pps_info_flags
|= pic
->extended_mv
<< 3;
662 result
.pps_info_flags
|= pic
->extended_dmv
<< 8;
663 result
.pps_info_flags
|= pic
->dquant
<< 1;
666 result
.chroma_format
= 1;
669 //(((unsigned int)(pPicParams->advance.reserved1)) << SPS_INFO_VC1_RESERVED_SHIFT)
672 uint8_t frame_coding_mode
673 uint8_t deblockEnable
680 /* extract the frame number from a referenced video buffer */
681 static uint32_t get_ref_pic_idx(struct ruvd_decoder
*dec
, struct pipe_video_buffer
*ref
)
683 uint32_t min
= MAX2(dec
->frame_number
, NUM_MPEG2_REFS
) - NUM_MPEG2_REFS
;
684 uint32_t max
= MAX2(dec
->frame_number
, 1) - 1;
687 /* seems to be the most sane fallback */
691 /* get the frame number from the associated data */
692 frame
= (uintptr_t)vl_video_buffer_get_associated_data(ref
, &dec
->base
);
694 /* limit the frame number to a valid range */
695 return MAX2(MIN2(frame
, max
), min
);
698 /* get mpeg2 specific msg bits */
699 static struct ruvd_mpeg2
get_mpeg2_msg(struct ruvd_decoder
*dec
,
700 struct pipe_mpeg12_picture_desc
*pic
)
702 const int *zscan
= pic
->alternate_scan
? vl_zscan_alternate
: vl_zscan_normal
;
703 struct ruvd_mpeg2 result
;
706 memset(&result
, 0, sizeof(result
));
707 result
.decoded_pic_idx
= dec
->frame_number
;
708 for (i
= 0; i
< 2; ++i
)
709 result
.ref_pic_idx
[i
] = get_ref_pic_idx(dec
, pic
->ref
[i
]);
711 result
.load_intra_quantiser_matrix
= 1;
712 result
.load_nonintra_quantiser_matrix
= 1;
714 for (i
= 0; i
< 64; ++i
) {
715 result
.intra_quantiser_matrix
[i
] = pic
->intra_matrix
[zscan
[i
]];
716 result
.nonintra_quantiser_matrix
[i
] = pic
->non_intra_matrix
[zscan
[i
]];
719 result
.profile_and_level_indication
= 0;
720 result
.chroma_format
= 0x1;
722 result
.picture_coding_type
= pic
->picture_coding_type
;
723 result
.f_code
[0][0] = pic
->f_code
[0][0] + 1;
724 result
.f_code
[0][1] = pic
->f_code
[0][1] + 1;
725 result
.f_code
[1][0] = pic
->f_code
[1][0] + 1;
726 result
.f_code
[1][1] = pic
->f_code
[1][1] + 1;
727 result
.intra_dc_precision
= pic
->intra_dc_precision
;
728 result
.pic_structure
= pic
->picture_structure
;
729 result
.top_field_first
= pic
->top_field_first
;
730 result
.frame_pred_frame_dct
= pic
->frame_pred_frame_dct
;
731 result
.concealment_motion_vectors
= pic
->concealment_motion_vectors
;
732 result
.q_scale_type
= pic
->q_scale_type
;
733 result
.intra_vlc_format
= pic
->intra_vlc_format
;
734 result
.alternate_scan
= pic
->alternate_scan
;
739 /* get mpeg4 specific msg bits */
740 static struct ruvd_mpeg4
get_mpeg4_msg(struct ruvd_decoder
*dec
,
741 struct pipe_mpeg4_picture_desc
*pic
)
743 struct ruvd_mpeg4 result
;
746 memset(&result
, 0, sizeof(result
));
747 result
.decoded_pic_idx
= dec
->frame_number
;
748 for (i
= 0; i
< 2; ++i
)
749 result
.ref_pic_idx
[i
] = get_ref_pic_idx(dec
, pic
->ref
[i
]);
751 result
.variant_type
= 0;
752 result
.profile_and_level_indication
= 0xF0; // ASP Level0
754 result
.video_object_layer_verid
= 0x5; // advanced simple
755 result
.video_object_layer_shape
= 0x0; // rectangular
757 result
.video_object_layer_width
= dec
->base
.width
;
758 result
.video_object_layer_height
= dec
->base
.height
;
760 result
.vop_time_increment_resolution
= pic
->vop_time_increment_resolution
;
762 result
.flags
|= pic
->short_video_header
<< 0;
763 //result.flags |= obmc_disable << 1;
764 result
.flags
|= pic
->interlaced
<< 2;
765 result
.flags
|= 1 << 3; // load_intra_quant_mat
766 result
.flags
|= 1 << 4; // load_nonintra_quant_mat
767 result
.flags
|= pic
->quarter_sample
<< 5;
768 result
.flags
|= 1 << 6; // complexity_estimation_disable
769 result
.flags
|= pic
->resync_marker_disable
<< 7;
770 //result.flags |= data_partitioned << 8;
771 //result.flags |= reversible_vlc << 9;
772 result
.flags
|= 0 << 10; // newpred_enable
773 result
.flags
|= 0 << 11; // reduced_resolution_vop_enable
774 //result.flags |= scalability << 12;
775 //result.flags |= is_object_layer_identifier << 13;
776 //result.flags |= fixed_vop_rate << 14;
777 //result.flags |= newpred_segment_type << 15;
779 result
.quant_type
= pic
->quant_type
;
781 for (i
= 0; i
< 64; ++i
) {
782 result
.intra_quant_mat
[i
] = pic
->intra_matrix
[vl_zscan_normal
[i
]];
783 result
.nonintra_quant_mat
[i
] = pic
->non_intra_matrix
[vl_zscan_normal
[i
]];
789 uint8_t vop_coding_type
790 uint8_t vop_fcode_forward
791 uint8_t vop_fcode_backward
792 uint8_t rounding_control
793 uint8_t alternate_vertical_scan_flag
794 uint8_t top_field_first
801 * destroy this video decoder
803 static void ruvd_destroy(struct pipe_video_codec
*decoder
)
805 struct ruvd_decoder
*dec
= (struct ruvd_decoder
*)decoder
;
810 map_msg_fb_it_buf(dec
);
811 memset(dec
->msg
, 0, sizeof(*dec
->msg
));
812 dec
->msg
->size
= sizeof(*dec
->msg
);
813 dec
->msg
->msg_type
= RUVD_MSG_DESTROY
;
814 dec
->msg
->stream_handle
= dec
->stream_handle
;
819 dec
->ws
->cs_destroy(dec
->cs
);
821 for (i
= 0; i
< NUM_BUFFERS
; ++i
) {
822 rvid_destroy_buffer(&dec
->msg_fb_it_buffers
[i
]);
823 rvid_destroy_buffer(&dec
->bs_buffers
[i
]);
826 rvid_destroy_buffer(&dec
->dpb
);
827 if (u_reduce_video_profile(dec
->base
.profile
) == PIPE_VIDEO_FORMAT_HEVC
)
828 rvid_destroy_buffer(&dec
->ctx
);
834 * start decoding of a new frame
836 static void ruvd_begin_frame(struct pipe_video_codec
*decoder
,
837 struct pipe_video_buffer
*target
,
838 struct pipe_picture_desc
*picture
)
840 struct ruvd_decoder
*dec
= (struct ruvd_decoder
*)decoder
;
845 frame
= ++dec
->frame_number
;
846 vl_video_buffer_set_associated_data(target
, decoder
, (void *)frame
,
847 &ruvd_destroy_associated_data
);
850 dec
->bs_ptr
= dec
->ws
->buffer_map(
851 dec
->bs_buffers
[dec
->cur_buffer
].res
->cs_buf
,
852 dec
->cs
, PIPE_TRANSFER_WRITE
);
856 * decode a macroblock
858 static void ruvd_decode_macroblock(struct pipe_video_codec
*decoder
,
859 struct pipe_video_buffer
*target
,
860 struct pipe_picture_desc
*picture
,
861 const struct pipe_macroblock
*macroblocks
,
862 unsigned num_macroblocks
)
864 /* not supported (yet) */
871 static void ruvd_decode_bitstream(struct pipe_video_codec
*decoder
,
872 struct pipe_video_buffer
*target
,
873 struct pipe_picture_desc
*picture
,
874 unsigned num_buffers
,
875 const void * const *buffers
,
876 const unsigned *sizes
)
878 struct ruvd_decoder
*dec
= (struct ruvd_decoder
*)decoder
;
886 for (i
= 0; i
< num_buffers
; ++i
) {
887 struct rvid_buffer
*buf
= &dec
->bs_buffers
[dec
->cur_buffer
];
888 unsigned new_size
= dec
->bs_size
+ sizes
[i
];
890 if (new_size
> buf
->res
->buf
->size
) {
891 dec
->ws
->buffer_unmap(buf
->res
->cs_buf
);
892 if (!rvid_resize_buffer(dec
->screen
, dec
->cs
, buf
, new_size
)) {
893 RVID_ERR("Can't resize bitstream buffer!");
897 dec
->bs_ptr
= dec
->ws
->buffer_map(buf
->res
->cs_buf
, dec
->cs
,
898 PIPE_TRANSFER_WRITE
);
902 dec
->bs_ptr
+= dec
->bs_size
;
905 memcpy(dec
->bs_ptr
, buffers
[i
], sizes
[i
]);
906 dec
->bs_size
+= sizes
[i
];
907 dec
->bs_ptr
+= sizes
[i
];
912 * end decoding of the current frame
914 static void ruvd_end_frame(struct pipe_video_codec
*decoder
,
915 struct pipe_video_buffer
*target
,
916 struct pipe_picture_desc
*picture
)
918 struct ruvd_decoder
*dec
= (struct ruvd_decoder
*)decoder
;
919 struct radeon_winsys_cs_handle
*dt
;
920 struct rvid_buffer
*msg_fb_it_buf
, *bs_buf
;
928 msg_fb_it_buf
= &dec
->msg_fb_it_buffers
[dec
->cur_buffer
];
929 bs_buf
= &dec
->bs_buffers
[dec
->cur_buffer
];
931 bs_size
= align(dec
->bs_size
, 128);
932 memset(dec
->bs_ptr
, 0, bs_size
- dec
->bs_size
);
933 dec
->ws
->buffer_unmap(bs_buf
->res
->cs_buf
);
935 map_msg_fb_it_buf(dec
);
936 dec
->msg
->size
= sizeof(*dec
->msg
);
937 dec
->msg
->msg_type
= RUVD_MSG_DECODE
;
938 dec
->msg
->stream_handle
= dec
->stream_handle
;
939 dec
->msg
->status_report_feedback_number
= dec
->frame_number
;
941 dec
->msg
->body
.decode
.stream_type
= dec
->stream_type
;
942 dec
->msg
->body
.decode
.decode_flags
= 0x1;
943 dec
->msg
->body
.decode
.width_in_samples
= dec
->base
.width
;
944 dec
->msg
->body
.decode
.height_in_samples
= dec
->base
.height
;
946 dec
->msg
->body
.decode
.dpb_size
= dec
->dpb
.res
->buf
->size
;
947 dec
->msg
->body
.decode
.bsd_size
= bs_size
;
948 dec
->msg
->body
.decode
.db_pitch
= dec
->base
.width
;
950 dt
= dec
->set_dtb(dec
->msg
, (struct vl_video_buffer
*)target
);
952 switch (u_reduce_video_profile(picture
->profile
)) {
953 case PIPE_VIDEO_FORMAT_MPEG4_AVC
:
954 dec
->msg
->body
.decode
.codec
.h264
= get_h264_msg(dec
, (struct pipe_h264_picture_desc
*)picture
);
957 case PIPE_VIDEO_FORMAT_HEVC
:
958 dec
->msg
->body
.decode
.codec
.h265
= get_h265_msg(dec
, target
, (struct pipe_h265_picture_desc
*)picture
);
961 case PIPE_VIDEO_FORMAT_VC1
:
962 dec
->msg
->body
.decode
.codec
.vc1
= get_vc1_msg((struct pipe_vc1_picture_desc
*)picture
);
965 case PIPE_VIDEO_FORMAT_MPEG12
:
966 dec
->msg
->body
.decode
.codec
.mpeg2
= get_mpeg2_msg(dec
, (struct pipe_mpeg12_picture_desc
*)picture
);
969 case PIPE_VIDEO_FORMAT_MPEG4
:
970 dec
->msg
->body
.decode
.codec
.mpeg4
= get_mpeg4_msg(dec
, (struct pipe_mpeg4_picture_desc
*)picture
);
978 dec
->msg
->body
.decode
.db_surf_tile_config
= dec
->msg
->body
.decode
.dt_surf_tile_config
;
979 dec
->msg
->body
.decode
.extension_support
= 0x1;
981 /* set at least the feedback buffer size */
982 dec
->fb
[0] = FB_BUFFER_SIZE
;
986 send_cmd(dec
, RUVD_CMD_DPB_BUFFER
, dec
->dpb
.res
->cs_buf
, 0,
987 RADEON_USAGE_READWRITE
, RADEON_DOMAIN_VRAM
);
988 if (u_reduce_video_profile(picture
->profile
) == PIPE_VIDEO_FORMAT_HEVC
) {
989 send_cmd(dec
, RUVD_CMD_CONTEXT_BUFFER
, dec
->ctx
.res
->cs_buf
, 0,
990 RADEON_USAGE_READWRITE
, RADEON_DOMAIN_VRAM
);
992 send_cmd(dec
, RUVD_CMD_BITSTREAM_BUFFER
, bs_buf
->res
->cs_buf
,
993 0, RADEON_USAGE_READ
, RADEON_DOMAIN_GTT
);
994 send_cmd(dec
, RUVD_CMD_DECODING_TARGET_BUFFER
, dt
, 0,
995 RADEON_USAGE_WRITE
, RADEON_DOMAIN_VRAM
);
996 send_cmd(dec
, RUVD_CMD_FEEDBACK_BUFFER
, msg_fb_it_buf
->res
->cs_buf
,
997 FB_BUFFER_OFFSET
, RADEON_USAGE_WRITE
, RADEON_DOMAIN_GTT
);
999 send_cmd(dec
, RUVD_CMD_ITSCALING_TABLE_BUFFER
, msg_fb_it_buf
->res
->cs_buf
,
1000 FB_BUFFER_OFFSET
+ FB_BUFFER_SIZE
, RADEON_USAGE_READ
, RADEON_DOMAIN_GTT
);
1001 set_reg(dec
, RUVD_ENGINE_CNTL
, 1);
1008 * flush any outstanding command buffers to the hardware
1010 static void ruvd_flush(struct pipe_video_codec
*decoder
)
1015 * create and UVD decoder
1017 struct pipe_video_codec
*ruvd_create_decoder(struct pipe_context
*context
,
1018 const struct pipe_video_codec
*templ
,
1019 ruvd_set_dtb set_dtb
)
1021 struct radeon_winsys
* ws
= ((struct r600_common_context
*)context
)->ws
;
1022 struct r600_common_context
*rctx
= (struct r600_common_context
*)context
;
1024 unsigned width
= templ
->width
, height
= templ
->height
;
1025 unsigned bs_buf_size
;
1026 struct radeon_info info
;
1027 struct ruvd_decoder
*dec
;
1030 ws
->query_info(ws
, &info
);
1032 switch(u_reduce_video_profile(templ
->profile
)) {
1033 case PIPE_VIDEO_FORMAT_MPEG12
:
1034 if (templ
->entrypoint
> PIPE_VIDEO_ENTRYPOINT_BITSTREAM
|| info
.family
< CHIP_PALM
)
1035 return vl_create_mpeg12_decoder(context
, templ
);
1038 case PIPE_VIDEO_FORMAT_MPEG4
:
1039 case PIPE_VIDEO_FORMAT_MPEG4_AVC
:
1040 width
= align(width
, VL_MACROBLOCK_WIDTH
);
1041 height
= align(height
, VL_MACROBLOCK_HEIGHT
);
1049 dec
= CALLOC_STRUCT(ruvd_decoder
);
1054 if (info
.drm_major
< 3)
1055 dec
->use_legacy
= TRUE
;
1058 dec
->base
.context
= context
;
1059 dec
->base
.width
= width
;
1060 dec
->base
.height
= height
;
1062 dec
->base
.destroy
= ruvd_destroy
;
1063 dec
->base
.begin_frame
= ruvd_begin_frame
;
1064 dec
->base
.decode_macroblock
= ruvd_decode_macroblock
;
1065 dec
->base
.decode_bitstream
= ruvd_decode_bitstream
;
1066 dec
->base
.end_frame
= ruvd_end_frame
;
1067 dec
->base
.flush
= ruvd_flush
;
1069 dec
->stream_type
= profile2stream_type(dec
, info
.family
);
1070 dec
->set_dtb
= set_dtb
;
1071 dec
->stream_handle
= rvid_alloc_stream_handle();
1072 dec
->screen
= context
->screen
;
1074 dec
->cs
= ws
->cs_create(rctx
->ctx
, RING_UVD
, NULL
, NULL
, NULL
);
1076 RVID_ERR("Can't get command submission context.\n");
1080 bs_buf_size
= width
* height
* 512 / (16 * 16);
1081 for (i
= 0; i
< NUM_BUFFERS
; ++i
) {
1082 unsigned msg_fb_it_size
= FB_BUFFER_OFFSET
+ FB_BUFFER_SIZE
;
1083 STATIC_ASSERT(sizeof(struct ruvd_msg
) <= FB_BUFFER_OFFSET
);
1085 msg_fb_it_size
+= IT_SCALING_TABLE_SIZE
;
1086 if (!rvid_create_buffer(dec
->screen
, &dec
->msg_fb_it_buffers
[i
],
1087 msg_fb_it_size
, PIPE_USAGE_STAGING
)) {
1088 RVID_ERR("Can't allocated message buffers.\n");
1092 if (!rvid_create_buffer(dec
->screen
, &dec
->bs_buffers
[i
],
1093 bs_buf_size
, PIPE_USAGE_STAGING
)) {
1094 RVID_ERR("Can't allocated bitstream buffers.\n");
1098 rvid_clear_buffer(context
, &dec
->msg_fb_it_buffers
[i
]);
1099 rvid_clear_buffer(context
, &dec
->bs_buffers
[i
]);
1102 dpb_size
= calc_dpb_size(dec
);
1104 if (!rvid_create_buffer(dec
->screen
, &dec
->dpb
, dpb_size
, PIPE_USAGE_DEFAULT
)) {
1105 RVID_ERR("Can't allocated dpb.\n");
1109 rvid_clear_buffer(context
, &dec
->dpb
);
1111 if (u_reduce_video_profile(dec
->base
.profile
) == PIPE_VIDEO_FORMAT_HEVC
) {
1112 unsigned ctx_size
= calc_ctx_size(dec
);
1113 if (!rvid_create_buffer(dec
->screen
, &dec
->ctx
, ctx_size
, PIPE_USAGE_DEFAULT
)) {
1114 RVID_ERR("Can't allocated context buffer.\n");
1117 rvid_clear_buffer(context
, &dec
->ctx
);
1120 map_msg_fb_it_buf(dec
);
1121 dec
->msg
->size
= sizeof(*dec
->msg
);
1122 dec
->msg
->msg_type
= RUVD_MSG_CREATE
;
1123 dec
->msg
->stream_handle
= dec
->stream_handle
;
1124 dec
->msg
->body
.create
.stream_type
= dec
->stream_type
;
1125 dec
->msg
->body
.create
.width_in_samples
= dec
->base
.width
;
1126 dec
->msg
->body
.create
.height_in_samples
= dec
->base
.height
;
1127 dec
->msg
->body
.create
.dpb_size
= dpb_size
;
1135 if (dec
->cs
) dec
->ws
->cs_destroy(dec
->cs
);
1137 for (i
= 0; i
< NUM_BUFFERS
; ++i
) {
1138 rvid_destroy_buffer(&dec
->msg_fb_it_buffers
[i
]);
1139 rvid_destroy_buffer(&dec
->bs_buffers
[i
]);
1142 rvid_destroy_buffer(&dec
->dpb
);
1143 if (u_reduce_video_profile(dec
->base
.profile
) == PIPE_VIDEO_FORMAT_HEVC
)
1144 rvid_destroy_buffer(&dec
->ctx
);
1151 /* calculate top/bottom offset */
1152 static unsigned texture_offset(struct radeon_surf
*surface
, unsigned layer
)
1154 return surface
->level
[0].offset
+
1155 layer
* surface
->level
[0].slice_size
;
1158 /* hw encode the aspect of macro tiles */
1159 static unsigned macro_tile_aspect(unsigned macro_tile_aspect
)
1161 switch (macro_tile_aspect
) {
1163 case 1: macro_tile_aspect
= 0; break;
1164 case 2: macro_tile_aspect
= 1; break;
1165 case 4: macro_tile_aspect
= 2; break;
1166 case 8: macro_tile_aspect
= 3; break;
1168 return macro_tile_aspect
;
1171 /* hw encode the bank width and height */
1172 static unsigned bank_wh(unsigned bankwh
)
1176 case 1: bankwh
= 0; break;
1177 case 2: bankwh
= 1; break;
1178 case 4: bankwh
= 2; break;
1179 case 8: bankwh
= 3; break;
1185 * fill decoding target field from the luma and chroma surfaces
1187 void ruvd_set_dt_surfaces(struct ruvd_msg
*msg
, struct radeon_surf
*luma
,
1188 struct radeon_surf
*chroma
)
1190 msg
->body
.decode
.dt_pitch
= luma
->level
[0].pitch_bytes
;
1191 switch (luma
->level
[0].mode
) {
1192 case RADEON_SURF_MODE_LINEAR_ALIGNED
:
1193 msg
->body
.decode
.dt_tiling_mode
= RUVD_TILE_LINEAR
;
1194 msg
->body
.decode
.dt_array_mode
= RUVD_ARRAY_MODE_LINEAR
;
1196 case RADEON_SURF_MODE_1D
:
1197 msg
->body
.decode
.dt_tiling_mode
= RUVD_TILE_8X8
;
1198 msg
->body
.decode
.dt_array_mode
= RUVD_ARRAY_MODE_1D_THIN
;
1200 case RADEON_SURF_MODE_2D
:
1201 msg
->body
.decode
.dt_tiling_mode
= RUVD_TILE_8X8
;
1202 msg
->body
.decode
.dt_array_mode
= RUVD_ARRAY_MODE_2D_THIN
;
1209 msg
->body
.decode
.dt_luma_top_offset
= texture_offset(luma
, 0);
1210 msg
->body
.decode
.dt_chroma_top_offset
= texture_offset(chroma
, 0);
1211 if (msg
->body
.decode
.dt_field_mode
) {
1212 msg
->body
.decode
.dt_luma_bottom_offset
= texture_offset(luma
, 1);
1213 msg
->body
.decode
.dt_chroma_bottom_offset
= texture_offset(chroma
, 1);
1215 msg
->body
.decode
.dt_luma_bottom_offset
= msg
->body
.decode
.dt_luma_top_offset
;
1216 msg
->body
.decode
.dt_chroma_bottom_offset
= msg
->body
.decode
.dt_chroma_top_offset
;
1219 assert(luma
->bankw
== chroma
->bankw
);
1220 assert(luma
->bankh
== chroma
->bankh
);
1221 assert(luma
->mtilea
== chroma
->mtilea
);
1223 msg
->body
.decode
.dt_surf_tile_config
|= RUVD_BANK_WIDTH(bank_wh(luma
->bankw
));
1224 msg
->body
.decode
.dt_surf_tile_config
|= RUVD_BANK_HEIGHT(bank_wh(luma
->bankh
));
1225 msg
->body
.decode
.dt_surf_tile_config
|= RUVD_MACRO_TILE_ASPECT_RATIO(macro_tile_aspect(luma
->mtilea
));