23 : m_size_bytes(size_bytes)
25 , m_modality(modality)
32 "VKBuffer created (uninitialized): {} bytes, modality: {}",
42 "clear() on VKBuffer with no GPU resources: nothing to clear");
53 "Cannot get device address of uninitialized VKBuffer");
57 if (
m_usage != Usage::UNIFORM_BDA &&
m_usage != Usage::STORAGE_BDA) {
59 "get_device_address() called on buffer without BDA usage flags");
66 if (!buffer_service) {
67 error<std::runtime_error>(
70 std::source_location::current(),
71 "Cannot query buffer device address: BufferService not available");
74 auto shared_this = std::const_pointer_cast<VKBuffer>(
75 std::static_pointer_cast<const VKBuffer>(shared_from_this()));
77 return buffer_service->get_buffer_device_address(
78 std::static_pointer_cast<void>(shared_this));
85 "Cannot set_data on uninitialized VKBuffer. Register with BufferManager first.");
103 error<std::runtime_error>(
106 std::source_location::current(),
107 "Data size {} exceeds buffer capacity {}",
117 "set_data() on device-local buffer requires BufferUploadProcessor in chain");
125 "Cannot get_data from uninitialized VKBuffer");
134 return { raw_bytes };
138 "get_data() on device-local buffer requires BufferDownloadProcessor");
152 "Cannot resize uninitialized VKBuffer");
159 if (!buffer_service) {
160 error<std::runtime_error>(
163 std::source_location::current(),
164 "Cannot resize buffer: BufferService not available");
167 std::vector<uint8_t> old_data;
170 old_data.resize(copy_size);
174 "Preserved {} bytes of old buffer data", copy_size);
180 if (!display_service) {
181 error<std::runtime_error>(
184 std::source_location::current(),
185 "Cannot resize buffer: BufferService not available");
188 display_service->wait_idle();
189 buffer_service->destroy_buffer(shared_from_this());
198 buffer_service->initialize_buffer(shared_from_this());
201 error<std::runtime_error>(
204 std::source_location::current(),
205 "Failed to recreate buffer after resize");
213 "Restored {} bytes to resized buffer", old_data.size());
230 if (
m_usage == Usage::INDIRECT) {
231 auto default_flag = vk::BufferUsageFlagBits::eTransferSrc | vk::BufferUsageFlagBits::eTransferDst;
233 "Indirect buffer usage is not supported in VKBuffer. Force returning default {} flag.", vk::to_string(default_flag));
243 return vk::MemoryPropertyFlagBits::eHostVisible | vk::MemoryPropertyFlagBits::eHostCoherent;
245 return vk::MemoryPropertyFlagBits::eDeviceLocal;
261 processor->on_attach(shared_from_this());
287 using namespace Kakshya;
292 case DataModality::VERTICES_3D: {
296 m_dimensions.push_back(DataDimension::grouped(
"scalar",
count, 1, DataDimension::Role::CUSTOM));
299 m_dimensions.push_back(DataDimension::grouped(
"tangents",
count, 3, DataDimension::Role::CUSTOM));
302 case DataModality::VERTEX_POSITIONS_3D: {
303 uint64_t
count = byte_count /
sizeof(glm::vec3);
308 case DataModality::VERTEX_NORMALS_3D: {
309 uint64_t
count = byte_count /
sizeof(glm::vec3);
314 case DataModality::TEXTURE_COORDS_2D: {
315 uint64_t
count = byte_count /
sizeof(glm::vec2);
320 case DataModality::VERTEX_COLORS_RGB: {
321 uint64_t
count = byte_count /
sizeof(glm::vec3);
326 case DataModality::VERTEX_COLORS_RGBA: {
327 uint64_t
count = byte_count /
sizeof(glm::vec4);
332 case DataModality::AUDIO_1D: {
333 uint64_t samples = byte_count /
sizeof(double);
339 m_dimensions.emplace_back(
"data", byte_count, 1, DataDimension::Role::CUSTOM);
352 if (default_render && default_render->get_render_pipeline_id() ==
id)
353 return default_render;
358 auto buffer = shared_from_this();
360 auto render = std::dynamic_pointer_cast<RenderProcessor>(processor);
361 if (render && render->get_render_pipeline_id() ==
id)
365 for (
const auto& processor : {
369 auto render = std::dynamic_pointer_cast<RenderProcessor>(processor);
370 if (render && render->get_render_pipeline_id() ==
id)
378 std::vector<std::shared_ptr<RenderProcessor>> render_processors;
381 auto add_processor = [&render_processors, &primary](
const std::shared_ptr<BufferProcessor>& processor) {
382 auto render = std::dynamic_pointer_cast<RenderProcessor>(processor);
383 if (!render || render == primary
384 || std::ranges::find(render_processors, render) != render_processors.end()) {
387 render_processors.push_back(std::move(render));
393 auto buffer = shared_from_this();
402 return render_processors;
406 std::shared_ptr<RenderProcessor>& render_processor,
410 if (!render_processor)
411 render_processor = std::make_shared<RenderProcessor>(shader_config);
415 render_processor->set_target_window(
417 std::dynamic_pointer_cast<VKBuffer>(shared_from_this()));
419 render_processor->set_primitive_topology(config.
topology);
420 render_processor->set_triangulate(config.
triangulate);
421 render_processor->set_polygon_mode(config.
polygon_mode);
422 render_processor->set_cull_mode(config.
cull_mode);
423 render_processor->set_scissor(config.
scissor);
455 auto computed_layout = layout;
465 buffer->set_vertex_layout(layout.value());
472 if (
buffer->is_host_visible()) {
477 std::dynamic_pointer_cast<VKBuffer>(shared_from_this()),
482 if (
buffer->is_host_visible()) {
485 std::dynamic_pointer_cast<VKBuffer>(shared_from_this()),
489 "Cloning device-local VKBuffer to another device-local VKBuffer requires external data transfer");
499 return std::dynamic_pointer_cast<Buffers::Buffer>(
clone_to(
usage));
521 error<std::runtime_error>(
524 std::source_location::current(),
525 "VKBufferProcessor requires a valid BufferService");
527 if (!
buffer->is_initialized()) {
#define MF_INFO(comp, ctx,...)
#define MF_ERROR(comp, ctx,...)
#define MF_RT_ERROR(comp, ctx,...)
#define MF_TRACE(comp, ctx,...)
#define MF_WARN(comp, ctx,...)
#define MF_DEBUG(comp, ctx,...)
std::shared_ptr< NetworkGeometryBuffer > buffer
BufferProcessingChain * chain
Advanced pipeline manager for multi-stage buffer transformations with backend optimization.
Registry::Service::ComputeService * m_compute_service
void initialize_compute_service()
void initialize_buffer_service()
Registry::Service::BufferService * m_buffer_service
void ensure_initialized(const std::shared_ptr< VKBuffer > &buffer)
std::vector< std::pair< size_t, size_t > > m_dirty_ranges
void infer_dimensions_from_data(size_t byte_count)
Infer Kakshya::DataDimension entries from a given byte count.
void set_vertex_layout(const Kakshya::VertexLayout &layout)
Set vertex layout for this buffer.
std::vector< std::pair< size_t, size_t > > get_and_clear_invalid_ranges()
Retrieve and clear all invalid ranges.
void resize(size_t new_size, bool preserve_data=false)
Resize buffer and recreate GPU resources if needed.
void process_default() override
Run the buffer's default processor (if set and enabled)
std::vector< Kakshya::DataVariant > get_data()
Read buffer contents as Kakshya DataVariant.
std::shared_ptr< Buffers::BufferProcessor > get_default_processor() const override
Get the currently attached default processor.
std::optional< Kakshya::VertexLayout > m_vertex_layout
std::vector< Kakshya::DataDimension > m_dimensions
std::shared_ptr< Buffers::BufferProcessingChain > m_processing_chain
std::vector< std::pair< size_t, size_t > > get_and_clear_dirty_ranges()
Retrieve and clear all dirty ranges.
std::shared_ptr< Buffers::BufferProcessingChain > get_processing_chain() override
Access the buffer's processing chain.
void set_default_processor(const std::shared_ptr< BufferProcessor > &processor) override
Set the buffer's default processor.
virtual std::shared_ptr< RenderProcessor > get_render_processor() const
Get a RenderProcessor suitable for rendering this buffer.
std::vector< std::pair< size_t, size_t > > m_invalid_ranges
void clear() override
Clear buffer contents.
std::optional< Kakshya::VertexLayout > get_vertex_layout() const
Get vertex layout if set.
void set_processing_chain(const std::shared_ptr< BufferProcessingChain > &chain, bool force=false) override
Replace the buffer's processing chain.
VKBufferResources m_resources
std::shared_ptr< Buffer > clone_to(uint8_t dest_desc) override
Creates a clone of this buffer for a specific channel or usage enum.
void apply_render_config(const RenderConfig &config, const ShaderConfig &shader_config)
Configure the internal m_render_processor from a RenderConfig.
std::shared_ptr< Buffers::BufferProcessor > m_default_processor
void mark_dirty_range(size_t offset, size_t size)
Get device memory handle.
bool is_initialized() const
Check whether Vulkan handles are present (buffer registered)
vk::BufferUsageFlags get_usage_flags() const
Get appropriate VkBufferUsageFlags for creation based on Usage.
std::shared_ptr< RenderProcessor > m_render_processor
vk::MemoryPropertyFlags get_memory_properties() const
Get appropriate VkMemoryPropertyFlags for allocation based on Usage.
std::vector< std::shared_ptr< RenderProcessor > > get_additional_render_processors()
Get additional live render processors attached through the chain.
Kakshya::DataModality m_modality
void set_modality(Kakshya::DataModality modality)
Update the semantic modality and re-infer dimensions.
void set_data(const std::vector< Kakshya::DataVariant > &data)
Write data into the buffer.
uint64_t get_device_address() const
Get the Vulkan device address for this buffer (if applicable)
bool is_host_visible() const
Whether this VKBuffer should be host-visible.
~VKBuffer() override
Virtual destructor.
void mark_invalid_range(size_t offset, size_t size)
Mark a range as invalid (needs download)
auto gpu_buffer() const
Get raw buffer info for GPU upload.
Type-erased accessor for NDData with semantic view construction.
Interface * get_service()
Query for a backend service.
static BackendRegistry & instance()
Get the global registry instance.
ProcessingToken
Bitfield enum defining processing characteristics and backend requirements for buffer operations.
@ GRAPHICS_BACKEND
Standard graphics processing backend configuration.
uint64_t RenderPipelineID
bool clear_gpu_buffer(const std::shared_ptr< VKBuffer > &target)
Zero a registered GPU buffer in place (auto-detects host-visible vs device-local)
void download_device_local(const std::shared_ptr< VKBuffer > &source, const std::shared_ptr< VKBuffer > &target, const std::shared_ptr< VKBuffer > &staging_buffer)
Download data from a device-local buffer using a staging buffer.
void upload_device_local(const std::shared_ptr< VKBuffer > &target, const std::shared_ptr< VKBuffer > &staging_buffer, const Kakshya::DataVariant &data, size_t dst_offset)
Upload data to a device-local buffer using a staging buffer.
@ BufferManagement
Buffer Management (Buffers::BufferManager, creating buffers)
@ BufferProcessing
Buffer processing (Buffers::BufferManager, processing chains)
@ Buffers
Buffers, Managers, processors and processing chains.
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.
std::string_view modality_to_string(DataModality modality)
Convert DataModality enum to string representation.
BufferUsageHint
Semantic usage hint for buffer allocation and memory properties.
vk::BufferUsageFlags to_buffer_usage_flags(BufferUsageHint hint)
Resolve the extra vk::BufferUsageFlags a BufferUsageHint requires, on top of whatever base usage the ...
void add_processor(const std::shared_ptr< Buffers::BufferProcessor > &processor, const std::shared_ptr< Buffers::Buffer > &buffer, Buffers::ProcessingToken token)
Adds a processor to a specific buffer.
void compute_stride()
Helper: compute stride from attributes if not explicitly set.
Complete description of vertex data layout in a buffer.
Type-neutral vertex carrying the universal 60-byte attribute layout.
std::shared_ptr< Core::Window > target_window
std::optional< Kinesis::Scissor > scissor
Clip this buffer's draws to an NDC region.
bool triangulate
Reduce supplied spans to triangles before drawing them.
PrimitiveTopology topology
std::string fragment_shader
std::string geometry_shader
Unified rendering configuration for graphics buffers.
std::function< void(const std::shared_ptr< void > &)> initialize_buffer
Initialize a buffer object.
Backend buffer management service interface.
Backend compute shader and pipeline service interface.
Backend display and presentation service interface.