Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
 help / color / mirror / Atom feed
From: Lynne <dev@lynne.ee>
To: ffmpeg-devel@ffmpeg.org
Cc: Lynne <dev@lynne.ee>
Subject: [FFmpeg-devel] [PATCH v4 05/16] hwcontext_vulkan: use the common host map function to map frame data
Date: Thu, 13 Mar 2025 18:03:37 +0100
Message-ID: <20250313170355.92290-6-dev@lynne.ee> (raw)
In-Reply-To: <20250313170355.92290-1-dev@lynne.ee>

---
 libavutil/hwcontext_vulkan.c | 190 ++++++++++-------------------------
 1 file changed, 54 insertions(+), 136 deletions(-)

diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c
index fcff34b5e2..1104e02cfd 100644
--- a/libavutil/hwcontext_vulkan.c
+++ b/libavutil/hwcontext_vulkan.c
@@ -4033,155 +4033,73 @@ static int get_plane_buf(AVHWFramesContext *hwfc, AVBufferRef **dst,
     return 0;
 }
 
-static int create_mapped_buffer(AVHWFramesContext *hwfc,
-                                FFVkBuffer *vkb, VkBufferUsageFlags usage,
-                                size_t size,
-                                VkExternalMemoryBufferCreateInfo *create_desc,
-                                VkImportMemoryHostPointerInfoEXT *import_desc,
-                                VkMemoryHostPointerPropertiesEXT props)
-{
-    int err;
-    VkResult ret;
-    VulkanDevicePriv *p = hwfc->device_ctx->hwctx;
-    FFVulkanFunctions *vk = &p->vkctx.vkfn;
-    AVVulkanDeviceContext *hwctx = &p->p;
-
-    VkBufferCreateInfo buf_spawn = {
-        .sType       = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
-        .pNext       = create_desc,
-        .usage       = usage,
-        .sharingMode = VK_SHARING_MODE_EXCLUSIVE,
-        .size        = size,
-    };
-    VkMemoryRequirements req = {
-        .size           = size,
-        .alignment      = p->hprops.minImportedHostPointerAlignment,
-        .memoryTypeBits = props.memoryTypeBits,
-    };
-
-    err = ff_vk_alloc_mem(&p->vkctx, &req,
-                          VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT,
-                          import_desc, &vkb->flags, &vkb->mem);
-    if (err < 0)
-        return err;
-
-    ret = vk->CreateBuffer(hwctx->act_dev, &buf_spawn, hwctx->alloc, &vkb->buf);
-    if (ret != VK_SUCCESS) {
-        vk->FreeMemory(hwctx->act_dev, vkb->mem, hwctx->alloc);
-        return AVERROR_EXTERNAL;
-    }
-
-    ret = vk->BindBufferMemory(hwctx->act_dev, vkb->buf, vkb->mem, 0);
-    if (ret != VK_SUCCESS) {
-        vk->FreeMemory(hwctx->act_dev, vkb->mem, hwctx->alloc);
-        vk->DestroyBuffer(hwctx->act_dev, vkb->buf, hwctx->alloc);
-        return AVERROR_EXTERNAL;
-    }
-
-    return 0;
-}
-
-static void destroy_avvkbuf(void *opaque, uint8_t *data)
-{
-    FFVulkanContext *s = opaque;
-    FFVkBuffer *buf = (FFVkBuffer *)data;
-    ff_vk_free_buf(s, buf);
-    av_free(buf);
-}
-
 static int host_map_frame(AVHWFramesContext *hwfc, AVBufferRef **dst, int *nb_bufs,
                           AVFrame *swf, VkBufferImageCopy *region, int upload)
 {
     int err;
-    VkResult ret;
     VulkanDevicePriv *p = hwfc->device_ctx->hwctx;
-    FFVulkanFunctions *vk = &p->vkctx.vkfn;
-    AVVulkanDeviceContext *hwctx = &p->p;
 
+    uint32_t p_w, p_h;
+    int nb_src_bufs = 0;
     const int planes = av_pix_fmt_count_planes(swf->format);
 
-    VkExternalMemoryBufferCreateInfo create_desc = {
-        .sType = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO,
-        .handleTypes = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT,
-    };
-    VkImportMemoryHostPointerInfoEXT import_desc = {
-        .sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT,
-        .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT,
-    };
-    VkMemoryHostPointerPropertiesEXT props;
-
-    for (int i = 0; i < planes; i++) {
-        FFVkBuffer *vkb;
-        uint32_t p_w, p_h;
-        size_t offs;
-        size_t buffer_size;
-
-        /* We can't host map images with negative strides */
-        if (swf->linesize[i] < 0) {
-            err = AVERROR(EINVAL);
-            goto fail;
-        }
-
-        get_plane_wh(&p_w, &p_h, swf->format, swf->width, swf->height, i);
-
-        /* Get the previous point at which mapping was possible and use it */
-        offs = (uintptr_t)swf->data[i] % p->hprops.minImportedHostPointerAlignment;
-        import_desc.pHostPointer = swf->data[i] - offs;
-
-        props = (VkMemoryHostPointerPropertiesEXT) {
-            VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT,
-        };
-        ret = vk->GetMemoryHostPointerPropertiesEXT(hwctx->act_dev,
-                                                    import_desc.handleType,
-                                                    import_desc.pHostPointer,
-                                                    &props);
-        if (!(ret == VK_SUCCESS && props.memoryTypeBits)) {
-            err = AVERROR(EINVAL);
-            goto fail;
-        }
-
-        /* Buffer region for this plane */
-        region[i] = (VkBufferImageCopy) {
-            .bufferOffset = offs,
-            .bufferRowLength = swf->linesize[i],
-            .bufferImageHeight = p_h,
-            .imageSubresource.layerCount = 1,
-            .imageExtent = (VkExtent3D){ p_w, p_h, 1 },
-            /* Rest of the fields adjusted/filled in later */
-        };
+    /* We can't host map images with negative strides */
+    for (int i = 0; i < planes; i++)
+        if (swf->linesize[i] < 0)
+            return AVERROR(EINVAL);
 
-        /* Add the offset at the start, which gets ignored */
-        buffer_size = offs + swf->linesize[i]*p_h;
-        buffer_size = FFALIGN(buffer_size, p->props.properties.limits.minMemoryMapAlignment);
-        buffer_size = FFALIGN(buffer_size, p->hprops.minImportedHostPointerAlignment);
+    /* Count the number of buffers in the software frame */
+    while (swf->buf[nb_src_bufs++]);
 
-        /* Create a buffer */
-        vkb = av_mallocz(sizeof(*vkb));
-        if (!vkb) {
-            err = AVERROR(ENOMEM);
-            goto fail;
-        }
+    /* Single buffer contains all planes */
+    if (nb_src_bufs == 1) {
+        err = ff_vk_host_map_buffer(&p->vkctx, &dst[0],
+                                    swf->data[0], swf->buf[0],
+                                    upload ? VK_BUFFER_USAGE_TRANSFER_SRC_BIT :
+                                             VK_BUFFER_USAGE_TRANSFER_DST_BIT);
+        if (err < 0)
+            return err;
+        (*nb_bufs)++;
 
-        err = create_mapped_buffer(hwfc, vkb,
-                                   upload ? VK_BUFFER_USAGE_TRANSFER_SRC_BIT :
-                                            VK_BUFFER_USAGE_TRANSFER_DST_BIT,
-                                   buffer_size, &create_desc, &import_desc,
-                                   props);
-        if (err < 0) {
-            av_free(vkb);
-            goto fail;
+        for (int i = 0; i < planes; i++) {
+            get_plane_wh(&p_w, &p_h, swf->format, swf->width, swf->height, i);
+
+            /* Buffer region for this plane */
+            region[i] = (VkBufferImageCopy) {
+                .bufferOffset = ((FFVkBuffer *)dst[0]->data)->virtual_offset +
+                                swf->data[i] - swf->data[0],
+                .bufferRowLength = swf->linesize[i],
+                .bufferImageHeight = p_h,
+                .imageSubresource.layerCount = 1,
+                .imageExtent = (VkExtent3D){ p_w, p_h, 1 },
+                /* Rest of the fields adjusted/filled in later */
+            };
         }
-
-        /* Create a ref */
-        dst[*nb_bufs] = av_buffer_create((uint8_t *)vkb, sizeof(*vkb),
-                                         destroy_avvkbuf, &p->vkctx, 0);
-        if (!dst[*nb_bufs]) {
-            destroy_avvkbuf(&p->vkctx, (uint8_t *)vkb);
-            err = AVERROR(ENOMEM);
-            goto fail;
+    } else if (nb_src_bufs == planes) { /* One buffer per plane */
+        for (int i = 0; i < planes; i++) {
+            err = ff_vk_host_map_buffer(&p->vkctx, &dst[i],
+                                        swf->data[i], swf->buf[i],
+                                        upload ? VK_BUFFER_USAGE_TRANSFER_SRC_BIT :
+                                                 VK_BUFFER_USAGE_TRANSFER_DST_BIT);
+            if (err < 0)
+                goto fail;
+            (*nb_bufs)++;
+
+            get_plane_wh(&p_w, &p_h, swf->format, swf->width, swf->height, i);
+
+            /* Buffer region for this plane */
+            region[i] = (VkBufferImageCopy) {
+                .bufferOffset = ((FFVkBuffer *)dst[i]->data)->virtual_offset,
+                .bufferRowLength = swf->linesize[i],
+                .bufferImageHeight = p_h,
+                .imageSubresource.layerCount = 1,
+                .imageExtent = (VkExtent3D){ p_w, p_h, 1 },
+                /* Rest of the fields adjusted/filled in later */
+            };
         }
-
-        (*nb_bufs)++;
+    } else {
+        /* Weird layout (3 planes, 2 buffers), patch welcome, fallback to copy */
+        return AVERROR_PATCHWELCOME;
     }
 
     return 0;
-- 
2.47.2
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

  parent reply	other threads:[~2025-03-13 17:05 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-03-13 17:03 [FFmpeg-devel] [PATCH v4 00/16] Add a Vulkan compute based FFv1 hwaccel Lynne
2025-03-13 17:03 ` [FFmpeg-devel] [PATCH v4 01/16] pixfmt: add AV_PIX_FMT_GBRAP32 Lynne
2025-03-14 15:13   ` Michael Niedermayer
2025-03-14 15:59     ` Lynne
2025-03-14 18:34       ` Marton Balint
2025-03-13 17:03 ` [FFmpeg-devel] [PATCH v4 02/16] vulkan: rename ff_vk_set_descriptor_image to ff_vk_shader_update_img Lynne
2025-03-13 17:03 ` [FFmpeg-devel] [PATCH v4 03/16] vulkan: add ff_vk_create_imageview Lynne
2025-03-13 17:03 ` [FFmpeg-devel] [PATCH v4 04/16] vulkan: copy host-mapping buffer code from hwcontext Lynne
2025-03-13 17:03 ` Lynne [this message]
2025-03-13 17:03 ` [FFmpeg-devel] [PATCH v4 06/16] vulkan: workaround BGR storage image undefined behaviour Lynne
2025-03-13 17:03 ` [FFmpeg-devel] [PATCH v4 07/16] vulkan_decode: support software-defined decoders Lynne
2025-03-13 17:03 ` [FFmpeg-devel] [PATCH v4 08/16] vulkan_decode: support multiple image views Lynne
2025-03-13 17:03 ` [FFmpeg-devel] [PATCH v4 09/16] vulkan_decode: adjust number of async contexts created Lynne
2025-03-13 17:03 ` [FFmpeg-devel] [PATCH v4 10/16] ffv1enc_vulkan: refactor shaders slightly to support sharing Lynne
2025-03-13 17:03 ` [FFmpeg-devel] [PATCH v4 11/16] vulkan: unify handling of BGR and simplify ffv1_rct Lynne
2025-03-13 17:03 ` [FFmpeg-devel] [PATCH v4 12/16] vulkan: add ff_vk_exec_add_dep_wait_sem() Lynne
2025-03-13 17:03 ` [FFmpeg-devel] [PATCH v4 13/16] vulkan: add support for AV_PIX_FMT_GBRAP32 Lynne
2025-03-13 17:03 ` [FFmpeg-devel] [PATCH v4 14/16] ffv1dec: add support for hwaccels Lynne
2025-03-13 17:03 ` [FFmpeg-devel] [PATCH v4 15/16] FFHWAccel: add buffer_ref argument to start_frame Lynne
2025-03-13 22:08   ` Andreas Rheinhardt
2025-03-13 23:03     ` Lynne
2025-03-14  2:23       ` Lynne
2025-03-13 17:03 ` [FFmpeg-devel] [PATCH v4 16/16] ffv1: add a Vulkan-based decoder Lynne

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20250313170355.92290-6-dev@lynne.ee \
    --to=dev@lynne.ee \
    --cc=ffmpeg-devel@ffmpeg.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

This inbox may be cloned and mirrored by anyone:

	git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \
		ffmpegdev@gitmailbox.com
	public-inbox-index ffmpegdev

Example config snippet for mirrors.


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git