Pull every feed and write its result.
Called at the top of processing_function, before descriptors are rebuilt, so a storage feed creating its buffer binds the same cycle. Callables run on whichever thread drives the chain.
321{
323 if (entry.early != early) {
324 continue;
325 }
326
328
329 if (!entry.is_storage) {
330 if (
const auto* typed = std::get_if<Kakshya::GpuValue>(&
value)) {
332 if (!entry.mismatch_logged) {
334 "feed '{}' returned a value of a different format than its push constant field",
name);
335 entry.mismatch_logged = true;
336 }
337 continue;
338 }
339
340 std::array<std::byte, 64> bytes {};
342
344 const size_t required = entry.offset + written;
345 if (data.size() < required) {
346 data.resize(required);
347 }
348
349 std::memcpy(data.data() + entry.offset, bytes.data(), written);
350 continue;
351 }
352
355 if (!entry.mismatch_logged) {
357 "feed '{}' writes a push constant but returned a DataVariant",
name);
358 entry.mismatch_logged = true;
359 }
360 continue;
361 }
362
364 const size_t required = entry.offset + entry.size;
365 if (data.size() < required) {
366 data.resize(required);
367 }
368
369 if (entry.size == sizeof(float)) {
370 const auto narrowed = static_cast<float>(*scalar);
371 std::memcpy(data.data() + entry.offset, &narrowed, sizeof(float));
372 } else {
373 std::memcpy(data.data() + entry.offset,
scalar,
sizeof(
double));
374 }
375 continue;
376 }
377
378 auto* variant = std::get_if<Kakshya::DataVariant>(&
value);
379 if (!variant) {
380 if (!entry.mismatch_logged) {
382 "feed '{}' writes a storage descriptor but returned a push constant value",
name);
383 entry.mismatch_logged = true;
384 }
385 continue;
386 }
387
389 auto [
ptr, bytes,
format] = accessor.gpu_buffer();
390
391 if (!
ptr || bytes == 0) {
393 "feed '{}' produced no bytes",
name);
394 continue;
395 }
396
397 if (!entry.buffer) {
398 entry.buffer = std::make_shared<VKBuffer>(
399 static_cast<size_t>(static_cast<float>(bytes) * 1.5F),
400 m_config.
bindings.at(entry.descriptor_name).type == vk::DescriptorType::eUniformBuffer
401 ? VKBuffer::Usage::UNIFORM
404
406
408 "feed '{}' backing buffer created at {} bytes",
409 name, entry.buffer->get_size_bytes());
410 } else if (entry.buffer->get_size_bytes() < bytes) {
411 const size_t grown = bytes * 3 / 2;
412
414 "feed '{}' backing buffer resized {} to {} bytes",
415 name, entry.buffer->get_size_bytes(), grown);
416
417 entry.buffer->resize(grown, false);
419 }
420
422 }
423}
#define MF_ERROR(comp, ctx,...)
#define MF_RT_WARN(comp, ctx,...)
#define MF_DEBUG(comp, ctx,...)
const std::vector< uint8_t > & get_push_constant_data() const
Get current push constant data.
bool m_needs_descriptor_rebuild
std::unordered_map< std::string, Feed > m_feeds
void bind_buffer(const std::string &descriptor_name, const std::shared_ptr< VKBuffer > &buffer)
Bind a VKBuffer to a named shader descriptor.
std::variant< double, Kakshya::GpuValue, Kakshya::DataVariant > FeedValue
What a feed callable returns.
void upload_host_visible(const std::shared_ptr< VKBuffer > &target, const Kakshya::DataVariant &data, size_t dst_offset)
Upload data to a host-visible buffer.
@ BufferProcessing
Buffer processing (Buffers::BufferManager, processing chains)
@ Buffers
Buffers, Managers, processors and processing chains.
@ Kakshya
Containers[Signalsource, Stream, File], Regions, DataProcessors.
DataModality
Data modality types for cross-modal analysis.
@ UNKNOWN
Unknown or undefined modality.
GpuDataFormat gpu_value_format(const GpuValue &value) noexcept
The GpuDataFormat of the value held.
size_t gpu_value_write(const GpuValue &value, std::span< std::byte > out) noexcept
Copies the held value's bytes into out, unconverted.
@ HOST_STORAGE
Host-visible storage buffer (eStorageBuffer + eHostVisible|eHostCoherent)
std::unordered_map< std::string, ShaderBinding > bindings