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
This commit is contained in:
Lynne 2025-01-07 13:56:11 +09:00
parent 5a72266d49
commit 851a84650e
Signed by: Lynne
GPG key ID: A2FEA5F03F034464
2 changed files with 41 additions and 19 deletions

View file

@ -112,6 +112,9 @@ typedef struct VulkanDevicePriv {
VkPhysicalDeviceMemoryProperties mprops; VkPhysicalDeviceMemoryProperties mprops;
VkPhysicalDeviceExternalMemoryHostPropertiesEXT hprops; VkPhysicalDeviceExternalMemoryHostPropertiesEXT hprops;
/* Opaque FD external semaphore properties */
VkExternalSemaphoreProperties ext_sem_props_opaque;
/* Enabled features */ /* Enabled features */
VulkanDeviceFeatures feats; VulkanDeviceFeatures feats;
@ -1715,6 +1718,7 @@ static int vulkan_device_init(AVHWDeviceContext *ctx)
FFVulkanFunctions *vk = &p->vkctx.vkfn; FFVulkanFunctions *vk = &p->vkctx.vkfn;
VkQueueFamilyProperties2 *qf; VkQueueFamilyProperties2 *qf;
VkQueueFamilyVideoPropertiesKHR *qf_vid; VkQueueFamilyVideoPropertiesKHR *qf_vid;
VkPhysicalDeviceExternalSemaphoreInfo ext_sem_props_info;
int graph_index, comp_index, tx_index, enc_index, dec_index; int graph_index, comp_index, tx_index, enc_index, dec_index;
/* Set device extension flags */ /* Set device extension flags */
@ -1760,6 +1764,24 @@ static int vulkan_device_init(AVHWDeviceContext *ctx)
return AVERROR_EXTERNAL; 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)); qf = av_malloc_array(qf_num, sizeof(VkQueueFamilyProperties2));
if (!qf) if (!qf)
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
@ -2419,8 +2441,19 @@ static int create_frame(AVHWFramesContext *hwfc, AVVkFrame **frame,
VulkanDevicePriv *p = ctx->hwctx; VulkanDevicePriv *p = ctx->hwctx;
AVVulkanDeviceContext *hwctx = &p->p; AVVulkanDeviceContext *hwctx = &p->p;
FFVulkanFunctions *vk = &p->vkctx.vkfn; 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, .sType = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO,
#ifdef _WIN32 #ifdef _WIN32
.handleTypes = IsWindows8OrGreater() .handleTypes = IsWindows8OrGreater()
@ -2431,23 +2464,13 @@ static int create_frame(AVHWFramesContext *hwfc, AVVkFrame **frame,
#endif #endif
}; };
VkSemaphoreTypeCreateInfo sem_type_info = { /* Check if exporting is supported before chaining any structs */
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO, if (p->ext_sem_props_opaque.externalSemaphoreFeatures & VK_EXTERNAL_SEMAPHORE_FEATURE_EXPORTABLE_BIT) {
#ifdef _WIN32 if (p->vkctx.extensions & (FF_VK_EXT_EXTERNAL_WIN32_SEM | FF_VK_EXT_EXTERNAL_FD_SEM))
.pNext = p->vkctx.extensions & FF_VK_EXT_EXTERNAL_WIN32_SEM ? &ext_sem_info : NULL, ff_vk_link_struct(&sem_type_info, &ext_sem_info_opaque);
#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 = { f = av_vk_frame_alloc();
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
.pNext = &sem_type_info,
};
AVVkFrame *f = av_vk_frame_alloc();
if (!f) { if (!f) {
av_log(ctx, AV_LOG_ERROR, "Unable to allocate memory for AVVkFrame!\n"); av_log(ctx, AV_LOG_ERROR, "Unable to allocate memory for AVVkFrame!\n");
return AVERROR(ENOMEM); return AVERROR(ENOMEM);

View file

@ -35,10 +35,8 @@ typedef uint64_t FFVulkanExtensions;
#define FF_VK_EXT_EXTERNAL_HOST_MEMORY (1ULL << 4) /* VK_EXT_external_memory_host */ #define FF_VK_EXT_EXTERNAL_HOST_MEMORY (1ULL << 4) /* VK_EXT_external_memory_host */
#define FF_VK_EXT_DEBUG_UTILS (1ULL << 5) /* VK_EXT_debug_utils */ #define FF_VK_EXT_DEBUG_UTILS (1ULL << 5) /* VK_EXT_debug_utils */
#ifdef _WIN32
#define FF_VK_EXT_EXTERNAL_WIN32_MEMORY (1ULL << 6) /* VK_KHR_external_memory_win32 */ #define FF_VK_EXT_EXTERNAL_WIN32_MEMORY (1ULL << 6) /* VK_KHR_external_memory_win32 */
#define FF_VK_EXT_EXTERNAL_WIN32_SEM (1ULL << 7) /* VK_KHR_external_semaphore_win32 */ #define FF_VK_EXT_EXTERNAL_WIN32_SEM (1ULL << 7) /* VK_KHR_external_semaphore_win32 */
#endif
#define FF_VK_EXT_DESCRIPTOR_BUFFER (1ULL << 8) /* VK_EXT_descriptor_buffer */ #define FF_VK_EXT_DESCRIPTOR_BUFFER (1ULL << 8) /* VK_EXT_descriptor_buffer */
#define FF_VK_EXT_DEVICE_DRM (1ULL << 9) /* VK_EXT_physical_device_drm */ #define FF_VK_EXT_DEVICE_DRM (1ULL << 9) /* VK_EXT_physical_device_drm */
@ -82,6 +80,7 @@ typedef uint64_t FFVulkanExtensions;
MACRO(1, 0, FF_VK_EXT_NO_FLAG, CreateDevice) \ MACRO(1, 0, FF_VK_EXT_NO_FLAG, CreateDevice) \
MACRO(1, 0, FF_VK_EXT_NO_FLAG, GetPhysicalDeviceFeatures2) \ MACRO(1, 0, FF_VK_EXT_NO_FLAG, GetPhysicalDeviceFeatures2) \
MACRO(1, 0, FF_VK_EXT_NO_FLAG, GetPhysicalDeviceProperties) \ MACRO(1, 0, FF_VK_EXT_NO_FLAG, GetPhysicalDeviceProperties) \
MACRO(1, 0, FF_VK_EXT_NO_FLAG, GetPhysicalDeviceExternalSemaphoreProperties) \
MACRO(1, 0, FF_VK_EXT_VIDEO_QUEUE, GetPhysicalDeviceVideoCapabilitiesKHR) \ MACRO(1, 0, FF_VK_EXT_VIDEO_QUEUE, GetPhysicalDeviceVideoCapabilitiesKHR) \
MACRO(1, 0, FF_VK_EXT_VIDEO_QUEUE, GetPhysicalDeviceVideoFormatPropertiesKHR) \ MACRO(1, 0, FF_VK_EXT_VIDEO_QUEUE, GetPhysicalDeviceVideoFormatPropertiesKHR) \
MACRO(1, 0, FF_VK_EXT_NO_FLAG, DeviceWaitIdle) \ MACRO(1, 0, FF_VK_EXT_NO_FLAG, DeviceWaitIdle) \