MayaFlux 0.2.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.vertex_shader == INVALID_SHADER) {
274 "Vertex shader required for graphics pipeline");
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 if (config.semantic_vertex_layout.has_value()) {
302 "Pipeline using semantic VertexLayout ({} vertices, {} attributes)",
303 config.semantic_vertex_layout->vertex_count,
304 config.semantic_vertex_layout->attributes.size());
305
306 auto [vk_bindings, vk_attributes] = translate_semantic_layout(
307 config.semantic_vertex_layout.value());
308
309 vk_config.vertex_bindings = vk_bindings;
310 vk_config.vertex_attributes = vk_attributes;
311 vk_config.use_vertex_shader_reflection = false;
312
313 } else if (!config.vertex_bindings.empty() || !config.vertex_attributes.empty()) {
315 "Pipeline using explicit vertex config ({} bindings, {} attributes)",
316 config.vertex_bindings.size(), config.vertex_attributes.size());
317
318 for (const auto& binding : config.vertex_bindings) {
319 Core::VertexBinding vk_binding {};
320 vk_binding.binding = binding.binding;
321 vk_binding.stride = binding.stride;
322 vk_binding.input_rate = binding.per_instance ? vk::VertexInputRate::eInstance : vk::VertexInputRate::eVertex;
323 vk_config.vertex_bindings.push_back(vk_binding);
324 }
325
326 for (const auto& attr : config.vertex_attributes) {
327 Core::VertexAttribute vk_attr {};
328 vk_attr.location = attr.location;
329 vk_attr.binding = attr.binding;
330 vk_attr.format = attr.format;
331 vk_attr.offset = attr.offset;
332 vk_config.vertex_attributes.push_back(vk_attr);
333 }
334
335 vk_config.use_vertex_shader_reflection = false;
336 } else {
338 "Pipeline will use shader reflection for vertex input");
339 vk_config.use_vertex_shader_reflection = config.use_vertex_shader_reflection;
340 }
341
342 vk_config.topology = to_vk_topology(config.topology);
343 vk_config.primitive_restart_enable = false;
344
345 vk_config.polygon_mode = to_vk_polygon_mode(config.rasterization.polygon_mode);
346 vk_config.cull_mode = to_vk_cull_mode(config.rasterization.cull_mode);
347 vk_config.front_face = config.rasterization.front_face_ccw ? vk::FrontFace::eCounterClockwise : vk::FrontFace::eClockwise;
348 vk_config.line_width = config.rasterization.line_width;
349 vk_config.depth_clamp_enable = config.rasterization.depth_clamp;
350 vk_config.depth_bias_enable = config.rasterization.depth_bias;
351
352 vk_config.depth_test_enable = config.depth_stencil.depth_test_enable;
353 vk_config.depth_write_enable = config.depth_stencil.depth_write_enable;
354 vk_config.depth_compare_op = to_vk_compare_op(config.depth_stencil.depth_compare_op);
355 vk_config.stencil_test_enable = config.depth_stencil.stencil_test_enable;
356
357 for (const auto& blend : config.blend_attachments) {
358 Core::ColorBlendAttachment vk_blend;
359 vk_blend.blend_enable = blend.blend_enable;
360 vk_blend.src_color_blend_factor = to_vk_blend_factor(blend.src_color_factor);
361 vk_blend.dst_color_blend_factor = to_vk_blend_factor(blend.dst_color_factor);
362 vk_blend.color_blend_op = to_vk_blend_op(blend.color_blend_op);
363 vk_blend.src_alpha_blend_factor = to_vk_blend_factor(blend.src_alpha_factor);
364 vk_blend.dst_alpha_blend_factor = to_vk_blend_factor(blend.dst_alpha_factor);
365 vk_blend.alpha_blend_op = to_vk_blend_op(blend.alpha_blend_op);
366 vk_config.color_blend_attachments.push_back(vk_blend);
367 }
368
369 std::vector<vk::DescriptorSetLayout> layouts;
370 for (const auto& desc_set : config.descriptor_sets) {
371 std::vector<vk::DescriptorSetLayoutBinding> bindings;
372 for (const auto& binding : desc_set) {
373 vk::DescriptorSetLayoutBinding vk_binding;
374 vk_binding.binding = binding.binding;
375 vk_binding.descriptorType = binding.type;
376 vk_binding.descriptorCount = 1;
377 vk_binding.stageFlags = vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eFragment;
378 bindings.push_back(vk_binding);
379 }
380
381 vk::DescriptorSetLayoutCreateInfo layout_info;
382 layout_info.bindingCount = static_cast<uint32_t>(bindings.size());
383 layout_info.pBindings = bindings.data();
384
385 auto layout = m_shader_foundry->get_device().createDescriptorSetLayout(layout_info);
386 layouts.push_back(layout);
387 }
388 vk_config.descriptor_set_layouts = layouts;
389
390 if (config.push_constant_size > 0) {
391 vk::PushConstantRange range;
392 range.stageFlags = vk::ShaderStageFlagBits::eVertex | vk::ShaderStageFlagBits::eFragment;
393 range.offset = 0;
394 range.size = static_cast<uint32_t>(config.push_constant_size);
395 vk_config.push_constant_ranges.push_back(range);
396 }
397
398 vk_config.color_attachment_formats = color_formats;
399 vk_config.depth_attachment_format = depth_format;
400
401 vk_config.dynamic_states = {
402 vk::DynamicState::eViewport,
403 vk::DynamicState::eScissor
404 };
405
406 auto pipeline = std::make_shared<Core::VKGraphicsPipeline>();
407 if (!pipeline->create(m_shader_foundry->get_device(), vk_config)) {
409 "Failed to create VKGraphicsPipeline for dynamic rendering");
410
411 for (auto layout : layouts) {
412 m_shader_foundry->get_device().destroyDescriptorSetLayout(layout);
413 }
415 }
416
417 auto pipeline_id = m_next_pipeline_id.fetch_add(1);
418 PipelineState state;
419 state.shader_ids = { config.vertex_shader, config.fragment_shader };
420 state.pipeline = pipeline;
421 state.layouts = layouts;
422 state.layout = pipeline->get_layout();
423 m_pipelines[pipeline_id] = std::move(state);
424
426 "Dynamic rendering pipeline created (ID: {}, {} color attachments)",
427 pipeline_id, color_formats.size());
428
429 return pipeline_id;
430}
#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.
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, 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::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::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: