use crate::ir::serial::wire::tags::access_from_tag;
use crate::ir::serial::wire::{BufferDecl, Program, Reader, MAX_BUFFERS};
#[inline]
pub fn from_wire(bytes: &[u8]) -> Result<Program, String> {
let mut reader = Reader {
bytes,
pos: 0,
depth: 0,
};
reader.expect_magic()?;
let entry_op_id = match reader.u8()? {
0 => None,
1 => Some(reader.string()?),
tag => {
return Err(format!(
"Fix: unknown IR entry op id tag {tag}; use a Program serializer compatible with this vyre version."
));
}
};
let buffer_count = reader.bounded_len(MAX_BUFFERS, "buffer count")?;
let mut buffers = Vec::with_capacity(buffer_count);
for _ in 0..buffer_count {
buffers.push(BufferDecl {
name: reader.string()?,
binding: reader.u32()?,
access: access_from_tag(reader.u8()?)?,
element: reader.data_type()?,
count: reader.u32()?,
is_output: reader.u8()? != 0,
});
}
let workgroup_size = [reader.u32()?, reader.u32()?, reader.u32()?];
let entry = reader.nodes()?;
if reader.pos != reader.bytes.len() {
return Err(
"IR wire format has trailing bytes. Fix: provide exactly one VIR0 Program blob."
.to_string(),
);
}
Ok(Program::new(buffers, workgroup_size, entry).with_optional_entry_op_id(entry_op_id))
}