[FFmpeg-cvslog] hwcontext_vulkan: do not chain structs of unsupported extensions in vkCreateDevice

Lynne git at videolan.org
Sun Aug 11 06:21:33 EEST 2024


ffmpeg | branch: master | Lynne <dev at lynne.ee> | Sun Aug 11 04:27:52 2024 +0200| [ef11a6456d40de57bbda9369ecedf5f242020703] | committer: Lynne

hwcontext_vulkan: do not chain structs of unsupported extensions in vkCreateDevice

Fixes:

vkCreateDevice(): pCreateInfo->pNext<VkPhysicalDeviceOpticalFlowFeaturesNV> includes a
pointer to a VkPhysicalDeviceOpticalFlowFeaturesNV, but when creating VkDevice, the
parent extension (VK_NV_optical_flow) was not included in ppEnabledExtensionNames.
The Vulkan spec states: Each pNext member of any structure (including this one) in
the pNext chain must be either NULL or a pointer to a valid struct for extending
VkDeviceCreateInfo.

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=ef11a6456d40de57bbda9369ecedf5f242020703
---

 libavutil/hwcontext_vulkan.c | 32 +++++++++++++++++++++-----------
 libavutil/vulkan.h           |  9 +++++++++
 2 files changed, 30 insertions(+), 11 deletions(-)

diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c
index 59d519727b..bdf39407e1 100644
--- a/libavutil/hwcontext_vulkan.c
+++ b/libavutil/hwcontext_vulkan.c
@@ -1369,17 +1369,27 @@ static int vulkan_device_create_internal(AVHWDeviceContext *ctx,
     p->device_features_1_2.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES;
     p->device_features_1_2.pNext = &p->device_features_1_3;
     p->device_features_1_3.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_3_FEATURES;
-    p->device_features_1_3.pNext = &p->desc_buf_features;
-    p->desc_buf_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_BUFFER_FEATURES_EXT;
-    p->desc_buf_features.pNext = &p->atomic_float_features;
-    p->atomic_float_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT;
-    p->atomic_float_features.pNext = &p->coop_matrix_features;
-    p->coop_matrix_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_KHR;
-    p->coop_matrix_features.pNext = &p->optical_flow_features;
-    p->optical_flow_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_OPTICAL_FLOW_FEATURES_NV;
-    p->optical_flow_features.pNext = &p->shader_object_features;
-    p->shader_object_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_OBJECT_FEATURES_EXT;
-    p->shader_object_features.pNext = NULL;
+    p->device_features_1_3.pNext = NULL;
+
+#define OPT_CHAIN(EXT_FLAG, STRUCT_P, TYPE)                            \
+    do {                                                               \
+        if (p->vkctx.extensions & EXT_FLAG) {                          \
+            (STRUCT_P)->sType = TYPE;                                  \
+            ff_vk_link_struct(hwctx->device_features.pNext, STRUCT_P); \
+        }                                                              \
+    } while (0)
+
+    OPT_CHAIN(FF_VK_EXT_DESCRIPTOR_BUFFER, &p->desc_buf_features,
+              VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_BUFFER_FEATURES_EXT);
+    OPT_CHAIN(FF_VK_EXT_ATOMIC_FLOAT, &p->atomic_float_features,
+              VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_FLOAT_FEATURES_EXT);
+    OPT_CHAIN(FF_VK_EXT_COOP_MATRIX, &p->coop_matrix_features,
+              VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COOPERATIVE_MATRIX_FEATURES_KHR);
+    OPT_CHAIN(FF_VK_EXT_SHADER_OBJECT, &p->shader_object_features,
+              VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_OBJECT_FEATURES_EXT);
+    OPT_CHAIN(FF_VK_EXT_OPTICAL_FLOW, &p->optical_flow_features,
+              VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_OPTICAL_FLOW_FEATURES_NV);
+#undef OPT_CHAIN
 
     ctx->free = vulkan_device_free;
 
diff --git a/libavutil/vulkan.h b/libavutil/vulkan.h
index ee0ea18fac..05bd71ae45 100644
--- a/libavutil/vulkan.h
+++ b/libavutil/vulkan.h
@@ -291,6 +291,15 @@ static inline const void *ff_vk_find_struct(const void *chain, VkStructureType s
     return NULL;
 }
 
+static inline void ff_vk_link_struct(void *chain, const void *in)
+{
+    VkBaseOutStructure *out = chain;
+    while (out->pNext)
+        out = out->pNext;
+
+    out->pNext = (void *)in;
+}
+
 /* Identity mapping - r = r, b = b, g = g, a = a */
 extern const VkComponentMapping ff_comp_identity_map;
 



More information about the ffmpeg-cvslog mailing list