Message ID | 20211109091843.2024927-7-wenbin.chen@intel.com |
---|---|
State | New |
Headers | show |
Series | [FFmpeg-devel,1/7] hwcontext_vaapi: Use PRIME_2 memory type for modifiers. | expand |
Context | Check | Description |
---|---|---|
andriy/configurex86 | warning | Failed to apply patch |
andriy/configureppc | warning | Failed to apply patch |
9 Nov 2021, 10:18 by wenbin.chen@intel.com: > When vulkan image exports to drm, the tilling need to be > VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT. Now add code to create vulkan > image using this format. > > Now the following command line works: > > ffmpeg -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -hwaccel_output_format \ > vaapi -i input_1080p.264 -vf "hwmap=derive_device=vulkan,format=vulkan, \ > scale_vulkan=1920:1080,hwmap=derive_device=vaapi,format=vaapi" -c:v h264_vaapi output.264 > > Signed-off-by: Wenbin Chen <wenbin.chen@intel.com> > --- > libavutil/hwcontext_vulkan.c | 76 +++++++++++++++++++++++++++++++++--- > libavutil/hwcontext_vulkan.h | 5 +++ > 2 files changed, 75 insertions(+), 6 deletions(-) > > diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c > index 29ade94b7f..e252c2177e 100644 > --- a/libavutil/hwcontext_vulkan.c > +++ b/libavutil/hwcontext_vulkan.c > @@ -1919,6 +1919,7 @@ static void try_export_flags(AVHWFramesContext *hwfc, > AVVulkanDeviceContext *dev_hwctx = hwfc->device_ctx->hwctx; > VulkanDevicePriv *p = hwfc->device_ctx->internal->priv; > FFVulkanFunctions *vk = &p->vkfn; > + const int has_modifiers = hwctx->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT; > VkExternalImageFormatProperties eprops = { > .sType = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR, > }; > @@ -1926,9 +1927,18 @@ static void try_export_flags(AVHWFramesContext *hwfc, > .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2, > .pNext = &eprops, > }; > + VkPhysicalDeviceImageDrmFormatModifierInfoEXT phy_dev_mod_info = { > + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT, > + .pNext = NULL, > + .pQueueFamilyIndices = p->qfs, > + .queueFamilyIndexCount = p->num_qfs, > + .sharingMode = p->num_qfs > 1 ? VK_SHARING_MODE_CONCURRENT : > + VK_SHARING_MODE_EXCLUSIVE, > + }; > VkPhysicalDeviceExternalImageFormatInfo enext = { > .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO, > .handleType = exp, > + .pNext = has_modifiers ? &phy_dev_mod_info : NULL, > }; > VkPhysicalDeviceImageFormatInfo2 pinfo = { > .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, > @@ -1940,11 +1950,15 @@ static void try_export_flags(AVHWFramesContext *hwfc, > .flags = VK_IMAGE_CREATE_ALIAS_BIT, > }; > > - ret = vk->GetPhysicalDeviceImageFormatProperties2(dev_hwctx->phys_dev, > - &pinfo, &props); > - if (ret == VK_SUCCESS) { > - *iexp |= exp; > - *comp_handle_types |= eprops.externalMemoryProperties.compatibleHandleTypes; > + for (int i = 0; i < (has_modifiers ? hwctx->modifier_count : 1); i++) { > + if (has_modifiers && hwctx->modifier_count) > + phy_dev_mod_info.drmFormatModifier = hwctx->modifiers[i]; > + ret = vk->GetPhysicalDeviceImageFormatProperties2(dev_hwctx->phys_dev, > + &pinfo, &props); > + if (ret == VK_SUCCESS) { > + *iexp |= exp; > + *comp_handle_types |= eprops.externalMemoryProperties.compatibleHandleTypes; > + } > } > } > > @@ -2007,6 +2021,7 @@ fail: > static void vulkan_frames_uninit(AVHWFramesContext *hwfc) > { > VulkanFramesPriv *fp = hwfc->internal->priv; > + AVVulkanFramesContext *hwctx = hwfc->hwctx; > > free_exec_ctx(hwfc, &fp->conv_ctx); > free_exec_ctx(hwfc, &fp->upload_ctx); > @@ -2021,11 +2036,60 @@ static int vulkan_frames_init(AVHWFramesContext *hwfc) > VulkanFramesPriv *fp = hwfc->internal->priv; > AVVulkanDeviceContext *dev_hwctx = hwfc->device_ctx->hwctx; > VulkanDevicePriv *p = hwfc->device_ctx->internal->priv; > + const int has_modifiers = !!(p->extensions & FF_VK_EXT_DRM_MODIFIER_FLAGS); > > /* Default pool flags */ > - hwctx->tiling = hwctx->tiling ? hwctx->tiling : p->use_linear_images ? > + hwctx->tiling = hwctx->tiling ? hwctx->tiling : has_modifiers ? > + VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT : p->use_linear_images ? > VK_IMAGE_TILING_LINEAR : VK_IMAGE_TILING_OPTIMAL; > > + /* get the supported modifier */ > + if (has_modifiers) { > + const VkFormat *fmt = av_vkfmt_from_pixfmt(hwfc->sw_format); > + FFVulkanFunctions *vk = &p->vkfn; > + VkDrmFormatModifierPropertiesEXT mod_props[MAX_VULKAN_MODIFIERS]; > + > + VkDrmFormatModifierPropertiesListEXT mod_props_list = { > + .sType = VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT, > + .pNext = NULL, > + .drmFormatModifierCount = 0, > + .pDrmFormatModifierProperties = NULL, > + }; > + VkFormatProperties2 prop = { > + .sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2, > + .pNext = &mod_props_list, > + }; > + > + vk->GetPhysicalDeviceFormatProperties2(dev_hwctx->phys_dev, fmt[0], &prop); > + if (!mod_props_list.drmFormatModifierCount) { > + av_log(hwfc, AV_LOG_ERROR, "There are not supported modifiers for sw_format\n"); > + return AVERROR(EINVAL); > + } > + mod_props_list.drmFormatModifierCount = > + FFMIN(mod_props_list.drmFormatModifierCount, MAX_VULKAN_MODIFIERS); > + > + mod_props_list.pDrmFormatModifierProperties = mod_props; > + vk->GetPhysicalDeviceFormatProperties2(dev_hwctx->phys_dev, fmt[0], &prop); > + > + hwctx->modifier_count = 0; > + for (int i = 0; i < mod_props_list.drmFormatModifierCount; i++) { > + if (!(mod_props[i].drmFormatModifierTilingFeatures & DEFAULT_USAGE_FLAGS)) > + continue; > + hwctx->modifiers[hwctx->modifier_count++] = mod_props[i].drmFormatModifier; > + } > + if (!hwctx->modifier_count) { > + av_log(hwfc, AV_LOG_ERROR, "The supported modifiers doesn't support" > + "default usage\n"); > + return AVERROR(EINVAL); > + } > + > + hwctx->create_pnext = &hwctx->modifier_info; > + hwctx->modifier_info.pNext = NULL; > + hwctx->modifier_info.sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT; > + hwctx->modifier_info.drmFormatModifierCount = hwctx->modifier_count; > + hwctx->modifier_info.pDrmFormatModifiers = hwctx->modifiers; > + } > + > if (!hwctx->usage) > hwctx->usage = DEFAULT_USAGE_FLAGS; > > diff --git a/libavutil/hwcontext_vulkan.h b/libavutil/hwcontext_vulkan.h > index efb602ef27..113448bb51 100644 > --- a/libavutil/hwcontext_vulkan.h > +++ b/libavutil/hwcontext_vulkan.h > @@ -32,6 +32,7 @@ > * with the data pointer set to an AVVkFrame. > */ > > +#define MAX_VULKAN_MODIFIERS 16 > /** > * Main Vulkan context, allocated as AVHWDeviceContext.hwctx. > * All of these can be set before init to change what the context uses > @@ -149,6 +150,10 @@ typedef struct AVVulkanFramesContext { > */ > void *create_pnext; > > + VkImageDrmFormatModifierListCreateInfoEXT modifier_info; > + uint64_t modifiers[MAX_VULKAN_MODIFIERS]; > + int modifier_count; > I don't like having a platform-specific variable in the context, but I understand why it's necessary. Wouldn't a single modifier be sufficient, though, rather than exposing all supported modifiers? Since all images that are allocated by the frames context should all have the same modifier.
> 9 Nov 2021, 10:18 by wenbin.chen@intel.com: > > > When vulkan image exports to drm, the tilling need to be > > VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT. Now add code to > create vulkan > > image using this format. > > > > Now the following command line works: > > > > ffmpeg -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 - > hwaccel_output_format \ > > vaapi -i input_1080p.264 -vf "hwmap=derive_device=vulkan,format=vulkan, > \ > > scale_vulkan=1920:1080,hwmap=derive_device=vaapi,format=vaapi" -c:v > h264_vaapi output.264 > > > > Signed-off-by: Wenbin Chen <wenbin.chen@intel.com> > > --- > > libavutil/hwcontext_vulkan.c | 76 +++++++++++++++++++++++++++++++++- > -- > > libavutil/hwcontext_vulkan.h | 5 +++ > > 2 files changed, 75 insertions(+), 6 deletions(-) > > > > diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c > > index 29ade94b7f..e252c2177e 100644 > > --- a/libavutil/hwcontext_vulkan.c > > +++ b/libavutil/hwcontext_vulkan.c > > @@ -1919,6 +1919,7 @@ static void > try_export_flags(AVHWFramesContext *hwfc, > > AVVulkanDeviceContext *dev_hwctx = hwfc->device_ctx->hwctx; > > VulkanDevicePriv *p = hwfc->device_ctx->internal->priv; > > FFVulkanFunctions *vk = &p->vkfn; > > + const int has_modifiers = hwctx->tiling == > VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT; > > VkExternalImageFormatProperties eprops = { > > .sType = > VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR, > > }; > > @@ -1926,9 +1927,18 @@ static void > try_export_flags(AVHWFramesContext *hwfc, > > .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2, > > .pNext = &eprops, > > }; > > + VkPhysicalDeviceImageDrmFormatModifierInfoEXT phy_dev_mod_info > = { > > + .sType = > VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER > _INFO_EXT, > > + .pNext = NULL, > > + .pQueueFamilyIndices = p->qfs, > > + .queueFamilyIndexCount = p->num_qfs, > > + .sharingMode = p->num_qfs > 1 ? > VK_SHARING_MODE_CONCURRENT : > > + VK_SHARING_MODE_EXCLUSIVE, > > + }; > > VkPhysicalDeviceExternalImageFormatInfo enext = { > > .sType = > VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO, > > .handleType = exp, > > + .pNext = has_modifiers ? &phy_dev_mod_info : NULL, > > }; > > VkPhysicalDeviceImageFormatInfo2 pinfo = { > > .sType = > VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, > > @@ -1940,11 +1950,15 @@ static void > try_export_flags(AVHWFramesContext *hwfc, > > .flags = VK_IMAGE_CREATE_ALIAS_BIT, > > }; > > > > - ret = vk->GetPhysicalDeviceImageFormatProperties2(dev_hwctx- > >phys_dev, > > - &pinfo, &props); > > - if (ret == VK_SUCCESS) { > > - *iexp |= exp; > > - *comp_handle_types |= > eprops.externalMemoryProperties.compatibleHandleTypes; > > + for (int i = 0; i < (has_modifiers ? hwctx->modifier_count : 1); i++) { > > + if (has_modifiers && hwctx->modifier_count) > > + phy_dev_mod_info.drmFormatModifier = hwctx->modifiers[i]; > > + ret = vk->GetPhysicalDeviceImageFormatProperties2(dev_hwctx- > >phys_dev, > > + &pinfo, &props); > > + if (ret == VK_SUCCESS) { > > + *iexp |= exp; > > + *comp_handle_types |= > eprops.externalMemoryProperties.compatibleHandleTypes; > > + } > > } > > } > > > > @@ -2007,6 +2021,7 @@ fail: > > static void vulkan_frames_uninit(AVHWFramesContext *hwfc) > > { > > VulkanFramesPriv *fp = hwfc->internal->priv; > > + AVVulkanFramesContext *hwctx = hwfc->hwctx; > > > > free_exec_ctx(hwfc, &fp->conv_ctx); > > free_exec_ctx(hwfc, &fp->upload_ctx); > > @@ -2021,11 +2036,60 @@ static int > vulkan_frames_init(AVHWFramesContext *hwfc) > > VulkanFramesPriv *fp = hwfc->internal->priv; > > AVVulkanDeviceContext *dev_hwctx = hwfc->device_ctx->hwctx; > > VulkanDevicePriv *p = hwfc->device_ctx->internal->priv; > > + const int has_modifiers = !!(p->extensions & > FF_VK_EXT_DRM_MODIFIER_FLAGS); > > > > /* Default pool flags */ > > - hwctx->tiling = hwctx->tiling ? hwctx->tiling : p->use_linear_images ? > > + hwctx->tiling = hwctx->tiling ? hwctx->tiling : has_modifiers ? > > + VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT : p- > >use_linear_images ? > > VK_IMAGE_TILING_LINEAR : VK_IMAGE_TILING_OPTIMAL; > > > > + /* get the supported modifier */ > > + if (has_modifiers) { > > + const VkFormat *fmt = av_vkfmt_from_pixfmt(hwfc->sw_format); > > + FFVulkanFunctions *vk = &p->vkfn; > > + VkDrmFormatModifierPropertiesEXT > mod_props[MAX_VULKAN_MODIFIERS]; > > + > > + VkDrmFormatModifierPropertiesListEXT mod_props_list = { > > + .sType = > VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT, > > + .pNext = NULL, > > + .drmFormatModifierCount = 0, > > + .pDrmFormatModifierProperties = NULL, > > + }; > > + VkFormatProperties2 prop = { > > + .sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2, > > + .pNext = &mod_props_list, > > + }; > > + > > + vk->GetPhysicalDeviceFormatProperties2(dev_hwctx->phys_dev, > fmt[0], &prop); > > + if (!mod_props_list.drmFormatModifierCount) { > > + av_log(hwfc, AV_LOG_ERROR, "There are not supported modifiers > for sw_format\n"); > > + return AVERROR(EINVAL); > > + } > > + mod_props_list.drmFormatModifierCount = > > + FFMIN(mod_props_list.drmFormatModifierCount, > MAX_VULKAN_MODIFIERS); > > + > > + mod_props_list.pDrmFormatModifierProperties = mod_props; > > + vk->GetPhysicalDeviceFormatProperties2(dev_hwctx->phys_dev, > fmt[0], &prop); > > + > > + hwctx->modifier_count = 0; > > + for (int i = 0; i < mod_props_list.drmFormatModifierCount; i++) { > > + if (!(mod_props[i].drmFormatModifierTilingFeatures & > DEFAULT_USAGE_FLAGS)) > > + continue; > > + hwctx->modifiers[hwctx->modifier_count++] = > mod_props[i].drmFormatModifier; > > + } > > + if (!hwctx->modifier_count) { > > + av_log(hwfc, AV_LOG_ERROR, "The supported modifiers doesn't > support" > > + "default usage\n"); > > + return AVERROR(EINVAL); > > + } > > + > > + hwctx->create_pnext = &hwctx->modifier_info; > > + hwctx->modifier_info.pNext = NULL; > > + hwctx->modifier_info.sType = > VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INF > O_EXT; > > + hwctx->modifier_info.drmFormatModifierCount = hwctx- > >modifier_count; > > + hwctx->modifier_info.pDrmFormatModifiers = hwctx->modifiers; > > + } > > + > > if (!hwctx->usage) > > hwctx->usage = DEFAULT_USAGE_FLAGS; > > > > diff --git a/libavutil/hwcontext_vulkan.h b/libavutil/hwcontext_vulkan.h > > index efb602ef27..113448bb51 100644 > > --- a/libavutil/hwcontext_vulkan.h > > +++ b/libavutil/hwcontext_vulkan.h > > @@ -32,6 +32,7 @@ > > * with the data pointer set to an AVVkFrame. > > */ > > > > +#define MAX_VULKAN_MODIFIERS 16 > > /** > > * Main Vulkan context, allocated as AVHWDeviceContext.hwctx. > > * All of these can be set before init to change what the context uses > > @@ -149,6 +150,10 @@ typedef struct AVVulkanFramesContext { > > */ > > void *create_pnext; > > > > + VkImageDrmFormatModifierListCreateInfoEXT modifier_info; > > + uint64_t modifiers[MAX_VULKAN_MODIFIERS]; > > + int modifier_count; > > > > I don't like having a platform-specific variable in the context, but I > understand why it's necessary. Wouldn't a single modifier be sufficient, > though, rather than exposing all supported modifiers? Since all images > that are allocated by the frames context should all have the same > modifier. It is sufficient but it is not optimal, because driver can choose the optimal modifier from the list according to the platform but user can't. I can use dynamic allocation instead of putting these variables in context. Thanks Wenbin > _______________________________________________ > 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".
diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c index 29ade94b7f..e252c2177e 100644 --- a/libavutil/hwcontext_vulkan.c +++ b/libavutil/hwcontext_vulkan.c @@ -1919,6 +1919,7 @@ static void try_export_flags(AVHWFramesContext *hwfc, AVVulkanDeviceContext *dev_hwctx = hwfc->device_ctx->hwctx; VulkanDevicePriv *p = hwfc->device_ctx->internal->priv; FFVulkanFunctions *vk = &p->vkfn; + const int has_modifiers = hwctx->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT; VkExternalImageFormatProperties eprops = { .sType = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR, }; @@ -1926,9 +1927,18 @@ static void try_export_flags(AVHWFramesContext *hwfc, .sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2, .pNext = &eprops, }; + VkPhysicalDeviceImageDrmFormatModifierInfoEXT phy_dev_mod_info = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT, + .pNext = NULL, + .pQueueFamilyIndices = p->qfs, + .queueFamilyIndexCount = p->num_qfs, + .sharingMode = p->num_qfs > 1 ? VK_SHARING_MODE_CONCURRENT : + VK_SHARING_MODE_EXCLUSIVE, + }; VkPhysicalDeviceExternalImageFormatInfo enext = { .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO, .handleType = exp, + .pNext = has_modifiers ? &phy_dev_mod_info : NULL, }; VkPhysicalDeviceImageFormatInfo2 pinfo = { .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, @@ -1940,11 +1950,15 @@ static void try_export_flags(AVHWFramesContext *hwfc, .flags = VK_IMAGE_CREATE_ALIAS_BIT, }; - ret = vk->GetPhysicalDeviceImageFormatProperties2(dev_hwctx->phys_dev, - &pinfo, &props); - if (ret == VK_SUCCESS) { - *iexp |= exp; - *comp_handle_types |= eprops.externalMemoryProperties.compatibleHandleTypes; + for (int i = 0; i < (has_modifiers ? hwctx->modifier_count : 1); i++) { + if (has_modifiers && hwctx->modifier_count) + phy_dev_mod_info.drmFormatModifier = hwctx->modifiers[i]; + ret = vk->GetPhysicalDeviceImageFormatProperties2(dev_hwctx->phys_dev, + &pinfo, &props); + if (ret == VK_SUCCESS) { + *iexp |= exp; + *comp_handle_types |= eprops.externalMemoryProperties.compatibleHandleTypes; + } } } @@ -2007,6 +2021,7 @@ fail: static void vulkan_frames_uninit(AVHWFramesContext *hwfc) { VulkanFramesPriv *fp = hwfc->internal->priv; + AVVulkanFramesContext *hwctx = hwfc->hwctx; free_exec_ctx(hwfc, &fp->conv_ctx); free_exec_ctx(hwfc, &fp->upload_ctx); @@ -2021,11 +2036,60 @@ static int vulkan_frames_init(AVHWFramesContext *hwfc) VulkanFramesPriv *fp = hwfc->internal->priv; AVVulkanDeviceContext *dev_hwctx = hwfc->device_ctx->hwctx; VulkanDevicePriv *p = hwfc->device_ctx->internal->priv; + const int has_modifiers = !!(p->extensions & FF_VK_EXT_DRM_MODIFIER_FLAGS); /* Default pool flags */ - hwctx->tiling = hwctx->tiling ? hwctx->tiling : p->use_linear_images ? + hwctx->tiling = hwctx->tiling ? hwctx->tiling : has_modifiers ? + VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT : p->use_linear_images ? VK_IMAGE_TILING_LINEAR : VK_IMAGE_TILING_OPTIMAL; + /* get the supported modifier */ + if (has_modifiers) { + const VkFormat *fmt = av_vkfmt_from_pixfmt(hwfc->sw_format); + FFVulkanFunctions *vk = &p->vkfn; + VkDrmFormatModifierPropertiesEXT mod_props[MAX_VULKAN_MODIFIERS]; + + VkDrmFormatModifierPropertiesListEXT mod_props_list = { + .sType = VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT, + .pNext = NULL, + .drmFormatModifierCount = 0, + .pDrmFormatModifierProperties = NULL, + }; + VkFormatProperties2 prop = { + .sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2, + .pNext = &mod_props_list, + }; + + vk->GetPhysicalDeviceFormatProperties2(dev_hwctx->phys_dev, fmt[0], &prop); + if (!mod_props_list.drmFormatModifierCount) { + av_log(hwfc, AV_LOG_ERROR, "There are not supported modifiers for sw_format\n"); + return AVERROR(EINVAL); + } + mod_props_list.drmFormatModifierCount = + FFMIN(mod_props_list.drmFormatModifierCount, MAX_VULKAN_MODIFIERS); + + mod_props_list.pDrmFormatModifierProperties = mod_props; + vk->GetPhysicalDeviceFormatProperties2(dev_hwctx->phys_dev, fmt[0], &prop); + + hwctx->modifier_count = 0; + for (int i = 0; i < mod_props_list.drmFormatModifierCount; i++) { + if (!(mod_props[i].drmFormatModifierTilingFeatures & DEFAULT_USAGE_FLAGS)) + continue; + hwctx->modifiers[hwctx->modifier_count++] = mod_props[i].drmFormatModifier; + } + if (!hwctx->modifier_count) { + av_log(hwfc, AV_LOG_ERROR, "The supported modifiers doesn't support" + "default usage\n"); + return AVERROR(EINVAL); + } + + hwctx->create_pnext = &hwctx->modifier_info; + hwctx->modifier_info.pNext = NULL; + hwctx->modifier_info.sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT; + hwctx->modifier_info.drmFormatModifierCount = hwctx->modifier_count; + hwctx->modifier_info.pDrmFormatModifiers = hwctx->modifiers; + } + if (!hwctx->usage) hwctx->usage = DEFAULT_USAGE_FLAGS; diff --git a/libavutil/hwcontext_vulkan.h b/libavutil/hwcontext_vulkan.h index efb602ef27..113448bb51 100644 --- a/libavutil/hwcontext_vulkan.h +++ b/libavutil/hwcontext_vulkan.h @@ -32,6 +32,7 @@ * with the data pointer set to an AVVkFrame. */ +#define MAX_VULKAN_MODIFIERS 16 /** * Main Vulkan context, allocated as AVHWDeviceContext.hwctx. * All of these can be set before init to change what the context uses @@ -149,6 +150,10 @@ typedef struct AVVulkanFramesContext { */ void *create_pnext; + VkImageDrmFormatModifierListCreateInfoEXT modifier_info; + uint64_t modifiers[MAX_VULKAN_MODIFIERS]; + int modifier_count; + /** * Extension data for memory allocation. Must have as many entries as * the number of planes of the sw_format.
When vulkan image exports to drm, the tilling need to be VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT. Now add code to create vulkan image using this format. Now the following command line works: ffmpeg -hwaccel vaapi -hwaccel_device /dev/dri/renderD128 -hwaccel_output_format \ vaapi -i input_1080p.264 -vf "hwmap=derive_device=vulkan,format=vulkan, \ scale_vulkan=1920:1080,hwmap=derive_device=vaapi,format=vaapi" -c:v h264_vaapi output.264 Signed-off-by: Wenbin Chen <wenbin.chen@intel.com> --- libavutil/hwcontext_vulkan.c | 76 +++++++++++++++++++++++++++++++++--- libavutil/hwcontext_vulkan.h | 5 +++ 2 files changed, 75 insertions(+), 6 deletions(-)