History

hwcontext_vulkan: properly support STORAGE usage for mutliplane images

Fixes multiplane support on Nvidia. Also, remove the ENCODE usage, even if the driver signals it as supported. Currently, it's not used, and when it is used, it'll be gated behind two extension checks.

Lynne committed 3 years ago

Commit 81cc0e11 parent 2a36e442 files · +39 −21Browse files

Unified · Split

2 files
  1. libavfilter/vulkan_filter.c +15 −9
  2. libavutil/hwcontext_vulkan.c +24 −12
libavfilter/vulkan_filter.c+15−9
@@ -42,18 +42,23 @@ int ff_vk_filter_init_context(AVFilterContext *avctx, FFVulkanContext *s, · 41 unmodified lines
4242 vk_frames = frames_ctx->hwctx;
4343 vk_dev = device_ctx->hwctx;
4444
45− /* Basic format validation */
45+ /* Width and height mismatch */
4646 if (width != frames_ctx->width ||
47− height != frames_ctx->height ||
48− sw_format != frames_ctx->sw_format ||
49− (vk_frames->tiling != VK_IMAGE_TILING_LINEAR &&
50− vk_frames->tiling != VK_IMAGE_TILING_OPTIMAL) ||
51− !(vk_frames->usage & VK_IMAGE_USAGE_SAMPLED_BIT)) {
47+ height != frames_ctx->height)
48+ goto skip;
49+
50+ /* Format mismatch */
51+ if (sw_format != frames_ctx->sw_format)
5252 goto skip;
53− }
5453
55− if (vk_frames->usage & VK_IMAGE_USAGE_STORAGE_BIT)
56− goto accept;
54+ /* Unusual tiling mismatch. Don't let linear through either. */
55+ if (vk_frames->tiling != VK_IMAGE_TILING_OPTIMAL)
56+ goto skip;
57+
58+ /* Usage mismatch */
59+ if ((vk_frames->usage & (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT)) !=
60+ (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT))
61+ goto skip;
5762
5863 s->extensions = ff_vk_extensions_to_mask(vk_dev->enabled_dev_extensions,
5964 vk_dev->nb_enabled_dev_extensions);
@@ -110,6 +115,7 @@ accept: · 50 unmodified lines
110115 vk_frames = frames_ctx->hwctx;
111116 vk_frames->tiling = VK_IMAGE_TILING_OPTIMAL;
112117 vk_frames->usage = VK_IMAGE_USAGE_SAMPLED_BIT |
118+ VK_IMAGE_USAGE_STORAGE_BIT |
113119 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
114120 VK_IMAGE_USAGE_TRANSFER_DST_BIT;
115121
libavutil/hwcontext_vulkan.c+24−12
@@ -282,9 +282,11 @@ FN_MAP_TO(VkImageUsageFlags, usage, VkFormatFeatureFlagBits2, feats) · 281 unmodified lines
282282
283283 static int vkfmt_from_pixfmt2(AVHWDeviceContext *dev_ctx, enum AVPixelFormat p,
284284 VkImageTiling tiling,
285− VkFormat fmts[AV_NUM_DATA_POINTERS],
286− int *nb_images, VkImageAspectFlags *aspect,
287− VkImageUsageFlags *supported_usage, int disable_multiplane)
285+ VkFormat fmts[AV_NUM_DATA_POINTERS], /* Output format list */
286+ int *nb_images, /* Output number of images */
287+ VkImageAspectFlags *aspect, /* Output aspect */
288+ VkImageUsageFlags *supported_usage, /* Output supported usage */
289+ int disable_multiplane, int need_storage)
288290 {
289291 AVVulkanDeviceContext *hwctx = dev_ctx->hwctx;
290292 VulkanDevicePriv *priv = dev_ctx->internal->priv;
@@ -301,6 +303,7 @@ static int vkfmt_from_pixfmt2(AVHWDeviceContext *dev_ctx, enum AVPixelFormat p, · 10 unmodified lines
301303 };
302304 VkFormatFeatureFlagBits2 feats_primary, feats_secondary;
303305 int basics_primary = 0, basics_secondary = 0;
306+ int storage_primary = 0, storage_secondary = 0;
304307
305308 vk->GetPhysicalDeviceFormatProperties2(hwctx->phys_dev,
306309 vk_formats_list[i].vkf,
@@ -310,6 +313,7 @@ static int vkfmt_from_pixfmt2(AVHWDeviceContext *dev_ctx, enum AVPixelFormat p, · 3 unmodified lines
310313 prop.formatProperties.linearTilingFeatures :
311314 prop.formatProperties.optimalTilingFeatures;
312315 basics_primary = (feats_primary & basic_flags) == basic_flags;
316+ storage_primary = !!(feats_primary & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT);
313317
314318 if (vk_formats_list[i].vkf != vk_formats_list[i].fallback[0]) {
315319 vk->GetPhysicalDeviceFormatProperties2(hwctx->phys_dev,
@@ -319,11 +323,15 @@ static int vkfmt_from_pixfmt2(AVHWDeviceContext *dev_ctx, enum AVPixelFormat p, · 3 unmodified lines
319323 prop.formatProperties.linearTilingFeatures :
320324 prop.formatProperties.optimalTilingFeatures;
321325 basics_secondary = (feats_secondary & basic_flags) == basic_flags;
326+ storage_secondary = !!(feats_secondary & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT);
322327 } else {
323328 basics_secondary = basics_primary;
329+ storage_secondary = storage_primary;
324330 }
325331
326− if (basics_primary && !(disable_multiplane && vk_formats_list[i].vk_planes > 1)) {
332+ if (basics_primary &&
333+ !(disable_multiplane && vk_formats_list[i].vk_planes > 1) &&
334+ (!need_storage || (need_storage && (storage_primary | storage_secondary)))) {
327335 if (fmts)
328336 fmts[0] = vk_formats_list[i].vkf;
329337 if (nb_images)
@@ -331,9 +339,12 @@ static int vkfmt_from_pixfmt2(AVHWDeviceContext *dev_ctx, enum AVPixelFormat p, · 1 unmodified line
331339 if (aspect)
332340 *aspect = vk_formats_list[i].aspect;
333341 if (supported_usage)
334− *supported_usage = map_feats_to_usage(feats_primary);
342+ *supported_usage = map_feats_to_usage(feats_primary) |
343+ ((need_storage && (storage_primary | storage_secondary)) ?
344+ VK_IMAGE_USAGE_STORAGE_BIT : 0);
335345 return 0;
336− } else if (basics_secondary) {
346+ } else if (basics_secondary &&
347+ (!need_storage || (need_storage && storage_secondary))) {
337348 if (fmts) {
338349 for (int j = 0; j < vk_formats_list[i].nb_images_fallback; j++)
339350 fmts[j] = vk_formats_list[i].fallback[j];
@@ -1640,7 +1651,7 @@ static int vulkan_frames_get_constraints(AVHWDeviceContext *ctx, · 1300 unmodified lines
16401651 count += vkfmt_from_pixfmt2(ctx, vk_formats_list[i].pixfmt,
16411652 p->use_linear_images ? VK_IMAGE_TILING_LINEAR :
16421653 VK_IMAGE_TILING_OPTIMAL,
1643− NULL, NULL, NULL, NULL, 0) >= 0;
1654+ NULL, NULL, NULL, NULL, 0, 0) >= 0;
16441655 }
16451656
16461657 #if CONFIG_CUDA
@@ -1658,7 +1669,7 @@ static int vulkan_frames_get_constraints(AVHWDeviceContext *ctx, · 11 unmodified lines
16581669 if (vkfmt_from_pixfmt2(ctx, vk_formats_list[i].pixfmt,
16591670 p->use_linear_images ? VK_IMAGE_TILING_LINEAR :
16601671 VK_IMAGE_TILING_OPTIMAL,
1661− NULL, NULL, NULL, NULL, 0) >= 0) {
1672+ NULL, NULL, NULL, NULL, 0, 0) >= 0) {
16621673 constraints->valid_sw_formats[count++] = vk_formats_list[i].pixfmt;
16631674 }
16641675 }
@@ -2294,7 +2305,8 @@ static int vulkan_frames_init(AVHWFramesContext *hwfc) · 629 unmodified lines
22942305 /* Check if the sw_format itself is supported */
22952306 err = vkfmt_from_pixfmt2(hwfc->device_ctx, hwfc->sw_format,
22962307 hwctx->tiling, NULL,
2297− NULL, NULL, &supported_usage, 0);
2308+ NULL, NULL, &supported_usage, 0,
2309+ hwctx->usage & VK_IMAGE_USAGE_STORAGE_BIT);
22982310 if (err < 0) {
22992311 av_log(hwfc, AV_LOG_ERROR, "Unsupported sw format: %s!\n",
23002312 av_get_pix_fmt_name(hwfc->sw_format));
@@ -2304,7 +2316,8 @@ static int vulkan_frames_init(AVHWFramesContext *hwfc) · 3 unmodified lines
23042316 err = vkfmt_from_pixfmt2(hwfc->device_ctx, hwfc->sw_format,
23052317 hwctx->tiling, hwctx->format, NULL,
23062318 NULL, &supported_usage,
2307− disable_multiplane);
2319+ disable_multiplane,
2320+ hwctx->usage & VK_IMAGE_USAGE_STORAGE_BIT);
23082321 if (err < 0)
23092322 return err;
23102323 }
@@ -2314,8 +2327,7 @@ static int vulkan_frames_init(AVHWFramesContext *hwfc) · 3 unmodified lines
23142327 hwctx->usage = supported_usage & (VK_BUFFER_USAGE_TRANSFER_DST_BIT |
23152328 VK_BUFFER_USAGE_TRANSFER_SRC_BIT |
23162329 VK_IMAGE_USAGE_STORAGE_BIT |
2317− VK_IMAGE_USAGE_SAMPLED_BIT |
2318− VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR);
2330+ VK_IMAGE_USAGE_SAMPLED_BIT);
23192331 }
23202332
23212333 /* Image creation flags.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t