[gtk+/wip/otte/rendernode: 75/110] vulkan: Split PipelineLayout into its own object



commit f7717a965e1ea435db458992646bc0efa1247c56
Author: Benjamin Otte <otte redhat com>
Date:   Wed Dec 14 08:00:58 2016 +0100

    vulkan: Split PipelineLayout into its own object
    
    This way, we can share the layout between different pipelines.

 gsk/gskvulkanpipeline.c          |  151 +++++++++++++++++++++++++-------------
 gsk/gskvulkanpipelineprivate.h   |   21 ++++-
 gsk/gskvulkanrender.c            |   11 ++-
 gsk/gskvulkanrenderpass.c        |    8 +-
 gsk/gskvulkanrenderpassprivate.h |    2 +-
 5 files changed, 129 insertions(+), 64 deletions(-)
---
diff --git a/gsk/gskvulkanpipeline.c b/gsk/gskvulkanpipeline.c
index d1b1ed3..2888c62 100644
--- a/gsk/gskvulkanpipeline.c
+++ b/gsk/gskvulkanpipeline.c
@@ -7,15 +7,22 @@
 
 #include <graphene.h>
 
+struct _GskVulkanPipelineLayout
+{
+  volatile gint ref_count;
+  GdkVulkanContext *vulkan;
+
+  VkPipelineLayout pipeline_layout;
+  VkDescriptorSetLayout descriptor_set_layout;
+};
+
 struct _GskVulkanPipeline
 {
   GObject parent_instance;
 
-  GdkVulkanContext *vulkan;
+  GskVulkanPipelineLayout *layout;
 
   VkPipeline pipeline;
-  VkPipelineLayout pipeline_layout;
-  VkDescriptorSetLayout descriptor_set_layout;
 
   GskVulkanShader *vertex_shader;
   GskVulkanShader *fragment_shader;
@@ -27,7 +34,7 @@ static void
 gsk_vulkan_pipeline_finalize (GObject *gobject)
 {
   GskVulkanPipeline *self = GSK_VULKAN_PIPELINE (gobject);
-  VkDevice device = gdk_vulkan_context_get_device (self->vulkan);
+  VkDevice device = gdk_vulkan_context_get_device (self->layout->vulkan);
 
   vkDestroyPipeline (device,
                      self->pipeline,
@@ -36,15 +43,7 @@ gsk_vulkan_pipeline_finalize (GObject *gobject)
   g_clear_pointer (&self->fragment_shader, gsk_vulkan_shader_free);
   g_clear_pointer (&self->vertex_shader, gsk_vulkan_shader_free);
 
-  vkDestroyPipelineLayout (device,
-                           self->pipeline_layout,
-                           NULL);
-
-  vkDestroyDescriptorSetLayout (device,
-                                self->descriptor_set_layout,
-                                NULL);
-
-  g_clear_object (&self->vulkan);
+  g_clear_pointer (&self->layout, gsk_vulkan_pipeline_layout_unref);
 
   G_OBJECT_CLASS (gsk_vulkan_pipeline_parent_class)->finalize (gobject);
 }
@@ -61,50 +60,25 @@ gsk_vulkan_pipeline_init (GskVulkanPipeline *self)
 }
 
 GskVulkanPipeline *
-gsk_vulkan_pipeline_new (GdkVulkanContext *context,
-                         VkRenderPass      render_pass)
+gsk_vulkan_pipeline_new (GskVulkanPipelineLayout *layout,
+                         const char              *shader_name,
+                         VkRenderPass             render_pass)
 {
   GskVulkanPipeline *self;
   VkDevice device;
 
-  g_return_val_if_fail (GDK_IS_VULKAN_CONTEXT (context), NULL);
+  g_return_val_if_fail (layout != NULL, NULL);
+  g_return_val_if_fail (shader_name != NULL, NULL);
   g_return_val_if_fail (render_pass != VK_NULL_HANDLE, NULL);
 
-  device = gdk_vulkan_context_get_device (context);
-
   self = g_object_new (GSK_TYPE_VULKAN_PIPELINE, NULL);
 
-  self->vulkan = g_object_ref (context);
-
-  GSK_VK_CHECK (vkCreateDescriptorSetLayout, device,
-                                             &(VkDescriptorSetLayoutCreateInfo) {
-                                                 .sType = 
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
-                                                 .bindingCount = 1,
-                                                 .pBindings = (VkDescriptorSetLayoutBinding[1]) {
-                                                     {
-                                                         .binding = 0,
-                                                         .descriptorType = 
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
-                                                         .descriptorCount = 1,
-                                                         .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT
-                                                     }
-                                                 }
-                                             },
-                                             NULL,
-                                             &self->descriptor_set_layout);
+  self->layout = gsk_vulkan_pipeline_layout_ref (layout);
 
-  GSK_VK_CHECK (vkCreatePipelineLayout, device,
-                                        &(VkPipelineLayoutCreateInfo) {
-                                            .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
-                                            .setLayoutCount = 1,
-                                            .pSetLayouts = &self->descriptor_set_layout,
-                                            .pushConstantRangeCount = 
gst_vulkan_push_constants_get_range_count (),
-                                            .pPushConstantRanges = gst_vulkan_push_constants_get_ranges ()
-                                        },
-                                        NULL,
-                                        &self->pipeline_layout);
+  device = gdk_vulkan_context_get_device (layout->vulkan);
 
-  self->vertex_shader = gsk_vulkan_shader_new_from_resource (context, GSK_VULKAN_SHADER_VERTEX, "blit", 
NULL);
-  self->fragment_shader = gsk_vulkan_shader_new_from_resource (context, GSK_VULKAN_SHADER_FRAGMENT, "blit", 
NULL);
+  self->vertex_shader = gsk_vulkan_shader_new_from_resource (layout->vulkan, GSK_VULKAN_SHADER_VERTEX, 
shader_name, NULL);
+  self->fragment_shader = gsk_vulkan_shader_new_from_resource (layout->vulkan, GSK_VULKAN_SHADER_FRAGMENT, 
shader_name, NULL);
 
   GSK_VK_CHECK (vkCreateGraphicsPipelines, device,
                                            VK_NULL_HANDLE,
@@ -196,7 +170,7 @@ gsk_vulkan_pipeline_new (GdkVulkanContext *context,
                                                        VK_DYNAMIC_STATE_SCISSOR
                                                    },
                                                },
-                                               .layout = self->pipeline_layout,
+                                               .layout = gsk_vulkan_pipeline_layout_get_pipeline_layout 
(self->layout),
                                                .renderPass = render_pass,
                                                .subpass = 0,
                                                .basePipelineHandle = VK_NULL_HANDLE,
@@ -205,7 +179,6 @@ gsk_vulkan_pipeline_new (GdkVulkanContext *context,
                                            NULL,
                                            &self->pipeline);
 
-
   return self;
 }
 
@@ -215,14 +188,90 @@ gsk_vulkan_pipeline_get_pipeline (GskVulkanPipeline *self)
   return self->pipeline;
 }
 
