diff --git a/gdk/gdkdisplayprivate.h b/gdk/gdkdisplayprivate.h index 2bb3c759e5..21848ae4db 100644 --- a/gdk/gdkdisplayprivate.h +++ b/gdk/gdkdisplayprivate.h @@ -48,6 +48,7 @@ typedef enum { GDK_VULKAN_FEATURE_SEMAPHORE_EXPORT = 1 << 2, GDK_VULKAN_FEATURE_SEMAPHORE_IMPORT = 1 << 3, GDK_VULKAN_FEATURE_INCREMENTAL_PRESENT = 1 << 4, + GDK_VULKAN_FEATURE_SWAPCHAIN_MAINTENANCE = 1 << 5, } GdkVulkanFeatures; /* Tracks information about the device grab on this display */ diff --git a/gdk/gdkvulkancontext.c b/gdk/gdkvulkancontext.c index 2b07cac88e..83288f3add 100644 --- a/gdk/gdkvulkancontext.c +++ b/gdk/gdkvulkancontext.c @@ -41,6 +41,7 @@ static const GdkDebugKey gsk_vulkan_feature_keys[] = { { "semaphore-export", GDK_VULKAN_FEATURE_SEMAPHORE_EXPORT, "Disable sync of exported dmabufs" }, { "semaphore-import", GDK_VULKAN_FEATURE_SEMAPHORE_IMPORT, "Disable sync of imported dmabufs" }, { "incremental-present", GDK_VULKAN_FEATURE_INCREMENTAL_PRESENT, "Do not send damage regions" }, + { "swapchain-maintenance", GDK_VULKAN_FEATURE_SWAPCHAIN_MAINTENANCE, "Do not used advanced swapchain features" }, }; #endif @@ -303,6 +304,15 @@ surface_present_mode_to_string (VkPresentModeKHR present_mode) return "(unknown)"; } +static gboolean +gdk_vulkan_context_has_feature (GdkVulkanContext *self, + GdkVulkanFeatures feature) +{ + GdkDisplay *display = gdk_draw_context_get_display (GDK_DRAW_CONTEXT (self)); + + return (display->vulkan_features & feature) ? TRUE : FALSE; +} + static const VkPresentModeKHR preferred_present_modes[] = { VK_PRESENT_MODE_MAILBOX_KHR, VK_PRESENT_MODE_IMMEDIATE_KHR, @@ -457,8 +467,9 @@ gdk_vulkan_context_check_swapchain (GdkVulkanContext *context, res = GDK_VK_CHECK (vkCreateSwapchainKHR, device, &(VkSwapchainCreateInfoKHR) { .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, - .pNext = NULL, - .flags = 0, + .flags = + (gdk_vulkan_context_has_feature (context, GDK_VULKAN_FEATURE_SWAPCHAIN_MAINTENANCE) ? + VK_SWAPCHAIN_CREATE_DEFERRED_MEMORY_ALLOCATION_BIT_EXT : 0), .surface = priv->surface, .minImageCount = CLAMP (4, capabilities.minImageCount, @@ -556,8 +567,12 @@ physical_device_supports_extension (VkPhysicalDevice device, static GdkVulkanFeatures physical_device_check_features (VkPhysicalDevice device) { + VkPhysicalDeviceSwapchainMaintenance1FeaturesEXT swapchain_maintenance1_features = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SWAPCHAIN_MAINTENANCE_1_FEATURES_EXT, + }; VkPhysicalDeviceVulkan12Features v12_features = { .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES, + .pNext = &swapchain_maintenance1_features }; VkPhysicalDeviceSamplerYcbcrConversionFeatures ycbcr_features = { .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES, @@ -603,6 +618,10 @@ physical_device_check_features (VkPhysicalDevice device) if (physical_device_supports_extension (device, VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME)) features |= GDK_VULKAN_FEATURE_INCREMENTAL_PRESENT; + if (swapchain_maintenance1_features.swapchainMaintenance1 || + physical_device_supports_extension (device, VK_EXT_SWAPCHAIN_MAINTENANCE_1_EXTENSION_NAME)) + features |= GDK_VULKAN_FEATURE_SWAPCHAIN_MAINTENANCE; + return features; } @@ -692,11 +711,10 @@ gdk_vulkan_context_end_frame (GdkDrawContext *draw_context, GdkVulkanContext *context = GDK_VULKAN_CONTEXT (draw_context); GdkVulkanContextPrivate *priv = gdk_vulkan_context_get_instance_private (context); GdkSurface *surface = gdk_draw_context_get_surface (draw_context); - GdkDisplay *display = gdk_draw_context_get_display (draw_context); VkRectLayerKHR *rectangles; int n_regions; - if (display->vulkan_features & GDK_VULKAN_FEATURE_INCREMENTAL_PRESENT) + if (gdk_vulkan_context_has_feature (context, GDK_VULKAN_FEATURE_INCREMENTAL_PRESENT)) { double scale; @@ -1507,6 +1525,11 @@ gdk_display_create_vulkan_device (GdkDisplay *display, { if (queue_props[j].queueFlags & VK_QUEUE_GRAPHICS_BIT) { + VkPhysicalDeviceSwapchainMaintenance1FeaturesEXT swapchain_maintenance1_features = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SWAPCHAIN_MAINTENANCE_1_FEATURES_EXT, + .swapchainMaintenance1 = VK_TRUE, + }; + gpointer create_device_pNext = NULL; GPtrArray *device_extensions; device_extensions = g_ptr_array_new (); @@ -1535,6 +1558,12 @@ gdk_display_create_vulkan_device (GdkDisplay *display, } if (features & GDK_VULKAN_FEATURE_INCREMENTAL_PRESENT) g_ptr_array_add (device_extensions, (gpointer) VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME); + if (features & GDK_VULKAN_FEATURE_SWAPCHAIN_MAINTENANCE) + { + g_ptr_array_add (device_extensions, (gpointer) VK_EXT_SWAPCHAIN_MAINTENANCE_1_EXTENSION_NAME); + swapchain_maintenance1_features.pNext = create_device_pNext; + create_device_pNext = &swapchain_maintenance1_features; + } #define ENABLE_IF(flag) ((features & (flag)) ? VK_TRUE : VK_FALSE) GDK_DISPLAY_DEBUG (display, VULKAN, "Using Vulkan device %u, queue %u", i, j); @@ -1553,6 +1582,7 @@ gdk_display_create_vulkan_device (GdkDisplay *display, .pNext = &(VkPhysicalDeviceVulkan11Features) { .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES, .samplerYcbcrConversion = ENABLE_IF (GDK_VULKAN_FEATURE_YCBCR), + .pNext = create_device_pNext, } }, NULL, @@ -1671,6 +1701,10 @@ gdk_display_create_vulkan_instance (GdkDisplay *display, g_ptr_array_add (used_extensions, (gpointer) VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME); if (g_str_equal (extensions[i].extensionName, VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME)) g_ptr_array_add (used_extensions, (gpointer) VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME); + if (g_str_equal (extensions[i].extensionName, VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME)) + g_ptr_array_add (used_extensions, (gpointer) VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME); + if (g_str_equal (extensions[i].extensionName, VK_EXT_SURFACE_MAINTENANCE_1_EXTENSION_NAME)) + g_ptr_array_add (used_extensions, (gpointer) VK_EXT_SURFACE_MAINTENANCE_1_EXTENSION_NAME); } res = vkCreateInstance (&(VkInstanceCreateInfo) {