[gtk+] vulkan: Add infrastructure for multiple pipelines



commit 08a2a29c26f12c7a856a5c24d1083a05f687a484
Author: Benjamin Otte <otte redhat com>
Date:   Wed Dec 14 09:40:15 2016 +0100

    vulkan: Add infrastructure for multiple pipelines
    
    And use it to draw solid colors with a 2nd pipeline.

 gsk/gskvulkanrender.c                |   35 ++++++++++++++++++++++++++-------
 gsk/gskvulkanrenderpass.c            |   30 +++++++++++++++++++++++++++++
 gsk/gskvulkanrenderprivate.h         |    9 ++++++++
 gsk/resources/vulkan/color.frag.glsl |   17 ++++++++++++++++
 gsk/resources/vulkan/color.frag.spv  |  Bin 0 -> 892 bytes
 gsk/resources/vulkan/color.vert.glsl |   19 ++++++++++++++++++
 gsk/resources/vulkan/color.vert.spv  |  Bin 0 -> 1104 bytes
 7 files changed, 102 insertions(+), 8 deletions(-)
---
diff --git a/gsk/gskvulkanrender.c b/gsk/gskvulkanrender.c
index 1c27648..9eec621 100644
--- a/gsk/gskvulkanrender.c
+++ b/gsk/gskvulkanrender.c
@@ -34,7 +34,7 @@ struct _GskVulkanRender
   uint32_t descriptor_pool_maxsets;
   VkDescriptorSet *descriptor_sets;  
   gsize n_descriptor_sets;
-  GskVulkanPipeline *pipeline;
+  GskVulkanPipeline *pipelines[GSK_VULKAN_N_PIPELINES];
 
   VkCommandBuffer command_buffer;
 
@@ -164,8 +164,6 @@ gsk_vulkan_render_new (GskRenderer      *renderer,
 
   self->layout = gsk_vulkan_pipeline_layout_new (self->vulkan);
 
-  self->pipeline = gsk_vulkan_pipeline_new (self->layout, "blit", self->render_pass);
-
   return self;
 }
 
@@ -289,6 +287,29 @@ gsk_vulkan_render_collect_vertices (GskVulkanRender *self)
   return buffer;
 }
 
+GskVulkanPipeline *
+gsk_vulkan_render_get_pipeline (GskVulkanRender       *self,
+                                GskVulkanPipelineType  type)
+{
+  static const struct {
+    const char *name;
+  } pipeline_info[GSK_VULKAN_N_PIPELINES] = {
+    { "blit" },
+    { "color" }
+  };
+
+  g_return_val_if_fail (type < GSK_VULKAN_N_PIPELINES, NULL);
+
+  if (self->pipelines[type] == NULL)
+    {
+      self->pipelines[type] = gsk_vulkan_pipeline_new (self->layout,
+                                                       pipeline_info[type].name,
+                                                       self->render_pass);
+    }
+
+  return self->pipelines[type];
+}
+
 VkDescriptorSet
 gsk_vulkan_render_get_descriptor_set (GskVulkanRender *self,
                                       gsize            id)
@@ -455,10 +476,6 @@ gsk_vulkan_render_draw (GskVulkanRender   *self,
                         },
                         VK_SUBPASS_CONTENTS_INLINE);
 
-  vkCmdBindPipeline (self->command_buffer,
-                     VK_PIPELINE_BIND_POINT_GRAPHICS,
-                     gsk_vulkan_pipeline_get_pipeline (self->pipeline));
-
   vkCmdBindVertexBuffers (self->command_buffer,
                           0,
                           1,
@@ -547,6 +564,7 @@ gsk_vulkan_render_free (GskVulkanRender *self)
   GHashTableIter iter;
   gpointer key, value;
   VkDevice device;
+  guint i;
   
   gsk_vulkan_render_cleanup (self);
 
@@ -566,7 +584,8 @@ gsk_vulkan_render_free (GskVulkanRender *self)
     }
   g_hash_table_unref (self->framebuffers);
 
-  g_clear_object (&self->pipeline);
+  for (i = 0; i < GSK_VULKAN_N_PIPELINES; i++)
+    g_clear_object (&self->pipelines[i]);
 
   g_clear_pointer (&self->layout, gsk_vulkan_pipeline_layout_unref);
 
