[gtk+] vulkan: Add infrastructure for push constants



commit 62eb9d42aac9807a9a1b811f839e4a668aac3a62
Author: Benjamin Otte <otte redhat com>
Date:   Wed Dec 14 07:21:21 2016 +0100

    vulkan: Add infrastructure for push constants
    
    THe code includes fragment push constants for colors, but that code is
    so far unused.

 gsk/Makefile.am                     |    2 +
 gsk/gskvulkanpipeline.c             |   11 +---
 gsk/gskvulkanpushconstants.c        |  101 +++++++++++++++++++++++++++++++++++
 gsk/gskvulkanpushconstantsprivate.h |   46 ++++++++++++++++
 gsk/gskvulkanrenderpass.c           |   64 ++++++++++++----------
 5 files changed, 188 insertions(+), 36 deletions(-)
---
diff --git a/gsk/Makefile.am b/gsk/Makefile.am
index f27cf2f..3959970 100644
--- a/gsk/Makefile.am
+++ b/gsk/Makefile.am
@@ -28,6 +28,7 @@ gsk_private_vulan_source_h = \
        gskvulkanimageprivate.h \
        gskvulkanmemoryprivate.h \
        gskvulkanpipelineprivate.h \
+       gskvulkanpushconstantsprivate.h \
        gskvulkanrenderprivate.h \
        gskvulkanrendererprivate.h \
        gskvulkanrenderpassprivate.h \
@@ -37,6 +38,7 @@ gsk_private_vulkan_source_c = \
        gskvulkanimage.c \
        gskvulkanmemory.c \
        gskvulkanpipeline.c \
+       gskvulkanpushconstants.c \
        gskvulkanrender.c \
        gskvulkanrenderer.c \
        gskvulkanrenderpass.c \
diff --git a/gsk/gskvulkanpipeline.c b/gsk/gskvulkanpipeline.c
index a0b43fd..d1b1ed3 100644
--- a/gsk/gskvulkanpipeline.c
+++ b/gsk/gskvulkanpipeline.c
@@ -2,6 +2,7 @@
 
 #include "gskvulkanpipelineprivate.h"
 
+#include "gskvulkanpushconstantsprivate.h"
 #include "gskvulkanshaderprivate.h"
 
 #include <graphene.h>
@@ -96,14 +97,8 @@ gsk_vulkan_pipeline_new (GdkVulkanContext *context,
                                             .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
                                             .setLayoutCount = 1,
                                             .pSetLayouts = &self->descriptor_set_layout,
-                                            .pushConstantRangeCount = 1,
-                                            .pPushConstantRanges = (VkPushConstantRange[1]) {
-                                                {
-                                                    .stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
-                                                    .offset = 0,
-                                                    .size = sizeof (graphene_matrix_t)
-                                                }
-                                            }
+                                            .pushConstantRangeCount = 
gst_vulkan_push_constants_get_range_count (),
+                                            .pPushConstantRanges = gst_vulkan_push_constants_get_ranges ()
                                         },
                                         NULL,
                                         &self->pipeline_layout);
