vulkan: Split PipelineLayout into its own object
This way, we can share the layout between different pipelines.
This commit is contained in:
@@ -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);
|
||||
self->layout = gsk_vulkan_pipeline_layout_ref (layout);
|
||||
|
||||
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);
|
||||
device = gdk_vulkan_context_get_device (layout->vulkan);
|
||||
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user