MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
VKBuffer.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "Buffer.hpp"
4
6
8
10struct BufferService;
11struct ComputeService;
12}
13
14namespace MayaFlux::Core {
15class Window;
16}
17
18namespace MayaFlux::Buffers {
19
20class RenderProcessor;
21struct ShaderConfig;
22
23/**
24 * @struct VKBufferResources
25 * @brief Raw Vulkan handles owned by a VKBuffer instance.
26 *
27 * The index_buffer / index_memory / index_size_bytes fields are populated
28 * by GeometryBindingsProcessor after index data upload and consumed by
29 * RenderProcessor to select the indexed draw path. They are null/zero for
30 * all non-indexed geometry; no separate allocation object is required.
31 */
33 vk::Buffer buffer;
34 vk::DeviceMemory memory;
35 void* mapped_ptr { nullptr };
36
37 vk::Buffer index_buffer;
38 vk::DeviceMemory index_memory;
39 size_t index_size_bytes { 0 };
40};
41
42using RenderPipelineID = uint64_t;
43using CommandBufferID = uint64_t;
44
45/**
46 * @class VKBuffer
47 * @brief Vulkan-backed buffer wrapper used in processing chains
48 *
49 * VKBuffer is a lightweight, high-level representation of a GPU buffer used by
50 * the MayaFlux processing pipeline. It carries semantic metadata (Kakshya
51 * modalities and dimensions), integrates with the Buffer processing chain and
52 * BufferManager, and exposes Vulkan handles once the backend registers the
53 * buffer. Prior to registration the object contains no GPU resources and can
54 * be manipulated cheaply (like AudioBuffer).
55 *
56 * Responsibilities:
57 * - Store buffer size, usage intent and semantic modality
58 * - Provide inferred data dimensions for processors and pipeline inspection
59 * - Hold Vulkan handles (VkBuffer, VkDeviceMemory) assigned by graphics backend
60 * - Provide convenience helpers for common Vulkan creation flags and memory props
61 * - Integrate with BufferProcessor / BufferProcessingChain for default processing
62 *
63 * Note: Actual allocation, mapping and command-based transfers are performed by
64 * the graphics backend / BufferManager. VKBuffer only stores handles and
65 * metadata and provides helpers for processors to operate on it.
66 */
67class MAYAFLUX_API VKBuffer : public Buffer {
68public:
70
71 enum class Usage : uint8_t {
72 STAGING, ///< Host-visible staging buffer (CPU-writable, eTransferSrc|Dst)
73 DEVICE, ///< Device-local GPU-only buffer
74 COMPUTE, ///< Storage buffer for compute shaders (device-local)
75 VERTEX, ///< Vertex buffer
76 INDEX, ///< Index buffer
77 UNIFORM, ///< Uniform buffer (host-visible)
78 UNIFORM_BDA, ///< Uniform buffer with device address query support
79 STORAGE_BDA, ///< Storage buffer with device address query support
80 HOST_STORAGE, ///< Host-visible storage buffer (eStorageBuffer + eHostVisible|eHostCoherent)
81 };
82
83 /**
84 * @brief Context shared with BufferProcessors during pipeline execution
85 *
86 * Processors can use this struct to share data (e.g., push constant staging)
87 * and metadata during processing of this buffer in a chain.
88 */
90 std::vector<uint8_t> push_constant_staging;
91
92 std::vector<Portal::Graphics::DescriptorBindingInfo> descriptor_buffer_bindings;
93
94 std::unordered_map<std::string, std::any> metadata;
95 };
96
97 /**
98 * @brief Engine-internal per-frame binding state
99 *
100 * Carries descriptor bindings written by engine processors (e.g.
101 * MeshNetworkProcessor SSBOs) that must reach RenderProcessor::execute_shader
102 * without passing through the user-facing PipelineContext. Access is
103 * unrestricted by convention only: engine processors write here, user code
104 * should not.
105 */
107 std::vector<Portal::Graphics::DescriptorBindingInfo> ssbo_bindings;
108 };
109
110 /**
111 * @brief Construct an unregistered VKBuffer
112 *
113 * Creates a VKBuffer object with the requested capacity, usage intent and
114 * semantic modality. No Vulkan resources are created by this constructor —
115 * registration with the BufferManager / backend is required to allocate
116 * VkBuffer and VkDeviceMemory.
117 *
118 * @param size_bytes Buffer capacity in bytes.
119 * @param usage Intended usage pattern (affects Vulkan flags and memory).
120 * @param modality Semantic interpretation of the buffer contents.
121 */
122 VKBuffer(
123 size_t size_bytes,
124 Usage usage,
125 Kakshya::DataModality modality = Kakshya::DataModality::VERTICES_3D);
126
127 VKBuffer() = default;
128
129 /**
130 * @brief Virtual destructor
131 *
132 * VKBuffer does not own Vulkan resources directly; cleanup is handled by
133 * the backend during unregistration. The destructor ensures derived class
134 * cleanup and safe destruction semantics.
135 */
136 ~VKBuffer() override;
137
138 /**
139 * @brief Get the Vulkan device address for this buffer (if applicable)
140 * @return 64-bit device address, or 0 if not BDA-capable or not initialized
141 *
142 * Only buffers created with Usage::UNIFORM_BDA or Usage::STORAGE_BDA and
143 * registered with the backend will return a valid device address. This is
144 * used by processors that need to bind buffers via device address (e.g.,
145 * for ray tracing or bindless access).
146 */
147 [[nodiscard]] uint64_t get_device_address() const;
148
149 /**
150 * @brief Clear buffer contents
151 *
152 * If the buffer is host-visible and mapped the memory is zeroed. For
153 * device-local buffers the backend must provide a ClearBufferProcessor
154 * that performs the appropriate GPU-side clear.
155 */
156 void clear() override;
157
158 /**
159 * @brief Read buffer contents as Kakshya DataVariant
160 *
161 * For host-visible buffers this returns a single DataVariant containing the
162 * raw bytes. For device-local buffers this warns and returns empty — a
163 * BufferDownloadProcessor should be used to read GPU-only memory.
164 *
165 * @return Vector of DataVariant objects representing buffer contents.
166 */
167 std::vector<Kakshya::DataVariant> get_data();
168
169 /**
170 * @brief Write data into the buffer
171 *
172 * If the buffer is host-visible and mapped the provided data is copied into
173 * the mapped memory. For device-local buffers, a BufferUploadProcessor must
174 * be present in the processing chain to perform the staging/upload.
175 *
176 * @param data Vector of Kakshya::DataVariant containing the payload to copy.
177 */
178 void set_data(const std::vector<Kakshya::DataVariant>& data);
179
180 /**
181 * @brief Resize buffer and recreate GPU resources if needed
182 * @param new_size New size in bytes
183 * @param preserve_data If true, copy existing data to new buffer
184 *
185 * If buffer is already initialized (has GPU resources), this will:
186 * 1. Create new GPU buffer with new size
187 * 2. Optionally copy old data
188 * 3. Destroy old GPU buffer
189 * 4. Update buffer resources
190 *
191 * If buffer is not initialized, just updates logical size.
192 */
193 void resize(size_t new_size, bool preserve_data = false);
194
195 /**
196 * @brief Get current logical size in bytes
197 * @return Buffer size in bytes.
198 */
199 size_t get_size() const { return m_size_bytes; }
200
201 /**
202 * @brief Run the buffer's default processor (if set and enabled)
203 *
204 * Invokes the attached default BufferProcessor. Processors should be
205 * prepared to handle mapped/unmapped memory according to buffer usage.
206 */
207 void process_default() override;
208
209 /**
210 * @brief Set the buffer's default processor
211 *
212 * Attaches a processor that will be invoked by process_default(). The
213 * previous default processor (if any) is detached first.
214 *
215 * @param processor Shared pointer to a BufferProcessor or nullptr to clear.
216 */
217 void set_default_processor(const std::shared_ptr<BufferProcessor>& processor) override;
218
219 /**
220 * @brief Get the currently attached default processor
221 * @return Shared pointer to the default BufferProcessor or nullptr.
222 */
223 std::shared_ptr<Buffers::BufferProcessor> get_default_processor() const override;
224
225 /**
226 * @brief Access the buffer's processing chain
227 * @return Shared pointer to the BufferProcessingChain used for this buffer.
228 */
229 std::shared_ptr<Buffers::BufferProcessingChain> get_processing_chain() override;
230
231 /**
232 * @brief Replace the buffer's processing chain
233 * @param chain New processing chain to assign.
234 * @param force If true, replaces existing chain even if one is set.
235 */
236 void set_processing_chain(const std::shared_ptr<BufferProcessingChain>& chain, bool force = false) override;
237
238 bool has_data_for_cycle() const override { return m_has_data; }
239 bool needs_removal() const override { return m_needs_removal; }
240 void mark_for_processing(bool has_data) override { m_has_data = has_data; }
241 void mark_for_removal() override { m_needs_removal = true; }
242 void enforce_default_processing(bool should_process) override { m_process_default = should_process; }
243 bool needs_default_processing() override { return m_process_default; }
244
245 /**
246 * @brief Try to acquire processing lock for this buffer
247 * @return True if lock acquired, false if already processing.
248 *
249 * Uses an atomic flag to guard concurrent processing attempts.
250 */
251 inline bool try_acquire_processing() override
252 {
253 bool expected = false;
254 return m_is_processing.compare_exchange_strong(expected, true,
255 std::memory_order_acquire, std::memory_order_relaxed);
256 }
257
258 /**
259 * @brief Release previously acquired processing lock
260 */
261 inline void release_processing() override
262 {
263 m_is_processing.store(false, std::memory_order_release);
264 }
265
266 /**
267 * @brief Query whether the buffer is currently being processed
268 * @return True if a processing operation holds the lock.
269 */
270 inline bool is_processing() const override
271 {
272 return m_is_processing.load(std::memory_order_acquire);
273 }
274
275 /** Get VkBuffer handle (VK_NULL_HANDLE if not registered) */
276 vk::Buffer& get_buffer() { return m_resources.buffer; }
277
278 /* Get logical buffer size as VkDeviceSize */
279 vk::DeviceSize get_size_bytes() const { return m_size_bytes; }
280
281 /** Check whether Vulkan handles are present (buffer registered) */
282 bool is_initialized() const { return m_resources.buffer != VK_NULL_HANDLE; }
283
284 /**
285 * @brief Setup processors with a processing token
286 * @param token ProcessingToken to assign.
287 *
288 * For VKBuffer this is a no-op as processors get the token.
289 * This is meant for derived classes that need to setup default processors
290 */
291 virtual void setup_processors(ProcessingToken token) { }
292
293 /** Get the buffer's semantic modality */
294 Kakshya::DataModality get_modality() const { return m_modality; }
295
296 /** Get the inferred data dimensions for the buffer contents */
297 const std::vector<Kakshya::DataDimension>& get_dimensions() const { return m_dimensions; }
298
299 /**
300 * @brief Update the semantic modality and re-infer dimensions
301 * @param modality New Kakshya::DataModality to apply.
302 */
303 void set_modality(Kakshya::DataModality modality);
304
305 /** Retrieve the declared usage intent */
306 Usage get_usage() const { return m_usage; }
307
308 /** Set VkBuffer handle after backend allocation */
309 void set_buffer(vk::Buffer buffer) { m_resources.buffer = buffer; }
310
311 /** Set device memory handle after backend allocation */
312 void set_memory(vk::DeviceMemory memory) { m_resources.memory = memory; }
313
314 /** Set mapped host pointer (for host-visible allocations) */
315 void set_mapped_ptr(void* ptr) { m_resources.mapped_ptr = ptr; }
316
317 /** Set all buffer resources at once */
318 inline void set_buffer_resources(const VKBufferResources& resources)
319 {
320 m_resources = resources;
321 }
322
323 /**
324 * @brief Store raw index buffer handles produced by the geometry upload path.
325 *
326 * Called by GeometryBindingsProcessor after allocating and uploading index
327 * data. Overwrites any previously stored handles. Pass null handles and
328 * zero size to clear (non-indexed geometry).
329 *
330 * @param buf Allocated vk::Buffer with INDEX usage flags.
331 * @param mem Backing vk::DeviceMemory.
332 * @param size Byte size of the index buffer.
333 */
334 void set_index_resources(vk::Buffer buf, vk::DeviceMemory mem, size_t size)
335 {
336 m_resources.index_buffer = buf;
337 m_resources.index_memory = mem;
338 m_resources.index_size_bytes = size;
339 }
340
341 /** Get all buffer resources at once */
342 inline const VKBufferResources& get_buffer_resources() { return m_resources; }
343
344 /**
345 * @brief Return the raw index buffer handle.
346 * @return vk::Buffer; operator bool() returns false when non-indexed.
347 */
348 [[nodiscard]] vk::Buffer get_index_buffer() const { return m_resources.index_buffer; }
349
350 /**
351 * @brief Number of bytes in the index buffer.
352 * @return Byte count; divide by sizeof(uint32_t) for index count.
353 * Zero when non-indexed.
354 */
355 [[nodiscard]] size_t get_index_buffer_size() const { return m_resources.index_size_bytes; }
356
357 /**
358 * @brief True when an index buffer has been associated with this buffer.
359 */
360 [[nodiscard]] bool has_index_buffer() const
361 {
362 return static_cast<bool>(m_resources.index_buffer);
363 }
364
365 /**
366 * @brief Whether this VKBuffer should be host-visible
367 * @return True for staging or uniform buffers, false for device-local types.
368 */
369 bool is_host_visible() const
370 {
371 return m_usage == Usage::STAGING
372 || m_usage == Usage::UNIFORM
373 || m_usage == Usage::UNIFORM_BDA
374 || m_usage == Usage::STORAGE_BDA
375 || m_usage == Usage::HOST_STORAGE;
376 }
377
378 /**
379 * @brief Get appropriate VkBufferUsageFlags for creation based on Usage
380 * @return VkBufferUsageFlags to be used when creating VkBuffer.
381 */
382 vk::BufferUsageFlags get_usage_flags() const;
383
384 /**
385 * @brief Get appropriate VkMemoryPropertyFlags for allocation based on Usage
386 * @return VkMemoryPropertyFlags to request during memory allocation.
387 */
388 vk::MemoryPropertyFlags get_memory_properties() const;
389
390 /** Get mapped host pointer (nullptr if not host-visible or unmapped) */
391 void* get_mapped_ptr() const { return m_resources.mapped_ptr; }
392
393 /** Get device memory handle */
394 void mark_dirty_range(size_t offset, size_t size);
395
396 /** Mark a range as invalid (needs download) */
397 void mark_invalid_range(size_t offset, size_t size);
398
399 /** Retrieve and clear all dirty ranges */
400 std::vector<std::pair<size_t, size_t>> get_and_clear_dirty_ranges();
401
402 /** Retrieve and clear all invalid ranges */
403 std::vector<std::pair<size_t, size_t>> get_and_clear_invalid_ranges();
404
405 /**
406 * @brief Associate this buffer with a window for rendering
407 * @param window Target window for rendering this buffer's content
408 *
409 * When this buffer is processed, its content will be rendered to the associated window.
410 * Currently supports one window per buffer (will be extended to multiple windows).
411 */
412 void set_pipeline_window(RenderPipelineID id, const std::shared_ptr<Core::Window>& window)
413 {
414 m_window_pipelines[id] = window;
415 }
416
417 /**
418 * @brief Get the window associated with this buffer
419 * @return Target window, or nullptr if not set
420 */
421 std::shared_ptr<Core::Window> get_pipeline_window(RenderPipelineID id) const
422 {
423 auto it = m_window_pipelines.find(id);
424 if (it != m_window_pipelines.end()) {
425 return it->second;
426 }
427 return nullptr;
428 }
429
430 /**
431 * @brief Check if this buffer has a rendering pipeline configured
432 */
434 {
435 return !m_window_pipelines.empty();
436 }
437
438 /**
439 * @brief Get all render pipelines associated with this buffer
440 * @return Map of RenderPipelineID to associated windows
441 */
442 std::unordered_map<RenderPipelineID, std::shared_ptr<Core::Window>> get_render_pipelines() const
443 {
444 return m_window_pipelines;
445 }
446
447 /**
448 * @brief Store recorded command buffer for a pipeline
449 */
451 CommandBufferID cmd_id)
452 {
453 m_pipeline_commands[pipeline_id] = cmd_id;
454 }
455
456 /**
457 * @brief Get recorded command buffer for a pipeline
458 */
460 {
461 auto it = m_pipeline_commands.find(pipeline_id);
462 return it != m_pipeline_commands.end() ? it->second : 0;
463 }
464
465 /**
466 * @brief Clear all recorded commands (called after presentation)
467 */
469 {
470 m_pipeline_commands.clear();
471 }
472
473 /**
474 * @brief Set vertex layout for this buffer
475 *
476 * Required before using buffer with graphics rendering.
477 * Describes how to interpret buffer data as vertices.
478 *
479 * @param layout VertexLayout describing vertex structure
480 */
481 void set_vertex_layout(const Kakshya::VertexLayout& layout);
482
483 /**
484 * @brief Get vertex layout if set
485 * @return Optional containing layout, or empty if not set
486 */
487 std::optional<Kakshya::VertexLayout> get_vertex_layout() const { return m_vertex_layout; }
488
489 /**
490 * @brief Check if this buffer has vertex layout configured
491 */
492 bool has_vertex_layout() const { return m_vertex_layout.has_value(); }
493
494 /**
495 * @brief Clear vertex layout
496 */
498 {
499 m_vertex_layout.reset();
500 }
501
502 std::shared_ptr<Buffer> clone_to(uint8_t dest_desc) override;
503
504 /**
505 * @brief Create a clone of this buffer with the same data and properties
506 * @param usage Usage enum for the cloned buffer
507 * @return Shared pointer to the cloned VKBuffer
508 *
509 * The cloned buffer will have the same size, modality, dimensions,
510 * processing chain and default processor as the original. Changes to
511 * one buffer after cloning do not affect the other.
512 */
513 std::shared_ptr<VKBuffer> clone_to(Usage usage);
514
515 /** Set whether this buffer is for internal engine usage */
516 void force_internal_usage(bool internal) override { m_internal_usage = internal; }
517
518 /** Check whether this buffer is for internal engine usage */
519 bool is_internal_only() const override { return m_internal_usage; }
520
521 /** Access the pipeline context for custom metadata (non-const) */
522 PipelineContext& get_pipeline_context() { return m_pipeline_context; }
523
524 /** Access the pipeline context for custom metadata (const) */
525 const PipelineContext& get_pipeline_context() const { return m_pipeline_context; }
526
527 [[nodiscard]] EngineContext& get_engine_context() { return m_engine_context; }
528 [[nodiscard]] const EngineContext& get_engine_context() const { return m_engine_context; }
529
530 /**
531 * @brief Mark config as changed (processors will detect and react)
532 * @param is_dirty Whether the config is now dirty (default: true)
533 * NOTE: Child classes override this to call their internal setup_rendering() with the new config, which may have additional side effects.
534 */
535 virtual void mark_render_config_dirty(bool is_dirty = true) { m_render_config_dirty = is_dirty; }
536
537 /**
538 * @brief Check if config has changed since last frame
539 */
540 [[nodiscard]] bool is_render_config_dirty() const { return m_render_config_dirty; }
541
542 /**
543 * @brief Get the current render configuration
544 * @return RenderConfig struct with current settings
545 */
546 RenderConfig get_render_config() const { return m_render_config; }
547
548 /**
549 * @brief Update the render configuration and mark as dirty
550 * @param config New RenderConfig to apply
551 *
552 * This will update the buffer's render configuration and set the dirty flag,
553 * signaling to any RenderProcessor that it needs to reconfigure rendering for this buffer.
554 * NOTE: Child classes override this to call their internal setup_rendering() with the new config, which may have additional side effects.
555 */
556 virtual void set_render_config(const RenderConfig& config)
557 {
558 m_render_config = config;
559 m_render_config_dirty = true;
560 }
561
562 /**
563 * @brief Mark this buffer as requiring depth testing when rendered
564 */
565 void set_needs_depth_attachment(bool needs) { m_needs_depth = needs; }
566
567 /**
568 * @brief Check if this buffer requires depth attachment for rendering
569 */
570 [[nodiscard]] bool needs_depth_attachment() const { return m_needs_depth; }
571
572 /**
573 * @brief Get a RenderProcessor suitable for rendering this buffer
574 * @return Shared pointer to a RenderProcessor, or nullptr if not renderable
575 *
576 * By default returns nullptr. Derived classes that support rendering should
577 * override this to return an appropriate RenderProcessor instance.
578 */
579 virtual std::shared_ptr<RenderProcessor> get_render_processor() const { return m_render_processor; }
580
581 inline void set_render_processor(std::shared_ptr<RenderProcessor> rp) { m_render_processor = std::move(rp); }
582
583protected:
584 /**
585 * @brief Called by derived classes to set their context-specific defaults
586 * @param config RenderConfig with default values for this buffer type
587 *
588 * Example (GeometryBuffer calls this in constructor):
589 * RenderConfig defaults;
590 * defaults.vertex_shader = "point.vert.spv";
591 * defaults.fragment_shader = "point.frag.spv";
592 * defaults.topology = PrimitiveTopology::POINT_LIST;
593 * set_default_render_config(defaults);
594 */
596 {
597 m_render_config = config;
598 m_render_config_dirty = false;
599 }
600
601 /**
602 * @brief Configure the internal m_render_processor from a RenderConfig.
603 */
604 void apply_render_config(const RenderConfig& config, const ShaderConfig& shader_config);
605
606 /**
607 * @brief Configure a RenderProcessor, creating one if null.
608 * @param render_processor Existing processor to configure, or nullptr to create one.
609 * @param config RenderConfig with settings to apply
610 */
611 void apply_render_config(
612 std::shared_ptr<RenderProcessor>& render_processor,
613 const RenderConfig& config,
614 const ShaderConfig& shader_config);
615
616 bool m_render_config_dirty {};
618 std::shared_ptr<RenderProcessor> m_render_processor;
619
620private:
622
623 // Buffer parameters
624 size_t m_size_bytes {};
625 Usage m_usage {};
626 bool m_needs_depth {};
627
628 // Semantic metadata
630 std::vector<Kakshya::DataDimension> m_dimensions;
631
632 std::optional<Kakshya::VertexLayout> m_vertex_layout;
633
634 // Buffer interface state
635 bool m_has_data { true };
636 bool m_needs_removal {};
637 bool m_process_default { true };
638 bool m_internal_usage {};
639 std::atomic<bool> m_is_processing;
640 std::shared_ptr<Buffers::BufferProcessor> m_default_processor;
641 std::shared_ptr<Buffers::BufferProcessingChain> m_processing_chain;
645
646 std::unordered_map<RenderPipelineID, std::shared_ptr<Core::Window>> m_window_pipelines;
647 std::unordered_map<RenderPipelineID, CommandBufferID> m_pipeline_commands;
648
649 std::vector<std::pair<size_t, size_t>> m_dirty_ranges;
650 std::vector<std::pair<size_t, size_t>> m_invalid_ranges;
651
652 /**
653 * @brief Infer Kakshya::DataDimension entries from a given byte count
654 *
655 * Uses the current modality and provided byte count to populate
656 * m_dimensions so processors and UI code can reason about the buffer's layout.
657 *
658 * @param byte_count Number of bytes of data to infer dimensions from.
659 */
660 void infer_dimensions_from_data(size_t byte_count);
661};
662
664protected:
667
670 void ensure_initialized(const std::shared_ptr<VKBuffer>& buffer);
671};
672
673} // namespace MayaFlux::Buffers
const uint8_t * ptr
Central computational transformation interface for continuous buffer processing.
Backend-agnostic interface for sequential data storage and transformation.
Definition Buffer.hpp:37
Registry::Service::ComputeService * m_compute_service
Definition VKBuffer.hpp:666
Registry::Service::BufferService * m_buffer_service
Definition VKBuffer.hpp:665
void ensure_initialized(const std::shared_ptr< VKBuffer > &buffer)
Definition VKBuffer.cpp:471
std::vector< std::pair< size_t, size_t > > m_dirty_ranges
Definition VKBuffer.hpp:649
bool is_render_config_dirty() const
Check if config has changed since last frame.
Definition VKBuffer.hpp:540
std::unordered_map< RenderPipelineID, std::shared_ptr< Core::Window > > get_render_pipelines() const
Get all render pipelines associated with this buffer.
Definition VKBuffer.hpp:442
size_t get_index_buffer_size() const
Number of bytes in the index buffer.
Definition VKBuffer.hpp:355
void * get_mapped_ptr() const
Get mapped host pointer (nullptr if not host-visible or unmapped)
Definition VKBuffer.hpp:391
CommandBufferID get_pipeline_command(RenderPipelineID pipeline_id) const
Get recorded command buffer for a pipeline.
Definition VKBuffer.hpp:459
ProcessingToken m_processing_token
Definition VKBuffer.hpp:642
void set_pipeline_command(RenderPipelineID pipeline_id, CommandBufferID cmd_id)
Store recorded command buffer for a pipeline.
Definition VKBuffer.hpp:450
PipelineContext m_pipeline_context
Definition VKBuffer.hpp:643
void set_render_processor(std::shared_ptr< RenderProcessor > rp)
Definition VKBuffer.hpp:581
std::unordered_map< RenderPipelineID, std::shared_ptr< Core::Window > > m_window_pipelines
Definition VKBuffer.hpp:646
std::optional< Kakshya::VertexLayout > m_vertex_layout
Definition VKBuffer.hpp:632
std::vector< Kakshya::DataDimension > m_dimensions
Definition VKBuffer.hpp:630
std::shared_ptr< Buffers::BufferProcessingChain > m_processing_chain
Definition VKBuffer.hpp:641
bool is_processing() const override
Query whether the buffer is currently being processed.
Definition VKBuffer.hpp:270
RenderConfig get_render_config() const
Get the current render configuration.
Definition VKBuffer.hpp:546
EngineContext m_engine_context
Definition VKBuffer.hpp:644
bool has_render_pipeline() const
Check if this buffer has a rendering pipeline configured.
Definition VKBuffer.hpp:433
bool needs_depth_attachment() const
Check if this buffer requires depth attachment for rendering.
Definition VKBuffer.hpp:570
bool needs_removal() const override
Checks if the buffer should be removed from processing chains.
Definition VKBuffer.hpp:239
bool has_data_for_cycle() const override
Checks if the buffer has data for the current processing cycle.
Definition VKBuffer.hpp:238
virtual std::shared_ptr< RenderProcessor > get_render_processor() const
Get a RenderProcessor suitable for rendering this buffer.
Definition VKBuffer.hpp:579
void clear_pipeline_commands()
Clear all recorded commands (called after presentation)
Definition VKBuffer.hpp:468
vk::Buffer get_index_buffer() const
Return the raw index buffer handle.
Definition VKBuffer.hpp:348
Usage get_usage() const
Retrieve the declared usage intent.
Definition VKBuffer.hpp:306
const EngineContext & get_engine_context() const
Definition VKBuffer.hpp:528
Kakshya::DataModality get_modality() const
Get the buffer's semantic modality.
Definition VKBuffer.hpp:294
const PipelineContext & get_pipeline_context() const
Access the pipeline context for custom metadata (const)
Definition VKBuffer.hpp:525
EngineContext & get_engine_context()
Definition VKBuffer.hpp:527
std::vector< std::pair< size_t, size_t > > m_invalid_ranges
Definition VKBuffer.hpp:650
void set_mapped_ptr(void *ptr)
Set mapped host pointer (for host-visible allocations)
Definition VKBuffer.hpp:315
vk::DeviceSize get_size_bytes() const
Definition VKBuffer.hpp:279
bool has_index_buffer() const
True when an index buffer has been associated with this buffer.
Definition VKBuffer.hpp:360
std::optional< Kakshya::VertexLayout > get_vertex_layout() const
Get vertex layout if set.
Definition VKBuffer.hpp:487
VKBufferResources m_resources
Definition VKBuffer.hpp:621
PipelineContext & get_pipeline_context()
Access the pipeline context for custom metadata (non-const)
Definition VKBuffer.hpp:522
void clear_vertex_layout()
Clear vertex layout.
Definition VKBuffer.hpp:497
void set_memory(vk::DeviceMemory memory)
Set device memory handle after backend allocation.
Definition VKBuffer.hpp:312
void set_needs_depth_attachment(bool needs)
Mark this buffer as requiring depth testing when rendered.
Definition VKBuffer.hpp:565
vk::Buffer & get_buffer()
Get VkBuffer handle (VK_NULL_HANDLE if not registered)
Definition VKBuffer.hpp:276
bool needs_default_processing() override
Checks if the buffer should undergo default processing.
Definition VKBuffer.hpp:243
std::shared_ptr< Buffers::BufferProcessor > m_default_processor
Definition VKBuffer.hpp:640
virtual void setup_processors(ProcessingToken token)
Setup processors with a processing token.
Definition VKBuffer.hpp:291
virtual void mark_render_config_dirty(bool is_dirty=true)
Mark config as changed (processors will detect and react)
Definition VKBuffer.hpp:535
void set_pipeline_window(RenderPipelineID id, const std::shared_ptr< Core::Window > &window)
Associate this buffer with a window for rendering.
Definition VKBuffer.hpp:412
bool is_initialized() const
Check whether Vulkan handles are present (buffer registered)
Definition VKBuffer.hpp:282
void enforce_default_processing(bool should_process) override
Controls whether the buffer should use default processing.
Definition VKBuffer.hpp:242
bool is_internal_only() const override
Check whether this buffer is for internal engine usage.
Definition VKBuffer.hpp:519
void set_buffer(vk::Buffer buffer)
Set VkBuffer handle after backend allocation.
Definition VKBuffer.hpp:309
bool has_vertex_layout() const
Check if this buffer has vertex layout configured.
Definition VKBuffer.hpp:492
const std::vector< Kakshya::DataDimension > & get_dimensions() const
Get the inferred data dimensions for the buffer contents.
Definition VKBuffer.hpp:297
std::shared_ptr< RenderProcessor > m_render_processor
Definition VKBuffer.hpp:618
virtual void set_render_config(const RenderConfig &config)
Update the render configuration and mark as dirty.
Definition VKBuffer.hpp:556
void set_index_resources(vk::Buffer buf, vk::DeviceMemory mem, size_t size)
Store raw index buffer handles produced by the geometry upload path.
Definition VKBuffer.hpp:334
std::atomic< bool > m_is_processing
Definition VKBuffer.hpp:639
const VKBufferResources & get_buffer_resources()
Get all buffer resources at once.
Definition VKBuffer.hpp:342
void set_default_render_config(const RenderConfig &config)
Called by derived classes to set their context-specific defaults.
Definition VKBuffer.hpp:595
Kakshya::DataModality m_modality
Definition VKBuffer.hpp:629
void release_processing() override
Release previously acquired processing lock.
Definition VKBuffer.hpp:261
void set_buffer_resources(const VKBufferResources &resources)
Set all buffer resources at once.
Definition VKBuffer.hpp:318
void force_internal_usage(bool internal) override
Set whether this buffer is for internal engine usage.
Definition VKBuffer.hpp:516
size_t get_size() const
Get current logical size in bytes.
Definition VKBuffer.hpp:199
void mark_for_removal() override
Marks the buffer for removal from processing chains.
Definition VKBuffer.hpp:241
std::unordered_map< RenderPipelineID, CommandBufferID > m_pipeline_commands
Definition VKBuffer.hpp:647
bool is_host_visible() const
Whether this VKBuffer should be host-visible.
Definition VKBuffer.hpp:369
void mark_for_processing(bool has_data) override
Marks the buffer's data availability for the current processing cycle.
Definition VKBuffer.hpp:240
std::shared_ptr< Core::Window > get_pipeline_window(RenderPipelineID id) const
Get the window associated with this buffer.
Definition VKBuffer.hpp:421
~VKBuffer() override
Virtual destructor.
bool try_acquire_processing() override
Try to acquire processing lock for this buffer.
Definition VKBuffer.hpp:251
Vulkan-backed buffer wrapper used in processing chains.
Definition VKBuffer.hpp:67
ProcessingToken
Bitfield enum defining processing characteristics and backend requirements for buffer operations.
uint64_t RenderPipelineID
Definition VKBuffer.hpp:42
uint64_t CommandBufferID
Definition VKBuffer.hpp:43
DataModality
Data modality types for cross-modal analysis.
Definition NDData.hpp:81
Raw Vulkan handles owned by a VKBuffer instance.
Definition VKBuffer.hpp:32
std::vector< Portal::Graphics::DescriptorBindingInfo > ssbo_bindings
Definition VKBuffer.hpp:107
Engine-internal per-frame binding state.
Definition VKBuffer.hpp:106
std::vector< Portal::Graphics::DescriptorBindingInfo > descriptor_buffer_bindings
Definition VKBuffer.hpp:92
std::vector< uint8_t > push_constant_staging
Definition VKBuffer.hpp:90
std::unordered_map< std::string, std::any > metadata
Definition VKBuffer.hpp:94
Context shared with BufferProcessors during pipeline execution.
Definition VKBuffer.hpp:89
Complete description of vertex data layout in a buffer.
Unified rendering configuration for graphics buffers.
Backend buffer management service interface.
Backend compute shader and pipeline service interface.