MayaFlux 0.5.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
BackendResoureManager.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "vulkan/vulkan.hpp"
4
6struct BufferService;
7}
8
9namespace MayaFlux::Buffers {
10class VKBuffer;
11}
12
13namespace MayaFlux::Core {
14
15class VKContext;
16class VKImage;
17class VKCommandManager;
18
19/**
20 * @class BackendResourceManager
21 * @brief Manages Vulkan resources (buffers, images, samplers) for the graphics backend
22 */
23class MAYAFLUX_API BackendResourceManager {
24public:
25 BackendResourceManager(VKContext& context, VKCommandManager& command_manager);
27
28 void setup_backend_service(const std::shared_ptr<Registry::Service::BufferService>& buffer_service);
29
30 // ========================================================================
31 // Buffer management
32 // ========================================================================
33
34 /**
35 * @brief Initialize a buffer for use with the graphics backend
36 * @param buffer Shared pointer to the buffer to initialize
37 */
38 void initialize_buffer(const std::shared_ptr<Buffers::VKBuffer>& buffer);
39
40 /**
41 * @brief Allocate a raw VkBuffer/VkDeviceMemory pair without an owning
42 * VKBuffer object.
43 * @param size_bytes Buffer capacity in bytes.
44 * @param usage Vulkan buffer usage flags.
45 * @param memory_properties Vulkan memory property flags.
46 * @param host_visible When true, the allocation is mapped and out_mapped_ptr
47 * is populated; when false, out_mapped_ptr is left null.
48 * @param out_buffer Receives the created vk::Buffer.
49 * @param out_memory Receives the bound vk::DeviceMemory.
50 * @param out_mapped_ptr Receives the mapped host pointer, or nullptr if
51 * @p host_visible is false.
52 *
53 * Same allocation sequence as initialize_buffer() (createBuffer,
54 * getBufferMemoryRequirements, allocateMemory, bindBufferMemory, optional
55 * mapMemory), without requiring or populating a VKBuffer. Intended for
56 * VKBuffer subclasses that own secondary raw handle pairs directly in
57 * VKBufferResources::back_buffers rather than as separate VKBuffer objects.
58 */
59 void allocate_raw_buffer(
60 size_t size_bytes,
61 vk::BufferUsageFlags usage,
62 vk::MemoryPropertyFlags memory_properties,
63 bool host_visible,
64 vk::Buffer& out_buffer,
65 vk::DeviceMemory& out_memory,
66 void*& out_mapped_ptr);
67
68 /**
69 * @brief Cleanup a buffer and release associated resources
70 * @param buffer Shared pointer to the buffer to cleanup
71 */
72 void cleanup_buffer(const std::shared_ptr<Buffers::VKBuffer>& buffer);
73
74 /**
75 * @brief Query the Vulkan device address of an initialized BDA-capable buffer
76 * @param buffer Buffer with Usage::UNIFORM_BDA or Usage::STORAGE_BDA
77 * @return vk::DeviceAddress, or 0 if the buffer was not created with eShaderDeviceAddress
78 */
79 [[nodiscard]] vk::DeviceAddress get_buffer_device_address(
80 const std::shared_ptr<Buffers::VKBuffer>& buffer) const;
81
82 /**
83 * @brief Flush any pending buffer operations (e.g., uploads/downloads)
84 */
85 void flush_pending_buffer_operations();
86
87 // ========================================================================
88 // Buffer management
89 // ========================================================================
90
91 /**
92 * @brief Initialize a VKImage (allocate VkImage, memory, and create image view)
93 * @param image VKImage to initialize
94 *
95 * Follows the same pattern as initialize_buffer:
96 * 1. Create VkImage
97 * 2. Allocate VkDeviceMemory
98 * 3. Bind memory to image
99 * 4. Create VkImageView
100 * 5. Store handles in VKImage
101 */
102 void initialize_image(const std::shared_ptr<VKImage>& image);
103
104 /**
105 * @brief Cleanup a VKImage (destroy view, image, and free memory)
106 * @param image VKImage to cleanup
107 */
108 void cleanup_image(const std::shared_ptr<VKImage>& image);
109
110 /**
111 * @brief Transition image layout using a pipeline barrier
112 * @param image VkImage handle
113 * @param old_layout Current layout
114 * @param new_layout Target layout
115 * @param mip_levels Number of mip levels to transition
116 * @param array_layers Number of array layers to transition
117 *
118 * Executes immediately on graphics queue. Use for initial setup and
119 * one-off transitions. For rendering, prefer manual barriers.
120 */
121 void transition_image_layout(
122 vk::Image image,
123 vk::ImageLayout old_layout,
124 vk::ImageLayout new_layout,
125 uint32_t mip_levels = 1,
126 uint32_t array_layers = 1,
127 vk::ImageAspectFlags aspect_flags = vk::ImageAspectFlagBits::eColor);
128
129 /**
130 * @brief Upload data to an image (creates staging buffer internally)
131 * @param image Target VKImage
132 * @param data Pixel data pointer
133 * @param size Data size in bytes
134 */
135 void upload_image_data(
136 std::shared_ptr<VKImage> image,
137 const void* data,
138 size_t size);
139
140 /**
141 * @brief Upload image data using a caller-supplied persistent staging buffer.
142 * Identical to upload_image_data() but skips the per-call VkBuffer
143 * allocation. The staging buffer must be host-visible and at least
144 * @p size bytes. Intended for high-frequency streaming uploads.
145 * @param image Target VKImage.
146 * @param data Source pixel data pointer.
147 * @param size Byte count.
148 * @param staging Pre-allocated host-visible staging buffer.
149 * @param deferred If true, command recording will be deferred and must be flushed
150 */
151 void upload_image_data(
152 std::shared_ptr<VKImage> image,
153 const void* data,
154 size_t size,
155 const std::shared_ptr<Buffers::VKBuffer>& staging, bool deferred = false);
156
157 /**
158 * @brief Download image data to a host pointer.
159 *
160 * When @p staging is null, allocates and destroys a per-call staging
161 * buffer internally. When @p staging is supplied, it is used as-is and
162 * not destroyed after — the caller owns its lifetime.
163 *
164 * When @p deferred is false (default), submits under a fence and blocks
165 * the calling thread on vkWaitForFences. This is non-blocking relative
166 * to the graphics queue (waitIdle is never called).
167 * When @p deferred is true and staging is supplied, records commands for
168 * deferred submission; the caller is responsible for flushing.
169 *
170 * @param image Source image.
171 * @param data Destination host pointer, at least @p size bytes.
172 * @param size Byte count to read.
173 * @param staging Persistent host-visible buffer, or nullptr for
174 * per-call allocation.
175 * @param deferred Record for deferred submission (requires staging).
176 * @param restore_layout Layout to restore after the copy.
177 * @param restore_stage Pipeline stage that consumes the image after restore.
178 */
179 void download_image_data(
180 std::shared_ptr<VKImage> image,
181 void* data,
182 size_t size,
183 const std::shared_ptr<Buffers::VKBuffer>& staging = nullptr,
184 bool deferred = false,
185 vk::ImageLayout restore_layout = vk::ImageLayout::eShaderReadOnlyOptimal,
186 vk::PipelineStageFlags restore_stage = vk::PipelineStageFlagBits::eFragmentShader);
187
188 // ========================================================================
189 // Sampler management
190 // ========================================================================
191
192 /**
193 * @brief Create sampler
194 * @param filter Mag/min filter
195 * @param address_mode Texture address mode (wrap, clamp, etc.)
196 * @param anisotropy Max anisotropy (0 = disabled)
197 * @return Sampler handle
198 */
199 vk::Sampler create_sampler(
200 vk::Filter filter = vk::Filter::eLinear,
201 vk::SamplerAddressMode address_mode = vk::SamplerAddressMode::eRepeat,
202 float max_anisotropy = 0.0F);
203
204 /**
205 * @brief Destroy sampler
206 */
207 void destroy_sampler(vk::Sampler sampler);
208
209 // ========================================================================
210 // Memory management
211 // ========================================================================
212
213 /**
214 * @brief Find a suitable memory type for Vulkan buffer allocation
215 * @param type_filter Memory type bits filter
216 * @param properties Desired memory property flags
217 * @return Index of the suitable memory type
218 */
219 uint32_t find_memory_type(uint32_t type_filter, vk::MemoryPropertyFlags properties) const;
220
221 // ========================================================================
222 // Command management
223 // ========================================================================
224
225 /**
226 * @brief Execute immediate command recording for buffer operations
227 * @param recorder Command recording function
228 */
229 void execute_immediate_commands(const std::function<void(vk::CommandBuffer)>& recorder);
230
231 /**
232 * @brief Record deferred command recording for buffer operations
233 * @param recorder Command recording function
234 */
235 void record_deferred_commands(const std::function<void(vk::CommandBuffer)>& recorder);
236
237 /**
238 * @brief Flush deferred commands and return a semaphore that signals when they are complete
239 * @return Semaphore that will be signaled when deferred commands are finished
240 */
241 vk::Semaphore flush_deferred_commands();
242
243 // ========================================================================
244 // Cleanup
245 // ========================================================================
246
247 void cleanup();
248
249private:
252
253 std::vector<std::shared_ptr<Buffers::VKBuffer>> m_managed_buffers;
254 std::unordered_map<size_t, vk::Sampler> m_sampler_cache;
255
256 vk::Semaphore m_deferred_semaphore {};
257
258 size_t compute_sampler_hash(vk::Filter filter, vk::SamplerAddressMode address_mode, float max_anisotropy) const;
259};
260
261} // namespace MayaFlux::Core
IO::ImageData image
Definition Decoder.cpp:64
std::unordered_map< size_t, vk::Sampler > m_sampler_cache
std::vector< std::shared_ptr< Buffers::VKBuffer > > m_managed_buffers
Manages Vulkan resources (buffers, images, samplers) for the graphics backend.
Manages Vulkan command pools and command buffers.
High-level wrapper for Vulkan instance and device.
Definition VKContext.hpp:16
std::shared_ptr< Kriya::SamplingPipeline > create_sampler(const std::string &filepath, uint32_t num_samples, bool truncate, uint32_t channel, uint64_t max_dur_ms)
Construct a built SamplingPipeline from an audio file.
Definition Rigs.cpp:15