hwcontext_vulkan: expose enabled device and instance extensions
authorLynne <dev@lynne.ee>
Sun, 10 May 2020 10:47:50 +0000 (11:47 +0100)
committerLynne <dev@lynne.ee>
Sun, 10 May 2020 22:20:48 +0000 (23:20 +0100)
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.

doc/APIchanges
libavutil/hwcontext_vulkan.c
libavutil/hwcontext_vulkan.h
libavutil/version.h

index b3e7e89..75cfdb0 100644 (file)
@@ -15,6 +15,10 @@ libavutil:     2017-10-21
 
 API changes, most recent first:
 
+2020-05-10 - xxxxxxxxxx - lavu 56.44.100 - hwcontext_vulkan.h
+  Add enabled_inst_extensions, num_enabled_inst_extensions, enabled_dev_extensions
+  and num_enabled_dev_extensions fields to AVVulkanDeviceContext
+
 2020-04-22 - 0e1db79e37 - lavc 58.81.100 - packet.h
                         - lavu 56.43.100 - dovi_meta.h
   Add AV_PKT_DATA_DOVI_CONF and AVDOVIDecoderConfigurationRecord.
index cb805b0..aca34a3 100644 (file)
@@ -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");
index ebc2891..7f921d7 100644 (file)
@@ -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;
 
 /**
index ea9363e..48d8a38 100644 (file)
@@ -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, \