[gtk+/wip/otte/vulkan: 14/28] vulkan: Keep render objects around



commit 603da1143096444d981f28d4c17be115e419ba2d
Author: Benjamin Otte <otte redhat com>
Date:   Thu Dec 8 18:40:35 2016 +0100

    vulkan: Keep render objects around
    
    That way we can reuse them. We only create a new one if the last render
    operation hasn't finished executing.

 gsk/gskvulkanrender.c        |   81 ++++++++++++++++++++++++++++++------------
 gsk/gskvulkanrenderer.c      |   28 +++++++++++++--
 gsk/gskvulkanrenderprivate.h |    3 ++
 3 files changed, 86 insertions(+), 26 deletions(-)
---
diff --git a/gsk/gskvulkanrender.c b/gsk/gskvulkanrender.c
index a876a2a..b645dc3 100644
--- a/gsk/gskvulkanrender.c
+++ b/gsk/gskvulkanrender.c
@@ -68,8 +68,6 @@ gsk_vulkan_render_new (GskRenderer      *renderer,
   self->vulkan = context;
   self->renderer = renderer;
 
-  gsk_vulkan_render_compute_mvp (self);
-
   device = gdk_vulkan_context_get_device (self->vulkan);
 
   GSK_VK_CHECK (vkCreateCommandPool, device,
@@ -84,26 +82,11 @@ gsk_vulkan_render_new (GskRenderer      *renderer,
   GSK_VK_CHECK (vkCreateFence, device,
                                &(VkFenceCreateInfo) {
                                    .sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
-                                   .flags = 0
+                                   .flags = VK_FENCE_CREATE_SIGNALED_BIT
                                },
                                NULL,
                                &self->fence);
 
-  GSK_VK_CHECK (vkAllocateCommandBuffers, device,
-                                          &(VkCommandBufferAllocateInfo) {
-                                              .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
-                                              .commandPool = self->command_pool,
-                                              .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
-                                              .commandBufferCount = 1,
-                                          },
-                                          &self->command_buffer);
-
-  GSK_VK_CHECK (vkBeginCommandBuffer, self->command_buffer,
-                                      &(VkCommandBufferBeginInfo) {
-                                          .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
-                                          .flags = 0
-                                      });
-
   return self;
 }
 
@@ -294,22 +277,41 @@ gsk_vulkan_render_submit (GskVulkanRender *self)
                                  &self->fence,
                                  VK_TRUE,
                                  INT64_MAX);
-  GSK_VK_CHECK (vkResetFences, gdk_vulkan_context_get_device (self->vulkan),
-                               1,
-                               &self->fence);
 }
 