diff --git a/gsk/gskvulkanpushconstants.c b/gsk/gskvulkanpushconstants.c
new file mode 100644
index 0000000..485ec8b
--- /dev/null
+++ b/gsk/gskvulkanpushconstants.c
@@ -0,0 +1,101 @@
+#include "config.h"
+
+#include "gskvulkanpushconstantsprivate.h"
+
+#include <math.h>
+
+void
+gsk_vulkan_push_constants_init (GskVulkanPushConstants  *constants,
+                                const graphene_matrix_t *mvp)
+{
+  GdkRGBA transparent = { 0, 0, 0, 0 };
+
+  gsk_vulkan_push_constants_set_mvp (constants, mvp);
+  gsk_vulkan_push_constants_set_color (constants, &transparent);
+}
+
+void
+gsk_vulkan_push_constants_init_copy (GskVulkanPushConstants       *self,
+                                     const GskVulkanPushConstants *src)
+{
+  *self = *src;
+}
+
+void
+gsk_vulkan_push_constants_set_mvp (GskVulkanPushConstants  *self,
+                                   const graphene_matrix_t *mvp)
+{
+  graphene_matrix_to_float (mvp, self->vertex.mvp);
+}
+
+void
+gsk_vulkan_push_constants_multiply_mvp (GskVulkanPushConstants  *self,
+                                        const graphene_matrix_t *transform)
+{
+  graphene_matrix_t old_mvp, new_mvp;
+
+  graphene_matrix_init_from_float (&old_mvp, self->vertex.mvp);
+  graphene_matrix_multiply (transform, &old_mvp, &new_mvp);
+  gsk_vulkan_push_constants_set_mvp (self, &new_mvp);
+}
+
+void
+gsk_vulkan_push_constants_set_color (GskVulkanPushConstants *self,
+                                     const GdkRGBA          *color)
+{
+  self->fragment.color[0] = pow (color->red, 2.2);
+  self->fragment.color[1] = pow (color->green, 2.2);
+  self->fragment.color[2] = pow (color->blue, 2.2);
+  self->fragment.color[3] = color->alpha;
+}
+
+void
+gsk_vulkan_push_constants_push_vertex (GskVulkanPushConstants *self,
+                                       VkCommandBuffer         command_buffer,
+                                       VkPipelineLayout        pipeline_layout)
+{
+  vkCmdPushConstants (command_buffer,
+                      pipeline_layout,
+                      VK_SHADER_STAGE_VERTEX_BIT,
+                      G_STRUCT_OFFSET (GskVulkanPushConstants, vertex),
+                      sizeof (self->vertex),
+                      &self->vertex);
+}
+
+void
+gsk_vulkan_push_constants_push_fragment (GskVulkanPushConstants *self,
+                                         VkCommandBuffer         command_buffer,
+                                         VkPipelineLayout        pipeline_layout)
+{
+  vkCmdPushConstants (command_buffer,
+                      pipeline_layout,
+                      VK_SHADER_STAGE_FRAGMENT_BIT,
+                      G_STRUCT_OFFSET (GskVulkanPushConstants, fragment),
+                      sizeof (self->fragment),
+                      &self->fragment);
+}
+
+uint32_t
+gst_vulkan_push_constants_get_range_count (void)
+{
+  return 2;
+}
+
+const VkPushConstantRange *
+gst_vulkan_push_constants_get_ranges (void)
+{
+  static const VkPushConstantRange ranges[2] = {
+      {
+          .stageFlags = VK_SHADER_STAGE_VERTEX_BIT,
+          .offset = G_STRUCT_OFFSET (GskVulkanPushConstants, vertex),
+          .size = sizeof (((GskVulkanPushConstants *) 0)->vertex)
+      },
+      {
+          .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT,
+          .offset = G_STRUCT_OFFSET (GskVulkanPushConstants, fragment),
+          .size = sizeof (((GskVulkanPushConstants *) 0)->fragment)
+      }
+  };
+
+  return ranges;
+}
diff --git a/gsk/gskvulkanpushconstantsprivate.h b/gsk/gskvulkanpushconstantsprivate.h
new file mode 100644
index 0000000..37ac01f
--- /dev/null
+++ b/gsk/gskvulkanpushconstantsprivate.h
@@ -0,0 +1,46 @@
+#ifndef __GSK_VULKAN_PUSH_CONSTANTS_PRIVATE_H__
+#define __GSK_VULKAN_PUSH_CONSTANTS_PRIVATE_H__
+
+#include <gdk/gdk.h>
+#include <graphene.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GskVulkanPushConstants GskVulkanPushConstants;
+
+struct _GskVulkanPushConstants
+{
+  struct {
+    float mvp[16];
+  } vertex;
+  struct {
+    float color[4];
+  } fragment;
+};
+
+const VkPushConstantRange *
+                        gst_vulkan_push_constants_get_ranges            (void) G_GNUC_PURE;
+uint32_t                gst_vulkan_push_constants_get_range_count       (void) G_GNUC_PURE;
+
+void                    gsk_vulkan_push_constants_init                  (GskVulkanPushConstants         
*constants,
+                                                                         const graphene_matrix_t        
*mvp);
+void                    gsk_vulkan_push_constants_init_copy             (GskVulkanPushConstants         
*self,
+                                                                         const GskVulkanPushConstants   
*src);
+
+void                    gsk_vulkan_push_constants_set_mvp               (GskVulkanPushConstants         
*self,
+                                                                         const graphene_matrix_t        
*mvp);
+void                    gsk_vulkan_push_constants_multiply_mvp          (GskVulkanPushConstants         
*self,
+                                                                         const graphene_matrix_t        
*transform);
+void                    gsk_vulkan_push_constants_set_color             (GskVulkanPushConstants         
*self,
+                                                                         const GdkRGBA                  
*color);
+
+void                    gsk_vulkan_push_constants_push_vertex           (GskVulkanPushConstants         
*self,
+                                                                         VkCommandBuffer                 
command_buffer,
+                                                                         VkPipelineLayout                
pipeline_layout);
+void                    gsk_vulkan_push_constants_push_fragment         (GskVulkanPushConstants         
*self,
+                                                                         VkCommandBuffer                 
command_buffer,
+                                                                         VkPipelineLayout                
pipeline_layout);
+
+G_END_DECLS
+
+#endif /* __GSK_VULKAN_PUSH_CONSTANTS_PRIVATE_H__ */
diff --git a/gsk/gskvulkanrenderpass.c b/gsk/gskvulkanrenderpass.c
index 9b28951..527fb31 100644
--- a/gsk/gskvulkanrenderpass.c
+++ b/gsk/gskvulkanrenderpass.c
@@ -5,6 +5,7 @@
 #include "gskvulkanimageprivate.h"
 #include "gskrendernodeprivate.h"
 #include "gskrenderer.h"
+#include "gskvulkanpushconstantsprivate.h"
 #include "gskvulkanrendererprivate.h"
 
 typedef struct _GskVulkanRenderOp GskVulkanRenderOp;
@@ -13,7 +14,8 @@ typedef enum {
   GSK_VULKAN_OP_FALLBACK,
   GSK_VULKAN_OP_SURFACE,
   GSK_VULKAN_OP_TEXTURE,
-  GSK_VULKAN_OP_BIND_MVP
+  GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS,
+  GSK_VULKAN_OP_PUSH_FRAGMENT_CONSTANTS
 } GskVulkanOpType;
 
 struct _GskVulkanRenderOp
@@ -21,7 +23,7 @@ struct _GskVulkanRenderOp
   GskVulkanOpType      type;
   GskRenderNode       *node; /* node that's the source of this op */
   GskVulkanImage      *source; /* source image to render */
-  graphene_matrix_t    mvp; /* new mvp to set */
+  GskVulkanPushConstants constants; /* new constants to push */
   gsize                vertex_offset; /* offset into vertex buffer */
   gsize                vertex_count; /* number of vertices */
   gsize                descriptor_set_index; /* index into descriptor sets array for the right descriptor 
set to bind */
@@ -56,10 +58,10 @@ gsk_vulkan_render_pass_free (GskVulkanRenderPass *self)
 }
 
 void
-gsk_vulkan_render_pass_add_node (GskVulkanRenderPass     *self,
-                                 GskVulkanRender         *render,
-                                 const graphene_matrix_t *mvp,
-                                 GskRenderNode           *node)
+gsk_vulkan_render_pass_add_node (GskVulkanRenderPass           *self,
+                                 GskVulkanRender               *render,
+                                 const GskVulkanPushConstants  *constants,
+                                 GskRenderNode                 *node)
 {
   GskVulkanRenderOp op = {
     .type = GSK_VULKAN_OP_FALLBACK,
@@ -93,7 +95,7 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass     *self,
 
         for (i = 0; i < gsk_container_node_get_n_children (node); i++)
           {
-            gsk_vulkan_render_pass_add_node (self, render, mvp, gsk_container_node_get_child (node, i));
+            gsk_vulkan_render_pass_add_node (self, render, constants, gsk_container_node_get_child (node, 
i));
           }
       }
       break;
@@ -101,12 +103,13 @@ gsk_vulkan_render_pass_add_node (GskVulkanRenderPass     *self,
       {
         graphene_matrix_t transform;
 
-        op.type = GSK_VULKAN_OP_BIND_MVP;
         gsk_transform_node_get_transform (node, &transform);
-        graphene_matrix_multiply (&transform, mvp, &op.mvp);
+        op.type = GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS;
+        gsk_vulkan_push_constants_init_copy (&op.constants, constants);
+        gsk_vulkan_push_constants_multiply_mvp (&op.constants, &transform);
         g_array_append_val (self->render_ops, op);
-        gsk_vulkan_render_pass_add_node (self, render, &op.mvp, gsk_transform_node_get_child (node));
-        graphene_matrix_init_from_matrix (&op.mvp, mvp);
+        gsk_vulkan_render_pass_add_node (self, render, &op.constants, gsk_transform_node_get_child (node));
+        gsk_vulkan_push_constants_init_copy (&op.constants, constants);
         g_array_append_val (self->render_ops, op);
       }
       break;
@@ -120,14 +123,16 @@ gsk_vulkan_render_pass_add (GskVulkanRenderPass     *self,
                             const graphene_matrix_t *mvp,
                             GskRenderNode           *node)
 {
-  GskVulkanRenderOp op = {
-    .type = GSK_VULKAN_OP_BIND_MVP,
-    .mvp = *mvp
-  };
+  GskVulkanRenderOp op = { 0, };
 
+  op.type = GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS;
+  gsk_vulkan_push_constants_init (&op.constants, mvp);
   g_array_append_val (self->render_ops, op);
 
-  gsk_vulkan_render_pass_add_node (self, render, mvp, node);
+  op.type = GSK_VULKAN_OP_PUSH_FRAGMENT_CONSTANTS;
+  g_array_append_val (self->render_ops, op);
+
+  gsk_vulkan_render_pass_add_node (self, render, &op.constants, node);
 }
 
 static void
@@ -206,7 +211,8 @@ gsk_vulkan_render_pass_upload (GskVulkanRenderPass *self,
 
         default:
           g_assert_not_reached ();
-        case GSK_VULKAN_OP_BIND_MVP:
+        case GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS:
+        case GSK_VULKAN_OP_PUSH_FRAGMENT_CONSTANTS:
           break;
         }
     }
@@ -262,7 +268,8 @@ gsk_vulkan_render_pass_collect_vertices (GskVulkanRenderPass *self,
 
         default:
           g_assert_not_reached ();
-        case GSK_VULKAN_OP_BIND_MVP:
+        case GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS:
+        case GSK_VULKAN_OP_PUSH_FRAGMENT_CONSTANTS:
           op->vertex_offset = 0;
           op->vertex_count = 0;
           break;
@@ -296,7 +303,8 @@ gsk_vulkan_render_pass_reserve_descriptor_sets (GskVulkanRenderPass *self,
 
         default:
           g_assert_not_reached ();
-        case GSK_VULKAN_OP_BIND_MVP:
+        case GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS:
+        case GSK_VULKAN_OP_PUSH_FRAGMENT_CONSTANTS:
           break;
         }
     }
@@ -309,7 +317,6 @@ gsk_vulkan_render_pass_draw (GskVulkanRenderPass     *self,
                              VkCommandBuffer          command_buffer)
 {
   GskVulkanRenderOp *op;
-  float float_matrix[16];
   guint i;
 
   for (i = 0; i < self->render_ops->len; i++)
@@ -337,15 +344,16 @@ gsk_vulkan_render_pass_draw (GskVulkanRenderPass     *self,
                      op->vertex_offset, 0);
           break;
 
-        case GSK_VULKAN_OP_BIND_MVP:
-          graphene_matrix_to_float (&op->mvp, float_matrix);
-          vkCmdPushConstants (command_buffer,
-                              gsk_vulkan_pipeline_get_pipeline_layout (pipeline),
-                              VK_SHADER_STAGE_VERTEX_BIT,
-                              0,
-                              sizeof (float_matrix),
-                              &float_matrix);
+        case GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS:
+          gsk_vulkan_push_constants_push_vertex (&op->constants,
+                                                 command_buffer, 
+                                                 gsk_vulkan_pipeline_get_pipeline_layout (pipeline));
+          break;
 
+        case GSK_VULKAN_OP_PUSH_FRAGMENT_CONSTANTS:
+          gsk_vulkan_push_constants_push_fragment (&op->constants,
+                                                   command_buffer, 
+                                                   gsk_vulkan_pipeline_get_pipeline_layout (pipeline));
           break;
 
         default:


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