diff --git a/gsk/gskvulkanrenderpass.c b/gsk/gskvulkanrenderpass.c
index a786fbb..a2d66c8 100644
--- a/gsk/gskvulkanrenderpass.c
+++ b/gsk/gskvulkanrenderpass.c
@@ -17,6 +17,7 @@ typedef enum {
   GSK_VULKAN_OP_FALLBACK,
   GSK_VULKAN_OP_SURFACE,
   GSK_VULKAN_OP_TEXTURE,
+  GSK_VULKAN_OP_COLOR,
   /* GskVulkanOpPushConstants */
   GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS,
   GSK_VULKAN_OP_PUSH_FRAGMENT_CONSTANTS
@@ -26,6 +27,7 @@ struct _GskVulkanOpRender
 {
   GskVulkanOpType      type;
   GskRenderNode       *node; /* node that's the source of this op */
+  GskVulkanPipeline   *pipeline; /* pipeline to use */
   GskVulkanImage      *source; /* source image to render */
   gsize                vertex_offset; /* offset into vertex buffer */
   gsize                vertex_count; /* number of vertices */
@@ -93,16 +95,30 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass           *self,
 
     default:
       op.type = GSK_VULKAN_OP_FALLBACK;
+      op.render.pipeline = gsk_vulkan_render_get_pipeline (render, GSK_VULKAN_PIPELINE_BLIT);
       g_array_append_val (self->render_ops, op);
       break;
 
     case GSK_CAIRO_NODE:
       op.type = GSK_VULKAN_OP_SURFACE;
+      op.render.pipeline = gsk_vulkan_render_get_pipeline (render, GSK_VULKAN_PIPELINE_BLIT);
       g_array_append_val (self->render_ops, op);
       break;
 
     case GSK_TEXTURE_NODE:
       op.type = GSK_VULKAN_OP_TEXTURE;
+      op.render.pipeline = gsk_vulkan_render_get_pipeline (render, GSK_VULKAN_PIPELINE_BLIT);
+      g_array_append_val (self->render_ops, op);
+      break;
+
+    case GSK_COLOR_NODE:
+      op.type = GSK_VULKAN_OP_PUSH_FRAGMENT_CONSTANTS;
+      gsk_vulkan_push_constants_init_copy (&op.constants.constants, constants);
+      gsk_vulkan_push_constants_set_color (&op.constants.constants, gsk_color_node_peek_color (node));
+      g_array_append_val (self->render_ops, op);
+
+      op.type = GSK_VULKAN_OP_COLOR;
+      op.render.pipeline = gsk_vulkan_render_get_pipeline (render, GSK_VULKAN_PIPELINE_COLOR);
       g_array_append_val (self->render_ops, op);
       break;
 
@@ -125,6 +141,7 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass           *self,
         gsk_vulkan_push_constants_init_copy (&op.constants.constants, constants);
         gsk_vulkan_push_constants_multiply_mvp (&op.constants.constants, &transform);
         g_array_append_val (self->render_ops, op);
+
         gsk_vulkan_render_pass_add_node (self, render, &op.constants.constants, gsk_transform_node_get_child 
(node));
         gsk_vulkan_push_constants_init_copy (&op.constants.constants, constants);
         g_array_append_val (self->render_ops, op);
@@ -228,6 +245,7 @@ gsk_vulkan_render_pass_upload (GskVulkanRenderPass *self,
 
         default:
           g_assert_not_reached ();
+        case GSK_VULKAN_OP_COLOR:
         case GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS:
         case GSK_VULKAN_OP_PUSH_FRAGMENT_CONSTANTS:
           break;
@@ -279,6 +297,7 @@ gsk_vulkan_render_pass_collect_vertices (GskVulkanRenderPass *self,
         case GSK_VULKAN_OP_FALLBACK:
         case GSK_VULKAN_OP_SURFACE:
         case GSK_VULKAN_OP_TEXTURE:
+        case GSK_VULKAN_OP_COLOR:
           op->render.vertex_offset = offset + n;
           op->render.vertex_count = gsk_vulkan_render_op_collect_vertices (&op->render, vertices + n + 
offset);
           break;
@@ -318,6 +337,7 @@ gsk_vulkan_render_pass_reserve_descriptor_sets (GskVulkanRenderPass *self,
 
         default:
           g_assert_not_reached ();
+        case GSK_VULKAN_OP_COLOR:
         case GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS:
         case GSK_VULKAN_OP_PUSH_FRAGMENT_CONSTANTS:
           break;
@@ -331,6 +351,7 @@ gsk_vulkan_render_pass_draw (GskVulkanRenderPass     *self,
                              GskVulkanPipelineLayout *layout,
                              VkCommandBuffer          command_buffer)
 {
+  GskVulkanPipeline *current_pipeline = NULL;
   GskVulkanOp *op;
   guint i;
 
@@ -353,6 +374,15 @@ gsk_vulkan_render_pass_draw (GskVulkanRenderPass     *self,
                                    },
                                    0,
                                    NULL);
+          /* fall through */                        
+        case GSK_VULKAN_OP_COLOR:
+          if (current_pipeline != op->render.pipeline)
+            {
+              current_pipeline = op->render.pipeline;
+              vkCmdBindPipeline (command_buffer,
+                                 VK_PIPELINE_BIND_POINT_GRAPHICS,
+                                 gsk_vulkan_pipeline_get_pipeline (current_pipeline));
+            }
 
           vkCmdDraw (command_buffer,
                      op->render.vertex_count, 1,
diff --git a/gsk/gskvulkanrenderprivate.h b/gsk/gskvulkanrenderprivate.h
index 1791245..a85ee95 100644
--- a/gsk/gskvulkanrenderprivate.h
+++ b/gsk/gskvulkanrenderprivate.h
@@ -9,6 +9,13 @@
 
 G_BEGIN_DECLS
 
+typedef enum {
+  GSK_VULKAN_PIPELINE_BLIT,
+  GSK_VULKAN_PIPELINE_COLOR,
+  /* add more */
+  GSK_VULKAN_N_PIPELINES
+} GskVulkanPipelineType;
+
 typedef struct _GskVulkanRender GskVulkanRender;
 typedef struct _GskVulkanVertex GskVulkanVertex;
 
@@ -38,6 +45,8 @@ void                    gsk_vulkan_render_add_node                      (GskVulk
 
 void                    gsk_vulkan_render_upload                        (GskVulkanRender        *self);
 
+GskVulkanPipeline *     gsk_vulkan_render_get_pipeline                  (GskVulkanRender        *self,
+                                                                         GskVulkanPipelineType   
pipeline_type);
 VkDescriptorSet         gsk_vulkan_render_get_descriptor_set            (GskVulkanRender        *self,
                                                                          gsize                   id);
 gsize                   gsk_vulkan_render_reserve_descriptor_set        (GskVulkanRender        *self,
diff --git a/gsk/resources/vulkan/color.frag.glsl b/gsk/resources/vulkan/color.frag.glsl
new file mode 100644
index 0000000..952f9b7
--- /dev/null
+++ b/gsk/resources/vulkan/color.frag.glsl
@@ -0,0 +1,17 @@
+#version 420 core
+
+layout(location = 0) in vec2 inTexCoord;
+
+layout(set = 0, binding = 0) uniform sampler2D inTexture;
+
+layout(push_constant) uniform PushConstants {
+    mat4 mvp;
+    vec4 color;
+} push;
+
+layout(location = 0) out vec4 color;
+
+void main()
+{
+    color = push.color;
+}
diff --git a/gsk/resources/vulkan/color.frag.spv b/gsk/resources/vulkan/color.frag.spv
new file mode 100644
index 0000000..45ffde5
Binary files /dev/null and b/gsk/resources/vulkan/color.frag.spv differ
diff --git a/gsk/resources/vulkan/color.vert.glsl b/gsk/resources/vulkan/color.vert.glsl
new file mode 100644
index 0000000..2522b7e
--- /dev/null
+++ b/gsk/resources/vulkan/color.vert.glsl
@@ -0,0 +1,19 @@
+#version 420 core
+
+layout(location = 0) in vec2 inPosition;
+layout(location = 1) in vec2 inTexCoord;
+
+layout(push_constant) uniform PushConstants {
+    mat4 mvp;
+} push;
+
+layout(location = 0) out vec2 outTexCoord;
+
+out gl_PerVertex {
+  vec4 gl_Position;
+};
+
+void main() {
+  gl_Position = push.mvp * vec4 (inPosition, 0.0, 1.0);
+  outTexCoord = inTexCoord;
+}
diff --git a/gsk/resources/vulkan/color.vert.spv b/gsk/resources/vulkan/color.vert.spv
new file mode 100644
index 0000000..3deee1c
Binary files /dev/null and b/gsk/resources/vulkan/color.vert.spv differ


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