From 3f42d92eafa64cf4d82e1d41d6551d0f8d53205e Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Thu, 19 Oct 2023 12:54:14 +0200 Subject: [PATCH] gpu: Add GdkDisplay::vulkan_features use it to collect the optional features we are interested in and turn them on only if available. For now we add the dmabuf features, but we don't use them yet. --- gdk/gdkdisplayprivate.h | 6 +++ gdk/gdkvulkancontext.c | 69 +++++++++++++++++++++++++------- gsk/gpu/gskvulkandevice.c | 9 +++++ gsk/gpu/gskvulkandeviceprivate.h | 3 ++ 4 files changed, 73 insertions(+), 14 deletions(-) diff --git a/gdk/gdkdisplayprivate.h b/gdk/gdkdisplayprivate.h index 702f7bdbd4..085a1226c1 100644 --- a/gdk/gdkdisplayprivate.h +++ b/gdk/gdkdisplayprivate.h @@ -41,6 +41,11 @@ G_BEGIN_DECLS typedef struct _GdkDisplayClass GdkDisplayClass; +typedef enum { + GDK_VULKAN_FEATURE_DMABUF = 1 << 0, + GDK_VULKAN_FEATURE_YCBCR = 1 << 1 +} GdkVulkanFeatures; + /* Tracks information about the device grab on this display */ typedef struct { @@ -107,6 +112,7 @@ struct _GdkDisplay char *vk_pipeline_cache_etag; guint vk_save_pipeline_cache_source; GHashTable *vk_shader_modules; + GdkVulkanFeatures vulkan_features; guint vulkan_refcount; #endif /* GDK_RENDERING_VULKAN */ diff --git a/gdk/gdkvulkancontext.c b/gdk/gdkvulkancontext.c index 4ba2c6bbd4..ebf74ed039 100644 --- a/gdk/gdkvulkancontext.c +++ b/gdk/gdkvulkancontext.c @@ -533,6 +533,36 @@ physical_device_supports_extension (VkPhysicalDevice device, return FALSE; } +static gboolean +physical_device_check_features (VkPhysicalDevice device, + GdkVulkanFeatures *out_features) +{ + VkPhysicalDeviceSamplerYcbcrConversionFeatures ycbcr_features = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES + }; + VkPhysicalDeviceFeatures2 features = { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2, + .pNext = &ycbcr_features + }; + + vkGetPhysicalDeviceFeatures2 (device, &features); + + *out_features = 0; + + if (!features.features.shaderUniformBufferArrayDynamicIndexing || + !features.features.shaderSampledImageArrayDynamicIndexing) + return FALSE; + + if (ycbcr_features.samplerYcbcrConversion) + *out_features |= GDK_VULKAN_FEATURE_YCBCR; + + if (physical_device_supports_extension (device, VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME) && + physical_device_supports_extension (device, VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME)) + *out_features |= GDK_VULKAN_FEATURE_DMABUF; + + return TRUE; +} + static void gdk_vulkan_context_begin_frame (GdkDrawContext *draw_context, GdkMemoryDepth depth, @@ -1368,11 +1398,15 @@ gdk_display_create_vulkan_device (GdkDisplay *display, for (i = first; i < last; i++) { + GdkVulkanFeatures features; uint32_t n_queue_props; if (!physical_device_supports_extension (devices[i], VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME)) continue; + if (!physical_device_check_features (devices[i], &features)) + continue; + vkGetPhysicalDeviceQueueFamilyProperties (devices[i], &n_queue_props, NULL); VkQueueFamilyProperties *queue_props = g_newa (VkQueueFamilyProperties, n_queue_props); vkGetPhysicalDeviceQueueFamilyProperties (devices[i], &n_queue_props, queue_props); @@ -1381,16 +1415,17 @@ gdk_display_create_vulkan_device (GdkDisplay *display, if (queue_props[j].queueFlags & VK_QUEUE_GRAPHICS_BIT) { GPtrArray *device_extensions; - gboolean has_incremental_present; - - has_incremental_present = physical_device_supports_extension (devices[i], - VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME); device_extensions = g_ptr_array_new (); g_ptr_array_add (device_extensions, (gpointer) VK_KHR_SWAPCHAIN_EXTENSION_NAME); g_ptr_array_add (device_extensions, (gpointer) VK_KHR_MAINTENANCE_3_EXTENSION_NAME); g_ptr_array_add (device_extensions, (gpointer) VK_EXT_DESCRIPTOR_INDEXING_EXTENSION_NAME); - if (has_incremental_present) + if (features & GDK_VULKAN_FEATURE_DMABUF) + { + g_ptr_array_add (device_extensions, (gpointer) VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME); + g_ptr_array_add (device_extensions, (gpointer) VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME); + } + if (physical_device_supports_extension (devices[i], VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME)) g_ptr_array_add (device_extensions, (gpointer) VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME); GDK_DISPLAY_DEBUG (display, VULKAN, "Using Vulkan device %u, queue %u", i, j); @@ -1406,15 +1441,19 @@ gdk_display_create_vulkan_device (GdkDisplay *display, }, .enabledExtensionCount = device_extensions->len, .ppEnabledExtensionNames = (const char * const *) device_extensions->pdata, - .pNext = &(VkPhysicalDeviceVulkan12Features) { - .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES, - .shaderSampledImageArrayNonUniformIndexing = VK_TRUE, - .shaderStorageBufferArrayNonUniformIndexing = VK_TRUE, - .descriptorIndexing = VK_TRUE, - .descriptorBindingPartiallyBound = VK_TRUE, - .descriptorBindingVariableDescriptorCount = VK_TRUE, - .descriptorBindingSampledImageUpdateAfterBind = VK_TRUE, - .descriptorBindingStorageBufferUpdateAfterBind = VK_TRUE, + .pNext = &(VkPhysicalDeviceVulkan11Features) { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_1_FEATURES, + .samplerYcbcrConversion = features & GDK_VULKAN_FEATURE_YCBCR ? VK_TRUE : VK_FALSE, + .pNext = &(VkPhysicalDeviceVulkan12Features) { + .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_1_2_FEATURES, + .shaderSampledImageArrayNonUniformIndexing = VK_TRUE, + .shaderStorageBufferArrayNonUniformIndexing = VK_TRUE, + .descriptorIndexing = VK_TRUE, + .descriptorBindingPartiallyBound = VK_TRUE, + .descriptorBindingVariableDescriptorCount = VK_TRUE, + .descriptorBindingSampledImageUpdateAfterBind = VK_TRUE, + .descriptorBindingStorageBufferUpdateAfterBind = VK_TRUE, + } } }, NULL, @@ -1429,6 +1468,7 @@ gdk_display_create_vulkan_device (GdkDisplay *display, display->vk_physical_device = devices[i]; vkGetDeviceQueue(display->vk_device, j, 0, &display->vk_queue); display->vk_queue_family_index = j; + display->vulkan_features = features; return TRUE; } } @@ -1685,6 +1725,7 @@ gdk_display_unref_vulkan (GdkDisplay *display) return; GDK_DEBUG (VULKAN, "Closing Vulkan instance"); + display->vulkan_features = 0; g_hash_table_iter_init (&iter, display->vk_shader_modules); while (g_hash_table_iter_next (&iter, &key, &value)) { diff --git a/gsk/gpu/gskvulkandevice.c b/gsk/gpu/gskvulkandevice.c index c45dec49b9..6de7551e4d 100644 --- a/gsk/gpu/gskvulkandevice.c +++ b/gsk/gpu/gskvulkandevice.c @@ -17,6 +17,7 @@ struct _GskVulkanDevice GskGpuDevice parent_instance; GskVulkanAllocator *allocators[VK_MAX_MEMORY_TYPES]; + GdkVulkanFeatures features; GHashTable *pipeline_cache; GHashTable *render_pass_cache; @@ -314,6 +315,7 @@ gsk_vulkan_device_get_for_display (GdkDisplay *display, return NULL; self = g_object_new (GSK_TYPE_VULKAN_DEVICE, NULL); + self->features = display->vulkan_features; vkGetPhysicalDeviceProperties (display->vk_physical_device, &vk_props); gsk_gpu_device_setup (GSK_GPU_DEVICE (self), @@ -332,6 +334,13 @@ gsk_vulkan_device_get_max_descriptors (GskVulkanDevice *self) return DESCRIPTOR_POOL_MAXITEMS; } +gboolean +gsk_vulkan_device_has_feature (GskVulkanDevice *self, + GdkVulkanFeatures feature) +{ + return (self->features & feature) == feature; +} + VkDevice gsk_vulkan_device_get_vk_device (GskVulkanDevice *self) { diff --git a/gsk/gpu/gskvulkandeviceprivate.h b/gsk/gpu/gskvulkandeviceprivate.h index 84a369d9e9..c68bd2bae1 100644 --- a/gsk/gpu/gskvulkandeviceprivate.h +++ b/gsk/gpu/gskvulkandeviceprivate.h @@ -7,6 +7,7 @@ #include "gskvulkanmemoryprivate.h" #include +#include "gdk/gdkdisplayprivate.h" G_BEGIN_DECLS @@ -26,6 +27,8 @@ GskGpuDevice * gsk_vulkan_device_get_for_display (GdkDisp GError **error); gsize gsk_vulkan_device_get_max_descriptors (GskVulkanDevice *self) G_GNUC_PURE; +gboolean gsk_vulkan_device_has_feature (GskVulkanDevice *self, + GdkVulkanFeatures feature) G_GNUC_PURE; VkDevice gsk_vulkan_device_get_vk_device (GskVulkanDevice *self) G_GNUC_PURE; VkPhysicalDevice gsk_vulkan_device_get_vk_physical_device (GskVulkanDevice *self) G_GNUC_PURE;