1 #include "config.h"
2
3 #include "gskvulkanlineargradientpipelineprivate.h"
4
5 struct _GskVulkanLinearGradientPipeline
6 {
7 GObject parent_instance;
8 };
9
10 typedef struct _GskVulkanLinearGradientInstance GskVulkanLinearGradientInstance;
11
12 struct _GskVulkanLinearGradientInstance
13 {
14 float rect[4];
15 float start[2];
16 float end[2];
17 gint32 repeating;
18 gint32 stop_count;
19 float offsets[GSK_VULKAN_LINEAR_GRADIENT_PIPELINE_MAX_COLOR_STOPS];
20 float colors[GSK_VULKAN_LINEAR_GRADIENT_PIPELINE_MAX_COLOR_STOPS][4];
21 };
22
G_DEFINE_TYPE(GskVulkanLinearGradientPipeline,gsk_vulkan_linear_gradient_pipeline,GSK_TYPE_VULKAN_PIPELINE)23 G_DEFINE_TYPE (GskVulkanLinearGradientPipeline, gsk_vulkan_linear_gradient_pipeline, GSK_TYPE_VULKAN_PIPELINE)
24
25 static const VkPipelineVertexInputStateCreateInfo *
26 gsk_vulkan_linear_gradient_pipeline_get_input_state_create_info (GskVulkanPipeline *self)
27 {
28 static const VkVertexInputBindingDescription vertexBindingDescriptions[] = {
29 {
30 .binding = 0,
31 .stride = sizeof (GskVulkanLinearGradientInstance),
32 .inputRate = VK_VERTEX_INPUT_RATE_INSTANCE
33 }
34 };
35 static const VkVertexInputAttributeDescription vertexInputAttributeDescription[] = {
36 {
37 .location = 0,
38 .binding = 0,
39 .format = VK_FORMAT_R32G32B32A32_SFLOAT,
40 .offset = 0,
41 },
42 {
43 .location = 1,
44 .binding = 0,
45 .format = VK_FORMAT_R32G32_SFLOAT,
46 .offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, start),
47 },
48 {
49 .location = 2,
50 .binding = 0,
51 .format = VK_FORMAT_R32G32_SFLOAT,
52 .offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, end),
53 },
54 {
55 .location = 3,
56 .binding = 0,
57 .format = VK_FORMAT_R32_SINT,
58 .offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, repeating),
59 },
60 {
61 .location = 4,
62 .binding = 0,
63 .format = VK_FORMAT_R32_SINT,
64 .offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, stop_count),
65 },
66 {
67 .location = 5,
68 .binding = 0,
69 .format = VK_FORMAT_R32G32B32A32_SFLOAT,
70 .offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, offsets),
71 },
72 {
73 .location = 6,
74 .binding = 0,
75 .format = VK_FORMAT_R32G32B32A32_SFLOAT,
76 .offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, offsets) + sizeof (float) * 4,
77 },
78 {
79 .location = 7,
80 .binding = 0,
81 .format = VK_FORMAT_R32G32B32A32_SFLOAT,
82 .offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, colors[0]),
83 },
84 {
85 .location = 8,
86 .binding = 0,
87 .format = VK_FORMAT_R32G32B32A32_SFLOAT,
88 .offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, colors[1]),
89 },
90 {
91 .location = 9,
92 .binding = 0,
93 .format = VK_FORMAT_R32G32B32A32_SFLOAT,
94 .offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, colors[2]),
95 },
96 {
97 .location = 10,
98 .binding = 0,
99 .format = VK_FORMAT_R32G32B32A32_SFLOAT,
100 .offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, colors[3]),
101 },
102 {
103 .location = 11,
104 .binding = 0,
105 .format = VK_FORMAT_R32G32B32A32_SFLOAT,
106 .offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, colors[4]),
107 },
108 {
109 .location = 12,
110 .binding = 0,
111 .format = VK_FORMAT_R32G32B32A32_SFLOAT,
112 .offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, colors[5]),
113 },
114 {
115 .location = 13,
116 .binding = 0,
117 .format = VK_FORMAT_R32G32B32A32_SFLOAT,
118 .offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, colors[6]),
119 },
120 {
121 .location = 14,
122 .binding = 0,
123 .format = VK_FORMAT_R32G32B32A32_SFLOAT,
124 .offset = G_STRUCT_OFFSET (GskVulkanLinearGradientInstance, colors[7]),
125 }
126 };
127 static const VkPipelineVertexInputStateCreateInfo info = {
128 .sType = VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
129 .vertexBindingDescriptionCount = G_N_ELEMENTS (vertexBindingDescriptions),
130 .pVertexBindingDescriptions = vertexBindingDescriptions,
131 .vertexAttributeDescriptionCount = G_N_ELEMENTS (vertexInputAttributeDescription),
132 .pVertexAttributeDescriptions = vertexInputAttributeDescription
133 };
134
135 return &info;
136 }
137
138 static void
gsk_vulkan_linear_gradient_pipeline_finalize(GObject * gobject)139 gsk_vulkan_linear_gradient_pipeline_finalize (GObject *gobject)
140 {
141 //GskVulkanLinearGradientPipeline *self = GSK_VULKAN_LINEAR_GRADIENT_PIPELINE (gobject);
142
143 G_OBJECT_CLASS (gsk_vulkan_linear_gradient_pipeline_parent_class)->finalize (gobject);
144 }
145
146 static void
gsk_vulkan_linear_gradient_pipeline_class_init(GskVulkanLinearGradientPipelineClass * klass)147 gsk_vulkan_linear_gradient_pipeline_class_init (GskVulkanLinearGradientPipelineClass *klass)
148 {
149 GskVulkanPipelineClass *pipeline_class = GSK_VULKAN_PIPELINE_CLASS (klass);
150
151 G_OBJECT_CLASS (klass)->finalize = gsk_vulkan_linear_gradient_pipeline_finalize;
152
153 pipeline_class->get_input_state_create_info = gsk_vulkan_linear_gradient_pipeline_get_input_state_create_info;
154 }
155
156 static void
gsk_vulkan_linear_gradient_pipeline_init(GskVulkanLinearGradientPipeline * self)157 gsk_vulkan_linear_gradient_pipeline_init (GskVulkanLinearGradientPipeline *self)
158 {
159 }
160
161 GskVulkanPipeline *
gsk_vulkan_linear_gradient_pipeline_new(GdkVulkanContext * context,VkPipelineLayout layout,const char * shader_name,VkRenderPass render_pass)162 gsk_vulkan_linear_gradient_pipeline_new (GdkVulkanContext *context,
163 VkPipelineLayout layout,
164 const char *shader_name,
165 VkRenderPass render_pass)
166 {
167 return gsk_vulkan_pipeline_new (GSK_TYPE_VULKAN_LINEAR_GRADIENT_PIPELINE, context, layout, shader_name, render_pass);
168 }
169
170 gsize
gsk_vulkan_linear_gradient_pipeline_count_vertex_data(GskVulkanLinearGradientPipeline * pipeline)171 gsk_vulkan_linear_gradient_pipeline_count_vertex_data (GskVulkanLinearGradientPipeline *pipeline)
172 {
173 return sizeof (GskVulkanLinearGradientInstance);
174 }
175
176 void
gsk_vulkan_linear_gradient_pipeline_collect_vertex_data(GskVulkanLinearGradientPipeline * pipeline,guchar * data,const graphene_rect_t * rect,const graphene_point_t * start,const graphene_point_t * end,gboolean repeating,gsize n_stops,const GskColorStop * stops)177 gsk_vulkan_linear_gradient_pipeline_collect_vertex_data (GskVulkanLinearGradientPipeline *pipeline,
178 guchar *data,
179 const graphene_rect_t *rect,
180 const graphene_point_t *start,
181 const graphene_point_t *end,
182 gboolean repeating,
183 gsize n_stops,
184 const GskColorStop *stops)
185 {
186 GskVulkanLinearGradientInstance *instance = (GskVulkanLinearGradientInstance *) data;
187 gsize i;
188
189 if (n_stops > GSK_VULKAN_LINEAR_GRADIENT_PIPELINE_MAX_COLOR_STOPS)
190 {
191 g_warning ("Only %u color stops supported.", GSK_VULKAN_LINEAR_GRADIENT_PIPELINE_MAX_COLOR_STOPS);
192 n_stops = GSK_VULKAN_LINEAR_GRADIENT_PIPELINE_MAX_COLOR_STOPS;
193 }
194 instance->rect[0] = rect->origin.x;
195 instance->rect[1] = rect->origin.y;
196 instance->rect[2] = rect->size.width;
197 instance->rect[3] = rect->size.height;
198 instance->start[0] = start->x;
199 instance->start[1] = start->y;
200 instance->end[0] = end->x;
201 instance->end[1] = end->y;
202 instance->repeating = repeating;
203 instance->stop_count = n_stops;
204 for (i = 0; i < n_stops; i++)
205 {
206 instance->offsets[i] = stops[i].offset;
207 instance->colors[i][0] = stops[i].color.red;
208 instance->colors[i][1] = stops[i].color.green;
209 instance->colors[i][2] = stops[i].color.blue;
210 instance->colors[i][3] = stops[i].color.alpha;
211 }
212 }
213
214 gsize
gsk_vulkan_linear_gradient_pipeline_draw(GskVulkanLinearGradientPipeline * pipeline,VkCommandBuffer command_buffer,gsize offset,gsize n_commands)215 gsk_vulkan_linear_gradient_pipeline_draw (GskVulkanLinearGradientPipeline *pipeline,
216 VkCommandBuffer command_buffer,
217 gsize offset,
218 gsize n_commands)
219 {
220 vkCmdDraw (command_buffer,
221 6, n_commands,
222 0, offset);
223
224 return n_commands;
225 }
226