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.
This commit is contained in:
Benjamin Otte 2023-10-19 12:54:14 +02:00
parent f0f6af1cf8
commit 223d1343de
4 changed files with 73 additions and 14 deletions

View File

@ -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 */

View File

@ -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))
{

View File

@ -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)
{

View File

@ -7,6 +7,7 @@
#include "gskvulkanmemoryprivate.h"
#include <gdk/gdkvulkancontext.h>
#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;