vulkan: Add infrastructure for multiple pipelines

And use it to draw solid colors with a 2nd pipeline.
This commit is contained in:
Benjamin Otte 2016-12-14 09:40:15 +01:00
parent 7d837a2ae6
commit 08a2a29c26
7 changed files with 102 additions and 8 deletions

View File

@ -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);

View File

@ -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,

View File

@ -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,

View File

@ -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;
}

Binary file not shown.

View File

@ -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;
}

Binary file not shown.