summaryrefslogtreecommitdiff
path: root/libavutil/hwcontext_vulkan.c
diff options
context:
space:
mode:
authorLynne <dev@lynne.ee>2020-05-10 11:47:50 +0100
committerLynne <dev@lynne.ee>2020-05-10 23:20:48 +0100
commitdccd07f66dfc236206bd37633a4666dbe666c0d5 (patch)
tree96d75b06b50e02967400ca2f1cc6f0daef1fddec /libavutil/hwcontext_vulkan.c
parent3c5e5a5095144d72f0ce6387e4ce840f46f454ea (diff)
hwcontext_vulkan: expose enabled device and instance extensions
This solves a huge oversight - it lets users reliably use their own AVVulkanDeviceContext. Otherwise, the extensions supplied and enabled are not discoverable by anything outside of hwcontext_vulkan. Also clarifies that any user-supplied VkInstance must be at least 1.1.
Diffstat (limited to 'libavutil/hwcontext_vulkan.c')
-rw-r--r--libavutil/hwcontext_vulkan.c40
1 files changed, 31 insertions, 9 deletions
diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c
index cb805b0d1b..aca34a35a8 100644
--- a/libavutil/hwcontext_vulkan.c
+++ b/libavutil/hwcontext_vulkan.c
@@ -445,15 +445,13 @@ static int create_instance(AVHWDeviceContext *ctx, AVDictionary *opts)
/* Try to create the instance */
ret = vkCreateInstance(&inst_props, hwctx->alloc, &hwctx->inst);
- /* Free used memory */
- for (int i = 0; i < inst_props.enabledExtensionCount; i++)
- av_free((void *)inst_props.ppEnabledExtensionNames[i]);
- av_free((void *)inst_props.ppEnabledExtensionNames);
-
/* Check for errors */
if (ret != VK_SUCCESS) {
av_log(ctx, AV_LOG_ERROR, "Instance creation failure: %s\n",
vk_ret2str(ret));
+ for (int i = 0; i < inst_props.enabledExtensionCount; i++)
+ av_free((void *)inst_props.ppEnabledExtensionNames[i]);
+ av_free((void *)inst_props.ppEnabledExtensionNames);
return AVERROR_EXTERNAL;
}
@@ -476,6 +474,9 @@ static int create_instance(AVHWDeviceContext *ctx, AVDictionary *opts)
hwctx->alloc, &p->debug_ctx);
}
+ hwctx->enabled_inst_extensions = inst_props.ppEnabledExtensionNames;
+ hwctx->nb_enabled_inst_extensions = inst_props.enabledExtensionCount;
+
return 0;
}
@@ -781,6 +782,14 @@ static void vulkan_device_free(AVHWDeviceContext *ctx)
}
vkDestroyInstance(hwctx->inst, hwctx->alloc);
+
+ for (int i = 0; i < hwctx->nb_enabled_inst_extensions; i++)
+ av_free((void *)hwctx->enabled_inst_extensions[i]);
+ av_free((void *)hwctx->enabled_inst_extensions);
+
+ for (int i = 0; i < hwctx->nb_enabled_dev_extensions; i++)
+ av_free((void *)hwctx->enabled_dev_extensions[i]);
+ av_free((void *)hwctx->enabled_dev_extensions);
}
static int vulkan_device_create_internal(AVHWDeviceContext *ctx,
@@ -841,13 +850,12 @@ static int vulkan_device_create_internal(AVHWDeviceContext *ctx,
ret = vkCreateDevice(hwctx->phys_dev, &dev_info, hwctx->alloc,
&hwctx->act_dev);
- for (int i = 0; i < dev_info.enabledExtensionCount; i++)
- av_free((void *)dev_info.ppEnabledExtensionNames[i]);
- av_free((void *)dev_info.ppEnabledExtensionNames);
-
if (ret != VK_SUCCESS) {
av_log(ctx, AV_LOG_ERROR, "Device creation failure: %s\n",
vk_ret2str(ret));
+ for (int i = 0; i < dev_info.enabledExtensionCount; i++)
+ av_free((void *)dev_info.ppEnabledExtensionNames[i]);
+ av_free((void *)dev_info.ppEnabledExtensionNames);
err = AVERROR_EXTERNAL;
goto end;
}
@@ -857,6 +865,9 @@ static int vulkan_device_create_internal(AVHWDeviceContext *ctx,
if (opt_d)
p->use_linear_images = strtol(opt_d->value, NULL, 10);
+ hwctx->enabled_dev_extensions = dev_info.ppEnabledExtensionNames;
+ hwctx->nb_enabled_dev_extensions = dev_info.enabledExtensionCount;
+
end:
return err;
}
@@ -868,6 +879,17 @@ static int vulkan_device_init(AVHWDeviceContext *ctx)
AVVulkanDeviceContext *hwctx = ctx->hwctx;
VulkanDevicePriv *p = ctx->internal->priv;
+ /* Set device extension flags */
+ for (int i = 0; i < hwctx->nb_enabled_dev_extensions; i++) {
+ for (int j = 0; j < FF_ARRAY_ELEMS(optional_device_exts); j++) {
+ if (!strcmp(hwctx->enabled_dev_extensions[i],
+ optional_device_exts[j].name)) {
+ p->extensions |= optional_device_exts[j].flag;
+ break;
+ }
+ }
+ }
+
vkGetPhysicalDeviceQueueFamilyProperties(hwctx->phys_dev, &queue_num, NULL);
if (!queue_num) {
av_log(ctx, AV_LOG_ERROR, "Failed to get queues!\n");