MayaFlux 0.4.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches

◆ as_texture_access()

MAYAFLUX_API std::optional< TextureAccess > MayaFlux::Kakshya::as_texture_access ( const DataVariant variant)

Extract a TextureAccess from a DataVariant.

Parameters
variantSource data.
Returns
Populated TextureAccess, or std::nullopt on incompatible type.

DataVariant active type → GpuDataFormat mapping: vector<uint8_t> → UINT8 vector<uint16_t> → UINT16 vector<uint32_t> → UINT32 vector<float> → FLOAT32 vector<double> → FLOAT32 (narrowed, warned) vector<complex<float>> → VEC2_F32 (identical layout to glm::vec2) vector<glm::vec2> → VEC2_F32 vector<glm::vec3> → VEC4_F32 (W=0 promotion, warned) vector<glm::vec4> → VEC4_F32 vector<complex<double>> → std::nullopt (logged error) vector<glm::mat4> → std::nullopt (logged error)

Definition at line 69 of file TextureAccess.cpp.

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()) {
75 MF_WARN(Journal::Component::Kakshya, Journal::Context::Runtime,
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>>) {
83 MF_ERROR(Journal::Component::Kakshya, Journal::Context::Runtime,
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>) {
90 MF_ERROR(Journal::Component::Kakshya, Journal::Context::Runtime,
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),
135 .format = GpuDataFormat::VEC2_F32
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),
143 .format = GpuDataFormat::VEC4_F32
144 };
145 }
146
147 // ---- narrowing: double → float -------------------------------------
148
149 if constexpr (std::is_same_v<T, double>) {
150 MF_WARN(Journal::Component::Kakshya, Journal::Context::Runtime,
151 "as_texture_access: double narrowed to float for texel upload. "
152 "Precision beyond float range is lost.");
153 TextureAccess acc;
154 acc.format = GpuDataFormat::FLOAT32;
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>) {
168 MF_WARN(Journal::Component::Kakshya, Journal::Context::Runtime,
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;
172 acc.format = GpuDataFormat::VEC4_F32;
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 ----------------
184 MF_ERROR(Journal::Component::Kakshya, Journal::Context::Runtime,
185 "as_texture_access: unhandled variant type {}",
186 typeid(T).name());
187 return std::nullopt;
188 },
189 variant);
190}
#define MF_ERROR(comp, ctx,...)
#define MF_WARN(comp, ctx,...)

References MayaFlux::Kakshya::TextureAccess::byte_count, MayaFlux::Kakshya::TextureAccess::conversion_buffer, MayaFlux::Kakshya::TextureAccess::data_ptr, FLOAT32, MayaFlux::Kakshya::TextureAccess::format, MayaFlux::Journal::Kakshya, MF_ERROR, MF_WARN, MayaFlux::Journal::Runtime, UINT16, UINT32, UINT8, VEC2_F32, and VEC4_F32.

Referenced by MayaFlux::Portal::Graphics::TextureLoom::create_2d(), and MayaFlux::Buffers::TextureProcessor::update_pixels_if_dirty().

+ Here is the caller graph for this function: