From ab56ce154bbb7fbec19ccffb40cf4c1e8085230d 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 Part-of: --- src/amd/vulkan/radv_video.c | 1 - src/amd/vulkan/radv_video.h | 2 ++ src/amd/vulkan/radv_video_enc.c | 27 ++++++++++++++++++--------- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/amd/vulkan/radv_video.c b/src/amd/vulkan/radv_video.c index f67f12e4e1d..4ca3d1a6e6a 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 bc2a5d1b8f5..85c2665cd1a 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 d1f80c3bdb1..9457fae3ac5 100644 --- a/src/amd/vulkan/radv_video_enc.c +++ b/src/amd/vulkan/radv_video_enc.c @@ -2026,7 +2026,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; @@ -2037,7 +2037,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; @@ -2095,6 +2095,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; @@ -2103,14 +2109,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; @@ -2198,7 +2207,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;