28 const std::string& name,
29 const std::shared_ptr<Nodes::Node>& node,
30 const std::string& descriptor_name,
32 vk::DescriptorType type)
36 "Cannot bind null node '{}'", name);
42 "Descriptor '{}' not found in shader config", descriptor_name);
52 .descriptor_name = descriptor_name,
54 .binding_index = binding_config.binding,
57 .gpu_buffer = gpu_buffer,
59 .buffer_size =
sizeof(float)
67 "Bound scalar node '{}' to descriptor '{}'", name, descriptor_name);
71 const std::string& name,
72 const std::shared_ptr<Nodes::Node>& node,
73 const std::string& descriptor_name,
75 vk::DescriptorType type)
79 "Cannot bind null node '{}'", name);
85 "Descriptor '{}' not found in shader config", descriptor_name);
91 size_t initial_size = 4096 *
sizeof(float);
96 .descriptor_name = descriptor_name,
98 .binding_index = binding_config.binding,
101 .gpu_buffer = gpu_buffer,
103 .buffer_size = initial_size
111 "Bound vector node '{}' to descriptor '{}'", name, descriptor_name);
115 const std::string& name,
116 const std::shared_ptr<Nodes::Node>& node,
117 const std::string& descriptor_name,
119 vk::DescriptorType type)
123 "Cannot bind null node '{}'", name);
129 "Descriptor '{}' not found in shader config", descriptor_name);
135 size_t initial_size =
static_cast<long>(1024) * 1024 *
sizeof(
float);
140 .descriptor_name = descriptor_name,
142 .binding_index = binding_config.binding,
145 .gpu_buffer = gpu_buffer,
147 .buffer_size = initial_size
155 "Bound matrix node '{}' to descriptor '{}'", name, descriptor_name);
168 "Unbound node '{}'", name);
179 std::vector<std::string> names;
182 names.push_back(name);
193 auto& bindings_list = buffer->get_pipeline_context().descriptor_buffer_bindings;
199 for (
auto& existing_binding : bindings_list) {
200 if (existing_binding.set == binding.set_index && existing_binding.binding == binding.binding_index) {
201 existing_binding.buffer_info.buffer = binding.gpu_buffer->get_buffer();
202 existing_binding.buffer_info.offset = binding.buffer_offset;
203 existing_binding.buffer_info.range = binding.buffer_size;
210 bindings_list.push_back({ .set = binding.set_index,
211 .binding = binding.binding_index,
212 .type = binding.type,
213 .buffer_info = vk::DescriptorBufferInfo {
214 binding.gpu_buffer->get_buffer(),
215 binding.buffer_offset,
216 binding.buffer_size } });
224 "Pipeline created for DescriptorBindingsProcessor (ID: {}, {} node bindings)",
238 "Binding has null node");
246 auto value =
static_cast<float>(binding.
node->get_last_output());
255 if (!gpu_vec || !gpu_vec->has_gpu_data()) {
257 "Node context does not provide GpuVectorData");
261 auto data = gpu_vec->gpu_data();
270 if (!gpu_mat || !gpu_mat->has_gpu_data()) {
272 "Node context does not provide GpuMatrixData");
276 auto data = gpu_mat->gpu_data();
284 if (!gpu_struct || !gpu_struct->has_gpu_data()) {
286 "Node context does not provide GpuStructuredData");
290 auto data = gpu_struct->gpu_data();
299 const std::string& name,
300 const std::shared_ptr<Nodes::Node>& node,
301 const std::string& descriptor_name,
303 vk::DescriptorType type)
307 "Cannot bind null node '{}'", name);
313 "Descriptor '{}' not found in shader config", descriptor_name);
319 size_t initial_size =
static_cast<long>(1024) * 64;
324 .descriptor_name = descriptor_name,
326 .binding_index = binding_config.binding,
329 .gpu_buffer = gpu_buffer,
331 .buffer_size = initial_size
337 "Bound structured node '{}' to descriptor '{}'", name, descriptor_name);
342 size_t required_size)
344 if (required_size <= binding.gpu_buffer->get_size_bytes()) {
348 size_t new_size = required_size * 3 / 2;
351 "Resizing descriptor buffer '{}': {} → {} bytes",
363 vk::DescriptorType type)
367 if (type == vk::DescriptorType::eUniformBuffer) {
373 auto buffer = std::make_shared<VKBuffer>(
381 if (!buffer_service) {
382 error<std::runtime_error>(
385 std::source_location::current(),
386 "create_descriptor_buffer requires a valid BufferService");
389 buffer_service->initialize_buffer(buffer);
#define MF_ERROR(comp, ctx,...)
#define MF_RT_ERROR(comp, ctx,...)
#define MF_DEBUG(comp, ctx,...)
void update_descriptor_from_node(DescriptorBinding &binding)
Update descriptor from node context.
void unbind_node(const std::string &name)
Remove a binding.
void bind_scalar_node(const std::string &name, const std::shared_ptr< Nodes::Node > &node, const std::string &descriptor_name, uint32_t set, vk::DescriptorType type=vk::DescriptorType::eUniformBuffer)
Bind scalar node output to descriptor.
void execute_shader(const std::shared_ptr< VKBuffer > &buffer) override
void bind_matrix_node(const std::string &name, const std::shared_ptr< Nodes::Node > &node, const std::string &descriptor_name, uint32_t set, vk::DescriptorType type=vk::DescriptorType::eStorageBuffer)
Bind matrix node (MatrixContext) to descriptor.
void on_pipeline_created(Portal::Graphics::ComputePipelineID pipeline_id) override
Called after pipeline creation - allocates GPU buffers for descriptors.
void ensure_buffer_capacity(DescriptorBinding &binding, size_t required_size)
Ensure descriptor buffer has sufficient capacity.
std::shared_ptr< VKBuffer > create_descriptor_buffer(size_t size, vk::DescriptorType type)
Create GPU buffer for a descriptor binding.
bool has_binding(const std::string &name) const
Check if binding exists.
void bind_structured_node(const std::string &name, const std::shared_ptr< Nodes::Node > &node, const std::string &descriptor_name, uint32_t set, vk::DescriptorType type=vk::DescriptorType::eStorageBuffer)
Bind structured node (arrays of POD structs) to descriptor.
std::unordered_map< std::string, DescriptorBinding > m_bindings
void bind_vector_node(const std::string &name, const std::shared_ptr< Nodes::Node > &node, const std::string &descriptor_name, uint32_t set, vk::DescriptorType type=vk::DescriptorType::eStorageBuffer)
Bind vector node (VectorContext) to descriptor.
@ MATRIX
2D grid from MatrixContext
@ VECTOR
Array from VectorContext.
@ SCALAR
Single value from node output.
@ STRUCTURED
Array of structs from StructuredContext.
DescriptorBindingsProcessor(const std::string &shader_path)
Create DescriptorBindingsProcessor with shader path.
std::vector< std::string > get_binding_names() const
Get all binding names.
void unbind_buffer(const std::string &descriptor_name)
Unbind a buffer from a descriptor.
bool m_needs_descriptor_rebuild
virtual void on_pipeline_created(Portal::Graphics::ComputePipelineID pipeline_id)
Called after pipeline is created.
void bind_buffer(const std::string &descriptor_name, const std::shared_ptr< VKBuffer > &buffer)
Bind a VKBuffer to a named shader descriptor.
Abstract base class for shader-based buffer processing.
@ UNIFORM
Uniform buffer (host-visible when requested)
@ COMPUTE
Storage buffer for compute shaders.
GPU-uploadable 2D grid data interface.
GPU-uploadable structured data (arrays of POD structs)
GPU-uploadable 1D array data interface.
Base context class for node callbacks.
Interface * get_service()
Query for a backend service.
static BackendRegistry & instance()
Get the global registry instance.
void upload_to_gpu(const void *data, size_t size, const std::shared_ptr< VKBuffer > &target, const std::shared_ptr< VKBuffer > &staging)
Upload raw data to GPU buffer (auto-detects host-visible vs device-local)
@ BufferProcessing
Buffer processing (Buffers::BufferManager, processing chains)
@ Buffers
Buffers, Managers, processors and processing chains.
@ UNKNOWN
Unknown or undefined modality.
uint64_t ComputePipelineID
size_t buffer_size
Size to write.
std::string descriptor_name
Matches ShaderProcessor binding name.
std::shared_ptr< Nodes::Node > node
std::shared_ptr< VKBuffer > gpu_buffer
UBO/SSBO backing storage.
std::unordered_map< std::string, ShaderBinding > bindings
Backend buffer management service interface.