vyre-driver 0.4.1

Driver layer: registry, runtime, pipeline, routing, diagnostics. Substrate-agnostic backend machinery. Part of the vyre GPU compiler.
//! Dispatch ABI parameter derivation from binding plans.

use crate::binding::{Binding, BindingRole};

/// Derive the dispatch element count from a binding plan.
#[must_use]
pub fn dispatch_element_count(bindings: &[Binding]) -> u32 {
    let output_count = bindings
        .iter()
        .filter(|binding| binding.role == BindingRole::Output)
        .map(|binding| binding.element_count)
        .max()
        .unwrap_or(0);
    if output_count > 0 {
        return output_count;
    }

    bindings
        .iter()
        .filter(|binding| binding.role != BindingRole::Shared)
        .map(|binding| binding.element_count)
        .max()
        .unwrap_or(1)
        .max(1)
}

/// Build per-buffer element-count parameter words for a dispatch.
#[must_use]
pub fn dispatch_param_words(bindings: &[Binding], element_count: u32) -> Vec<u32> {
    let mut words = Vec::with_capacity(bindings.len().saturating_add(1).max(1));
    dispatch_param_words_into(bindings, element_count, &mut words);
    words
}

/// Build per-buffer element-count parameter words into caller-owned storage.
pub fn dispatch_param_words_into(bindings: &[Binding], element_count: u32, words: &mut Vec<u32>) {
    words.clear();
    words.resize(bindings.len().saturating_add(1).max(1), 0);
    words[0] = element_count;
    for binding in bindings {
        if binding.buffer_index + 1 >= words.len() {
            words.resize(binding.buffer_index + 2, 0);
        }
        words[binding.buffer_index + 1] = if binding.element_count == 0 {
            element_count
        } else {
            binding.element_count
        };
    }
}