MayaFlux 0.1.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
StagingUtils.hpp
Go to the documentation of this file.
1#pragma once
2
5
6namespace MayaFlux::Buffers {
7
8class VKBuffer;
9class AudioBuffer;
10
11/**
12 * @brief Upload data to a host-visible buffer
13 * @param target Target VKBuffer to upload data into
14 * @param data DataVariant containing the data to upload
15 *
16 * This function handles uploading data from a Kakshya::DataVariant into a
17 * host-visible VKBuffer. It maps the buffer memory, copies the data, and
18 * marks the buffer as dirty for synchronization.
19 */
20MAYAFLUX_API void upload_host_visible(const std::shared_ptr<VKBuffer>& target, const Kakshya::DataVariant& data);
21
22/**
23 * @brief Upload data to a device-local buffer using a staging buffer
24 * @param target Target VKBuffer to upload data into
25 * @param staging_buffer Host-visible staging VKBuffer used for the upload
26 * @param data DataVariant containing the data to upload
27 *
28 * This function handles uploading data from a Kakshya::DataVariant into a
29 * device-local VKBuffer by utilizing a staging buffer. It copies the data
30 * into the staging buffer, flushes it, and then issues a command to copy
31 * from the staging buffer to the target device-local buffer.
32 */
33MAYAFLUX_API void upload_device_local(const std::shared_ptr<VKBuffer>& target, const std::shared_ptr<VKBuffer>& staging_buffer, const Kakshya::DataVariant& data);
34
35/**
36 * @brief Download data from a host-visible buffer
37 * @param source Source VKBuffer to download data from
38 * @param target Target VKBuffer to store the downloaded data
39 *
40 * This function handles downloading data from a host-visible VKBuffer.
41 * It maps the buffer memory, copies the data into a CPU-accessible format,
42 * and updates the associated target buffer.
43 */
44MAYAFLUX_API void download_host_visible(const std::shared_ptr<VKBuffer>& source, const std::shared_ptr<VKBuffer>& target);
45
46/**
47 * @brief Download data from a device-local buffer using a staging buffer
48 * @param source Source VKBuffer to download data from
49 * @param target Target VKBuffer to store the downloaded data
50 * @param staging_buffer Host-visible staging VKBuffer used for the download
51 *
52 * This function handles downloading data from a device-local VKBuffer by
53 * utilizing a staging buffer. It issues a command to copy the data from
54 * the device-local buffer to the staging buffer, invalidates the staging
55 * buffer memory, and then copies the data into a CPU-accessible format
56 * to update the target buffer.
57 */
58MAYAFLUX_API void download_device_local(const std::shared_ptr<VKBuffer>& source, const std::shared_ptr<VKBuffer>& target, const std::shared_ptr<VKBuffer>& staging_buffer);
59
60/**
61 * @brief Upload raw data to GPU buffer (auto-detects host-visible vs device-local)
62 * @param data Source data pointer
63 * @param size Size in bytes
64 * @param target Target GPU buffer
65 * @param staging Optional staging buffer (created if needed for device-local)
66 *
67 * Convenience wrapper over StagingUtils that:
68 * - Converts raw pointer → DataVariant
69 * - Auto-detects if buffer is host-visible or device-local
70 * - Handles staging buffer creation if needed
71 */
72MAYAFLUX_API void upload_to_gpu(
73 const void* data,
74 size_t size,
75 const std::shared_ptr<VKBuffer>& target,
76 const std::shared_ptr<VKBuffer>& staging = nullptr);
77
78/**
79 * @brief Upload typed data to GPU buffer
80 * @tparam T Data type (float, double, int, etc.)
81 * @param data Source data span
82 * @param target Target GPU buffer
83 * @param staging Optional staging buffer
84 */
85template <typename T>
87 std::span<const T> data,
88 const std::shared_ptr<VKBuffer>& target,
89 const std::shared_ptr<VKBuffer>& staging = nullptr)
90{
91 upload_to_gpu(data.data(), data.size_bytes(), target, staging);
92}
93
94/**
95 * @brief Upload vector to GPU buffer
96 * @tparam T Data type
97 * @param data Source data vector
98 * @param target Target GPU buffer
99 * @param staging Optional staging buffer
100 */
101template <typename T>
103 const std::vector<T>& data,
104 const std::shared_ptr<VKBuffer>& target,
105 const std::shared_ptr<VKBuffer>& staging = nullptr)
106{
107 upload_to_gpu(std::span<const T>(data), target, staging);
108}
109
110/**
111 * @brief Download from GPU buffer to raw data (auto-detects host-visible vs device-local)
112 * @param source Source GPU buffer
113 * @param data Destination data pointer
114 * @param size Size in bytes
115 * @param staging Optional staging buffer (created if needed for device-local)
116 *
117 * Convenience wrapper over StagingUtils that:
118 * - Auto-detects if buffer is host-visible or device-local
119 * - Handles staging buffer creation if needed
120 * - Copies data to destination pointer
121 */
122MAYAFLUX_API void download_from_gpu(
123 const std::shared_ptr<VKBuffer>& source,
124 void* data,
125 size_t size,
126 const std::shared_ptr<VKBuffer>& staging = nullptr);
127
128/**
129 * @brief Download from GPU buffer to typed span
130 * @tparam T Data type
131 * @param source Source GPU buffer
132 * @param data Destination data span
133 * @param staging Optional staging buffer
134 */
135template <typename T>
137 const std::shared_ptr<VKBuffer>& source,
138 std::span<T> data,
139 const std::shared_ptr<VKBuffer>& staging = nullptr)
140{
141 download_from_gpu(source, data.data(), data.size_bytes(), staging);
142}
143
144/**
145 * @brief Download from GPU buffer to vector
146 * @tparam T Data type
147 * @param source Source GPU buffer
148 * @param data Destination data vector (resized if needed)
149 * @param staging Optional staging buffer
150 */
151template <typename T>
153 const std::shared_ptr<VKBuffer>& source,
154 std::vector<T>& data,
155 const std::shared_ptr<VKBuffer>& staging = nullptr)
156{
157 size_t element_count = source->get_size_bytes() / sizeof(T);
158 data.resize(element_count);
159 download_from_gpu(source, std::span<T>(data), staging);
160}
161
162/**
163 * @brief Create staging buffer for transfers
164 * @param size Size in bytes
165 * @return Host-visible staging buffer ready for transfers
166 */
167MAYAFLUX_API std::shared_ptr<VKBuffer> create_staging_buffer(size_t size);
168
169/**
170 * @brief Check if buffer is device-local (staging needed)
171 * @param buffer Buffer to check
172 * @return True if buffer is device-local
173 */
174MAYAFLUX_API bool is_device_local(const std::shared_ptr<VKBuffer>& buffer);
175
176/**
177 * @brief Upload data from DataAccess view to GPU buffer (precision-preserving)
178 * @tparam T View type (double, glm::dvec2, glm::dvec3, glm::vec3, float, etc.)
179 * @param accessor DataAccess instance providing the view
180 * @param target Target GPU buffer
181 * @param staging Optional staging buffer (auto-created if needed)
182 *
183 * Zero-copy when types match, automatic conversion cache when they don't.
184 * For AUDIO modalities, defaults to DOUBLE precision to preserve accuracy.
185 */
186template <typename T>
188 const Kakshya::DataAccess& accessor,
189 const std::shared_ptr<VKBuffer>& target,
190 const std::shared_ptr<VKBuffer>& staging = nullptr)
191{
192 auto view = accessor.view<T>();
193
194 const void* data_ptr = view.data();
195 size_t data_bytes = view.size() * sizeof(T);
196
197 if constexpr (std::is_same_v<T, double>) {
198 if (target->get_format() != vk::Format::eR64Sfloat) {
200 "Uploading double precision to buffer with format {}. Consider using R64Sfloat for audio.",
201 vk::to_string(target->get_format()));
202 }
203 }
204
205 upload_to_gpu(data_ptr, data_bytes, target, staging);
206}
207
208/**
209 * @brief Upload structured data with GLM double-precision types
210 * @tparam T GLM type (glm::dvec2, glm::dvec3, glm::dvec4 for double precision)
211 * @param accessor DataAccess with structured dimensions
212 * @param target Target GPU buffer
213 * @param staging Optional staging buffer
214 *
215 * Use this for high-precision structured data like audio samples interpreted
216 * as multi-dimensional vectors. Supports both single and double precision GLM types.
217 */
218template <typename T>
219 requires GlmType<T>
221 const Kakshya::DataAccess& accessor,
222 const std::shared_ptr<VKBuffer>& target,
223 const std::shared_ptr<VKBuffer>& staging = nullptr)
224{
225 if (!accessor.is_structured()) {
226 error<std::invalid_argument>(
229 std::source_location::current(),
230 "Cannot upload structured view from non-structured data");
231 }
232
233 auto structured_view = accessor.view<T>();
234 upload_to_gpu(structured_view.data(), structured_view.size_bytes(), target, staging);
235}
236
237/**
238 * @brief Download GPU buffer to DataAccess-compatible format (precision-preserving)
239 */
240template <typename T>
242 const std::shared_ptr<VKBuffer>& source,
243 Kakshya::DataVariant& target_variant,
244 const std::vector<Kakshya::DataDimension>& dimensions,
245 Kakshya::DataModality modality,
246 const std::shared_ptr<VKBuffer>& staging = nullptr)
247{
248 size_t element_count = source->get_size_bytes() / sizeof(T);
249
250 std::vector<T> temp_buffer(element_count);
251 download_from_gpu(source, temp_buffer, staging);
252
253 target_variant = std::move(temp_buffer);
254
255 return Kakshya::DataAccess(target_variant, dimensions, modality);
256}
257
258/**
259 * @brief Upload AudioBuffer to GPU (always double precision)
260 * @param audio_buffer Source audio buffer (double[])
261 * @param gpu_buffer Target GPU buffer (must support R64Sfloat format)
262 * @param staging Optional staging buffer (auto-created if needed)
263 *
264 * AudioBuffer is always double precision. This function ensures the GPU buffer
265 * is configured for double precision and performs a direct upload with no conversion.
266 *
267 * @throws std::runtime_error if gpu_buffer doesn't support double precision
268 */
270 const std::shared_ptr<AudioBuffer>& audio_buffer,
271 const std::shared_ptr<VKBuffer>& gpu_buffer,
272 const std::shared_ptr<VKBuffer>& staging = nullptr);
273
274/**
275 * @brief Download GPU buffer to AudioBuffer (expects double precision)
276 * @param gpu_buffer Source GPU buffer (should contain double precision data)
277 * @param audio_buffer Target audio buffer (always double[])
278 * @param staging Optional staging buffer (auto-created if needed)
279 *
280 * Downloads GPU data and copies to AudioBuffer. If the GPU buffer contains
281 * float data instead of double, DataAccess will handle the upconversion
282 * (though this is not recommended for audio precision).
283 */
285 const std::shared_ptr<VKBuffer>& gpu_buffer,
286 const std::shared_ptr<AudioBuffer>& audio_buffer,
287 const std::shared_ptr<VKBuffer>& staging = nullptr);
288
289} // namespace MayaFlux::Buffers
#define MF_WARN(comp, ctx,...)
auto view() const
Get explicit typed view of data.
Type-erased accessor for NDData with semantic view construction.
void upload_host_visible(const std::shared_ptr< VKBuffer > &target, const Kakshya::DataVariant &data)
Upload data to a host-visible buffer.
void upload_audio_to_gpu(const std::shared_ptr< AudioBuffer > &audio_buffer, const std::shared_ptr< VKBuffer > &gpu_buffer, const std::shared_ptr< VKBuffer > &staging)
Upload AudioBuffer to GPU (always double precision)
void upload_structured_view(const Kakshya::DataAccess &accessor, const std::shared_ptr< VKBuffer > &target, const std::shared_ptr< VKBuffer > &staging=nullptr)
Upload structured data with GLM double-precision types.
void upload_device_local(const std::shared_ptr< VKBuffer > &target, const std::shared_ptr< VKBuffer > &staging_buffer, const Kakshya::DataVariant &data)
Upload data to a device-local buffer using a staging buffer.
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 download_audio_from_gpu(const std::shared_ptr< VKBuffer > &gpu_buffer, const std::shared_ptr< AudioBuffer > &audio_buffer, const std::shared_ptr< VKBuffer > &staging)
Download GPU buffer to AudioBuffer (expects double precision)
void upload_from_view(const Kakshya::DataAccess &accessor, const std::shared_ptr< VKBuffer > &target, const std::shared_ptr< VKBuffer > &staging=nullptr)
Upload data from DataAccess view to GPU buffer (precision-preserving)
void download_from_gpu(const std::shared_ptr< VKBuffer > &source, void *data, size_t size, const std::shared_ptr< VKBuffer > &staging)
Download from GPU buffer to raw data (auto-detects host-visible vs device-local)
void download_host_visible(const std::shared_ptr< VKBuffer > &source, const std::shared_ptr< VKBuffer > &target)
Download data from a host-visible buffer.
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.
Kakshya::DataAccess download_to_view(const std::shared_ptr< VKBuffer > &source, Kakshya::DataVariant &target_variant, const std::vector< Kakshya::DataDimension > &dimensions, Kakshya::DataModality modality, const std::shared_ptr< VKBuffer > &staging=nullptr)
Download GPU buffer to DataAccess-compatible format (precision-preserving)
void upload_to_gpu(const void *data, size_t size, const std::shared_ptr< VKBuffer > &target, const std::shared_ptr< VKBuffer > &staging)
Upload raw data to GPU buffer (auto-detects host-visible vs device-local)
@ 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.
Definition NDData.hpp:73
DataModality
Data modality types for cross-modal analysis.
Definition NDData.hpp:78