26 const std::string&
name,
27 std::function<
float()> reader,
33 "FormaBindingsProcessor::bind_push_constant: null reader for '{}'",
name);
40 b.reader = std::move(reader);
41 b.typed_reader =
nullptr;
47 const std::string&
name,
48 std::function<
float()> reader,
54 "FormaBindingsProcessor::bind_push_constant: null reader for '{}'",
name);
60 "FormaBindingsProcessor::bind_push_constant: '{}' needs a single component format",
68 b.reader = std::move(reader);
69 b.typed_reader =
nullptr;
75 const std::string&
name,
81 "FormaBindingsProcessor::bind_typed_push_constant: null reader for '{}'",
name);
89 b.typed_reader = std::move(reader);
95 const std::string&
name,
96 std::function<
float()> reader,
97 const std::string& descriptor_name,
98 uint32_t binding_index,
104 "FormaBindingsProcessor::bind_descriptor: null reader for '{}'",
name);
111 b.reader = std::move(reader);
112 b.typed_reader =
nullptr;
120 .binding_index = binding_index,
122 .gpu_buffer = gpu_buf,
123 .buffer_size =
sizeof(float),
141 std::vector<std::string> names;
165 const auto& binding = found->second;
166 std::erase_if(
m_targets, [](
const auto& target) {
return target.expired(); });
169 const auto target = weak.lock();
170 auto& context = target->get_pipeline_context();
173 std::erase_if(context.push_constant_bindings, [&](
const auto& entry) {
174 return entry.offset == binding.pc->offset && entry.name == name;
179 const auto handle = binding.desc->gpu_buffer->get_buffer();
180 std::erase_if(context.descriptor_buffer_bindings, [&](
const auto& entry) {
181 return entry.set == binding.desc->set_index
182 && entry.binding == binding.desc->binding_index
183 && entry.buffer_info.buffer == handle;
194 const bool known = std::ranges::any_of(
m_targets, [&](
const auto& weak) {
195 return weak.lock() ==
buffer;
210 if (
b.typed_reader) {
218 "FormaBindingsProcessor: binding '{}' has no reader",
name);
222 const float value =
b.reader();
241 const std::string&
name,
244 const std::shared_ptr<VKBuffer>&
buffer)
246 auto& entries =
buffer->get_pipeline_context().push_constant_bindings;
248 auto it = std::ranges::find_if(entries, [&](
const auto& e) {
249 return e.offset == pc.
offset;
252 if (it == entries.end()) {
255 .data = std::vector<uint8_t>(pc.
size),
257 it = std::prev(entries.end());
262 std::span<std::byte>(
reinterpret_cast<std::byte*
>(it->data.data()), it->data.size()));
265 "FormaBindingsProcessor: binding '{}' does not fit its push constant slot",
name);
267 }
else if (pc.
size ==
sizeof(
float)) {
268 std::memcpy(it->data.data(), &
value,
sizeof(
float));
269 }
else if (pc.
size ==
sizeof(
double)) {
270 auto promoted =
static_cast<double>(
value);
271 std::memcpy(it->data.data(), &promoted,
sizeof(
double));
275 "FormaBindingsProcessor: PC write offset={} value={}", pc.
offset,
value);
279 const std::string&
name,
282 const std::shared_ptr<VKBuffer>&
buffer)
284 auto& entries =
buffer->get_pipeline_context().push_constant_bindings;
287 auto it = std::ranges::find_if(entries, [&](
const auto& e) {
288 return e.offset == pc.
offset;
291 if (it == entries.end()) {
294 .data = std::vector<uint8_t>(
width),
296 it = std::prev(entries.end());
297 }
else if (it->data.size() !=
width) {
298 it->data.resize(
width);
302 std::span<std::byte>(
reinterpret_cast<std::byte*
>(it->data.data()), it->data.size()));
308 const std::shared_ptr<VKBuffer>& attached)
312 auto& bindings_list = attached->get_pipeline_context().descriptor_buffer_bindings;
314 for (
auto& entry : bindings_list) {
316 entry.buffer_info.buffer = desc.
gpu_buffer->get_buffer();
317 entry.buffer_info.offset = 0;
318 entry.buffer_info.range =
sizeof(float);
323 bindings_list.push_back({
327 ? vk::DescriptorType::eUniformBuffer
328 : vk::DescriptorType::eStorageBuffer,
329 .buffer_info = vk::DescriptorBufferInfo {
330 desc.
gpu_buffer->get_buffer(), 0,
sizeof(float) },
338 ? VKBuffer::Usage::UNIFORM
339 : VKBuffer::Usage::COMPUTE;
341 auto buf = std::make_shared<VKBuffer>(
350 error<std::runtime_error>(
353 std::source_location::current(),
354 "FormaBindingsProcessor: no BufferService available");
357 svc->initialize_buffer(buf);
#define MF_ERROR(comp, ctx,...)
#define MF_RT_WARN(comp, ctx,...)
#define MF_RT_DEBUG(comp, ctx,...)
std::shared_ptr< NetworkGeometryBuffer > buffer
void unbind_buffer(const std::string &descriptor_name)
Unbind a buffer from a descriptor.
bool m_needs_descriptor_rebuild
void bind_buffer(const std::string &descriptor_name, const std::shared_ptr< VKBuffer > &buffer)
Bind a VKBuffer to a named shader descriptor.
Abstract base class for shader-based buffer processing.
Interface * get_service()
Query for a backend service.
static BackendRegistry & instance()
Get the global registry instance.
void upload_to_gpu(const void *data, size_t size, const std::shared_ptr< VKBuffer > &target, const std::shared_ptr< VKBuffer > &staging, size_t dst_offset)
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< float, glm::vec2, glm::vec3, glm::vec4, double, glm::dvec2, glm::dvec3, glm::dvec4, int32_t, uint32_t, uint8_t, uint16_t, glm::mat4 > GpuValue
One value of any GpuDataFormat.
size_t gpu_data_format_bytes(GpuDataFormat fmt) noexcept
Byte size of one element of a GpuDataFormat.
size_t gpu_data_format_components(GpuDataFormat fmt) noexcept
Number of scalar components in one element of a GpuDataFormat.
@ UNKNOWN
Unknown or undefined modality.
GpuDataFormat gpu_value_format(const GpuValue &value) noexcept
The GpuDataFormat of the value held.
size_t gpu_value_write(const GpuValue &value, std::span< std::byte > out) noexcept
Copies the held value's bytes into out, unconverted.
bool pack_gpu_value(GpuDataFormat dst, const T &value, std::span< std::byte > out) noexcept
Writes a typed value into out as one element of dst.
GpuDataFormat
GPU data formats with explicit precision levels.
DescriptorRole
Semantic descriptor type — maps to Vulkan descriptor types internally.
@ UNIFORM
Small, read-only, frequently updated (scalars, param structs)
BufferUsageHint
Semantic usage hint for buffer allocation and memory properties.
Self-describing push constant fragment staged on a VKBuffer.
Backend buffer management service interface.