Revert "hasvk: Encode B pictures on gen7."

This reverts commit 81cf1c16db.

The B frame work was never verified beyond its own four tests: every attempt
to run the whole encode family since has aborted on a device loss.  The
bisect that seemed to clear it was worthless, because only the first run
after a reboot was on a healthy GPU and every later measurement was taken on
a ring that had already hung.

Going back to the last commit with a completed run behind it: 120 of 120
executed, 92 passing, none failing.  B pictures can come back once they can
be verified one change at a time, on a machine with no other GPU client to
lose.
This commit is contained in:
elwrcl committed 2026-08-21 18:06:06 +03:00
1 parent 81cf1c16db
commit 26405fe38c
5 files changed
+22 -51

No files matched your search

-2
View File
@@ -3876,8 +3876,6 @@ struct anv_video_reference_state {
bool slot_valid[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_slot[ANV_VIDEO_MAX_DPB_SLOTS];
uint8_t l0_count; uint8_t l0_count;
uint8_t l1_slot[ANV_VIDEO_MAX_DPB_SLOTS];
uint8_t l1_count;
}; };
/* One picture's slice of an intra refresh cycle: the macroblocks of region /* One picture's slice of an intra refresh cycle: the macroblocks of region
+6 -8
View File
@@ -144,8 +144,9 @@ anv_GetPhysicalDeviceVideoCapabilitiesKHR(VkPhysicalDevice physicalDevice,
} else { } else {
/* Baseline and Main are supported. Main is accepted so that CABAC /* Baseline and Main are supported. Main is accepted so that CABAC
* (entropy_coding_mode_flag == 1, forbidden in Baseline) can be selected; * (entropy_coding_mode_flag == 1, forbidden in Baseline) can be selected;
* the PAK performs the entropy coding. High is rejected (8x8 transform / * the PAK performs the entropy coding. Main's inter-prediction features
* scaling lists not emitted). */ * (B slices) are still not emitted — only I frames are produced. High is
* rejected (8x8 transform / scaling lists not emitted). */
const VkVideoEncodeH264ProfileInfoKHR *h264_profile = const VkVideoEncodeH264ProfileInfoKHR *h264_profile =
vk_find_struct_const(pVideoProfile->pNext, VIDEO_ENCODE_H264_PROFILE_INFO_KHR); vk_find_struct_const(pVideoProfile->pNext, VIDEO_ENCODE_H264_PROFILE_INFO_KHR);
if (h264_profile) { if (h264_profile) {
@@ -207,10 +208,7 @@ anv_GetPhysicalDeviceVideoCapabilitiesKHR(VkPhysicalDevice physicalDevice,
* of them can be predicted from, though: each macroblock is coded against * of them can be predicted from, though: each macroblock is coded against
* reference index 0, so multi-reference and B frames are still out. */ * reference index 0, so multi-reference and B frames are still out. */
pCapabilities->maxDpbSlots = ANV_VIDEO_MAX_DPB_SLOTS; pCapabilities->maxDpbSlots = ANV_VIDEO_MAX_DPB_SLOTS;
/* Two, so a B picture can name one reference in each list. Prediction pCapabilities->maxActiveReferencePictures = 1;
* still only uses reference index 0 of whichever list a macroblock is
* coded against. */
pCapabilities->maxActiveReferencePictures = 2;
struct VkVideoEncodeCapabilitiesKHR *enc_caps = struct VkVideoEncodeCapabilitiesKHR *enc_caps =
(struct VkVideoEncodeCapabilitiesKHR *) (struct VkVideoEncodeCapabilitiesKHR *)
@@ -276,8 +274,8 @@ anv_GetPhysicalDeviceVideoCapabilitiesKHR(VkPhysicalDevice physicalDevice,
* slice splitting). */ * slice splitting). */
h264_enc_ext->maxSliceCount = 68; /* 1088/16, covers up to 1080p */ h264_enc_ext->maxSliceCount = 68; /* 1088/16, covers up to 1080p */
h264_enc_ext->maxPPictureL0ReferenceCount = 1; h264_enc_ext->maxPPictureL0ReferenceCount = 1;
h264_enc_ext->maxBPictureL0ReferenceCount = 1; h264_enc_ext->maxBPictureL0ReferenceCount = 0;
h264_enc_ext->maxL1ReferenceCount = 1; h264_enc_ext->maxL1ReferenceCount = 0;
h264_enc_ext->maxTemporalLayerCount = 1; h264_enc_ext->maxTemporalLayerCount = 1;
h264_enc_ext->expectDyadicTemporalLayerPattern = VK_FALSE; h264_enc_ext->expectDyadicTemporalLayerPattern = VK_FALSE;
h264_enc_ext->minQp = 0; h264_enc_ext->minQp = 0;
@@ -108,10 +108,7 @@ anv_h264_build_encode_slice_header(uint8_t *out_buf, uint32_t out_cap,
bool is_idr = pic_info->flags.IdrPicFlag; bool is_idr = pic_info->flags.IdrPicFlag;
unsigned nal_unit_type = is_idr ? 5 : 1; unsigned nal_unit_type = is_idr ? 5 : 1;
/* A picture nothing will reference must say so, or a decoder keeps it in unsigned nal_ref_idc = 1; /* I-frame is always a reference */
* the DPB and its frame_num accounting drifts: an IDR is always a
* reference, otherwise the client's is_reference decides. */
unsigned nal_ref_idc = (is_idr || pic_info->flags.is_reference) ? 1 : 0;
bw_put_bit(&bw, 0); /* forbidden_zero_bit */ bw_put_bit(&bw, 0); /* forbidden_zero_bit */
bw_put_u(&bw, nal_ref_idc, 2); bw_put_u(&bw, nal_ref_idc, 2);
@@ -142,24 +139,14 @@ anv_h264_build_encode_slice_header(uint8_t *out_buf, uint32_t out_cap,
if (pps->flags.redundant_pic_cnt_present_flag) if (pps->flags.redundant_pic_cnt_present_flag)
bw_put_ue(&bw, 0); bw_put_ue(&bw, 0);
/* Inter reference-list syntax (H.264 7.3.3). */ /* P-slice reference-list syntax (H.264 7.3.3). B slices are out of scope, so
bool is_b = (slice_hdr->slice_type == STD_VIDEO_H264_SLICE_TYPE_B); * direct_spatial_mv_pred_flag is never emitted. */
bool is_p = is_b || (slice_hdr->slice_type == STD_VIDEO_H264_SLICE_TYPE_P); bool is_p = (slice_hdr->slice_type == STD_VIDEO_H264_SLICE_TYPE_P);
if (is_b) {
/* direct_spatial_mv_pred_flag = 1: spatial direct mode, which derives
* its motion from neighbours instead of the co-located picture's stored
* vectors, so no direct MV buffer has to be read back. */
bw_put_bit(&bw, 1);
}
if (is_p) { if (is_p) {
/* num_ref_idx_active_override_flag = 0: use the PPS default counts. */ /* num_ref_idx_active_override_flag = 0: use the PPS default L0 count. */
bw_put_bit(&bw, 0); bw_put_bit(&bw, 0);
/* ref_pic_list_modification_flag_l0 = 0: default frame_num-ordered list. */ /* ref_pic_list_modification_flag_l0 = 0: default frame_num-ordered list. */
bw_put_bit(&bw, 0); bw_put_bit(&bw, 0);
if (is_b) {
/* ref_pic_list_modification_flag_l1 = 0: default POC-ordered list. */
bw_put_bit(&bw, 0);
}
} }
/* pred_weight_table is absent (weighted_pred_flag is off). */ /* pred_weight_table is absent (weighted_pred_flag is off). */
+11 -15
View File
@@ -192,9 +192,9 @@ genX(hasvk_mfc_emit_static_state)(struct anv_cmd_buffer *cmd_buffer,
avc_img.TrellisQuantizationChromaDisable = false; avc_img.TrellisQuantizationChromaDisable = false;
avc_img.IntraMBConformanceMaxSize = 0xEE8; avc_img.IntraMBConformanceMaxSize = 0xEE8;
avc_img.InterMBConformanceMaxSize = 0xBB8; avc_img.InterMBConformanceMaxSize = 0xBB8;
avc_img.NumberofReferenceFrames = refs->l0_count + refs->l1_count; avc_img.NumberofReferenceFrames = is_p ? 1 : 0;
avc_img.NumberofActiveReferencePicturesfromL0 = refs->l0_count; avc_img.NumberofActiveReferencePicturesfromL0 = is_p ? 1 : 0;
avc_img.NumberofActiveReferencePicturesfromL1 = refs->l1_count; avc_img.NumberofActiveReferencePicturesfromL1 = 0;
avc_img.InitialQPValue = 0; /* per-slice QP comes from SLICE_STATE */ avc_img.InitialQPValue = 0; /* per-slice QP comes from SLICE_STATE */
avc_img.PicOrderPresent = pps->flags.bottom_field_pic_order_in_frame_present_flag; avc_img.PicOrderPresent = pps->flags.bottom_field_pic_order_in_frame_present_flag;
avc_img.DeltaPicOrderAlwaysZero = sps->flags.delta_pic_order_always_zero_flag; avc_img.DeltaPicOrderAlwaysZero = sps->flags.delta_pic_order_always_zero_flag;
@@ -304,12 +304,11 @@ genX(hasvk_mfc_emit_static_state)(struct anv_cmd_buffer *cmd_buffer,
anv_batch_emit(&cmd_buffer->batch, GENX(MFX_AVC_REF_IDX_STATE), ref_idx) { anv_batch_emit(&cmd_buffer->batch, GENX(MFX_AVC_REF_IDX_STATE), ref_idx) {
ref_idx.ReferencePictureListSelect = list; ref_idx.ReferencePictureListSelect = list;
memset(ref_idx.ReferenceListEntry, 0x80, sizeof(ref_idx.ReferenceListEntry)); memset(ref_idx.ReferenceListEntry, 0x80, sizeof(ref_idx.ReferenceListEntry));
const uint8_t *slots = list == 0 ? refs->l0_slot : refs->l1_slot; if (is_p && list == 0) {
unsigned count = list == 0 ? refs->l0_count : refs->l1_count; unsigned n = MIN2(refs->l0_count,
if (is_p) { ARRAY_SIZE(ref_idx.ReferenceListEntry));
unsigned n = MIN2(count, ARRAY_SIZE(ref_idx.ReferenceListEntry));
for (unsigned i = 0; i < n; i++) for (unsigned i = 0; i < n; i++)
ref_idx.ReferenceListEntry[i] = 0x20 | (slots[i] << 1); ref_idx.ReferenceListEntry[i] = 0x20 | (refs->l0_slot[i] << 1);
} }
} }
} }
@@ -329,19 +328,16 @@ genX(hasvk_mfc_emit_slice)(struct anv_cmd_buffer *cmd_buffer,
uint32_t dst_page_offset, uint32_t dst_page_offset,
const struct anv_video_intra_refresh *intra_refresh) const struct anv_video_intra_refresh *intra_refresh)
{ {
/* An I slice predicts from nothing; P and B slices both predict from L0, /* A P slice references the previous reconstructed frame; an I slice does
* and a B slice additionally has L1 available. */ * not. B slices are out of scope. */
bool is_b = (slice_hdr->slice_type == STD_VIDEO_H264_SLICE_TYPE_B); bool is_p = (slice_hdr->slice_type == STD_VIDEO_H264_SLICE_TYPE_P);
bool is_p = is_b || (slice_hdr->slice_type == STD_VIDEO_H264_SLICE_TYPE_P);
/* MFX_AVC_SLICE_STATE is not used by decode; fields are matched against the /* MFX_AVC_SLICE_STATE is not used by decode; fields are matched against the
* VA-API reference encoder (gen6_mfc_avc_slice_state). The slice covers the * VA-API reference encoder (gen6_mfc_avc_slice_state). The slice covers the
* macroblock range [slice_start_mb, slice_end_mb) in raster order. */ * macroblock range [slice_start_mb, slice_end_mb) in raster order. */
anv_batch_emit(&cmd_buffer->batch, GENX(MFX_AVC_SLICE_STATE), slice) { anv_batch_emit(&cmd_buffer->batch, GENX(MFX_AVC_SLICE_STATE), slice) {
slice.SliceType = is_b ? BSlice : slice.SliceType = is_p ? PSlice : ISlice; /* P=0,B=1,I=2 */
is_p ? PSlice : ISlice; /* P=0,B=1,I=2 */
slice.NumberofReferencePicturesinInterpredictionList0 = is_p ? 1 : 0; slice.NumberofReferencePicturesinInterpredictionList0 = is_p ? 1 : 0;
slice.NumberofReferencePicturesinInterpredictionList1 = is_b ? 1 : 0;
slice.SliceQuantizationParameter = qp; slice.SliceQuantizationParameter = qp;
slice.CABACInitIDC = is_p ? slice_hdr->cabac_init_idc : 0; slice.CABACInitIDC = is_p ? slice_hdr->cabac_init_idc : 0;
slice.DisableDeblockingFilterIndicator = 1; slice.DisableDeblockingFilterIndicator = 1;
-8
View File
@@ -1237,14 +1237,6 @@ anv_h264_encode_video(struct anv_cmd_buffer *cmd_buffer,
break; break;
refs.l0_slot[refs.l0_count++] = s; refs.l0_slot[refs.l0_count++] = s;
} }
n = MIN2(ref_lists->num_ref_idx_l1_active_minus1 + 1,
ANV_VIDEO_MAX_DPB_SLOTS);
for (unsigned i = 0; i < n; i++) {
uint8_t s = ref_lists->RefPicList1[i];
if (s >= ANV_VIDEO_MAX_DPB_SLOTS || !refs.slot_valid[s])
break;
refs.l1_slot[refs.l1_count++] = s;
}
} }
/* A client that supplies reference slots but no list still means the /* A client that supplies reference slots but no list still means the
* first one, which is what the encoder used to assume unconditionally. */ * first one, which is what the encoder used to assume unconditionally. */