aboutsummaryrefslogtreecommitdiffstats
path: root/libavutil/hwcontext_vulkan.c
diff options
context:
space:
mode:
authorLynne <dev@lynne.ee>2025-01-07 13:56:11 +0900
committerLynne <dev@lynne.ee>2025-01-13 10:44:30 +0900
commit851a84650ef6026871f3b565d1f54c9d7a5397a4 (patch)
tree5483973cb4d5ae13d824c2055d3df0f7f4421a6a /libavutil/hwcontext_vulkan.c
parent5a72266d49a738cd75ff6733a71497e2e3550a63 (diff)
downloadffmpeg-851a84650ef6026871f3b565d1f54c9d7a5397a4.tar.gz
hwcontext_vulkan: check if semaphores are exportable before enabling exporting
lavapipe recently added support for external_semaphore_fd, but only for syncfiles, not for opaque file descriptors. The code is written to allow using syncfiles later on. Ref: https://gitlab.freedesktop.org/mesa/mesa/-/issues/12422
Diffstat (limited to 'libavutil/hwcontext_vulkan.c')
-rw-r--r--libavutil/hwcontext_vulkan.c57
1 files changed, 40 insertions, 17 deletions
diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c
index c5f4de5684..f728163529 100644
--- a/libavutil/hwcontext_vulkan.c
+++ b/libavutil/hwcontext_vulkan.c
@@ -112,6 +112,9 @@ typedef struct VulkanDevicePriv {
VkPhysicalDeviceMemoryProperties mprops;
VkPhysicalDeviceExternalMemoryHostPropertiesEXT hprops;
+ /* Opaque FD external semaphore properties */
+ VkExternalSemaphoreProperties ext_sem_props_opaque;
+
/* Enabled features */
VulkanDeviceFeatures feats;
@@ -1715,6 +1718,7 @@ static int vulkan_device_init(AVHWDeviceContext *ctx)
FFVulkanFunctions *vk = &p->vkctx.vkfn;
VkQueueFamilyProperties2 *qf;
VkQueueFamilyVideoPropertiesKHR *qf_vid;
+ VkPhysicalDeviceExternalSemaphoreInfo ext_sem_props_info;
int graph_index, comp_index, tx_index, enc_index, dec_index;
/* Set device extension flags */
@@ -1760,6 +1764,24 @@ static int vulkan_device_init(AVHWDeviceContext *ctx)
return AVERROR_EXTERNAL;
}
+ ext_sem_props_info = (VkPhysicalDeviceExternalSemaphoreInfo) {
+ .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO,
+ };
+
+ /* Opaque FD semaphore properties */
+ ext_sem_props_info.handleType =
+#ifdef _WIN32
+ IsWindows8OrGreater()
+ ? VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_BIT
+ : VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_WIN32_KMT_BIT;
+#else
+ VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_OPAQUE_FD_BIT;
+#endif
+ p->ext_sem_props_opaque.sType = VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES;
+ vk->GetPhysicalDeviceExternalSemaphoreProperties(hwctx->phys_dev,
+ &ext_sem_props_info,
+ &p->ext_sem_props_opaque);
+
qf = av_malloc_array(qf_num, sizeof(VkQueueFamilyProperties2));
if (!qf)
return AVERROR(ENOMEM);
@@ -2419,8 +2441,19 @@ static int create_frame(AVHWFramesContext *hwfc, AVVkFrame **frame,
VulkanDevicePriv *p = ctx->hwctx;
AVVulkanDeviceContext *hwctx = &p->p;
FFVulkanFunctions *vk = &p->vkctx.vkfn;
+ AVVkFrame *f;
- VkExportSemaphoreCreateInfo ext_sem_info = {
+ VkSemaphoreTypeCreateInfo sem_type_info = {
+ .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
+ .semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE,
+ .initialValue = 0,
+ };
+ VkSemaphoreCreateInfo sem_spawn = {
+ .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
+ .pNext = &sem_type_info,
+ };
+
+ VkExportSemaphoreCreateInfo ext_sem_info_opaque = {
.sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO,
#ifdef _WIN32
.handleTypes = IsWindows8OrGreater()
@@ -2431,23 +2464,13 @@ static int create_frame(AVHWFramesContext *hwfc, AVVkFrame **frame,
#endif
};
- VkSemaphoreTypeCreateInfo sem_type_info = {
- .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO,
-#ifdef _WIN32
- .pNext = p->vkctx.extensions & FF_VK_EXT_EXTERNAL_WIN32_SEM ? &ext_sem_info : NULL,
-#else
- .pNext = p->vkctx.extensions & FF_VK_EXT_EXTERNAL_FD_SEM ? &ext_sem_info : NULL,
-#endif
- .semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE,
- .initialValue = 0,
- };
-
- VkSemaphoreCreateInfo sem_spawn = {
- .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
- .pNext = &sem_type_info,
- };
+ /* Check if exporting is supported before chaining any structs */
+ if (p->ext_sem_props_opaque.externalSemaphoreFeatures & VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT) {
+ if (p->vkctx.extensions & (FF_VK_EXT_EXTERNAL_WIN32_SEM | FF_VK_EXT_EXTERNAL_FD_SEM))
+ ff_vk_link_struct(&sem_type_info, &ext_sem_info_opaque);
+ }
- AVVkFrame *f = av_vk_frame_alloc();
+ f = av_vk_frame_alloc();
if (!f) {
av_log(ctx, AV_LOG_ERROR, "Unable to allocate memory for AVVkFrame!\n");
return AVERROR(ENOMEM);