From e9956932bbf8d675abd5cc063f43e29de2fc4358 Mon Sep 17 00:00:00 2001 From: Benjamin Cheng Date: Wed, 26 Nov 2025 17:49:01 -0500 Subject: [PATCH] radv/video: Fix H264/H265 reference selection The order of pReferenceSlots is not well-defined by spec. Instead we need to look at the RefPicList0/1 which provides slot indices. Cc: mesa-stable Reviewed-by: David Rosca (cherry picked from commit ab56ce154bbb7fbec19ccffb40cf4c1e8085230d) Part-of: --- .pick_status.json | 2 +- src/amd/vulkan/radv_video.c | 1 - src/amd/vulkan/radv_video.h | 2 ++ src/amd/vulkan/radv_video_enc.c | 27 ++++++++++++++++++--------- 4 files changed, 21 insertions(+), 11 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index c4fecdaf5b7..adf64bd4d0d 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -114,7 +114,7 @@ "description": "radv/video: Fix H264/H265 reference selection", "nominated": true, "nomination_type": 1, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": null, "notes": null diff --git a/src/amd/vulkan/radv_video.c b/src/amd/vulkan/radv_video.c index 73a4e5cf8e8..447495f918b 100644 --- a/src/amd/vulkan/radv_video.c +++ b/src/amd/vulkan/radv_video.c @@ -24,7 +24,6 @@ #include "radv_image_view.h" #include "radv_video.h" -#define RADV_VIDEO_H264_MAX_DPB_SLOTS 17 #define RADV_VIDEO_H264_MAX_NUM_REF_FRAME 16 #define RADV_VIDEO_H265_MAX_DPB_SLOTS 17 #define RADV_VIDEO_H265_MAX_NUM_REF_FRAME 15 diff --git a/src/amd/vulkan/radv_video.h b/src/amd/vulkan/radv_video.h index 2c2ad32f2a4..b892c7ae37d 100644 --- a/src/amd/vulkan/radv_video.h +++ b/src/amd/vulkan/radv_video.h @@ -35,6 +35,8 @@ struct radv_cmd_stream; #define RADV_ENC_FEEDBACK_STATUS_IDX 10 +#define RADV_VIDEO_H264_MAX_DPB_SLOTS 17 + struct radv_vid_mem { struct radv_device_memory *mem; VkDeviceSize offset; diff --git a/src/amd/vulkan/radv_video_enc.c b/src/amd/vulkan/radv_video_enc.c index ae04998cb11..f06fbbb7e3d 100644 --- a/src/amd/vulkan/radv_video_enc.c +++ b/src/amd/vulkan/radv_video_enc.c @@ -1839,7 +1839,7 @@ radv_enc_params(struct radv_cmd_buffer *cmd_buffer, const VkVideoEncodeInfoKHR * switch (h264_pic->primary_pic_type) { case STD_VIDEO_H264_PICTURE_TYPE_P: case STD_VIDEO_H264_PICTURE_TYPE_B: - slot_idx = enc_info->pReferenceSlots[0].slotIndex; + slot_idx = h264_pic->pRefLists->RefPicList0[0]; break; default: break; @@ -1850,7 +1850,7 @@ radv_enc_params(struct radv_cmd_buffer *cmd_buffer, const VkVideoEncodeInfoKHR * switch (h265_pic->pic_type) { case STD_VIDEO_H265_PICTURE_TYPE_P: case STD_VIDEO_H265_PICTURE_TYPE_B: - slot_idx = enc_info->pReferenceSlots[0].slotIndex; + slot_idx = h265_pic->pRefLists->RefPicList0[0]; break; default: break; @@ -1908,6 +1908,12 @@ radv_enc_params_h264(struct radv_cmd_buffer *cmd_buffer, const VkVideoEncodeInfo assert(h264_picture_info); + unsigned slot_to_ref_idx[RADV_VIDEO_H264_MAX_DPB_SLOTS]; + memset(slot_to_ref_idx, 0xFF, sizeof(slot_to_ref_idx)); + for (unsigned idx = 0; idx < enc_info->referenceSlotCount; idx++) { + slot_to_ref_idx[enc_info->pReferenceSlots[idx].slotIndex] = idx; + } + const StdVideoEncodeH264PictureInfo *h264_pic = h264_picture_info->pStdPictureInfo; unsigned slot_idx_0 = 0xffffffff; unsigned slot_idx_1 = 0xffffffff; @@ -1916,14 +1922,17 @@ radv_enc_params_h264(struct radv_cmd_buffer *cmd_buffer, const VkVideoEncodeInfo switch (h264_pic->primary_pic_type) { case STD_VIDEO_H264_PICTURE_TYPE_P: - slot_idx_0 = enc_info->pReferenceSlots[0].slotIndex; - slot_info_0 = vk_find_struct_const(enc_info->pReferenceSlots[0].pNext, VIDEO_ENCODE_H264_DPB_SLOT_INFO_KHR); + slot_idx_0 = h264_pic->pRefLists->RefPicList0[0]; + slot_info_0 = vk_find_struct_const(enc_info->pReferenceSlots[slot_to_ref_idx[slot_idx_0]].pNext, + VIDEO_ENCODE_H264_DPB_SLOT_INFO_KHR); break; case STD_VIDEO_H264_PICTURE_TYPE_B: - slot_idx_0 = enc_info->pReferenceSlots[0].slotIndex; - slot_idx_1 = enc_info->pReferenceSlots[1].slotIndex; - slot_info_0 = vk_find_struct_const(enc_info->pReferenceSlots[0].pNext, VIDEO_ENCODE_H264_DPB_SLOT_INFO_KHR); - slot_info_1 = vk_find_struct_const(enc_info->pReferenceSlots[1].pNext, VIDEO_ENCODE_H264_DPB_SLOT_INFO_KHR); + slot_idx_0 = h264_pic->pRefLists->RefPicList0[0]; + slot_idx_1 = h264_pic->pRefLists->RefPicList1[0]; + slot_info_0 = vk_find_struct_const(enc_info->pReferenceSlots[slot_to_ref_idx[slot_idx_0]].pNext, + VIDEO_ENCODE_H264_DPB_SLOT_INFO_KHR); + slot_info_1 = vk_find_struct_const(enc_info->pReferenceSlots[slot_to_ref_idx[slot_idx_1]].pNext, + VIDEO_ENCODE_H264_DPB_SLOT_INFO_KHR); break; default: break; @@ -2011,7 +2020,7 @@ radv_enc_params_hevc(struct radv_cmd_buffer *cmd_buffer, const VkVideoEncodeInfo switch (h265_pic->pic_type) { case STD_VIDEO_H265_PICTURE_TYPE_P: - slot_idx_0 = enc_info->pReferenceSlots[0].slotIndex; + slot_idx_0 = h265_pic->pRefLists->RefPicList0[0]; break; default: break;