MayaFlux 0.5.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
NetworkGeometryProcessor.hpp
Go to the documentation of this file.
1#pragma once
2
4
6class NodeNetwork;
7class ParticleNetwork;
8class GraphicsOperator;
9} // namespace MayaFlux::Nodes
10
11namespace MayaFlux::Buffers {
12
13/**
14 * @class NetworkGeometryProcessor
15 * @brief BufferProcessor that aggregates geometry from NodeNetwork nodes
16 *
17 * Extracts geometry from all nodes within a network and uploads to GPU as
18 * a single vertex buffer. Handles network-specific patterns like ParticleNetwork
19 * and PointCloudNetwork.
20 *
21 * Key Differences from GeometryBindingsProcessor:
22 * - Operates on NodeNetwork (not single GeometryWriterNode)
23 * - Aggregates vertices from ALL internal nodes
24 * - Type-aware: special handling for ParticleNetwork, PointCloudNetwork, etc.
25 *
26 * Behavior:
27 * - Extracts ALL node geometry from bound networks
28 * - Aggregates into single vertex buffer
29 * - Uses staging buffer for device-local targets
30 * - Supports multiple network bindings (different networks → different buffers)
31 *
32 * Usage:
33 * ```cpp
34 * auto particles = std::make_shared<ParticleNetwork>(1000);
35 * auto vertex_buffer = std::make_shared<VKBuffer>(...);
36 *
37 * auto processor = std::make_shared<NetworkGeometryProcessor>();
38 * processor->bind_network("particles", particles, vertex_buffer);
39 *
40 * vertex_buffer->set_default_processor(processor);
41 * vertex_buffer->process_default(); // Aggregates all 1000 Poiints -> GPU
42 * ```
43 */
44class MAYAFLUX_API NetworkGeometryProcessor : public VKBufferProcessor {
45public:
47
48 /**
49 * @brief Structure representing a network geometry binding
50 */
52 std::shared_ptr<Nodes::Network::NodeNetwork> network;
53 std::shared_ptr<VKBuffer> gpu_vertex_buffer;
54 std::shared_ptr<VKBuffer> staging_buffer;
55
56 /**
57 * @brief Aggregate byte size of the most recent full upload.
58 *
59 * A cycle whose freshly computed aggregate size still matches this,
60 * and whose primary operator supports_incremental_upload(), takes the
61 * per-range partial-upload path; any size change forces a full
62 * re-upload and refreshes this value.
63 */
64 size_t last_total_bytes {};
65 };
66
67 /**
68 * @brief Bind a network to a GPU vertex buffer
69 * @param name Logical name for this binding
70 * @param network NodeNetwork to aggregate geometry from
71 * @param vertex_buffer GPU vertex buffer to upload to
72 *
73 * If vertex_buffer is device-local, a staging buffer is automatically created.
74 */
75 void bind_network(
76 const std::string& name,
77 const std::shared_ptr<Nodes::Network::NodeNetwork>& network,
78 const std::shared_ptr<VKBuffer>& vertex_buffer);
79
80 /**
81 * @brief Remove a network binding
82 * @param name Name of binding to remove
83 */
84 void unbind_network(const std::string& name);
85
86 /**
87 * @brief Check if a binding exists
88 * @param name Binding name
89 * @return True if binding exists
90 */
91 [[nodiscard]] bool has_binding(const std::string& name) const;
92
93 /**
94 * @brief Get all binding names
95 * @return Vector of binding names
96 */
97 [[nodiscard]] std::vector<std::string> get_binding_names() const;
98
99 /**
100 * @brief Get number of active bindings
101 * @return Binding count
102 */
103 [[nodiscard]] size_t get_binding_count() const;
104
105 /**
106 * @brief Get a specific binding
107 * @param name Binding name
108 * @return Optional containing binding if exists
109 */
110 [[nodiscard]] std::optional<NetworkBinding> get_binding(const std::string& name) const;
111
112 /**
113 * @brief BufferProcessor interface - aggregates and uploads network geometry
114 * @param buffer The buffer this processor is attached to
115 *
116 * For each bound network:
117 * 1. Extract vertices from all internal nodes
118 * 2. Aggregate into single vertex array
119 * 3. Upload to GPU vertex buffer
120 */
121 void processing_function(const std::shared_ptr<Buffer>& buffer) override;
122
123private:
124 std::unordered_map<std::string, NetworkBinding> m_bindings;
125 std::vector<uint8_t> m_staging_aggregate;
126
127 /**
128 * @brief Grow a binding's staging buffer to hold at least @p bytes.
129 *
130 * The target vertex buffer resizes with 1.5x headroom when a network grows,
131 * so the staging buffer it was sized against goes stale. Growing by the same
132 * factor keeps reallocation proportional to growth rather than per frame.
133 *
134 * @param binding Binding whose staging_buffer is checked and possibly replaced.
135 * @param bytes Required capacity.
136 */
137 void ensure_staging(NetworkBinding& binding, size_t bytes);
138
139 /**
140 * @brief Upload only the vertex sub-ranges a multi-group primary operator
141 * reports as dirty, instead of rebuilding the whole buffer.
142 * @return True when every dirty range was uploaded and the operator was
143 * marked clean, so the caller skips its full-buffer path. False
144 * when incremental upload does not apply (operator does not
145 * support it, aggregate size changed since the last full upload,
146 * a range fell outside the buffer) and the caller must fall back.
147 *
148 * An empty dirty-range list still returns true, skipping the upload
149 * entirely, so the caller must not invoke this while a downstream pass
150 * rewrites those vertex bytes in place each cycle.
151 */
152 bool try_incremental_upload(
154 uint32_t primary_stride_bytes,
155 NetworkBinding& binding,
156 const std::shared_ptr<VKBuffer>& vk_buffer,
157 size_t expected_total_bytes,
158 const std::string& name);
159};
160
161} // namespace MayaFlux::Buffers
Core::GlobalNetworkConfig network
Definition Config.cpp:39
std::string name
Definition VKDevice.cpp:143
std::unordered_map< std::string, NetworkBinding > m_bindings
BufferProcessor that aggregates geometry from NodeNetwork nodes.
Operator that produces GPU-renderable geometry.
Structure representing a network geometry binding.