vulkan: Add infrastructure for push constants

THe code includes fragment push constants for colors, but that code is
so far unused.
This commit is contained in:
Benjamin Otte 2016-12-14 07:21:21 +01:00
parent 58b2c1d009
commit 62eb9d42aa
5 changed files with 188 additions and 36 deletions

View File

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

View File

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

View File

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

View File

@ -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__ */

View File

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