summaryrefslogtreecommitdiffstats
path: root/third_party/rust/naga/benches/criterion.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/naga/benches/criterion.rs')
-rw-r--r--third_party/rust/naga/benches/criterion.rs276
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);