diff options
Diffstat (limited to 'third_party/rust/naga/benches/criterion.rs')
-rw-r--r-- | third_party/rust/naga/benches/criterion.rs | 276 |
1 files changed, 276 insertions, 0 deletions
diff --git a/third_party/rust/naga/benches/criterion.rs b/third_party/rust/naga/benches/criterion.rs new file mode 100644 index 0000000000..ee8765b921 --- /dev/null +++ b/third_party/rust/naga/benches/criterion.rs @@ -0,0 +1,276 @@ +use criterion::*; +use std::{fs, path::PathBuf, slice}; + +fn gather_inputs(folder: &str, extension: &str) -> Vec<Box<[u8]>> { + let mut list = Vec::new(); + let read_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")) + .join(folder) + .read_dir() + .unwrap(); + for file_entry in read_dir { + match file_entry { + Ok(entry) => match entry.path().extension() { + Some(ostr) if &*ostr == extension => { + let input = fs::read(entry.path()).unwrap_or_default(); + list.push(input.into_boxed_slice()); + } + _ => continue, + }, + Err(e) => { + log::warn!("Skipping file: {:?}", e); + continue; + } + } + } + list +} + +fn parse_glsl(stage: naga::ShaderStage, inputs: &[Box<[u8]>]) { + let mut parser = naga::front::glsl::Parser::default(); + let options = naga::front::glsl::Options { + stage, + defines: Default::default(), + }; + for input in inputs.iter() { + let string = std::str::from_utf8(input).unwrap(); + parser.parse(&options, string).unwrap(); + } +} + +fn frontends(c: &mut Criterion) { + let mut group = c.benchmark_group("front"); + #[cfg(all(feature = "wgsl-in", feature = "serialize", feature = "deserialize"))] + group.bench_function("bin", |b| { + let inputs_wgsl = gather_inputs("tests/in", "wgsl"); + let mut parser = naga::front::wgsl::Parser::new(); + let inputs_bin = inputs_wgsl + .iter() + .map(|input| { + let string = std::str::from_utf8(input).unwrap(); + let module = parser.parse(string).unwrap(); + bincode::serialize(&module).unwrap() + }) + .collect::<Vec<_>>(); + b.iter(move || { + for input in inputs_bin.iter() { + bincode::deserialize::<naga::Module>(input).unwrap(); + } + }); + }); + #[cfg(feature = "wgsl-in")] + group.bench_function("wgsl", |b| { + let inputs_wgsl = gather_inputs("tests/in", "wgsl"); + let inputs = inputs_wgsl + .iter() + .map(|input| std::str::from_utf8(input).unwrap()) + .collect::<Vec<_>>(); + let mut parser = naga::front::wgsl::Parser::new(); + b.iter(move || { + for &input in inputs.iter() { + parser.parse(input).unwrap(); + } + }); + }); + #[cfg(feature = "spv-in")] + group.bench_function("spv", |b| { + let inputs = gather_inputs("tests/in/spv", "spv"); + b.iter(move || { + let options = naga::front::spv::Options::default(); + for input in inputs.iter() { + let spv = + unsafe { slice::from_raw_parts(input.as_ptr() as *const u32, input.len() / 4) }; + let parser = naga::front::spv::Parser::new(spv.iter().cloned(), &options); + parser.parse().unwrap(); + } + }); + }); + #[cfg(feature = "glsl-in")] + group.bench_function("glsl", |b| { + let vert = gather_inputs("tests/in/glsl", "vert"); + b.iter(move || parse_glsl(naga::ShaderStage::Vertex, &vert)); + let frag = gather_inputs("tests/in/glsl", "frag"); + b.iter(move || parse_glsl(naga::ShaderStage::Vertex, &frag)); + //TODO: hangs for some reason! + //let comp = gather_inputs("tests/in/glsl", "comp"); + //b.iter(move || parse_glsl(naga::ShaderStage::Compute, &comp)); + }); +} + +#[cfg(feature = "wgsl-in")] +fn gather_modules() -> Vec<naga::Module> { + let inputs = gather_inputs("tests/in", "wgsl"); + let mut parser = naga::front::wgsl::Parser::new(); + inputs + .iter() + .map(|input| { + let string = std::str::from_utf8(input).unwrap(); + parser.parse(string).unwrap() + }) + .collect() +} +#[cfg(not(feature = "wgsl-in"))] +fn gather_modules() -> Vec<naga::Module> { + Vec::new() +} + +fn validation(c: &mut Criterion) { + let inputs = gather_modules(); + let mut group = c.benchmark_group("valid"); + #[cfg(feature = "validate")] + group.bench_function("safe", |b| { + let mut validator = naga::valid::Validator::new( + naga::valid::ValidationFlags::all(), + naga::valid::Capabilities::all(), + ); + b.iter(|| { + for input in inputs.iter() { + validator.validate(input).unwrap(); + } + }); + }); + #[cfg(feature = "validate")] + group.bench_function("unsafe", |b| { + let mut validator = naga::valid::Validator::new( + naga::valid::ValidationFlags::empty(), + naga::valid::Capabilities::all(), + ); + b.iter(|| { + for input in inputs.iter() { + validator.validate(input).unwrap(); + } + }); + }); +} + +fn backends(c: &mut Criterion) { + #[cfg(feature = "validate")] + let inputs = { + let mut validator = naga::valid::Validator::new( + naga::valid::ValidationFlags::empty(), + naga::valid::Capabilities::empty(), + ); + let input_modules = gather_modules(); + input_modules + .into_iter() + .flat_map(|module| validator.validate(&module).ok().map(|info| (module, info))) + .collect::<Vec<_>>() + }; + #[cfg(not(feature = "validate"))] + let inputs = Vec::<(naga::Module, naga::valid::ModuleInfo)>::new(); + + let mut group = c.benchmark_group("back"); + #[cfg(feature = "wgsl-out")] + group.bench_function("wgsl", |b| { + b.iter(|| { + let mut string = String::new(); + let flags = naga::back::wgsl::WriterFlags::empty(); + for &(ref module, ref info) in inputs.iter() { + let mut writer = naga::back::wgsl::Writer::new(&mut string, flags); + writer.write(module, info).unwrap(); + string.clear(); + } + }); + }); + + #[cfg(feature = "spv-out")] + group.bench_function("spv", |b| { + b.iter(|| { + let mut data = Vec::new(); + let options = naga::back::spv::Options::default(); + for &(ref module, ref info) in inputs.iter() { + let mut writer = naga::back::spv::Writer::new(&options).unwrap(); + writer.write(module, info, None, &mut data).unwrap(); + data.clear(); + } + }); + }); + #[cfg(feature = "spv-out")] + group.bench_function("spv-separate", |b| { + b.iter(|| { + let mut data = Vec::new(); + let options = naga::back::spv::Options::default(); + for &(ref module, ref info) in inputs.iter() { + let mut writer = naga::back::spv::Writer::new(&options).unwrap(); + for ep in module.entry_points.iter() { + let pipeline_options = naga::back::spv::PipelineOptions { + shader_stage: ep.stage, + entry_point: ep.name.clone(), + }; + writer + .write(module, info, Some(&pipeline_options), &mut data) + .unwrap(); + data.clear(); + } + } + }); + }); + + #[cfg(feature = "msl-out")] + group.bench_function("msl", |b| { + b.iter(|| { + let mut string = String::new(); + let options = naga::back::msl::Options::default(); + for &(ref module, ref info) in inputs.iter() { + let pipeline_options = naga::back::msl::PipelineOptions::default(); + let mut writer = naga::back::msl::Writer::new(&mut string); + writer + .write(module, info, &options, &pipeline_options) + .unwrap(); + string.clear(); + } + }); + }); + + #[cfg(feature = "hlsl-out")] + group.bench_function("hlsl", |b| { + b.iter(|| { + let options = naga::back::hlsl::Options::default(); + let mut string = String::new(); + for &(ref module, ref info) in inputs.iter() { + let mut writer = naga::back::hlsl::Writer::new(&mut string, &options); + let _ = writer.write(module, info); // may fail on unimplemented things + string.clear(); + } + }); + }); + + #[cfg(feature = "glsl-out")] + group.bench_function("glsl-separate", |b| { + b.iter(|| { + let mut string = String::new(); + let options = naga::back::glsl::Options { + version: naga::back::glsl::Version::new_gles(320), + writer_flags: naga::back::glsl::WriterFlags::empty(), + binding_map: Default::default(), + }; + for &(ref module, ref info) in inputs.iter() { + for ep in module.entry_points.iter() { + let pipeline_options = naga::back::glsl::PipelineOptions { + shader_stage: ep.stage, + entry_point: ep.name.clone(), + multiview: None, + }; + match naga::back::glsl::Writer::new( + &mut string, + module, + info, + &options, + &pipeline_options, + naga::proc::BoundsCheckPolicies::default(), + ) { + Ok(mut writer) => { + let _ = writer.write(); // can error if unsupported + } + Err(_) => { + // missing features + } + }; + string.clear(); + } + } + }); + }); +} + +criterion_group!(criterion, frontends, validation, backends,); +criterion_main!(criterion); |