[gtk+/wip/otte/vulkan: 38/41] vulkan: acquire/present images when drawing



commit 363b5c4868d2c0c73774eadef9fa50df85136633
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  |   87 +++++++++++++++++++++++++++++++++++++++++++++-
 gdk/gdkvulkancontext.h  |    6 +++-
 gsk/gskvulkanrenderer.c |   27 ++++++++++++++
 3 files changed, 117 insertions(+), 3 deletions(-)
---
diff --git a/gdk/gdkvulkancontext.c b/gdk/gdkvulkancontext.c
index 03cbbfe..89d1f6a 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;
@@ -150,12 +164,52 @@ gdk_vulkan_context_dispose (GObject *gobject)
 }
 
 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);
+
+  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
@@ -350,6 +404,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 +478,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 +500,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 dc8cffe..eec00f7 100644
--- a/gsk/gskvulkanrenderer.c
+++ b/gsk/gskvulkanrenderer.c
@@ -283,6 +283,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)
 {
@@ -291,6 +317,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]