mirror of
https://github.com/elwrcl/intel-hard-graphics.git
synced 2026-10-31 19:08:03 +03:00
hasvk: Add VK_KHR_video_encode_intra_refresh for gen7.
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]>
This commit is contained in:
6 files changed
+126
-12
No files matched your search
@@ -3852,6 +3852,50 @@ struct anv_video_session_params {
|
||||
struct vk_video_session_parameters vk;
|
||||
};
|
||||
|
||||
/* One picture's slice of an intra refresh cycle: the macroblocks of region
|
||||
* `index` out of `cycle_duration` are coded intra, the rest inter.
|
||||
*/
|
||||
struct anv_video_intra_refresh {
|
||||
VkVideoEncodeIntraRefreshModeFlagBitsKHR mode;
|
||||
uint32_t cycle_duration;
|
||||
uint32_t index;
|
||||
};
|
||||
|
||||
/* Whether the macroblock at (x, y) falls in the region being refreshed. The
|
||||
* regions divide the picture evenly, so a cycle longer than the number of
|
||||
* blocks along the split axis simply leaves some of them empty.
|
||||
*/
|
||||
static inline bool
|
||||
anv_video_mb_is_intra_refreshed(const struct anv_video_intra_refresh *ir,
|
||||
uint32_t x, uint32_t y,
|
||||
uint32_t width_in_mbs, uint32_t height_in_mbs)
|
||||
{
|
||||
if (ir == NULL || ir->cycle_duration == 0)
|
||||
return false;
|
||||
|
||||
uint32_t pos, total;
|
||||
switch (ir->mode) {
|
||||
case VK_VIDEO_ENCODE_INTRA_REFRESH_MODE_BLOCK_ROW_BASED_BIT_KHR:
|
||||
pos = y;
|
||||
total = height_in_mbs;
|
||||
break;
|
||||
case VK_VIDEO_ENCODE_INTRA_REFRESH_MODE_BLOCK_COLUMN_BASED_BIT_KHR:
|
||||
pos = x;
|
||||
total = width_in_mbs;
|
||||
break;
|
||||
case VK_VIDEO_ENCODE_INTRA_REFRESH_MODE_BLOCK_BASED_BIT_KHR:
|
||||
pos = y * width_in_mbs + x;
|
||||
total = width_in_mbs * height_in_mbs;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t first = (uint64_t)ir->index * total / ir->cycle_duration;
|
||||
uint32_t last = (uint64_t)(ir->index + 1) * total / ir->cycle_duration;
|
||||
return pos >= first && pos < last;
|
||||
}
|
||||
|
||||
static inline uint32_t khr_perf_query_preamble_offset(const struct anv_query_pool *pool,
|
||||
uint32_t pass)
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user