MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
NetworkGeometryBuffer.cpp
Go to the documentation of this file.
2
4
8
10
11namespace MayaFlux::Buffers {
12
13namespace {
14 Portal::Graphics::RenderConfig resolve_config(const Portal::Graphics::RenderConfig& config)
15 {
16 VKBuffer::RenderConfig resolved_config = config;
17
18 switch (config.topology) {
20 if (config.vertex_shader.empty())
21 resolved_config.vertex_shader = "point.vert.spv";
22 if (config.fragment_shader.empty())
23 resolved_config.fragment_shader = "point.frag.spv";
24 break;
27
28 if (config.fragment_shader.empty())
29 resolved_config.fragment_shader = "line.frag.spv";
30
31#ifndef MAYAFLUX_PLATFORM_MACOS
32 if (config.vertex_shader.empty())
33 resolved_config.vertex_shader = "line.vert.spv";
34 if (config.geometry_shader.empty())
35 resolved_config.geometry_shader = "line.geom.spv";
36#else
37 if (config.vertex_shader.empty())
38 resolved_config.vertex_shader = "line_fallback.vert.spv";
39
41#endif // !MAYAFLUX_PLATFORM_MACOS
42 break;
45 if (config.vertex_shader.empty())
46 resolved_config.vertex_shader = "triangle.vert.spv";
47 if (config.fragment_shader.empty())
48 resolved_config.fragment_shader = "triangle.frag.spv";
49 break;
50 default:
51 if (config.vertex_shader.empty())
52 resolved_config.vertex_shader = "point.vert.spv";
53 if (config.fragment_shader.empty())
54 resolved_config.fragment_shader = "point.frag.spv";
55 }
56
57 return resolved_config;
58 }
59
60}
61
63 std::shared_ptr<Nodes::Network::NodeNetwork> network,
64 const std::string& binding_name,
65 float over_allocate_factor)
66 : VKBuffer(
67 calculate_buffer_size(network, over_allocate_factor),
68 Usage::VERTEX,
69 Kakshya::DataModality::VERTEX_POSITIONS_3D)
70 , m_network(std::move(network))
71 , m_binding_name(binding_name)
72{
73 if (!m_network) {
74 error<std::invalid_argument>(
77 std::source_location::current(),
78 "Cannot create NetworkGeometryBuffer with null NodeNetwork");
79 }
80
82 "Created NetworkGeometryBuffer '{}' for {} nodes ({} bytes estimated)",
84 m_network->get_node_count(),
86}
87
89{
90 auto self = std::dynamic_pointer_cast<NetworkGeometryBuffer>(shared_from_this());
91
92 m_processor = std::make_shared<NetworkGeometryProcessor>();
93 m_processor->set_processing_token(token);
94 m_processor->bind_network(
97 self);
98
100
101 auto chain = get_processing_chain();
102 if (!chain) {
103 chain = std::make_shared<BufferProcessingChain>();
105 }
106 chain->set_preferred_token(token);
107
109 "Setup NetworkGeometryProcessor for '{}' with token {}",
110 m_binding_name, static_cast<int>(token));
111}
112
114{
115 auto resolved_config = resolve_config(config);
116
117 apply_render_config(resolved_config, ShaderConfig { resolved_config.vertex_shader });
118
119 get_processing_chain()->add_processor(m_render_processor, shared_from_this());
120
121 set_default_render_config(resolved_config);
122}
123
125{
126 if (!m_network) {
127 return 0;
128 }
129
130 auto* operator_ptr = m_network->get_operator();
131 if (operator_ptr) {
132 auto* graphics_op = dynamic_cast<Nodes::Network::GraphicsOperator*>(operator_ptr);
133 if (graphics_op) {
134 return static_cast<uint32_t>(graphics_op->get_vertex_count());
135 }
136 }
137
138 return static_cast<uint32_t>(m_network->get_node_count());
139}
140
142 const std::shared_ptr<Nodes::Network::NodeNetwork>& network,
143 float over_allocate_factor)
144{
145 if (!network) {
146 return 0;
147 }
148
149 size_t node_count = network->get_node_count();
150 if (node_count == 0) {
152 "NodeNetwork has zero nodes. Buffer will be created with minimum size.");
153 return 4096;
154 }
155
156 size_t base_size = 0;
157
158 if (auto* operator_ptr = network->get_operator()) {
159 if (auto graphics_op = dynamic_cast<Nodes::Network::GraphicsOperator*>(operator_ptr)) {
160 size_t vertex_count = graphics_op->get_vertex_count();
161 auto layout = graphics_op->get_vertex_layout();
162
163 if (vertex_count > 0 && layout.stride_bytes > 0) {
164 base_size = vertex_count * layout.stride_bytes;
165
167 "Network geometry buffer sizing: {} vertices × {} bytes = {} bytes (operator: {})",
168 vertex_count, layout.stride_bytes, base_size, operator_ptr->get_type_name());
169 }
170 }
171 }
172
173 if (base_size == 0) {
174 size_t vertex_size = sizeof(Kakshya::PointVertex);
175 base_size = node_count * vertex_size;
176
178 "Network geometry buffer fallback sizing: {} nodes × {} bytes = {} bytes",
179 node_count, vertex_size, base_size);
180 }
181
182 auto allocated_size = static_cast<size_t>(
183 static_cast<float>(base_size) * over_allocate_factor);
184
185 if (over_allocate_factor > 1.0F) {
187 "Over-allocated by {}x: {} → {} bytes",
188 over_allocate_factor, base_size, allocated_size);
189 }
190
191 return allocated_size;
192}
193
195{
196 const auto resolved_config = resolve_config(config);
197 auto self = std::dynamic_pointer_cast<VKBuffer>(shared_from_this());
198
199 std::shared_ptr<RenderProcessor> render;
200 apply_render_config(render, resolved_config, ShaderConfig { resolved_config.vertex_shader });
201
202 get_processing_chain()->add_processor(render, shared_from_this());
203 render->set_buffer_vertex_layout(self, Kakshya::VertexLayout::for_lines());
204 render->set_vertex_range(0, 0);
205
206 m_chain_render_processors.push_back({ .render_processor = render });
207
209 "Added chain render processor #{} to NetworkGeometryBuffer",
211}
212
213std::shared_ptr<RenderProcessor> NetworkGeometryBuffer::get_chain_render_processor(size_t index) const
214{
215 if (index >= m_chain_render_processors.size())
216 return nullptr;
217 return m_chain_render_processors[index].render_processor;
218}
219
221 size_t index,
222 uint32_t vertex_offset,
223 uint32_t vertex_count,
224 const std::optional<Kakshya::VertexLayout>& layout)
225{
226 if (index == 0) {
228 m_render_processor->set_vertex_range(vertex_offset, vertex_count);
229 return;
230 }
231
232 const size_t ci = index - 1;
233 if (ci >= m_chain_render_processors.size())
234 return;
235
236 auto& entry = m_chain_render_processors[ci];
237 entry.vertex_offset = vertex_offset;
238 entry.vertex_count = vertex_count;
239 entry.render_processor->set_vertex_range(vertex_offset, vertex_count);
240
241 if (layout) {
242 auto self = std::dynamic_pointer_cast<VKBuffer>(shared_from_this());
243 entry.render_processor->set_buffer_vertex_layout(self, *layout);
244 }
245}
246
247} // namespace MayaFlux::Buffers
#define MF_INFO(comp, ctx,...)
#define MF_WARN(comp, ctx,...)
#define MF_DEBUG(comp, ctx,...)
Core::GlobalNetworkConfig network
Definition Config.cpp:37
std::vector< ChainRenderEntry > m_chain_render_processors
NetworkGeometryBuffer(std::shared_ptr< Nodes::Network::NodeNetwork > network, const std::string &binding_name="network_geometry", float over_allocate_factor=2.0F)
Create geometry buffer from network.
std::shared_ptr< NetworkGeometryProcessor > m_processor
void add_chain_operator_rendering(const RenderConfig &config)
Add a RenderProcessor for a specific operator chain index.
uint32_t get_vertex_count() const
Get current vertex count (aggregated from all network nodes)
std::shared_ptr< Nodes::Network::NodeNetwork > m_network
void setup_rendering(const RenderConfig &config)
Setup rendering with RenderProcessor.
void update_chain_render_range(size_t index, uint32_t vertex_offset, uint32_t vertex_count, const std::optional< Kakshya::VertexLayout > &layout)
Update vertex range for a specific operator chain index.
std::shared_ptr< RenderProcessor > get_chain_render_processor(size_t index) const
Get RenderProcessor for a specific operator chain index.
static size_t calculate_buffer_size(const std::shared_ptr< Nodes::Network::NodeNetwork > &network, float over_allocate_factor)
Calculate initial buffer size based on network node count.
void setup_processors(ProcessingToken token) override
Initialize the buffer and its processors.
std::shared_ptr< Buffers::BufferProcessingChain > get_processing_chain() override
Access the buffer's processing chain.
Definition VKBuffer.cpp:286
void set_default_processor(const std::shared_ptr< BufferProcessor > &processor) override
Set the buffer's default processor.
Definition VKBuffer.cpp:270
Portal::Graphics::RenderConfig RenderConfig
Definition VKBuffer.hpp:69
vk::DeviceSize get_size_bytes() const
Definition VKBuffer.hpp:279
void set_processing_chain(const std::shared_ptr< BufferProcessingChain > &chain, bool force=false) override
Replace the buffer's processing chain.
Definition VKBuffer.cpp:291
void apply_render_config(const RenderConfig &config, const ShaderConfig &shader_config)
Configure the internal m_render_processor from a RenderConfig.
Definition VKBuffer.cpp:359
std::shared_ptr< RenderProcessor > m_render_processor
Definition VKBuffer.hpp:618
void set_default_render_config(const RenderConfig &config)
Called by derived classes to set their context-specific defaults.
Definition VKBuffer.hpp:595
Vulkan-backed buffer wrapper used in processing chains.
Definition VKBuffer.hpp:67
Operator that produces GPU-renderable geometry.
ProcessingToken
Bitfield enum defining processing characteristics and backend requirements for buffer operations.
@ BufferManagement
Buffer Management (Buffers::BufferManager, creating buffers)
@ Init
Engine/subsystem initialization.
@ Buffers
Buffers, Managers, processors and processing chains.
Vertex type for point primitives (POINT_LIST topology)
static VertexLayout for_lines(uint32_t stride=60)
Factory: layout for LineVertex (position, color, thickness, uv, normal, tangent)
Unified rendering configuration for graphics buffers.