From 847c7e23154d2213bbe63c91975c2e0c7c5269f2 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Thu, 7 Nov 2024 22:01:57 +0100 Subject: [PATCH] vulkan: Add support for D3D12 fences --- gdk/gdkdisplayprivate.h | 5 +++-- gdk/gdkvulkancontext.c | 11 +++++++++++ gsk/gpu/gskvulkanframe.c | 3 +++ gsk/gpu/gskvulkanimage.c | 29 +++++++++++++++++++++++++++++ gsk/gpu/gskvulkanimageprivate.h | 3 +++ 5 files changed, 49 insertions(+), 2 deletions(-) diff --git a/gdk/gdkdisplayprivate.h b/gdk/gdkdisplayprivate.h index bc4c861a52..d5ae560473 100644 --- a/gdk/gdkdisplayprivate.h +++ b/gdk/gdkdisplayprivate.h @@ -52,8 +52,9 @@ typedef enum { GDK_VULKAN_FEATURE_TIMELINE_SEMAPHORE = 1 << 3, GDK_VULKAN_FEATURE_SEMAPHORE_EXPORT = 1 << 4, GDK_VULKAN_FEATURE_SEMAPHORE_IMPORT = 1 << 5, - GDK_VULKAN_FEATURE_INCREMENTAL_PRESENT = 1 << 6, - GDK_VULKAN_FEATURE_SWAPCHAIN_MAINTENANCE = 1 << 7, + GDK_VULKAN_FEATURE_WIN32_SEMAPHORE = 1 << 6, + GDK_VULKAN_FEATURE_INCREMENTAL_PRESENT = 1 << 7, + GDK_VULKAN_FEATURE_SWAPCHAIN_MAINTENANCE = 1 << 8, } GdkVulkanFeatures; #define GDK_VULKAN_N_FEATURES 6 diff --git a/gdk/gdkvulkancontext.c b/gdk/gdkvulkancontext.c index abbcd0ffaf..bf53044cc2 100644 --- a/gdk/gdkvulkancontext.c +++ b/gdk/gdkvulkancontext.c @@ -42,6 +42,7 @@ const GdkDebugKey gdk_vulkan_feature_keys[] = { { "timeline-semaphore", GDK_VULKAN_FEATURE_TIMELINE_SEMAPHORE, "Disable timeline semaphore support (disables Windows sync)"}, { "semaphore-export", GDK_VULKAN_FEATURE_SEMAPHORE_EXPORT, "Disable sync of exported dmabufs" }, { "semaphore-import", GDK_VULKAN_FEATURE_SEMAPHORE_IMPORT, "Disable sync of imported dmabufs" }, + { "win32-semaphore", GDK_VULKAN_FEATURE_WIN32_SEMAPHORE, "Disable Windows sync support" }, { "incremental-present", GDK_VULKAN_FEATURE_INCREMENTAL_PRESENT, "Do not send damage regions" }, { "swapchain-maintenance", GDK_VULKAN_FEATURE_SWAPCHAIN_MAINTENANCE, "Do not use advanced swapchain features" }, }; @@ -639,6 +640,10 @@ physical_device_check_features (VkPhysicalDevice device) #ifdef GDK_WINDOWING_WIN32 if (physical_device_supports_extension (device, VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME)) features |= GDK_VULKAN_FEATURE_WIN32; + + if ((features & GDK_VULKAN_FEATURE_TIMELINE_SEMAPHORE) && + physical_device_supports_extension (device, VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME)) + features |= GDK_VULKAN_FEATURE_WIN32_SEMAPHORE; #endif if (physical_device_supports_extension (device, VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME)) @@ -1488,6 +1493,8 @@ gdk_display_create_vulkan_device (GdkDisplay *display, G_N_ELEMENTS (gdk_vulkan_feature_keys)); if (skip_features & GDK_VULKAN_FEATURE_YCBCR) skip_features |= GDK_VULKAN_FEATURE_DMABUF; + if (skip_features & GDK_VULKAN_FEATURE_TIMELINE_SEMAPHORE) + skip_features |= GDK_VULKAN_FEATURE_WIN32_SEMAPHORE; if (GDK_DISPLAY_DEBUG_CHECK (display, VULKAN)) { @@ -1595,6 +1602,10 @@ gdk_display_create_vulkan_device (GdkDisplay *display, g_ptr_array_add (device_extensions, (gpointer) VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME); g_ptr_array_add (device_extensions, (gpointer) VK_KHR_EXTERNAL_MEMORY_WIN32_EXTENSION_NAME); } + if (features & GDK_VULKAN_FEATURE_WIN32_SEMAPHORE) + { + g_ptr_array_add (device_extensions, (gpointer) VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME); + } #endif if (features & (GDK_VULKAN_FEATURE_SEMAPHORE_IMPORT | GDK_VULKAN_FEATURE_SEMAPHORE_EXPORT)) { diff --git a/gsk/gpu/gskvulkanframe.c b/gsk/gpu/gskvulkanframe.c index 9d2b3aae4d..fc078ee702 100644 --- a/gsk/gpu/gskvulkanframe.c +++ b/gsk/gpu/gskvulkanframe.c @@ -239,6 +239,9 @@ gsk_vulkan_frame_upload_texture (GskGpuFrame *frame, image = gsk_vulkan_image_new_for_d3d12resource (GSK_VULKAN_DEVICE (gsk_gpu_frame_get_device (frame)), gdk_d3d12_texture_get_resource (d3d_texture), gdk_d3d12_texture_get_resource_handle (d3d_texture), + gdk_d3d12_texture_get_fence (d3d_texture), + gdk_d3d12_texture_get_fence_handle (d3d_texture), + gdk_d3d12_texture_get_fence_wait (d3d_texture), gdk_memory_format_alpha (gdk_texture_get_format (texture)) != GDK_MEMORY_ALPHA_STRAIGHT); if (image) { diff --git a/gsk/gpu/gskvulkanimage.c b/gsk/gpu/gskvulkanimage.c index 72d4886dff..0707ec4376 100644 --- a/gsk/gpu/gskvulkanimage.c +++ b/gsk/gpu/gskvulkanimage.c @@ -1300,6 +1300,9 @@ GskGpuImage * gsk_vulkan_image_new_for_d3d12resource (GskVulkanDevice *device, ID3D12Resource *resource, HANDLE resource_handle, + ID3D12Fence *fence, + HANDLE fence_handle, + guint64 fence_wait, gboolean premultiplied) { GskVulkanImage *self; @@ -1465,6 +1468,32 @@ gsk_vulkan_image_new_for_d3d12resource (GskVulkanDevice *device, .memoryOffset = self->allocation.offset, }); + if (gsk_vulkan_device_has_feature (device, GDK_VULKAN_FEATURE_WIN32_SEMAPHORE) && fence) + { + PFN_vkImportSemaphoreWin32HandleKHR func_vkImportSemaphoreWin32HandleKHR; + func_vkImportSemaphoreWin32HandleKHR = (PFN_vkImportSemaphoreWin32HandleKHR) vkGetDeviceProcAddr (vk_device, "vkImportSemaphoreWin32HandleKHR"); + + GSK_VK_CHECK (vkCreateSemaphore, vk_device, + &(VkSemaphoreCreateInfo) { + .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO, + .pNext = &(VkSemaphoreTypeCreateInfo) { + .sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO, + .semaphoreType = VK_SEMAPHORE_TYPE_TIMELINE, + }, + }, + NULL, + &self->vk_semaphore); + + GSK_VK_CHECK (func_vkImportSemaphoreWin32HandleKHR, vk_device, + &(VkImportSemaphoreWin32HandleInfoKHR) { + .sType = VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR, + .handleType = VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_D3D12_FENCE_BIT, + .semaphore = self->vk_semaphore, + .handle = fence_handle, + }); + self->vk_semaphore_wait = fence_wait; + } + if (is_yuv) { self->ycbcr = gsk_vulkan_device_get_ycbcr (device, vk_format); diff --git a/gsk/gpu/gskvulkanimageprivate.h b/gsk/gpu/gskvulkanimageprivate.h index ec1d4c0ce1..683ca18b95 100644 --- a/gsk/gpu/gskvulkanimageprivate.h +++ b/gsk/gpu/gskvulkanimageprivate.h @@ -55,6 +55,9 @@ GdkTexture * gsk_vulkan_image_to_dmabuf_texture (GskVulk GskGpuImage * gsk_vulkan_image_new_for_d3d12resource (GskVulkanDevice *device, ID3D12Resource *resource, HANDLE resource_handle, + ID3D12Fence *fence, + HANDLE fence_handle, + guint64 fence_wait, gboolean premultiplied); #endif