From: Victor Jaquez <vjaquez@igalia.com> To: ffmpeg-devel@ffmpeg.org Subject: Re: [FFmpeg-devel] [PATCH] hwcontext_vulkan: use host image copy Date: Mon, 2 Jun 2025 20:55:49 +0200 Message-ID: <yrwb2c33wokfed3rivmfei6n6a2az6djbdtoh4wcupw5ftdfqi@m5v7osuydr27> (raw) In-Reply-To: <20250602165831.1462152-1-dev@lynne.ee> On Tue, 03 Jun 2025 at 01:58, Lynne wrote: > --- > libavutil/hwcontext_vulkan.c | 84 +++++++++++++++++++++++++++++++++++- > libavutil/vulkan_functions.h | 6 +++ > libavutil/vulkan_loader.h | 1 + > 3 files changed, 89 insertions(+), 2 deletions(-) > > diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c > index ce485a85a2..b22e4e375a 100644 > --- a/libavutil/hwcontext_vulkan.c > +++ b/libavutil/hwcontext_vulkan.c > @@ -80,6 +80,7 @@ typedef struct VulkanDeviceFeatures { > VkPhysicalDeviceVulkan13Features vulkan_1_3; > VkPhysicalDeviceTimelineSemaphoreFeatures timeline_semaphore; > VkPhysicalDeviceShaderSubgroupRotateFeaturesKHR subgroup_rotate; > + VkPhysicalDeviceHostImageCopyFeaturesEXT host_image_copy; > > #ifdef VK_KHR_shader_expect_assume > VkPhysicalDeviceShaderExpectAssumeFeaturesKHR expect_assume; > @@ -208,6 +209,8 @@ static void device_features_init(AVHWDeviceContext *ctx, VulkanDeviceFeatures *f > VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES); > FF_VK_STRUCT_EXT(s, &feats->device, &feats->subgroup_rotate, FF_VK_EXT_SUBGROUP_ROTATE, > VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_SUBGROUP_ROTATE_FEATURES_KHR); > + FF_VK_STRUCT_EXT(s, &feats->device, &feats->host_image_copy, FF_VK_EXT_HOST_IMAGE_COPY, > + VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_HOST_IMAGE_COPY_FEATURES_EXT); > > #ifdef VK_KHR_shader_expect_assume > FF_VK_STRUCT_EXT(s, &feats->device, &feats->expect_assume, FF_VK_EXT_EXPECT_ASSUME, > @@ -287,6 +290,7 @@ static void device_features_copy_needed(VulkanDeviceFeatures *dst, VulkanDeviceF > > COPY_VAL(timeline_semaphore.timelineSemaphore); > COPY_VAL(subgroup_rotate.shaderSubgroupRotate); > + COPY_VAL(host_image_copy.hostImageCopy); > > COPY_VAL(video_maintenance_1.videoMaintenance1); > #ifdef VK_KHR_video_maintenance2 > @@ -610,6 +614,7 @@ static const VulkanOptExtension optional_device_exts[] = { > { VK_NV_OPTICAL_FLOW_EXTENSION_NAME, FF_VK_EXT_OPTICAL_FLOW }, > { VK_EXT_SHADER_OBJECT_EXTENSION_NAME, FF_VK_EXT_SHADER_OBJECT }, > { VK_KHR_SHADER_SUBGROUP_ROTATE_EXTENSION_NAME, FF_VK_EXT_SUBGROUP_ROTATE }, > + { VK_EXT_HOST_IMAGE_COPY_EXTENSION_NAME, FF_VK_EXT_HOST_IMAGE_COPY }, > #ifdef VK_KHR_shader_expect_assume > { VK_KHR_SHADER_EXPECT_ASSUME_EXTENSION_NAME, FF_VK_EXT_EXPECT_ASSUME }, > #endif > @@ -2802,11 +2807,15 @@ static int vulkan_frames_init(AVHWFramesContext *hwfc) > > /* Image usage flags */ > if (!hwctx->usage) { > - hwctx->usage = supported_usage & (VK_IMAGE_USAGE_TRANSFER_DST_BIT | > - VK_IMAGE_USAGE_TRANSFER_SRC_BIT | > + hwctx->usage = supported_usage & (VK_IMAGE_USAGE_TRANSFER_SRC_BIT | > VK_IMAGE_USAGE_STORAGE_BIT | > VK_IMAGE_USAGE_SAMPLED_BIT); > > + if (p->vkctx.extensions & FF_VK_EXT_HOST_IMAGE_COPY) > + hwctx->usage |= VK_IMAGE_USAGE_HOST_TRANSFER_BIT; > + else > + hwctx->usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT; > + > /* Enables encoding of images, if supported by format and extensions */ > if ((supported_usage & VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR) && > (p->vkctx.extensions & (FF_VK_EXT_VIDEO_ENCODE_QUEUE | > @@ -4125,6 +4134,74 @@ fail: > return err; > } > > +static int vulkan_transfer_host(AVHWFramesContext *hwfc, AVFrame *hwf, > + AVFrame *swf, int upload) > +{ > + VulkanDevicePriv *p = hwfc->device_ctx->hwctx; > + AVVulkanDeviceContext *hwctx = &p->p; > + FFVulkanFunctions *vk = &p->vkctx.vkfn; > + > + AVVkFrame *hwf_vk = (AVVkFrame *)hwf->data[0]; > + const int planes = av_pix_fmt_count_planes(swf->format); > + const int nb_images = ff_vk_count_images(hwf_vk); > + > + if (upload) { > + VkMemoryToImageCopy region_info = { > + .sType = VK_STRUCTURE_TYPE_MEMORY_TO_IMAGE_COPY, > + .imageSubresource = { > + .layerCount = 1, > + }, > + }; > + VkCopyMemoryToImageInfo copy_info = { > + .sType = VK_STRUCTURE_TYPE_COPY_MEMORY_TO_IMAGE_INFO, > + .flags = VK_HOST_IMAGE_COPY_MEMCPY, > + .regionCount = 1, > + .pRegions = ®ion_info, > + }; > + for (int i = 0; i < planes; i++) { > + int img_idx = FFMIN(i, (nb_images - 1)); > + uint32_t p_w, p_h; > + get_plane_wh(&p_w, &p_h, swf->format, swf->width, swf->height, i); > + > + region_info.pHostPointer = swf->data[i]; > + region_info.imageSubresource.aspectMask = ff_vk_aspect_flag(hwf, i); > + region_info.imageExtent = (VkExtent3D){ p_w, p_h, 1 }; > + copy_info.dstImage = hwf_vk->img[img_idx]; > + copy_info.dstImageLayout = hwf_vk->layout[img_idx]; > + > + vk->CopyMemoryToImageEXT(hwctx->act_dev, ©_info); > + } > + } else { > + VkImageToMemoryCopy region_info = { > + .sType = VK_STRUCTURE_TYPE_MEMORY_TO_IMAGE_COPY, > + .imageSubresource = { > + .layerCount = 1, > + }, > + }; > + VkCopyImageToMemoryInfo copy_info = { > + .sType = VK_STRUCTURE_TYPE_COPY_IMAGE_TO_MEMORY_INFO, > + .flags = VK_HOST_IMAGE_COPY_MEMCPY, > + .regionCount = 1, > + .pRegions = ®ion_info, > + }; > + for (int i = 0; i < planes; i++) { > + int img_idx = FFMIN(i, (nb_images - 1)); > + uint32_t p_w, p_h; > + get_plane_wh(&p_w, &p_h, swf->format, swf->width, swf->height, i); > + > + region_info.pHostPointer = swf->data[i]; > + region_info.imageSubresource.aspectMask = ff_vk_aspect_flag(hwf, i); > + region_info.imageExtent = (VkExtent3D){ p_w, p_h, 1 }; > + copy_info.srcImage = hwf_vk->img[img_idx]; > + copy_info.srcImageLayout = hwf_vk->layout[img_idx]; > + > + vk->CopyImageToMemoryEXT(hwctx->act_dev, ©_info); > + } > + } > + > + return 0; > +} > + > static int vulkan_transfer_frame(AVHWFramesContext *hwfc, > AVFrame *swf, AVFrame *hwf, > int upload) > @@ -4161,6 +4238,9 @@ static int vulkan_transfer_frame(AVHWFramesContext *hwfc, > if (swf->width > hwfc->width || swf->height > hwfc->height) > return AVERROR(EINVAL); > > + if (p->vkctx.extensions & FF_VK_EXT_HOST_IMAGE_COPY) > + return vulkan_transfer_host(hwfc, hwf, swf, upload); > + > for (int i = 0; i < av_pix_fmt_count_planes(swf->format); i++) { > uint32_t p_w, p_h; > get_plane_wh(&p_w, &p_h, swf->format, swf->width, swf->height, i); > diff --git a/libavutil/vulkan_functions.h b/libavutil/vulkan_functions.h > index 8b413013e6..ea0f978bb9 100644 > --- a/libavutil/vulkan_functions.h > +++ b/libavutil/vulkan_functions.h > @@ -49,6 +49,7 @@ typedef uint64_t FFVulkanExtensions; > #define FF_VK_EXT_RELAXED_EXTENDED_INSTR (1ULL << 15) /* VK_KHR_shader_relaxed_extended_instruction */ > #define FF_VK_EXT_EXPECT_ASSUME (1ULL << 16) /* VK_KHR_shader_expect_assume */ > #define FF_VK_EXT_SUBGROUP_ROTATE (1ULL << 17) /* VK_KHR_shader_subgroup_rotate */ > +#define FF_VK_EXT_HOST_IMAGE_COPY (1ULL << 18) /* VK_EXT_image_copy */ VK_EXT_host_image_copy > > /* Video extensions */ > #define FF_VK_EXT_VIDEO_QUEUE (1ULL << 36) /* VK_KHR_video_queue */ > @@ -207,6 +208,11 @@ typedef uint64_t FFVulkanExtensions; > /* sync2 */ \ > MACRO(1, 1, FF_VK_EXT_NO_FLAG, CmdPipelineBarrier2) \ > \ > + /* Host image copy */ \ > + MACRO(1, 1, FF_VK_EXT_HOST_IMAGE_COPY, TransitionImageLayoutEXT) \ > + MACRO(1, 1, FF_VK_EXT_HOST_IMAGE_COPY, CopyMemoryToImageEXT) \ > + MACRO(1, 1, FF_VK_EXT_HOST_IMAGE_COPY, CopyImageToMemoryEXT) \ > + \ > /* Video queue */ \ > MACRO(1, 1, FF_VK_EXT_VIDEO_QUEUE, CreateVideoSessionKHR) \ > MACRO(1, 1, FF_VK_EXT_VIDEO_QUEUE, CreateVideoSessionParametersKHR) \ > diff --git a/libavutil/vulkan_loader.h b/libavutil/vulkan_loader.h > index a7976fe560..7e805fdd4c 100644 > --- a/libavutil/vulkan_loader.h > +++ b/libavutil/vulkan_loader.h > @@ -59,6 +59,7 @@ static inline uint64_t ff_vk_extensions_to_mask(const char * const *extensions, > { VK_NV_OPTICAL_FLOW_EXTENSION_NAME, FF_VK_EXT_OPTICAL_FLOW }, > { VK_EXT_SHADER_OBJECT_EXTENSION_NAME, FF_VK_EXT_SHADER_OBJECT }, > { VK_KHR_SHADER_SUBGROUP_ROTATE_EXTENSION_NAME, FF_VK_EXT_SUBGROUP_ROTATE }, > + { VK_EXT_HOST_IMAGE_COPY_EXTENSION_NAME, FF_VK_EXT_HOST_IMAGE_COPY }, > { VK_KHR_VIDEO_MAINTENANCE_1_EXTENSION_NAME, FF_VK_EXT_VIDEO_MAINTENANCE_1 }, > #ifdef VK_KHR_video_maintenance2 > { VK_KHR_VIDEO_MAINTENANCE_2_EXTENSION_NAME, FF_VK_EXT_VIDEO_MAINTENANCE_2 }, > -- > 2.49.0.395.g12beb8f557c > _______________________________________________ > 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". > _______________________________________________ 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".
prev parent reply other threads:[~2025-06-02 18:56 UTC|newest] Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top 2025-06-02 16:58 Lynne 2025-06-02 17:30 ` Niklas Haas 2025-06-02 17:35 ` Niklas Haas 2025-06-02 18:55 ` Victor Jaquez [this message]
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=yrwb2c33wokfed3rivmfei6n6a2az6djbdtoh4wcupw5ftdfqi@m5v7osuydr27 \ --to=vjaquez@igalia.com \ --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