mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-02-03 02:10:24 +01:00
radeonsi/vcn: Ensure DPB has as many buffers as references
In case of corrupted streams (or application bugs) the number
of references may not be equal to DPB size. This needs to be fixed by
filling the missing slots with dummy buffers.
Cc: mesa-stable
Reviewed-by: Leo Liu <leo.liu@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29055>
(cherry picked from commit 47b6ca47d0)
This commit is contained in:
parent
36b162f629
commit
7adccd14fa
3 changed files with 45 additions and 14 deletions
|
|
@ -564,7 +564,7 @@
|
|||
"description": "radeonsi/vcn: Ensure DPB has as many buffers as references",
|
||||
"nominated": true,
|
||||
"nomination_type": 0,
|
||||
"resolution": 0,
|
||||
"resolution": 1,
|
||||
"main_sha": null,
|
||||
"because_sha": null,
|
||||
"notes": null
|
||||
|
|
|
|||
|
|
@ -279,7 +279,8 @@ static rvcn_dec_message_avc_t get_h264_msg(struct radeon_decoder *dec,
|
|||
dec->ref_codec.bts = CODEC_8_BITS;
|
||||
dec->ref_codec.index = result.decoded_pic_idx;
|
||||
dec->ref_codec.ref_size = 16;
|
||||
memset(dec->ref_codec.ref_list, 0xff, sizeof(dec->ref_codec.ref_list));
|
||||
dec->ref_codec.num_refs = result.curr_pic_ref_frame_num;
|
||||
STATIC_ASSERT(sizeof(dec->ref_codec.ref_list) == sizeof(result.ref_frame_list));
|
||||
memcpy(dec->ref_codec.ref_list, result.ref_frame_list, sizeof(result.ref_frame_list));
|
||||
}
|
||||
|
||||
|
|
@ -292,7 +293,7 @@ static rvcn_dec_message_hevc_t get_h265_msg(struct radeon_decoder *dec,
|
|||
struct pipe_h265_picture_desc *pic)
|
||||
{
|
||||
rvcn_dec_message_hevc_t result;
|
||||
unsigned i, j;
|
||||
unsigned i, j, num_refs = 0;
|
||||
|
||||
memset(&result, 0, sizeof(result));
|
||||
result.sps_info_flags = 0;
|
||||
|
|
@ -413,9 +414,10 @@ static rvcn_dec_message_hevc_t get_h265_msg(struct radeon_decoder *dec,
|
|||
|
||||
result.poc_list[i] = pic->PicOrderCntVal[i];
|
||||
|
||||
if (ref)
|
||||
if (ref) {
|
||||
ref_pic = (uintptr_t)vl_video_buffer_get_associated_data(ref, &dec->base);
|
||||
else
|
||||
num_refs++;
|
||||
} else
|
||||
ref_pic = 0x7F;
|
||||
result.ref_pic_list[i] = ref_pic;
|
||||
}
|
||||
|
|
@ -469,7 +471,8 @@ static rvcn_dec_message_hevc_t get_h265_msg(struct radeon_decoder *dec,
|
|||
CODEC_10_BITS : CODEC_8_BITS;
|
||||
dec->ref_codec.index = result.curr_idx;
|
||||
dec->ref_codec.ref_size = 15;
|
||||
memset(dec->ref_codec.ref_list, 0x7f, sizeof(dec->ref_codec.ref_list));
|
||||
dec->ref_codec.num_refs = num_refs;
|
||||
STATIC_ASSERT(sizeof(dec->ref_codec.ref_list) == sizeof(result.ref_pic_list));
|
||||
memcpy(dec->ref_codec.ref_list, result.ref_pic_list, sizeof(result.ref_pic_list));
|
||||
}
|
||||
return result;
|
||||
|
|
@ -507,7 +510,7 @@ static rvcn_dec_message_vp9_t get_vp9_msg(struct radeon_decoder *dec,
|
|||
struct pipe_vp9_picture_desc *pic)
|
||||
{
|
||||
rvcn_dec_message_vp9_t result;
|
||||
unsigned i ,j;
|
||||
unsigned i, j, num_refs = 0;
|
||||
|
||||
memset(&result, 0, sizeof(result));
|
||||
|
||||
|
|
@ -641,9 +644,13 @@ static rvcn_dec_message_vp9_t get_vp9_msg(struct radeon_decoder *dec,
|
|||
get_current_pic_index(dec, target, &result.curr_pic_idx);
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
result.ref_frame_map[i] =
|
||||
(pic->ref[i]) ? (uintptr_t)vl_video_buffer_get_associated_data(pic->ref[i], &dec->base)
|
||||
: 0x7f;
|
||||
uintptr_t ref_frame;
|
||||
if (pic->ref[i]) {
|
||||
ref_frame = (uintptr_t)vl_video_buffer_get_associated_data(pic->ref[i], &dec->base);
|
||||
num_refs++;
|
||||
} else
|
||||
ref_frame = 0x7f;
|
||||
result.ref_frame_map[i] = ref_frame;
|
||||
}
|
||||
|
||||
result.frame_refs[0] = result.ref_frame_map[pic->picture_parameter.pic_fields.last_ref_frame];
|
||||
|
|
@ -669,6 +676,7 @@ static rvcn_dec_message_vp9_t get_vp9_msg(struct radeon_decoder *dec,
|
|||
CODEC_10_BITS : CODEC_8_BITS;
|
||||
dec->ref_codec.index = result.curr_pic_idx;
|
||||
dec->ref_codec.ref_size = 8;
|
||||
dec->ref_codec.num_refs = num_refs;
|
||||
memset(dec->ref_codec.ref_list, 0x7f, sizeof(dec->ref_codec.ref_list));
|
||||
memcpy(dec->ref_codec.ref_list, result.ref_frame_map, sizeof(result.ref_frame_map));
|
||||
}
|
||||
|
|
@ -959,7 +967,7 @@ static rvcn_dec_message_av1_t get_av1_msg(struct radeon_decoder *dec,
|
|||
struct pipe_av1_picture_desc *pic)
|
||||
{
|
||||
rvcn_dec_message_av1_t result;
|
||||
unsigned i, j;
|
||||
unsigned i, j, num_refs = 0;
|
||||
uint16_t tile_count = pic->picture_parameter.tile_cols * pic->picture_parameter.tile_rows;
|
||||
|
||||
memset(&result, 0, sizeof(result));
|
||||
|
|
@ -1151,9 +1159,13 @@ static rvcn_dec_message_av1_t get_av1_msg(struct radeon_decoder *dec,
|
|||
result.order_hint_bits = pic->picture_parameter.order_hint_bits_minus_1 + 1;
|
||||
|
||||
for (i = 0; i < NUM_AV1_REFS; ++i) {
|
||||
result.ref_frame_map[i] =
|
||||
(pic->ref[i]) ? (uintptr_t)vl_video_buffer_get_associated_data(pic->ref[i], &dec->base)
|
||||
: 0x7f;
|
||||
uintptr_t ref_frame;
|
||||
if (pic->ref[i]) {
|
||||
ref_frame = (uintptr_t)vl_video_buffer_get_associated_data(pic->ref[i], &dec->base);
|
||||
num_refs++;
|
||||
} else
|
||||
ref_frame = 0x7f;
|
||||
result.ref_frame_map[i] = ref_frame;
|
||||
}
|
||||
for (i = 0; i < NUM_AV1_REFS_PER_FRAME; ++i)
|
||||
result.frame_refs[i] = result.ref_frame_map[pic->picture_parameter.ref_frame_idx[i]];
|
||||
|
|
@ -1300,6 +1312,7 @@ static rvcn_dec_message_av1_t get_av1_msg(struct radeon_decoder *dec,
|
|||
dec->ref_codec.bts = pic->picture_parameter.bit_depth_idx ? CODEC_10_BITS : CODEC_8_BITS;
|
||||
dec->ref_codec.index = result.curr_pic_idx;
|
||||
dec->ref_codec.ref_size = 8;
|
||||
dec->ref_codec.num_refs = num_refs;
|
||||
memset(dec->ref_codec.ref_list, 0x7f, sizeof(dec->ref_codec.ref_list));
|
||||
memcpy(dec->ref_codec.ref_list, result.ref_frame_map, sizeof(result.ref_frame_map));
|
||||
}
|
||||
|
|
@ -1887,6 +1900,23 @@ static unsigned rvcn_dec_dynamic_dpb_t2_message(struct radeon_decoder *dec, rvcn
|
|||
list_addtail(&dpb->list, &dec->dpb_ref_list);
|
||||
}
|
||||
|
||||
if (dynamic_dpb_t2->dpbArraySize < dec->ref_codec.num_refs) {
|
||||
struct rvcn_dec_dynamic_dpb_t2 *d =
|
||||
list_first_entry(&dec->dpb_ref_list, struct rvcn_dec_dynamic_dpb_t2, list);
|
||||
addr = dec->ws->buffer_get_virtual_address(d->dpb.res->buf);
|
||||
if (!addr && dummy)
|
||||
addr = dec->ws->buffer_get_virtual_address(dummy->dpb.res->buf);
|
||||
assert(addr);
|
||||
for (i = 0; i < dec->ref_codec.num_refs; ++i) {
|
||||
if (dynamic_dpb_t2->dpbAddrLo[i] || dynamic_dpb_t2->dpbAddrHi[i])
|
||||
continue;
|
||||
dynamic_dpb_t2->dpbAddrLo[i] = addr;
|
||||
dynamic_dpb_t2->dpbAddrHi[i] = addr >> 32;
|
||||
++dynamic_dpb_t2->dpbArraySize;
|
||||
}
|
||||
assert(dynamic_dpb_t2->dpbArraySize == dec->ref_codec.num_refs);
|
||||
}
|
||||
|
||||
dec->ws->cs_add_buffer(&dec->cs, dpb->dpb.res->buf,
|
||||
RADEON_USAGE_READWRITE | RADEON_USAGE_SYNCHRONIZED, RADEON_DOMAIN_VRAM);
|
||||
addr = dec->ws->buffer_get_virtual_address(dpb->dpb.res->buf);
|
||||
|
|
|
|||
|
|
@ -121,6 +121,7 @@ struct radeon_decoder {
|
|||
} bts;
|
||||
uint8_t index;
|
||||
unsigned ref_size;
|
||||
unsigned num_refs;
|
||||
uint8_t ref_list[16];
|
||||
} ref_codec;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue