Each macroblock's intra/inter decision is already made on its own when the
PAK objects are emitted, so refreshing a region is a matter of coding the
macroblocks it covers the way an I slice codes them. Regions divide the
picture evenly along rows, columns or raster order, which leaves the block,
block-row and block-column modes supported and gives empty regions for free
when the cycle is longer than the split axis.
Two things needed care. PAK keeps the I slice numbering for MbType5Bits
inside a P slice, where H.264 itself offsets intra mb_types by 5; handing it
the offset value hangs the MFC. And under constrained intra prediction a
neighbour only counts as available if it is in the refresh region too,
because prediction may not cross into an inter macroblock.
Nothing constrains motion away from not-yet-refreshed regions, which is
sound only because there is no motion estimation: every vector is zero, so a
macroblock reads its own co-located block and never leaves its region.
Motion estimation will have to honour VkVideoReferenceIntraRefreshInfoKHR's
dirty region count.
Per-picture-partition mode is not offered. It wants the refreshed slice
coded as an I slice, header included, rather than as intra macroblocks
inside a P slice.
dEQP-VK.video.encode.h264.intra_refresh_* goes from 44 NotSupported to 12
Pass; all three modes pass in the variants that can run. The other 32 stop
at a CTS precondition, maxDpbSlots >= GOP frame count, which the driver's
two slots do not meet. Raising that needs real DPB slot tracking and is
what gates B frames and ffmpeg's encoder too.
Co-Authored-By: Claude Opus 5 <[email protected]>
The queue family properties claimed no support with the note that the VCS
"seemingly cannot do a posted memory write". It can: the encode feedback
query already writes its availability, buffer offset and byte count from a
video queue through exactly the same MI_FLUSH_DW post-sync write, and the
VK_QUERY_TYPE_RESULT_STATUS_ONLY_KHR paths in genX_query.c are complete.
Only the advertised capability was missing.
dEQP-VK.video.encode.h264.query_with_status_* goes from NotSupported, where
it failed device creation, to 4/4 Pass; the family is now 40 of 120 with no
failures. h264 decode is unaffected.
Co-Authored-By: Claude Opus 5 <[email protected]>
VK_IMAGE_LAYOUT_GENERAL already lands on the conservative aux choice for
every usage, since anv_layout_to_aux_state() derives that from the layout's
usage flags and GENERAL reports all of them, and video images carry no aux
at all. So the layout itself needed no work; what the extension does add is
a requirement that the host image copy layout lists name every layout it
declares interchangeable with GENERAL.
Those layouts can only be offered if a host copy is safe in each of them,
and the CPU cannot resolve an aux surface on its way to the image. Create
images that carry VK_IMAGE_USAGE_HOST_TRANSFER_BIT without one, which makes
every layout equivalent for them and vkTransitionImageLayoutEXT a genuine
no-op rather than one justified by only ever offering GENERAL.
dEQP-VK.video.encode.h264 goes from 18 to 36 passes out of 120, still with
no failures: the general_layout variants were the whole gap.
dEQP-VK.image.host_image_copy goes from 2037 passes and one failure to
19140 passes and none, the failure having been the properties test checking
exactly this list.
Co-Authored-By: Claude Opus 5 <[email protected]>
VK_KHR_video_maintenance1 lets a client chain VkVideoInlineQueryInfoKHR onto
vkCmdEncodeVideoKHR instead of bracketing it with vkCmdBeginQuery and
vkCmdEndQuery. The driver advertises the feature but only ever wrote the
feedback result to the address vkCmdBeginQuery had recorded, so with an
inline query nothing wrote the result or marked it available and the client
waited on a query that never became ready.
Derive the address from the chained pool when one is present.
dEQP-VK.video.encode.h264.inline_query_* went from DEVICE_LOST, which also
aborted the rest of the run, to Pass. With this and the missing 352x288
input clip generated, the whole h264 encode family now runs clean: 18 pass,
0 fail out of 120, no aborts.
Co-Authored-By: Claude Opus 5 <[email protected]>
MFX_QM_STATE and MFX_FQM_STATE hold separate register sets for the intra
and the inter scaling lists, but only the intra ones were programmed. The
hardware therefore quantized every inter residual with whatever those
registers happened to hold, so a coded P macroblock came back corrupted
while I frames were correct. That is why the P path shipped as skip-only.
With both sets programmed, P macroblocks can carry a real residual: encode
them as coded BP_L0_16x16 with a zero motion vector instead of forcing
P_Skip. A P frame now tracks changing content rather than repeating its
reference.
Measured on a 176x144 clip at QP 26, P frame luma PSNR against the true
source: 12.81 dB before, 43.87 dB after (the I frame scores 44.53 dB), at
2062 bytes versus the I frame's 4474. With an unchanged source the P frame
costs 67 bytes, down from 4862.
dEQP-VK.video.encode.h264.* goes from 12 to 14 passes with no new failures.
There is still no motion estimation, so a moving block costs a full residual
rather than a motion vector.
Co-Authored-By: Claude Opus 5 <[email protected]>
GPGPU_WALKER has no encoding for a zero group count, so passing one
through walks the full dimension and the command never retires, hanging
rcs0 (GPU HANG ecode 7:1:8ff8ffff, EIR and PGTBL_ER both clear). A zero
dispatch is legal and defined as a no-op, so drop it at record time.
through walks the full dimension and the command never retires, hanging
rcs0 (GPU HANG ecode 7:1:8ff8ffff, EIR and PGTBL_ER both clear). A zero
dispatch is legal and defined as a no-op, so drop it at record time.
Gen9+ uses COMPUTE_WALKER and handles this in hardware, which is why
upstream anv carries no equivalent guard.
Fixes dEQP-VK.compute.pipeline.basic.empty_workgroup_{all,x,y,z} and
empty_shader, which previously aborted the run and could take the whole
machine down. compute.pipeline.* now 20285 cases, 0 fail.