[gtk+/wip/matthiasc/renderpasses: 6/10] first pass at multiple render passes



commit b9bb357eb2add08a94a05f90d9a18e6a1e7ba1da
Author: Matthias Clasen <mclasen redhat com>
Date:   Tue Sep 26 12:07:37 2017 -0400

    first pass at multiple render passes
    
    Missing synchronization.

 gsk/gskvulkanrender.c        |  101 ++++++++++++++++++++++++++++++++++++-----
 gsk/gskvulkanrenderpass.c    |   34 +++++++++++++-
 gsk/gskvulkanrenderprivate.h |    5 ++
 3 files changed, 125 insertions(+), 15 deletions(-)
---
diff --git a/gsk/gskvulkanrender.c b/gsk/gskvulkanrender.c
index ad10adf..a2fc0a7 100644
--- a/gsk/gskvulkanrender.c
+++ b/gsk/gskvulkanrender.c
@@ -57,7 +57,7 @@ struct _GskVulkanRender
 
   GskVulkanImage *target;
 
-  GSList *render_passes;
+  GList *render_passes;
   GSList *cleanup_images;
 };
 
@@ -68,7 +68,6 @@ typedef struct {
   cairo_region_t *clip;
   int scale_factor;
   VkRenderPass render_pass;
-  gboolean own_render_pass;
 } RenderPassData;
 
 static void
