458{
460 if (!context) {
462 "No context found for window '{}'",
463 window->get_create_info().title);
464 return;
465 }
466
469
470 size_t frame_index = context->current_frame;
471 auto& in_flight = context->in_flight[frame_index];
472 auto& image_available = context->image_available[frame_index];
473 auto& render_finished = context->render_finished[frame_index];
474
475 if (device.waitForFences(1, &in_flight, VK_TRUE, UINT64_MAX) == vk::Result::eTimeout) {
477 "Skipping frame rendering for window '{}' due to in-flight fence timeout",
478 context->window->get_create_info().title);
479 return;
480 }
481
482 auto image_index_opt = context->swapchain->acquire_next_image(image_available);
483 if (!image_index_opt.has_value()) {
484 context->needs_recreation = true;
485 return;
486 }
487 uint32_t image_index = image_index_opt.value();
488
489 if (device.resetFences(1, &in_flight) != vk::Result::eSuccess) {
491 "Failed to reset in-flight fence for window '{}'",
492 context->window->get_create_info().title);
493 return;
494 }
495
496 vk::SubmitInfo submit_info {};
497 vk::PipelineStageFlags wait_stages[] = { vk::PipelineStageFlagBits::eColorAttachmentOutput };
498 submit_info.waitSemaphoreCount = 1;
499 submit_info.pWaitSemaphores = &image_available;
500 submit_info.pWaitDstStageMask = wait_stages;
501 submit_info.commandBufferCount = 1;
502 submit_info.pCommandBuffers = &(context->command_buffer);
503 submit_info.signalSemaphoreCount = 1;
504 submit_info.pSignalSemaphores = &render_finished;
505
506 try {
507 auto result = graphics_queue.submit(1, &submit_info, in_flight);
508 } catch (const std::exception& e) {
512 std::source_location::current(),
513 "Unexpected error during command buffer submission: {}",
514 e.what());
515 return;
516 }
517
518 bool present_success = context->swapchain->present(image_index, render_finished, graphics_queue);
519 if (!present_success) {
520 context->needs_recreation = true;
521 }
522
523 context->current_frame = (frame_index + 1) % context->in_flight.size();
524}
#define MF_ERROR(comp, ctx,...)
#define MF_RT_WARN(comp, ctx,...)
#define MF_RT_ERROR(comp, ctx,...)
WindowRenderContext * find_window_context(const std::shared_ptr< Window > &window)
vk::Device get_device() const
Get logical device.
vk::Queue get_graphics_queue() const
Get graphics queue.
@ GraphicsBackend
Graphics/visual rendering backend (Vulkan, OpenGL)
void error_rethrow(Component component, Context context, std::source_location location=std::source_location::current(), std::string_view additional_context="")
Catch and log an exception, then rethrow it.
@ Core
Core engine, backend, subsystems.