diff options
Diffstat (limited to 'gsk')
-rw-r--r-- | gsk/Makefile.am | 2 | ||||
-rw-r--r-- | gsk/gskvulkanpipeline.c | 11 | ||||
-rw-r--r-- | gsk/gskvulkanpushconstants.c | 101 | ||||
-rw-r--r-- | gsk/gskvulkanpushconstantsprivate.h | 46 | ||||
-rw-r--r-- | gsk/gskvulkanrenderpass.c | 64 |
5 files changed, 188 insertions, 36 deletions
diff --git a/gsk/Makefile.am b/gsk/Makefile.am index f27cf2f744..395997035d 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 a0b43fdc9d..d1b1ed3138 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 0000000000..485ec8b36c --- /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 0000000000..37ac01f6ae --- /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 9b28951a23..527fb31f55 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: |