gtk/gsk/vulkan/gskvulkancommandpool.c
Benjamin Otte 710c39027b vulkan: Keep track of command buffers
Fixes a rather large memleak.
2018-02-17 08:04:43 +01:00

132 lines
4.9 KiB
C

#include "config.h"
#include "gskvulkancommandpoolprivate.h"
#include "gskvulkanpipelineprivate.h"
struct _GskVulkanCommandPool
{
GdkVulkanContext *vulkan;
VkCommandPool vk_command_pool;
GPtrArray *buffers;
};
GskVulkanCommandPool *
gsk_vulkan_command_pool_new (GdkVulkanContext *context)
{
GskVulkanCommandPool *self;
self = g_slice_new0 (GskVulkanCommandPool);
self->vulkan = g_object_ref (context);
GSK_VK_CHECK (vkCreateCommandPool, gdk_vulkan_context_get_device (context),
&(const VkCommandPoolCreateInfo) {
.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
.queueFamilyIndex = gdk_vulkan_context_get_queue_family_index (self->vulkan),
.flags = 0
},
NULL,
&self->vk_command_pool);
self->buffers = g_ptr_array_new ();
return self;
}
static void
gsk_vulkan_command_pool_free_buffers (GskVulkanCommandPool *self)
{
vkFreeCommandBuffers (gdk_vulkan_context_get_device (self->vulkan),
self->vk_command_pool,
self->buffers->len,
(VkCommandBuffer *) self->buffers->pdata);
g_ptr_array_set_size (self->buffers, 0);
}
void
gsk_vulkan_command_pool_free (GskVulkanCommandPool *self)
{
gsk_vulkan_command_pool_free_buffers (self);
g_ptr_array_unref (self->buffers);
vkDestroyCommandPool (gdk_vulkan_context_get_device (self->vulkan),
self->vk_command_pool,
NULL);
g_slice_free (GskVulkanCommandPool, self);
}
void
gsk_vulkan_command_pool_reset (GskVulkanCommandPool *self)
{
gsk_vulkan_command_pool_free_buffers (self);
GSK_VK_CHECK (vkResetCommandPool, gdk_vulkan_context_get_device (self->vulkan),
self->vk_command_pool,
0);
}
VkCommandBuffer
gsk_vulkan_command_pool_get_buffer (GskVulkanCommandPool *self)
{
VkCommandBuffer command_buffer;
GSK_VK_CHECK (vkAllocateCommandBuffers, gdk_vulkan_context_get_device (self->vulkan),
&(VkCommandBufferAllocateInfo) {
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
.commandPool = self->vk_command_pool,
.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
.commandBufferCount = 1,
},
&command_buffer);
g_ptr_array_add (self->buffers, command_buffer);
GSK_VK_CHECK (vkBeginCommandBuffer, command_buffer,
&(VkCommandBufferBeginInfo) {
.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
.flags = 0
});
return command_buffer;
}
void
gsk_vulkan_command_pool_submit_buffer (GskVulkanCommandPool *self,
VkCommandBuffer command_buffer,
gsize wait_semaphore_count,
VkSemaphore *wait_semaphores,
gsize signal_semaphore_count,
VkSemaphore *signal_semaphores,
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_FRAGMENT_SHADER_BIT;
}
GSK_VK_CHECK (vkQueueSubmit, gdk_vulkan_context_get_queue (self->vulkan),
1,
&(VkSubmitInfo) {
.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
.waitSemaphoreCount = wait_semaphore_count,
.pWaitSemaphores = wait_semaphores,
.pWaitDstStageMask = wait_semaphore_flags,
.commandBufferCount = 1,
.pCommandBuffers = (VkCommandBuffer[1]) {
command_buffer
},
.signalSemaphoreCount = signal_semaphore_count,
.pSignalSemaphores = signal_semaphores,
},
fence);
}