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

◆ initialize_pipeline()

void MayaFlux::Buffers::RenderProcessor::initialize_pipeline ( const std::shared_ptr< VKBuffer > &  buffer)
overrideprotectedvirtual

Implements MayaFlux::Buffers::ShaderProcessor.

Definition at line 266 of file RenderProcessor.cpp.

267{
270 "Vertex shader not loaded");
271 return;
272 }
273
276 "Fragment shader not loaded");
277 return;
278 }
279
280 if (!m_target_window) {
282 "Target window not set");
283 return;
284 }
285
286 const auto* state = get_or_cache_buffer_state(buffer);
287 if (!state) {
289 "initialize_pipeline: layout not yet available, deferring");
291 return;
292 }
293
295
297
298 Portal::Graphics::RenderPipelineConfig pipeline_config;
299 pipeline_config.vertex_shader = m_shader_id;
300 pipeline_config.fragment_shader = m_fragment_shader_id;
301 pipeline_config.geometry_shader = m_geometry_shader_id;
302 pipeline_config.tess_control_shader = m_tess_control_shader_id;
303 pipeline_config.tess_eval_shader = m_tess_eval_shader_id;
304
305 pipeline_config.topology = pipeline_topology();
306 pipeline_config.rasterization.polygon_mode = m_polygon_mode;
307 pipeline_config.rasterization.cull_mode = m_cull_mode;
308
309 if (m_blend_attachment.has_value()) {
310 pipeline_config.blend_attachments.push_back(m_blend_attachment.value());
311 } else {
312 pipeline_config.blend_attachments.emplace_back();
313 }
314
315 pipeline_config.depth_stencil = m_depth_stencil;
316
317 pipeline_config.semantic_vertex_layout = state->semantic_layout;
318 pipeline_config.use_vertex_shader_reflection = state->use_reflection;
319
320 pipeline_config.push_constant_size = resolve_push_constant_size(buffer);
321
322 auto& descriptor_bindings = buffer->get_pipeline_context().descriptor_buffer_bindings;
323 std::map<std::pair<uint32_t, uint32_t>, Portal::Graphics::DescriptorBindingInfo> unified_bindings;
324
325 for (const auto& binding : descriptor_bindings) {
326 unified_bindings[{ binding.set, binding.binding }] = binding;
327 }
328
329 for (const auto& [name, binding] : m_config.bindings) {
330 auto key = std::make_pair(binding.set, binding.binding);
331 if (unified_bindings.find(key) == unified_bindings.end()) {
332 unified_bindings[key] = Portal::Graphics::DescriptorBindingInfo {
333 .set = binding.set,
334 .binding = binding.binding,
335 .type = binding.type,
336 .buffer_info = {},
337 .name = name,
338 .count = binding.count
339 };
340 }
341 }
342
343 std::vector<Portal::Graphics::DescriptorBindingInfo> unregistered;
345 if (shader_id == Portal::Graphics::INVALID_SHADER) {
346 continue;
347 }
348 for (const auto& used : Portal::Graphics::get_shader_foundry().get_active_descriptor_bindings(shader_id)) {
349 if (used.set == 0 || unified_bindings.contains({ used.set, used.binding })) {
350 continue;
351 }
352 unregistered.push_back(used);
353 }
354 }
355
356 for (auto it = m_awaited_bindings.begin(); it != m_awaited_bindings.end();) {
357 const auto slot = *it;
358 const bool pending = std::ranges::any_of(unregistered, [&slot](const auto& used) {
359 return used.set == slot.first && used.binding == slot.second;
360 });
361 if (pending) {
362 ++it;
363 continue;
364 }
366 "Set {} binding {} is now registered, the shader's binding is supplied",
367 slot.first, slot.second);
368 it = m_awaited_bindings.erase(it);
369 }
370
371 if (!unregistered.empty()) {
372 constexpr uint32_t k_binding_grace_ticks = 30;
374 && m_binding_wait_ticks < k_binding_grace_ticks;
375
376 for (const auto& used : unregistered) {
377 const bool first_seen = m_awaited_bindings.emplace(used.set, used.binding).second;
378 if (waiting && first_seen) {
380 "Waiting for set {} binding {} ({}), which the shader uses, to be registered before creating the pipeline",
381 used.set, used.binding, vk::to_string(used.type));
382 }
383 }
384
385 if (waiting) {
388 return;
389 }
390
391 for (const auto& used : unregistered) {
393 "Set {} binding {} ({}), which the shader uses, is not registered. "
394 "Creating the pipeline with an empty slot that is filled once a processor registers it",
395 used.set, used.binding, vk::to_string(used.type));
396 unified_bindings.emplace(std::make_pair(used.set, used.binding),
397 Portal::Graphics::DescriptorBindingInfo {
398 .set = used.set,
399 .binding = used.binding,
400 .type = used.type,
401 .buffer_info = {},
402 .name = used.name });
403 }
404 }
406
407 std::map<uint32_t, std::vector<Portal::Graphics::DescriptorBindingInfo>> bindings_by_set;
408 for (const auto& [key, binding] : unified_bindings) {
409 bindings_by_set[binding.set].push_back(binding);
410 }
411
412 for (const auto& [set_index, set_bindings] : bindings_by_set) {
413 pipeline_config.descriptor_sets.push_back(set_bindings);
414 }
415
416 vk::Format swapchain_format = static_cast<vk::Format>(
418
419 vk::Format depth_format = m_depth_enabled
420 ? vk::Format::eD32Sfloat
421 : vk::Format::eUndefined;
422
424
425 m_pipeline_id = flow.create_pipeline(pipeline_config, { swapchain_format }, depth_format);
426
429 "Failed to create render pipeline");
430 return;
431 }
432
433 if (m_depth_enabled) {
434 buffer->set_needs_depth_attachment(true);
435 }
436
439
441}
#define MF_INFO(comp, ctx,...)
#define MF_ERROR(comp, ctx,...)
#define MF_RT_ERROR(comp, ctx,...)
#define MF_WARN(comp, ctx,...)
#define MF_DEBUG(comp, ctx,...)
std::shared_ptr< NetworkGeometryBuffer > buffer
std::string name
Definition VKDevice.cpp:123
Portal::Graphics::ShaderID m_fragment_shader_id
std::optional< Portal::Graphics::BlendAttachmentConfig > m_blend_attachment
Registry::Service::DisplayService * m_display_service
Portal::Graphics::ShaderID m_geometry_shader_id
Portal::Graphics::RenderPipelineID m_pipeline_id
Portal::Graphics::ShaderID m_tess_control_shader_id
BufferState * get_or_cache_buffer_state(const std::shared_ptr< VKBuffer > &buffer)
Portal::Graphics::DepthStencilConfig m_depth_stencil
Portal::Graphics::PrimitiveTopology pipeline_topology() const
Topology the pipeline is built with, as opposed to the topology m_runs are declared in.
std::set< std::pair< uint32_t, uint32_t > > m_awaited_bindings
void retire_current_pipeline()
Move the current pipeline to the retired list and drop its buffer associations.
Portal::Graphics::PolygonMode m_polygon_mode
Portal::Graphics::CullMode m_cull_mode
std::shared_ptr< Core::Window > m_target_window
Portal::Graphics::ShaderID m_tess_eval_shader_id
Portal::Graphics::ShaderID m_shader_id
size_t resolve_push_constant_size(const std::shared_ptr< VKBuffer > &buffer) const
Byte width of this processor's push constant block, extended to cover any fragment staged on the buff...
virtual void on_pipeline_created(Portal::Graphics::ComputePipelineID pipeline_id)
Called after pipeline is created.
std::vector< Portal::Graphics::DescriptorSetID > m_descriptor_set_ids
void register_window_for_rendering(const std::shared_ptr< Core::Window > &window)
Register a window for dynamic rendering.
@ BufferProcessing
Buffer processing (Buffers::BufferManager, processing chains)
@ Portal
High-level user-facing API layer.
@ Buffers
Buffers, Managers, processors and processing chains.
constexpr RenderPipelineID INVALID_RENDER_PIPELINE
constexpr ShaderID INVALID_SHADER
MAYAFLUX_API RenderFlow & get_render_flow()
Get the global render flow instance.
MAYAFLUX_API ShaderFoundry & get_shader_foundry()
Get the global shader compiler instance.
static constexpr DomainSpec Graphics
Domain constant for Graphics domain.
Definition Creator.hpp:444
std::function< int(const std::shared_ptr< void > &)> get_swapchain_format
Get actual swapchain format for a window.

