@@ -392,88 +392,97 @@ bool SwapchainImplVK::Present(const std::shared_ptr<SwapchainImageVK>& image,
392392 }
393393
394394 const auto & context = ContextVK::Cast (*context_strong);
395+ context.GetConcurrentWorkerTaskRunner ()->PostTask (
396+ [&, index, image, current_frame = current_frame_] {
397+ auto context_strong = context_.lock ();
398+ if (!context_strong) {
399+ return ;
400+ }
401+ const auto & context = ContextVK::Cast (*context_strong);
402+ const auto & sync = synchronizers_[current_frame];
403+
404+ // ----------------------------------------------------------------------------
405+ // / Transition the image to color-attachment-optimal.
406+ // /
407+ sync->final_cmd_buffer = context.CreateCommandBuffer ();
408+ if (!sync->final_cmd_buffer ) {
409+ return ;
410+ }
395411
396- const auto & sync = synchronizers_[current_frame_];
397-
398- // ----------------------------------------------------------------------------
399- // / Transition the image to color-attachment-optimal.
400- // /
401- sync->final_cmd_buffer = context.CreateCommandBuffer ();
402- if (!sync->final_cmd_buffer ) {
403- return false ;
404- }
405-
406- auto vk_final_cmd_buffer = CommandBufferVK::Cast (*sync->final_cmd_buffer )
407- .GetEncoder ()
408- ->GetCommandBuffer ();
409- {
410- BarrierVK barrier;
411- barrier.new_layout = vk::ImageLayout::ePresentSrcKHR;
412- barrier.cmd_buffer = vk_final_cmd_buffer;
413- barrier.src_access = vk::AccessFlagBits::eColorAttachmentWrite;
414- barrier.src_stage = vk::PipelineStageFlagBits::eColorAttachmentOutput;
415- barrier.dst_access = {};
416- barrier.dst_stage = vk::PipelineStageFlagBits::eBottomOfPipe;
417-
418- if (!image->SetLayout (barrier)) {
419- return false ;
420- }
421-
422- if (vk_final_cmd_buffer.end () != vk::Result::eSuccess) {
423- return false ;
424- }
425- }
412+ auto vk_final_cmd_buffer =
413+ CommandBufferVK::Cast (*sync->final_cmd_buffer )
414+ .GetEncoder ()
415+ ->GetCommandBuffer ();
416+ {
417+ BarrierVK barrier;
418+ barrier.new_layout = vk::ImageLayout::ePresentSrcKHR;
419+ barrier.cmd_buffer = vk_final_cmd_buffer;
420+ barrier.src_access = vk::AccessFlagBits::eColorAttachmentWrite;
421+ barrier.src_stage = vk::PipelineStageFlagBits::eColorAttachmentOutput;
422+ barrier.dst_access = {};
423+ barrier.dst_stage = vk::PipelineStageFlagBits::eBottomOfPipe;
424+
425+ if (!image->SetLayout (barrier)) {
426+ return ;
427+ }
428+
429+ if (vk_final_cmd_buffer.end () != vk::Result::eSuccess) {
430+ return ;
431+ }
432+ }
426433
427- // ----------------------------------------------------------------------------
428- // / Signal that the presentation semaphore is ready.
429- // /
430- {
431- vk::SubmitInfo submit_info;
432- vk::PipelineStageFlags wait_stage =
433- vk::PipelineStageFlagBits::eColorAttachmentOutput;
434- submit_info.setWaitDstStageMask (wait_stage);
435- submit_info.setWaitSemaphores (*sync->render_ready );
436- submit_info.setSignalSemaphores (*sync->present_ready );
437- submit_info.setCommandBuffers (vk_final_cmd_buffer);
438- auto result =
439- context.GetGraphicsQueue ()->Submit (submit_info, *sync->acquire );
440- if (result != vk::Result::eSuccess) {
441- VALIDATION_LOG << " Could not wait on render semaphore: "
442- << vk::to_string (result);
443- return false ;
444- }
445- }
434+ // ----------------------------------------------------------------------------
435+ // / Signal that the presentation semaphore is ready.
436+ // /
437+ {
438+ vk::SubmitInfo submit_info;
439+ vk::PipelineStageFlags wait_stage =
440+ vk::PipelineStageFlagBits::eColorAttachmentOutput;
441+ submit_info.setWaitDstStageMask (wait_stage);
442+ submit_info.setWaitSemaphores (*sync->render_ready );
443+ submit_info.setSignalSemaphores (*sync->present_ready );
444+ submit_info.setCommandBuffers (vk_final_cmd_buffer);
445+ auto result =
446+ context.GetGraphicsQueue ()->Submit (submit_info, *sync->acquire );
447+ if (result != vk::Result::eSuccess) {
448+ VALIDATION_LOG << " Could not wait on render semaphore: "
449+ << vk::to_string (result);
450+ return ;
451+ }
452+ }
446453
447- // ----------------------------------------------------------------------------
448- // / Present the image.
449- // /
450- uint32_t indices[] = {static_cast <uint32_t >(index)};
451-
452- vk::PresentInfoKHR present_info;
453- present_info.setSwapchains (*swapchain_);
454- present_info.setImageIndices (indices);
455- present_info.setWaitSemaphores (*sync->present_ready );
456-
457- switch (auto result = present_queue_.presentKHR (present_info)) {
458- case vk::Result::eErrorOutOfDateKHR:
459- // Caller will recreate the impl on acquisition, not submission.
460- [[fallthrough]];
461- case vk::Result::eErrorSurfaceLostKHR:
462- // Vulkan guarantees that the set of queue operations will still complete
463- // successfully.
464- [[fallthrough]];
465- case vk::Result::eSuccess:
466- is_rotated_ = false ;
467- return true ;
468- case vk::Result::eSuboptimalKHR:
469- is_rotated_ = true ;
470- return true ;
471- default :
472- VALIDATION_LOG << " Could not present queue: " << vk::to_string (result);
473- return false ;
474- }
475- FML_UNREACHABLE ();
476- return false ;
454+ // ----------------------------------------------------------------------------
455+ // / Present the image.
456+ // /
457+ uint32_t indices[] = {static_cast <uint32_t >(index)};
458+
459+ vk::PresentInfoKHR present_info;
460+ present_info.setSwapchains (*swapchain_);
461+ present_info.setImageIndices (indices);
462+ present_info.setWaitSemaphores (*sync->present_ready );
463+
464+ switch (auto result = present_queue_.presentKHR (present_info)) {
465+ case vk::Result::eErrorOutOfDateKHR:
466+ // Caller will recreate the impl on acquisition, not submission.
467+ [[fallthrough]];
468+ case vk::Result::eErrorSurfaceLostKHR:
469+ // Vulkan guarantees that the set of queue operations will still
470+ // complete successfully.
471+ [[fallthrough]];
472+ case vk::Result::eSuccess:
473+ is_rotated_ = false ;
474+ return ;
475+ case vk::Result::eSuboptimalKHR:
476+ is_rotated_ = true ;
477+ return ;
478+ default :
479+ VALIDATION_LOG << " Could not present queue: "
480+ << vk::to_string (result);
481+ return ;
482+ }
483+ FML_UNREACHABLE ();
484+ });
485+ return true ;
477486}
478487
479488} // namespace impeller
0 commit comments