[gtk+] vulkan: Implement multiple render passes
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] vulkan: Implement multiple render passes
- Date: Thu, 28 Sep 2017 12:40:13 +0000 (UTC)
commit d61a71590942ece5da40a21bd80d77751147e99e
Author: Matthias Clasen <mclasen redhat com>
Date: Wed Sep 27 20:56:01 2017 -0400
vulkan: Implement multiple render passes
Whenever we need a node as a texture, we now start a new render
pass that renders the node into a new intermediate texture, and
set up a semaphore to make the current render pass wait for it.
As part of this reorganization, much of the setup and drawing
code moved from gskvulkanrender.c to gskvulkanrenderpass.c.
gsk/gskvulkanrender.c | 204 ++++++++++++-------------------
gsk/gskvulkanrenderer.c | 1 +
gsk/gskvulkanrenderpass.c | 255 +++++++++++++++++++++++++++++++++-----
gsk/gskvulkanrenderpassprivate.h | 25 ++--
gsk/gskvulkanrenderprivate.h | 9 ++
5 files changed, 324 insertions(+), 170 deletions(-)
---
diff --git a/gsk/gskvulkanrender.c b/gsk/gskvulkanrender.c
index 5888866..06b593c 100644
--- a/gsk/gskvulkanrender.c
+++ b/gsk/gskvulkanrender.c
@@ -23,9 +23,6 @@
#include "gskvulkantextpipelineprivate.h"
#include "gskvulkanpushconstantsprivate.h"
-#define ORTHO_NEAR_PLANE -10000
-#define ORTHO_FAR_PLANE 10000
-
#define DESCRIPTOR_POOL_MAXSETS 128
#define DESCRIPTOR_POOL_MAXSETS_INCREASE 128
@@ -34,7 +31,6 @@ struct _GskVulkanRender
GskRenderer *renderer;
GdkVulkanContext *vulkan;
- graphene_matrix_t mvp;
int scale_factor;
VkRect2D viewport;
cairo_region_t *clip;
@@ -46,7 +42,6 @@ struct _GskVulkanRender
VkDescriptorSetLayout descriptor_set_layout;
VkPipelineLayout pipeline_layout[3]; /* indexed by number of textures */
GskVulkanUploader *uploader;
- GskVulkanBuffer *vertex_buffer;
GHashTable *descriptor_set_indexes;
VkDescriptorPool descriptor_pool;
@@ -57,7 +52,7 @@ struct _GskVulkanRender
GskVulkanImage *target;
- GSList *render_passes;
+ GList *render_passes;
GSList *cleanup_images;
};
@@ -67,7 +62,6 @@ gsk_vulkan_render_setup (GskVulkanRender *self,
const graphene_rect_t *rect)
{
GdkWindow *window = gsk_renderer_get_window (self->renderer);
- graphene_matrix_t modelview, projection;
self->target = g_object_ref (target);
@@ -88,15 +82,6 @@ gsk_vulkan_render_setup (GskVulkanRender *self,
self->viewport.extent.height = gdk_window_get_height (window) * self->scale_factor;
self->clip = gdk_drawing_context_get_clip (gsk_renderer_get_drawing_context (self->renderer));
}
-
- graphene_matrix_init_scale (&modelview, self->scale_factor, self->scale_factor, 1.0);
- graphene_matrix_init_ortho (&projection,
- self->viewport.offset.x, self->viewport.offset.x + self->viewport.extent.width,
- self->viewport.offset.y, self->viewport.offset.y +
self->viewport.extent.height,
- ORTHO_NEAR_PLANE,
- ORTHO_FAR_PLANE);
-
- graphene_matrix_multiply (&modelview, &projection, &self->mvp);
}
GskVulkanRender *
@@ -243,7 +228,7 @@ gsk_vulkan_render_remove_framebuffer_from_image (gpointer data,
g_slice_free (HashFramebufferEntry, fb);
}
-static VkFramebuffer
+VkFramebuffer
gsk_vulkan_render_get_framebuffer (GskVulkanRender *self,
GskVulkanImage *image)
{
@@ -285,70 +270,69 @@ 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 (pass,
- self,
- &self->mvp,
- &GRAPHENE_RECT_INIT (
- self->viewport.offset.x, self->viewport.offset.y,
- self->viewport.extent.width, self->viewport.extent.height
- ),
- node);
+ GskVulkanRenderPass *pass;
+
+ pass = gsk_vulkan_render_pass_new (self->vulkan,
+ self->target,
+ self->scale_factor,
+ &GRAPHENE_RECT_INIT (
+ self->viewport.offset.x, self->viewport.offset.y,
+ self->viewport.extent.width, self->viewport.extent.height
+ ),
+ self->clip,
+ VK_NULL_HANDLE);
+
+ self->render_passes = g_list_prepend (self->render_passes, pass);
+
+ gsk_vulkan_render_pass_add (pass, self, node);
}
void
-gsk_vulkan_render_upload (GskVulkanRender *self)
+gsk_vulkan_render_add_node_for_texture (GskVulkanRender *self,
+ GskRenderNode *node,
+ const graphene_rect_t *bounds,
+ GskVulkanImage *target,
+ VkSemaphore semaphore)
{
- GSList *l;
+ GskVulkanRenderPass *pass;
+ cairo_region_t *clip;
- for (l = self->render_passes; l; l = l->next)
- {
- gsk_vulkan_render_pass_upload (l->data, self, self->uploader);
- }
+ clip = cairo_region_create_rectangle (&(cairo_rectangle_int_t) {
+ 0, 0,
+ gsk_vulkan_image_get_width (target),
+ gsk_vulkan_image_get_height (target)
+ });
- gsk_vulkan_uploader_upload (self->uploader);
-}
+ pass = gsk_vulkan_render_pass_new (self->vulkan,
+ target,
+ 1,
+ bounds,
+ clip,
+ semaphore);
-static gsize
-gsk_vulkan_renderer_count_vertex_data (GskVulkanRender *self)
-{
- gsize n_bytes;
- GSList *l;
+ cairo_region_destroy (clip);
- n_bytes = 0;
- for (l = self->render_passes; l; l = l->next)
- {
- n_bytes += gsk_vulkan_render_pass_count_vertex_data (l->data);
- }
+ self->render_passes = g_list_prepend (self->render_passes, pass);
- return n_bytes;
+ gsk_vulkan_render_pass_add (pass, self, node);
}
-static GskVulkanBuffer *
-gsk_vulkan_render_collect_vertex_data (GskVulkanRender *self)
+void
+gsk_vulkan_render_upload (GskVulkanRender *self)
{
- GskVulkanBuffer *buffer;
- guchar *data;
- GSList *l;
- gsize offset, n_bytes;
-
- offset = 0;
- n_bytes = gsk_vulkan_renderer_count_vertex_data (self);
- buffer = gsk_vulkan_buffer_new (self->vulkan, n_bytes);
- data = gsk_vulkan_buffer_map (buffer);
+ GList *l;
- for (l = self->render_passes; l; l = l->next)
+ /* gsk_vulkan_render_pass_upload may call gsk_vulkan_render_add_node_for_texture,
+ * prepending new render passes to the list. Therefore, we walk the list from
+ * the end.
+ */
+ for (l = g_list_last (self->render_passes); l; l = l->prev)
{
- offset += gsk_vulkan_render_pass_collect_vertex_data (l->data, self, data, offset, n_bytes - offset);
- g_assert (offset <= n_bytes);
+ GskVulkanRenderPass *pass = l->data;
+ gsk_vulkan_render_pass_upload (pass, self, self->uploader);
}
- gsk_vulkan_buffer_unmap (buffer);
-
- return buffer;
+ gsk_vulkan_uploader_upload (self->uploader);
}
GskVulkanPipeline *
@@ -424,6 +408,8 @@ gsk_vulkan_render_reserve_descriptor_set (GskVulkanRender *self,
{
gpointer id_plus_one;
+ g_assert (source != NULL);
+
id_plus_one = g_hash_table_lookup (self->descriptor_set_indexes, source);
if (id_plus_one)
return GPOINTER_TO_SIZE (id_plus_one) - 1;
@@ -441,14 +427,15 @@ gsk_vulkan_render_prepare_descriptor_sets (GskVulkanRender *self,
GHashTableIter iter;
gpointer key, value;
VkDevice device;
- GSList *l;
+ GList *l;
guint i, needed_sets;
device = gdk_vulkan_context_get_device (self->vulkan);
for (l = self->render_passes; l; l = l->next)
{
- gsk_vulkan_render_pass_reserve_descriptor_sets (l->data, self);
+ GskVulkanRenderPass *pass = l->data;
+ gsk_vulkan_render_pass_reserve_descriptor_sets (pass, self);
}
needed_sets = g_hash_table_size (self->descriptor_set_indexes);
@@ -534,68 +521,35 @@ void
gsk_vulkan_render_draw (GskVulkanRender *self,
VkSampler sampler)
{
- VkCommandBuffer command_buffer;
- GSList *l;
- guint i;
+ GList *l;
gsk_vulkan_render_prepare_descriptor_sets (self, sampler);
- command_buffer = gsk_vulkan_command_pool_get_buffer (self->command_pool);
-
- self->vertex_buffer = gsk_vulkan_render_collect_vertex_data (self);
-
- vkCmdSetViewport (command_buffer,
- 0,
- 1,
- &(VkViewport) {
- .x = 0,
- .y = 0,
- .width = self->viewport.extent.width,
- .height = self->viewport.extent.height,
- .minDepth = 0,
- .maxDepth = 1
- });
-
- for (i = 0; i < cairo_region_num_rectangles (self->clip); i++)
+ for (l = self->render_passes; l; l = l->next)
{
- cairo_rectangle_int_t rect;
-
- cairo_region_get_rectangle (self->clip, i, &rect);
-
- vkCmdSetScissor (command_buffer,
- 0,
- 1,
- &(VkRect2D) {
- { rect.x * self->scale_factor, rect.y * self->scale_factor },
- { rect.width * self->scale_factor, rect.height * self->scale_factor }
- });
-
- vkCmdBeginRenderPass (command_buffer,
- &(VkRenderPassBeginInfo) {
- .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
- .renderPass = self->render_pass,
- .framebuffer = gsk_vulkan_render_get_framebuffer (self, self->target),
- .renderArea = {
- { rect.x * self->scale_factor, rect.y * self->scale_factor },
- { rect.width * self->scale_factor, rect.height * self->scale_factor }
- },
- .clearValueCount = 1,
- .pClearValues = (VkClearValue [1]) {
- { .color = { .float32 = { 0.f, 0.f, 0.f, 0.f } } }
- }
- },
- VK_SUBPASS_CONTENTS_INLINE);
-
- for (l = self->render_passes; l; l = l->next)
- {
- gsk_vulkan_render_pass_draw (l->data, self, self->vertex_buffer, 3, self->pipeline_layout,
command_buffer);
- }
-
- vkCmdEndRenderPass (command_buffer);
+ GskVulkanRenderPass *pass = l->data;
+ VkCommandBuffer command_buffer;
+ gsize wait_semaphore_count;
+ gsize signal_semaphore_count;
+ VkSemaphore *wait_semaphores;
+ VkSemaphore *signal_semaphores;
+
+ wait_semaphore_count = gsk_vulkan_render_pass_get_wait_semaphores (pass, &wait_semaphores);
+ signal_semaphore_count = gsk_vulkan_render_pass_get_signal_semaphores (pass, &signal_semaphores);
+
+ command_buffer = gsk_vulkan_command_pool_get_buffer (self->command_pool);
+
+ gsk_vulkan_render_pass_draw (pass, self, 3, self->pipeline_layout, command_buffer);
+
+ gsk_vulkan_command_pool_submit_buffer (self->command_pool,
+ command_buffer,
+ wait_semaphore_count,
+ wait_semaphores,
+ signal_semaphore_count,
+ signal_semaphores,
+ l->next != NULL ? VK_NULL_HANDLE : self->fence);
}
- gsk_vulkan_command_pool_submit_buffer (self->command_pool, command_buffer, 0, NULL, 0, NULL, self->fence);
-
if (GSK_RENDER_MODE_CHECK (SYNC))
{
GSK_VK_CHECK (vkWaitForFences, gdk_vulkan_context_get_device (self->vulkan),
@@ -634,14 +588,12 @@ gsk_vulkan_render_cleanup (GskVulkanRender *self)
gsk_vulkan_command_pool_reset (self->command_pool);
- g_clear_pointer (&self->vertex_buffer, gsk_vulkan_buffer_free);
-
g_hash_table_remove_all (self->descriptor_set_indexes);
GSK_VK_CHECK (vkResetDescriptorPool, device,
self->descriptor_pool,
0);
- g_slist_free_full (self->render_passes, (GDestroyNotify) gsk_vulkan_render_pass_free);
+ g_list_free_full (self->render_passes, (GDestroyNotify) gsk_vulkan_render_pass_free);
self->render_passes = NULL;
g_slist_free_full (self->cleanup_images, g_object_unref);
self->cleanup_images = NULL;
diff --git a/gsk/gskvulkanrenderer.c b/gsk/gskvulkanrenderer.c
index 6666880..661128c 100644
--- a/gsk/gskvulkanrenderer.c
+++ b/gsk/gskvulkanrenderer.c
@@ -246,6 +246,7 @@ gsk_vulkan_renderer_render (GskRenderer *renderer,
#ifdef G_ENABLE_DEBUG
profiler = gsk_renderer_get_profiler (renderer);
+ gsk_profiler_counter_set (profiler, self->profile_counters.fallback_pixels, 0);
gsk_profiler_timer_begin (profiler, self->profile_timers.cpu_time);
#endif
diff --git a/gsk/gskvulkanrenderpass.c b/gsk/gskvulkanrenderpass.c
index 022c08d..e82c4a2 100644
--- a/gsk/gskvulkanrenderpass.c
+++ b/gsk/gskvulkanrenderpass.c
@@ -27,6 +27,9 @@
#include <cairo-ft.h>
+#define ORTHO_NEAR_PLANE -10000
+#define ORTHO_FAR_PLANE 10000
+
typedef union _GskVulkanOp GskVulkanOp;
typedef struct _GskVulkanOpRender GskVulkanOpRender;
typedef struct _GskVulkanOpText GskVulkanOpText;
@@ -107,17 +110,97 @@ struct _GskVulkanRenderPass
GArray *render_ops;
+ GskVulkanImage *target;
+ int scale_factor;
+ graphene_rect_t viewport;
+ cairo_region_t *clip;
+ graphene_matrix_t mvp;
+
+ VkRenderPass render_pass;
+ VkSemaphore signal_semaphore;
+ GArray *wait_semaphores;
+ GskVulkanBuffer *vertex_data;
+
GQuark fallback_pixels;
};
GskVulkanRenderPass *
-gsk_vulkan_render_pass_new (GdkVulkanContext *context)
+gsk_vulkan_render_pass_new (GdkVulkanContext *context,
+ GskVulkanImage *target,
+ int scale_factor,
+ graphene_rect_t *viewport,
+ cairo_region_t *clip,
+ VkSemaphore signal_semaphore)
{
GskVulkanRenderPass *self;
+ graphene_matrix_t modelview, projection;
+ VkImageLayout final_layout;
self = g_slice_new0 (GskVulkanRenderPass);
self->vulkan = g_object_ref (context);
self->render_ops = g_array_new (FALSE, FALSE, sizeof (GskVulkanOp));
+
+ self->target = g_object_ref (target);
+ self->scale_factor = scale_factor;
+ self->clip = cairo_region_copy (clip);
+ self->viewport = GRAPHENE_RECT_INIT (0, 0, viewport->size.width, viewport->size.height);
+
+ graphene_matrix_init_scale (&modelview, self->scale_factor, self->scale_factor, 1.0);
+ graphene_matrix_init_ortho (&projection,
+ viewport->origin.x, viewport->origin.x + viewport->size.width,
+ viewport->origin.y, viewport->origin.y + viewport->size.height,
+ ORTHO_NEAR_PLANE,
+ ORTHO_FAR_PLANE);
+ graphene_matrix_multiply (&modelview, &projection, &self->mvp);
+
+ if (signal_semaphore != VK_NULL_HANDLE) // this is a dependent pass
+ final_layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+ else
+ final_layout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
+ GSK_VK_CHECK (vkCreateRenderPass, gdk_vulkan_context_get_device (self->vulkan),
+ &(VkRenderPassCreateInfo) {
+ .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
+ .attachmentCount = 1,
+ .pAttachments = (VkAttachmentDescription[]) {
+ {
+ .format = gdk_vulkan_context_get_image_format (self->vulkan),
+ .samples = VK_SAMPLE_COUNT_1_BIT,
+ .loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR,
+ .storeOp = VK_ATTACHMENT_STORE_OP_STORE,
+ .initialLayout = VK_IMAGE_LAYOUT_UNDEFINED,
+ .finalLayout = final_layout
+ }
+ },
+ .subpassCount = 1,
+ .pSubpasses = (VkSubpassDescription []) {
+ {
+ .pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
+ .inputAttachmentCount = 0,
+ .colorAttachmentCount = 1,
+ .pColorAttachments = (VkAttachmentReference []) {
+ {
+ .attachment = 0,
+ .layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
+ }
+ },
+ .pResolveAttachments = (VkAttachmentReference []) {
+ {
+ .attachment = VK_ATTACHMENT_UNUSED,
+ .layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
+ }
+ },
+ .pDepthStencilAttachment = NULL,
+ }
+ },
+ .dependencyCount = 0
+ },
+ NULL,
+ &self->render_pass);
+
+ self->signal_semaphore = signal_semaphore;
+ self->wait_semaphores = g_array_new (FALSE, FALSE, sizeof (VkSemaphore));
+ self->vertex_data = NULL;
+
#ifdef G_ENABLE_DEBUG
self->fallback_pixels = g_quark_from_static_string ("fallback-pixels");
#endif
@@ -130,6 +213,19 @@ gsk_vulkan_render_pass_free (GskVulkanRenderPass *self)
{
g_array_unref (self->render_ops);
g_object_unref (self->vulkan);
+ g_object_unref (self->target);
+ cairo_region_destroy (self->clip);
+ vkDestroyRenderPass (gdk_vulkan_context_get_device (self->vulkan),
+ self->render_pass,
+ NULL);
+ if (self->vertex_data)
+ gsk_vulkan_buffer_free (self->vertex_data);
+ if (self->signal_semaphore != VK_NULL_HANDLE)
+ vkDestroySemaphore (gdk_vulkan_context_get_device (self->vulkan),
+ self->signal_semaphore,
+ NULL);
+ g_array_unref (self->wait_semaphores);
+
g_slice_free (GskVulkanRenderPass, self);
}
@@ -530,14 +626,12 @@ fallback:
void
gsk_vulkan_render_pass_add (GskVulkanRenderPass *self,
GskVulkanRender *render,
- const graphene_matrix_t *mvp,
- const graphene_rect_t *viewport,
GskRenderNode *node)
{
GskVulkanOp op = { 0, };
op.type = GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS;
- gsk_vulkan_push_constants_init (&op.constants.constants, mvp, viewport);
+ gsk_vulkan_push_constants_init (&op.constants.constants, &self->mvp, &self->viewport);
g_array_append_val (self->render_ops, op);
gsk_vulkan_render_pass_add_node (self, render, &op.constants.constants, node);
@@ -559,15 +653,39 @@ gsk_vulkan_render_pass_get_node_as_texture (GskVulkanRenderPass *self,
switch (gsk_render_node_get_node_type (node))
{
case GSK_TEXTURE_NODE:
- return gsk_vulkan_renderer_ref_texture_image (GSK_VULKAN_RENDERER (gsk_vulkan_render_get_renderer
(render)),
- gsk_texture_node_get_texture (node),
- uploader);
+ result = gsk_vulkan_renderer_ref_texture_image (GSK_VULKAN_RENDERER
(gsk_vulkan_render_get_renderer (render)),
+ gsk_texture_node_get_texture (node),
+ uploader);
+ gsk_vulkan_render_add_cleanup_image (render, result);
+ return result;
+
case GSK_CAIRO_NODE:
surface = cairo_surface_reference (gsk_cairo_node_get_surface (node));
goto got_surface;
- default:
- break;
+ default: ;
+ {
+ VkSemaphore semaphore;
+
+ result = gsk_vulkan_image_new_for_texture (self->vulkan,
+ ceil (bounds->size.width),
+ ceil (bounds->size.height));
+
+ vkCreateSemaphore (gdk_vulkan_context_get_device (self->vulkan),
+ &(VkSemaphoreCreateInfo) {
+ VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
+ NULL,
+ 0
+ },
+ NULL,
+ &semaphore);
+
+ g_array_append_val (self->wait_semaphores, semaphore);
+ gsk_vulkan_render_add_node_for_texture (render, node, bounds, result, semaphore);
+ gsk_vulkan_render_add_cleanup_image (render, result);
+
+ return result;
+ }
}
}
@@ -756,7 +874,7 @@ gsk_vulkan_render_pass_upload (GskVulkanRenderPass *self,
{
GskRenderNode *child = gsk_color_matrix_node_get_child (op->render.node);
- op->render.source = gsk_vulkan_render_pass_get_node_as_texture (self,
+ op->render.source = gsk_vulkan_render_pass_get_node_as_texture (self,
render,
uploader,
child,
@@ -813,7 +931,7 @@ gsk_vulkan_render_pass_upload (GskVulkanRenderPass *self,
}
}
-gsize
+static gsize
gsk_vulkan_render_pass_count_vertex_data (GskVulkanRenderPass *self)
{
GskVulkanOp *op;
@@ -892,6 +1010,7 @@ gsk_vulkan_render_pass_count_vertex_data (GskVulkanRenderPass *self)
default:
g_assert_not_reached ();
+
case GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS:
continue;
}
@@ -900,7 +1019,7 @@ gsk_vulkan_render_pass_count_vertex_data (GskVulkanRenderPass *self)
return n_bytes;
}
-gsize
+static gsize
gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self,
GskVulkanRender *render,
guchar *data,
@@ -1124,23 +1243,39 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self,
return n_bytes;
}
-GskVulkanBuffer *
+static GskVulkanBuffer *
gsk_vulkan_render_pass_get_vertex_data (GskVulkanRenderPass *self,
GskVulkanRender *render)
{
- gsize n_bytes;
- GskVulkanBuffer *buffer;
- guchar *data;
-
- n_bytes = gsk_vulkan_render_pass_count_vertex_data (self);
- buffer = gsk_vulkan_buffer_new (self->vulkan, n_bytes);
- data = gsk_vulkan_buffer_map (buffer);
+ if (self->vertex_data == NULL)
+ {
+ gsize n_bytes;
+ guchar *data;
+
+ n_bytes = gsk_vulkan_render_pass_count_vertex_data (self);
+ self->vertex_data = gsk_vulkan_buffer_new (self->vulkan, n_bytes);
+ data = gsk_vulkan_buffer_map (self->vertex_data);
+ gsk_vulkan_render_pass_collect_vertex_data (self, render, data, 0, n_bytes);
+ gsk_vulkan_buffer_unmap (self->vertex_data);
+ }
- gsk_vulkan_render_pass_collect_vertex_data (self, render, data, 0, n_bytes);
+ return self->vertex_data;
+}
- gsk_vulkan_buffer_unmap (buffer);
+gsize
+gsk_vulkan_render_pass_get_wait_semaphores (GskVulkanRenderPass *self,
+ VkSemaphore **semaphores)
+{
+ *semaphores = (VkSemaphore *)self->wait_semaphores->data;
+ return self->wait_semaphores->len;
+}
- return buffer;
+gsize
+gsk_vulkan_render_pass_get_signal_semaphores (GskVulkanRenderPass *self,
+ VkSemaphore **semaphores)
+{
+ *semaphores = (VkSemaphore *)&self->signal_semaphore;
+ return self->signal_semaphore != VK_NULL_HANDLE ? 1 : 0;
}
void
@@ -1180,6 +1315,7 @@ gsk_vulkan_render_pass_reserve_descriptor_sets (GskVulkanRenderPass *self,
default:
g_assert_not_reached ();
+
case GSK_VULKAN_OP_COLOR:
case GSK_VULKAN_OP_LINEAR_GRADIENT:
case GSK_VULKAN_OP_PUSH_VERTEX_CONSTANTS:
@@ -1191,18 +1327,20 @@ gsk_vulkan_render_pass_reserve_descriptor_sets (GskVulkanRenderPass *self,
}
}
-void
-gsk_vulkan_render_pass_draw (GskVulkanRenderPass *self,
- GskVulkanRender *render,
- GskVulkanBuffer *vertex_buffer,
- guint layout_count,
- VkPipelineLayout *pipeline_layout,
- VkCommandBuffer command_buffer)
+static void
+gsk_vulkan_render_pass_draw_rect (GskVulkanRenderPass *self,
+ GskVulkanRender *render,
+ guint layout_count,
+ VkPipelineLayout *pipeline_layout,
+ VkCommandBuffer command_buffer)
{
GskVulkanPipeline *current_pipeline = NULL;
gsize current_draw_index = 0;
GskVulkanOp *op;
guint i, step;
+ GskVulkanBuffer *vertex_buffer;
+
+ vertex_buffer = gsk_vulkan_render_pass_get_vertex_data (self, render);
for (i = 0; i < self->render_ops->len; i += step)
{
@@ -1555,3 +1693,60 @@ gsk_vulkan_render_pass_draw (GskVulkanRenderPass *self,
}
}
}
+
+void
+gsk_vulkan_render_pass_draw (GskVulkanRenderPass *self,
+ GskVulkanRender *render,
+ guint layout_count,
+ VkPipelineLayout *pipeline_layout,
+ VkCommandBuffer command_buffer)
+{
+ guint i;
+
+ vkCmdSetViewport (command_buffer,
+ 0,
+ 1,
+ &(VkViewport) {
+ .x = 0,
+ .y = 0,
+ .width = self->viewport.size.width,
+ .height = self->viewport.size.height,
+ .minDepth = 0,
+ .maxDepth = 1
+ });
+
+ for (i = 0; i < cairo_region_num_rectangles (self->clip); i++)
+ {
+ cairo_rectangle_int_t rect;
+
+ cairo_region_get_rectangle (self->clip, i, &rect);
+
+ vkCmdSetScissor (command_buffer,
+ 0,
+ 1,
+ &(VkRect2D) {
+ { rect.x * self->scale_factor, rect.y * self->scale_factor },
+ { rect.width * self->scale_factor, rect.height * self->scale_factor }
+ });
+
+ vkCmdBeginRenderPass (command_buffer,
+ &(VkRenderPassBeginInfo) {
+ .sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
+ .renderPass = self->render_pass,
+ .framebuffer = gsk_vulkan_render_get_framebuffer (render, self->target),
+ .renderArea = {
+ { rect.x * self->scale_factor, rect.y * self->scale_factor },
+ { rect.width * self->scale_factor, rect.height * self->scale_factor }
+ },
+ .clearValueCount = 1,
+ .pClearValues = (VkClearValue [1]) {
+ { .color = { .float32 = { 0.f, 0.f, 0.f, 0.f } } }
+ }
+ },
+ VK_SUBPASS_CONTENTS_INLINE);
+
+ gsk_vulkan_render_pass_draw_rect (self, render, layout_count, pipeline_layout, command_buffer);
+
+ vkCmdEndRenderPass (command_buffer);
+ }
+}
diff --git a/gsk/gskvulkanrenderpassprivate.h b/gsk/gskvulkanrenderpassprivate.h
index 808ea88..3af9470 100644
--- a/gsk/gskvulkanrenderpassprivate.h
+++ b/gsk/gskvulkanrenderpassprivate.h
@@ -11,36 +11,33 @@
G_BEGIN_DECLS
-GskVulkanRenderPass * gsk_vulkan_render_pass_new (GdkVulkanContext *context);
+GskVulkanRenderPass * gsk_vulkan_render_pass_new (GdkVulkanContext *context,
+ GskVulkanImage *target,
+ int
scale_factor,
+ graphene_rect_t *viewport,
+ cairo_region_t *clip,
+ VkSemaphore
signal_semaphore);
+
void gsk_vulkan_render_pass_free (GskVulkanRenderPass *self);
void gsk_vulkan_render_pass_add (GskVulkanRenderPass *self,
GskVulkanRender *render,
- const graphene_matrix_t*mvp,
- const graphene_rect_t *viewport,
GskRenderNode *node);
void gsk_vulkan_render_pass_upload (GskVulkanRenderPass *self,
GskVulkanRender *render,
GskVulkanUploader *uploader);
-
-gsize gsk_vulkan_render_pass_count_vertex_data (GskVulkanRenderPass *self);
-gsize gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self,
- GskVulkanRender *render,
- guchar *data,
- gsize offset,
- gsize total);
-GskVulkanBuffer * gsk_vulkan_render_pass_get_vertex_data (GskVulkanRenderPass *self,
- GskVulkanRender *render);
-
void gsk_vulkan_render_pass_reserve_descriptor_sets (GskVulkanRenderPass *self,
GskVulkanRender *render);
void gsk_vulkan_render_pass_draw (GskVulkanRenderPass *self,
GskVulkanRender *render,
- GskVulkanBuffer
*vertex_buffer,
guint
layout_count,
VkPipelineLayout
*pipeline_layout,
VkCommandBuffer
command_buffer);
+gsize gsk_vulkan_render_pass_get_wait_semaphores (GskVulkanRenderPass *self,
+ VkSemaphore **semaphores);
+gsize gsk_vulkan_render_pass_get_signal_semaphores (GskVulkanRenderPass *self,
+ VkSemaphore **semaphores);
G_END_DECLS
diff --git a/gsk/gskvulkanrenderprivate.h b/gsk/gskvulkanrenderprivate.h
index 4bd2484..ec553be 100644
--- a/gsk/gskvulkanrenderprivate.h
+++ b/gsk/gskvulkanrenderprivate.h
@@ -69,6 +69,13 @@ void gsk_vulkan_render_add_cleanup_image (GskVulk
void gsk_vulkan_render_add_node (GskVulkanRender *self,
GskRenderNode *node);
+void gsk_vulkan_render_add_node_for_texture (GskVulkanRender *self,
+ GskRenderNode *node,
+ const graphene_rect_t *bounds,
+ GskVulkanImage *target,
+ VkSemaphore semaphore);
+
+
void gsk_vulkan_render_upload (GskVulkanRender *self);
GskVulkanPipeline * gsk_vulkan_render_get_pipeline (GskVulkanRender *self,
@@ -83,6 +90,8 @@ void gsk_vulkan_render_draw (GskVulk
void gsk_vulkan_render_submit (GskVulkanRender *self);
GskTexture * gsk_vulkan_render_download_target (GskVulkanRender *self);
+VkFramebuffer gsk_vulkan_render_get_framebuffer (GskVulkanRender *self,
+ GskVulkanImage *image);
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]