@@ -320,7 +319,77 @@ gsk_vulkan_render_add_node (GskVulkanRender *self,
   data->clip = cairo_region_copy (self->clip);
   data->render_pass = self->render_pass;
 
-  self->render_passes = g_slist_prepend (self->render_passes, data);
+  self->render_passes = g_list_prepend (self->render_passes, data);
+
+  gsk_vulkan_render_pass_add (data->pass,
+                              self,
+                              &self->mvp,
+                              &GRAPHENE_RECT_INIT (
+                                  self->viewport.offset.x, self->viewport.offset.y,
+                                  self->viewport.extent.width, self->viewport.extent.height
+                              ),
+                              node);
+}
+
+void
+gsk_vulkan_render_add_node_for_texture (GskVulkanRender *self,
+                                        GskRenderNode   *node,
+                                        GskVulkanImage  *target)
+{
+  RenderPassData *data;
+
+  data = g_new0 (RenderPassData, 1);
+  data->pass = gsk_vulkan_render_pass_new (self->vulkan);
+  data->target = g_object_ref (target);
+  data->render = self;
+  data->scale_factor = 1;
+  data->clip = cairo_region_create_rectangle (&(cairo_rectangle_int_t) {
+                                                0, 0,
+                                                gsk_vulkan_image_get_width (target),
+                                                gsk_vulkan_image_get_height (target)
+                                                });
+
+  GSK_VK_CHECK (vkCreateRenderPass, gdk_vulkan_context_get_device (self->vulkan),
+                                    &(VkRenderPassCreateInfo) {
+                                        .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
+                                        .attachmentCount = 1,
+                                        .pAttachments = (VkAttachmentDescription[]) {
+                                           {
+                                              .format = gdk_vulkan_context_get_image_format (self->vulkan),
+                                              .samples = VK_SAMPLE_COUNT_1_BIT,
+                                              .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
+                                              .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
+                                              .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
+                                              .finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR,
+                                           }
+                                        },
+                                        .subpassCount = 1,
+                                        .pSubpasses = (VkSubpassDescription []) {
+                                           {
+                                              .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
+                                              .inputAttachmentCount = 0,
+                                              .colorAttachmentCount = 1,
+                                              .pColorAttachments = (VkAttachmentReference []) {
+                                                 {
+                                                    .attachment = 0,
+                                                     .layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
+                                                  }
+                                               },
+                                               .pResolveAttachments = (VkAttachmentReference []) {
+                                                  {
+                                                     .attachment = VK_ATTACHMENT_UNUSED,
+                                                     .layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
+                                                  }
+                                               },
+                                               .pDepthStencilAttachment = NULL,
+                                            }
+                                         },
+                                         .dependencyCount = 0
+                                      },
+                                      NULL,
+                                      &data->render_pass);
+
+  self->render_passes = g_list_prepend (self->render_passes, data);
 
   gsk_vulkan_render_pass_add (data->pass,
                               self,
@@ -335,9 +404,13 @@ gsk_vulkan_render_add_node (GskVulkanRender *self,
 void
 gsk_vulkan_render_upload (GskVulkanRender *self)
 {
-  GSList *l;
+  GList *l;
 
-  for (l = self->render_passes; l; l = l->next)
+  /* gsk_vulkan_render_pass_upload may call gsk_vulkan_render_add_node_for_texture,
+   * prepending new render passes to the list. Therefore, we walk the list from
+   * the end.
+   */
+  for (l = g_list_last (self->render_passes); l; l = l->prev)
 
     {
       RenderPassData *data = l->data;
@@ -348,10 +421,10 @@ gsk_vulkan_render_upload (GskVulkanRender *self)
 }
 
 static gsize
-gsk_vulkan_renderer_count_vertex_data (GskVulkanRender *self)
+gsk_vulkan_render_count_vertex_data (GskVulkanRender *self)
 {
   gsize n_bytes;
-  GSList *l;
+  GList *l;
 
   n_bytes = 0;
   for (l = self->render_passes; l; l = l->next)
@@ -368,18 +441,18 @@ gsk_vulkan_render_collect_vertex_data (GskVulkanRender *self)
 {
   GskVulkanBuffer *buffer;
   guchar *data;
-  GSList *l;
+  GList *l;
   gsize offset, n_bytes;
   
   offset = 0;
-  n_bytes = gsk_vulkan_renderer_count_vertex_data (self);
+  n_bytes = gsk_vulkan_render_count_vertex_data (self);
   buffer = gsk_vulkan_buffer_new (self->vulkan, n_bytes);
   data = gsk_vulkan_buffer_map (buffer);
 
   for (l = self->render_passes; l; l = l->next)
     {
       RenderPassData *pass = l->data;
-      offset += gsk_vulkan_render_pass_collect_vertex_data (pass->pass, self, data, offset, n_bytes - 
offset);
+      offset += gsk_vulkan_render_pass_collect_vertex_data (pass->pass, self, data, offset, n_bytes);
       g_assert (offset <= n_bytes);
     }
 
@@ -461,6 +534,8 @@ gsk_vulkan_render_reserve_descriptor_set (GskVulkanRender *self,
 {
   gpointer id_plus_one;
 
+  g_assert (source != NULL);
+
   id_plus_one = g_hash_table_lookup (self->descriptor_set_indexes, source);
   if (id_plus_one)
     return GPOINTER_TO_SIZE (id_plus_one) - 1;
@@ -478,7 +553,7 @@ gsk_vulkan_render_prepare_descriptor_sets (GskVulkanRender *self,
   GHashTableIter iter;
   gpointer key, value;
   VkDevice device;
-  GSList *l;
+  GList *l;
   guint i, needed_sets;
 
   device = gdk_vulkan_context_get_device (self->vulkan);
@@ -573,7 +648,7 @@ gsk_vulkan_render_draw (GskVulkanRender   *self,
                         VkSampler          sampler)
 {
   VkCommandBuffer command_buffer;
-  GSList *l;
+  GList *l;
   guint i;
 
   gsk_vulkan_render_prepare_descriptor_sets (self, sampler);
@@ -680,7 +755,7 @@ gsk_vulkan_render_cleanup (GskVulkanRender *self)
                                        self->descriptor_pool,
                                        0);
 
-  g_slist_free_full (self->render_passes, (GDestroyNotify) render_pass_data_free);
+  g_list_free_full (self->render_passes, (GDestroyNotify) render_pass_data_free);
   self->render_passes = NULL;
   g_slist_free_full (self->cleanup_images, g_object_unref);
   self->cleanup_images = NULL;
diff --git a/gsk/gskvulkanrenderpass.c b/gsk/gskvulkanrenderpass.c
index 3cb7e66..b89b699 100644
--- a/gsk/gskvulkanrenderpass.c
+++ b/gsk/gskvulkanrenderpass.c
@@ -559,6 +559,7 @@ gsk_vulkan_render_pass_get_node_as_texture (GskVulkanRenderPass   *self,
       switch (gsk_render_node_get_node_type (node))
         {
         case GSK_TEXTURE_NODE:
+          g_assert (gsk_texture_node_get_texture (node) != NULL);
           return gsk_vulkan_renderer_ref_texture_image (GSK_VULKAN_RENDERER (gsk_vulkan_render_get_renderer 
(render)),
                                                         gsk_texture_node_get_texture (node),
                                                         uploader);
@@ -566,8 +567,15 @@ gsk_vulkan_render_pass_get_node_as_texture (GskVulkanRenderPass   *self,
           surface = cairo_surface_reference (gsk_cairo_node_get_surface (node));
           goto got_surface;
 
-        default:
-          break;
+        default: ;
+          result = gsk_vulkan_image_new_for_atlas (self->vulkan,
+                                                   ceil (bounds->size.width),
+                                                   ceil (bounds->size.height));
+          g_assert (result != NULL);
+          gsk_vulkan_render_add_node_for_texture (render, node, result);
+          g_assert (result != 0);
+
+          return result;
         }
     }
 
@@ -756,11 +764,13 @@ gsk_vulkan_render_pass_upload (GskVulkanRenderPass  *self,
           {
             GskRenderNode *child = gsk_color_matrix_node_get_child (op->render.node);
 
+            g_assert (child != NULL);
             op->render.source = gsk_vulkan_render_pass_get_node_as_texture (self, 
                                                                             render,
                                                                             uploader,
                                                                             child,
                                                                             &child->bounds);
+            g_assert (op->render.source != NULL);
           }
           break;
 
@@ -769,6 +779,8 @@ gsk_vulkan_render_pass_upload (GskVulkanRenderPass  *self,
             GskRenderNode *start = gsk_cross_fade_node_get_start_child (op->render.node);
             GskRenderNode *end = gsk_cross_fade_node_get_end_child (op->render.node);
 
+            g_assert (start!= NULL);
+            g_assert (end!= NULL);
             op->render.source = gsk_vulkan_render_pass_get_node_as_texture (self,
                                                                             render,
                                                                             uploader,
@@ -779,6 +791,8 @@ gsk_vulkan_render_pass_upload (GskVulkanRenderPass  *self,
                                                                              uploader,
                                                                              end,
                                                                              &end->bounds);
+            g_assert (op->render.source!= NULL);
+            g_assert (op->render.source2!= NULL);
           }
           break;
 
@@ -892,6 +906,7 @@ gsk_vulkan_render_pass_count_vertex_data (GskVulkanRenderPass *self)
 
         default:
           g_assert_not_reached ();
+
         case GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS:
           continue;
         }
@@ -929,6 +944,7 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self,
                                                            data + n_bytes + offset,
                                                            &op->render.node->bounds);
             n_bytes += op->render.vertex_count;
+      g_assert (n_bytes + offset <= total);
           }
           break;
 
@@ -947,6 +963,7 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self,
                                                           op->text.start_glyph,
                                                           op->text.num_glyphs);
             n_bytes += op->text.vertex_count;
+      g_assert (n_bytes + offset <= total);
           }
           break;
 
@@ -964,6 +981,7 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self,
                                                                 op->text.start_glyph,
                                                                 op->text.num_glyphs);
             n_bytes += op->text.vertex_count;
+      g_assert (n_bytes + offset <= total);
           }
           break;
 
@@ -975,6 +993,7 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self,
                                                            &op->render.node->bounds,
                                                            gsk_color_node_peek_color (op->render.node));
             n_bytes += op->render.vertex_count;
+      g_assert (n_bytes + offset <= total);
           }
           break;
 
@@ -990,6 +1009,7 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self,
                                                                      
gsk_linear_gradient_node_get_n_color_stops (op->render.node),
                                                                      
gsk_linear_gradient_node_peek_color_stops (op->render.node));
             n_bytes += op->render.vertex_count;
+      g_assert (n_bytes + offset <= total);
           }
           break;
 
@@ -1012,6 +1032,7 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self,
                                                             &color_matrix,
                                                             &color_offset);
             n_bytes += op->render.vertex_count;
