336{
338 if (!ctx) {
340 "Window not registered for submit_and_present");
341 return;
342 }
343
345
346 size_t frame_index = ctx->current_frame;
347 auto& in_flight = ctx->in_flight[frame_index];
348 auto& image_available = ctx->image_available[frame_index];
349 auto& render_finished = ctx->render_finished[frame_index];
350
351 vk::SubmitInfo submit_info {};
352 vk::PipelineStageFlags wait_stages[] = { vk::PipelineStageFlagBits::eColorAttachmentOutput };
353 submit_info.waitSemaphoreCount = 1;
354 submit_info.pWaitSemaphores = &image_available;
355 submit_info.pWaitDstStageMask = wait_stages;
356 submit_info.commandBufferCount = 1;
357 submit_info.pCommandBuffers = &command_buffer;
358 submit_info.signalSemaphoreCount = 1;
359 submit_info.pSignalSemaphores = &render_finished;
360
361 try {
362 auto result = graphics_queue.submit(1, &submit_info, in_flight);
363 } catch (const vk::SystemError& e) {
365 "Failed to submit primary command buffer: {}", e.what());
366 return;
367 }
368
369 bool present_success = ctx->swapchain->present(
370 ctx->current_image_index, render_finished, graphics_queue);
371
372 if (!present_success) {
373 ctx->needs_recreation = true;
374 }
375
376 ctx->current_frame = (frame_index + 1) % ctx->in_flight.size();
377
379 "Window '{}': frame submitted and presented",
380 window->get_create_info().title);
381}
#define MF_RT_ERROR(comp, ctx,...)
#define MF_RT_TRACE(comp, ctx,...)
WindowRenderContext * find_window_context(const std::shared_ptr< Window > &window)
vk::Queue get_graphics_queue() const
Get graphics queue.
@ GraphicsCallback
Graphics/visual rendering callback - frame-rate real-time.
@ Core
Core engine, backend, subsystems.