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: 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