MayaFlux 0.1.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches

◆ create_pipeline()

RenderPipelineID MayaFlux::Portal::Graphics::RenderFlow::create_pipeline ( const RenderPipelineConfig config)

Create graphics pipeline with full configuration.

Parameters
configComplete pipeline configuration
Returns
Pipeline ID or INVALID_RENDER_PIPELINE on error

Definition at line 377 of file RenderFlow.cpp.

378{
379 if (!is_initialized()) {
381 "RenderFlow not initialized");
383 }
384
385 if (config.vertex_shader == INVALID_SHADER) {
387 "Vertex shader required for graphics pipeline");
389 }
390
391 if (config.render_pass == INVALID_RENDER_PASS) {
393 "Render pass required for graphics pipeline");
394 return INVALID_RENDER_PASS;
395 }
396
397 auto rp_it = m_render_passes.find(config.render_pass);
398 if (rp_it == m_render_passes.end()) {
400 "Invalid render pass ID: {}", config.render_pass);
402 }
403
404 Core::GraphicsPipelineConfig vk_config;
405
406 vk_config.vertex_shader = m_shader_foundry->get_vk_shader_module(config.vertex_shader);
407 if (config.fragment_shader != INVALID_SHADER) {
408 vk_config.fragment_shader = m_shader_foundry->get_vk_shader_module(config.fragment_shader);
409 }
410 if (config.geometry_shader != INVALID_SHADER) {
411 vk_config.geometry_shader = m_shader_foundry->get_vk_shader_module(config.geometry_shader);
412 }
413 if (config.tess_control_shader != INVALID_SHADER) {
414 vk_config.tess_control_shader = m_shader_foundry->get_vk_shader_module(config.tess_control_shader);
415 }
416 if (config.tess_eval_shader != INVALID_SHADER) {
417 vk_config.tess_evaluation_shader = m_shader_foundry->get_vk_shader_module(config.tess_eval_shader);
418 }
419
420 if (config.semantic_vertex_layout.has_value()) {
422 "Pipeline using semantic VertexLayout ({} vertices, {} attributes)",
423 config.semantic_vertex_layout->vertex_count,
424 config.semantic_vertex_layout->attributes.size());
425
426 auto [vk_bindings, vk_attributes] = translate_semantic_layout(
427 config.semantic_vertex_layout.value());
428
429 vk_config.vertex_bindings = vk_bindings;
430 vk_config.vertex_attributes = vk_attributes;
431 vk_config.use_vertex_shader_reflection = false;
432
433 } else if (!config.vertex_bindings.empty() || !config.vertex_attributes.empty()) {
435 "Pipeline using explicit vertex config ({} bindings, {} attributes)",
436 config.vertex_bindings.size(), config.vertex_attributes.size());
437
438 for (const auto& binding : config.vertex_bindings) {
439 Core::VertexBinding vk_binding {};
440 vk_binding.binding = binding.binding;
441 vk_binding.stride = binding.stride;
442 vk_binding.input_rate = binding.per_instance ? vk::VertexInputRate::eInstance : vk::VertexInputRate::eVertex;
443 vk_config.vertex_bindings.push_back(vk_binding);
444 }
445
446 for (const auto& attr : config.vertex_attributes) {
447 Core::VertexAttribute vk_attr {};
448 vk_attr.location = attr.location;
449 vk_attr.binding = attr.binding;
450 vk_attr.format = attr.format;
451 vk_attr.offset = attr.offset;
452 vk_config.vertex_attributes.push_back(vk_attr);
453 }
454
455 vk_config.use_vertex_shader_reflection = false;
456 } else {
458 "Pipeline will use shader reflection for vertex input");
459 vk_config.use_vertex_shader_reflection = config.use_vertex_shader_reflection;
460 }
461
462 vk_config.topology = to_vk_topology(config.topology);
463 vk_config.primitive_restart_enable = false;
464
465 vk_config.polygon_mode = to_vk_polygon_mode(config.rasterization.polygon_mode);
466 vk_config.cull_mode = to_vk_cull_mode(config.rasterization.cull_mode);
467 vk_config.front_face = config.rasterization.front_face_ccw ? vk::FrontFace::eCounterClockwise : vk::FrontFace::eClockwise;
468 vk_config.line_width = config.rasterization.line_width;
469 vk_config.depth_clamp_enable = config.rasterization.depth_clamp;
470 vk_config.depth_bias_enable = config.rasterization.depth_bias;
471
472 vk_config.depth_test_enable = config.depth_stencil.depth_test_enable;
473 vk_config.depth_write_enable = config.depth_stencil.depth_write_enable;
474 vk_config.depth_compare_op = to_vk_compare_op(config.depth_stencil.depth_compare_op);
475 vk_config.stencil_test_enable = config.depth_stencil.stencil_test_enable;
476
477 for (const auto& blend : config.blend_attachments) {
478 Core::ColorBlendAttachment vk_blend;
479 vk_blend.blend_enable = blend.blend_enable;
480 vk_blend.src_color_blend_factor = to_vk_blend_factor(blend.src_color_factor);
481 vk_blend.dst_color_blend_factor = to_vk_blend_factor(blend.dst_color_factor);
482 vk_blend.color_blend_op = to_vk_blend_op(blend.color_blend_op);
483 vk_blend.src_alpha_blend_factor = to_vk_blend_factor(blend.src_alpha_factor);
484 vk_blend.dst_alpha_blend_factor = to_vk_blend_factor(blend.dst_alpha_factor);
485 vk_blend.alpha_blend_op = to_vk_blend_op(blend.alpha_blend_op);
486 vk_config.color_blend_attachments.push_back(vk_blend);
487 }
488
489 std::vector<vk::DescriptorSetLayout> layouts;
490 for (const auto& desc_set : config.descriptor_sets) {
491 std::vector<vk::DescriptorSetLayoutBinding> bindings;
492 for (const auto& binding : desc_set) {
493 vk::DescriptorSetLayoutBinding vk_binding;
494 vk_binding.binding = binding.binding;
495 vk_binding.descriptorType = binding.type;
496 vk_binding.descriptorCount = 1;
497 vk_binding.stageFlags = vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eFragment;
498 bindings.push_back(vk_binding);
499 }
500
501 vk::DescriptorSetLayoutCreateInfo layout_info;
502 layout_info.bindingCount = static_cast<uint32_t>(bindings.size());
503 layout_info.pBindings = bindings.data();
504
505 auto layout = m_shader_foundry->get_device().createDescriptorSetLayout(layout_info);
506 layouts.push_back(layout);
507 }
508 vk_config.descriptor_set_layouts = layouts;
509
510 if (config.push_constant_size > 0) {
511 vk::PushConstantRange range;
512 range.stageFlags = vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eFragment;
513 range.offset = 0;
514 range.size = static_cast<uint32_t>(config.push_constant_size);
515 vk_config.push_constant_ranges.push_back(range);
516 }
517
518 vk_config.render_pass = rp_it->second.render_pass->get();
519 vk_config.subpass = config.subpass;
520
521 vk_config.dynamic_states = {
522 vk::DynamicState::eViewport,
523 vk::DynamicState::eScissor
524 };
525
526 auto pipeline = std::make_shared<Core::VKGraphicsPipeline>();
527 if (!pipeline->create(m_shader_foundry->get_device(), vk_config)) {
529 "Failed to create VKGraphicsPipeline");
530
531 for (auto layout : layouts) {
532 m_shader_foundry->get_device().destroyDescriptorSetLayout(layout);
533 }
535 }
536
537 auto pipeline_id = m_next_pipeline_id.fetch_add(1);
538 PipelineState state;
539 state.shader_ids = { config.vertex_shader, config.fragment_shader };
540 state.pipeline = pipeline;
541 state.layouts = layouts;
542 state.layout = pipeline->get_layout();
543 state.render_pass = config.render_pass;
544 m_pipelines[pipeline_id] = std::move(state);
545
547 "Graphics pipeline created (ID: {}, {} descriptor sets)",
548 pipeline_id, layouts.size());
549
550 return pipeline_id;
551}
#define MF_INFO(comp, ctx,...)
#define MF_ERROR(comp, ctx,...)
#define MF_DEBUG(comp, ctx,...)
std::unordered_map< RenderPassID, RenderPassState > m_render_passes
std::unordered_map< RenderPipelineID, PipelineState > m_pipelines
std::atomic< uint64_t > m_next_pipeline_id
std::shared_ptr< Core::VKShaderModule > get_vk_shader_module(ShaderID shader_id)
@ Rendering
GPU rendering operations (graphics pipeline, frame rendering)
@ Portal
High-level user-facing API layer.
constexpr RenderPipelineID INVALID_RENDER_PIPELINE
constexpr RenderPassID INVALID_RENDER_PASS
constexpr ShaderID INVALID_SHADER

