Merge branch 'vulkan-prepare' into 'main'
Drop vulkan refcounting See merge request GNOME/gtk!7916
This commit is contained in:
@@ -438,11 +438,10 @@ gdk_display_dispose (GObject *object)
|
||||
g_clear_pointer (&display->egl_dmabuf_formats, gdk_dmabuf_formats_unref);
|
||||
g_clear_pointer (&display->egl_internal_formats, gdk_dmabuf_formats_unref);
|
||||
#ifdef GDK_RENDERING_VULKAN
|
||||
if (display->vk_dmabuf_formats)
|
||||
{
|
||||
gdk_display_unref_vulkan (display);
|
||||
g_assert (display->vk_dmabuf_formats == NULL);
|
||||
}
|
||||
if (display->vk_instance)
|
||||
gdk_display_destroy_vulkan_instance (display);
|
||||
g_assert (display->vk_dmabuf_formats == NULL);
|
||||
g_clear_error (&display->vulkan_error);
|
||||
#endif
|
||||
|
||||
g_clear_object (&priv->gl_context);
|
||||
@@ -1286,6 +1285,53 @@ gdk_display_get_keymap (GdkDisplay *display)
|
||||
return GDK_DISPLAY_GET_CLASS (display)->get_keymap (display);
|
||||
}
|
||||
|
||||
/*< private >
|
||||
* gdk_display_prepare_vulkan:
|
||||
* @self: a `GdkDisplay`
|
||||
* @error: return location for a `GError`
|
||||
*
|
||||
* Checks that Vulkan is available for @self and ensures that it is
|
||||
* properly initialized.
|
||||
*
|
||||
* When this fails, an @error will be set describing the error and this
|
||||
* function returns %FALSE.
|
||||
*
|
||||
* Note that even if this function succeeds, creating a `GdkVulkanContext`
|
||||
* may still fail.
|
||||
*
|
||||
* This function is idempotent. Calling it multiple times will just
|
||||
* return the same value or error.
|
||||
*
|
||||
* You never need to call this function, GDK will call it automatically
|
||||
* as needed.
|
||||
*
|
||||
* Returns: %TRUE if the display supports Vulkan
|
||||
*/
|
||||
gboolean
|
||||
gdk_display_prepare_vulkan (GdkDisplay *self,
|
||||
GError **error)
|
||||
{
|
||||
g_return_val_if_fail (GDK_IS_DISPLAY (self), FALSE);
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
|
||||
#ifdef GDK_RENDERING_VULKAN
|
||||
if (!self->vk_instance && !self->vulkan_error)
|
||||
gdk_display_create_vulkan_instance (self, &self->vulkan_error);
|
||||
|
||||
if (self->vk_instance == NULL)
|
||||
{
|
||||
if (error)
|
||||
*error = g_error_copy (self->vulkan_error);
|
||||
}
|
||||
|
||||
return self->vk_instance != NULL;
|
||||
#else
|
||||
g_set_error (error, GDK_VULKAN_ERROR, GDK_VULKAN_ERROR_UNSUPPORTED,
|
||||
"GTK was built without Vulkan support");
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*<private>
|
||||
* gdk_display_create_vulkan_context:
|
||||
* @self: a `GdkDisplay`
|
||||
|
@@ -126,7 +126,7 @@ struct _GdkDisplay
|
||||
GdkDmabufFormats *vk_dmabuf_formats;
|
||||
GdkVulkanFeatures vulkan_features;
|
||||
|
||||
guint vulkan_refcount;
|
||||
GError *vulkan_error;
|
||||
#endif /* GDK_RENDERING_VULKAN */
|
||||
|
||||
/* egl info */
|
||||
@@ -239,6 +239,8 @@ void _gdk_display_unpause_events (GdkDisplay *display
|
||||
|
||||
void gdk_display_init_dmabuf (GdkDisplay *self);
|
||||
|
||||
gboolean gdk_display_prepare_vulkan (GdkDisplay *self,
|
||||
GError **error);
|
||||
gboolean gdk_display_has_vulkan_feature (GdkDisplay *self,
|
||||
GdkVulkanFeatures feature);
|
||||
GdkVulkanContext * gdk_display_create_vulkan_context (GdkDisplay *self,
|
||||
|
@@ -367,7 +367,6 @@ gdk_vulkan_context_dispose (GObject *gobject)
|
||||
{
|
||||
GdkVulkanContext *context = GDK_VULKAN_CONTEXT (gobject);
|
||||
GdkVulkanContextPrivate *priv = gdk_vulkan_context_get_instance_private (context);
|
||||
GdkDisplay *display;
|
||||
VkDevice device;
|
||||
guint i;
|
||||
|
||||
@@ -397,11 +396,6 @@ gdk_vulkan_context_dispose (GObject *gobject)
|
||||
priv->surface = VK_NULL_HANDLE;
|
||||
}
|
||||
|
||||
/* display will be unset in gdk_draw_context_dispose() */
|
||||
display = gdk_draw_context_get_display (GDK_DRAW_CONTEXT (context));
|
||||
if (display && priv->vulkan_ref)
|
||||
gdk_display_unref_vulkan (display);
|
||||
|
||||
G_OBJECT_CLASS (gdk_vulkan_context_parent_class)->dispose (gobject);
|
||||
}
|
||||
|
||||
@@ -887,8 +881,7 @@ gdk_vulkan_context_real_init (GInitable *initable,
|
||||
VkBool32 supported;
|
||||
uint32_t i;
|
||||
|
||||
priv->vulkan_ref = gdk_display_init_vulkan (display, error);
|
||||
if (!priv->vulkan_ref)
|
||||
if (!gdk_display_prepare_vulkan (display, error))
|
||||
return FALSE;
|
||||
|
||||
if (surface == NULL)
|
||||
@@ -1668,7 +1661,7 @@ gdk_vulkan_debug_report (VkDebugReportFlagsEXT flags,
|
||||
return VK_FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gboolean
|
||||
gdk_display_create_vulkan_instance (GdkDisplay *display,
|
||||
GError **error)
|
||||
{
|
||||
@@ -1678,6 +1671,8 @@ gdk_display_create_vulkan_instance (GdkDisplay *display,
|
||||
gboolean have_debug_report = FALSE;
|
||||
VkResult res;
|
||||
|
||||
g_assert (display->vk_instance == NULL);
|
||||
|
||||
if (!gdk_has_feature (GDK_FEATURE_VULKAN))
|
||||
{
|
||||
g_set_error_literal (error, GDK_VULKAN_ERROR, GDK_VULKAN_ERROR_NOT_AVAILABLE,
|
||||
@@ -1804,66 +1799,16 @@ gdk_display_create_vulkan_instance (GdkDisplay *display,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* gdk_display_init_vulkan:
|
||||
* @display: a display
|
||||
* @error: A potential error message
|
||||
*
|
||||
* Initializes Vulkan and returns an error on failure.
|
||||
*
|
||||
* If Vulkan is already initialized, this function returns
|
||||
* %TRUE and increases the refcount of the existing instance.
|
||||
*
|
||||
* You need to gdk_display_unref_vulkan() to close it again.
|
||||
*
|
||||
* Returns: %TRUE if Vulkan is initialized.
|
||||
**/
|
||||
gboolean
|
||||
gdk_display_init_vulkan (GdkDisplay *display,
|
||||
GError **error)
|
||||
{
|
||||
if (display->vulkan_refcount == 0)
|
||||
{
|
||||
if (!gdk_display_create_vulkan_instance (display, error))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
display->vulkan_refcount++;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* gdk_display_ref_vulkan:
|
||||
* @display: a GdkDisplay
|
||||
*
|
||||
* Increases the refcount of an existing Vulkan instance.
|
||||
*
|
||||
* This function must not be called if Vulkan may not be initialized
|
||||
* yet, call gdk_display_init_vulkan() in that case.
|
||||
**/
|
||||
void
|
||||
gdk_display_ref_vulkan (GdkDisplay *display)
|
||||
{
|
||||
g_assert (display->vulkan_refcount > 0);
|
||||
|
||||
display->vulkan_refcount++;
|
||||
}
|
||||
|
||||
void
|
||||
gdk_display_unref_vulkan (GdkDisplay *display)
|
||||
gdk_display_destroy_vulkan_instance (GdkDisplay *display)
|
||||
{
|
||||
GHashTableIter iter;
|
||||
gpointer key, value;
|
||||
|
||||
g_return_if_fail (GDK_IS_DISPLAY (display));
|
||||
g_return_if_fail (display->vulkan_refcount > 0);
|
||||
g_assert (GDK_IS_DISPLAY (display));
|
||||
g_assert (display->vk_instance != NULL);
|
||||
|
||||
display->vulkan_refcount--;
|
||||
if (display->vulkan_refcount > 0)
|
||||
return;
|
||||
|
||||
GDK_DEBUG (VULKAN, "Closing Vulkan instance");
|
||||
GDK_DEBUG (VULKAN, "Destroy Vulkan instance");
|
||||
display->vulkan_features = 0;
|
||||
g_clear_pointer (&display->vk_dmabuf_formats, gdk_dmabuf_formats_unref);
|
||||
g_hash_table_iter_init (&iter, display->vk_shader_modules);
|
||||
@@ -1941,11 +1886,9 @@ gdk_vulkan_init_dmabuf (GdkDisplay *display)
|
||||
return;
|
||||
|
||||
if (!gdk_has_feature (GDK_FEATURE_DMABUF) ||
|
||||
!gdk_display_init_vulkan (display, NULL) ||
|
||||
((display->vulkan_features & GDK_VULKAN_FEATURE_DMABUF) == 0))
|
||||
{
|
||||
return;
|
||||
}
|
||||
!gdk_display_prepare_vulkan (display, NULL) ||
|
||||
(display->vulkan_features & GDK_VULKAN_FEATURE_DMABUF) == 0)
|
||||
return;
|
||||
|
||||
vulkan_builder = gdk_dmabuf_formats_builder_new ();
|
||||
|
||||
|
@@ -73,10 +73,9 @@ gdk_vulkan_handle_result (VkResult res,
|
||||
|
||||
#define GDK_VK_CHECK(func, ...) gdk_vulkan_handle_result (func (__VA_ARGS__), G_STRINGIFY (func))
|
||||
|
||||
gboolean gdk_display_init_vulkan (GdkDisplay *display,
|
||||
gboolean gdk_display_create_vulkan_instance (GdkDisplay *display,
|
||||
GError **error);
|
||||
void gdk_display_ref_vulkan (GdkDisplay *display);
|
||||
void gdk_display_unref_vulkan (GdkDisplay *display);
|
||||
void gdk_display_destroy_vulkan_instance (GdkDisplay *display);
|
||||
|
||||
void gdk_vulkan_init_dmabuf (GdkDisplay *display);
|
||||
|
||||
|
@@ -343,8 +343,6 @@ gsk_vulkan_device_finalize (GObject *object)
|
||||
g_clear_pointer (&self->allocators[i], gsk_vulkan_allocator_unref);
|
||||
g_clear_pointer (&self->external_allocator, gsk_vulkan_allocator_unref);
|
||||
|
||||
gdk_display_unref_vulkan (display);
|
||||
|
||||
G_OBJECT_CLASS (gsk_vulkan_device_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
@@ -422,7 +420,7 @@ gsk_vulkan_device_get_for_display (GdkDisplay *display,
|
||||
if (self)
|
||||
return GSK_GPU_DEVICE (g_object_ref (self));
|
||||
|
||||
if (!gdk_display_init_vulkan (display, error))
|
||||
if (!gdk_display_prepare_vulkan (display, error))
|
||||
return NULL;
|
||||
|
||||
self = g_object_new (GSK_TYPE_VULKAN_DEVICE, NULL);
|
||||
|
@@ -653,7 +653,16 @@ vulkan_supported_platform (GdkSurface *surface,
|
||||
VkPhysicalDeviceProperties props;
|
||||
GError *error = NULL;
|
||||
|
||||
if (!gdk_display_init_vulkan (display, &error))
|
||||
#ifdef GDK_WINDOWING_WAYLAND
|
||||
if (!GDK_IS_WAYLAND_DISPLAY (gdk_surface_get_display (surface)) && !as_fallback)
|
||||
{
|
||||
GSK_DEBUG (RENDERER, "Not using '%s': platform is not Wayland",
|
||||
g_type_name (renderer_type));
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!gdk_display_prepare_vulkan (display, &error))
|
||||
{
|
||||
GSK_DEBUG (RENDERER, "Not using Vulkan%s: %s",
|
||||
as_fallback ? " as fallback" : "",
|
||||
@@ -685,15 +694,7 @@ vulkan_supported_platform (GdkSurface *surface,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef GDK_WINDOWING_WAYLAND
|
||||
if (GDK_IS_WAYLAND_DISPLAY (gdk_surface_get_display (surface)))
|
||||
return TRUE;
|
||||
#endif
|
||||
|
||||
GSK_DEBUG (RENDERER, "Not using '%s': platform is not Wayland",
|
||||
g_type_name (renderer_type));
|
||||
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static GType
|
||||
|
@@ -577,7 +577,7 @@ init_vulkan (GtkInspectorGeneral *gen)
|
||||
const char *types[] = { "other", "integrated GPU", "discrete GPU", "virtual GPU", "CPU" };
|
||||
GError *error = NULL;
|
||||
|
||||
if (!gdk_display_init_vulkan (gen->display, &error))
|
||||
if (!gdk_display_prepare_vulkan (gen->display, &error))
|
||||
{
|
||||
gtk_label_set_text (GTK_LABEL (gen->vk_device), C_("Vulkan device", "None"));
|
||||
gtk_widget_set_visible (gen->vk_error_row, TRUE);
|
||||
@@ -617,8 +617,6 @@ init_vulkan (GtkInspectorGeneral *gen)
|
||||
add_instance_extensions (gen->vulkan_extensions_list);
|
||||
add_device_extensions (gen->display->vk_physical_device, gen->vulkan_extensions_list);
|
||||
add_layers (gen->vulkan_layers_list);
|
||||
|
||||
gdk_display_unref_vulkan (gen->display);
|
||||
#else
|
||||
gtk_label_set_text (GTK_LABEL (gen->vk_device), C_("Vulkan device", "None"));
|
||||
gtk_widget_set_visible (gen->vk_api_version_row, FALSE);
|
||||
|
Reference in New Issue
Block a user