133 VkCommandPool vk_command_pool = VK_NULL_HANDLE;
134 VkCommandPoolCreateInfo vk_command_pool_create_info = {
135 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
137 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT | VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
138 device->vk_queue_family_};
139 vkCreateCommandPool(device->vk_device_, &vk_command_pool_create_info,
nullptr, &vk_command_pool);
145 VkCommandBuffer vk_command_buffer = VK_NULL_HANDLE;
149 std::optional<render_graph::VKCommandBufferWrapper> command_buffer;
156 if (submit_task ==
nullptr) {
167 if (submit_task->
wait_semaphore != VK_NULL_HANDLE && command_buffer.has_value()) {
168 command_buffer->end_recording();
169 unsubmitted_command_buffers.
append(vk_command_buffer);
170 command_buffer.reset();
173 if (!command_buffer.has_value()) {
175 if (command_buffers_unused.
is_empty()) {
176 command_buffers_in_use.
remove_old(current_timeline,
177 [&](VkCommandBuffer vk_command_buffer) {
178 command_buffers_unused.
append(vk_command_buffer);
183 if (command_buffers_unused.
is_empty()) {
184 command_buffers_unused.
resize(10, VK_NULL_HANDLE);
185 VkCommandBufferAllocateInfo vk_command_buffer_allocate_info = {
186 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
189 VK_COMMAND_BUFFER_LEVEL_PRIMARY,
191 vkAllocateCommandBuffers(
192 device->vk_device_, &vk_command_buffer_allocate_info, command_buffers_unused.
data());
195 vk_command_buffer = command_buffers_unused.
pop_last();
196 command_buffer = std::make_optional<render_graph::VKCommandBufferWrapper>(
197 vk_command_buffer, device->extensions_);
198 command_buffer->begin_recording();
201 BLI_assert(vk_command_buffer != VK_NULL_HANDLE);
213 submit_infos.
clear();
214 if (!unsubmitted_command_buffers.
is_empty()) {
215 VkSubmitInfo vk_submit_info = {VK_STRUCTURE_TYPE_SUBMIT_INFO,
220 uint32_t(unsubmitted_command_buffers.
size()),
221 unsubmitted_command_buffers.
data(),
224 submit_infos.
append(vk_submit_info);
228 command_buffer->end_recording();
229 unsubmitted_command_buffers.
append(vk_command_buffer);
231 uint32_t wait_semaphore_len = submit_task->
wait_semaphore == VK_NULL_HANDLE ? 0 : 1;
232 uint32_t signal_semaphore_len = submit_task->
signal_semaphore == VK_NULL_HANDLE ? 1 : 2;
233 VkSemaphore signal_semaphores[2] = {device->vk_timeline_semaphore_,
237 VkTimelineSemaphoreSubmitInfo vk_timeline_semaphore_submit_info = {
238 VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO,
242 signal_semaphore_len,
243 signal_semaphore_values};
244 VkSubmitInfo vk_submit_info = {VK_STRUCTURE_TYPE_SUBMIT_INFO,
245 &vk_timeline_semaphore_submit_info,
250 &unsubmitted_command_buffers.
last(),
251 signal_semaphore_len,
253 submit_infos.
append(vk_submit_info);
256 std::scoped_lock lock_queue(*device->queue_mutex_);
257 vkQueueSubmit(device->vk_queue_,
263 std::unique_lock<blender::Mutex>
lock(
268 vk_command_buffer = VK_NULL_HANDLE;
269 for (VkCommandBuffer vk_command_buffer : unsubmitted_command_buffers) {
272 unsubmitted_command_buffers.clear();
273 command_buffer.reset();
278 MEM_delete<VKRenderGraphSubmitTask>(submit_task);
280 CLOG_INFO(&
LOG, 3,
"submission runner is being canceled");
283 vkDeviceWaitIdle(device->vk_device_);
285 command_buffers_unused.
append(vk_command_buffer);
287 vkFreeCommandBuffers(device->vk_device_,
289 command_buffers_unused.
size(),
290 command_buffers_unused.
data());
291 vkDestroyCommandPool(device->vk_device_, vk_command_pool,
nullptr);