135 VkCommandPool vk_command_pool = VK_NULL_HANDLE;
136 VkCommandPoolCreateInfo vk_command_pool_create_info = {
137 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
139 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT | VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
140 device->vk_queue_family_};
141 vkCreateCommandPool(device->vk_device_, &vk_command_pool_create_info,
nullptr, &vk_command_pool);
147 VkCommandBuffer vk_command_buffer = VK_NULL_HANDLE;
151 std::optional<render_graph::VKCommandBufferWrapper> command_buffer;
158 if (submit_task ==
nullptr) {
169 if (submit_task->
wait_semaphore != VK_NULL_HANDLE && command_buffer.has_value()) {
170 command_buffer->end_recording();
171 unsubmitted_command_buffers.
append(vk_command_buffer);
172 command_buffer.reset();
175 if (!command_buffer.has_value()) {
177 if (command_buffers_unused.
is_empty()) {
178 command_buffers_in_use.
remove_old(current_timeline,
179 [&](VkCommandBuffer vk_command_buffer) {
180 command_buffers_unused.
append(vk_command_buffer);
185 if (command_buffers_unused.
is_empty()) {
186 command_buffers_unused.
resize(10, VK_NULL_HANDLE);
187 VkCommandBufferAllocateInfo vk_command_buffer_allocate_info = {
188 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
191 VK_COMMAND_BUFFER_LEVEL_PRIMARY,
193 vkAllocateCommandBuffers(
194 device->vk_device_, &vk_command_buffer_allocate_info, command_buffers_unused.
data());
197 vk_command_buffer = command_buffers_unused.
pop_last();
198 command_buffer = std::make_optional<render_graph::VKCommandBufferWrapper>(
199 vk_command_buffer, device->extensions_);
200 command_buffer->begin_recording();
203 BLI_assert(vk_command_buffer != VK_NULL_HANDLE);
215 submit_infos.
clear();
216 if (!unsubmitted_command_buffers.
is_empty()) {
217 VkSubmitInfo vk_submit_info = {VK_STRUCTURE_TYPE_SUBMIT_INFO,
222 uint32_t(unsubmitted_command_buffers.
size()),
223 unsubmitted_command_buffers.
data(),
226 submit_infos.
append(vk_submit_info);
230 command_buffer->end_recording();
231 unsubmitted_command_buffers.
append(vk_command_buffer);
233 uint32_t wait_semaphore_len = submit_task->
wait_semaphore == VK_NULL_HANDLE ? 0 : 1;
234 uint32_t signal_semaphore_len = submit_task->
signal_semaphore == VK_NULL_HANDLE ? 1 : 2;
235 VkSemaphore signal_semaphores[2] = {device->vk_timeline_semaphore_,
239 VkTimelineSemaphoreSubmitInfo vk_timeline_semaphore_submit_info = {
240 VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO,
244 signal_semaphore_len,
245 signal_semaphore_values};
246 VkSubmitInfo vk_submit_info = {VK_STRUCTURE_TYPE_SUBMIT_INFO,
247 &vk_timeline_semaphore_submit_info,
252 &unsubmitted_command_buffers.
last(),
253 signal_semaphore_len,
255 submit_infos.
append(vk_submit_info);
258 std::scoped_lock lock_queue(*device->queue_mutex_);
259 vkQueueSubmit(device->vk_queue_,
265 std::unique_lock<blender::Mutex>
lock(
270 vk_command_buffer = VK_NULL_HANDLE;
271 for (VkCommandBuffer vk_command_buffer : unsubmitted_command_buffers) {
274 unsubmitted_command_buffers.clear();
275 command_buffer.reset();
282 MEM_delete<VKRenderGraphSubmitTask>(submit_task);
288 std::scoped_lock
lock(*device->queue_mutex_);
289 vkDeviceWaitIdle(device->vk_device_);
292 command_buffers_unused.
append(vk_command_buffer);
294 vkFreeCommandBuffers(device->vk_device_,
296 command_buffers_unused.
size(),
297 command_buffers_unused.
data());
298 vkDestroyCommandPool(device->vk_device_, vk_command_pool,
nullptr);