This is an automated email from the git hooks/post-receive script.

Git pushed a commit to branch master
in repository ffmpeg.

commit ecd3b68059df4461b51416d6a9dd30b062f7be62
Author:     Emil J. Tywoniak <[email protected]>
AuthorDate: Sun Oct 25 22:56:31 2026 +0100
Commit:     Lynne <[email protected]>
CommitDate: Sat Nov 7 08:34:56 2026 +0000

    avcodec/vulkan_encode: flush and invalidate non-coherent packet buffers
    
    The packet buffer can be non-coherent (e.g. Intel non-LLC GPUs). The
    headers written by the CPU were never flushed before submission, and
    the readback flushed instead of invalidating. On Meteor Lake this
    corrupted h264_vulkan and hevc_vulkan output at random.
    
    Assisted-by: Claude Opus 5.5
---
 libavcodec/vulkan_encode.c | 50 ++++++++++++++++++++++++----------------------
 1 file changed, 26 insertions(+), 24 deletions(-)

diff --git a/libavcodec/vulkan_encode.c b/libavcodec/vulkan_encode.c
index 9d3c9b04c5..d654cf05d6 100644
--- a/libavcodec/vulkan_encode.c
+++ b/libavcodec/vulkan_encode.c
@@ -337,6 +337,13 @@ static int vulkan_encode_issue(AVCodecContext *avctx,
         }
     }
 
+    /* Flush the headers written above if needed */
+    if (encode_info.dstBufferOffset)
+        RET(ff_vk_flush_buffer(&ctx->s, sd_buf, 0,
+                               FFALIGN(encode_info.dstBufferOffset,
+                                       
ctx->s.props.properties.limits.nonCoherentAtomSize),
+                               1));
+
     vp->slices_offset = encode_info.dstBufferOffset;
 
     /* Align buffer size to the nearest lower alignment requirement. */
@@ -492,6 +499,7 @@ static int vulkan_encode_output(AVCodecContext *avctx,
                                 FFHWBaseEncodePicture *base_pic, AVPacket *pkt)
 {
     VkResult ret;
+    int err, offs;
     FFVulkanEncodePicture *vp = base_pic->priv;
     FFVulkanEncodeContext *ctx = avctx->priv_data;
     FFHWBaseEncodeContext *base_ctx = &ctx->base;
@@ -520,32 +528,26 @@ static int vulkan_encode_output(AVCodecContext *avctx,
         return AVERROR_EXTERNAL;
     }
 
-    /* Invalidate buffer if needed */
-    if (!(sd_buf->flags & VK_MEMORY_PROPERTY_HOST_COHERENT_BIT)) {
-        FFVulkanFunctions *vk = &ctx->s.vkfn;
-        VkMappedMemoryRange invalidate_buf;
-
-        int offs = vp->slices_offset;
-        /* If the non-coherent alignment is greater than the bitstream buffer
-         * offset's alignment, and the offs value is not aligned already,
-         * align it to the previous alignment point. */
-        if (ctx->s.props.properties.limits.nonCoherentAtomSize >
-            ctx->caps.minBitstreamBufferOffsetAlignment && offs &&
-            (FFALIGN(offs, ctx->s.props.properties.limits.nonCoherentAtomSize) 
!= offs)) {
-            offs -= ctx->s.props.properties.limits.nonCoherentAtomSize;
-            offs = FFALIGN(FFMAX(offs, 0), 
ctx->s.props.properties.limits.nonCoherentAtomSize);
-        }
-
-        invalidate_buf = (VkMappedMemoryRange) {
-            .sType = VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE,
-            .memory = sd_buf->mem,
-            .offset = offs,
-            .size = VK_WHOLE_SIZE,
-        };
-
-        vk->FlushMappedMemoryRanges(ctx->s.hwctx->act_dev, 1, &invalidate_buf);
+    /* If the non-coherent alignment is greater than the bitstream buffer
+     * offset's alignment, and the offs value is not aligned already,
+     * align it to the previous alignment point. */
+    offs = vp->slices_offset;
+    if (ctx->s.props.properties.limits.nonCoherentAtomSize >
+        ctx->caps.minBitstreamBufferOffsetAlignment && offs &&
+        (FFALIGN(offs, ctx->s.props.properties.limits.nonCoherentAtomSize) != 
offs)) {
+        offs -= ctx->s.props.properties.limits.nonCoherentAtomSize;
+        offs = FFALIGN(FFMAX(offs, 0), 
ctx->s.props.properties.limits.nonCoherentAtomSize);
     }
 
+    /* Invalidate buffer if needed */
+    err = ff_vk_flush_buffer(&ctx->s, sd_buf, offs,
+                             FFALIGN(vp->slices_offset + query_data[0] +
+                                     query_data[1] - offs,
+                                     
ctx->s.props.properties.limits.nonCoherentAtomSize),
+                             0);
+    if (err < 0)
+        return err;
+
     if (vp->non_independent_frame) {
         av_assert0(!ctx->prev_buf_ref);
         size_t prev_buf_size = vp->slices_offset + query_data[0] + 
query_data[1];

-- 
To stop receiving notification emails like this one, please contact
[email protected].
_______________________________________________
ffmpeg-cvslog mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to