References MayaFlux::Core::ColorBlendAttachment::alpha_blend_op, MayaFlux::Core::VertexBinding::binding, MayaFlux::Portal::Graphics::RenderPipelineConfig::blend_attachments, MayaFlux::Core::ColorBlendAttachment::blend_enable, MayaFlux::Core::GraphicsPipelineConfig::color_blend_attachments, MayaFlux::Core::ColorBlendAttachment::color_blend_op, MayaFlux::Core::GraphicsPipelineConfig::cull_mode, MayaFlux::Portal::Graphics::RasterizationConfig::cull_mode, MayaFlux::Portal::Graphics::RasterizationConfig::depth_bias, MayaFlux::Core::GraphicsPipelineConfig::depth_bias_enable, MayaFlux::Portal::Graphics::RasterizationConfig::depth_clamp, MayaFlux::Core::GraphicsPipelineConfig::depth_clamp_enable, MayaFlux::Core::GraphicsPipelineConfig::depth_compare_op, MayaFlux::Portal::Graphics::DepthStencilConfig::depth_compare_op, MayaFlux::Portal::Graphics::RenderPipelineConfig::depth_stencil, MayaFlux::Core::GraphicsPipelineConfig::depth_test_enable, MayaFlux::Portal::Graphics::DepthStencilConfig::depth_test_enable, MayaFlux::Core::GraphicsPipelineConfig::depth_write_enable, MayaFlux::Portal::Graphics::DepthStencilConfig::depth_write_enable, MayaFlux::Core::GraphicsPipelineConfig::descriptor_set_layouts, MayaFlux::Portal::Graphics::RenderPipelineConfig::descriptor_sets, MayaFlux::Core::ColorBlendAttachment::dst_alpha_blend_factor, MayaFlux::Core::ColorBlendAttachment::dst_color_blend_factor, MayaFlux::Core::GraphicsPipelineConfig::dynamic_states, MayaFlux::Core::GraphicsPipelineConfig::fragment_shader, MayaFlux::Portal::Graphics::RenderPipelineConfig::fragment_shader, MayaFlux::Core::GraphicsPipelineConfig::front_face, MayaFlux::Portal::Graphics::RasterizationConfig::front_face_ccw, MayaFlux::Core::GraphicsPipelineConfig::geometry_shader, MayaFlux::Portal::Graphics::RenderPipelineConfig::geometry_shader, MayaFlux::Portal::Graphics::ShaderFoundry::get_device(), MayaFlux::Portal::Graphics::ShaderFoundry::get_vk_shader_module(), MayaFlux::Portal::Graphics::INVALID_RENDER_PASS, MayaFlux::Portal::Graphics::INVALID_RENDER_PIPELINE, MayaFlux::Portal::Graphics::INVALID_SHADER, is_initialized(), MayaFlux::Portal::Graphics::RenderFlow::PipelineState::layout, MayaFlux::Portal::Graphics::RenderFlow::PipelineState::layouts, MayaFlux::Core::GraphicsPipelineConfig::line_width, MayaFlux::Portal::Graphics::RasterizationConfig::line_width, MayaFlux::Core::VertexAttribute::location, m_next_pipeline_id, m_pipelines, m_render_passes, m_shader_foundry, MF_DEBUG, MF_ERROR, MF_INFO, MayaFlux::Portal::Graphics::RenderFlow::PipelineState::pipeline, MayaFlux::Core::GraphicsPipelineConfig::polygon_mode, MayaFlux::Portal::Graphics::RasterizationConfig::polygon_mode, MayaFlux::Journal::Portal, MayaFlux::Core::GraphicsPipelineConfig::primitive_restart_enable, MayaFlux::Core::GraphicsPipelineConfig::push_constant_ranges, MayaFlux::Portal::Graphics::RenderPipelineConfig::push_constant_size, MayaFlux::Portal::Graphics::RenderPipelineConfig::rasterization, MayaFlux::Core::GraphicsPipelineConfig::render_pass, MayaFlux::Portal::Graphics::RenderPipelineConfig::render_pass, MayaFlux::Portal::Graphics::RenderFlow::PipelineState::render_pass, MayaFlux::Journal::Rendering, MayaFlux::Portal::Graphics::RenderPipelineConfig::semantic_vertex_layout, MayaFlux::Portal::Graphics::RenderFlow::PipelineState::shader_ids, MayaFlux::Core::ColorBlendAttachment::src_alpha_blend_factor, MayaFlux::Core::ColorBlendAttachment::src_color_blend_factor, MayaFlux::Core::GraphicsPipelineConfig::stencil_test_enable, MayaFlux::Portal::Graphics::DepthStencilConfig::stencil_test_enable, MayaFlux::Core::GraphicsPipelineConfig::subpass, MayaFlux::Portal::Graphics::RenderPipelineConfig::subpass, MayaFlux::Core::GraphicsPipelineConfig::tess_control_shader, MayaFlux::Portal::Graphics::RenderPipelineConfig::tess_control_shader, MayaFlux::Portal::Graphics::RenderPipelineConfig::tess_eval_shader, MayaFlux::Core::GraphicsPipelineConfig::tess_evaluation_shader, MayaFlux::Core::GraphicsPipelineConfig::topology, MayaFlux::Portal::Graphics::RenderPipelineConfig::topology, MayaFlux::Core::GraphicsPipelineConfig::use_vertex_shader_reflection, MayaFlux::Portal::Graphics::RenderPipelineConfig::use_vertex_shader_reflection, MayaFlux::Core::GraphicsPipelineConfig::vertex_attributes, MayaFlux::Portal::Graphics::RenderPipelineConfig::vertex_attributes, MayaFlux::Core::GraphicsPipelineConfig::vertex_bindings, MayaFlux::Portal::Graphics::RenderPipelineConfig::vertex_bindings, MayaFlux::Core::GraphicsPipelineConfig::vertex_shader, and MayaFlux::Portal::Graphics::RenderPipelineConfig::vertex_shader.

Referenced by create_simple_pipeline().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: