vulkan: Move vertex data tracking to the pipeline subclass

That way, different pipelines can draw different kinds of data.
This commit is contained in:
Benjamin Otte 2016-12-18 01:45:07 +01:00
parent 9aecd6dd56
commit e68b18aa4e
7 changed files with 141 additions and 77 deletions

View File

@ -7,7 +7,17 @@ struct _GskVulkanBlendPipeline
GObject parent_instance;
};
G_DEFINE_TYPE (GskVulkanBlendPipeline, gsk_vulkan_blend_pipeline, G_TYPE_OBJECT)
typedef struct _GskVulkanVertex GskVulkanVertex;
struct _GskVulkanVertex
{
float x;
float y;
float tex_x;
float tex_y;
};
G_DEFINE_TYPE (GskVulkanBlendPipeline, gsk_vulkan_blend_pipeline, GSK_TYPE_VULKAN_PIPELINE)
static void
gsk_vulkan_blend_pipeline_finalize (GObject *gobject)
@ -35,3 +45,37 @@ gsk_vulkan_blend_pipeline_new (GskVulkanPipelineLayout *layout,
{
return gsk_vulkan_pipeline_new (GSK_TYPE_VULKAN_BLEND_PIPELINE, layout, shader_name, render_pass);
}
gsize
gsk_vulkan_blend_pipeline_count_vertex_data (GskVulkanBlendPipeline *pipeline)
{
return sizeof (GskVulkanVertex) * 6;
}
void
gsk_vulkan_blend_pipeline_collect_vertex_data (GskVulkanBlendPipeline *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_blend_pipeline_draw (GskVulkanBlendPipeline *pipeline,
VkCommandBuffer command_buffer,
gsize offset,
gsize n_commands)
{
vkCmdDraw (command_buffer,
n_commands * 6, 1,
offset, 0);
return n_commands * 6;
}

View File

@ -1,7 +1,7 @@
#ifndef __GSK_VULKAN_BLEND_PIPELINE_PRIVATE_H__
#define __GSK_VULKAN_BLEND_PIPELINE_PRIVATE_H__
#include <gdk/gdk.h>
#include <graphene.h>
#include "gskvulkanpipelineprivate.h"
@ -17,6 +17,15 @@ GskVulkanPipeline * gsk_vulkan_blend_pipeline_new (GskVulk
const char *shader_name,
VkRenderPass render_pass);
gsize gsk_vulkan_blend_pipeline_count_vertex_data (GskVulkanBlendPipeline *pipeline);
void gsk_vulkan_blend_pipeline_collect_vertex_data (GskVulkanBlendPipeline *pipeline,
guchar *data,
const graphene_rect_t *rect);
gsize gsk_vulkan_blend_pipeline_draw (GskVulkanBlendPipeline *pipeline,
VkCommandBuffer command_buffer,
gsize offset,
gsize n_commands);
G_END_DECLS
#endif /* __GSK_VULKAN_BLEND_PIPELINE_PRIVATE_H__ */

View File

@ -73,7 +73,7 @@ gsk_vulkan_pipeline_new (GType pipeline_type,
VkDevice device;
g_return_val_if_fail (!g_type_is_a (pipeline_type, GSK_TYPE_VULKAN_PIPELINE), NULL);
g_return_val_if_fail (g_type_is_a (pipeline_type, GSK_TYPE_VULKAN_PIPELINE), NULL);
g_return_val_if_fail (layout != NULL, NULL);
g_return_val_if_fail (shader_name != NULL, NULL);
g_return_val_if_fail (render_pass != VK_NULL_HANDLE, NULL);

View File

@ -246,37 +246,37 @@ gsk_vulkan_render_upload (GskVulkanRender *self)
}
static gsize
gsk_vulkan_renderer_count_vertices (GskVulkanRender *self)
gsk_vulkan_renderer_count_vertex_data (GskVulkanRender *self)
{
gsize count;
gsize n_bytes;
GSList *l;
count = 0;
n_bytes = 0;
for (l = self->render_passes; l; l = l->next)
{
count += gsk_vulkan_render_pass_count_vertices (l->data);
n_bytes += gsk_vulkan_render_pass_count_vertex_data (l->data);
}
return count;
return n_bytes;
}
static GskVulkanBuffer *
gsk_vulkan_render_collect_vertices (GskVulkanRender *self)
gsk_vulkan_render_collect_vertex_data (GskVulkanRender *self)
{
GskVulkanBuffer *buffer;
GskVulkanVertex *vertices;
guchar *data;
GSList *l;
gsize offset, count;
gsize offset, n_bytes;
offset = 0;
count = gsk_vulkan_renderer_count_vertices (self);
buffer = gsk_vulkan_buffer_new (self->vulkan, sizeof (GskVulkanVertex) * count);
vertices = (GskVulkanVertex *) gsk_vulkan_buffer_map (buffer);
n_bytes = gsk_vulkan_renderer_count_vertex_data (self);
buffer = gsk_vulkan_buffer_new (self->vulkan, n_bytes);
data = gsk_vulkan_buffer_map (buffer);
for (l = self->render_passes; l; l = l->next)
{
offset += gsk_vulkan_render_pass_collect_vertices (l->data, vertices, offset, count - offset);
g_assert (offset <= count);
offset += gsk_vulkan_render_pass_collect_vertex_data (l->data, data, offset, n_bytes - offset);
g_assert (offset <= n_bytes);
}
gsk_vulkan_buffer_unmap (buffer);
@ -441,7 +441,7 @@ gsk_vulkan_render_draw (GskVulkanRender *self,
command_buffer = gsk_vulkan_command_pool_get_buffer (self->command_pool);
buffer = gsk_vulkan_render_collect_vertices (self);
buffer = gsk_vulkan_render_collect_vertex_data (self);
vkCmdSetViewport (command_buffer,
0,
@ -476,17 +476,9 @@ gsk_vulkan_render_draw (GskVulkanRender *self,
},
VK_SUBPASS_CONTENTS_INLINE);
vkCmdBindVertexBuffers (command_buffer,
0,
1,
(VkBuffer[1]) {
gsk_vulkan_buffer_get_buffer (buffer)
},
(VkDeviceSize[1]) { 0 });
for (l = self->render_passes; l; l = l->next)
{
gsk_vulkan_render_pass_draw (l->data, self, self->layout, command_buffer);
gsk_vulkan_render_pass_draw (l->data, self, buffer, self->layout, command_buffer);
}
vkCmdEndRenderPass (command_buffer);

View File

@ -2,6 +2,7 @@
#include "gskvulkanrenderpassprivate.h"
#include "gskvulkanblendpipelineprivate.h"
#include "gskvulkanimageprivate.h"
#include "gskrendernodeprivate.h"
#include "gskrenderer.h"
@ -255,40 +256,13 @@ gsk_vulkan_render_pass_upload (GskVulkanRenderPass *self,
}
gsize
gsk_vulkan_render_pass_count_vertices (GskVulkanRenderPass *self)
{
return self->render_ops->len * 6;
}
static gsize
gsk_vulkan_render_op_collect_vertices (GskVulkanOpRender *op,
GskVulkanVertex *vertices)
{
graphene_rect_t bounds;
gsk_render_node_get_bounds (op->node, &bounds);
vertices[0] = (GskVulkanVertex) { bounds.origin.x, bounds.origin.y, 0.0, 0.0 };
vertices[1] = (GskVulkanVertex) { bounds.origin.x + bounds.size.width, bounds.origin.y, 1.0, 0.0 };
vertices[2] = (GskVulkanVertex) { bounds.origin.x, bounds.origin.y + bounds.size.height, 0.0, 1.0 };
vertices[3] = (GskVulkanVertex) { bounds.origin.x, bounds.origin.y + bounds.size.height, 0.0, 1.0 };
vertices[4] = (GskVulkanVertex) { bounds.origin.x + bounds.size.width, bounds.origin.y, 1.0, 0.0 };
vertices[5] = (GskVulkanVertex) { bounds.origin.x + bounds.size.width, bounds.origin.y + bounds.size.height, 1.0, 1.0 };
return 6;
}
gsize
gsk_vulkan_render_pass_collect_vertices (GskVulkanRenderPass *self,
GskVulkanVertex *vertices,
gsize offset,
gsize total)
gsk_vulkan_render_pass_count_vertex_data (GskVulkanRenderPass *self)
{
GskVulkanOp *op;
gsize n;
gsize n_bytes;
guint i;
n = 0;
n_bytes = 0;
for (i = 0; i < self->render_ops->len; i++)
{
op = &g_array_index (self->render_ops, GskVulkanOp, i);
@ -299,8 +273,52 @@ gsk_vulkan_render_pass_collect_vertices (GskVulkanRenderPass *self,
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);
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;
default:
g_assert_not_reached ();
case GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS:
case GSK_VULKAN_OP_PUSH_FRAGMENT_CONSTANTS:
continue;
}
}
return n_bytes;
}
gsize
gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self,
guchar *data,
gsize offset,
gsize total)
{
GskVulkanOp *op;
gsize n_bytes;
guint i;
n_bytes = 0;
for (i = 0; i < self->render_ops->len; i++)
{
op = &g_array_index (self->render_ops, GskVulkanOp, i);
switch (op->type)
{
case GSK_VULKAN_OP_FALLBACK:
case GSK_VULKAN_OP_SURFACE:
case GSK_VULKAN_OP_TEXTURE:
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_blend_pipeline_collect_vertex_data (GSK_VULKAN_BLEND_PIPELINE (op->render.pipeline),
data + n_bytes + offset,
&bounds);
n_bytes += op->render.vertex_count;
}
break;
default:
@ -310,11 +328,10 @@ gsk_vulkan_render_pass_collect_vertices (GskVulkanRenderPass *self,
continue;
}
n += op->render.vertex_count;
g_assert (n + offset <= total);
g_assert (n_bytes + offset <= total);
}
return n;
return n_bytes;
}
void
@ -349,10 +366,12 @@ gsk_vulkan_render_pass_reserve_descriptor_sets (GskVulkanRenderPass *self,
void
gsk_vulkan_render_pass_draw (GskVulkanRenderPass *self,
GskVulkanRender *render,
GskVulkanBuffer *vertex_buffer,
GskVulkanPipelineLayout *layout,
VkCommandBuffer command_buffer)
{
GskVulkanPipeline *current_pipeline = NULL;
gsize current_draw_index = 0;
GskVulkanOp *op;
guint i;
@ -383,11 +402,19 @@ gsk_vulkan_render_pass_draw (GskVulkanRenderPass *self,
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;
}
vkCmdDraw (command_buffer,
op->render.vertex_count, 1,
op->render.vertex_offset, 0);
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_PUSH_VERTEX_CONSTANTS:

View File

@ -4,7 +4,7 @@
#include <gdk/gdk.h>
#include <gsk/gskrendernode.h>
#include "gsk/gskvulkancommandpoolprivate.h"
#include "gsk/gskvulkanbufferprivate.h"
#include "gsk/gskvulkanrenderprivate.h"
G_BEGIN_DECLS
@ -23,9 +23,9 @@ void gsk_vulkan_render_pass_upload (GskVulk
GskVulkanRender *render,
GskVulkanUploader *uploader);
gsize gsk_vulkan_render_pass_count_vertices (GskVulkanRenderPass *self);
gsize gsk_vulkan_render_pass_collect_vertices (GskVulkanRenderPass *self,
GskVulkanVertex *vertices,
gsize gsk_vulkan_render_pass_count_vertex_data (GskVulkanRenderPass *self);
gsize gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self,
guchar *data,
gsize offset,
gsize total);
@ -33,6 +33,7 @@ void gsk_vulkan_render_pass_reserve_descriptor_sets (GskVulk
GskVulkanRender *render);
void gsk_vulkan_render_pass_draw (GskVulkanRenderPass *self,
GskVulkanRender *render,
GskVulkanBuffer *vertex_buffer,
GskVulkanPipelineLayout *layout,
VkCommandBuffer command_buffer);

View File

@ -17,15 +17,6 @@ typedef enum {
} GskVulkanPipelineType;
typedef struct _GskVulkanRender GskVulkanRender;
typedef struct _GskVulkanVertex GskVulkanVertex;
struct _GskVulkanVertex
{
float x;
float y;
float tex_x;
float tex_y;
};
GskVulkanRender * gsk_vulkan_render_new (GskRenderer *renderer,
GdkVulkanContext *context);