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