+      g_assert (n_bytes + offset <= total);
           }
           break;
 
@@ -1023,6 +1044,7 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self,
                                                           &op->render.node->bounds,
                                                           gsk_blur_node_get_radius (op->render.node));
             n_bytes += op->render.vertex_count;
+      g_assert (n_bytes + offset <= total);
           }
           break;
 
@@ -1035,6 +1057,7 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self,
                                                             gsk_color_matrix_node_peek_color_matrix 
(op->render.node),
                                                             gsk_color_matrix_node_peek_color_offset 
(op->render.node));
             n_bytes += op->render.vertex_count;
+      g_assert (n_bytes + offset <= total);
           }
           break;
 
@@ -1047,6 +1070,7 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self,
                                                             gsk_border_node_peek_widths (op->render.node),
                                                             gsk_border_node_peek_colors (op->render.node));
             n_bytes += op->render.vertex_count;
+      g_assert (n_bytes + offset <= total);
           }
           break;
 
@@ -1062,6 +1086,7 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self,
                                                                 gsk_inset_shadow_node_get_spread 
(op->render.node),
                                                                 gsk_inset_shadow_node_get_blur_radius 
(op->render.node));
             n_bytes += op->render.vertex_count;
+      g_assert (n_bytes + offset <= total);
           }
           break;
 
