30 void ensure_staging(std::shared_ptr<VKBuffer>& staging,
size_t size)
32 if (!staging || staging->get_size_bytes() <
size) {
40 : m_writes(
std::make_unique<Memory::LockFreeQueue<
WriteFn, k_write_queue_capacity>>())
49 "DataWriteProcessor write queue is full; the write was dropped");
55 auto payload = std::make_shared<Kakshya::DataVariant>(std::move(data));
57 const auto bytes = Kakshya::convert_variant<uint8_t>(*
payload);
58 if (!target || !target->is_initialized() || bytes.size_bytes() == 0
59 || dst_offset + bytes.size_bytes() > target->get_size_bytes()) {
61 "DataWriteProcessor write_buffer needs an initialized target with room for the data");
73 auto payload = std::make_shared<Kakshya::DataVariant>(std::move(data));
75 const auto bytes = Kakshya::convert_variant<uint8_t>(*
payload);
76 const size_t size = bytes.size_bytes();
78 if (
const auto volume = std::dynamic_pointer_cast<VolumeGridBuffer>(vk);
79 volume && volume->has_field(
name)) {
80 if (
size != volume->get_field_bytes(
name)) {
82 "DataWriteProcessor write_field '{}' needs exactly {} bytes",
name, volume->get_field_bytes(
name));
85 volume->seed_raw(
name, bytes.data(),
size);
89 if (
const auto network = std::dynamic_pointer_cast<NetworkGeometryBuffer>(vk);
93 "DataWriteProcessor write_field '{}' needs exactly {} bytes",
name,
network->get_state_bytes(
name));
97 if (!slot.mapped_ptr) {
105 "DataWriteProcessor write_field found no field named '{}' on the attached buffer",
name);
111 auto payload = std::make_shared<Kakshya::DataVariant>(std::move(data));
113 const auto bytes = Kakshya::convert_variant<uint8_t>(*
payload);
114 const auto& slots = vk->get_buffer_resources().back_buffers;
115 if (
index >= slots.size() || bytes.size_bytes() == 0) {
117 "DataWriteProcessor write_back_buffer needs an existing slot and nonempty data");
120 if (!slots[
index].mapped_ptr) {
129 auto mesh = std::make_shared<Kakshya::MeshData>(std::move(data));
131 if (
const auto mesh_buffer = std::dynamic_pointer_cast<MeshBuffer>(vk)) {
132 mesh_buffer->set_mesh_data(std::move(*mesh));
136 if (
const auto geometry_buffer = std::dynamic_pointer_cast<GeometryBuffer>(vk)) {
137 if (
const auto node = std::dynamic_pointer_cast<Nodes::GpuSync::MeshWriterNode>(
138 geometry_buffer->get_geometry_node())) {
139 node->set_mesh(*mesh);
144 if (
const auto network_buffer = std::dynamic_pointer_cast<MeshNetworkBuffer>(vk)) {
145 const auto network = network_buffer->get_network();
147 if (found && found->node) {
148 found->node->set_mesh(*mesh);
154 "DataWriteProcessor write_mesh needs a MeshBuffer, a GeometryBuffer driven by a MeshWriterNode, "
155 "or a MeshNetworkBuffer with a named slot that has a node");
161 auto payload = std::make_shared<Kakshya::ImageData>(std::move(
image));
163 const auto texture = std::dynamic_pointer_cast<TextureBuffer>(vk);
164 if (!texture ||
payload->format != texture->get_format()
165 ||
payload->width != texture->get_width() ||
payload->height != texture->get_height()
166 || !
payload->is_consistent()) {
168 "DataWriteProcessor write_pixels needs a TextureBuffer and an image of its format and size");
177 auto payload = std::make_shared<Kakshya::ImageData>(std::move(
image));
181 const auto texture = std::dynamic_pointer_cast<TextureBuffer>(vk);
183 auto& loom = TextureLoom::instance();
184 const auto format = TextureLoom::writable_format(gpu_image);
186 ||
payload->width != gpu_image->get_width() ||
payload->height != gpu_image->get_height()
187 || !
payload->is_consistent()) {
189 "DataWriteProcessor write_texture_pixels needs a TextureBuffer with a writable GPU image "
190 "and an image of its format and size");
201 loom.upload_data(gpu_image,
payload->data(),
size);
221 const auto*
src =
static_cast<const uint8_t*
>(data);
262 auto vk = std::dynamic_pointer_cast<VKBuffer>(
buffer);
264 error<std::invalid_argument>(
267 std::source_location::current(),
268 "DataWriteProcessor requires a VKBuffer");
272 m_topology = vk->get_render_config().topology;
274 if (!vk->is_host_visible()) {
299 "DataWriteProcessor attached (modality: {}, staging: {})",
324 auto vk = std::dynamic_pointer_cast<VKBuffer>(
buffer);
327 "DataWriteProcessor attached to non-VKBuffer");
331 while (
auto write =
m_writes->pop()) {
338 if (
auto rp = vk->get_render_processor()) {
352 if (
auto rp = vk->get_render_processor()) {
373 for (
size_t i = 1; i <
m_active.size(); ++i) {
395 auto bytes = Kakshya::convert_variant<uint8_t>(slot);
402 std::optional<Kakshya::VertexAccess> access;
420 "DataWriteProcessor: vertex access failed for modality {}",
427 vk->set_vertex_layout(access->layout);
435 "DataWriteProcessor: as_texture_access failed for modality {}",
444 "DataWriteProcessor: setup_pixel_target() not called before texture upload");
454 "DataWriteProcessor: failed to create GPU texture {}x{}",
459 if (
auto rp = vk->get_render_processor()) {
478 if (required <= vk->get_size_bytes()) {
482 vk->resize(
static_cast<size_t>(
static_cast<float>(required) * 1.5F),
false);
#define MF_ERROR(comp, ctx,...)
#define MF_RT_ERROR(comp, ctx,...)
#define MF_DEBUG(comp, ctx,...)
Core::GlobalNetworkConfig network
std::shared_ptr< NetworkGeometryBuffer > buffer
ProcessingToken m_processing_token
void upload_secondary(const std::shared_ptr< VKBuffer > &vk, Kakshya::DataVariant &slot)
std::vector< Kakshya::DataVariant > m_data_pending
void set_pixel_data(Kakshya::DataVariant variant)
Supply pixel data for the co-resident texture on the next cycle.
std::shared_ptr< VKBuffer > m_write_staging
void processing_function(const std::shared_ptr< Buffer > &buffer) override
The core processing function that must be implemented by derived classes.
Kakshya::DataVariant m_pixel_pending
bool m_tex_binding_confirmed
void on_detach(const std::shared_ptr< Buffer > &buffer) override
Called when this processor is detached from a buffer.
static bool is_vertex_modality(Kakshya::DataModality m) noexcept
std::atomic_flag m_texture_dirty
Portal::Graphics::ImageFormat m_tex_format
std::atomic_flag m_pixel_dirty
void write_back_buffer(size_t index, Kakshya::DataVariant data)
Write a raw back_buffers slot of the attached buffer.
void write_buffer(std::shared_ptr< VKBuffer > target, Kakshya::DataVariant data, size_t dst_offset=0)
Write bytes into another VKBuffer, such as a plain descriptor-bound buffer.
void set_vertices(const void *data, size_t byte_count)
Supply pre-packed interleaved vertex bytes for the next cycle.
std::string m_tex_binding
std::function< void(DataWriteProcessor &, const std::shared_ptr< VKBuffer > &)> WriteFn
Kakshya::GpuDataFormat m_last_texture_format
void upload_texture(const std::shared_ptr< VKBuffer > &vk, Kakshya::DataVariant &slot)
void write_texture_pixels(Kakshya::ImageData image)
Write pixels straight into the attached TextureBuffer's GPU image.
void ensure_capacity(const std::shared_ptr< VKBuffer > &vk, size_t required)
Portal::Graphics::PrimitiveTopology m_topology
void set_data(Kakshya::DataVariant variant)
Supply a single data value for the next cycle (slot 0).
std::atomic_flag m_data_dirty
std::shared_ptr< Core::VKImage > m_gpu_texture
void upload_raw(const std::shared_ptr< VKBuffer > &vk, Kakshya::DataVariant &slot)
Kakshya::DataModality m_modality
std::optional< PendingTexture > m_pending_texture
void upload_vertex(const std::shared_ptr< VKBuffer > &vk, std::vector< Kakshya::DataVariant > &slots)
Kakshya::DataVariant m_pixel_active
void enqueue_write(WriteFn fn)
void setup_pixel_target(uint32_t width, uint32_t height, Portal::Graphics::ImageFormat format, std::string binding="texSampler")
Configure the pixel upload path for texture modalities.
std::shared_ptr< VKBuffer > m_write_image_staging
std::unique_ptr< Memory::LockFreeQueue< WriteFn, k_write_queue_capacity > > m_writes
void on_attach(const std::shared_ptr< Buffer > &buffer) override
Called when this processor is attached to a buffer.
std::vector< Kakshya::DataVariant > m_active
void write_pixels(Kakshya::ImageData image)
Write the retained host pixels of the attached TextureBuffer.
void write_mesh(Kakshya::MeshData data, std::string slot={})
Write mesh geometry to the attached buffer's authoritative copy.
std::shared_ptr< VKBuffer > m_staging
void upload_primary(const std::shared_ptr< VKBuffer > &vk, std::vector< Kakshya::DataVariant > &slots)
void set_texture(std::shared_ptr< Core::VKImage > image, std::string binding)
Supply a texture to bind on the next graphics tick.
Kakshya::GpuDataFormat last_texture_format() const noexcept
Returns the GpuDataFormat resolved on the last texture upload.
bool has_pending() const noexcept
Returns true if a snapshot has been set and not yet consumed.
std::shared_ptr< VKBuffer > m_image_staging
static bool is_texture_modality(Kakshya::DataModality m) noexcept
void write_field(std::string name, Kakshya::DataVariant data)
Write a named field of the attached buffer.
Modality-aware multi-slot write processor for plain VKBuffer.
auto gpu_buffer() const
Get raw buffer info for GPU upload.
Type-erased accessor for NDData with semantic view construction.
Portal-level texture creation and management.
std::shared_ptr< VKBuffer > create_image_staging_buffer(size_t size)
Allocate a persistent host-visible staging buffer sized for repeated streaming uploads to an image of...
std::shared_ptr< Core::VKImage > resolve_gpu_image(const T &buffer)
Resolve the GPU-resident image from any GpuImageSource buffer.
@ GRAPHICS_BACKEND
Standard graphics processing backend configuration.
std::shared_ptr< VKBuffer > create_staging_buffer(size_t size)
Create staging buffer for transfers.
bool is_device_local(const std::shared_ptr< VKBuffer > &buffer)
Check if buffer is device-local (staging needed)
void upload_to_gpu(const void *data, size_t size, const std::shared_ptr< VKBuffer > &target, const std::shared_ptr< VKBuffer > &staging, size_t dst_offset)
Upload raw data to GPU buffer (auto-detects host-visible vs device-local)
void upload_back_buffer(const VKBufferResources::GenerationSlot &slot, const void *data, size_t size, std::shared_ptr< VKBuffer > &staging)
Upload host memory into a raw back_buffers slot.
@ BufferProcessing
Buffer processing (Buffers::BufferManager, processing chains)
@ Buffers
Buffers, Managers, processors and processing chains.
ImageFormat
User-friendly image format enum.
std::optional< VertexAccess > as_line_vertex_access(std::span< const DataVariant > channels, const VertexAccessConfig &config)
Assemble line-vertex-compatible bytes from one or more data channels.
std::optional< VertexAccess > as_point_vertex_access(std::span< const DataVariant > channels, const VertexAccessConfig &config)
Assemble point-vertex-compatible bytes from one or more data channels.
std::variant< std::vector< double >, std::vector< float >, std::vector< uint8_t >, std::vector< uint16_t >, std::vector< uint32_t >, std::vector< std::complex< float > >, std::vector< std::complex< double > >, std::vector< glm::vec2 >, std::vector< glm::vec3 >, std::vector< glm::vec4 >, std::vector< glm::mat4 > > DataVariant
Multi-type data storage for different precision needs.
DataModality
Data modality types for cross-modal analysis.
@ SPECTRAL_2D
2D spectral data (time + frequency)
@ UNKNOWN
Unknown or undefined modality.
@ VERTICES_3D
3D vertex data (positions, normals, etc.)
@ VIDEO_GRAYSCALE
3D video (time + 2D grayscale)
@ VIDEO_COLOR
4D video (time + 2D + color)
@ TEXTURE_2D
2D texture data
@ IMAGE_COLOR
2D RGB/RGBA image
@ IMAGE_2D
2D image (grayscale or single channel)
std::string_view modality_to_string(DataModality modality)
Convert DataModality enum to string representation.
GpuDataFormat
GPU data formats with explicit precision levels.
std::optional< VertexAccess > as_mesh_vertex_access(std::span< const DataVariant > channels, const VertexAccessConfig &config)
Assemble mesh-vertex-compatible bytes from one or more data channels.
std::optional< TextureAccess > as_texture_access(const DataVariant &variant)
Extract a TextureAccess from a DataVariant.
MAYAFLUX_API TextureLoom & get_texture_manager()
Get the global texture manager instance.
std::shared_ptr< Core::VKImage > image
Raw image data loaded from file or read back from a GPU image.
Owning CPU-side representation of a loaded or generated mesh.
static VertexLayout for_raw(uint32_t stride=60)
Factory: layout for raw vertex data with common attributes.
static VertexLayout for_lines(uint32_t stride=60)
Factory: layout for LineVertex (position, color, thickness, uv, normal, tangent)
static VertexLayout for_meshes(uint32_t stride=60)
Factory: layout for MeshVertex (position, color, weight, uv, normal, tangent)
static VertexLayout for_points(uint32_t stride=60)
Factory: layout for PointVertex (position, color, size, uv, normal, tangent)