1 #include "config.h"
2 
3 #include "gskvulkancommandpoolprivate.h"
4 #include "gskvulkanpipelineprivate.h"
5 
6 struct _GskVulkanCommandPool
7 {
8   GdkVulkanContext *vulkan;
9 
10   VkCommandPool vk_command_pool;
11   GPtrArray *buffers;
12 };
13 
14 GskVulkanCommandPool *
gsk_vulkan_command_pool_new(GdkVulkanContext * context)15 gsk_vulkan_command_pool_new (GdkVulkanContext *context)
16 {
17   GskVulkanCommandPool *self;
18 
19   self = g_slice_new0 (GskVulkanCommandPool);
20 
21   self->vulkan = g_object_ref (context);
22 
23   GSK_VK_CHECK (vkCreateCommandPool, gdk_vulkan_context_get_device (context),
24                                      &(const VkCommandPoolCreateInfo) {
25                                          .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
26                                          .queueFamilyIndex = gdk_vulkan_context_get_queue_family_index (self->vulkan),
27                                          .flags = 0
28                                      },
29                                      NULL,
30                                      &self->vk_command_pool);
31 
32   self->buffers = g_ptr_array_new ();
33 
34   return self;
35 }
36 
37 static void
gsk_vulkan_command_pool_free_buffers(GskVulkanCommandPool * self)38 gsk_vulkan_command_pool_free_buffers (GskVulkanCommandPool *self)
39 {
40   vkFreeCommandBuffers (gdk_vulkan_context_get_device (self->vulkan),
41                         self->vk_command_pool,
42                         self->buffers->len,
43                         (VkCommandBuffer *) self->buffers->pdata);
44 
45   g_ptr_array_set_size (self->buffers, 0);
46 }
47 
48 void
gsk_vulkan_command_pool_free(GskVulkanCommandPool * self)49 gsk_vulkan_command_pool_free (GskVulkanCommandPool *self)
50 {
51   gsk_vulkan_command_pool_free_buffers (self);
52   g_ptr_array_unref (self->buffers);
53 
54   vkDestroyCommandPool (gdk_vulkan_context_get_device (self->vulkan),
55                         self->vk_command_pool,
56                         NULL);
57 
58   g_slice_free (GskVulkanCommandPool, self);
59 }
60 
61 void
gsk_vulkan_command_pool_reset(GskVulkanCommandPool * self)62 gsk_vulkan_command_pool_reset (GskVulkanCommandPool *self)
63 {
64   gsk_vulkan_command_pool_free_buffers (self);
65 
66   GSK_VK_CHECK (vkResetCommandPool, gdk_vulkan_context_get_device (self->vulkan),
67                                     self->vk_command_pool,
68                                     0);
69 }
70 
71 VkCommandBuffer
gsk_vulkan_command_pool_get_buffer(GskVulkanCommandPool * self)72 gsk_vulkan_command_pool_get_buffer (GskVulkanCommandPool *self)
73 {
74   VkCommandBuffer command_buffer;
75 
76   GSK_VK_CHECK (vkAllocateCommandBuffers, gdk_vulkan_context_get_device (self->vulkan),
77                                           &(VkCommandBufferAllocateInfo) {
78                                               .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
79                                               .commandPool = self->vk_command_pool,
80                                               .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
81                                               .commandBufferCount = 1,
82                                           },
83                                           &command_buffer);
84   g_ptr_array_add (self->buffers, command_buffer);
85 
86   GSK_VK_CHECK (vkBeginCommandBuffer, command_buffer,
87                                       &(VkCommandBufferBeginInfo) {
88                                           .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
89                                           .flags = 0
90                                       });
91 
92   return command_buffer;
93 }
94 
95 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)96 gsk_vulkan_command_pool_submit_buffer (GskVulkanCommandPool *self,
97                                        VkCommandBuffer       command_buffer,
98                                        gsize                 wait_semaphore_count,
99                                        VkSemaphore          *wait_semaphores,
100                                        gsize                 signal_semaphore_count,
101                                        VkSemaphore          *signal_semaphores,
102                                        VkFence               fence)
103 {
104   VkPipelineStageFlags *wait_semaphore_flags = NULL;
105 
106   GSK_VK_CHECK (vkEndCommandBuffer, command_buffer);
107 
108   if (wait_semaphore_count > 0)
109     {
110       wait_semaphore_flags = alloca (sizeof (VkPipelineStageFlags) * wait_semaphore_count);
111       for (int i = 0; i < wait_semaphore_count; i++)
112         wait_semaphore_flags[i] = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
113     }
114 
115   GSK_VK_CHECK (vkQueueSubmit, gdk_vulkan_context_get_queue (self->vulkan),
116                                1,
117                                &(VkSubmitInfo) {
118                                   .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO,
119                                   .waitSemaphoreCount = wait_semaphore_count,
120                                   .pWaitSemaphores = wait_semaphores,
121                                   .pWaitDstStageMask = wait_semaphore_flags,
122                                   .commandBufferCount = 1,
123                                   .pCommandBuffers = (VkCommandBuffer[1]) {
124                                       command_buffer
125                                   },
126                                   .signalSemaphoreCount = signal_semaphore_count,
127                                   .pSignalSemaphores = signal_semaphores,
128                                },
129                                fence);
130 }
131 
132