hasvk: Track DPB slots instead of assuming a single reference.

The encoder ignored VkVideoReferenceSlotInfoKHR entirely: it took
pReferenceSlots[0] as the one reference, wrote its address into frame store 0
and hardcoded the L0 list to that store.  Two DPB slots were all it could
honestly advertise, which is fewer than a GOP of any length needs.

Record each slot the operation names under its own index, since a slot maps
onto the frame store of the same index and MFX_PIPE_BUF_ADDR_STATE holds 16
of those, and build the L0 entries from StdVideoEncodeH264ReferenceListsInfo,
whose RefPicList0 already carries slot indices.  Clients that pass reference
slots without a list keep the old behaviour.

maxDpbSlots therefore goes to 16.  maxActiveReferencePictures stays at 1:
every macroblock is still coded against reference index 0, so a picture may
be kept in the DPB but only the one it names first is predicted from.

dEQP-VK.video.encode.h264.intra_refresh_* goes from 12 Pass and 32 stopped at
the maxDpbSlots >= GOP frame count precondition to 36 Pass, the remaining 8
being per-picture-partition mode, which is not offered.  The family as a whole
is 76 of 120 with no failures.  ffmpeg's h264_vulkan encoder no longer trips
its slot_index assertion and produces a full GOP.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
elwrclandClaude Opus 5 committed 2026-08-21 07:55:40 +03:00
1 parent 0716678e70
commit 9cb5c4385b
5 files changed
+84 -29

No files matched your search

+16
View File
@@ -3852,6 +3852,22 @@ struct anv_video_session_params {
struct vk_video_session_parameters vk;
};
/* MFX_PIPE_BUF_ADDR_STATE has 16 reference picture addresses, so the hardware
* can hold 16 frame stores. A DPB slot maps straight onto a frame store of
* the same index, which keeps the reference lists trivial to build.
*/
#define ANV_VIDEO_MAX_DPB_SLOTS 16
/* The reference pictures one encode operation can reach: where each DPB slot
* lives, and which slots its L0 list names, in order.
*/
struct anv_video_reference_state {
struct anv_address slot_address[ANV_VIDEO_MAX_DPB_SLOTS];
bool slot_valid[ANV_VIDEO_MAX_DPB_SLOTS];
uint8_t l0_slot[ANV_VIDEO_MAX_DPB_SLOTS];
uint8_t l0_count;
};
/* One picture's slice of an intra refresh cycle: the macroblocks of region
* `index` out of `cycle_duration` are coded intra, the rest inter.
*/