MayaFlux 0.5.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches

◆ upload_volume()

bool MayaFlux::IO::upload_volume ( const Kakshya::VolumeData data,
const std::shared_ptr< Buffers::VolumeGridBuffer > &  volume 
)

Upload every field of a host VolumeData into a GPU-resident volume.

The reverse of download_volume: for each field in data whose name is declared on volume, writes its bytes into the current write slot via VolumeGridBuffer::seed_raw. The calling thread must have command queue access, matching download_volume's requirement, since seed_raw records a transfer that must resolve before the next one can be issued.

A scalar field (VolumeField holding vector<float>) uploads directly. A vector field is expanded from glm::vec3 to glm::vec4 first, zeroing the fourth component, because the GPU layout carries that padding and VolumeData does not — the inverse of the gather download_volume performs. That expansion costs an allocation at four thirds the input size.

A field named in data but not declared on volume, or whose declared stride does not match what the field's variant implies (float for a scalar, vec4 for a vector), is skipped with an error; the rest of the upload proceeds. Neither VolumeData's lattice nor its cell count is checked against the volume's own — a mismatch surfaces as seed_raw's own size-mismatch error per field, not as a single upfront rejection.

Each field is one seed_raw call rather than a batched transfer: simpler than building a seed_raw counterpart to read_fields' batching, at the cost of one staging round trip per field instead of one for the whole upload. Worth revisiting if upload_volume becomes a per-frame path rather than the one-shot load this exists for.

Parameters
dataSource, typically from IO::VolumeReader::load().
volumeDestination. Fields must already be declared; this call never declares one.
Returns
True if at least one field was uploaded.

Definition at line 124 of file VolumeTransfer.cpp.

127{
128 if (!volume) {
129 MF_ERROR(Journal::Component::IO, Journal::Context::FileIO,
130 "upload_volume: null volume");
131 return false;
132 }
133
134 if (!data.is_consistent()) {
135 MF_ERROR(Journal::Component::IO, Journal::Context::FileIO,
136 "upload_volume: VolumeData failed is_consistent()");
137 return false;
138 }
139
140 size_t uploaded = 0;
141
142 for (const auto& field : data.fields) {
143 if (!volume->has_field(field.name)) {
144 MF_ERROR(Journal::Component::IO, Journal::Context::FileIO,
145 "upload_volume: no field named '{}' on this volume, skipped", field.name);
146 continue;
147 }
148
149 const size_t stride = volume->get_field_stride(field.name);
150
151 if (const auto* scalars = field.as_scalar()) {
152 if (stride != sizeof(float)) {
153 MF_ERROR(Journal::Component::IO, Journal::Context::FileIO,
154 "upload_volume: field '{}' has stride {}, but VolumeData holds a scalar "
155 "(expected {}), skipped",
156 field.name, stride, sizeof(float));
157 continue;
158 }
159 volume->seed_raw(field.name, scalars->data(), scalars->size() * sizeof(float));
160 ++uploaded;
161 continue;
162 }
163
164 const auto* vectors = field.as_vector();
165 if (stride != sizeof(glm::vec4)) {
166 MF_ERROR(Journal::Component::IO, Journal::Context::FileIO,
167 "upload_volume: field '{}' has stride {}, but VolumeData holds a vector "
168 "(expected {}), skipped",
169 field.name, stride, sizeof(glm::vec4));
170 continue;
171 }
172
173 std::vector<glm::vec4> padded(vectors->size());
174 for (size_t i = 0; i < vectors->size(); ++i) {
175 padded[i] = glm::vec4((*vectors)[i], 0.0F);
176 }
177 volume->seed_raw(field.name, padded.data(), padded.size() * sizeof(glm::vec4));
178 ++uploaded;
179 }
180
181 if (uploaded == 0) {
182 MF_ERROR(Journal::Component::IO, Journal::Context::FileIO,
183 "upload_volume: no field was uploaded");
184 return false;
185 }
186
187 MF_DEBUG(Journal::Component::IO, Journal::Context::FileIO,
188 "upload_volume: {} of {} fields", uploaded, data.fields.size());
189
190 return true;
191}
#define MF_ERROR(comp, ctx,...)
#define MF_DEBUG(comp, ctx,...)
bool is_consistent() const
Check that every field is densely populated over the lattice.
std::vector< VolumeField > fields

References MayaFlux::Kakshya::VolumeData::fields, MayaFlux::Journal::FileIO, MayaFlux::Journal::IO, MayaFlux::Kakshya::VolumeData::is_consistent(), MF_DEBUG, and MF_ERROR.

Referenced by MayaFlux::IO::IOManager::load_volume().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: