[gtk+/wip/otte/vulkan: 33/62] vulkan: acquire/present images when drawing
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/otte/vulkan: 33/62] vulkan: acquire/present images when drawing
- Date: Fri, 9 Dec 2016 17:37:43 +0000 (UTC)
commit 8ba2898e08a8fd1038991d117705990a1fc9e398
Author: Benjamin Otte <otte redhat com>
Date: Thu Dec 1 04:07:20 2016 +0100
vulkan: acquire/present images when drawing
Another step towards the final goal of actually showing something.
gdk/gdkvulkancontext.c | 159 +++++++++++++++++++++++++++++++++++++----------
gdk/gdkvulkancontext.h | 6 ++-
gsk/gskvulkanrenderer.c | 27 ++++++++
3 files changed, 157 insertions(+), 35 deletions(-)
---
diff --git a/gdk/gdkvulkancontext.c b/gdk/gdkvulkancontext.c
index 03cbbfe..f0af29b 100644
--- a/gdk/gdkvulkancontext.c
+++ b/gdk/gdkvulkancontext.c
@@ -36,9 +36,12 @@ struct _GdkVulkanContextPrivate {
int swapchain_width, swapchain_height;
VkSwapchainKHR swapchain;
+ VkSemaphore draw_semaphore;
guint n_images;
VkImage *images;
+
+ uint32_t draw_index;
};
enum {
@@ -121,13 +124,24 @@ 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;
g_clear_pointer (&priv->images, g_free);
priv->n_images = 0;
+ device = gdk_vulkan_context_get_device (context);
+
+ if (priv->draw_semaphore != VK_NULL_HANDLE)
+ {
+ vkDestroySemaphore (device,
+ priv->draw_semaphore,
+ NULL);
+ priv->draw_semaphore = VK_NULL_HANDLE;
+ }
+
if (priv->swapchain != VK_NULL_HANDLE)
{
- vkDestroySwapchainKHR (gdk_vulkan_context_get_device (context),
+ vkDestroySwapchainKHR (device,
priv->swapchain,
NULL);
priv->swapchain = VK_NULL_HANDLE;
@@ -149,36 +163,6 @@ gdk_vulkan_context_dispose (GObject *gobject)
G_OBJECT_CLASS (gdk_vulkan_context_parent_class)->dispose (gobject);
}
-static void
-gdk_vulkan_context_class_init (GdkVulkanContextClass *klass)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-
- gobject_class->dispose = gdk_vulkan_context_dispose;
-
- /**
- * GdkVulkanContext::images-updated:
- * @context: the object on which the signal is emitted
- *
- * This signal is emitted when the images managed by this context have
- * changed. Usually this means that the swapchain had to be recreated,
- * for example in response to a change of the window size.
- */
- signals[IMAGES_UPDATED] =
- g_signal_new (g_intern_static_string ("images-updated"),
- G_OBJECT_CLASS_TYPE (gobject_class),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-}
-
-static void
-gdk_vulkan_context_init (GdkVulkanContext *self)
-{
-}
-
static gboolean
gdk_vulkan_context_check_swapchain (GdkVulkanContext *context,
GError **error)
@@ -259,8 +243,8 @@ gdk_vulkan_context_check_swapchain (GdkVulkanContext *context,
if (res == VK_SUCCESS)
{
- priv->swapchain_width = gdk_window_get_width (window);
- priv->swapchain_height = gdk_window_get_height (window);
+ priv->swapchain_width = capabilities.currentExtent.width;
+ priv->swapchain_height = capabilities.currentExtent.height;
priv->swapchain = new_swapchain;
GDK_VK_CHECK (vkGetSwapchainImagesKHR, device,
@@ -288,6 +272,84 @@ gdk_vulkan_context_check_swapchain (GdkVulkanContext *context,
return res == VK_SUCCESS;
}
+static void
+gdk_vulkan_context_begin_frame (GdkDrawContext *draw_context,
+ cairo_region_t *region)
+{
+ GdkVulkanContext *context = GDK_VULKAN_CONTEXT (draw_context);
+ GdkVulkanContextPrivate *priv = gdk_vulkan_context_get_instance_private (context);
+ GError *error = NULL;
+
+ if (!gdk_vulkan_context_check_swapchain (context, &error))
+ {
+ g_warning ("%s", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ GDK_VK_CHECK (vkAcquireNextImageKHR, gdk_vulkan_context_get_device (context),
+ priv->swapchain,
+ UINT64_MAX,
+ priv->draw_semaphore,
+ VK_NULL_HANDLE,
+ &priv->draw_index);
+}
+
+static void
+gdk_vulkan_context_end_frame (GdkDrawContext *draw_context,
+ cairo_region_t *painted,
+ cairo_region_t *damage)
+{
+ GdkVulkanContext *context = GDK_VULKAN_CONTEXT (draw_context);
+ GdkVulkanContextPrivate *priv = gdk_vulkan_context_get_instance_private (context);
+
+ GDK_VK_CHECK (vkQueuePresentKHR, gdk_vulkan_context_get_queue (context),
+ &(VkPresentInfoKHR) {
+ .sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR,
+ .swapchainCount = 1,
+ .pSwapchains = (VkSwapchainKHR[]) {
+ priv->swapchain
+ },
+ .pImageIndices = (uint32_t[]) {
+ priv->draw_index
+ },
+ });
+}
+
+static void
+gdk_vulkan_context_class_init (GdkVulkanContextClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GdkDrawContextClass *draw_context_class = GDK_DRAW_CONTEXT_CLASS (klass);
+
+ gobject_class->dispose = gdk_vulkan_context_dispose;
+
+ draw_context_class->begin_frame = gdk_vulkan_context_begin_frame;
+ draw_context_class->end_frame = gdk_vulkan_context_end_frame;
+
+ /**
+ * GdkVulkanContext::images-updated:
+ * @context: the object on which the signal is emitted
+ *
+ * This signal is emitted when the images managed by this context have
+ * changed. Usually this means that the swapchain had to be recreated,
+ * for example in response to a change of the window size.
+ */
+ signals[IMAGES_UPDATED] =
+ g_signal_new (g_intern_static_string ("images-updated"),
+ G_OBJECT_CLASS_TYPE (gobject_class),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+static void
+gdk_vulkan_context_init (GdkVulkanContext *self)
+{
+}
+
static gboolean
gdk_vulkan_context_real_init (GInitable *initable,
GCancellable *cancellable,
@@ -350,6 +412,13 @@ gdk_vulkan_context_real_init (GInitable *initable,
if (!gdk_vulkan_context_check_swapchain (context, error))
goto out_surface;
+ GDK_VK_CHECK (vkCreateSemaphore, gdk_vulkan_context_get_device (context),
+ &(VkSemaphoreCreateInfo) {
+ .sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
+ },
+ NULL,
+ &priv->draw_semaphore);
+
return TRUE;
}
@@ -417,7 +486,7 @@ gdk_vulkan_context_get_image_format (GdkVulkanContext *context)
return priv->image_format.format;
}
-guint
+uint32_t
gdk_vulkan_context_get_n_images (GdkVulkanContext *context)
{
GdkVulkanContextPrivate *priv = gdk_vulkan_context_get_instance_private (context);
@@ -439,6 +508,28 @@ gdk_vulkan_context_get_image (GdkVulkanContext *context,
return priv->images[id];
}
+uint32_t
+gdk_vulkan_context_get_draw_index (GdkVulkanContext *context)
+{
+ GdkVulkanContextPrivate *priv = gdk_vulkan_context_get_instance_private (context);
+
+ g_return_val_if_fail (GDK_IS_VULKAN_CONTEXT (context), 0);
+ g_return_val_if_fail (gdk_draw_context_is_drawing (GDK_DRAW_CONTEXT (context)), 0);
+
+ return priv->draw_index;
+}
+
+VkSemaphore
+gdk_vulkan_context_get_draw_semaphore (GdkVulkanContext *context)
+{
+ GdkVulkanContextPrivate *priv = gdk_vulkan_context_get_instance_private (context);
+
+ g_return_val_if_fail (GDK_IS_VULKAN_CONTEXT (context), VK_NULL_HANDLE);
+ g_return_val_if_fail (gdk_draw_context_is_drawing (GDK_DRAW_CONTEXT (context)), VK_NULL_HANDLE);
+
+ return priv->draw_semaphore;
+}
+
static gboolean
gdk_display_create_vulkan_device (GdkDisplay *display,
GError **error)
diff --git a/gdk/gdkvulkancontext.h b/gdk/gdkvulkancontext.h
index 2690048..1dfa648 100644
--- a/gdk/gdkvulkancontext.h
+++ b/gdk/gdkvulkancontext.h
@@ -64,10 +64,14 @@ uint32_t gdk_vulkan_context_get_queue_family_index (GdkVulkanCo
GDK_AVAILABLE_IN_3_90
VkFormat gdk_vulkan_context_get_image_format (GdkVulkanContext *context);
GDK_AVAILABLE_IN_3_90
-guint gdk_vulkan_context_get_n_images (GdkVulkanContext *context);
+uint32_t gdk_vulkan_context_get_n_images (GdkVulkanContext *context);
GDK_AVAILABLE_IN_3_90
VkImage gdk_vulkan_context_get_image (GdkVulkanContext *context,
guint id);
+GDK_AVAILABLE_IN_3_90
+uint32_t gdk_vulkan_context_get_draw_index (GdkVulkanContext *context);
+GDK_AVAILABLE_IN_3_90
+VkSemaphore gdk_vulkan_context_get_draw_semaphore (GdkVulkanContext *context);
#endif /* GDK_WINDOWING_VULKAN */
diff --git a/gsk/gskvulkanrenderer.c b/gsk/gskvulkanrenderer.c
index 1bf4329..ccae2de 100644
--- a/gsk/gskvulkanrenderer.c
+++ b/gsk/gskvulkanrenderer.c
@@ -285,6 +285,32 @@ gsk_vulkan_renderer_render (GskRenderer *renderer,
#endif
}
+static GdkDrawingContext *
+gsk_vulkan_renderer_begin_draw_frame (GskRenderer *renderer,
+ const cairo_region_t *region)
+{
+ GskVulkanRenderer *self = GSK_VULKAN_RENDERER (renderer);
+ cairo_region_t *whole_window;
+ GdkDrawingContext *result;
+ GdkWindow *window;
+
+ window = gsk_renderer_get_window (renderer);
+
+ whole_window = cairo_region_create_rectangle (&(GdkRectangle) {
+ 0, 0,
+ gdk_window_get_width (window),
+ gdk_window_get_height (window)
+ });
+
+ result = gdk_window_begin_draw_frame (window,
+ GDK_DRAW_CONTEXT (self->vulkan),
+ region);
+
+ cairo_region_destroy (whole_window);
+
+ return result;
+}
+
static void
gsk_vulkan_renderer_class_init (GskVulkanRendererClass *klass)
{
@@ -293,6 +319,7 @@ gsk_vulkan_renderer_class_init (GskVulkanRendererClass *klass)
renderer_class->realize = gsk_vulkan_renderer_realize;
renderer_class->unrealize = gsk_vulkan_renderer_unrealize;
renderer_class->render = gsk_vulkan_renderer_render;
+ renderer_class->begin_draw_frame = gsk_vulkan_renderer_begin_draw_frame;
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]