@@ -1077,6 +1102,7 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self,
                                                                 gsk_outset_shadow_node_get_spread 
(op->render.node),
                                                                 gsk_outset_shadow_node_get_blur_radius 
(op->render.node));
             n_bytes += op->render.vertex_count;
+      g_assert (n_bytes + offset <= total);
           }
           break;
 
@@ -1093,6 +1119,7 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self,
                                                                 &end->bounds,
                                                                 gsk_cross_fade_node_get_progress 
(op->render.node));
             n_bytes += op->render.vertex_count;
+      g_assert (n_bytes + offset <= total);
           }
           break;
 
@@ -1109,11 +1136,13 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self,
                                                                 &bottom->bounds,
                                                                 gsk_blend_node_get_blend_mode 
(op->render.node));
             n_bytes += op->render.vertex_count;
+      g_assert (n_bytes + offset <= total);
           }
           break;
 
         default:
           g_assert_not_reached ();
+
         case GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS:
           continue;
         }
@@ -1161,6 +1190,7 @@ gsk_vulkan_render_pass_reserve_descriptor_sets (GskVulkanRenderPass *self,
 
         default:
           g_assert_not_reached ();
+
         case GSK_VULKAN_OP_COLOR:
         case GSK_VULKAN_OP_LINEAR_GRADIENT:
         case GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS:
diff --git a/gsk/gskvulkanrenderprivate.h b/gsk/gskvulkanrenderprivate.h
index ed35019..953e75c 100644
--- a/gsk/gskvulkanrenderprivate.h
+++ b/gsk/gskvulkanrenderprivate.h
@@ -69,6 +69,11 @@ void                    gsk_vulkan_render_add_cleanup_image             (GskVulk
 void                    gsk_vulkan_render_add_node                      (GskVulkanRender        *self,
                                                                          GskRenderNode          *node);
 
+void                    gsk_vulkan_render_add_node_for_texture          (GskVulkanRender        *self,
+                                                                         GskRenderNode          *node,
+                                                                         GskVulkanImage         *target);
+
+
 void                    gsk_vulkan_render_upload                        (GskVulkanRender        *self);
 
 GskVulkanPipeline *     gsk_vulkan_render_get_pipeline                  (GskVulkanRender        *self,


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