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".
next prev parent reply other threads:[~2025-03-13 17:05 UTC|newest]
Thread overview: 25+ 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
2025-03-15 16:57 ` [FFmpeg-devel] [PATCH v4 00/16] Add a Vulkan compute based FFv1 hwaccel Lynne
2025-04-08 16:44 ` Jerome Martinez
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