[gtk+/wip/otte/vulkan: 9/28] vulkan: Add GskVulkanRenderPass
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/otte/vulkan: 9/28] vulkan: Add GskVulkanRenderPass
- Date: Fri, 9 Dec 2016 06:27:48 +0000 (UTC)
commit 8a4e4079271d213a0a5827765f3e73bec78261fc
Author: Benjamin Otte <otte redhat com>
Date: Thu Dec 8 13:26:36 2016 +0100
vulkan: Add GskVulkanRenderPass
And move the actual rendering code there.
A RenderPass is a collection of operations on the same target that
get executed one after another. It roughly targets VkRenderPass or
rather the subpasses of a VkRenderPass.
For now, only the infrastructure is there. No real stuff is happening.
gsk/Makefile.am | 2 +
gsk/gskvulkanrender.c | 200 ++++++++++++++++++++++++++++++++
gsk/gskvulkanrenderer.c | 202 ++-------------------------------
gsk/gskvulkanrenderpass.c | 233 ++++++++++++++++++++++++++++++++++++++
gsk/gskvulkanrenderpassprivate.h | 37 ++++++
gsk/gskvulkanrenderprivate.h | 42 +++++++-
6 files changed, 520 insertions(+), 196 deletions(-)
---
diff --git a/gsk/Makefile.am b/gsk/Makefile.am
index bde8dbe..32f37d3 100644
--- a/gsk/Makefile.am
+++ b/gsk/Makefile.am
@@ -30,6 +30,7 @@ gsk_private_vulan_source_h = \
gskvulkanpipelineprivate.h \
gskvulkanrenderprivate.h \
gskvulkanrendererprivate.h \
+ gskvulkanrenderpassprivate.h \
gskvulkanshaderprivate.h
gsk_private_vulkan_source_c = \
gskvulkanbuffer.c \
@@ -38,6 +39,7 @@ gsk_private_vulkan_source_c = \
gskvulkanpipeline.c \
gskvulkanrender.c \
gskvulkanrenderer.c \
+ gskvulkanrenderpass.c \
gskvulkanshader.c
endif
diff --git a/gsk/gskvulkanrender.c b/gsk/gskvulkanrender.c
index 3dff0bf..c57e701 100644
--- a/gsk/gskvulkanrender.c
+++ b/gsk/gskvulkanrender.c
@@ -2,16 +2,56 @@
#include "gskvulkanrenderprivate.h"
+#include "gskrendererprivate.h"
+#include "gskvulkanbufferprivate.h"
#include "gskvulkanpipelineprivate.h"
+#include "gskvulkanrenderpassprivate.h"
+
+#define ORTHO_NEAR_PLANE -10000
+#define ORTHO_FAR_PLANE 10000
+
+static void
+gsk_vulkan_render_compute_mvp (GskVulkanRender *self)
+{
+ GdkWindow *window = gsk_renderer_get_window (self->renderer);
+ graphene_matrix_t modelview, projection;
+ cairo_rectangle_int_t extents;
+
+ cairo_region_get_extents (gdk_drawing_context_get_clip (gsk_renderer_get_drawing_context (self->renderer)),
+ &extents);
+
+ self->scale_factor = gsk_renderer_get_scale_factor (self->renderer);
+ self->size.width = gdk_window_get_width (window) * self->scale_factor;
+ self->size.height = gdk_window_get_height (window) * self->scale_factor;
+ self->scissor.offset.x = extents.x * self->scale_factor;
+ self->scissor.offset.y = extents.y * self->scale_factor;
+ self->scissor.extent.width = extents.width * self->scale_factor;
+ self->scissor.extent.height = extents.height * self->scale_factor;
+
+ graphene_matrix_init_scale (&modelview, self->scale_factor, self->scale_factor, 1.0);
+ graphene_matrix_init_ortho (&projection,
+ 0, self->size.width,
+ 0, self->size.height,
+ ORTHO_NEAR_PLANE,
+ ORTHO_FAR_PLANE);
+ graphene_matrix_multiply (&modelview, &projection, &self->mvp);
+}
void
gsk_vulkan_render_init (GskVulkanRender *self,
+ GskRenderer *renderer,
GdkVulkanContext *context,
VkCommandPool command_pool)
{
self->vulkan = context;
+ self->renderer = renderer;
self->command_pool = command_pool;
+ self->render_passes = NULL;
+ self->cleanup_images = NULL;
+
+ gsk_vulkan_render_compute_mvp (self);
+
GSK_VK_CHECK (vkAllocateCommandBuffers, gdk_vulkan_context_get_device (self->vulkan),
&(VkCommandBufferAllocateInfo) {
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
@@ -29,6 +69,163 @@ gsk_vulkan_render_init (GskVulkanRender *self,
}
void
+gsk_vulkan_render_add_cleanup_image (GskVulkanRender *self,
+ GskVulkanImage *image)
+{
+ self->cleanup_images = g_slist_prepend (self->cleanup_images, image);
+}
+
+void
+gsk_vulkan_render_add_node (GskVulkanRender *self,
+ GskRenderNode *node)
+{
+ GskVulkanRenderPass *pass = gsk_vulkan_render_pass_new (self->vulkan);
+
+ self->render_passes = g_slist_prepend (self->render_passes, pass);
+
+ gsk_vulkan_render_pass_add_node (pass, self, node);
+}
+
+void
+gsk_vulkan_render_upload (GskVulkanRender *self)
+{
+ GSList *l;
+
+ for (l = self->render_passes; l; l = l->next)
+ {
+ gsk_vulkan_render_pass_upload (l->data, self);
+ }
+}
+
+static gsize
+gsk_vulkan_renderer_count_vertices (GskVulkanRender *self)
+{
+ gsize count;
+ GSList *l;
+
+ count = 0;
+ for (l = self->render_passes; l; l = l->next)
+ {
+ count += gsk_vulkan_render_pass_count_vertices (l->data);
+ }
+
+ return count;
+}
+
+static GskVulkanBuffer *
+gsk_vulkan_render_collect_vertices (GskVulkanRender *self)
+{
+ GskVulkanBuffer *buffer;
+ GskVulkanVertex *vertices;
+ GSList *l;
+ gsize offset, count;
+
+ 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);
+
+ 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);
+ }
+
+ gsk_vulkan_buffer_unmap (buffer);
+
+ return buffer;
+}
+
+void
+gsk_vulkan_render_draw (GskVulkanRender *self,
+ GskVulkanPipeline *pipeline,
+ VkRenderPass render_pass,
+ VkFramebuffer framebuffer,
+ VkDescriptorSet descriptor_set,
+ VkSampler sampler)
+{
+ GskVulkanBuffer *buffer;
+ GSList *l;
+
+ buffer = gsk_vulkan_render_collect_vertices (self);
+
+ for (l = self->render_passes; l; l = l->next)
+ {
+ gsk_vulkan_render_pass_update_descriptor_sets (l->data, descriptor_set, sampler);
+ }
+
+ vkCmdSetViewport (self->command_buffer,
+ 0,
+ 1,
+ &(VkViewport) {
+ .x = 0,
+ .y = 0,
+ .width = self->size.width,
+ .height = self->size.height,
+ .minDepth = 0,
+ .maxDepth = 1
+ });
+
+ vkCmdSetScissor (self->command_buffer,
+ 0,
+ 1,
+ &self->scissor);
+
+ vkCmdBeginRenderPass (self->command_buffer,
+ &(VkRenderPassBeginInfo) {
+ .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
+ .renderPass = render_pass,
+ .framebuffer = framebuffer,
+ .renderArea = {
+ { 0, 0 },
+ { self->size.width, self->size.height }
+ },
+ .clearValueCount = 1,
+ .pClearValues = (VkClearValue [1]) {
+ { .color = { .float32 = { 0.f, 0.f, 0.f, 0.f } } }
+ }
+ },
+ VK_SUBPASS_CONTENTS_INLINE);
+
+ vkCmdBindPipeline (self->command_buffer,
+ VK_PIPELINE_BIND_POINT_GRAPHICS,
+ gsk_vulkan_pipeline_get_pipeline (pipeline));
+
+ vkCmdBindDescriptorSets (self->command_buffer,
+ VK_PIPELINE_BIND_POINT_GRAPHICS,
+ gsk_vulkan_pipeline_get_pipeline_layout (pipeline),
+ 0,
+ 1,
+ &descriptor_set,
+ 0,
+ NULL);
+
+ vkCmdBindVertexBuffers (self->command_buffer,
+ 0,
+ 1,
+ (VkBuffer[1]) {
+ gsk_vulkan_buffer_get_buffer (buffer)
+ },
+ (VkDeviceSize[1]) { 0 });
+
+ vkCmdPushConstants (self->command_buffer,
+ gsk_vulkan_pipeline_get_pipeline_layout (pipeline),
+ VK_SHADER_STAGE_VERTEX_BIT,
+ 0,
+ sizeof (graphene_matrix_t),
+ &self->mvp);
+
+ for (l = self->render_passes; l; l = l->next)
+ {
+ gsk_vulkan_render_pass_draw (l->data, self);
+ }
+
+ vkCmdEndRenderPass (self->command_buffer);
+
+ gsk_vulkan_buffer_free (buffer);
+}
+
+void
gsk_vulkan_render_submit (GskVulkanRender *self,
VkFence fence)
{
@@ -66,4 +263,7 @@ gsk_vulkan_render_finish (GskVulkanRender *self)
GSK_VK_CHECK (vkResetCommandPool, gdk_vulkan_context_get_device (self->vulkan),
self->command_pool,
0);
+
+ g_slist_free_full (self->render_passes, (GDestroyNotify) gsk_vulkan_render_pass_free);
+ g_slist_free_full (self->cleanup_images, (GDestroyNotify) gsk_vulkan_image_free);
}
diff --git a/gsk/gskvulkanrenderer.c b/gsk/gskvulkanrenderer.c
index 9856f3f..8bf422e 100644
--- a/gsk/gskvulkanrenderer.c
+++ b/gsk/gskvulkanrenderer.c
@@ -332,201 +332,12 @@ gsk_vulkan_renderer_unrealize (GskRenderer *renderer)
g_clear_object (&self->vulkan);
}
-static GskVulkanImage *
-gsk_vulkan_renderer_prepare_render (GskVulkanRenderer *self,
- VkCommandBuffer command_buffer,
- GskRenderNode *root)
-{
- GdkWindow *window;
- GskRenderer *fallback;
- GskVulkanImage *image;
- cairo_surface_t *surface;
- cairo_t *cr;
-
- window = gsk_renderer_get_window (GSK_RENDERER (self));
- surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
- gdk_window_get_width (window),
- gdk_window_get_height (window));
- cr = cairo_create (surface);
- fallback = gsk_renderer_create_fallback (GSK_RENDERER (self),
- &GRAPHENE_RECT_INIT(
- 0, 0,
- gdk_window_get_width (window),
- gdk_window_get_height (window)
- ),
- cr);
-
- gsk_renderer_render (fallback, root, NULL);
- g_object_unref (fallback);
-
- cairo_destroy (cr);
-
- image = gsk_vulkan_image_new_from_data (self->vulkan,
- command_buffer,
- cairo_image_surface_get_data (surface),
- cairo_image_surface_get_width (surface),
- cairo_image_surface_get_height (surface),
- cairo_image_surface_get_stride (surface));
- cairo_surface_destroy (surface);
-
- return image;
-}
-
-static void
-gsk_vulkan_renderer_do_render_commands (GskVulkanRenderer *self,
- VkCommandBuffer command_buffer)
-{
- GskVulkanBuffer *buffer;
- GdkWindow *window = gsk_renderer_get_window (GSK_RENDERER (self));
- int width = gdk_window_get_width (window);
- int height = gdk_window_get_height (window);
- float pts[] = {
- 0.0, 0.0, 0.0, 0.0,
- width, 0.0, 1.0, 0.0,
- 0.0, height, 0.0, 1.0,
-
- 0.0, height, 0.0, 1.0,
- width, 0.0, 1.0, 0.0,
- width, height, 1.0, 1.0
- };
- guchar *data;
-
- buffer = gsk_vulkan_buffer_new (self->vulkan, sizeof (pts));
-
- data = gsk_vulkan_buffer_map (buffer);
- memcpy (data, pts, sizeof (pts));
- gsk_vulkan_buffer_unmap (buffer);
-
- vkCmdBindPipeline (command_buffer,
- VK_PIPELINE_BIND_POINT_GRAPHICS,
- gsk_vulkan_pipeline_get_pipeline (self->pipeline));
-
- vkCmdBindDescriptorSets (command_buffer,
- VK_PIPELINE_BIND_POINT_GRAPHICS,
- gsk_vulkan_pipeline_get_pipeline_layout (self->pipeline),
- 0,
- 1,
- &self->descriptor_set,
- 0,
- NULL);
-
- vkCmdBindVertexBuffers (command_buffer,
- 0,
- 1,
- (VkBuffer[1]) {
- gsk_vulkan_buffer_get_buffer (buffer)
- },
- (VkDeviceSize[1]) { 0 });
-
- vkCmdDraw (command_buffer,
- 6, 1,
- 0, 0);
-
- gsk_vulkan_buffer_free (buffer);
-}
-
-#define ORTHO_NEAR_PLANE -10000
-#define ORTHO_FAR_PLANE 10000
-
-static void
-gsk_vulkan_renderer_do_render_pass (GskVulkanRenderer *self,
- VkCommandBuffer command_buffer,
- GskVulkanImage *image)
-{
- GdkRectangle extents;
- GdkWindow *window;
- int scale_factor, unscaled_width, unscaled_height;
- graphene_matrix_t modelview, projection, mvp;
-
- window = gsk_renderer_get_window (GSK_RENDERER (self));
- cairo_region_get_extents (gdk_drawing_context_get_clip (gsk_renderer_get_drawing_context (GSK_RENDERER
(self))),
- &extents);
- scale_factor = gsk_renderer_get_scale_factor (GSK_RENDERER (self));
- unscaled_width = gdk_window_get_width (window) * scale_factor;
- unscaled_height = gdk_window_get_height (window) * scale_factor;
-
- vkUpdateDescriptorSets (gdk_vulkan_context_get_device (self->vulkan),
- 1,
- (VkWriteDescriptorSet[1]) {
- {
- .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
- .dstSet = self->descriptor_set,
- .dstBinding = 0,
- .dstArrayElement = 0,
- .descriptorCount = 1,
- .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
- .pImageInfo = &(VkDescriptorImageInfo) {
- .sampler = self->sampler,
- .imageView = gsk_vulkan_image_get_image_view (image),
- .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
- }
- }
- },
- 0, NULL);
-
- vkCmdBeginRenderPass (command_buffer,
- &(VkRenderPassBeginInfo) {
- .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
- .renderPass = self->render_pass,
- .framebuffer = self->targets[gdk_vulkan_context_get_draw_index
(self->vulkan)]->framebuffer,
- .renderArea = {
- { 0, 0 },
- { unscaled_width, unscaled_height }
- },
- .clearValueCount = 1,
- .pClearValues = (VkClearValue [1]) {
- { .color = { .float32 = { 0.f, 0.f, 0.f, 0.f } } }
- }
- },
- VK_SUBPASS_CONTENTS_INLINE);
-
- vkCmdSetViewport (command_buffer,
- 0,
- 1,
- &(VkViewport) {
- .x = 0,
- .y = 0,
- .width = unscaled_width,
- .height = unscaled_height,
- .minDepth = 0,
- .maxDepth = 1
- });
-
- vkCmdSetScissor (command_buffer,
- 0,
- 1,
- &(VkRect2D) {
- { extents.x * scale_factor, extents.y * scale_factor },
- { extents.width * scale_factor, extents.height * scale_factor }
- });
-
- graphene_matrix_init_scale (&modelview, scale_factor, scale_factor, 1.0);
- graphene_matrix_init_ortho (&projection,
- 0, unscaled_width,
- 0, unscaled_height,
- ORTHO_NEAR_PLANE,
- ORTHO_FAR_PLANE);
- graphene_matrix_multiply (&modelview, &projection, &mvp);
-
- vkCmdPushConstants (command_buffer,
- gsk_vulkan_pipeline_get_pipeline_layout (self->pipeline),
- VK_SHADER_STAGE_VERTEX_BIT,
- 0,
- sizeof (graphene_matrix_t),
- &mvp);
-
- gsk_vulkan_renderer_do_render_commands (self, command_buffer);
-
- vkCmdEndRenderPass (command_buffer);
-}
-
static void
gsk_vulkan_renderer_render (GskRenderer *renderer,
GskRenderNode *root)
{
GskVulkanRenderer *self = GSK_VULKAN_RENDERER (renderer);
GskVulkanRender render;
- GskVulkanImage *image;
#ifdef G_ENABLE_DEBUG
GskProfiler *profiler;
gint64 cpu_time;
@@ -537,15 +348,18 @@ gsk_vulkan_renderer_render (GskRenderer *renderer,
gsk_profiler_timer_begin (profiler, self->profile_timers.cpu_time);
#endif
- gsk_vulkan_render_init (&render, self->vulkan, self->command_pool);
+ gsk_vulkan_render_init (&render, renderer, self->vulkan, self->command_pool);
- image = gsk_vulkan_renderer_prepare_render (self, render.command_buffer, root);
+ gsk_vulkan_render_add_node (&render, root);
- gsk_vulkan_renderer_do_render_pass (self, render.command_buffer, image);
+ gsk_vulkan_render_upload (&render);
- gsk_vulkan_render_submit (&render, self->command_pool_fence);
+ gsk_vulkan_render_draw (&render, self->pipeline,
+ self->render_pass,
+ self->targets[gdk_vulkan_context_get_draw_index (self->vulkan)]->framebuffer,
+ self->descriptor_set, self->sampler);
- gsk_vulkan_image_free (image);
+ gsk_vulkan_render_submit (&render, self->command_pool_fence);
gsk_vulkan_render_finish (&render);
diff --git a/gsk/gskvulkanrenderpass.c b/gsk/gskvulkanrenderpass.c
new file mode 100644
index 0000000..373bc6c
--- /dev/null
+++ b/gsk/gskvulkanrenderpass.c
@@ -0,0 +1,233 @@
+#include "config.h"
+
+#include "gskvulkanrenderpassprivate.h"
+
+#include "gskvulkanimageprivate.h"
+#include "gskrendernodeprivate.h"
+#include "gskrenderer.h"
+
+typedef struct _GskVulkanRenderOp GskVulkanRenderOp;
+
+typedef enum {
+ GSK_VULKAN_OP_FALLBACK
+} GskVulkanOpType;
+
+struct _GskVulkanRenderOp
+{
+ GskVulkanOpType type;
+ GskRenderNode *node; /* node that's the source of this op */
+ GskVulkanRenderPass *pass; /* render pass required to set up node */
+ GskVulkanImage *source; /* source image to render */
+ gsize vertex_offset; /* offset into vertex buffer */
+ gsize vertex_count; /* number of vertices */
+};
+
+struct _GskVulkanRenderPass
+{
+ GdkVulkanContext *vulkan;
+
+ GArray *render_ops;
+};
+
+GskVulkanRenderPass *
+gsk_vulkan_render_pass_new (GdkVulkanContext *context)
+{
+ GskVulkanRenderPass *self;
+
+ self = g_slice_new0 (GskVulkanRenderPass);
+ self->vulkan = g_object_ref (context);
+ self->render_ops = g_array_new (FALSE, FALSE, sizeof (GskVulkanRenderOp));
+
+ return self;
+}
+
+void
+gsk_vulkan_render_pass_free (GskVulkanRenderPass *self)
+{
+ g_array_unref (self->render_ops);
+ g_object_unref (self->vulkan);
+
+ g_slice_free (GskVulkanRenderPass, self);
+}
+
+void
+gsk_vulkan_render_pass_add_node (GskVulkanRenderPass *self,
+ GskVulkanRender *render,
+ GskRenderNode *node)
+{
+ GskVulkanRenderOp op = {
+ .type = GSK_VULKAN_OP_FALLBACK,
+ .node = node
+ };
+
+ g_array_append_val (self->render_ops, op);
+}
+
+static void
+gsk_vulkan_render_pass_upload_fallback (GskVulkanRenderOp *op,
+ GskVulkanRender *render)
+{
+ graphene_rect_t bounds;
+ GskRenderer *fallback;
+ cairo_surface_t *surface;
+ cairo_t *cr;
+
+ gsk_render_node_get_bounds (op->node, &bounds);
+
+ surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+ ceil (bounds.size.width),
+ ceil (bounds.size.height));
+ cr = cairo_create (surface);
+ cairo_translate (cr, bounds.origin.x, bounds.origin.y);
+
+ fallback = gsk_renderer_create_fallback (render->renderer,
+ &bounds,
+ cr);
+ gsk_renderer_render (fallback, op->node, NULL);
+ g_object_unref (fallback);
+
+ cairo_destroy (cr);
+
+ op->source = gsk_vulkan_image_new_from_data (render->vulkan,
+ render->command_buffer,
+ cairo_image_surface_get_data (surface),
+ cairo_image_surface_get_width (surface),
+ cairo_image_surface_get_height (surface),
+ cairo_image_surface_get_stride (surface));
+
+ cairo_surface_destroy (surface);
+
+ gsk_vulkan_render_add_cleanup_image (render, op->source);
+}
+
+void
+gsk_vulkan_render_pass_upload (GskVulkanRenderPass *self,
+ GskVulkanRender *render)
+{
+ GskVulkanRenderOp *op;
+ guint i;
+
+ for (i = 0; i < self->render_ops->len; i++)
+ {
+ op = &g_array_index (self->render_ops, GskVulkanRenderOp, i);
+
+ switch (op->type)
+ {
+ case GSK_VULKAN_OP_FALLBACK:
+ gsk_vulkan_render_pass_upload_fallback (op, render);
+ break;
+
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+ }
+}
+
+gsize
+gsk_vulkan_render_pass_count_vertices (GskVulkanRenderPass *self)
+{
+ return self->render_ops->len * 6;
+}
+
+static gsize
+gsk_vulkan_render_op_collect_vertices (GskVulkanRenderOp *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)
+{
+ GskVulkanRenderOp *op;
+ gsize n;
+ guint i;
+
+ n = 0;
+ for (i = 0; i < self->render_ops->len; i++)
+ {
+ op = &g_array_index (self->render_ops, GskVulkanRenderOp, i);
+
+ switch (op->type)
+ {
+ case GSK_VULKAN_OP_FALLBACK:
+ op->vertex_offset = offset + n;
+ op->vertex_count = gsk_vulkan_render_op_collect_vertices (op, vertices + n + offset);
+ break;
+
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+
+ n += op->vertex_count;
+ g_assert (n + offset <= total);
+ }
+
+ return n;
+}
+
+void
+gsk_vulkan_render_pass_update_descriptor_sets (GskVulkanRenderPass *self,
+ VkDescriptorSet descriptor_set,
+ VkSampler sampler)
+{
+ GskVulkanRenderOp *op;
+ guint i;
+
+ for (i = 0; i < self->render_ops->len; i++)
+ {
+ op = &g_array_index (self->render_ops, GskVulkanRenderOp, i);
+
+ vkUpdateDescriptorSets (gdk_vulkan_context_get_device (self->vulkan),
+ 1,
+ (VkWriteDescriptorSet[1]) {
+ {
+ .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
+ .dstSet = descriptor_set,
+ .dstBinding = 0,
+ .dstArrayElement = 0,
+ .descriptorCount = 1,
+ .descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
+ .pImageInfo = &(VkDescriptorImageInfo) {
+ .sampler = sampler,
+ .imageView = gsk_vulkan_image_get_image_view (op->source),
+ .imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
+ }
+ }
+ },
+ 0, NULL);
+ }
+}
+
+void
+gsk_vulkan_render_pass_draw (GskVulkanRenderPass *self,
+ GskVulkanRender *render)
+{
+ GskVulkanRenderOp *op;
+ guint i;
+
+ for (i = 0; i < self->render_ops->len; i++)
+ {
+ op = &g_array_index (self->render_ops, GskVulkanRenderOp, i);
+
+ vkCmdDraw (render->command_buffer,
+ op->vertex_count, 1,
+ op->vertex_offset, 0);
+ }
+}
diff --git a/gsk/gskvulkanrenderpassprivate.h b/gsk/gskvulkanrenderpassprivate.h
new file mode 100644
index 0000000..eb22761
--- /dev/null
+++ b/gsk/gskvulkanrenderpassprivate.h
@@ -0,0 +1,37 @@
+#ifndef __GSK_VULKAN_RENDER_PASS_PRIVATE_H__
+#define __GSK_VULKAN_RENDER_PASS_PRIVATE_H__
+
+#include <gdk/gdk.h>
+#include <gsk/gskrendernode.h>
+
+#include "gsk/gskvulkanrenderprivate.h"
+
+G_BEGIN_DECLS
+
+typedef struct _GskVulkanRenderPass GskVulkanRenderPass;
+
+GskVulkanRenderPass * gsk_vulkan_render_pass_new (GdkVulkanContext *context);
+void gsk_vulkan_render_pass_free (GskVulkanRenderPass *self);
+
+void gsk_vulkan_render_pass_add_node (GskVulkanRenderPass *self,
+ GskVulkanRender *render,
+ GskRenderNode *node);
+
+void gsk_vulkan_render_pass_upload (GskVulkanRenderPass *self,
+ GskVulkanRender *render);
+
+gsize gsk_vulkan_render_pass_count_vertices (GskVulkanRenderPass *self);
+gsize gsk_vulkan_render_pass_collect_vertices (GskVulkanRenderPass *self,
+ GskVulkanVertex *vertices,
+ gsize offset,
+ gsize total);
+
+void gsk_vulkan_render_pass_update_descriptor_sets (GskVulkanRenderPass *self,
+ VkDescriptorSet
descriptor_set,
+ VkSampler sampler);
+void gsk_vulkan_render_pass_draw (GskVulkanRenderPass *self,
+ GskVulkanRender *render);
+
+G_END_DECLS
+
+#endif /* __GSK_VULKAN_RENDER_PASS_PRIVATE_H__ */
diff --git a/gsk/gskvulkanrenderprivate.h b/gsk/gskvulkanrenderprivate.h
index c1f3202..53f67de 100644
--- a/gsk/gskvulkanrenderprivate.h
+++ b/gsk/gskvulkanrenderprivate.h
@@ -2,28 +2,66 @@
#define __GSK_VULKAN_RENDER_PRIVATE_H__
#include <gdk/gdk.h>
+#include <gsk/gskrendernode.h>
+
+#include "gsk/gskvulkanimageprivate.h"
+#include "gsk/gskvulkanpipelineprivate.h"
G_BEGIN_DECLS
typedef struct _GskVulkanRender GskVulkanRender;
+typedef struct _GskVulkanVertex GskVulkanVertex;
struct _GskVulkanRender
{
+ GskRenderer *renderer;
GdkVulkanContext *vulkan;
+ graphene_matrix_t mvp;
+ int scale_factor;
+ VkExtent2D size;
+ VkRect2D scissor;
+
+
VkCommandPool command_pool;
VkCommandBuffer command_buffer;
+
+ GSList *render_passes;
+ GSList *cleanup_images;
+};
+
+struct _GskVulkanVertex
+{
+ float x;
+ float y;
+ float tex_x;
+ float tex_y;
};
void gsk_vulkan_render_init (GskVulkanRender *self,
+ GskRenderer *renderer,
GdkVulkanContext *context,
VkCommandPool
command_pool);
+void gsk_vulkan_render_finish (GskVulkanRender *self);
+
+void gsk_vulkan_render_add_cleanup_image (GskVulkanRender *self,
+ GskVulkanImage *image);
+
+void gsk_vulkan_render_add_node (GskVulkanRender *self,
+ GskRenderNode *node);
+
+void gsk_vulkan_render_upload (GskVulkanRender *self);
+
+void gsk_vulkan_render_draw (GskVulkanRender *self,
+ GskVulkanPipeline *pipeline,
+ VkRenderPass render_pass,
+ VkFramebuffer framebuffer,
+ VkDescriptorSet
descriptor_set,
+ VkSampler sampler);
void gsk_vulkan_render_submit (GskVulkanRender *self,
VkFence fence);
-void gsk_vulkan_render_finish (GskVulkanRender *self);
-
G_END_DECLS
#endif /* __GSK_VULKAN_RENDER_PRIVATE_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]