From 5f0305356929ecdaf81cdedaf7333e1cee63b697 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sat, 6 Jan 2024 19:58:24 +0100 Subject: [PATCH 01/19] gsk: include Vulkan renderer in public header The Vulkan renderer can just be public API, because it doesn't expose any Vulkan-specific APIs. And it can just exist when compiled without Vulkan, because it can fail to realize. Also move get rid of the gsk/vulkan/gskvulkanrenderer.h header. It was experimental and isn't necessary now that the renderer is included via gsk.h. --- demos/node-editor/node-editor-window.c | 3 --- gsk/gpu/gskvulkanrenderer.c | 16 +++++++++++++--- gsk/{vulkan => gpu}/gskvulkanrenderer.h | 10 +++++----- gsk/gsk.h | 1 + gsk/gskrenderer.c | 7 +++---- gsk/meson.build | 16 +++++++--------- gtk/gtktestutils.c | 8 ++------ testsuite/gdk/memorytexture.c | 5 ----- testsuite/gsk/scaling.c | 5 ----- 9 files changed, 31 insertions(+), 40 deletions(-) rename gsk/{vulkan => gpu}/gskvulkanrenderer.h (92%) diff --git a/demos/node-editor/node-editor-window.c b/demos/node-editor/node-editor-window.c index a29ac33ccbf..a7d6a9064ff 100644 --- a/demos/node-editor/node-editor-window.c +++ b/demos/node-editor/node-editor-window.c @@ -28,9 +28,6 @@ #ifdef GDK_WINDOWING_BROADWAY #include "gsk/broadway/gskbroadwayrenderer.h" #endif -#ifdef GDK_RENDERING_VULKAN -#include "gsk/vulkan/gskvulkanrenderer.h" -#endif #include #ifdef CAIRO_HAS_SVG_SURFACE diff --git a/gsk/gpu/gskvulkanrenderer.c b/gsk/gpu/gskvulkanrenderer.c index 7ba5fdbd114..eee7ec26b5b 100644 --- a/gsk/gpu/gskvulkanrenderer.c +++ b/gsk/gpu/gskvulkanrenderer.c @@ -1,20 +1,26 @@ #include "config.h" -#include "gsk/vulkan/gskvulkanrenderer.h" +#include "gskvulkanrenderer.h" #include "gskgpurendererprivate.h" + +#ifdef GDK_RENDERING_VULKAN + #include "gskvulkandeviceprivate.h" #include "gskvulkanframeprivate.h" #include "gskvulkanimageprivate.h" #include "gdk/gdkdisplayprivate.h" +#endif struct _GskVulkanRenderer { GskGpuRenderer parent_instance; +#ifdef GDK_RENDERING_VULKAN guint n_targets; GskGpuImage **targets; +#endif }; struct _GskVulkanRendererClass @@ -24,6 +30,7 @@ struct _GskVulkanRendererClass G_DEFINE_TYPE (GskVulkanRenderer, gsk_vulkan_renderer, GSK_TYPE_GPU_RENDERER) +#ifdef GDK_RENDERING_VULKAN static void gsk_vulkan_renderer_free_targets (GskVulkanRenderer *self) { @@ -171,10 +178,12 @@ gsk_vulkan_renderer_unrealize (GskRenderer *renderer) GSK_RENDERER_CLASS (gsk_vulkan_renderer_parent_class)->unrealize (renderer); } +#endif static void gsk_vulkan_renderer_class_init (GskVulkanRendererClass *klass) { +#ifdef GDK_RENDERING_VULKAN GskGpuRendererClass *gpu_renderer_class = GSK_GPU_RENDERER_CLASS (klass); GskRendererClass *renderer_class = GSK_RENDERER_CLASS (klass); @@ -188,6 +197,7 @@ gsk_vulkan_renderer_class_init (GskVulkanRendererClass *klass) gpu_renderer_class->get_dmabuf_formats = gsk_vulkan_renderer_get_dmabuf_formats; renderer_class->unrealize = gsk_vulkan_renderer_unrealize; +#endif } static void @@ -203,8 +213,8 @@ gsk_vulkan_renderer_init (GskVulkanRenderer *self) * The Vulkan renderer is a renderer that uses the Vulkan library for * rendering. * - * This function is only available when GTK was compiled with Vulkan - * support. + * This renderer will fail to realize when GTK was not compiled with + * Vulkan support. * * Returns: a new Vulkan renderer **/ diff --git a/gsk/vulkan/gskvulkanrenderer.h b/gsk/gpu/gskvulkanrenderer.h similarity index 92% rename from gsk/vulkan/gskvulkanrenderer.h rename to gsk/gpu/gskvulkanrenderer.h index 0b4e74a58df..0346e5ca863 100644 --- a/gsk/vulkan/gskvulkanrenderer.h +++ b/gsk/gpu/gskvulkanrenderer.h @@ -20,10 +20,6 @@ #include #include -#ifdef GDK_RENDERING_VULKAN - -#include - G_BEGIN_DECLS #define GSK_TYPE_VULKAN_RENDERER (gsk_vulkan_renderer_get_type ()) @@ -38,6 +34,8 @@ G_BEGIN_DECLS * GskVulkanRenderer: * * A GSK renderer that is using Vulkan. + * + * This renderer will fail to realize if Vulkan is not supported. */ typedef struct _GskVulkanRenderer GskVulkanRenderer; typedef struct _GskVulkanRendererClass GskVulkanRendererClass; @@ -48,4 +46,6 @@ GType gsk_vulkan_renderer_get_type (void) G_GNUC_CO GDK_AVAILABLE_IN_ALL GskRenderer * gsk_vulkan_renderer_new (void); -#endif +G_DEFINE_AUTOPTR_CLEANUP_FUNC(GskVulkanRenderer, g_object_unref) + +G_END_DECLS diff --git a/gsk/gsk.h b/gsk/gsk.h index 9f2ee451dd2..11155ff150a 100644 --- a/gsk/gsk.h +++ b/gsk/gsk.h @@ -32,6 +32,7 @@ #include #include +#include #include #include diff --git a/gsk/gskrenderer.c b/gsk/gskrenderer.c index ec93c06ac6a..7d9d8bdd76f 100644 --- a/gsk/gskrenderer.c +++ b/gsk/gskrenderer.c @@ -38,20 +38,19 @@ #include "gskcairorenderer.h" #include "gskdebugprivate.h" -#include "gl/gskglrenderer.h" #include "gskprofilerprivate.h" #include "gskrendernodeprivate.h" #include "gskoffloadprivate.h" #include "gskenumtypes.h" +#include "gl/gskglrenderer.h" +#include "gpu/gskvulkanrenderer.h" + #include #include #include -#ifdef GDK_RENDERING_VULKAN -#include "vulkan/gskvulkanrenderer.h" -#endif #ifdef GDK_WINDOWING_X11 #include #endif diff --git a/gsk/meson.build b/gsk/meson.build index 273fdc63bc8..b30a7ec9f8a 100644 --- a/gsk/meson.build +++ b/gsk/meson.build @@ -109,6 +109,7 @@ gsk_private_sources = files([ 'gpu/gskgpuuberop.c', 'gpu/gskgpuuploadop.c', 'gpu/gsknglrenderer.c', + 'gpu/gskvulkanrenderer.c', ]) gsk_f16c_sources = files([ @@ -138,6 +139,12 @@ gsk_public_gl_headers = files([ install_headers(gsk_public_gl_headers, subdir: 'gtk-4.0/gsk/gl') gsk_public_headers += gsk_public_gl_headers +gsk_public_gpu_headers = files([ + 'gpu/gskvulkanrenderer.h' +]) +install_headers(gsk_public_gpu_headers, subdir: 'gtk-4.0/gsk/gpu') +gsk_public_headers += gsk_public_gpu_headers + if get_variable('broadway_enabled') gsk_public_broadway_headers = files([ 'broadway/gskbroadwayrenderer.h' @@ -146,14 +153,6 @@ if get_variable('broadway_enabled') gsk_public_headers += gsk_public_broadway_headers endif -if have_vulkan - gsk_public_vulkan_headers = files([ - 'vulkan/gskvulkanrenderer.h' - ]) - install_headers(gsk_public_vulkan_headers, subdir: 'gtk-4.0/gsk/vulkan') - gsk_public_headers += gsk_public_vulkan_headers -endif - gsk_private_vulkan_shaders = [] gsk_private_vulkan_compiled_shaders = [] gsk_private_vulkan_compiled_shaders_deps = [] @@ -168,7 +167,6 @@ if have_vulkan 'gpu/gskvulkanimage.c', 'gpu/gskvulkanmemory.c', 'gpu/gskvulkanrealdescriptors.c', - 'gpu/gskvulkanrenderer.c', 'gpu/gskvulkansubdescriptors.c', ]) endif # have_vulkan diff --git a/gtk/gtktestutils.c b/gtk/gtktestutils.c index face9c37236..05232d57630 100644 --- a/gtk/gtktestutils.c +++ b/gtk/gtktestutils.c @@ -27,6 +27,8 @@ #include "gtktextview.h" #include "gtkrange.h" +#include + #include #include #include @@ -40,16 +42,10 @@ #include #define GTK_COMPILATION -#include - #ifdef GDK_WINDOWING_BROADWAY #include #endif -#ifdef GDK_RENDERING_VULKAN -#include -#endif - #ifdef GDK_WINDOWING_X11 #include #endif diff --git a/testsuite/gdk/memorytexture.c b/testsuite/gdk/memorytexture.c index 5d53e7ae591..afbd243995e 100644 --- a/testsuite/gdk/memorytexture.c +++ b/testsuite/gdk/memorytexture.c @@ -1,9 +1,6 @@ #include #include "gsk/gl/gskglrenderer.h" -#ifdef GDK_RENDERING_VULKAN -#include "gsk/vulkan/gskvulkanrenderer.h" -#endif #include @@ -1483,13 +1480,11 @@ main (int argc, char *argv[]) g_clear_object (&ngl_renderer); } -#ifdef GDK_RENDERING_VULKAN vulkan_renderer = gsk_vulkan_renderer_new (); if (!gsk_renderer_realize (vulkan_renderer, NULL, NULL)) { g_clear_object (&vulkan_renderer); } -#endif result = g_test_run (); diff --git a/testsuite/gsk/scaling.c b/testsuite/gsk/scaling.c index 70039f5d710..b73b4138405 100644 --- a/testsuite/gsk/scaling.c +++ b/testsuite/gsk/scaling.c @@ -1,9 +1,6 @@ #include #include "gsk/gl/gskglrenderer.h" -#ifdef GDK_RENDERING_VULKAN -#include "gsk/vulkan/gskvulkanrenderer.h" -#endif #include @@ -25,12 +22,10 @@ struct { "cairo", gsk_cairo_renderer_new, }, -#ifdef GDK_RENDERING_VULKAN { "vulkan", gsk_vulkan_renderer_new, }, -#endif { "ngl", gsk_ngl_renderer_new, -- GitLab From c8529df309ced8c9b658d92391b67ad935ce2a0b Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sun, 7 Jan 2024 09:38:48 +0100 Subject: [PATCH 02/19] inspector: Use Vulkan without a context This means we don't need to include gdkvulkancontext.h and it means we don't initialize Vulkan if it isn't initialized yet. Should we? Should we add a button maybe? No idea. --- gtk/inspector/general.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/gtk/inspector/general.c b/gtk/inspector/general.c index 7b01a994381..fc0f8b62d38 100644 --- a/gtk/inspector/general.c +++ b/gtk/inspector/general.c @@ -447,7 +447,7 @@ init_gl (GtkInspectorGeneral *gen) #ifdef GDK_RENDERING_VULKAN static gboolean -has_debug_extension (GdkVulkanContext *context) +has_debug_extension (void) { uint32_t i; uint32_t n_extensions; @@ -465,7 +465,7 @@ has_debug_extension (GdkVulkanContext *context) } static gboolean -has_validation_layer (GdkVulkanContext *context) +has_validation_layer (void) { uint32_t i; uint32_t n_layers; @@ -487,9 +487,6 @@ static void init_vulkan (GtkInspectorGeneral *gen) { #ifdef GDK_RENDERING_VULKAN - GdkSurface *surface; - GdkVulkanContext *context; - if (gdk_display_get_debug_flags (gen->display) & GDK_DEBUG_VULKAN_DISABLE) { gtk_label_set_text (GTK_LABEL (gen->vk_device), C_("Vulkan device", "Disabled")); @@ -498,11 +495,7 @@ init_vulkan (GtkInspectorGeneral *gen) return; } - surface = gdk_surface_new_toplevel (gen->display); - context = gdk_surface_create_vulkan_context (surface, NULL); - gdk_surface_destroy (surface); - - if (context) + if (gen->display->vk_device) { VkPhysicalDevice vk_device; VkPhysicalDeviceProperties props; @@ -510,7 +503,7 @@ init_vulkan (GtkInspectorGeneral *gen) char *api_version; char *driver_version; - vk_device = gdk_vulkan_context_get_physical_device (context); + vk_device = gen->display->vk_physical_device; vkGetPhysicalDeviceProperties (vk_device, &props); device_name = g_strdup_printf ("%s (%d)", props.deviceName, props.deviceType); @@ -541,11 +534,9 @@ init_vulkan (GtkInspectorGeneral *gen) add_check_row (gen, GTK_LIST_BOX (gen->vulkan_extensions_box), "VK_KHR_wayland_surface", TRUE, 0); #endif add_check_row (gen, GTK_LIST_BOX (gen->vulkan_extensions_box), VK_EXT_DEBUG_REPORT_EXTENSION_NAME, - has_debug_extension (context), 0); + has_debug_extension (), 0); add_check_row (gen, GTK_LIST_BOX (gen->vulkan_extensions_box), "VK_LAYER_KHRONOS_validation", - has_validation_layer (context), 0); - - g_object_unref (context); + has_validation_layer (), 0); } else #endif -- GitLab From d21467e2e80e732479fc4b60a9dc12429419567c Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sun, 7 Jan 2024 09:39:21 +0100 Subject: [PATCH 03/19] gdk: Remove all VulkanContext API All API for GdkVulkanContext gets removed here. It was experimental and it's not a good API. So get rid of it. --- gdk/gdkvulkancontext.h | 31 ------------------------------- gdk/gdkvulkancontextprivate.h | 14 ++++++++++++++ gsk/gpu/gskvulkandeviceprivate.h | 2 +- 3 files changed, 15 insertions(+), 32 deletions(-) diff --git a/gdk/gdkvulkancontext.h b/gdk/gdkvulkancontext.h index 55a347861b9..3bc9f50961a 100644 --- a/gdk/gdkvulkancontext.h +++ b/gdk/gdkvulkancontext.h @@ -44,37 +44,6 @@ GQuark gdk_vulkan_error_quark (void); GDK_AVAILABLE_IN_ALL GType gdk_vulkan_context_get_type (void) G_GNUC_CONST; -#ifndef __GI_SCANNER__ -#ifdef GDK_RENDERING_VULKAN - -GDK_AVAILABLE_IN_ALL -const char * gdk_vulkan_strerror (VkResult result); - -GDK_AVAILABLE_IN_ALL -VkInstance gdk_vulkan_context_get_instance (GdkVulkanContext *context); -GDK_AVAILABLE_IN_ALL -VkPhysicalDevice gdk_vulkan_context_get_physical_device (GdkVulkanContext *context); -GDK_AVAILABLE_IN_ALL -VkDevice gdk_vulkan_context_get_device (GdkVulkanContext *context); -GDK_AVAILABLE_IN_ALL -VkQueue gdk_vulkan_context_get_queue (GdkVulkanContext *context); -GDK_AVAILABLE_IN_ALL -uint32_t gdk_vulkan_context_get_queue_family_index (GdkVulkanContext *context); -GDK_AVAILABLE_IN_ALL -VkFormat gdk_vulkan_context_get_image_format (GdkVulkanContext *context); -GDK_AVAILABLE_IN_ALL -uint32_t gdk_vulkan_context_get_n_images (GdkVulkanContext *context); -GDK_AVAILABLE_IN_ALL -VkImage gdk_vulkan_context_get_image (GdkVulkanContext *context, - guint id); -GDK_AVAILABLE_IN_ALL -uint32_t gdk_vulkan_context_get_draw_index (GdkVulkanContext *context); -GDK_AVAILABLE_IN_ALL -VkSemaphore gdk_vulkan_context_get_draw_semaphore (GdkVulkanContext *context); - -#endif /* GDK_RENDERING_VULKAN */ -#endif /* __GI_SCANNER__ */ - G_DEFINE_AUTOPTR_CLEANUP_FUNC(GdkVulkanContext, g_object_unref) G_END_DECLS diff --git a/gdk/gdkvulkancontextprivate.h b/gdk/gdkvulkancontextprivate.h index 904c44d661e..a68a821321b 100644 --- a/gdk/gdkvulkancontextprivate.h +++ b/gdk/gdkvulkancontextprivate.h @@ -57,6 +57,8 @@ struct _GdkVulkanContextClass #ifdef GDK_RENDERING_VULKAN +const char * gdk_vulkan_strerror (VkResult result); + static inline VkResult gdk_vulkan_handle_result (VkResult res, const char *called_function) @@ -84,6 +86,18 @@ VkShaderModule gdk_display_get_vk_shader_module (GdkDisp void gdk_display_vulkan_pipeline_cache_updated (GdkDisplay *display); +VkInstance gdk_vulkan_context_get_instance (GdkVulkanContext *context); +VkPhysicalDevice gdk_vulkan_context_get_physical_device (GdkVulkanContext *context); +VkDevice gdk_vulkan_context_get_device (GdkVulkanContext *context); +VkQueue gdk_vulkan_context_get_queue (GdkVulkanContext *context); +uint32_t gdk_vulkan_context_get_queue_family_index (GdkVulkanContext *context); +VkFormat gdk_vulkan_context_get_image_format (GdkVulkanContext *context); +uint32_t gdk_vulkan_context_get_n_images (GdkVulkanContext *context); +VkImage gdk_vulkan_context_get_image (GdkVulkanContext *context, + guint id); +uint32_t gdk_vulkan_context_get_draw_index (GdkVulkanContext *context); +VkSemaphore gdk_vulkan_context_get_draw_semaphore (GdkVulkanContext *context); + GdkMemoryFormat gdk_vulkan_context_get_offscreen_format (GdkVulkanContext *context, GdkMemoryDepth depth); diff --git a/gsk/gpu/gskvulkandeviceprivate.h b/gsk/gpu/gskvulkandeviceprivate.h index 6e79a04a6eb..564cb54051a 100644 --- a/gsk/gpu/gskvulkandeviceprivate.h +++ b/gsk/gpu/gskvulkandeviceprivate.h @@ -6,8 +6,8 @@ #include "gskgpuclipprivate.h" #include "gskvulkanmemoryprivate.h" -#include #include "gdk/gdkdisplayprivate.h" +#include "gdk/gdkvulkancontextprivate.h" G_BEGIN_DECLS -- GitLab From df09975753130f9590fc40a4b9aaa031f79fd5c6 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sun, 7 Jan 2024 10:00:04 +0100 Subject: [PATCH 04/19] renderer: Pass the display as part of the vfunc We allow realizing renderers without surfaces. But they still need a display, so pass it explicitly. --- gsk/broadway/gskbroadwayrenderer.c | 1 + gsk/gl/gskglrenderer.c | 12 ++------ gsk/gpu/gskgpurenderer.c | 7 +---- gsk/gskcairorenderer.c | 1 + gsk/gskrenderer.c | 48 +++++++++++++++++++++++++----- gsk/gskrendererprivate.h | 1 + 6 files changed, 47 insertions(+), 23 deletions(-) diff --git a/gsk/broadway/gskbroadwayrenderer.c b/gsk/broadway/gskbroadwayrenderer.c index c89f471b02e..cd960b8ddaa 100644 --- a/gsk/broadway/gskbroadwayrenderer.c +++ b/gsk/broadway/gskbroadwayrenderer.c @@ -35,6 +35,7 @@ G_DEFINE_TYPE (GskBroadwayRenderer, gsk_broadway_renderer, GSK_TYPE_RENDERER) static gboolean gsk_broadway_renderer_realize (GskRenderer *renderer, + GdkDisplay *display, GdkSurface *surface, GError **error) { diff --git a/gsk/gl/gskglrenderer.c b/gsk/gl/gskglrenderer.c index 0942e2767d4..51d7eb78304 100644 --- a/gsk/gl/gskglrenderer.c +++ b/gsk/gl/gskglrenderer.c @@ -162,6 +162,7 @@ gsk_gl_renderer_new (void) static gboolean gsk_gl_renderer_realize (GskRenderer *renderer, + GdkDisplay *display, GdkSurface *surface, GError **error) { @@ -169,7 +170,6 @@ gsk_gl_renderer_realize (GskRenderer *renderer, GskGLRenderer *self = (GskGLRenderer *)renderer; GdkGLContext *context = NULL; GskGLDriver *driver = NULL; - GdkDisplay *display; gboolean ret = FALSE; gboolean debug_shaders = FALSE; GdkGLAPI api; @@ -182,15 +182,9 @@ gsk_gl_renderer_realize (GskRenderer *renderer, g_assert (self->command_queue == NULL); if (surface == NULL) - { - display = gdk_display_get_default (); /* FIXME: allow different displays somehow ? */ - context = gdk_display_create_gl_context (display, error); - } + context = gdk_display_create_gl_context (display, error); else - { - display = gdk_surface_get_display (surface); - context = gdk_surface_create_gl_context (surface, error); - } + context = gdk_surface_create_gl_context (surface, error); if (!context || !gdk_gl_context_realize (context, error)) goto failure; diff --git a/gsk/gpu/gskgpurenderer.c b/gsk/gpu/gskgpurenderer.c index fb87d5359d5..00d50099e7e 100644 --- a/gsk/gpu/gskgpurenderer.c +++ b/gsk/gpu/gskgpurenderer.c @@ -188,18 +188,13 @@ gsk_gpu_renderer_get_frame (GskGpuRenderer *self) static gboolean gsk_gpu_renderer_realize (GskRenderer *renderer, + GdkDisplay *display, GdkSurface *surface, GError **error) { GskGpuRenderer *self = GSK_GPU_RENDERER (renderer); GskGpuRendererPrivate *priv = gsk_gpu_renderer_get_instance_private (self); GskGpuOptimizations context_optimizations; - GdkDisplay *display; - - if (surface) - display = gdk_surface_get_display (surface); - else - display = gdk_display_get_default (); priv->device = GSK_GPU_RENDERER_GET_CLASS (self)->get_device (display, error); if (priv->device == NULL) diff --git a/gsk/gskcairorenderer.c b/gsk/gskcairorenderer.c index 71725f4b2fb..7ba3434ecd9 100644 --- a/gsk/gskcairorenderer.c +++ b/gsk/gskcairorenderer.c @@ -50,6 +50,7 @@ G_DEFINE_TYPE (GskCairoRenderer, gsk_cairo_renderer, GSK_TYPE_RENDERER) static gboolean gsk_cairo_renderer_realize (GskRenderer *renderer, + GdkDisplay *display, GdkSurface *surface, GError **error) { diff --git a/gsk/gskrenderer.c b/gsk/gskrenderer.c index 7d9d8bdd76f..0e52c670000 100644 --- a/gsk/gskrenderer.c +++ b/gsk/gskrenderer.c @@ -102,6 +102,7 @@ static GParamSpec *gsk_renderer_properties[N_PROPS]; static gboolean gsk_renderer_real_realize (GskRenderer *self, + GdkDisplay *display, GdkSurface *surface, GError **error) { @@ -255,6 +256,32 @@ gsk_renderer_is_realized (GskRenderer *renderer) return priv->is_realized; } +static gboolean +gsk_renderer_do_realize (GskRenderer *renderer, + GdkDisplay *display, + GdkSurface *surface, + GError **error) +{ + GskRendererPrivate *priv = gsk_renderer_get_instance_private (renderer); + + if (surface) + priv->surface = g_object_ref (surface); + + if (!GSK_RENDERER_GET_CLASS (renderer)->realize (renderer, display, surface, error)) + { + g_clear_object (&priv->surface); + return FALSE; + } + + priv->is_realized = TRUE; + + g_object_notify (G_OBJECT (renderer), "realized"); + if (surface) + g_object_notify (G_OBJECT (renderer), "surface"); + + return TRUE; +} + /** * gsk_renderer_realize: * @renderer: a `GskRenderer` @@ -277,21 +304,26 @@ gsk_renderer_realize (GskRenderer *renderer, GdkSurface *surface, GError **error) { - GskRendererPrivate *priv = gsk_renderer_get_instance_private (renderer); - g_return_val_if_fail (GSK_IS_RENDERER (renderer), FALSE); g_return_val_if_fail (!gsk_renderer_is_realized (renderer), FALSE); g_return_val_if_fail (surface == NULL || GDK_IS_SURFACE (surface), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - if (surface) - priv->surface = g_object_ref (surface); - - if (!GSK_RENDERER_GET_CLASS (renderer)->realize (renderer, surface, error)) + if (surface == NULL) { - g_clear_object (&priv->surface); - return FALSE; + return gsk_renderer_do_realize (renderer, + gdk_display_get_default (), + NULL, + error); } + else + { + return gsk_renderer_do_realize (renderer, + gdk_surface_get_display (surface), + surface, + error); + } +} priv->is_realized = TRUE; diff --git a/gsk/gskrendererprivate.h b/gsk/gskrendererprivate.h index 2d020be493d..cf080498185 100644 --- a/gsk/gskrendererprivate.h +++ b/gsk/gskrendererprivate.h @@ -41,6 +41,7 @@ struct _GskRendererClass gboolean supports_offload; gboolean (* realize) (GskRenderer *renderer, + GdkDisplay *display, GdkSurface *surface, GError **error); void (* unrealize) (GskRenderer *renderer); -- GitLab From d0bf33339e8bf44262689ffde37a50e211e0fbe8 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sun, 7 Jan 2024 10:00:38 +0100 Subject: [PATCH 05/19] API: Add gsk_renderer_realize_for_display() This makes realizing a renderer without a surface explicit. And more importantly, it allows passing a different display than the default one. --- gsk/gskrenderer.c | 34 ++++++++++++++++++++++++++++------ gsk/gskrenderer.h | 4 ++++ 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/gsk/gskrenderer.c b/gsk/gskrenderer.c index 0e52c670000..156c448faff 100644 --- a/gsk/gskrenderer.c +++ b/gsk/gskrenderer.c @@ -293,6 +293,8 @@ gsk_renderer_do_realize (GskRenderer *renderer, * * Since GTK 4.6, the surface may be `NULL`, which allows using * renderers without having to create a surface. + * Since GTK 4.14, it is recommended to use [method@Gsk.Renderer.realize_for_display] + * instead. * * Note that it is mandatory to call [method@Gsk.Renderer.unrealize] before * destroying the renderer. @@ -325,13 +327,33 @@ gsk_renderer_realize (GskRenderer *renderer, } } - priv->is_realized = TRUE; - - g_object_notify (G_OBJECT (renderer), "realized"); - if (surface) - g_object_notify (G_OBJECT (renderer), "surface"); +/** + * gsk_renderer_realize_for_display: + * @renderer: a `GskRenderer` + * @display: the `GdkDisplay` renderer will be used on + * @error: return location for an error + * + * Creates the resources needed by the @renderer to render the scene + * graph. + * + * Note that it is mandatory to call [method@Gsk.Renderer.unrealize] before + * destroying the renderer. + * + * Returns: Whether the renderer was successfully realized + * + * Since: 4.14 + */ +gboolean +gsk_renderer_realize_for_display (GskRenderer *renderer, + GdkDisplay *display, + GError **error) +{ + g_return_val_if_fail (GSK_IS_RENDERER (renderer), FALSE); + g_return_val_if_fail (!gsk_renderer_is_realized (renderer), FALSE); + g_return_val_if_fail (display == NULL || GDK_IS_DISPLAY (display), FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - return TRUE; + return gsk_renderer_do_realize (renderer, display, NULL, error); } /** diff --git a/gsk/gskrenderer.h b/gsk/gskrenderer.h index af73141e2b0..97a828b5b7f 100644 --- a/gsk/gskrenderer.h +++ b/gsk/gskrenderer.h @@ -47,6 +47,10 @@ GDK_AVAILABLE_IN_ALL gboolean gsk_renderer_realize (GskRenderer *renderer, GdkSurface *surface, GError **error); +GDK_AVAILABLE_IN_4_14 +gboolean gsk_renderer_realize_for_display (GskRenderer *renderer, + GdkDisplay *display, + GError **error); GDK_AVAILABLE_IN_ALL void gsk_renderer_unrealize (GskRenderer *renderer); GDK_AVAILABLE_IN_ALL -- GitLab From b48658888347a9a39bf09cef3152cd1b92b3ccf8 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sun, 7 Jan 2024 10:03:44 +0100 Subject: [PATCH 06/19] dmabuf: Use gsk_renderer_realize_for_display() We want to use the correct display when realizing our dmabuf downloaders. It's a good thing that the inspector doesn't use dmabufs, isn't it? --- gdk/gdkdmabufegl.c | 10 +++++----- gdk/gdkvulkancontext.c | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/gdk/gdkdmabufegl.c b/gdk/gdkdmabufegl.c index 54a6a6b897e..1282d314dd2 100644 --- a/gdk/gdkdmabufegl.c +++ b/gdk/gdkdmabufegl.c @@ -140,10 +140,10 @@ gdk_dmabuf_egl_downloader_collect_formats (GdkDisplay *display, typedef struct _GskRenderer GskRenderer; -extern GskRenderer * gsk_gl_renderer_new (void); -extern gboolean gsk_renderer_realize (GskRenderer *renderer, - GdkSurface *surface, - GError **error); +extern GskRenderer * gsk_gl_renderer_new (void); +extern gboolean gsk_renderer_realize_for_display (GskRenderer *renderer, + GdkDisplay *display, + GError **error); GdkDmabufDownloader * gdk_dmabuf_get_egl_downloader (GdkDisplay *display, @@ -176,7 +176,7 @@ gdk_dmabuf_get_egl_downloader (GdkDisplay *display, renderer = gsk_gl_renderer_new (); - if (!gsk_renderer_realize (renderer, NULL, &error)) + if (!gsk_renderer_realize_for_display (renderer, display, &error)) { g_warning ("Failed to realize GL renderer: %s", error->message); g_error_free (error); diff --git a/gdk/gdkvulkancontext.c b/gdk/gdkvulkancontext.c index 01e47005cab..fc596466f3e 100644 --- a/gdk/gdkvulkancontext.c +++ b/gdk/gdkvulkancontext.c @@ -1833,10 +1833,10 @@ gdk_display_unref_vulkan (GdkDisplay *display) typedef struct _GskRenderer GskRenderer; -extern GskRenderer * gsk_vulkan_renderer_new (void); -extern gboolean gsk_renderer_realize (GskRenderer *renderer, - GdkSurface *surface, - GError **error); +extern GskRenderer * gsk_vulkan_renderer_new (void); +extern gboolean gsk_renderer_realize_for_display (GskRenderer *renderer, + GdkDisplay *display, + GError **error); GdkDmabufDownloader * gdk_vulkan_get_dmabuf_downloader (GdkDisplay *display, @@ -1903,7 +1903,7 @@ gdk_vulkan_get_dmabuf_downloader (GdkDisplay *display, renderer = gsk_vulkan_renderer_new (); - if (!gsk_renderer_realize (renderer, NULL, &error)) + if (!gsk_renderer_realize_for_display (renderer, display, &error)) { g_warning ("Failed to realize GL renderer: %s", error->message); g_error_free (error); -- GitLab From e2c8b7fa6c3f13439b1bbc990c763e8778db3bec Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sun, 7 Jan 2024 10:07:48 +0100 Subject: [PATCH 07/19] testsuite: Use gsk_renderer_realize_for_display() ... in all the places where we used realize (NULL) before. --- testsuite/gdk/memorytexture.c | 11 +++++++---- testsuite/gdk/texture-threads.c | 2 +- testsuite/gsk/scaling.c | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/testsuite/gdk/memorytexture.c b/testsuite/gdk/memorytexture.c index afbd243995e..738a0da57d4 100644 --- a/testsuite/gdk/memorytexture.c +++ b/testsuite/gdk/memorytexture.c @@ -1453,6 +1453,7 @@ add_conversion_test (const char *name, int main (int argc, char *argv[]) { + GdkDisplay *display; int result; gtk_test_init (&argc, &argv, NULL); @@ -1462,26 +1463,28 @@ main (int argc, char *argv[]) add_conversion_test ("/memorytexture/conversion_1x1", test_conversion_1x1); add_conversion_test ("/memorytexture/conversion_random", test_conversion_random); - gl_context = gdk_display_create_gl_context (gdk_display_get_default (), NULL); + display = gdk_display_get_default (); + + gl_context = gdk_display_create_gl_context (display, NULL); if (gl_context == NULL || !gdk_gl_context_realize (gl_context, NULL)) { g_clear_object (&gl_context); } gl_renderer = gsk_gl_renderer_new (); - if (!gsk_renderer_realize (gl_renderer, NULL, NULL)) + if (!gsk_renderer_realize_for_display (gl_renderer, display, NULL)) { g_clear_object (&gl_renderer); } ngl_renderer = gsk_ngl_renderer_new (); - if (!gsk_renderer_realize (ngl_renderer, NULL, NULL)) + if (!gsk_renderer_realize_for_display (ngl_renderer, display, NULL)) { g_clear_object (&ngl_renderer); } vulkan_renderer = gsk_vulkan_renderer_new (); - if (!gsk_renderer_realize (vulkan_renderer, NULL, NULL)) + if (!gsk_renderer_realize_for_display (vulkan_renderer, display, NULL)) { g_clear_object (&vulkan_renderer); } diff --git a/testsuite/gdk/texture-threads.c b/testsuite/gdk/texture-threads.c index 529e2351e6f..40ef8eaba86 100644 --- a/testsuite/gdk/texture-threads.c +++ b/testsuite/gdk/texture-threads.c @@ -67,7 +67,7 @@ texture_threads (void) /* 1. Get a GL renderer */ gl_renderer = gsk_gl_renderer_new (); - if (!gsk_renderer_realize (gl_renderer, NULL, &error)) + if (!gsk_renderer_realize_for_display (gl_renderer, gdk_display_get_default (), &error)) { g_test_skip (error->message); diff --git a/testsuite/gsk/scaling.c b/testsuite/gsk/scaling.c index b73b4138405..698a5e7f56d 100644 --- a/testsuite/gsk/scaling.c +++ b/testsuite/gsk/scaling.c @@ -1046,7 +1046,7 @@ create_renderers (void) for (i = 0; i < G_N_ELEMENTS (renderers); i++) { renderers[i].renderer = renderers[i].create_func (); - if (!gsk_renderer_realize (renderers[i].renderer, NULL, &error)) + if (!gsk_renderer_realize_for_display (renderers[i].renderer, gdk_display_get_default (), &error)) { g_test_message ("Could not realize %s renderer: %s", renderers[i].name, error->message); g_clear_error (&error); -- GitLab From f57e211ba94647d04800c6fbe0364752d651a4c2 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sun, 7 Jan 2024 10:13:17 +0100 Subject: [PATCH 08/19] node-editor: Use gsk_renderer_realize_for_display() ... in all the places where we used realize (NULL) before. --- demos/node-editor/node-editor-window.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/demos/node-editor/node-editor-window.c b/demos/node-editor/node-editor-window.c index a7d6a9064ff..defed870e46 100644 --- a/demos/node-editor/node-editor-window.c +++ b/demos/node-editor/node-editor-window.c @@ -791,7 +791,7 @@ create_cairo_texture (NodeEditorWindow *self) return NULL; renderer = gsk_cairo_renderer_new (); - gsk_renderer_realize (renderer, NULL, NULL); + gsk_renderer_realize_for_display (renderer, gtk_widget_get_display (GTK_WIDGET (self)), NULL); texture = gsk_renderer_render_texture (renderer, node, NULL); gsk_render_node_unref (node); @@ -863,11 +863,11 @@ export_image_response_cb (GObject *source, GskRenderer *renderer; renderer = gsk_gl_renderer_new (); - if (!gsk_renderer_realize (renderer, NULL, NULL)) + if (!gsk_renderer_realize_for_display (renderer, gdk_display_get_default (), NULL)) { g_object_unref (renderer); renderer = gsk_cairo_renderer_new (); - if (!gsk_renderer_realize (renderer, NULL, NULL)) + if (!gsk_renderer_realize_for_display (renderer, gdk_display_get_default (), NULL)) { g_assert_not_reached (); } @@ -1118,8 +1118,11 @@ node_editor_window_add_renderer (NodeEditorWindow *self, const char *description) { GdkPaintable *paintable; + GdkDisplay *display; - if (!gsk_renderer_realize (renderer, NULL, NULL)) + display = gtk_widget_get_display (GTK_WIDGET (self)); + + if (!gsk_renderer_realize_for_display (renderer, display, NULL)) { GdkSurface *surface = gtk_native_get_surface (GTK_NATIVE (self)); g_assert (surface != NULL); -- GitLab From cf86a01b654bd447ba2acd9c1072c32ac2978c17 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sun, 7 Jan 2024 12:35:38 +0100 Subject: [PATCH 09/19] gsk: Include GL renderer in gsk.h Same as the Vulkan renderer --- gsk/gsk.h | 1 + 1 file changed, 1 insertion(+) diff --git a/gsk/gsk.h b/gsk/gsk.h index 11155ff150a..d118ef3c0a6 100644 --- a/gsk/gsk.h +++ b/gsk/gsk.h @@ -32,6 +32,7 @@ #include #include +#include #include #include -- GitLab From ee14b96c2883a29365d42630bd1e2933a752cf83 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sun, 7 Jan 2024 13:22:49 +0100 Subject: [PATCH 10/19] node-editor: Don't #include --- demos/node-editor/node-editor-window.c | 1 - 1 file changed, 1 deletion(-) diff --git a/demos/node-editor/node-editor-window.c b/demos/node-editor/node-editor-window.c index defed870e46..934379c03e3 100644 --- a/demos/node-editor/node-editor-window.c +++ b/demos/node-editor/node-editor-window.c @@ -24,7 +24,6 @@ #include "gtkrendererpaintableprivate.h" #include "gsk/gskrendernodeparserprivate.h" -#include "gsk/gl/gskglrenderer.h" #ifdef GDK_WINDOWING_BROADWAY #include "gsk/broadway/gskbroadwayrenderer.h" #endif -- GitLab From 0ba8903fa5dcf4bc774f9bd029de0ddd9c3e001c Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sun, 7 Jan 2024 13:23:22 +0100 Subject: [PATCH 11/19] testsuite: Don't #include --- testsuite/gdk/memorytexture.c | 2 -- testsuite/gdk/texture-threads.c | 2 -- testsuite/gsk/misc.c | 4 ---- testsuite/gsk/scaling.c | 4 ---- 4 files changed, 12 deletions(-) diff --git a/testsuite/gdk/memorytexture.c b/testsuite/gdk/memorytexture.c index 738a0da57d4..57cd48ab562 100644 --- a/testsuite/gdk/memorytexture.c +++ b/testsuite/gdk/memorytexture.c @@ -1,7 +1,5 @@ #include -#include "gsk/gl/gskglrenderer.h" - #include #define N 10 diff --git a/testsuite/gdk/texture-threads.c b/testsuite/gdk/texture-threads.c index 40ef8eaba86..b5a49930516 100644 --- a/testsuite/gdk/texture-threads.c +++ b/testsuite/gdk/texture-threads.c @@ -1,7 +1,5 @@ #include -#include "gsk/gl/gskglrenderer.h" - /* This function will be called from a thread and/or the main loop. * Textures are threadsafe after all. */ static void diff --git a/testsuite/gsk/misc.c b/testsuite/gsk/misc.c index b2d72d77b7c..e392c758a44 100644 --- a/testsuite/gsk/misc.c +++ b/testsuite/gsk/misc.c @@ -1,10 +1,6 @@ #include #include "gsk/gskrendernodeprivate.h" -#ifdef GDK_RENDERING_GL -#include -#endif - #include static void diff --git a/testsuite/gsk/scaling.c b/testsuite/gsk/scaling.c index 698a5e7f56d..e247ee9c94f 100644 --- a/testsuite/gsk/scaling.c +++ b/testsuite/gsk/scaling.c @@ -1,9 +1,5 @@ #include -#include "gsk/gl/gskglrenderer.h" - -#include - #define N 10 struct { -- GitLab From 637f6cc81bf8bdef1680f38f1435335876dd38d2 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sun, 7 Jan 2024 13:25:27 +0100 Subject: [PATCH 12/19] gtk: Don't #include --- gtk/gtktestutils.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/gtk/gtktestutils.c b/gtk/gtktestutils.c index 05232d57630..ae5043682e7 100644 --- a/gtk/gtktestutils.c +++ b/gtk/gtktestutils.c @@ -27,8 +27,6 @@ #include "gtktextview.h" #include "gtkrange.h" -#include - #include #include #include -- GitLab From 3bb1c2298fab78dece7dd7cd7113acb46170e7e5 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sun, 7 Jan 2024 13:21:15 +0100 Subject: [PATCH 13/19] gsk: Emit deprecation warning for #include This is a bit hacky, but it seems to work. Note: It doesn't work inside GTK because GTK_COMPILATION during the whole build. --- gsk/gl/gskglrenderer.h | 14 ++++++++++---- gsk/gl/gskglrendererprivate.h | 2 ++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/gsk/gl/gskglrenderer.h b/gsk/gl/gskglrenderer.h index acad1c91cdf..6d0095fe73e 100644 --- a/gsk/gl/gskglrenderer.h +++ b/gsk/gl/gskglrenderer.h @@ -20,7 +20,13 @@ #pragma once +#if !defined (__GSK_H_INSIDE__) && !defined (GTK_COMPILATION) #include +#define GSK_INCLUDE_WARNING(x) GDK_DEPRECATED_IN_4_14_FOR("#include instead of to avoid this warning") +#else +#include +#define GSK_INCLUDE_WARNING(x) x +#endif G_BEGIN_DECLS @@ -35,14 +41,14 @@ G_BEGIN_DECLS typedef struct _GskGLRenderer GskGLRenderer; typedef struct _GskGLRendererClass GskGLRendererClass; -GDK_AVAILABLE_IN_4_2 +GSK_INCLUDE_WARNING(GDK_AVAILABLE_IN_4_2) GType gsk_gl_renderer_get_type (void) G_GNUC_CONST; -GDK_AVAILABLE_IN_4_2 +GSK_INCLUDE_WARNING(GDK_AVAILABLE_IN_4_2) GskRenderer *gsk_gl_renderer_new (void); -GDK_AVAILABLE_IN_ALL +GSK_INCLUDE_WARNING(GDK_AVAILABLE_IN_ALL) GType gsk_ngl_renderer_get_type (void) G_GNUC_CONST; -GDK_AVAILABLE_IN_ALL +GSK_INCLUDE_WARNING(GDK_AVAILABLE_IN_ALL) GskRenderer *gsk_ngl_renderer_new (void); G_END_DECLS diff --git a/gsk/gl/gskglrendererprivate.h b/gsk/gl/gskglrendererprivate.h index 59a7222e71f..3902a7cd995 100644 --- a/gsk/gl/gskglrendererprivate.h +++ b/gsk/gl/gskglrendererprivate.h @@ -22,6 +22,8 @@ #include "gskglrenderer.h" +#include "gskglshader.h" + G_BEGIN_DECLS gboolean gsk_gl_renderer_try_compile_gl_shader (GskGLRenderer *renderer, -- GitLab From 6bac377fa5bf49aaa092f7fdc7dc54a1d1649c9a Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sun, 7 Jan 2024 13:50:02 +0100 Subject: [PATCH 14/19] gdk: Don't include vulkan.h in public API anymore --- gdk/gdkvulkancontext.h | 4 ---- gsk/gpu/gskvulkanmemoryprivate.h | 2 ++ tests/testdmabuf.c | 3 +++ 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/gdk/gdkvulkancontext.h b/gdk/gdkvulkancontext.h index 3bc9f50961a..bbcb9d8abfa 100644 --- a/gdk/gdkvulkancontext.h +++ b/gdk/gdkvulkancontext.h @@ -26,10 +26,6 @@ #include -#ifdef GDK_RENDERING_VULKAN -#include -#endif - G_BEGIN_DECLS #define GDK_TYPE_VULKAN_CONTEXT (gdk_vulkan_context_get_type ()) diff --git a/gsk/gpu/gskvulkanmemoryprivate.h b/gsk/gpu/gskvulkanmemoryprivate.h index 6dcb30c05aa..5fa7f615de4 100644 --- a/gsk/gpu/gskvulkanmemoryprivate.h +++ b/gsk/gpu/gskvulkanmemoryprivate.h @@ -2,6 +2,8 @@ #include +#include + G_BEGIN_DECLS #define GSK_VULKAN_MEMORY_MAPPABLE (VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | \ diff --git a/tests/testdmabuf.c b/tests/testdmabuf.c index 6ca82bd47f7..c6a2e263d85 100644 --- a/tests/testdmabuf.c +++ b/tests/testdmabuf.c @@ -6,6 +6,9 @@ #include #include +#ifdef GDK_RENDERING_VULKAN +#include +#endif /* For this to work, you may need to give /dev/dma_heap/system * lax permissions. */ -- GitLab From 3ac50b81f241b980ff7de073e4695797c92d1e5a Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sun, 7 Jan 2024 13:54:49 +0100 Subject: [PATCH 15/19] vulkan: Make gdk_display_create_vulkan_context() take a surface This is so we can deprecate gdk_surface_create_vulkan_context() which is public API in the next commit. --- gdk/gdkdisplay.c | 29 ++++++++++++++++++++++------- gdk/gdkdisplayprivate.h | 1 + gsk/gpu/gskvulkanrenderer.c | 6 +----- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/gdk/gdkdisplay.c b/gdk/gdkdisplay.c index 00182bfba29..9f51bce2229 100644 --- a/gdk/gdkdisplay.c +++ b/gdk/gdkdisplay.c @@ -1267,12 +1267,14 @@ gdk_display_get_keymap (GdkDisplay *display) /* * gdk_display_create_vulkan_context: * @self: a `GdkDisplay` + * @surface: (nullable): the `GdkSurface` to use or %NULL for a surfaceless + * context * @error: return location for an error * * Creates a new `GdkVulkanContext` for use with @display. * - * The context can not be used to draw to surfaces, it can only be - * used for custom rendering or compute. + * If @surface is NULL, the context can not be used to draw to surfaces, + * it can only be used for custom rendering or compute. * * If the creation of the `GdkVulkanContext` failed, @error will be set. * @@ -1281,9 +1283,11 @@ gdk_display_get_keymap (GdkDisplay *display) */ GdkVulkanContext * gdk_display_create_vulkan_context (GdkDisplay *self, + GdkSurface *surface, GError **error) { g_return_val_if_fail (GDK_IS_DISPLAY (self), NULL); + g_return_val_if_fail (surface == NULL || GDK_IS_SURFACE (surface), NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); if (gdk_display_get_debug_flags (self) & GDK_DEBUG_VULKAN_DISABLE) @@ -1300,11 +1304,22 @@ gdk_display_create_vulkan_context (GdkDisplay *self, return FALSE; } - return g_initable_new (GDK_DISPLAY_GET_CLASS (self)->vk_context_type, - NULL, - error, - "display", self, - NULL); + if (surface) + { + return g_initable_new (GDK_DISPLAY_GET_CLASS (self)->vk_context_type, + NULL, + error, + "surface", surface, + NULL); + } + else + { + return g_initable_new (GDK_DISPLAY_GET_CLASS (self)->vk_context_type, + NULL, + error, + "display", self, + NULL); + } } gboolean diff --git a/gdk/gdkdisplayprivate.h b/gdk/gdkdisplayprivate.h index a655ed33b3d..0c2f9355f7b 100644 --- a/gdk/gdkdisplayprivate.h +++ b/gdk/gdkdisplayprivate.h @@ -236,6 +236,7 @@ void gdk_display_init_dmabuf (GdkDisplay *self); gboolean gdk_display_has_vulkan_feature (GdkDisplay *self, GdkVulkanFeatures feature); GdkVulkanContext * gdk_display_create_vulkan_context (GdkDisplay *self, + GdkSurface *surface, GError **error); GdkGLContext * gdk_display_get_gl_context (GdkDisplay *display); diff --git a/gsk/gpu/gskvulkanrenderer.c b/gsk/gpu/gskvulkanrenderer.c index eee7ec26b5b..997a6d94480 100644 --- a/gsk/gpu/gskvulkanrenderer.c +++ b/gsk/gpu/gskvulkanrenderer.c @@ -89,11 +89,7 @@ gsk_vulkan_renderer_create_context (GskGpuRenderer *renderer, GskVulkanRenderer *self = GSK_VULKAN_RENDERER (renderer); GdkVulkanContext *context; - if (surface) - context = gdk_surface_create_vulkan_context (surface, error); - else - context = gdk_display_create_vulkan_context (display, error); - + context = gdk_display_create_vulkan_context (display, surface, error); if (context == NULL) return NULL; -- GitLab From 543c7ae52ae3c08def91d199e5fdc3b3287944fa Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sun, 7 Jan 2024 14:06:00 +0100 Subject: [PATCH 16/19] vulkan: Disable gdk_surface_create_vulkan_context() ... and deprecate it. It will now always return NULL and error out. We do not want to expose any Vulkan internals in the public API. --- gdk/gdksurface.c | 37 +++++++------------------------------ gdk/gdksurface.h | 2 +- 2 files changed, 8 insertions(+), 31 deletions(-) diff --git a/gdk/gdksurface.c b/gdk/gdksurface.c index 94675e9064f..d35516b4b40 100644 --- a/gdk/gdksurface.c +++ b/gdk/gdksurface.c @@ -1246,43 +1246,20 @@ gdk_surface_create_cairo_context (GdkSurface *surface) * @surface: a `GdkSurface` * @error: return location for an error * - * Creates a new `GdkVulkanContext` for rendering on @surface. + * Sets an error and returns %NULL. * - * If the creation of the `GdkVulkanContext` failed, @error will be set. + * Returns: (transfer full): %NULL * - * Returns: (transfer full): the newly created `GdkVulkanContext`, or - * %NULL on error + * Deprecated: 4.14: GTK does not expose any Vulkan internals. This + * function is a leftover that was accidentally exposed. */ GdkVulkanContext * gdk_surface_create_vulkan_context (GdkSurface *surface, GError **error) { - GdkDisplay *display; - - g_return_val_if_fail (GDK_IS_SURFACE (surface), NULL); - g_return_val_if_fail (error == NULL || *error == NULL, NULL); - - if (gdk_display_get_debug_flags (surface->display) & GDK_DEBUG_VULKAN_DISABLE) - { - g_set_error_literal (error, GDK_VULKAN_ERROR, GDK_VULKAN_ERROR_NOT_AVAILABLE, - _("Vulkan support disabled via GDK_DEBUG")); - return NULL; - } - - display = surface->display; - - if (GDK_DISPLAY_GET_CLASS (display)->vk_extension_name == NULL) - { - g_set_error (error, GDK_VULKAN_ERROR, GDK_VULKAN_ERROR_UNSUPPORTED, - "The %s backend has no Vulkan support.", G_OBJECT_TYPE_NAME (display)); - return FALSE; - } - - return g_initable_new (GDK_DISPLAY_GET_CLASS (display)->vk_context_type, - NULL, - error, - "surface", surface, - NULL); + g_set_error (error, GDK_VULKAN_ERROR, GDK_VULKAN_ERROR_UNSUPPORTED, + "GTK does not expose Vulkan internals."); + return FALSE; } static gboolean diff --git a/gdk/gdksurface.h b/gdk/gdksurface.h index 50c1efe779e..5c8025c38f9 100644 --- a/gdk/gdksurface.h +++ b/gdk/gdksurface.h @@ -134,7 +134,7 @@ GdkCairoContext *gdk_surface_create_cairo_context(GdkSurface *surface); GDK_AVAILABLE_IN_ALL GdkGLContext * gdk_surface_create_gl_context (GdkSurface *surface, GError **error); -GDK_AVAILABLE_IN_ALL +GDK_DEPRECATED_IN_4_14 GdkVulkanContext * gdk_surface_create_vulkan_context(GdkSurface *surface, GError **error); -- GitLab From ed12c0cd5ab7682af88665ad8b8ee811b265d19f Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sun, 7 Jan 2024 14:34:04 +0100 Subject: [PATCH 17/19] build: Enable Vulkan by default It's still possible to disable via -Dvulkan=disabled We force-disable it on Mac OS. I don't know how to best handle it on Windows. Technically we don't need it, because the Vulkan stuff we want is about dmabufs, but I have no idea how to convince the build system to toggle the default to "disabled" on Windows, so it has to stay enabled for now. --- .gitlab-ci/test-msvc.bat | 2 +- meson.build | 6 ++++-- meson_options.txt | 4 ++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.gitlab-ci/test-msvc.bat b/.gitlab-ci/test-msvc.bat index 89255b25b90..ff6b0853665 100644 --- a/.gitlab-ci/test-msvc.bat +++ b/.gitlab-ci/test-msvc.bat @@ -6,7 +6,7 @@ call "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliar :: FIXME: make warnings fatal pip3 install --upgrade --user meson~=0.64 || goto :error -meson setup -Dbackend_max_links=1 -Ddebug=false -Dmedia-gstreamer=disabled _build || goto :error +meson setup -Dbackend_max_links=1 -Ddebug=false -Dmedia-gstreamer=disabled -Dvulkan=disabled _build || goto :error ninja -C _build || goto :error goto :EOF diff --git a/meson.build b/meson.build index 1ea481dd5c2..a9663e501ca 100644 --- a/meson.build +++ b/meson.build @@ -101,6 +101,7 @@ wayland_enabled = get_option('wayland-backend') broadway_enabled = get_option('broadway-backend') macos_enabled = get_option('macos-backend') win32_enabled = get_option('win32-backend') +vulkan_enabled = get_option('vulkan') os_unix = false os_linux = false @@ -122,6 +123,7 @@ os_unix = not os_win32 if os_darwin wayland_enabled = false + vulkan_enabled = false else macos_enabled = false endif @@ -616,8 +618,8 @@ endif # be reported upstream and fixed. vulkan_dep = dependency('vulkan', version: vulkan_req, - required: get_option('vulkan')) -glslc = find_program('glslc', required: get_option('vulkan')) + required: vulkan_enabled) +glslc = find_program('glslc', required: vulkan_enabled) if vulkan_dep.found() have_vulkan = true vulkan_pkg_found = vulkan_dep.type_name() == 'pkgconfig' diff --git a/meson_options.txt b/meson_options.txt index 4b794e78141..3b2cb8ad37b 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -55,8 +55,8 @@ option('print-cups', option('vulkan', type: 'feature', - value: 'disabled', - description : 'Enable support for the experimental Vulkan renderer') + value: 'enabled', + description : 'Enable Vulkan support including the Vulkan renderer') option('cloudproviders', type: 'feature', -- GitLab From 440c207146109b861773123f64aea4f47ee52557 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sun, 7 Jan 2024 14:35:43 +0100 Subject: [PATCH 18/19] build: Enable Vulkan on msys CI --- .gitlab-ci/test-msys2.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci/test-msys2.sh b/.gitlab-ci/test-msys2.sh index 04894a75b8f..00f2c877f22 100644 --- a/.gitlab-ci/test-msys2.sh +++ b/.gitlab-ci/test-msys2.sh @@ -33,7 +33,8 @@ pacman --noconfirm -S --needed \ mingw-w64-$MSYS2_ARCH-gst-plugins-bad-libs \ mingw-w64-$MSYS2_ARCH-shared-mime-info \ mingw-w64-$MSYS2_ARCH-python-gobject \ - mingw-w64-$MSYS2_ARCH-shaderc + mingw-w64-$MSYS2_ARCH-shaderc \ + mingw-w64-$MSYS2_ARCH-vulkan mkdir -p _ccache export CCACHE_BASEDIR="$(pwd)" @@ -47,7 +48,6 @@ meson \ -Dx11-backend=false \ -Dwayland-backend=false \ -Dwin32-backend=true \ - -Dvulkan=disabled \ -Dintrospection=enabled \ -Dgtk:werror=true \ _build -- GitLab From 7830535c042c5626f251cdfec07cb9f1c56545be Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sun, 7 Jan 2024 14:56:01 +0100 Subject: [PATCH 19/19] vulkan: Guard dmabuf code with HAVE_DMABUF --- gdk/gdkvulkancontext.c | 4 ++++ gdk/gdkvulkancontextprivate.h | 2 ++ gsk/gpu/gskgpudownloadop.c | 3 +++ 3 files changed, 9 insertions(+) diff --git a/gdk/gdkvulkancontext.c b/gdk/gdkvulkancontext.c index fc596466f3e..cb50d42507c 100644 --- a/gdk/gdkvulkancontext.c +++ b/gdk/gdkvulkancontext.c @@ -1826,6 +1826,8 @@ gdk_display_unref_vulkan (GdkDisplay *display) display->vk_instance = VK_NULL_HANDLE; } +#ifdef HAVE_DMABUF + /* Hack. We don't include gsk/gsk.h here to avoid a build order problem * with the generated header gskenumtypes.h, so we need to hack around * a bit to access the gsk api we need. @@ -1915,6 +1917,8 @@ gdk_vulkan_get_dmabuf_downloader (GdkDisplay *display, return GDK_DMABUF_DOWNLOADER (renderer); } +#endif + VkShaderModule gdk_display_get_vk_shader_module (GdkDisplay *self, const char *resource_name) diff --git a/gdk/gdkvulkancontextprivate.h b/gdk/gdkvulkancontextprivate.h index a68a821321b..181ddf7f011 100644 --- a/gdk/gdkvulkancontextprivate.h +++ b/gdk/gdkvulkancontextprivate.h @@ -78,8 +78,10 @@ gboolean gdk_display_init_vulkan (GdkDisp void gdk_display_ref_vulkan (GdkDisplay *display); void gdk_display_unref_vulkan (GdkDisplay *display); +#ifdef HAVE_DMABUF GdkDmabufDownloader * gdk_vulkan_get_dmabuf_downloader (GdkDisplay *display, GdkDmabufFormatsBuilder *builder); +#endif VkShaderModule gdk_display_get_vk_shader_module (GdkDisplay *display, const char *resource_name); diff --git a/gsk/gpu/gskgpudownloadop.c b/gsk/gpu/gskgpudownloadop.c index c1c5517de9d..a9c3ec61484 100644 --- a/gsk/gpu/gskgpudownloadop.c +++ b/gsk/gpu/gskgpudownloadop.c @@ -69,6 +69,8 @@ gsk_gpu_download_op_print (GskGpuOp *op, } #ifdef GDK_RENDERING_VULKAN + +#ifdef HAVE_DMABUF /* The code needs to run here because vkGetSemaphoreFdKHR() may * only be called after the semaphore has been submitted via * vkQueueSubmit(). @@ -102,6 +104,7 @@ gsk_gpu_download_op_vk_sync_semaphore (GskGpuDownloadOp *self) vkDestroySemaphore (display->vk_device, self->vk_semaphore, NULL); } +#endif static void gsk_gpu_download_op_vk_create (GskGpuDownloadOp *self) -- GitLab