use super::put_nodes;
use crate::ir::serial::wire::framing::{
put_len_u32, put_string, put_u32, put_u8, MAGIC, WIRE_FORMAT_VERSION,
};
use crate::ir::serial::wire::tags::{access_tag, put_data_type};
use crate::ir::serial::wire::Program;
#[inline]
pub fn to_wire(program: &Program) -> Result<Vec<u8>, String> {
let capacity = MAGIC.len()
+ 1
+ program.entry_op_id().map_or(0, |id| 4 + id.len())
+ 4
+ program.buffers().len() * 32
+ 12
+ 4
+ program.entry().len() * 16;
let mut out = Vec::with_capacity(capacity + 2);
out.extend_from_slice(MAGIC);
out.extend_from_slice(&WIRE_FORMAT_VERSION.to_le_bytes());
match program.entry_op_id() {
Some(op_id) => {
put_u8(&mut out, 1);
put_string(&mut out, op_id)?;
}
None => put_u8(&mut out, 0),
}
put_len_u32(&mut out, program.buffers().len(), "buffer count")?;
for buffer in program.buffers() {
put_string(&mut out, &buffer.name)?;
put_u32(&mut out, buffer.binding);
put_u8(&mut out, access_tag(buffer.access.clone())?);
put_data_type(&mut out, &buffer.element)?;
put_u32(&mut out, buffer.count);
put_u8(&mut out, u8::from(buffer.is_output));
}
for size in program.workgroup_size {
put_u32(&mut out, size);
}
put_nodes(&mut out, program.entry())?;
Ok(out)
}