+/*** GskVulkanPipelineLayout ***/
+
+GskVulkanPipelineLayout *
+gsk_vulkan_pipeline_layout_new (GdkVulkanContext *context)
+{
+  GskVulkanPipelineLayout *self;
+  VkDevice device;
+
+  self = g_slice_new0 (GskVulkanPipelineLayout);
+  self->ref_count = 1;
+  self->vulkan = g_object_ref (context);
+
+  device = gdk_vulkan_context_get_device (context);
+
+  GSK_VK_CHECK (vkCreateDescriptorSetLayout, device,
+                                             &(VkDescriptorSetLayoutCreateInfo) {
+                                                 .sType = 
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
+                                                 .bindingCount = 1,
+                                                 .pBindings = (VkDescriptorSetLayoutBinding[1]) {
+                                                     {
+                                                         .binding = 0,
+                                                         .descriptorType = 
VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
+                                                         .descriptorCount = 1,
+                                                         .stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT
+                                                     }
+                                                 }
+                                             },
+                                             NULL,
+                                             &self->descriptor_set_layout);
+
+  GSK_VK_CHECK (vkCreatePipelineLayout, device,
+                                        &(VkPipelineLayoutCreateInfo) {
+                                            .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
+                                            .setLayoutCount = 1,
+                                            .pSetLayouts = &self->descriptor_set_layout,
+                                            .pushConstantRangeCount = 
gst_vulkan_push_constants_get_range_count (),
+                                            .pPushConstantRanges = gst_vulkan_push_constants_get_ranges ()
+                                        },
+                                        NULL,
+                                        &self->pipeline_layout);
+
+  return self;
+}
+
+GskVulkanPipelineLayout *
+gsk_vulkan_pipeline_layout_ref (GskVulkanPipelineLayout *self)
+{
+  self->ref_count++;
+
+  return self;
+}
+
+void
+gsk_vulkan_pipeline_layout_unref (GskVulkanPipelineLayout *self)
+{
+  VkDevice device;
+
+  self->ref_count--;
+
+  if (self->ref_count > 0)
+    return;
+
+  device = gdk_vulkan_context_get_device (self->vulkan);
+
+  vkDestroyPipelineLayout (device,
+                           self->pipeline_layout,
+                           NULL);
+
+  vkDestroyDescriptorSetLayout (device,
+                                self->descriptor_set_layout,
+                                NULL);
+
+  g_slice_free (GskVulkanPipelineLayout, self);
+}
+
+
 VkPipelineLayout
