Shared validation for the three bind overloads.
217{
220 "GpuFieldOperator::bind: operator is inert, its layout stride was "
221 "rejected at construction");
222 return false;
223 }
224
225 if (!any_flag(target)) {
227 "GpuFieldOperator::bind: empty target mask");
228 return false;
229 }
230
233 "GpuFieldOperator::bind: field '{}' has no usable shader half. A "
234 "DualField lambda must carry a trailing return type.",
236 return false;
237 }
238
240 if (!has_flag(target, bit))
241 continue;
242
244 if (!slot.has_value()) {
246 "GpuFieldOperator::bind: target bit {:#x} is not present in the "
247 "supplied vertex layout. Nothing was bound.",
248 static_cast<uint16_t>(bit));
249 return false;
250 }
251
252 if (slot->second != components) {
254 "GpuFieldOperator::bind: target bit {:#x} takes {} components, "
255 "field '{}' produces {}. Nothing was bound.",
256 static_cast<uint16_t
>(bit), slot->second,
source.name, components);
257 return false;
258 }
259 }
260
261 const auto clash = std::ranges::find_if(
m_bindings,
262 [&source](
const Binding&
b) {
263 return b.source.name ==
source.name &&
b.source.body !=
source.body;
264 });
265
268 "GpuFieldOperator::bind: a different field named '{}' is already "
269 "bound. Emitted function names must be unique; rename one field.",
271 return false;
272 }
273
274 return true;
275}
#define MF_ERROR(comp, ctx,...)
std::vector< Binding > m_bindings
std::optional< std::pair< uint32_t, uint32_t > > resolve_target(FieldTarget target) const
Locate a target's word offset and component count in the layout.
@ NodeProcessing
Node graph processing (Nodes::NodeGraphManager)
@ Nodes
DSP Generator and Filter Nodes, graph pipeline, node management.
@ Kinesis
General mathematical and physics algorithns.
constexpr std::array< FieldTarget, 6 > k_field_targets
Single-bit targets known to this version, in vertex layout order.
Kinesis::FieldTarget FieldTarget