| 312 | } |
| 313 | |
| 314 | bool vulkan_renderer::commit_internal(const bool is_blocking, const bool is_finishing, |
| 315 | completion_handler_f&& user_compl_handler, |
| 316 | function<void(const vulkan_command_buffer&)>&& renderer_compl_handler) { |
| 317 | assert(((!is_blocking && is_finishing) || is_blocking) && "non-blocking commit must always finish"); |
| 318 | assert(((!is_blocking && renderer_compl_handler) || is_blocking) && "non-blocking commit must have a renderer completion handler"); |
| 319 | |
| 320 | const auto& vk_queue = (const vulkan_queue&)cqueue; |
| 321 | |
| 322 | // add the completion handler for later (must do this before submission) |
| 323 | if (user_compl_handler) { |
| 324 | (void)add_completion_handler(std::move(user_compl_handler)); |
| 325 | } |
| 326 | |
| 327 | // non-blocking: add present completion handler at the end |
| 328 | if (!is_blocking && is_presenting) { |
| 329 | (void)add_completion_handler([this]() { |
| 330 | ((vulkan_compute*)cqueue.get_device().context)->queue_present(cqueue, cur_drawable->vk_drawable); |
| 331 | }); |
| 332 | } |
| 333 | |
| 334 | // if any image layout transitions are necessary, perform them now |
| 335 | if (!img_transition_barriers.empty()) { |
| 336 | VK_CMD_BLOCK_RET(vk_queue, "image layout transition", ({ |
| 337 | const VkDependencyInfo dep_info { |
| 338 | .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO, |
| 339 | .pNext = nullptr, |
| 340 | .dependencyFlags = 0, |
| 341 | .memoryBarrierCount = 0, |
| 342 | .pMemoryBarriers = nullptr, |
| 343 | .bufferMemoryBarrierCount = 0, |
| 344 | .pBufferMemoryBarriers = nullptr, |
| 345 | .imageMemoryBarrierCount = uint32_t(img_transition_barriers.size()), |
| 346 | .pImageMemoryBarriers = &img_transition_barriers[0], |
| 347 | }; |
| 348 | vkCmdPipelineBarrier2(block_cmd_buffer.cmd_buffer, &dep_info); |
| 349 | }), false, is_blocking); |
| 350 | } |
| 351 | |
| 352 | if (is_presenting) { |
| 353 | // transition drawable image back to present mode (after render pass is complete) |
| 354 | cur_drawable->vk_image->transition(&cqueue, render_cmd_buffer.cmd_buffer, 0 /* as per doc */, cur_drawable->vk_drawable.present_layout, |
| 355 | VK_PIPELINE_STAGE_2_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT); |
| 356 | } |
| 357 | |
| 358 | VK_CALL_RET(vkEndCommandBuffer(render_cmd_buffer.cmd_buffer), "failed to end command buffer", false) |
| 359 | vk_queue.submit_command_buffer(std::move(render_cmd_buffer), std::move(wait_fences), std::move(signal_fences), |
| 360 | std::move(renderer_compl_handler), is_blocking); |
| 361 | |
| 362 | // NOTE: all of this can only be called when doing a blocking commit(), for non-blocking commits, ownership |
| 363 | if (is_blocking) { |
| 364 | // if present has been called earlier, we can now actually present the image to the screen |
| 365 | if (is_presenting) { |
| 366 | ((vulkan_compute*)cqueue.get_device().context)->queue_present(cqueue, cur_drawable->vk_drawable); |
| 367 | is_presenting = false; |
| 368 | } |
| 369 | |
| 370 | if (!is_finishing) { |
| 371 | // reset |
no test coverage detected