-gsk_vulkan_pipeline_get_pipeline_layout (GskVulkanPipeline *self)
+gsk_vulkan_pipeline_layout_get_pipeline_layout (GskVulkanPipelineLayout *self)
 {
   return self->pipeline_layout;
 }
 
 VkDescriptorSetLayout
-gsk_vulkan_pipeline_get_descriptor_set_layout (GskVulkanPipeline *self)
+gsk_vulkan_pipeline_layout_get_descriptor_set_layout (GskVulkanPipelineLayout *self)
 {
   return self->descriptor_set_layout;
 }
diff --git a/gsk/gskvulkanpipelineprivate.h b/gsk/gskvulkanpipelineprivate.h
index 8395a2d..75a57db 100644
--- a/gsk/gskvulkanpipelineprivate.h
+++ b/gsk/gskvulkanpipelineprivate.h
@@ -7,6 +7,8 @@
 
 G_BEGIN_DECLS
 
+typedef struct _GskVulkanPipelineLayout GskVulkanPipelineLayout;
+
 #define GSK_TYPE_VULKAN_PIPELINE (gsk_vulkan_pipeline_get_type ())
 
 G_DECLARE_FINAL_TYPE (GskVulkanPipeline, gsk_vulkan_pipeline, GSK, VULKAN_PIPELINE, GObject)
@@ -24,12 +26,21 @@ gsk_vulkan_handle_result (VkResult    res,
 
 #define GSK_VK_CHECK(func, ...) gsk_vulkan_handle_result (func (__VA_ARGS__), G_STRINGIFY (func))
 
-GskVulkanPipeline *     gsk_vulkan_pipeline_new                         (GdkVulkanContext       *context,
-                                                                         VkRenderPass            
render_pass);
+GskVulkanPipelineLayout *       gsk_vulkan_pipeline_layout_new          (GdkVulkanContext               
*context);
+GskVulkanPipelineLayout *       gsk_vulkan_pipeline_layout_ref          (GskVulkanPipelineLayout        
*self);
+void                            gsk_vulkan_pipeline_layout_unref        (GskVulkanPipelineLayout        
*self);
+
+VkPipelineLayout                gsk_vulkan_pipeline_layout_get_pipeline_layout
+                                                                        (GskVulkanPipelineLayout        
*self);
+VkDescriptorSetLayout           gsk_vulkan_pipeline_layout_get_descriptor_set_layout
+                                                                        (GskVulkanPipelineLayout        
*self);
+
+
+GskVulkanPipeline *     gsk_vulkan_pipeline_new                         (GskVulkanPipelineLayout        
*layout,
+                                                                         const char                     
*shader_name,
+                                                                         VkRenderPass                    
render_pass);
 
-VkPipeline              gsk_vulkan_pipeline_get_pipeline                (GskVulkanPipeline      *self);
-VkPipelineLayout        gsk_vulkan_pipeline_get_pipeline_layout         (GskVulkanPipeline      *self);
-VkDescriptorSetLayout   gsk_vulkan_pipeline_get_descriptor_set_layout   (GskVulkanPipeline      *self);
+VkPipeline              gsk_vulkan_pipeline_get_pipeline                (GskVulkanPipeline              
*self);
 
 G_END_DECLS
 
diff --git a/gsk/gskvulkanrender.c b/gsk/gskvulkanrender.c
index 8727cde..1c27648 100644
--- a/gsk/gskvulkanrender.c
+++ b/gsk/gskvulkanrender.c
@@ -27,6 +27,7 @@ struct _GskVulkanRender
   VkCommandPool command_pool;
   VkFence fence;
   VkRenderPass render_pass;
+  GskVulkanPipelineLayout *layout;
 
   GHashTable *descriptor_set_indexes;
   VkDescriptorPool descriptor_pool;
@@ -161,7 +162,9 @@ gsk_vulkan_render_new (GskRenderer      *renderer,
                                       NULL,
                                       &self->render_pass);
 
-  self->pipeline = gsk_vulkan_pipeline_new (self->vulkan, self->render_pass);
+  self->layout = gsk_vulkan_pipeline_layout_new (self->vulkan);
+
+  self->pipeline = gsk_vulkan_pipeline_new (self->layout, "blit", self->render_pass);
 
   return self;
 }
