MayaFlux 0.3.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
DescriptorBindingsProcessor.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "ShaderProcessor.hpp"
4
5namespace MayaFlux::Nodes {
6class Node;
7}
8
9namespace MayaFlux::Buffers {
10
11class AudioBuffer;
12
13/**
14 * @class DescriptorBindingsProcessor
15 * @brief ShaderProcessor that uploads node outputs to descriptor sets
16 *
17 * Binds nodes to UBO/SSBO descriptors. Supports:
18 * - Scalar nodes (single value)
19 * - Vector nodes (contiguous arrays via VectorContext)
20 * - Matrix nodes (2D grids via MatrixContext)
21 * - Structured nodes (arrays of POD structs)
22 *
23 * Usage:
24 * auto processor = std::make_shared<DescriptorBindingsProcessor>(shader_config);
25 *
26 * // Bind scalar node to UBO
27 * processor->bind_scalar_node("frequency", freq_node,
28 * "params", 0, Portal::Graphics::DescriptorRole::UNIFORM);
29 *
30 * // Bind vector node to SSBO
31 * processor->bind_vector_node("spectrum", spectrum_node,
32 * "spectrum_data", 0, Portal::Graphics::DescriptorRole::STORAGE);
33 */
34class MAYAFLUX_API DescriptorBindingsProcessor : public ShaderProcessor {
35public:
36 enum class ProcessingMode : uint8_t {
37 INTERNAL, ///< Processor calls extract_single_sample() or processes node context
38 EXTERNAL ///< Processor reads node's current state (get_last_output/get_last_context)
39 };
40
41 enum class BindingType : uint8_t {
42 SCALAR, ///< Single value from node output
43 VECTOR, ///< Array from VectorContext
44 MATRIX, ///< 2D grid from MatrixContext
45 STRUCTURED ///< Array of structs from StructuredContext
46 };
47
48 enum class SourceType : uint8_t {
49 NODE,
50 AUDIO_BUFFER,
51 HOST_VK_BUFFER,
52 NETWORK_AUDIO,
53 NETWORK_GPU
54 };
55
57 std::shared_ptr<Nodes::Node> node;
58 std::shared_ptr<Buffers::Buffer> buffer;
59 std::shared_ptr<Nodes::Network::NodeNetwork> network;
60 std::string descriptor_name; ///< Matches ShaderProcessor binding name
61 uint32_t set_index;
62 uint32_t binding_index;
65 SourceType source_type { SourceType::NODE };
66 std::shared_ptr<VKBuffer> gpu_buffer; ///< UBO/SSBO backing storage
67 size_t buffer_offset {}; ///< Offset within buffer (for packed UBOs)
68 size_t buffer_size; ///< Size to write
69 std::atomic<ProcessingMode> processing_mode { ProcessingMode::INTERNAL };
70 };
71
72 /**
73 * @brief Create DescriptorBindingsProcessor with shader path
74 * @param shader_path Path to compute shader
75 */
76 DescriptorBindingsProcessor(const std::string& shader_path);
77
78 /**
79 * @brief Create DescriptorBindingsProcessor with shader config
80 * @param config Shader processor configuration
81 */
83
84 /**
85 * @brief Bind scalar node output to descriptor
86 * @param name Logical binding name
87 * @param node Node to read from
88 * @param descriptor_name Name in shader config bindings
89 * @param set Descriptor set index
90 * @param role UBO or SSBO
91 * @param mode Processing mode (default: INTERNAL)
92 */
93 void bind_scalar_node(
94 const std::string& name,
95 const std::shared_ptr<Nodes::Node>& node,
96 const std::string& descriptor_name,
97 uint32_t set,
98 Portal::Graphics::DescriptorRole role = Portal::Graphics::DescriptorRole::UNIFORM,
99 ProcessingMode mode = ProcessingMode::INTERNAL);
100
101 /**
102 * @brief Bind vector node (VectorContext) to descriptor
103 * @param name Logical binding name
104 * @param node Node that creates VectorContext
105 * @param descriptor_name Name in shader config bindings
106 * @param set Descriptor set index
107 * @param role Typically STORAGE for arrays
108 * @param mode Processing mode (default: INTERNAL)
109 */
110 void bind_vector_node(
111 const std::string& name,
112 const std::shared_ptr<Nodes::Node>& node,
113 const std::string& descriptor_name,
114 uint32_t set,
115 Portal::Graphics::DescriptorRole role = Portal::Graphics::DescriptorRole::STORAGE,
116 ProcessingMode mode = ProcessingMode::INTERNAL);
117
118 /**
119 * @brief Bind matrix node (MatrixContext) to descriptor
120 */
121 void bind_matrix_node(
122 const std::string& name,
123 const std::shared_ptr<Nodes::Node>& node,
124 const std::string& descriptor_name,
125 uint32_t set,
126 Portal::Graphics::DescriptorRole role = Portal::Graphics::DescriptorRole::STORAGE,
127 ProcessingMode mode = ProcessingMode::INTERNAL);
128
129 /**
130 * @brief Bind structured node (arrays of POD structs) to descriptor
131 * @param name Logical binding name
132 * @param node Node that creates context with GpuStructuredData
133 * @param descriptor_name Name in shader config bindings
134 * @param set Descriptor set index
135 * @param role Typically STORAGE for structured arrays
136 */
137 void bind_structured_node(
138 const std::string& name,
139 const std::shared_ptr<Nodes::Node>& node,
140 const std::string& descriptor_name,
141 uint32_t set,
142 Portal::Graphics::DescriptorRole role = Portal::Graphics::DescriptorRole::STORAGE,
143 ProcessingMode mode = ProcessingMode::INTERNAL);
144
145 /**
146 * @brief Bind an AudioBuffer as a descriptor source.
147 *
148 * Reads the buffer's double sample data each cycle, converts to float,
149 * and uploads to the descriptor. Always treated as VECTOR binding.
150 *
151 * @param name Logical binding name
152 * @param buffer AudioBuffer to read from
153 * @param descriptor_name Name in shader config bindings
154 * @param set Descriptor set index
155 * @param role Descriptor role (default: STORAGE)
156 */
157 void bind_audio_buffer(
158 const std::string& name,
159 const std::shared_ptr<AudioBuffer>& buffer,
160 const std::string& descriptor_name,
161 uint32_t set,
162 Portal::Graphics::DescriptorRole role = Portal::Graphics::DescriptorRole::STORAGE);
163
164 /**
165 * @brief Bind a host-visible VKBuffer as a descriptor source.
166 *
167 * Fails hard at bind time if the buffer is not host-visible.
168 * Reads mapped memory each cycle and uploads to the descriptor.
169 * Always treated as VECTOR binding.
170 *
171 * @param name Logical binding name
172 * @param buffer Host-visible VKBuffer to read from
173 * @param descriptor_name Name in shader config bindings
174 * @param set Descriptor set index
175 * @param role Descriptor role (default: STORAGE)
176 */
177 void bind_host_vk_buffer(
178 const std::string& name,
179 const std::shared_ptr<VKBuffer>& buffer,
180 const std::string& descriptor_name,
181 uint32_t set,
182 Portal::Graphics::DescriptorRole role = Portal::Graphics::DescriptorRole::STORAGE);
183
184 /**
185 * @brief Bind a NodeNetwork to a descriptor.
186 *
187 * Resolves source type at bind time:
188 * - Networks with get_audio_buffer() output → NETWORK_AUDIO (VECTOR binding)
189 * - Networks with a GraphicsOperator → NETWORK_GPU (STRUCTURED binding)
190 *
191 * Fails hard if the network satisfies neither condition.
192 *
193 * @param name Logical binding name
194 * @param network NodeNetwork to read from
195 * @param descriptor_name Name in shader config bindings
196 * @param set Descriptor set index
197 * @param role Descriptor role (default: STORAGE)
198 */
199 void bind_network(
200 const std::string& name,
201 const std::shared_ptr<Nodes::Network::NodeNetwork>& network,
202 const std::string& descriptor_name,
203 uint32_t set,
204 Portal::Graphics::DescriptorRole role = Portal::Graphics::DescriptorRole::STORAGE);
205
206 /**
207 * @brief Remove a binding
208 */
209 void unbind(const std::string& name);
210
211 /**
212 * @brief Check if binding exists
213 */
214 bool has_binding(const std::string& name) const;
215
216 /**
217 * @brief Get all binding names
218 */
219 std::vector<std::string> get_binding_names() const;
220
221 /**
222 * @brief Set processing mode for a specific binding
223 * @param name Binding name
224 * @param mode INTERNAL (processor processes node) or EXTERNAL (processor reads node state)
225 */
226 void set_processing_mode(const std::string& name, ProcessingMode mode);
227
228 /**
229 * @brief Set processing mode for all bindings
230 * @param mode INTERNAL or EXTERNAL
231 */
232 void set_processing_mode(ProcessingMode mode);
233
234 /**
235 * @brief Get processing mode for a specific binding
236 * @param name Binding name
237 * @return Current processing mode
238 */
239 ProcessingMode get_processing_mode(const std::string& name) const;
240
241protected:
242 /**
243 * @brief Called after pipeline creation - allocates GPU buffers for descriptors
244 */
245 void on_pipeline_created(Portal::Graphics::ComputePipelineID pipeline_id) override;
246
247 void execute_shader(const std::shared_ptr<VKBuffer>& buffer) override;
248
249 void initialize_pipeline(const std::shared_ptr<VKBuffer>& buffer) override { }
250
251 void initialize_descriptors(const std::shared_ptr<VKBuffer>& buffer) override { }
252
253private:
254 std::unordered_map<std::string, DescriptorBinding> m_bindings;
255
256 /**
257 * @brief Ensure descriptor buffer has sufficient capacity
258 * @param binding Descriptor binding to check
259 * @param required_size Minimum required size in bytes
260 *
261 * If buffer is too small, resizes with 50% over-allocation.
262 * Sets m_needs_descriptor_rebuild flag if resize occurs.
263 */
264 void ensure_buffer_capacity(DescriptorBinding& binding, size_t required_size);
265
266 /**
267 * @brief Update descriptor from node context
268 */
269 void update_descriptor_from_node(DescriptorBinding& binding);
270
271 /**
272 * @brief Create GPU buffer for a descriptor binding
273 */
274 std::shared_ptr<VKBuffer> create_descriptor_buffer(
275 size_t size,
277};
278
279} // namespace MayaFlux::Buffers
void initialize_descriptors(const std::shared_ptr< VKBuffer > &buffer) override
std::unordered_map< std::string, DescriptorBinding > m_bindings
void initialize_pipeline(const std::shared_ptr< VKBuffer > &buffer) override
ShaderProcessor that uploads node outputs to descriptor sets.
Abstract base class for shader-based buffer processing.
Contains the node-based computational processing system components.
Definition Chronie.hpp:11
DescriptorRole
Semantic descriptor type — maps to Vulkan descriptor types internally.
std::shared_ptr< VKBuffer > gpu_buffer
UBO/SSBO backing storage.