[gtk+/wip/matthiasc/renderpasses] add semaphores
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/matthiasc/renderpasses] add semaphores
- Date: Wed, 27 Sep 2017 10:15:05 +0000 (UTC)
commit 197fb074c9858a8a75ccccc0b28c4eeb724df41f
Author: Matthias Clasen <mclasen redhat com>
Date: Tue Sep 26 23:41:25 2017 -0400
add semaphores
gsk/gskprivate.h | 3 +
gsk/gskvulkancommandpool.c | 32 +++++-----
gsk/gskvulkancommandpoolprivate.h | 3 +
gsk/gskvulkanimage.c | 12 ++--
gsk/gskvulkanrender.c | 124 ++++++++++++++++++++++++++----------
gsk/gskvulkanrenderpass.c | 22 ++++++-
gsk/gskvulkanrenderpassprivate.h | 4 +-
gsk/gskvulkanrenderprivate.h | 5 +-
8 files changed, 144 insertions(+), 61 deletions(-)
---
diff --git a/gsk/gskprivate.h b/gsk/gskprivate.h
index 8584be6..5d9f88c 100644
--- a/gsk/gskprivate.h
+++ b/gsk/gskprivate.h
@@ -10,6 +10,9 @@ void gsk_ensure_resources (void);
int pango_glyph_string_num_glyphs (PangoGlyphString *glyphs);
+typedef struct _GskVulkanRender GskVulkanRender;
+typedef struct _GskVulkanRenderPass GskVulkanRenderPass;
+
G_END_DECLS
#endif /* __GSK_PRIVATE_H__ */
diff --git a/gsk/gskvulkancommandpool.c b/gsk/gskvulkancommandpool.c
index c2b9747..0125f64 100644
--- a/gsk/gskvulkancommandpool.c
+++ b/gsk/gskvulkancommandpool.c
@@ -75,33 +75,35 @@ gsk_vulkan_command_pool_get_buffer (GskVulkanCommandPool *self)
void
gsk_vulkan_command_pool_submit_buffer (GskVulkanCommandPool *self,
VkCommandBuffer command_buffer,
+ gsize wait_semaphore_count,
+ VkSemaphore *wait_semaphores,
+ VkSemaphore signal_semaphore,
VkFence fence)
{
+ VkPipelineStageFlags *wait_semaphore_flags = NULL;
+
GSK_VK_CHECK (vkEndCommandBuffer, command_buffer);
+ if (wait_semaphore_count > 0)
+ {
+ wait_semaphore_flags = alloca (sizeof (VkPipelineStageFlags) * wait_semaphore_count);
+ for (int i = 0; i < wait_semaphore_count; i++)
+ wait_semaphore_flags[i] = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
+ }
+
GSK_VK_CHECK (vkQueueSubmit, gdk_vulkan_context_get_queue (self->vulkan),
1,
&(VkSubmitInfo) {
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
-/*
- .waitSemaphoreCount = 1,
- .pWaitSemaphores = (VkSemaphore[1]) {
- gdk_vulkan_context_get_draw_semaphore (self->vulkan)
- },
-*/
- .pWaitDstStageMask = (VkPipelineStageFlags []) {
- VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
- },
+ .waitSemaphoreCount = wait_semaphore_count,
+ .pWaitSemaphores = wait_semaphores,
+ .pWaitDstStageMask = wait_semaphore_flags,
.commandBufferCount = 1,
.pCommandBuffers = (VkCommandBuffer[1]) {
command_buffer
},
-/*
- .signalSemaphoreCount = 1,
- .pSignalSemaphores = (VkSemaphore[1]) {
- gdk_vulkan_context_get_draw_semaphore (self->vulkan)
- }
-*/
+ .signalSemaphoreCount = signal_semaphore != VK_NULL_HANDLE ? 1 : 0,
+ .pSignalSemaphores = &signal_semaphore,
},
fence);
}
diff --git a/gsk/gskvulkancommandpoolprivate.h b/gsk/gskvulkancommandpoolprivate.h
index 0373908..48fed35 100644
--- a/gsk/gskvulkancommandpoolprivate.h
+++ b/gsk/gskvulkancommandpoolprivate.h
@@ -15,6 +15,9 @@ void gsk_vulkan_command_pool_reset (GskVulk
VkCommandBuffer gsk_vulkan_command_pool_get_buffer (GskVulkanCommandPool *self);
void gsk_vulkan_command_pool_submit_buffer (GskVulkanCommandPool *self,
VkCommandBuffer buffer,
+ gsize
wait_semaphore_count,
+ VkSemaphore
*wait_semaphores,
+ VkSemaphore
signal_semaphore,
VkFence fence);
G_END_DECLS
diff --git a/gsk/gskvulkanimage.c b/gsk/gskvulkanimage.c
index 5a286e1..46e83f1 100644
--- a/gsk/gskvulkanimage.c
+++ b/gsk/gskvulkanimage.c
@@ -154,7 +154,7 @@ gsk_vulkan_uploader_upload (GskVulkanUploader *self)
0, NULL,
self->before_buffer_barriers->len, (VkBufferMemoryBarrier *)
self->before_buffer_barriers->data,
self->before_image_barriers->len, (VkImageMemoryBarrier *)
self->before_image_barriers->data);
- gsk_vulkan_command_pool_submit_buffer (self->command_pool, command_buffer, VK_NULL_HANDLE);
+ gsk_vulkan_command_pool_submit_buffer (self->command_pool, command_buffer, 0, NULL, VK_NULL_HANDLE,
VK_NULL_HANDLE);
g_array_set_size (self->before_buffer_barriers, 0);
g_array_set_size (self->before_image_barriers, 0);
}
@@ -176,7 +176,7 @@ gsk_vulkan_uploader_upload (GskVulkanUploader *self)
if (self->copy_buffer != VK_NULL_HANDLE)
{
- gsk_vulkan_command_pool_submit_buffer (self->command_pool, self->copy_buffer, VK_NULL_HANDLE);
+ gsk_vulkan_command_pool_submit_buffer (self->command_pool, self->copy_buffer, 0, NULL, VK_NULL_HANDLE,
VK_NULL_HANDLE);
self->copy_buffer = VK_NULL_HANDLE;
}
}
@@ -760,11 +760,9 @@ gsk_vulkan_image_finalize (GObject *object)
GskVulkanImage *self = GSK_VULKAN_IMAGE (object);
if (self->vk_image_view != VK_NULL_HANDLE)
- {
- vkDestroyImageView (gdk_vulkan_context_get_device (self->vulkan),
- self->vk_image_view,
- NULL);
- }
+ vkDestroyImageView (gdk_vulkan_context_get_device (self->vulkan),
+ self->vk_image_view,
+ NULL);
/* memory is NULL for for_swapchain() images, where we don't own
* the VkImage */
diff --git a/gsk/gskvulkanrender.c b/gsk/gskvulkanrender.c
index 9ff7b8a..fc5f381 100644
--- a/gsk/gskvulkanrender.c
+++ b/gsk/gskvulkanrender.c
@@ -46,7 +46,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;
@@ -68,6 +67,9 @@ typedef struct {
cairo_region_t *clip;
int scale_factor;
VkRenderPass render_pass;
+ GskVulkanBuffer *vertex_data;
+ VkSemaphore signal_semaphore;
+ GArray *wait_semaphores;
} RenderPassData;
static void
@@ -82,6 +84,14 @@ render_pass_data_free (gpointer v)
vkDestroyRenderPass (gdk_vulkan_context_get_device (data->render->vulkan),
data->render_pass,
NULL);
+ if (data->vertex_data)
+ gsk_vulkan_buffer_free (data->vertex_data);
+ if (data->signal_semaphore != VK_NULL_HANDLE)
+ vkDestroySemaphore (gdk_vulkan_context_get_device (data->render->vulkan),
+ data->signal_semaphore,
+ NULL);
+ if (data->wait_semaphores)
+ g_array_unref (data->wait_semaphores);
g_free (data);
}
@@ -318,6 +328,8 @@ gsk_vulkan_render_add_node (GskVulkanRender *self,
data->scale_factor = self->scale_factor;
data->clip = cairo_region_copy (self->clip);
data->render_pass = self->render_pass;
+ data->signal_semaphore = VK_NULL_HANDLE;
+ data->wait_semaphores = NULL;
self->render_passes = g_list_prepend (self->render_passes, data);
@@ -331,10 +343,35 @@ gsk_vulkan_render_add_node (GskVulkanRender *self,
node);
}
+static void
+add_wait_semaphore (GskVulkanRender *self,
+ GskVulkanRenderPass *pass,
+ VkSemaphore semaphore)
+{
+ GList *l;
+
+ if (semaphore == VK_NULL_HANDLE)
+ return;
+
+ for (l = self->render_passes; l; l = l->next)
+ {
+ RenderPassData *data = l->data;
+ if (data->pass == pass)
+ {
+ if (data->wait_semaphores == NULL)
+ data->wait_semaphores = g_array_new (FALSE, FALSE, sizeof (VkSemaphore));
+
+ g_array_append_val (data->wait_semaphores, semaphore);
+ return;
+ }
+ }
+}
+
void
-gsk_vulkan_render_add_node_for_texture (GskVulkanRender *self,
- GskRenderNode *node,
- GskVulkanImage *target)
+gsk_vulkan_render_add_node_for_texture (GskVulkanRender *self,
+ GskVulkanRenderPass *pass,
+ GskRenderNode *node,
+ GskVulkanImage *target)
{
RenderPassData *data;
@@ -349,6 +386,16 @@ gsk_vulkan_render_add_node_for_texture (GskVulkanRender *self,
gsk_vulkan_image_get_height (target)
});
+ vkCreateSemaphore (gdk_vulkan_context_get_device (self->vulkan),
+ &(VkSemaphoreCreateInfo) {
+ VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO,
+ NULL,
+ 0
+ },
+ NULL,
+ &data->signal_semaphore);
+ add_wait_semaphore (self, pass, data->signal_semaphore);
+
GSK_VK_CHECK (vkCreateRenderPass, gdk_vulkan_context_get_device (self->vulkan),
&(VkRenderPassCreateInfo) {
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
@@ -647,31 +694,33 @@ void
gsk_vulkan_render_draw (GskVulkanRender *self,
VkSampler sampler)
{
- VkCommandBuffer command_buffer;
GList *l;
- guint i;
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 (l = self->render_passes; l; l = l->next)
{
RenderPassData *pass = l->data;
+ VkCommandBuffer command_buffer;
+ VkFence fence;
+ guint i;
+
+ pass->vertex_data = gsk_vulkan_render_pass_get_vertex_data (pass->pass, self);
+
+ command_buffer = gsk_vulkan_command_pool_get_buffer (self->command_pool);
+
+ 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 (pass->clip); i++)
{
cairo_rectangle_int_t rect;
@@ -702,22 +751,29 @@ gsk_vulkan_render_draw (GskVulkanRender *self,
},
VK_SUBPASS_CONTENTS_INLINE);
- gsk_vulkan_render_pass_draw (pass->pass, self, self->vertex_buffer, 3, self->pipeline_layout,
command_buffer);
-
+ gsk_vulkan_render_pass_draw (pass->pass, self, pass->vertex_data, 3, self->pipeline_layout,
command_buffer);
vkCmdEndRenderPass (command_buffer);
}
- }
- gsk_vulkan_command_pool_submit_buffer (self->command_pool, command_buffer, self->fence);
+ if (l->next == NULL) // last batch
+ fence = self->fence;
+ else
+ fence = VK_NULL_HANDLE;
+
+ gsk_vulkan_command_pool_submit_buffer (self->command_pool,
+ command_buffer,
+ pass->wait_semaphores ? pass->wait_semaphores->len : 0,
+ (VkSemaphore*)(pass->wait_semaphores ?
pass->wait_semaphores->data : NULL),
+ pass->signal_semaphore,
+ fence);
+ }
if (GSK_RENDER_MODE_CHECK (SYNC))
- {
- GSK_VK_CHECK (vkWaitForFences, gdk_vulkan_context_get_device (self->vulkan),
- 1,
- &self->fence,
- VK_TRUE,
- INT64_MAX);
- }
+ GSK_VK_CHECK (vkWaitForFences, gdk_vulkan_context_get_device (self->vulkan),
+ 1,
+ &self->fence,
+ VK_TRUE,
+ INT64_MAX);
}
GskTexture *
@@ -748,8 +804,6 @@ 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,
diff --git a/gsk/gskvulkanrenderpass.c b/gsk/gskvulkanrenderpass.c
index 6eae4a0..9d750a6 100644
--- a/gsk/gskvulkanrenderpass.c
+++ b/gsk/gskvulkanrenderpass.c
@@ -118,6 +118,7 @@ gsk_vulkan_render_pass_new (GdkVulkanContext *context)
self = g_slice_new0 (GskVulkanRenderPass);
self->vulkan = g_object_ref (context);
self->render_ops = g_array_new (FALSE, FALSE, sizeof (GskVulkanOp));
+
#ifdef G_ENABLE_DEBUG
self->fallback_pixels = g_quark_from_static_string ("fallback-pixels");
#endif
@@ -572,7 +573,7 @@ gsk_vulkan_render_pass_get_node_as_texture (GskVulkanRenderPass *self,
ceil (bounds->size.width),
ceil (bounds->size.height));
g_assert (result != NULL);
- gsk_vulkan_render_add_node_for_texture (render, node, result);
+ gsk_vulkan_render_add_node_for_texture (render, self, node, result);
g_assert (result != 0);
return result;
@@ -1153,6 +1154,25 @@ gsk_vulkan_render_pass_collect_vertex_data (GskVulkanRenderPass *self,
return n_bytes;
}
+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);
+
+ gsk_vulkan_render_pass_collect_vertex_data (self, render, data, 0, n_bytes);
+
+ gsk_vulkan_buffer_unmap (buffer);
+
+ return buffer;
+}
+
void
gsk_vulkan_render_pass_reserve_descriptor_sets (GskVulkanRenderPass *self,
GskVulkanRender *render)
diff --git a/gsk/gskvulkanrenderpassprivate.h b/gsk/gskvulkanrenderpassprivate.h
index 56bc9ad..808ea88 100644
--- a/gsk/gskvulkanrenderpassprivate.h
+++ b/gsk/gskvulkanrenderpassprivate.h
@@ -6,10 +6,10 @@
#include "gsk/gskvulkanbufferprivate.h"
#include "gsk/gskvulkanrenderprivate.h"
+#include "gsk/gskprivate.h"
G_BEGIN_DECLS
-typedef struct _GskVulkanRenderPass GskVulkanRenderPass;
GskVulkanRenderPass * gsk_vulkan_render_pass_new (GdkVulkanContext *context);
void gsk_vulkan_render_pass_free (GskVulkanRenderPass *self);
@@ -30,6 +30,8 @@ gsize gsk_vulkan_render_pass_collect_vertex_data (GskVulk
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);
diff --git a/gsk/gskvulkanrenderprivate.h b/gsk/gskvulkanrenderprivate.h
index 953e75c..9a4ea93 100644
--- a/gsk/gskvulkanrenderprivate.h
+++ b/gsk/gskvulkanrenderprivate.h
@@ -6,6 +6,8 @@
#include "gsk/gskvulkanimageprivate.h"
#include "gsk/gskvulkanpipelineprivate.h"
+#include "gsk/gskvulkanrenderpassprivate.h"
+#include "gsk/gskprivate.h"
G_BEGIN_DECLS
@@ -50,8 +52,6 @@ typedef enum {
GSK_VULKAN_N_PIPELINES
} GskVulkanPipelineType;
-typedef struct _GskVulkanRender GskVulkanRender;
-
GskVulkanRender * gsk_vulkan_render_new (GskRenderer *renderer,
GdkVulkanContext *context);
void gsk_vulkan_render_free (GskVulkanRender *self);
@@ -70,6 +70,7 @@ void gsk_vulkan_render_add_node (GskVulk
GskRenderNode *node);
void gsk_vulkan_render_add_node_for_texture (GskVulkanRender *self,
+ GskVulkanRenderPass *pass,
GskRenderNode *node,
GskVulkanImage *target);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]