@@ -369,7 +372,7 @@ gsk_vulkan_render_prepare_descriptor_sets (GskVulkanRender *self,
       VkDescriptorSetLayout layouts[needed_sets];
       for (i = 0; i < needed_sets; i++)
         {
-          layouts[i] = gsk_vulkan_pipeline_get_descriptor_set_layout (self->pipeline);
+          layouts[i] = gsk_vulkan_pipeline_layout_get_descriptor_set_layout (self->layout);
         }
       GSK_VK_CHECK (vkAllocateDescriptorSets, device,
                                               &(VkDescriptorSetAllocateInfo) {
@@ -466,7 +469,7 @@ gsk_vulkan_render_draw (GskVulkanRender   *self,
 
   for (l = self->render_passes; l; l = l->next)
     {
-      gsk_vulkan_render_pass_draw (l->data, self, self->pipeline, self->command_buffer);
+      gsk_vulkan_render_pass_draw (l->data, self, self->layout, self->command_buffer);
     }
 
   vkCmdEndRenderPass (self->command_buffer);
@@ -565,6 +568,8 @@ gsk_vulkan_render_free (GskVulkanRender *self)
 
   g_clear_object (&self->pipeline);
 
+  g_clear_pointer (&self->layout, gsk_vulkan_pipeline_layout_unref);
+
   vkDestroyRenderPass (device,
                        self->render_pass,
                        NULL);
diff --git a/gsk/gskvulkanrenderpass.c b/gsk/gskvulkanrenderpass.c
index f3de2f6..a786fbb 100644
--- a/gsk/gskvulkanrenderpass.c
+++ b/gsk/gskvulkanrenderpass.c
@@ -328,7 +328,7 @@ gsk_vulkan_render_pass_reserve_descriptor_sets (GskVulkanRenderPass *self,
 void
 gsk_vulkan_render_pass_draw (GskVulkanRenderPass     *self,
                              GskVulkanRender         *render,
-                             GskVulkanPipeline       *pipeline,
+                             GskVulkanPipelineLayout *layout,
                              VkCommandBuffer          command_buffer)
 {
   GskVulkanOp *op;
@@ -345,7 +345,7 @@ gsk_vulkan_render_pass_draw (GskVulkanRenderPass     *self,
         case GSK_VULKAN_OP_TEXTURE:
           vkCmdBindDescriptorSets (command_buffer,
                                    VK_PIPELINE_BIND_POINT_GRAPHICS,
-                                   gsk_vulkan_pipeline_get_pipeline_layout (pipeline),
+                                   gsk_vulkan_pipeline_layout_get_pipeline_layout (layout),
                                    0,
                                    1,
                                    (VkDescriptorSet[1]) {
@@ -362,13 +362,13 @@ gsk_vulkan_render_pass_draw (GskVulkanRenderPass     *self,
         case GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS:
           gsk_vulkan_push_constants_push_vertex (&op->constants.constants,
                                                  command_buffer, 
-                                                 gsk_vulkan_pipeline_get_pipeline_layout (pipeline));
+                                                 gsk_vulkan_pipeline_layout_get_pipeline_layout (layout));
           break;
 
         case GSK_VULKAN_OP_PUSH_FRAGMENT_CONSTANTS:
           gsk_vulkan_push_constants_push_fragment (&op->constants.constants,
                                                    command_buffer, 
-                                                   gsk_vulkan_pipeline_get_pipeline_layout (pipeline));
+                                                   gsk_vulkan_pipeline_layout_get_pipeline_layout (layout));
           break;
 
         default:
diff --git a/gsk/gskvulkanrenderpassprivate.h b/gsk/gskvulkanrenderpassprivate.h
index 5bb8d01..0ce7b8d 100644
--- a/gsk/gskvulkanrenderpassprivate.h
+++ b/gsk/gskvulkanrenderpassprivate.h
@@ -32,7 +32,7 @@ void                    gsk_vulkan_render_pass_reserve_descriptor_sets  (GskVulk
                                                                          GskVulkanRender        *render);
 void                    gsk_vulkan_render_pass_draw                     (GskVulkanRenderPass    *self,
                                                                          GskVulkanRender        *render,
-                                                                         GskVulkanPipeline      *pipeline,
+                                                                         GskVulkanPipelineLayout *layout,
                                                                          VkCommandBuffer         
command_buffer);
 
 G_END_DECLS


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