MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
MeshProcessor.cpp
Go to the documentation of this file.
1#include "MeshProcessor.hpp"
2#include "MeshBuffer.hpp"
3
5
10
11namespace MayaFlux::Buffers {
12
18
19// =============================================================================
20// on_attach
21// =============================================================================
22
23void MeshProcessor::on_attach(const std::shared_ptr<Buffer>& buffer)
24{
25 if (!m_buffer_service) {
28 }
29
30 if (!m_buffer_service) {
31 error<std::runtime_error>(
34 std::source_location::current(),
35 "MeshProcessor requires a valid BufferService");
36 }
37
38 auto mesh_buf = std::dynamic_pointer_cast<MeshBuffer>(buffer);
39 if (!mesh_buf) {
41 "MeshProcessor: attached to non-MeshBuffer — detaching");
42 return;
43 }
44
45 if (!mesh_buf->m_mesh_data.is_valid()) {
47 "MeshProcessor: MeshData is not valid on attach — no GPU resources allocated");
48 return;
49 }
50
51 m_mesh_buffer = mesh_buf;
52
53 ensure_initialized(mesh_buf);
54
55 allocate_gpu_buffers(mesh_buf);
56 upload_vertices(mesh_buf);
57 upload_indices(mesh_buf);
59
60 mesh_buf->clear_vertices_dirty();
61 mesh_buf->clear_indices_dirty();
62
63 mesh_buf->set_vertex_layout(mesh_buf->m_mesh_data.layout);
64
66 "MeshProcessor: initialised — {} vertices, {} indices ({} faces), stride {}",
67 mesh_buf->get_vertex_count(),
68 mesh_buf->get_index_count(),
69 mesh_buf->get_face_count(),
70 mesh_buf->m_mesh_data.layout.stride_bytes);
71}
72
73void MeshProcessor::on_detach(const std::shared_ptr<Buffer>& /*buffer*/)
74{
75 m_mesh_buffer.reset();
76 m_gpu_index_buffer.reset();
77 m_vertex_staging.reset();
78 m_index_staging.reset();
79}
80
81// =============================================================================
82// processing_function — per-cycle dirty check
83// =============================================================================
84
85void MeshProcessor::processing_function(const std::shared_ptr<Buffer>& /*buffer*/)
86{
87 if (!m_mesh_buffer) {
88 return;
89 }
90
91 if (auto node = m_mesh_buffer->get_node()) {
92 if (!node->get_mesh_vertices().empty()) {
93 const auto& verts = node->get_mesh_vertices();
94 const auto& indices = node->get_mesh_indices();
95 m_mesh_buffer->m_mesh_data.vertex_variant = std::vector<uint8_t>(
96 reinterpret_cast<const uint8_t*>(verts.data()),
97 reinterpret_cast<const uint8_t*>(verts.data() + verts.size()));
98 m_mesh_buffer->m_mesh_data.index_variant = indices;
99 m_mesh_buffer->m_mesh_data.layout.vertex_count = static_cast<uint32_t>(verts.size());
100 m_mesh_buffer->m_vertices_dirty.store(true, std::memory_order_release);
101 m_mesh_buffer->m_indices_dirty.store(true, std::memory_order_release);
102 }
103 }
104
105 if (m_mesh_buffer->vertices_dirty()) {
107 m_mesh_buffer->clear_vertices_dirty();
108
110 "MeshProcessor: re-uploaded vertex data ({} bytes)",
111 m_mesh_buffer->get_size_bytes());
112 }
113
114 if (m_mesh_buffer->indices_dirty()) {
117 m_mesh_buffer->clear_indices_dirty();
118
120 "MeshProcessor: re-uploaded index data ({} indices)",
121 m_mesh_buffer->get_index_count());
122 }
123}
124
125// =============================================================================
126// Private helpers
127// =============================================================================
128
129void MeshProcessor::allocate_gpu_buffers(const std::shared_ptr<MeshBuffer>& buf)
130{
131 const auto* vb = std::get_if<std::vector<uint8_t>>(
132 &buf->m_mesh_data.vertex_variant);
133 const auto* ib = std::get_if<std::vector<uint32_t>>(
134 &buf->m_mesh_data.index_variant);
135
136 if (!vb || vb->empty() || !ib || ib->empty()) {
138 "MeshProcessor::allocate_gpu_buffers: empty vertex or index data");
139 return;
140 }
141
142 if (!buf->is_host_visible()) {
144 }
145
146 const size_t idx_bytes = ib->size() * sizeof(uint32_t);
147 m_gpu_index_buffer = std::make_shared<VKBuffer>(
148 idx_bytes,
151
154
156 "MeshProcessor: allocated vertex buffer ({} bytes) + index buffer ({} bytes)",
157 vb->size(), idx_bytes);
158}
159
160void MeshProcessor::upload_vertices(const std::shared_ptr<MeshBuffer>& buf)
161{
162 const auto* vb = std::get_if<std::vector<uint8_t>>(
163 &buf->m_mesh_data.vertex_variant);
164 if (!vb || vb->empty()) {
165 return;
166 }
167
169 vb->data(),
170 vb->size(),
171 std::dynamic_pointer_cast<VKBuffer>(buf),
172 buf->is_host_visible() ? nullptr : m_vertex_staging);
173}
174
175void MeshProcessor::upload_indices(const std::shared_ptr<MeshBuffer>& buf)
176{
177 const auto* ib = std::get_if<std::vector<uint32_t>>(
178 &buf->m_mesh_data.index_variant);
179 if (!ib || ib->empty() || !m_gpu_index_buffer) {
180 return;
181 }
182
184 ib->data(),
185 ib->size() * sizeof(uint32_t),
188}
189
191{
193 return;
194 }
195
196 m_mesh_buffer->set_index_resources(
197 m_gpu_index_buffer->get_buffer(),
198 m_gpu_index_buffer->get_buffer_resources().memory,
199 m_gpu_index_buffer->get_size_bytes());
200}
201
202} // namespace MayaFlux::Buffers
#define MF_INFO(comp, ctx,...)
#define MF_ERROR(comp, ctx,...)
#define MF_DEBUG(comp, ctx,...)
void processing_function(const std::shared_ptr< Buffer > &buffer) override
The core processing function that must be implemented by derived classes.
std::shared_ptr< VKBuffer > m_vertex_staging
void allocate_gpu_buffers(const std::shared_ptr< MeshBuffer > &buf)
void upload_vertices(const std::shared_ptr< MeshBuffer > &buf)
std::shared_ptr< VKBuffer > m_index_staging
std::shared_ptr< MeshBuffer > m_mesh_buffer
std::shared_ptr< VKBuffer > m_gpu_index_buffer
void upload_indices(const std::shared_ptr< MeshBuffer > &buf)
void on_attach(const std::shared_ptr< Buffer > &buffer) override
Called when this processor is attached to a buffer.
void on_detach(const std::shared_ptr< Buffer > &buffer) override
Called when this processor is detached from a buffer.
Registry::Service::BufferService * m_buffer_service
Definition VKBuffer.hpp:665
void ensure_initialized(const std::shared_ptr< VKBuffer > &buffer)
Definition VKBuffer.cpp:471
Interface * get_service()
Query for a backend service.
static BackendRegistry & instance()
Get the global registry instance.
void upload_resizing(const void *data, size_t size, const std::shared_ptr< VKBuffer > &target, const std::shared_ptr< VKBuffer > &staging, float growth_factor)
Upload size bytes to target, growing both buffers first if needed.
@ GRAPHICS_BACKEND
Standard graphics processing backend configuration.
std::shared_ptr< VKBuffer > create_staging_buffer(size_t size)
Create staging buffer for transfers.
@ BufferProcessing
Buffer processing (Buffers::BufferManager, processing chains)
@ Buffers
Buffers, Managers, processors and processing chains.
@ UNKNOWN
Unknown or undefined modality.
Backend buffer management service interface.