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

◆ create_pipeline()

RenderPipelineID MayaFlux::Portal::Graphics::RenderFlow::create_pipeline ( const RenderPipelineConfig config,
const std::vector< vk::Format > &  color_formats,
vk::Format  depth_format = vk::Format::eUndefined 
)

Create graphics pipeline for dynamic rendering (no render pass object)

Parameters
configPipeline configuration
color_formatsColor attachment formats for dynamic rendering
depth_formatDepth attachment format
Returns
Pipeline ID or INVALID_RENDER_PIPELINE on error

Definition at line 261 of file RenderFlow.cpp.

265{
266 if (!is_initialized()) {
268 "RenderFlow not initialized");
270 }
271
272 if (config.mesh_shader == INVALID_SHADER && config.vertex_shader == INVALID_SHADER) {
274 "Pipeline requires either mesh shader or vertex shader");
276 }
277
278 if (color_formats.empty()) {
280 "At least one color format required for dynamic rendering pipeline");
282 }
283
284 Core::GraphicsPipelineConfig vk_config;
285
286 vk_config.vertex_shader = m_shader_foundry->get_vk_shader_module(config.vertex_shader);
287 if (config.fragment_shader != INVALID_SHADER) {
288 vk_config.fragment_shader = m_shader_foundry->get_vk_shader_module(config.fragment_shader);
289 }
290 if (config.geometry_shader != INVALID_SHADER) {
291 vk_config.geometry_shader = m_shader_foundry->get_vk_shader_module(config.geometry_shader);
292 }
293 if (config.tess_control_shader != INVALID_SHADER) {
294 vk_config.tess_control_shader = m_shader_foundry->get_vk_shader_module(config.tess_control_shader);
295 }
296 if (config.tess_eval_shader != INVALID_SHADER) {
297 vk_config.tess_evaluation_shader = m_shader_foundry->get_vk_shader_module(config.tess_eval_shader);
298 }
299
300 vk_config.mesh_shader = m_shader_foundry->get_vk_shader_module(config.mesh_shader);
301 if (config.task_shader != INVALID_SHADER) {
302 vk_config.task_shader = m_shader_foundry->get_vk_shader_module(config.task_shader);
303 }
304
305 if (config.fragment_shader != INVALID_SHADER) {
306 vk_config.fragment_shader = m_shader_foundry->get_vk_shader_module(config.fragment_shader);
307 }
308
309 if (config.semantic_vertex_layout.has_value()) {
311 "Pipeline using semantic VertexLayout ({} vertices, {} attributes)",
312 config.semantic_vertex_layout->vertex_count,
313 config.semantic_vertex_layout->attributes.size());
314
315 auto [vk_bindings, vk_attributes] = translate_semantic_layout(
316 config.semantic_vertex_layout.value());
317
318 vk_config.vertex_bindings = vk_bindings;
319 vk_config.vertex_attributes = vk_attributes;
320 vk_config.use_vertex_shader_reflection = false;
321
322 } else if (!config.vertex_bindings.empty() || !config.vertex_attributes.empty()) {
324 "Pipeline using explicit vertex config ({} bindings, {} attributes)",
325 config.vertex_bindings.size(), config.vertex_attributes.size());
326
327 for (const auto& binding : config.vertex_bindings) {
328 Core::VertexBinding vk_binding {};
329 vk_binding.binding = binding.binding;
330 vk_binding.stride = binding.stride;
331 vk_binding.input_rate = binding.per_instance ? vk::VertexInputRate::eInstance : vk::VertexInputRate::eVertex;
332 vk_config.vertex_bindings.push_back(vk_binding);
333 }
334
335 for (const auto& attr : config.vertex_attributes) {
336 Core::VertexAttribute vk_attr {};
337 vk_attr.location = attr.location;
338 vk_attr.binding = attr.binding;
339 vk_attr.format = attr.format;
340 vk_attr.offset = attr.offset;
341 vk_config.vertex_attributes.push_back(vk_attr);
342 }
343
344 vk_config.use_vertex_shader_reflection = false;
345 } else {
347 "Pipeline will use shader reflection for vertex input");
348 vk_config.use_vertex_shader_reflection = config.use_vertex_shader_reflection;
349 }
350
351 vk_config.topology = to_vk_topology(config.topology);
352 vk_config.primitive_restart_enable = false;
353
354 vk_config.polygon_mode = to_vk_polygon_mode(config.rasterization.polygon_mode);
355 vk_config.cull_mode = to_vk_cull_mode(config.rasterization.cull_mode);
356 vk_config.front_face = config.rasterization.front_face_ccw ? vk::FrontFace::eCounterClockwise : vk::FrontFace::eClockwise;
357 vk_config.line_width = config.rasterization.line_width;
358 vk_config.depth_clamp_enable = config.rasterization.depth_clamp;
359 vk_config.depth_bias_enable = config.rasterization.depth_bias;
360
361 vk_config.depth_test_enable = config.depth_stencil.depth_test_enable;
362 vk_config.depth_write_enable = config.depth_stencil.depth_write_enable;
363 vk_config.depth_compare_op = to_vk_compare_op(config.depth_stencil.depth_compare_op);
364 vk_config.stencil_test_enable = config.depth_stencil.stencil_test_enable;
365
366 for (const auto& blend : config.blend_attachments) {
367 Core::ColorBlendAttachment vk_blend;
368 vk_blend.blend_enable = blend.blend_enable;
369 vk_blend.src_color_blend_factor = to_vk_blend_factor(blend.src_color_factor);
370 vk_blend.dst_color_blend_factor = to_vk_blend_factor(blend.dst_color_factor);
371 vk_blend.color_blend_op = to_vk_blend_op(blend.color_blend_op);
372 vk_blend.src_alpha_blend_factor = to_vk_blend_factor(blend.src_alpha_factor);
373 vk_blend.dst_alpha_blend_factor = to_vk_blend_factor(blend.dst_alpha_factor);
374 vk_blend.alpha_blend_op = to_vk_blend_op(blend.alpha_blend_op);
375 vk_config.color_blend_attachments.push_back(vk_blend);
376 }
377
378 std::vector<vk::DescriptorSetLayout> layouts;
379 for (const auto& desc_set : config.descriptor_sets) {
380 std::vector<vk::DescriptorSetLayoutBinding> bindings;
381 for (const auto& binding : desc_set) {
382 vk::DescriptorSetLayoutBinding vk_binding;
383 vk_binding.binding = binding.binding;
384 vk_binding.descriptorType = binding.type;
385 vk_binding.descriptorCount = 1;
386 vk_binding.stageFlags = vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eFragment;
387 bindings.push_back(vk_binding);
388 }
389
390 vk::DescriptorSetLayoutCreateInfo layout_info;
391 layout_info.bindingCount = static_cast<uint32_t>(bindings.size());
392 layout_info.pBindings = bindings.data();
393
394 auto layout = m_shader_foundry->get_device().createDescriptorSetLayout(layout_info);
395 layouts.push_back(layout);
396 }
397 vk_config.descriptor_set_layouts = layouts;
398
399 vk::ShaderStageFlags push_constant_stages;
400
401 if (config.mesh_shader != INVALID_SHADER) {
402 push_constant_stages = vk::ShaderStageFlagBits::eMeshEXT;
403 if (config.task_shader != INVALID_SHADER) {
404 push_constant_stages |= vk::ShaderStageFlagBits::eTaskEXT;
405 }
406 if (config.fragment_shader != INVALID_SHADER) {
407 push_constant_stages |= vk::ShaderStageFlagBits::eFragment;
408 }
409 } else {
410 push_constant_stages = vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eFragment;
411 if (config.geometry_shader != INVALID_SHADER) {
412 push_constant_stages |= vk::ShaderStageFlagBits::eGeometry;
413 }
414 if (config.tess_control_shader != INVALID_SHADER) {
415 push_constant_stages |= vk::ShaderStageFlagBits::eTessellationControl;
416 }
417 if (config.tess_eval_shader != INVALID_SHADER) {
418 push_constant_stages |= vk::ShaderStageFlagBits::eTessellationEvaluation;
419 }
420 }
421
422 if (config.push_constant_size > 0) {
423 vk::PushConstantRange range;
424 range.stageFlags = push_constant_stages;
425 range.offset = 0;
426 range.size = static_cast<uint32_t>(config.push_constant_size);
427 vk_config.push_constant_ranges.push_back(range);
428 }
429
430 vk_config.color_attachment_formats = color_formats;
431 vk_config.depth_attachment_format = depth_format;
432
433 vk_config.dynamic_states = {
434 vk::DynamicState::eViewport,
435 vk::DynamicState::eScissor
436 };
437
438 auto pipeline = std::make_shared<Core::VKGraphicsPipeline>();
439 if (!pipeline->create(m_shader_foundry->get_device(), vk_config)) {
441 "Failed to create VKGraphicsPipeline for dynamic rendering");
442
443 for (auto layout : layouts) {
444 m_shader_foundry->get_device().destroyDescriptorSetLayout(layout);
445 }
447 }
448
449 auto pipeline_id = m_next_pipeline_id.fetch_add(1);
450 PipelineState state;
451 state.shader_ids = { config.vertex_shader, config.fragment_shader };
452 state.pipeline = pipeline;
453 state.layouts = layouts;
454 state.layout = pipeline->get_layout();
455 state.push_constant_stages = push_constant_stages;
456 m_pipelines[pipeline_id] = std::move(state);
457
459 "Dynamic rendering pipeline created (ID: {}, {} color attachments)",
460 pipeline_id, color_formats.size());
461
462 return pipeline_id;
463}
#define MF_INFO(comp, ctx,...)
#define MF_ERROR(comp, ctx,...)
#define MF_DEBUG(comp, ctx,...)
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.
std::vector< double > range(std::span< const double > data, size_t n_windows, uint32_t hop_size, uint32_t window_size)
Value range (max - min) per window.
Definition Analysis.cpp:452
constexpr RenderPipelineID INVALID_RENDER_PIPELINE
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_attachment_formats, MayaFlux::Core::GraphicsPipelineConfig::color_blend_attachments, MayaFlux::Core::ColorBlendAttachment::color_blend_op, MayaFlux::Core::GraphicsPipelineConfig::cull_mode, MayaFlux::Portal::Graphics::RasterizationConfig::cull_mode, MayaFlux::Core::GraphicsPipelineConfig::depth_attachment_format, 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_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_shader_foundry, MayaFlux::Core::GraphicsPipelineConfig::mesh_shader, MayaFlux::Portal::Graphics::RenderPipelineConfig::mesh_shader, 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::RenderFlow::PipelineState::push_constant_stages, MayaFlux::Portal::Graphics::RenderPipelineConfig::rasterization, 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::task_shader, MayaFlux::Portal::Graphics::RenderPipelineConfig::task_shader, 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.

+ Here is the call graph for this function: