* [FFmpeg-devel] [PATCH] hwcontext_vulkan: use host image copy
@ 2025-06-02 16:58 Lynne
2025-06-02 17:30 ` Niklas Haas
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Lynne @ 2025-06-02 16:58 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Lynne
---
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 */
/* 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".
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [FFmpeg-devel] [PATCH] hwcontext_vulkan: use host image copy
2025-06-02 16:58 [FFmpeg-devel] [PATCH] hwcontext_vulkan: use host image copy Lynne
@ 2025-06-02 17:30 ` Niklas Haas
2025-06-02 17:35 ` Niklas Haas
2025-06-02 18:55 ` Victor Jaquez
2 siblings, 0 replies; 4+ messages in thread
From: Niklas Haas @ 2025-06-02 17:30 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Lynne
On Tue, 03 Jun 2025 01:58:26 +0900 Lynne <dev@lynne.ee> 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;
> +
You should check for VK_FORMAT_FEATURE_2_HOST_IMAGE_TRANSFER_BIT instead of
enabling this blindly, since it may not be supported by all formats.
> /* 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);
I found vkCopyImageToMemory transfers to be substantially slower than
vice versa, maybe you can test this in your implementation?
> + }
> + }
> +
> + 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);
What if the frame is still in use?
> +
> 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 */
>
> /* 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".
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [FFmpeg-devel] [PATCH] hwcontext_vulkan: use host image copy
2025-06-02 16:58 [FFmpeg-devel] [PATCH] hwcontext_vulkan: use host image copy Lynne
2025-06-02 17:30 ` Niklas Haas
@ 2025-06-02 17:35 ` Niklas Haas
2025-06-02 18:55 ` Victor Jaquez
2 siblings, 0 replies; 4+ messages in thread
From: Niklas Haas @ 2025-06-02 17:35 UTC (permalink / raw)
To: ffmpeg-devel; +Cc: Lynne
On Tue, 03 Jun 2025 01:58:26 +0900 Lynne <dev@lynne.ee> 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];
What if the dstImageLayout is not compatible? You can get a list of compatible
image layouts via VkPhysicalDeviceHostImageCopyPropertiesEXT. And if not
compatible, you should transition the image layout to VK_IMAGE_LAYOUT_GENERAL.
> +
> + 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 */
>
> /* 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".
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [FFmpeg-devel] [PATCH] hwcontext_vulkan: use host image copy
2025-06-02 16:58 [FFmpeg-devel] [PATCH] hwcontext_vulkan: use host image copy Lynne
2025-06-02 17:30 ` Niklas Haas
2025-06-02 17:35 ` Niklas Haas
@ 2025-06-02 18:55 ` Victor Jaquez
2 siblings, 0 replies; 4+ messages in thread
From: Victor Jaquez @ 2025-06-02 18:55 UTC (permalink / raw)
To: ffmpeg-devel
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".
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2025-06-02 18:56 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-06-02 16:58 [FFmpeg-devel] [PATCH] hwcontext_vulkan: use host image copy Lynne
2025-06-02 17:30 ` Niklas Haas
2025-06-02 17:35 ` Niklas Haas
2025-06-02 18:55 ` Victor Jaquez
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