|  | // Copyright 2023 the Vello Authors | 
|  | // SPDX-License-Identifier: Apache-2.0 OR MIT | 
|  |  | 
|  | //! Build step. | 
|  |  | 
|  | // These modules are also included in the main crate, where the items are reachable | 
|  | #[allow(warnings, reason = "Checked elsewhere")] | 
|  | #[path = "src/compile/mod.rs"] | 
|  | mod compile; | 
|  | #[allow(warnings, reason = "Checked elsewhere")] | 
|  | #[path = "src/types.rs"] | 
|  | mod types; | 
|  |  | 
|  | use std::env; | 
|  | use std::fmt::Write; | 
|  | use std::path::Path; | 
|  |  | 
|  | use compile::ShaderInfo; | 
|  |  | 
|  | fn main() { | 
|  | let out_dir = env::var_os("OUT_DIR").unwrap(); | 
|  | let dest_path = Path::new(&out_dir).join("shaders.rs"); | 
|  |  | 
|  | println!("cargo:rerun-if-changed={}", compile::shader_dir().display()); | 
|  |  | 
|  | let mut shaders = match ShaderInfo::from_default() { | 
|  | Ok(s) => s, | 
|  | Err(err) => { | 
|  | let formatted = err.to_string(); | 
|  | for line in formatted.lines() { | 
|  | println!("cargo:warning={line}"); | 
|  | } | 
|  | return; | 
|  | } | 
|  | }; | 
|  |  | 
|  | // Drop the HashMap and sort by name so that we get deterministic order. | 
|  | let mut shaders = shaders.drain().collect::<Vec<_>>(); | 
|  | shaders.sort_by(|x, y| x.0.cmp(&y.0)); | 
|  | let mut buf = String::default(); | 
|  | write_types(&mut buf, &shaders).unwrap(); | 
|  | write_shaders(&mut buf, &shaders).unwrap(); | 
|  | std::fs::write(dest_path, &buf).unwrap(); | 
|  | } | 
|  |  | 
|  | fn write_types(buf: &mut String, shaders: &[(String, ShaderInfo)]) -> Result<(), std::fmt::Error> { | 
|  | writeln!(buf, "pub struct Shaders<'a> {{")?; | 
|  | for (name, _) in shaders { | 
|  | writeln!(buf, "    pub {name}: ComputeShader<'a>,")?; | 
|  | } | 
|  | writeln!(buf, "}}")?; | 
|  | Ok(()) | 
|  | } | 
|  |  | 
|  | fn write_shaders( | 
|  | buf: &mut String, | 
|  | shaders: &[(String, ShaderInfo)], | 
|  | ) -> Result<(), std::fmt::Error> { | 
|  | writeln!(buf, "mod generated {{")?; | 
|  | writeln!(buf, "    use super::*;")?; | 
|  | writeln!(buf, "    use BindType::*;")?; | 
|  | writeln!(buf, "    pub const SHADERS: Shaders<'static> = Shaders {{")?; | 
|  | for (name, info) in shaders { | 
|  | let bind_tys = info | 
|  | .bindings | 
|  | .iter() | 
|  | .map(|binding| binding.ty) | 
|  | .collect::<Vec<_>>(); | 
|  | let wg_bufs = &info.workgroup_buffers; | 
|  | writeln!(buf, "        {name}: ComputeShader {{")?; | 
|  | writeln!(buf, "            name: Cow::Borrowed({:?}),", name)?; | 
|  | writeln!( | 
|  | buf, | 
|  | "            workgroup_size: {:?},", | 
|  | info.workgroup_size | 
|  | )?; | 
|  | writeln!(buf, "            bindings: Cow::Borrowed(&{:?}),", bind_tys)?; | 
|  | writeln!( | 
|  | buf, | 
|  | "            workgroup_buffers: Cow::Borrowed(&{:?}),", | 
|  | wg_bufs | 
|  | )?; | 
|  | if cfg!(feature = "wgsl") { | 
|  | let indices = info | 
|  | .bindings | 
|  | .iter() | 
|  | .map(|binding| binding.location.1) | 
|  | .collect::<Vec<_>>(); | 
|  | writeln!(buf, "            wgsl: WgslSource {{")?; | 
|  | writeln!( | 
|  | buf, | 
|  | "                code: Cow::Borrowed({:?}),", | 
|  | info.source | 
|  | )?; | 
|  | writeln!( | 
|  | buf, | 
|  | "                binding_indices : Cow::Borrowed(&{:?}),", | 
|  | indices | 
|  | )?; | 
|  | writeln!(buf, "            }},")?; | 
|  | } | 
|  | if cfg!(feature = "msl") { | 
|  | write_msl(buf, info)?; | 
|  | } | 
|  | writeln!(buf, "        }},")?; | 
|  | } | 
|  | writeln!(buf, "    }};")?; | 
|  | writeln!(buf, "}}")?; | 
|  | Ok(()) | 
|  | } | 
|  |  | 
|  | #[cfg(not(feature = "msl"))] | 
|  | fn write_msl(_: &mut String, _: &ShaderInfo) -> Result<(), std::fmt::Error> { | 
|  | Ok(()) | 
|  | } | 
|  |  | 
|  | #[cfg(feature = "msl")] | 
|  | fn write_msl(buf: &mut String, info: &ShaderInfo) -> Result<(), std::fmt::Error> { | 
|  | let mut index_iter = compile::msl::BindingIndexIterator::default(); | 
|  | let indices = info | 
|  | .bindings | 
|  | .iter() | 
|  | .map(|binding| index_iter.next(binding.ty)) | 
|  | .collect::<Vec<_>>(); | 
|  | writeln!(buf, "            msl: MslSource {{")?; | 
|  | writeln!( | 
|  | buf, | 
|  | "                code: Cow::Borrowed({:?}),", | 
|  | compile::msl::translate(info).unwrap() | 
|  | )?; | 
|  | writeln!( | 
|  | buf, | 
|  | "                binding_indices : Cow::Borrowed(&{:?}),", | 
|  | indices | 
|  | )?; | 
|  | writeln!(buf, "            }},")?; | 
|  | Ok(()) | 
|  | } |