References MayaFlux::Buffers::ShaderConfig::bindings, MayaFlux::Portal::Graphics::RenderPipelineConfig::blend_attachments, buffer, MayaFlux::Journal::BufferProcessing, MayaFlux::Journal::Buffers, MayaFlux::Portal::Graphics::RasterizationConfig::cull_mode, MayaFlux::Portal::Graphics::RenderPipelineConfig::depth_stencil, MayaFlux::Portal::Graphics::RenderPipelineConfig::fragment_shader, MayaFlux::Portal::Graphics::RenderPipelineConfig::geometry_shader, MayaFlux::Portal::Graphics::ShaderFoundry::get_active_descriptor_bindings(), get_or_cache_buffer_state(), MayaFlux::Portal::Graphics::get_render_flow(), MayaFlux::Portal::Graphics::get_shader_foundry(), MayaFlux::Portal::Graphics::INVALID_RENDER_PIPELINE, MayaFlux::Portal::Graphics::INVALID_SHADER, m_awaited_bindings, m_binding_wait_ticks, m_blend_attachment, MayaFlux::Buffers::ShaderProcessor::m_config, m_cull_mode, m_depth_stencil, m_fragment_shader_id, m_geometry_shader_id, MayaFlux::Buffers::ShaderProcessor::m_needs_pipeline_rebuild, m_pipeline_id, m_polygon_mode, MayaFlux::Buffers::ShaderProcessor::m_shader_id, m_target_window, m_tess_control_shader_id, m_tess_eval_shader_id, MF_DEBUG, MF_ERROR, MF_INFO, MF_RT_ERROR, MF_WARN, name, MayaFlux::Portal::Graphics::DescriptorBindingInfo::name, pipeline_topology(), MayaFlux::Portal::Graphics::RasterizationConfig::polygon_mode, MayaFlux::Portal::Graphics::RenderPipelineConfig::push_constant_size, MayaFlux::Portal::Graphics::RenderPipelineConfig::rasterization, MayaFlux::Portal::Graphics::RenderFlow::register_window_for_rendering(), MayaFlux::Buffers::ShaderProcessor::resolve_push_constant_size(), MayaFlux::Portal::Graphics::RenderPipelineConfig::semantic_vertex_layout, MayaFlux::Portal::Graphics::DescriptorBindingInfo::set, MayaFlux::Portal::Graphics::RenderPipelineConfig::tess_control_shader, MayaFlux::Portal::Graphics::RenderPipelineConfig::tess_eval_shader, MayaFlux::Portal::Graphics::RenderPipelineConfig::topology, MayaFlux::Portal::Graphics::RenderPipelineConfig::use_vertex_shader_reflection, and MayaFlux::Portal::Graphics::RenderPipelineConfig::vertex_shader.

+ Here is the call graph for this function: