From b4f04d0c1dcc4d61ebdc9e3840fc3a3c6151c382 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sun, 18 Dec 2016 02:18:01 +0100 Subject: [PATCH] vulkan: Split color and blend pipelines --- gsk/Makefile.am | 2 + gsk/gskvulkancolorpipeline.c | 81 +++++++++++++++++++++++++++++ gsk/gskvulkancolorpipelineprivate.h | 31 +++++++++++ gsk/gskvulkanrender.c | 15 +++--- gsk/gskvulkanrenderpass.c | 46 ++++++++++++++-- 5 files changed, 165 insertions(+), 10 deletions(-) create mode 100644 gsk/gskvulkancolorpipeline.c create mode 100644 gsk/gskvulkancolorpipelineprivate.h diff --git a/gsk/Makefile.am b/gsk/Makefile.am index 5b41940fca..93480f6b8d 100644 --- a/gsk/Makefile.am +++ b/gsk/Makefile.am @@ -26,6 +26,7 @@ if HAVE_VULKAN gsk_private_vulan_source_h = \ gskvulkanblendpipelineprivate.h \ gskvulkanbufferprivate.h \ + gskvulkancolorpipelineprivate.h \ gskvulkancommandpoolprivate.h \ gskvulkanimageprivate.h \ gskvulkanmemoryprivate.h \ @@ -38,6 +39,7 @@ gsk_private_vulan_source_h = \ gsk_private_vulkan_source_c = \ gskvulkanblendpipeline.c \ gskvulkanbuffer.c \ + gskvulkancolorpipeline.c \ gskvulkancommandpool.c \ gskvulkanimage.c \ gskvulkanmemory.c \ diff --git a/gsk/gskvulkancolorpipeline.c b/gsk/gskvulkancolorpipeline.c new file mode 100644 index 0000000000..42a2c39496 --- /dev/null +++ b/gsk/gskvulkancolorpipeline.c @@ -0,0 +1,81 @@ +#include "config.h" + +#include "gskvulkancolorpipelineprivate.h" + +struct _GskVulkanColorPipeline +{ + GObject parent_instance; +}; + +typedef struct _GskVulkanVertex GskVulkanVertex; + +struct _GskVulkanVertex +{ + float x; + float y; + float tex_x; + float tex_y; +}; + +G_DEFINE_TYPE (GskVulkanColorPipeline, gsk_vulkan_color_pipeline, GSK_TYPE_VULKAN_PIPELINE) + +static void +gsk_vulkan_color_pipeline_finalize (GObject *gobject) +{ + //GskVulkanColorPipeline *self = GSK_VULKAN_COLOR_PIPELINE (gobject); + + G_OBJECT_CLASS (gsk_vulkan_color_pipeline_parent_class)->finalize (gobject); +} + +static void +gsk_vulkan_color_pipeline_class_init (GskVulkanColorPipelineClass *klass) +{ + G_OBJECT_CLASS (klass)->finalize = gsk_vulkan_color_pipeline_finalize; +} + +static void +gsk_vulkan_color_pipeline_init (GskVulkanColorPipeline *self) +{ +} + +GskVulkanPipeline * +gsk_vulkan_color_pipeline_new (GskVulkanPipelineLayout *layout, + const char *shader_name, + VkRenderPass render_pass) +{ + return gsk_vulkan_pipeline_new (GSK_TYPE_VULKAN_COLOR_PIPELINE, layout, shader_name, render_pass); +} + +gsize +gsk_vulkan_color_pipeline_count_vertex_data (GskVulkanColorPipeline *pipeline) +{ + return sizeof (GskVulkanVertex) * 6; +} + +void +gsk_vulkan_color_pipeline_collect_vertex_data (GskVulkanColorPipeline *pipeline, + guchar *data, + const graphene_rect_t *rect) +{ + GskVulkanVertex *vertices = (GskVulkanVertex *) data; + + vertices[0] = (GskVulkanVertex) { rect->origin.x, rect->origin.y, 0.0, 0.0 }; + vertices[1] = (GskVulkanVertex) { rect->origin.x + rect->size.width, rect->origin.y, 1.0, 0.0 }; + vertices[2] = (GskVulkanVertex) { rect->origin.x, rect->origin.y + rect->size.height, 0.0, 1.0 }; + vertices[3] = (GskVulkanVertex) { rect->origin.x, rect->origin.y + rect->size.height, 0.0, 1.0 }; + vertices[4] = (GskVulkanVertex) { rect->origin.x + rect->size.width, rect->origin.y, 1.0, 0.0 }; + vertices[5] = (GskVulkanVertex) { rect->origin.x + rect->size.width, rect->origin.y + rect->size.height, 1.0, 1.0 }; +} + +gsize +gsk_vulkan_color_pipeline_draw (GskVulkanColorPipeline *pipeline, + VkCommandBuffer command_buffer, + gsize offset, + gsize n_commands) +{ + vkCmdDraw (command_buffer, + n_commands * 6, 1, + offset, 0); + + return n_commands * 6; +} diff --git a/gsk/gskvulkancolorpipelineprivate.h b/gsk/gskvulkancolorpipelineprivate.h new file mode 100644 index 0000000000..4fbc22a44f --- /dev/null +++ b/gsk/gskvulkancolorpipelineprivate.h @@ -0,0 +1,31 @@ +#ifndef __GSK_VULKAN_COLOR_PIPELINE_PRIVATE_H__ +#define __GSK_VULKAN_COLOR_PIPELINE_PRIVATE_H__ + +#include + +#include "gskvulkanpipelineprivate.h" + +G_BEGIN_DECLS + +typedef struct _GskVulkanColorPipelineLayout GskVulkanColorPipelineLayout; + +#define GSK_TYPE_VULKAN_COLOR_PIPELINE (gsk_vulkan_color_pipeline_get_type ()) + +G_DECLARE_FINAL_TYPE (GskVulkanColorPipeline, gsk_vulkan_color_pipeline, GSK, VULKAN_COLOR_PIPELINE, GskVulkanPipeline) + +GskVulkanPipeline * gsk_vulkan_color_pipeline_new (GskVulkanPipelineLayout * layout, + const char *shader_name, + VkRenderPass render_pass); + +gsize gsk_vulkan_color_pipeline_count_vertex_data (GskVulkanColorPipeline *pipeline); +void gsk_vulkan_color_pipeline_collect_vertex_data (GskVulkanColorPipeline *pipeline, + guchar *data, + const graphene_rect_t *rect); +gsize gsk_vulkan_color_pipeline_draw (GskVulkanColorPipeline *pipeline, + VkCommandBuffer command_buffer, + gsize offset, + gsize n_commands); + +G_END_DECLS + +#endif /* __GSK_VULKAN_COLOR_PIPELINE_PRIVATE_H__ */ diff --git a/gsk/gskvulkanrender.c b/gsk/gskvulkanrender.c index 723e5018cb..05ca19c607 100644 --- a/gsk/gskvulkanrender.c +++ b/gsk/gskvulkanrender.c @@ -3,12 +3,14 @@ #include "gskvulkanrenderprivate.h" #include "gskrendererprivate.h" -#include "gskvulkanblendpipelineprivate.h" #include "gskvulkanbufferprivate.h" #include "gskvulkancommandpoolprivate.h" #include "gskvulkanpipelineprivate.h" #include "gskvulkanrenderpassprivate.h" +#include "gskvulkanblendpipelineprivate.h" +#include "gskvulkancolorpipelineprivate.h" + #define ORTHO_NEAR_PLANE -10000 #define ORTHO_FAR_PLANE 10000 @@ -290,18 +292,19 @@ gsk_vulkan_render_get_pipeline (GskVulkanRender *self, { static const struct { const char *name; + GskVulkanPipeline * (* create_func) (GskVulkanPipelineLayout *layout, const char *name, VkRenderPass render_pass); } pipeline_info[GSK_VULKAN_N_PIPELINES] = { - { "blit" }, - { "color" } + { "blit", gsk_vulkan_blend_pipeline_new }, + { "color", gsk_vulkan_color_pipeline_new } }; g_return_val_if_fail (type < GSK_VULKAN_N_PIPELINES, NULL); if (self->pipelines[type] == NULL) { - self->pipelines[type] = gsk_vulkan_blend_pipeline_new (self->layout, - pipeline_info[type].name, - self->render_pass); + self->pipelines[type] = pipeline_info[type].create_func (self->layout, + pipeline_info[type].name, + self->render_pass); } return self->pipelines[type]; diff --git a/gsk/gskvulkanrenderpass.c b/gsk/gskvulkanrenderpass.c index 0300cac093..337b6adbff 100644 --- a/gsk/gskvulkanrenderpass.c +++ b/gsk/gskvulkanrenderpass.c @@ -3,6 +3,7 @@ #include "gskvulkanrenderpassprivate.h" #include "gskvulkanblendpipelineprivate.h" +#include "gskvulkancolorpipelineprivate.h" #include "gskvulkanimageprivate.h" #include "gskrendernodeprivate.h" #include "gskrenderer.h" @@ -272,11 +273,15 @@ gsk_vulkan_render_pass_count_vertex_data (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_count = gsk_vulkan_blend_pipeline_count_vertex_data (GSK_VULKAN_BLEND_PIPELINE (op->render.pipeline)); n_bytes += op->render.vertex_count; break; + case GSK_VULKAN_OP_COLOR: + op->render.vertex_count = gsk_vulkan_color_pipeline_count_vertex_data (GSK_VULKAN_COLOR_PIPELINE (op->render.pipeline)); + n_bytes += op->render.vertex_count; + break; + default: g_assert_not_reached (); case GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS: @@ -308,7 +313,6 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self, case GSK_VULKAN_OP_FALLBACK: case GSK_VULKAN_OP_SURFACE: case GSK_VULKAN_OP_TEXTURE: - case GSK_VULKAN_OP_COLOR: { graphene_rect_t bounds; @@ -321,6 +325,19 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self, } break; + case GSK_VULKAN_OP_COLOR: + { + graphene_rect_t bounds; + + gsk_render_node_get_bounds (op->render.node, &bounds); + op->render.vertex_offset = offset + n_bytes; + gsk_vulkan_color_pipeline_collect_vertex_data (GSK_VULKAN_COLOR_PIPELINE (op->render.pipeline), + data + n_bytes + offset, + &bounds); + n_bytes += op->render.vertex_count; + } + break; + default: g_assert_not_reached (); case GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS: @@ -384,6 +401,22 @@ gsk_vulkan_render_pass_draw (GskVulkanRenderPass *self, case GSK_VULKAN_OP_FALLBACK: case GSK_VULKAN_OP_SURFACE: case GSK_VULKAN_OP_TEXTURE: + 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)); + vkCmdBindVertexBuffers (command_buffer, + 0, + 1, + (VkBuffer[1]) { + gsk_vulkan_buffer_get_buffer (vertex_buffer) + }, + (VkDeviceSize[1]) { op->render.vertex_offset }); + current_draw_index = 0; + } + vkCmdBindDescriptorSets (command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, gsk_vulkan_pipeline_layout_get_pipeline_layout (layout), @@ -394,7 +427,12 @@ gsk_vulkan_render_pass_draw (GskVulkanRenderPass *self, }, 0, NULL); - /* fall through */ + + current_draw_index += gsk_vulkan_blend_pipeline_draw (GSK_VULKAN_BLEND_PIPELINE (current_pipeline), + command_buffer, + current_draw_index, 1); + break; + case GSK_VULKAN_OP_COLOR: if (current_pipeline != op->render.pipeline) { @@ -412,7 +450,7 @@ gsk_vulkan_render_pass_draw (GskVulkanRenderPass *self, current_draw_index = 0; } - current_draw_index += gsk_vulkan_blend_pipeline_draw (GSK_VULKAN_BLEND_PIPELINE (current_pipeline), + current_draw_index += gsk_vulkan_color_pipeline_draw (GSK_VULKAN_COLOR_PIPELINE (current_pipeline), command_buffer, current_draw_index, 1); break;