diff options
author | Lynne <dev@lynne.ee> | 2020-05-10 11:47:50 +0100 |
---|---|---|
committer | Lynne <dev@lynne.ee> | 2020-05-10 23:20:48 +0100 |
commit | dccd07f66dfc236206bd37633a4666dbe666c0d5 (patch) | |
tree | 96d75b06b50e02967400ca2f1cc6f0daef1fddec /libavutil | |
parent | 3c5e5a5095144d72f0ce6387e4ce840f46f454ea (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')
-rw-r--r-- | libavutil/hwcontext_vulkan.c | 40 | ||||
-rw-r--r-- | libavutil/hwcontext_vulkan.h | 21 | ||||
-rw-r--r-- | libavutil/version.h | 2 |
3 files changed, 52 insertions, 11 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"); diff --git a/libavutil/hwcontext_vulkan.h b/libavutil/hwcontext_vulkan.h index ebc28916f3..7f921d7af1 100644 --- a/libavutil/hwcontext_vulkan.h +++ b/libavutil/hwcontext_vulkan.h @@ -39,7 +39,7 @@ typedef struct AVVulkanDeviceContext { */ const VkAllocationCallbacks *alloc; /** - * Instance + * Vulkan instance. Must be at least version 1.1. */ VkInstance inst; /** @@ -65,6 +65,25 @@ typedef struct AVVulkanDeviceContext { * Queue family index for compute ops */ int queue_family_comp_index; + /** + * Enabled instance extensions. By default, VK_KHR_surface is enabled if found. + * If supplying your own device context, set this to an array of strings, with + * each entry containing the specified Vulkan extension string to enable. + * Duplicates are possible and accepted. + * If no extensions are enabled, set these fields to NULL, and 0 respectively. + */ + const char * const *enabled_inst_extensions; + int nb_enabled_inst_extensions; + /** + * Enabled device extensions. By default, VK_KHR_external_memory_fd, + * VK_EXT_external_memory_dma_buf, VK_EXT_image_drm_format_modifier and + * VK_KHR_external_semaphore_fd are enabled if found. + * If supplying your own device context, these fields takes the same format as + * the above fields, with the same conditions that duplicates are possible + * and accepted, and that NULL and 0 respectively means no extensions are enabled. + */ + const char * const *enabled_dev_extensions; + int nb_enabled_dev_extensions; } AVVulkanDeviceContext; /** diff --git a/libavutil/version.h b/libavutil/version.h index ea9363e8e9..48d8a38c42 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -79,7 +79,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 56 -#define LIBAVUTIL_VERSION_MINOR 43 +#define LIBAVUTIL_VERSION_MINOR 44 #define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ |