MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
TextureAccess.cpp
Go to the documentation of this file.
1#include "TextureAccess.hpp"
2
4
5namespace MayaFlux::Kakshya {
6
7//==============================================================================
8// TextureAccess helpers
9//==============================================================================
10
11size_t TextureAccess::bytes_per_texel() const noexcept
12{
13 switch (format) {
15 return 1;
17 return 2;
21 return 4;
23 return 8;
25 return 12;
27 return 16;
29 return 8;
31 return 16;
33 return 24;
35 return 32;
36 default:
37 return 0;
38 }
39}
40
41uint32_t TextureAccess::channel_count() const noexcept
42{
43 switch (format) {
50 return 1;
53 return 2;
56 return 3;
59 return 4;
60 default:
61 return 0;
62 }
63}
64
65//==============================================================================
66// as_texture_access
67//==============================================================================
68
69std::optional<TextureAccess> as_texture_access(const DataVariant& variant)
70{
71 return std::visit([](const auto& vec) -> std::optional<TextureAccess> {
72 using T = typename std::decay_t<decltype(vec)>::value_type;
73
74 if (vec.empty()) {
76 "as_texture_access: empty variant");
77 return std::nullopt;
78 }
79
80 // ---- rejected types ------------------------------------------------
81
82 if constexpr (std::is_same_v<T, std::complex<double>>) {
84 "as_texture_access: complex<double> (RG64F) is not a sampled "
85 "image format in Vulkan. Use complex<float> for RG32F.");
86 return std::nullopt;
87 }
88
89 if constexpr (std::is_same_v<T, glm::mat4>) {
91 "as_texture_access: mat4 layout is ambiguous for texel upload. "
92 "Unpack each column to a vec4 and use vector<glm::vec4>.");
93 return std::nullopt;
94 }
95
96 // ---- zero-copy direct mappings ------------------------------------
97
98 if constexpr (std::is_same_v<T, uint8_t>) {
99 return TextureAccess {
100 .data_ptr = vec.data(),
101 .byte_count = vec.size() * sizeof(T),
102 .format = GpuDataFormat::UINT8
103 };
104 }
105
106 if constexpr (std::is_same_v<T, uint16_t>) {
107 return TextureAccess {
108 .data_ptr = vec.data(),
109 .byte_count = vec.size() * sizeof(T),
110 .format = GpuDataFormat::UINT16
111 };
112 }
113
114 if constexpr (std::is_same_v<T, uint32_t>) {
115 return TextureAccess {
116 .data_ptr = vec.data(),
117 .byte_count = vec.size() * sizeof(T),
118 .format = GpuDataFormat::UINT32
119 };
120 }
121
122 if constexpr (std::is_same_v<T, float>) {
123 return TextureAccess {
124 .data_ptr = vec.data(),
125 .byte_count = vec.size() * sizeof(T),
126 .format = GpuDataFormat::FLOAT32
127 };
128 }
129
130 if constexpr (std::is_same_v<T, glm::vec2>
131 || std::is_same_v<T, std::complex<float>>) {
132 return TextureAccess {
133 .data_ptr = vec.data(),
134 .byte_count = vec.size() * sizeof(T),
136 };
137 }
138
139 if constexpr (std::is_same_v<T, glm::vec4>) {
140 return TextureAccess {
141 .data_ptr = vec.data(),
142 .byte_count = vec.size() * sizeof(T),
144 };
145 }
146
147 // ---- narrowing: double → float -------------------------------------
148
149 if constexpr (std::is_same_v<T, double>) {
151 "as_texture_access: double narrowed to float for texel upload. "
152 "Precision beyond float range is lost.");
153 TextureAccess acc;
155 acc.conversion_buffer.resize(vec.size() * sizeof(float));
156 auto* dst = reinterpret_cast<float*>(acc.conversion_buffer.data());
157 for (size_t i = 0; i < vec.size(); ++i) {
158 dst[i] = static_cast<float>(vec[i]);
159 }
160 acc.data_ptr = acc.conversion_buffer.data();
161 acc.byte_count = acc.conversion_buffer.size();
162 return acc;
163 }
164
165 // ---- promotion: vec3 → vec4 (W = 0) --------------------------------
166
167 if constexpr (std::is_same_v<T, glm::vec3>) {
169 "as_texture_access: vec3 promoted to vec4 (W=0). "
170 "RGB32F is not a universally-supported sampled image format in Vulkan.");
171 TextureAccess acc;
173 acc.conversion_buffer.resize(vec.size() * sizeof(glm::vec4));
174 auto* dst = reinterpret_cast<glm::vec4*>(acc.conversion_buffer.data());
175 for (size_t i = 0; i < vec.size(); ++i) {
176 dst[i] = glm::vec4(vec[i], 0.0F);
177 }
178 acc.data_ptr = acc.conversion_buffer.data();
179 acc.byte_count = acc.conversion_buffer.size();
180 return acc;
181 }
182
183 // ---- unreachable for current DataVariant definition ----------------
185 "as_texture_access: unhandled variant type {}",
186 typeid(T).name());
187 return std::nullopt;
188 },
189 variant);
190}
191
192} // namespace MayaFlux::Kakshya
#define MF_ERROR(comp, ctx,...)
#define MF_WARN(comp, ctx,...)
@ Runtime
General runtime operations (default fallback)
@ Kakshya
Containers[Signalsource, Stream, File], Regions, DataProcessors.
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:76
std::optional< TextureAccess > as_texture_access(const DataVariant &variant)
Extract a TextureAccess from a DataVariant.
std::vector< std::byte > conversion_buffer
Promotion buffer.
size_t bytes_per_texel() const noexcept
Bytes per texel for this format.
uint32_t channel_count() const noexcept
Number of channels (components per texel).
Memory-compatible view of a DataVariant for texel upload.