MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
GeometryBindingsProcessor.hpp
Go to the documentation of this file.
1#pragma once
2
4
6class GeometryWriterNode;
7}
8
9namespace MayaFlux::Buffers {
10
11/**
12 * @class GeometryBindingsProcessor
13 * @brief BufferProcessor that uploads geometry node data to GPU vertex buffers
14 *
15 * Manages bindings between GeometryWriterNode instances (CPU-side) and GPU
16 * vertex buffers. Each frame, reads vertex data from nodes and uploads to
17 * corresponding GPU buffers via staging buffers.
18 *
19 * Behavior:
20 * - Uploads ALL bound geometries to their target vertex buffers
21 * - Uploads index data to a separate Usage::INDEX VKBuffer when the node
22 * carries indices; index buffer is created lazily on first appearance.
23 * - Staging buffers are created automatically for device-local targets
24 * (both vertex and index paths).
25 * - If target is device-local: uses staging buffer (auto-created)
26 * - If target is host-visible: direct upload (no staging)
27 * - If attached buffer is one of the targets: uploads its geometry
28 * - If attached buffer is NOT a target: uploads first geometry to it
29 *
30 * Usage:
31 * auto vertex_buffer = std::make_shared<VKBuffer>(
32 * 1000 * sizeof(Vertex),
33 * VKBuffer::Usage::VERTEX_BUFFER);
34 *
35 * auto processor = std::make_shared<GeometryBindingsProcessor>();
36 * processor->bind_geometry_node("particles", particle_node, vertex_buffer);
37 *
38 * vertex_buffer->set_default_processor(processor);
39 * vertex_buffer->process_default(); // Uploads geometry
40 */
41class MAYAFLUX_API GeometryBindingsProcessor : public VKBufferProcessor {
42public:
44
45 /**
46 * @struct GeometryBinding
47 * @brief Holds GPU resources for one GeometryWriterNode binding.
48 *
49 * Index buffer and its staging are created lazily in bind_geometry_node()
50 * when the node already carries index data, and in processing_function()
51 * on the first frame that index data appears. Both are null for non-indexed
52 * geometry; RenderProcessor queries has_index_buffer() before deciding
53 * which draw path to use.
54 */
56 std::shared_ptr<Nodes::GpuSync::GeometryWriterNode> node;
57 std::shared_ptr<VKBuffer> gpu_vertex_buffer;
58 std::shared_ptr<VKBuffer> staging_buffer;
59 std::shared_ptr<VKBuffer> gpu_index_buffer;
60 std::shared_ptr<VKBuffer> index_staging_buffer;
61 };
62
63 /**
64 * @brief Bind a geometry node to a GPU vertex buffer
65 * @param name Logical name for this binding
66 * @param node GeometryWriterNode to read vertices from
67 * @param vertex_buffer GPU vertex buffer to upload to
68 *
69 * If vertex_buffer is device-local, a staging buffer is automatically created.
70 * If vertex_buffer is host-visible, no staging is needed.
71 */
72 void bind_geometry_node(
73 const std::string& name,
74 const std::shared_ptr<Nodes::GpuSync::GeometryWriterNode>& node,
75 const std::shared_ptr<VKBuffer>& vertex_buffer);
76
77 /**
78 * @brief Remove a geometry binding
79 * @param name Name of binding to remove
80 */
81 void unbind_geometry_node(const std::string& name);
82
83 /**
84 * @brief Check if a binding exists
85 * @param name Binding name
86 * @return True if binding exists
87 */
88 [[nodiscard]] bool has_binding(const std::string& name) const;
89
90 /**
91 * @brief Get all binding names
92 * @return Vector of binding names
93 */
94 [[nodiscard]] std::vector<std::string> get_binding_names() const;
95
96 /**
97 * @brief Get number of active bindings
98 * @return Binding count
99 */
100 [[nodiscard]] size_t get_binding_count() const;
101
102 /**
103 * @brief Get a specific binding
104 * @param name Binding name
105 * @return Optional containing binding if exists
106 */
107 [[nodiscard]] std::optional<GeometryBinding> get_binding(const std::string& name) const;
108
109 /**
110 * @brief Supply a texture to bind on the next graphics tick.
111 *
112 * Mirrors FormaProcessor::set_texture. Stores the image and binding name
113 * behind an atomic dirty flag; processing_function binds it to the buffer's
114 * RenderProcessor on the next cycle. The descriptor slot must already exist
115 * in the pipeline (declared by GeometryBuffer::setup_rendering). Calling
116 * again replaces the pending binding before it is consumed.
117 *
118 * @param image GPU image. nullptr clears the binding.
119 * @param binding Descriptor name matching the fragment shader.
120 */
121 void set_texture(std::shared_ptr<Core::VKImage> image, std::string binding);
122
123 /**
124 * @brief BufferProcessor interface - uploads all bound geometries
125 * @param buffer The buffer this processor is attached to
126 *
127 * Uploads all geometry nodes to their target vertex buffers.
128 * Uses staging buffers for device-local targets.
129 */
130 void processing_function(const std::shared_ptr<Buffer>& buffer) override;
131
132private:
133 std::unordered_map<std::string, GeometryBinding> m_bindings;
134
135 /**
136 * @brief Upload index data for one binding, creating or growing the
137 * GPU index buffer as needed.
138 * @param name Logical binding name (for diagnostics only).
139 * @param binding Binding to operate on.
140 */
141 void upload_index_data(const std::string& name, GeometryBinding& binding);
142
144 std::shared_ptr<Core::VKImage> image;
145 std::string binding;
146 };
147
148 std::optional<PendingTexture> m_pending_texture;
149 std::atomic_flag m_texture_dirty;
150};
151
152} // namespace MayaFlux::Buffers
IO::ImageData image
Definition Decoder.cpp:57
std::unordered_map< std::string, GeometryBinding > m_bindings
BufferProcessor that uploads geometry node data to GPU vertex buffers.
std::shared_ptr< Nodes::GpuSync::GeometryWriterNode > node
Holds GPU resources for one GeometryWriterNode binding.