-void
-gsk_vulkan_render_free (GskVulkanRender *self)
+static void
+gsk_vulkan_render_cleanup (GskVulkanRender *self)
 {
   VkDevice device = gdk_vulkan_context_get_device (self->vulkan);
 
+  /* XXX: Wait for fence here or just in reset()? */
+  GSK_VK_CHECK (vkWaitForFences, device,
+                                 1,
+                                 &self->fence,
+                                 VK_TRUE,
+                                 INT64_MAX);
+
+  GSK_VK_CHECK (vkResetFences, device,
+                               1,
+                               &self->fence);
   GSK_VK_CHECK (vkResetCommandPool, device,
                                     self->command_pool,
                                     0);
 
   g_slist_free_full (self->render_passes, (GDestroyNotify) gsk_vulkan_render_pass_free);
+  self->render_passes = NULL;
   g_slist_free_full (self->cleanup_images, (GDestroyNotify) gsk_vulkan_image_free);
+  self->cleanup_images = NULL;
+}
+
+void
+gsk_vulkan_render_free (GskVulkanRender *self)
+{
+  VkDevice device;
+  
+  gsk_vulkan_render_cleanup (self);
+
+  device = gdk_vulkan_context_get_device (self->vulkan);
 
   vkDestroyFence (device,
                   self->fence,
@@ -321,6 +323,39 @@ gsk_vulkan_render_free (GskVulkanRender *self)
   g_slice_free (GskVulkanRender, self);
 }
 
+gboolean
+gsk_vulkan_render_is_busy (GskVulkanRender *self)
+{
+  return vkGetFenceStatus (gdk_vulkan_context_get_device (self->vulkan), self->fence) != VK_SUCCESS;
+}
+
+void
+gsk_vulkan_render_reset (GskVulkanRender *self)
+{
+  VkDevice device;
+
+  gsk_vulkan_render_cleanup (self);
+
+  gsk_vulkan_render_compute_mvp (self);
+
+  device = gdk_vulkan_context_get_device (self->vulkan);
+
+  GSK_VK_CHECK (vkAllocateCommandBuffers, device,
+                                          &(VkCommandBufferAllocateInfo) {
+                                              .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
+                                              .commandPool = self->command_pool,
+                                              .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
+                                              .commandBufferCount = 1,
+                                          },
+                                          &self->command_buffer);
+
+  GSK_VK_CHECK (vkBeginCommandBuffer, self->command_buffer,
+                                      &(VkCommandBufferBeginInfo) {
+                                          .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
+                                          .flags = 0
+                                      });
+}
+
 GskRenderer *
 gsk_vulkan_render_get_renderer (GskVulkanRender *self)
 {
diff --git a/gsk/gskvulkanrenderer.c b/gsk/gskvulkanrenderer.c
index 2332ccf..929ea91 100644
--- a/gsk/gskvulkanrenderer.c
+++ b/gsk/gskvulkanrenderer.c
@@ -42,6 +42,8 @@ struct _GskVulkanRenderer
 
   VkSampler sampler;
 
+  GSList *renders;
+
 #ifdef G_ENABLE_DEBUG
   ProfileTimers profile_timers;
 #endif
@@ -267,6 +269,9 @@ gsk_vulkan_renderer_realize (GskRenderer  *renderer,
                     self);
   gsk_vulkan_renderer_update_images_cb (self->vulkan, self);
 
+  /* We will need at least one render object, so create it early where we can still fail fine */
+  self->renders = g_slist_prepend (self->renders, gsk_vulkan_render_new (renderer, self->vulkan));
+
   return TRUE;
 }
 
@@ -276,6 +281,9 @@ gsk_vulkan_renderer_unrealize (GskRenderer *renderer)
   GskVulkanRenderer *self = GSK_VULKAN_RENDERER (renderer);
   VkDevice device;
 
+  g_slist_free_full (self->renders, (GDestroyNotify) gsk_vulkan_render_free);
+  self->renders = NULL;
+
   device = gdk_vulkan_context_get_device (self->vulkan);
 
   gsk_vulkan_renderer_free_targets (self);
@@ -310,6 +318,7 @@ gsk_vulkan_renderer_render (GskRenderer   *renderer,
 {
   GskVulkanRenderer *self = GSK_VULKAN_RENDERER (renderer);
   GskVulkanRender *render;
+  GSList *l;
 #ifdef G_ENABLE_DEBUG
   GskProfiler *profiler;
   gint64 cpu_time;
@@ -320,7 +329,22 @@ gsk_vulkan_renderer_render (GskRenderer   *renderer,
   gsk_profiler_timer_begin (profiler, self->profile_timers.cpu_time);
 #endif
 
-  render = gsk_vulkan_render_new (renderer, self->vulkan);
+  for (l = self->renders; l; l = l->next)
+    {
+      if (!gsk_vulkan_render_is_busy (l->data))
+        break;
+    }
+  if (l)
+    {
+      render = l->data;
+    }
+  else
+    {
+      render = gsk_vulkan_render_new (renderer, self->vulkan);
+      self->renders = g_slist_prepend (self->renders, render);
+    }
+
+  gsk_vulkan_render_reset (render);
 
   gsk_vulkan_render_add_node (render, root);
 
@@ -333,8 +357,6 @@ gsk_vulkan_renderer_render (GskRenderer   *renderer,
 
   gsk_vulkan_render_submit (render);
 
-  gsk_vulkan_render_free (render);
-
 #ifdef G_ENABLE_DEBUG
   cpu_time = gsk_profiler_timer_end (profiler, self->profile_timers.cpu_time);
   gsk_profiler_timer_set (profiler, self->profile_timers.cpu_time, cpu_time);
diff --git a/gsk/gskvulkanrenderprivate.h b/gsk/gskvulkanrenderprivate.h
index b4f5edd..a86e5c8 100644
--- a/gsk/gskvulkanrenderprivate.h
+++ b/gsk/gskvulkanrenderprivate.h
@@ -24,6 +24,9 @@ GskVulkanRender *       gsk_vulkan_render_new                           (GskRend
                                                                          GdkVulkanContext       *context);
 void                    gsk_vulkan_render_free                          (GskVulkanRender        *self);
 
+gboolean                gsk_vulkan_render_is_busy                       (GskVulkanRender        *self);
+void                    gsk_vulkan_render_reset                         (GskVulkanRender        *self);
+
 GskRenderer *           gsk_vulkan_render_get_renderer                  (GskVulkanRender        *self);
 
 void                    gsk_vulkan_render_add_cleanup_image             (GskVulkanRender        *self,


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