[gtk+/wip/otte/vulkan: 20/28] vulkan: Create framebuffers from GskVulkanRender object
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/otte/vulkan: 20/28] vulkan: Create framebuffers from GskVulkanRender object
- Date: Fri, 9 Dec 2016 06:28:44 +0000 (UTC)
commit cb130e82151d4c4ee94139296f329d648561af61
Author: Benjamin Otte <otte redhat com>
Date: Thu Dec 8 22:35:16 2016 +0100
vulkan: Create framebuffers from GskVulkanRender object
Also create them on-demand, as they need to be created per-image and
per-framebuffer, so we don't want to create loads of them.
gsk/gskvulkanrender.c | 90 +++++++++++++++++++++++++++++++++++++++---
gsk/gskvulkanrenderer.c | 80 +++++--------------------------------
gsk/gskvulkanrenderprivate.h | 8 ++--
3 files changed, 98 insertions(+), 80 deletions(-)
---
diff --git a/gsk/gskvulkanrender.c b/gsk/gskvulkanrender.c
index fa51779..8498ee1 100644
--- a/gsk/gskvulkanrender.c
+++ b/gsk/gskvulkanrender.c
@@ -20,11 +20,15 @@ struct _GskVulkanRender
VkExtent2D size;
VkRect2D scissor;
+ GHashTable *framebuffers;
VkCommandPool command_pool;
+ VkRenderPass render_pass;
VkFence fence;
VkCommandBuffer command_buffer;
+ GskVulkanImage *target;
+
GSList *render_passes;
GSList *cleanup_images;
};
@@ -58,7 +62,8 @@ gsk_vulkan_render_compute_mvp (GskVulkanRender *self)
GskVulkanRender *
gsk_vulkan_render_new (GskRenderer *renderer,
- GdkVulkanContext *context)
+ GdkVulkanContext *context,
+ VkRenderPass pretend_you_didnt_see_me)
{
GskVulkanRender *self;
VkDevice device;
@@ -67,6 +72,8 @@ gsk_vulkan_render_new (GskRenderer *renderer,
self->vulkan = context;
self->renderer = renderer;
+ self->render_pass = pretend_you_didnt_see_me;
+ self->framebuffers = g_hash_table_new (g_direct_hash, g_direct_equal);
device = gdk_vulkan_context_get_device (self->vulkan);
@@ -90,6 +97,58 @@ gsk_vulkan_render_new (GskRenderer *renderer,
return self;
}
+typedef struct {
+ VkFramebuffer framebuffer;
+} HashFramebufferEntry;
+
+static void
+gsk_vulkan_render_remove_framebuffer_from_image (gpointer data,
+ GObject *image)
+{
+ GskVulkanRender *self = data;
+ HashFramebufferEntry *fb;
+
+ fb = g_hash_table_lookup (self->framebuffers, image);
+ g_hash_table_remove (self->framebuffers, image);
+
+ vkDestroyFramebuffer (gdk_vulkan_context_get_device (self->vulkan),
+ fb->framebuffer,
+ NULL);
+
+ g_slice_free (HashFramebufferEntry, fb);
+}
+
+static VkFramebuffer
+gsk_vulkan_render_get_framebuffer (GskVulkanRender *self,
+ GskVulkanImage *image)
+{
+ HashFramebufferEntry *fb;
+
+ fb = g_hash_table_lookup (self->framebuffers, image);
+ if (fb)
+ return fb->framebuffer;
+
+ fb = g_slice_new0 (HashFramebufferEntry);
+ GSK_VK_CHECK (vkCreateFramebuffer, gdk_vulkan_context_get_device (self->vulkan),
+ &(VkFramebufferCreateInfo) {
+ .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
+ .renderPass = self->render_pass,
+ .attachmentCount = 1,
+ .pAttachments = (VkImageView[1]) {
+ gsk_vulkan_image_get_image_view (image)
+ },
+ .width = gsk_vulkan_image_get_width (image),
+ .height = gsk_vulkan_image_get_height (image),
+ .layers = 1
+ },
+ NULL,
+ &fb->framebuffer);
+ g_hash_table_insert (self->framebuffers, image, fb);
+ g_object_weak_ref (G_OBJECT (image), gsk_vulkan_render_remove_framebuffer_from_image, self);
+
+ return fb->framebuffer;
+}
+
void
gsk_vulkan_render_add_cleanup_image (GskVulkanRender *self,
GskVulkanImage *image)
@@ -161,8 +220,6 @@ gsk_vulkan_render_collect_vertices (GskVulkanRender *self)
void
gsk_vulkan_render_draw (GskVulkanRender *self,
GskVulkanPipeline *pipeline,
- VkRenderPass render_pass,
- VkFramebuffer framebuffer,
VkDescriptorSet descriptor_set,
VkSampler sampler)
{
@@ -196,8 +253,8 @@ gsk_vulkan_render_draw (GskVulkanRender *self,
vkCmdBeginRenderPass (self->command_buffer,
&(VkRenderPassBeginInfo) {
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
- .renderPass = render_pass,
- .framebuffer = framebuffer,
+ .renderPass = self->render_pass,
+ .framebuffer = gsk_vulkan_render_get_framebuffer (self, self->target),
.renderArea = {
{ 0, 0 },
{ self->size.width, self->size.height }
@@ -305,17 +362,35 @@ gsk_vulkan_render_cleanup (GskVulkanRender *self)
self->render_passes = NULL;
g_slist_free_full (self->cleanup_images, g_object_unref);
self->cleanup_images = NULL;
+
+ g_clear_object (&self->target);
}
void
gsk_vulkan_render_free (GskVulkanRender *self)
{
+ GHashTableIter iter;
+ gpointer key, value;
VkDevice device;
gsk_vulkan_render_cleanup (self);
device = gdk_vulkan_context_get_device (self->vulkan);
+ g_hash_table_iter_init (&iter, self->framebuffers);
+ while (g_hash_table_iter_next (&iter, &key, &value))
+ {
+ HashFramebufferEntry *fb = value;
+
+ vkDestroyFramebuffer (gdk_vulkan_context_get_device (self->vulkan),
+ fb->framebuffer,
+ NULL);
+ g_slice_free (HashFramebufferEntry, fb);
+ g_object_weak_unref (G_OBJECT (key), gsk_vulkan_render_remove_framebuffer_from_image, self);
+ g_hash_table_iter_remove (&iter);
+ }
+ g_hash_table_unref (self->framebuffers);
+
vkDestroyFence (device,
self->fence,
NULL);
@@ -333,12 +408,15 @@ gsk_vulkan_render_is_busy (GskVulkanRender *self)
}
void
-gsk_vulkan_render_reset (GskVulkanRender *self)
+gsk_vulkan_render_reset (GskVulkanRender *self,
+ GskVulkanImage *target)
{
VkDevice device;
gsk_vulkan_render_cleanup (self);
+ self->target = g_object_ref (target);
+
gsk_vulkan_render_compute_mvp (self);
device = gdk_vulkan_context_get_device (self->vulkan);
diff --git a/gsk/gskvulkanrenderer.c b/gsk/gskvulkanrenderer.c
index fe7623b..e04537d 100644
--- a/gsk/gskvulkanrenderer.c
+++ b/gsk/gskvulkanrenderer.c
@@ -15,8 +15,6 @@
#include <graphene.h>
-typedef struct _GskVulkanTarget GskVulkanTarget;
-
#ifdef G_ENABLE_DEBUG
typedef struct {
GQuark cpu_time;
@@ -31,7 +29,7 @@ struct _GskVulkanRenderer
GdkVulkanContext *vulkan;
guint n_targets;
- GskVulkanTarget **targets;
+ GskVulkanImage **targets;
VkRenderPass render_pass;
@@ -56,63 +54,6 @@ struct _GskVulkanRendererClass
G_DEFINE_TYPE (GskVulkanRenderer, gsk_vulkan_renderer, GSK_TYPE_RENDERER)
-struct _GskVulkanTarget {
- GskVulkanImage *image;
- VkFramebuffer framebuffer;
-};
-
-static GskVulkanTarget *
-gsk_vulkan_target_new_for_image (GskVulkanRenderer *self,
- VkImage image,
- gsize width,
- gsize height)
-{
- GskVulkanTarget *target;
- VkDevice device;
-
- device = gdk_vulkan_context_get_device (self->vulkan);
-
- target = g_slice_new0 (GskVulkanTarget);
-
- target->image = gsk_vulkan_image_new_for_swapchain (self->vulkan,
- image,
- gdk_vulkan_context_get_image_format (self->vulkan),
- width, height);
- GSK_VK_CHECK (vkCreateFramebuffer, device,
- &(VkFramebufferCreateInfo) {
- .sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
- .renderPass = self->render_pass,
- .attachmentCount = 1,
- .pAttachments = (VkImageView[1]) {
- gsk_vulkan_image_get_image_view (target->image)
- },
- .width = width,
- .height = height,
- .layers = 1
- },
- NULL,
- &target->framebuffer);
-
- return target;
-}
-
-static void
-gsk_vulkan_target_free (GskVulkanRenderer *self,
- GskVulkanTarget *target)
-{
- VkDevice device;
-
- device = gdk_vulkan_context_get_device (self->vulkan);
-
- vkDestroyFramebuffer (device,
- target->framebuffer,
- NULL);
-
- g_object_unref (target->image);
-
- g_slice_free (GskVulkanTarget, target);
-}
-
static void
gsk_vulkan_renderer_free_targets (GskVulkanRenderer *self)
{
@@ -120,7 +61,7 @@ gsk_vulkan_renderer_free_targets (GskVulkanRenderer *self)
for (i = 0; i < self->n_targets; i++)
{
- gsk_vulkan_target_free (self, self->targets[i]);
+ g_object_unref (self->targets[i]);
}
g_clear_pointer (&self->targets, g_free);
@@ -139,7 +80,7 @@ gsk_vulkan_renderer_update_images_cb (GdkVulkanContext *context,
gsk_vulkan_renderer_free_targets (self);
self->n_targets = gdk_vulkan_context_get_n_images (context);
- self->targets = g_new (GskVulkanTarget *, self->n_targets);
+ self->targets = g_new (GskVulkanImage *, self->n_targets);
window = gsk_renderer_get_window (GSK_RENDERER (self));
scale_factor = gdk_window_get_scale_factor (window);
@@ -148,9 +89,10 @@ gsk_vulkan_renderer_update_images_cb (GdkVulkanContext *context,
for (i = 0; i < self->n_targets; i++)
{
- self->targets[i] = gsk_vulkan_target_new_for_image (self,
- gdk_vulkan_context_get_image (context, i),
- width, height);
+ self->targets[i] = gsk_vulkan_image_new_for_swapchain (self->vulkan,
+ gdk_vulkan_context_get_image (context, i),
+ gdk_vulkan_context_get_image_format
(self->vulkan),
+ width, height);
}
}
@@ -259,7 +201,7 @@ gsk_vulkan_renderer_realize (GskRenderer *renderer,
gsk_vulkan_renderer_update_images_cb (self->vulkan, self);
/* We will need at least one render object, so create it early where we can still fail fine */
- self->renders = g_slist_prepend (self->renders, gsk_vulkan_render_new (renderer, self->vulkan));
+ self->renders = g_slist_prepend (self->renders, gsk_vulkan_render_new (renderer, self->vulkan,
self->render_pass));
return TRUE;
}
@@ -329,19 +271,17 @@ gsk_vulkan_renderer_render (GskRenderer *renderer,
}
else
{
- render = gsk_vulkan_render_new (renderer, self->vulkan);
+ render = gsk_vulkan_render_new (renderer, self->vulkan, self->render_pass);
self->renders = g_slist_prepend (self->renders, render);
}
- gsk_vulkan_render_reset (render);
+ gsk_vulkan_render_reset (render, self->targets[gdk_vulkan_context_get_draw_index (self->vulkan)]);
gsk_vulkan_render_add_node (render, root);
gsk_vulkan_render_upload (render);
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_render_submit (render);
diff --git a/gsk/gskvulkanrenderprivate.h b/gsk/gskvulkanrenderprivate.h
index a86e5c8..a17de86 100644
--- a/gsk/gskvulkanrenderprivate.h
+++ b/gsk/gskvulkanrenderprivate.h
@@ -21,11 +21,13 @@ struct _GskVulkanVertex
};
GskVulkanRender * gsk_vulkan_render_new (GskRenderer *renderer,
- GdkVulkanContext *context);
+ GdkVulkanContext *context,
+ VkRenderPass
pretend_you_didnt_see_me);
void gsk_vulkan_render_free (GskVulkanRender *self);
gboolean gsk_vulkan_render_is_busy (GskVulkanRender *self);
-void gsk_vulkan_render_reset (GskVulkanRender *self);
+void gsk_vulkan_render_reset (GskVulkanRender *self,
+ GskVulkanImage *target);
GskRenderer * gsk_vulkan_render_get_renderer (GskVulkanRender *self);
@@ -39,8 +41,6 @@ void gsk_vulkan_render_upload (GskVulk
void gsk_vulkan_render_draw (GskVulkanRender *self,
GskVulkanPipeline *pipeline,
- VkRenderPass render_pass,
- VkFramebuffer framebuffer,
VkDescriptorSet
descriptor_set,
VkSampler sampler);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]