[gtk+/wip/otte/vulkan: 50/59] gdk: Add GDK_VULKAN env variable



commit 8267f29e8cda1e288f67cdaca48347523af2241d
Author: Benjamin Otte <otte redhat com>
Date:   Tue Nov 29 15:35:04 2016 +0100

    gdk: Add GDK_VULKAN env variable
    
    Also add 2 flags:
    
    GDK_VULKAN="disable" will disable Vulkan usage.
    
    GDK_VULKAN="validate" will enable VK_LAYER_LUNARG_standard_validation.

 gdk/gdk.c              |   13 +++++++-
 gdk/gdkglobals.c       |    1 +
 gdk/gdkinternals.h     |    6 ++++
 gdk/gdkvulkancontext.c |   76 ++++++++++++++++++++++++++++++++----------------
 gdk/gdkwindow.c        |    7 ++++
 5 files changed, 77 insertions(+), 26 deletions(-)
---
diff --git a/gdk/gdk.c b/gdk/gdk.c
index a59a874..abcbfd2 100644
--- a/gdk/gdk.c
+++ b/gdk/gdk.c
@@ -150,6 +150,11 @@ static const GDebugKey gdk_gl_keys[] = {
   { "gles",                  GDK_GL_GLES },
 };
 
+static const GDebugKey gdk_vulkan_keys[] = {
+  { "disable",               GDK_VULKAN_DISABLE },
+  { "validate",              GDK_VULKAN_VALIDATE },
+};
+
 #ifdef G_ENABLE_DEBUG
 static const GDebugKey gdk_debug_keys[] = {
   { "events",        GDK_DEBUG_EVENTS },
@@ -276,7 +281,7 @@ void
 gdk_pre_parse (void)
 {
   const char *rendering_mode;
-  const gchar *gl_string;
+  const gchar *gl_string, *vulkan_string;
 
   gdk_initialized = TRUE;
 
@@ -305,6 +310,12 @@ gdk_pre_parse (void)
                                           (GDebugKey *) gdk_gl_keys,
                                           G_N_ELEMENTS (gdk_gl_keys));
 
+  vulkan_string = getenv("GDK_VULKAN");
+  if (vulkan_string != NULL)
+    _gdk_vulkan_flags = g_parse_debug_string (vulkan_string,
+                                              (GDebugKey *) gdk_vulkan_keys,
+                                              G_N_ELEMENTS (gdk_vulkan_keys));
+
   if (getenv ("GDK_NATIVE_WINDOWS"))
     {
       g_warning ("The GDK_NATIVE_WINDOWS environment variable is not supported in GTK3.\n"
diff --git a/gdk/gdkglobals.c b/gdk/gdkglobals.c
index 0bef8d7..ed3b15c 100644
--- a/gdk/gdkglobals.c
+++ b/gdk/gdkglobals.c
@@ -35,4 +35,5 @@ gchar              *_gdk_display_name = NULL;
 gchar              *_gdk_display_arg_name = NULL;
 gboolean            _gdk_disable_multidevice = FALSE;
 guint               _gdk_gl_flags = 0;
+guint               _gdk_vulkan_flags = 0;
 GdkRenderingMode    _gdk_rendering_mode = GDK_RENDERING_MODE_SIMILAR;
diff --git a/gdk/gdkinternals.h b/gdk/gdkinternals.h
index 1ea17e3..ab6ef3b 100644
--- a/gdk/gdkinternals.h
+++ b/gdk/gdkinternals.h
@@ -88,11 +88,17 @@ typedef enum {
   GDK_GL_GLES                   = 1 << 6
 } GdkGLFlags;
 
+typedef enum {
+  GDK_VULKAN_DISABLE                = 1 << 0,
+  GDK_VULKAN_VALIDATE               = 1 << 1,
+} GdkVulkanFlags;
+
 extern GList            *_gdk_default_filters;
 extern GdkWindow        *_gdk_parent_root;
 
 extern guint _gdk_debug_flags;
 extern guint _gdk_gl_flags;
+extern guint _gdk_vulkan_flags;
 extern GdkRenderingMode    _gdk_rendering_mode;
 
 #ifdef G_ENABLE_DEBUG
diff --git a/gdk/gdkvulkancontext.c b/gdk/gdkvulkancontext.c
index 577d217..f9405c0 100644
--- a/gdk/gdkvulkancontext.c
+++ b/gdk/gdkvulkancontext.c
@@ -457,6 +457,9 @@ gdk_display_create_vulkan_instance (GdkDisplay  *display,
                                     GError     **error)
 {
   uint32_t i;
+  GPtrArray *used_layers;
+  gboolean validate = FALSE;
+  VkResult res;
 
   if (GDK_DISPLAY_GET_CLASS (display)->vk_extension_name == NULL)
     {
@@ -484,6 +487,8 @@ gdk_display_create_vulkan_instance (GdkDisplay  *display,
   VkLayerProperties layers[n_layers];
   GDK_VK_CHECK (vkEnumerateInstanceLayerProperties, &n_layers, layers);
 
+  used_layers = g_ptr_array_new ();
+
   for (i = 0; i < n_layers; i++)
     {
       GDK_NOTE (VULKAN, g_print ("Layer available: %s v%u.%u.%u (%s)\n",
@@ -492,37 +497,58 @@ gdk_display_create_vulkan_instance (GdkDisplay  *display,
                                  VK_VERSION_MINOR (layers[i].specVersion),
                                  VK_VERSION_PATCH (layers[i].specVersion),
                                  layers[i].description));
+      if ((_gdk_vulkan_flags & GDK_VULKAN_VALIDATE) &&
+          g_str_equal (layers[i].layerName, "VK_LAYER_LUNARG_standard_validation"))
+        {
+          g_ptr_array_add (used_layers, (gpointer) "VK_LAYER_LUNARG_standard_validation");
+          validate = TRUE;
+        }
     }
 
-  if (GDK_VK_CHECK (vkCreateInstance, &(VkInstanceCreateInfo) {
-                                           VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
-                                           NULL,
-                                           0,
-                                           &(VkApplicationInfo) {
-                                               VK_STRUCTURE_TYPE_APPLICATION_INFO,
-                                               NULL,
-                                               g_get_application_name (),
-                                               0,
-                                               "GTK+",
-                                               VK_MAKE_VERSION (GDK_MAJOR_VERSION, GDK_MINOR_VERSION, 
GDK_MICRO_VERSION),
-                                               VK_API_VERSION_1_0 },
-                                           0,
-                                           NULL,
-                                           2,
-                                           (const char *const *) &(const char *[2]) {
-                                               VK_KHR_SURFACE_EXTENSION_NAME, 
-                                               GDK_DISPLAY_GET_CLASS (display)->vk_extension_name
-                                           },
-                                       },
-                                       NULL,
-                                       &display->vk_instance) != VK_SUCCESS)
+  if ((_gdk_vulkan_flags & GDK_VULKAN_VALIDATE) && !validate)
     {
-      g_set_error_literal (error, GDK_VULKAN_ERROR, GDK_VULKAN_ERROR_UNSUPPORTED,
-                           "Could not create a Vulkan instance.");
+      g_warning ("Vulkan validation layers were requested, but not found. Running without.");
+    }
+
+  res = GDK_VK_CHECK (vkCreateInstance, &(VkInstanceCreateInfo) {
+                                             VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
+                                             NULL,
+                                             0,
+                                             &(VkApplicationInfo) {
+                                                 VK_STRUCTURE_TYPE_APPLICATION_INFO,
+                                                 NULL,
+                                                 g_get_application_name (),
+                                                 0,
+                                                 "GTK+",
+                                                 VK_MAKE_VERSION (GDK_MAJOR_VERSION, GDK_MINOR_VERSION, 
GDK_MICRO_VERSION),
+                                                 VK_API_VERSION_1_0 },
+                                             used_layers->len,
+                                             (const char * const *) used_layers->pdata,
+                                             2,
+                                             (const char *const *) &(const char *[2]) {
+                                                 VK_KHR_SURFACE_EXTENSION_NAME, 
+                                                 GDK_DISPLAY_GET_CLASS (display)->vk_extension_name
+                                             },
+                                         },
+                                         NULL,
+                                         &display->vk_instance);
+  g_ptr_array_free (used_layers, TRUE);
+
+  if (res != VK_SUCCESS)
+    {
+      g_set_error (error, GDK_VULKAN_ERROR, GDK_VULKAN_ERROR_UNSUPPORTED,
+                   "Could not create a Vulkan instance: %s", gdk_vulkan_strerror (res));
       return FALSE;
     }
 
-  return gdk_display_create_vulkan_device (display, error);
+  if (!gdk_display_create_vulkan_device (display, error))
+    {
+      vkDestroyInstance (display->vk_instance, NULL);
+      display->vk_instance = VK_NULL_HANDLE;
+      return FALSE;
+    }
+
+  return TRUE;
 }
 
 gboolean
diff --git a/gdk/gdkwindow.c b/gdk/gdkwindow.c
index 5e889f1..a5eb621 100644
--- a/gdk/gdkwindow.c
+++ b/gdk/gdkwindow.c
@@ -2704,6 +2704,13 @@ gdk_window_create_vulkan_context (GdkWindow  *window,
   g_return_val_if_fail (GDK_IS_WINDOW (window), NULL);
   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
 
+  if (_gdk_vulkan_flags & GDK_VULKAN_DISABLE)
+    {
+      g_set_error_literal (error, GDK_VULKAN_ERROR, GDK_VULKAN_ERROR_NOT_AVAILABLE,
+                           _("Vulkan support disabled via GDK_DEBUG"));
+      return NULL;
+    }
+
   display = gdk_window_get_display (window);
 
   if (GDK_DISPLAY_GET_CLASS (display)->vk_extension_name == NULL)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]