forked from AuroraMiddleware/gtk
vulkan: Keep render objects around
That way we can reuse them. We only create a new one if the last render operation hasn't finished executing.
This commit is contained in:
parent
adff39953d
commit
ac9d48151b
@ -68,8 +68,6 @@ gsk_vulkan_render_new (GskRenderer *renderer,
|
||||
self->vulkan = context;
|
||||
self->renderer = renderer;
|
||||
|
||||
gsk_vulkan_render_compute_mvp (self);
|
||||
|
||||
device = gdk_vulkan_context_get_device (self->vulkan);
|
||||
|
||||
GSK_VK_CHECK (vkCreateCommandPool, device,
|
||||
@ -84,26 +82,11 @@ gsk_vulkan_render_new (GskRenderer *renderer,
|
||||
GSK_VK_CHECK (vkCreateFence, device,
|
||||
&(VkFenceCreateInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
|
||||
.flags = 0
|
||||
.flags = VK_FENCE_CREATE_SIGNALED_BIT
|
||||
},
|
||||
NULL,
|
||||
&self->fence);
|
||||
|
||||
GSK_VK_CHECK (vkAllocateCommandBuffers, device,
|
||||
&(VkCommandBufferAllocateInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
|
||||
.commandPool = self->command_pool,
|
||||
.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
|
||||
.commandBufferCount = 1,
|
||||
},
|
||||
&self->command_buffer);
|
||||
|
||||
GSK_VK_CHECK (vkBeginCommandBuffer, self->command_buffer,
|
||||
&(VkCommandBufferBeginInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
|
||||
.flags = 0
|
||||
});
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@ -294,22 +277,41 @@ gsk_vulkan_render_submit (GskVulkanRender *self)
|
||||
&self->fence,
|
||||
VK_TRUE,
|
||||
INT64_MAX);
|
||||
GSK_VK_CHECK (vkResetFences, gdk_vulkan_context_get_device (self->vulkan),
|
||||
1,
|
||||
&self->fence);
|
||||
}
|
||||
|
||||
void
|
||||
gsk_vulkan_render_free (GskVulkanRender *self)
|
||||
static void
|
||||
gsk_vulkan_render_cleanup (GskVulkanRender *self)
|
||||
{
|
||||
VkDevice device = gdk_vulkan_context_get_device (self->vulkan);
|
||||
|
||||
/* XXX: Wait for fence here or just in reset()? */
|
||||
GSK_VK_CHECK (vkWaitForFences, device,
|
||||
1,
|
||||
&self->fence,
|
||||
VK_TRUE,
|
||||
INT64_MAX);
|
||||
|
||||
GSK_VK_CHECK (vkResetFences, device,
|
||||
1,
|
||||
&self->fence);
|
||||
GSK_VK_CHECK (vkResetCommandPool, device,
|
||||
self->command_pool,
|
||||
0);
|
||||
|
||||
g_slist_free_full (self->render_passes, (GDestroyNotify) gsk_vulkan_render_pass_free);
|
||||
self->render_passes = NULL;
|
||||
g_slist_free_full (self->cleanup_images, (GDestroyNotify) gsk_vulkan_image_free);
|
||||
self->cleanup_images = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_vulkan_render_free (GskVulkanRender *self)
|
||||
{
|
||||
VkDevice device;
|
||||
|
||||
gsk_vulkan_render_cleanup (self);
|
||||
|
||||
device = gdk_vulkan_context_get_device (self->vulkan);
|
||||
|
||||
vkDestroyFence (device,
|
||||
self->fence,
|
||||
@ -321,6 +323,39 @@ gsk_vulkan_render_free (GskVulkanRender *self)
|
||||
g_slice_free (GskVulkanRender, self);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gsk_vulkan_render_is_busy (GskVulkanRender *self)
|
||||
{
|
||||
return vkGetFenceStatus (gdk_vulkan_context_get_device (self->vulkan), self->fence) != VK_SUCCESS;
|
||||
}
|
||||
|
||||
void
|
||||
gsk_vulkan_render_reset (GskVulkanRender *self)
|
||||
{
|
||||
VkDevice device;
|
||||
|
||||
gsk_vulkan_render_cleanup (self);
|
||||
|
||||
gsk_vulkan_render_compute_mvp (self);
|
||||
|
||||
device = gdk_vulkan_context_get_device (self->vulkan);
|
||||
|
||||
GSK_VK_CHECK (vkAllocateCommandBuffers, device,
|
||||
&(VkCommandBufferAllocateInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
|
||||
.commandPool = self->command_pool,
|
||||
.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
|
||||
.commandBufferCount = 1,
|
||||
},
|
||||
&self->command_buffer);
|
||||
|
||||
GSK_VK_CHECK (vkBeginCommandBuffer, self->command_buffer,
|
||||
&(VkCommandBufferBeginInfo) {
|
||||
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
|
||||
.flags = 0
|
||||
});
|
||||
}
|
||||
|
||||
GskRenderer *
|
||||
gsk_vulkan_render_get_renderer (GskVulkanRender *self)
|
||||
{
|
||||
|
@ -42,6 +42,8 @@ struct _GskVulkanRenderer
|
||||
|
||||
VkSampler sampler;
|
||||
|
||||
GSList *renders;
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
ProfileTimers profile_timers;
|
||||
#endif
|
||||
@ -267,6 +269,9 @@ gsk_vulkan_renderer_realize (GskRenderer *renderer,
|
||||
self);
|
||||
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));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -276,6 +281,9 @@ gsk_vulkan_renderer_unrealize (GskRenderer *renderer)
|
||||
GskVulkanRenderer *self = GSK_VULKAN_RENDERER (renderer);
|
||||
VkDevice device;
|
||||
|
||||
g_slist_free_full (self->renders, (GDestroyNotify) gsk_vulkan_render_free);
|
||||
self->renders = NULL;
|
||||
|
||||
device = gdk_vulkan_context_get_device (self->vulkan);
|
||||
|
||||
gsk_vulkan_renderer_free_targets (self);
|
||||
@ -310,6 +318,7 @@ gsk_vulkan_renderer_render (GskRenderer *renderer,
|
||||
{
|
||||
GskVulkanRenderer *self = GSK_VULKAN_RENDERER (renderer);
|
||||
GskVulkanRender *render;
|
||||
GSList *l;
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
GskProfiler *profiler;
|
||||
gint64 cpu_time;
|
||||
@ -320,7 +329,22 @@ gsk_vulkan_renderer_render (GskRenderer *renderer,
|
||||
gsk_profiler_timer_begin (profiler, self->profile_timers.cpu_time);
|
||||
#endif
|
||||
|
||||
render = gsk_vulkan_render_new (renderer, self->vulkan);
|
||||
for (l = self->renders; l; l = l->next)
|
||||
{
|
||||
if (!gsk_vulkan_render_is_busy (l->data))
|
||||
break;
|
||||
}
|
||||
if (l)
|
||||
{
|
||||
render = l->data;
|
||||
}
|
||||
else
|
||||
{
|
||||
render = gsk_vulkan_render_new (renderer, self->vulkan);
|
||||
self->renders = g_slist_prepend (self->renders, render);
|
||||
}
|
||||
|
||||
gsk_vulkan_render_reset (render);
|
||||
|
||||
gsk_vulkan_render_add_node (render, root);
|
||||
|
||||
@ -333,8 +357,6 @@ gsk_vulkan_renderer_render (GskRenderer *renderer,
|
||||
|
||||
gsk_vulkan_render_submit (render);
|
||||
|
||||
gsk_vulkan_render_free (render);
|
||||
|
||||
#ifdef G_ENABLE_DEBUG
|
||||
cpu_time = gsk_profiler_timer_end (profiler, self->profile_timers.cpu_time);
|
||||
gsk_profiler_timer_set (profiler, self->profile_timers.cpu_time, cpu_time);
|
||||
|
@ -24,6 +24,9 @@ GskVulkanRender * gsk_vulkan_render_new (GskRend
|
||||
GdkVulkanContext *context);
|
||||
void gsk_vulkan_render_free (GskVulkanRender *self);
|
||||
|
||||
gboolean gsk_vulkan_render_is_busy (GskVulkanRender *self);
|
||||
void gsk_vulkan_render_reset (GskVulkanRender *self);
|
||||
|
||||
GskRenderer * gsk_vulkan_render_get_renderer (GskVulkanRender *self);
|
||||
|
||||
void gsk_vulkan_render_add_cleanup_image (GskVulkanRender *self,
|
||||
|
Loading…
Reference in New Issue
Block a user