wgpu/tests/snapshots.rs

688 lines
21 KiB
Rust
Raw Normal View History

// A lot of the code can be unused based on configuration flags,
// the corresponding warnings aren't helpful.
#![allow(dead_code)]
Satisfy latest `clippy` lints (up to Rust 1.64) (#2081) * refactor: satisfy `clippy::borrow_deref_ref` * chore: satisfy `clippy::ptr_arg` * refactor: satisfy `clippy::needless_update` * chore: `allow(clippy::too_many_arguments)` on `write_output_glsl` test Since this is test code, I don't think there's a strong impetus to refactor types to consolidate or otherwise alter arguments here. Let's just `allow` this. * refactor: satisfy `clippy::single_match` I think it's sixes whether to keep this code as-is or to `allow(...)` as-is. 🤷🏻‍♂️ * refactor: satisfy `clippy::single_char_pattern` * refactor: satisfy `clippy::reversed_empty_ranges` The lint fires because it generally doesn't make sense to use a `Range` built this way; [upstream `Range` docs]) states: > It is empty if `start >= end`. `clippy` wants to help us from naively iterating over a `Range` like this! Thanks, `clippy`! However, we're not actually using the offending `addresses` variables for iteration. We're using them as a flat data structure with fields that happen to conceptually match. We can, therefore, sidestep this lint by "just" inlining into separate variables for start and end instead. [upstream `Range` docs]: https://doc.rust-lang.org/stable/std/ops/struct.Range.html * refactor: satisfy `clippy::pattern_type_mismatch` * chore: `allow(clippy::panic)` for `test` We definitely should let `panic!(...)` calls exist in `cfg(test)`! It's a very standard way to fail `#[test]` functions. It seems that previous test authors agree! 😅 * fixup! refactor: satisfy `clippy::pattern_type_mismatch` * fixup! refactor: satisfy `clippy::single_match`
2022-11-03 16:32:15 +00:00
use std::{
fs,
path::{Path, PathBuf},
};
2021-04-14 18:20:48 +00:00
2021-06-18 22:38:47 +00:00
const BASE_DIR_IN: &str = "tests/in";
const BASE_DIR_OUT: &str = "tests/out";
2021-04-14 18:20:48 +00:00
2020-12-13 06:20:39 +00:00
bitflags::bitflags! {
struct Targets: u32 {
const IR = 0x1;
const ANALYSIS = 0x2;
const SPIRV = 0x4;
const METAL = 0x8;
const GLSL = 0x10;
2021-03-02 06:28:32 +00:00
const DOT = 0x20;
const HLSL = 0x40;
const WGSL = 0x80;
2020-12-13 06:20:39 +00:00
}
}
2021-09-15 18:43:52 +00:00
#[derive(serde::Deserialize)]
struct SpvOutVersion(u8, u8);
impl Default for SpvOutVersion {
fn default() -> Self {
SpvOutVersion(1, 1)
}
}
#[derive(Default, serde::Deserialize)]
struct SpirvOutParameters {
version: SpvOutVersion,
#[serde(default)]
capabilities: naga::FastHashSet<spirv::Capability>,
#[serde(default)]
debug: bool,
#[serde(default)]
adjust_coordinate_space: bool,
#[serde(default)]
force_point_size: bool,
#[serde(default)]
clamp_frag_depth: bool,
#[serde(default)]
2021-09-15 18:43:52 +00:00
separate_entry_points: bool,
2022-04-19 18:23:07 +00:00
#[serde(default)]
#[cfg(all(feature = "deserialize", feature = "spv-out"))]
binding_map: naga::back::spv::BindingMap,
2021-09-15 18:43:52 +00:00
}
2020-12-11 14:56:10 +00:00
#[derive(Default, serde::Deserialize)]
struct WgslOutParameters {
#[serde(default)]
explicit_types: bool,
}
#[derive(Default, serde::Deserialize)]
struct Parameters {
#[serde(default)]
god_mode: bool,
#[cfg(feature = "deserialize")]
#[serde(default)]
bounds_check_policies: naga::proc::BoundsCheckPolicies,
#[serde(default)]
2021-09-15 18:43:52 +00:00
spv: SpirvOutParameters,
2021-04-07 14:29:35 +00:00
#[cfg(all(feature = "deserialize", feature = "msl-out"))]
#[serde(default)]
msl: naga::back::msl::Options,
2022-01-18 20:17:59 +00:00
#[cfg(all(feature = "deserialize", feature = "msl-out"))]
#[serde(default)]
msl_pipeline: naga::back::msl::PipelineOptions,
2021-06-27 04:26:12 +00:00
#[cfg(all(feature = "deserialize", feature = "glsl-out"))]
#[serde(default)]
glsl: naga::back::glsl::Options,
#[serde(default)]
glsl_exclude_list: naga::FastHashSet<String>,
2021-07-18 04:10:19 +00:00
#[cfg(all(feature = "deserialize", feature = "hlsl-out"))]
#[serde(default)]
hlsl: naga::back::hlsl::Options,
#[serde(default)]
wgsl: WgslOutParameters,
#[cfg(all(feature = "deserialize", feature = "glsl-out"))]
#[serde(default)]
glsl_multiview: Option<std::num::NonZeroU32>,
2020-12-08 05:23:29 +00:00
}
#[allow(unused_variables)]
fn check_targets(module: &naga::Module, name: &str, targets: Targets) {
2021-04-14 18:20:48 +00:00
let root = env!("CARGO_MANIFEST_DIR");
2021-06-18 22:38:47 +00:00
let params = match fs::read_to_string(format!("{}/{}/{}.param.ron", root, BASE_DIR_IN, name)) {
Ok(string) => ron::de::from_str(&string).expect("Couldn't parse param file"),
Err(_) => Parameters::default(),
};
let capabilities = if params.god_mode {
naga::valid::Capabilities::all()
} else {
naga::valid::Capabilities::empty()
};
2021-06-18 22:38:47 +00:00
let dest = PathBuf::from(root).join(BASE_DIR_OUT);
2021-04-14 18:20:48 +00:00
#[cfg(feature = "serialize")]
{
if targets.contains(Targets::IR) {
2021-11-16 14:17:51 +00:00
let config = ron::ser::PrettyConfig::default().new_line("\n".to_string());
2021-04-14 18:20:48 +00:00
let string = ron::ser::to_string_pretty(module, config).unwrap();
2021-06-18 22:38:47 +00:00
fs::write(dest.join(format!("ir/{}.ron", name)), string).unwrap();
}
}
let info = naga::valid::Validator::new(naga::valid::ValidationFlags::all(), capabilities)
.validate(module)
.expect("Naga module validation failed");
#[cfg(feature = "serialize")]
{
if targets.contains(Targets::ANALYSIS) {
2021-11-16 14:17:51 +00:00
let config = ron::ser::PrettyConfig::default().new_line("\n".to_string());
2021-04-14 18:20:48 +00:00
let string = ron::ser::to_string_pretty(&info, config).unwrap();
2021-06-18 22:38:47 +00:00
fs::write(dest.join(format!("analysis/{}.info.ron", name)), string).unwrap();
}
}
#[cfg(all(feature = "deserialize", feature = "spv-out"))]
{
if targets.contains(Targets::SPIRV) {
write_output_spv(
module,
&info,
&dest,
name,
&params.spv,
params.bounds_check_policies,
);
}
}
#[cfg(all(feature = "deserialize", feature = "msl-out"))]
{
if targets.contains(Targets::METAL) {
write_output_msl(
module,
&info,
&dest,
name,
&params.msl,
2022-01-18 20:17:59 +00:00
&params.msl_pipeline,
params.bounds_check_policies,
);
}
}
#[cfg(all(feature = "deserialize", feature = "glsl-out"))]
{
if targets.contains(Targets::GLSL) {
2021-03-07 03:47:21 +00:00
for ep in module.entry_points.iter() {
if params.glsl_exclude_list.contains(&ep.name) {
continue;
}
write_output_glsl(
module,
&info,
&dest,
name,
ep.stage,
&ep.name,
&params.glsl,
params.bounds_check_policies,
params.glsl_multiview,
);
}
}
}
2021-03-02 06:28:32 +00:00
#[cfg(feature = "dot-out")]
{
if targets.contains(Targets::DOT) {
let string = naga::back::dot::write(module, Some(&info), Default::default()).unwrap();
2021-06-18 22:38:47 +00:00
fs::write(dest.join(format!("dot/{}.dot", name)), string).unwrap();
2021-03-02 06:28:32 +00:00
}
}
#[cfg(all(feature = "deserialize", feature = "hlsl-out"))]
{
if targets.contains(Targets::HLSL) {
write_output_hlsl(module, &info, &dest, name, &params.hlsl);
}
}
#[cfg(all(feature = "deserialize", feature = "wgsl-out"))]
{
if targets.contains(Targets::WGSL) {
write_output_wgsl(module, &info, &dest, name, &params.wgsl);
}
}
}
#[cfg(feature = "spv-out")]
2021-06-18 22:38:47 +00:00
fn write_output_spv(
module: &naga::Module,
info: &naga::valid::ModuleInfo,
Satisfy latest `clippy` lints (up to Rust 1.64) (#2081) * refactor: satisfy `clippy::borrow_deref_ref` * chore: satisfy `clippy::ptr_arg` * refactor: satisfy `clippy::needless_update` * chore: `allow(clippy::too_many_arguments)` on `write_output_glsl` test Since this is test code, I don't think there's a strong impetus to refactor types to consolidate or otherwise alter arguments here. Let's just `allow` this. * refactor: satisfy `clippy::single_match` I think it's sixes whether to keep this code as-is or to `allow(...)` as-is. 🤷🏻‍♂️ * refactor: satisfy `clippy::single_char_pattern` * refactor: satisfy `clippy::reversed_empty_ranges` The lint fires because it generally doesn't make sense to use a `Range` built this way; [upstream `Range` docs]) states: > It is empty if `start >= end`. `clippy` wants to help us from naively iterating over a `Range` like this! Thanks, `clippy`! However, we're not actually using the offending `addresses` variables for iteration. We're using them as a flat data structure with fields that happen to conceptually match. We can, therefore, sidestep this lint by "just" inlining into separate variables for start and end instead. [upstream `Range` docs]: https://doc.rust-lang.org/stable/std/ops/struct.Range.html * refactor: satisfy `clippy::pattern_type_mismatch` * chore: `allow(clippy::panic)` for `test` We definitely should let `panic!(...)` calls exist in `cfg(test)`! It's a very standard way to fail `#[test]` functions. It seems that previous test authors agree! 😅 * fixup! refactor: satisfy `clippy::pattern_type_mismatch` * fixup! refactor: satisfy `clippy::single_match`
2022-11-03 16:32:15 +00:00
destination: &Path,
2021-06-18 22:38:47 +00:00
file_name: &str,
params: &SpirvOutParameters,
bounds_check_policies: naga::proc::BoundsCheckPolicies,
) {
use naga::back::spv;
use rspirv::binary::Disassemble;
println!("writing SPIR-V");
let mut flags = spv::WriterFlags::LABEL_VARYINGS;
flags.set(spv::WriterFlags::DEBUG, params.debug);
flags.set(
spv::WriterFlags::ADJUST_COORDINATE_SPACE,
params.adjust_coordinate_space,
);
flags.set(spv::WriterFlags::FORCE_POINT_SIZE, params.force_point_size);
flags.set(spv::WriterFlags::CLAMP_FRAG_DEPTH, params.clamp_frag_depth);
2021-02-14 05:37:54 +00:00
let options = spv::Options {
lang_version: (params.version.0, params.version.1),
flags,
capabilities: if params.capabilities.is_empty() {
None
} else {
Some(params.capabilities.clone())
},
bounds_check_policies,
2022-04-19 18:23:07 +00:00
binding_map: params.binding_map.clone(),
2021-02-14 05:37:54 +00:00
};
if params.separate_entry_points {
for ep in module.entry_points.iter() {
let pipeline_options = spv::PipelineOptions {
entry_point: ep.name.clone(),
shader_stage: ep.stage,
};
let spv = spv::write_vec(module, info, &options, Some(&pipeline_options)).unwrap();
let dis = rspirv::dr::load_words(spv)
.expect("Produced invalid SPIR-V")
.disassemble();
let path = format!("spv/{}.{}.spvasm", file_name, ep.name);
fs::write(destination.join(path), dis).unwrap();
}
} else {
let spv = spv::write_vec(module, info, &options, None).unwrap();
let dis = rspirv::dr::load_words(spv)
.expect("Produced invalid SPIR-V")
.disassemble();
fs::write(destination.join(format!("spv/{}.spvasm", file_name)), dis).unwrap();
}
}
2020-12-08 05:23:29 +00:00
#[cfg(feature = "msl-out")]
2021-06-18 22:38:47 +00:00
fn write_output_msl(
module: &naga::Module,
info: &naga::valid::ModuleInfo,
Satisfy latest `clippy` lints (up to Rust 1.64) (#2081) * refactor: satisfy `clippy::borrow_deref_ref` * chore: satisfy `clippy::ptr_arg` * refactor: satisfy `clippy::needless_update` * chore: `allow(clippy::too_many_arguments)` on `write_output_glsl` test Since this is test code, I don't think there's a strong impetus to refactor types to consolidate or otherwise alter arguments here. Let's just `allow` this. * refactor: satisfy `clippy::single_match` I think it's sixes whether to keep this code as-is or to `allow(...)` as-is. 🤷🏻‍♂️ * refactor: satisfy `clippy::single_char_pattern` * refactor: satisfy `clippy::reversed_empty_ranges` The lint fires because it generally doesn't make sense to use a `Range` built this way; [upstream `Range` docs]) states: > It is empty if `start >= end`. `clippy` wants to help us from naively iterating over a `Range` like this! Thanks, `clippy`! However, we're not actually using the offending `addresses` variables for iteration. We're using them as a flat data structure with fields that happen to conceptually match. We can, therefore, sidestep this lint by "just" inlining into separate variables for start and end instead. [upstream `Range` docs]: https://doc.rust-lang.org/stable/std/ops/struct.Range.html * refactor: satisfy `clippy::pattern_type_mismatch` * chore: `allow(clippy::panic)` for `test` We definitely should let `panic!(...)` calls exist in `cfg(test)`! It's a very standard way to fail `#[test]` functions. It seems that previous test authors agree! 😅 * fixup! refactor: satisfy `clippy::pattern_type_mismatch` * fixup! refactor: satisfy `clippy::single_match`
2022-11-03 16:32:15 +00:00
destination: &Path,
2021-06-18 22:38:47 +00:00
file_name: &str,
options: &naga::back::msl::Options,
2022-01-18 20:17:59 +00:00
pipeline_options: &naga::back::msl::PipelineOptions,
bounds_check_policies: naga::proc::BoundsCheckPolicies,
) {
2020-12-08 05:23:29 +00:00
use naga::back::msl;
println!("writing MSL");
let mut options = options.clone();
options.bounds_check_policies = bounds_check_policies;
let (string, tr_info) = msl::write_string(module, info, &options, pipeline_options)
.unwrap_or_else(|err| panic!("Metal write failed: {}", err));
for (ep, result) in module.entry_points.iter().zip(tr_info.entry_point_names) {
if let Err(error) = result {
panic!("Failed to translate '{}': {}", ep.name, error);
}
}
2021-06-18 22:38:47 +00:00
fs::write(destination.join(format!("msl/{}.msl", file_name)), string).unwrap();
2020-12-08 05:23:29 +00:00
}
#[cfg(feature = "glsl-out")]
Satisfy latest `clippy` lints (up to Rust 1.64) (#2081) * refactor: satisfy `clippy::borrow_deref_ref` * chore: satisfy `clippy::ptr_arg` * refactor: satisfy `clippy::needless_update` * chore: `allow(clippy::too_many_arguments)` on `write_output_glsl` test Since this is test code, I don't think there's a strong impetus to refactor types to consolidate or otherwise alter arguments here. Let's just `allow` this. * refactor: satisfy `clippy::single_match` I think it's sixes whether to keep this code as-is or to `allow(...)` as-is. 🤷🏻‍♂️ * refactor: satisfy `clippy::single_char_pattern` * refactor: satisfy `clippy::reversed_empty_ranges` The lint fires because it generally doesn't make sense to use a `Range` built this way; [upstream `Range` docs]) states: > It is empty if `start >= end`. `clippy` wants to help us from naively iterating over a `Range` like this! Thanks, `clippy`! However, we're not actually using the offending `addresses` variables for iteration. We're using them as a flat data structure with fields that happen to conceptually match. We can, therefore, sidestep this lint by "just" inlining into separate variables for start and end instead. [upstream `Range` docs]: https://doc.rust-lang.org/stable/std/ops/struct.Range.html * refactor: satisfy `clippy::pattern_type_mismatch` * chore: `allow(clippy::panic)` for `test` We definitely should let `panic!(...)` calls exist in `cfg(test)`! It's a very standard way to fail `#[test]` functions. It seems that previous test authors agree! 😅 * fixup! refactor: satisfy `clippy::pattern_type_mismatch` * fixup! refactor: satisfy `clippy::single_match`
2022-11-03 16:32:15 +00:00
#[allow(clippy::too_many_arguments)]
2021-06-18 22:38:47 +00:00
fn write_output_glsl(
module: &naga::Module,
info: &naga::valid::ModuleInfo,
Satisfy latest `clippy` lints (up to Rust 1.64) (#2081) * refactor: satisfy `clippy::borrow_deref_ref` * chore: satisfy `clippy::ptr_arg` * refactor: satisfy `clippy::needless_update` * chore: `allow(clippy::too_many_arguments)` on `write_output_glsl` test Since this is test code, I don't think there's a strong impetus to refactor types to consolidate or otherwise alter arguments here. Let's just `allow` this. * refactor: satisfy `clippy::single_match` I think it's sixes whether to keep this code as-is or to `allow(...)` as-is. 🤷🏻‍♂️ * refactor: satisfy `clippy::single_char_pattern` * refactor: satisfy `clippy::reversed_empty_ranges` The lint fires because it generally doesn't make sense to use a `Range` built this way; [upstream `Range` docs]) states: > It is empty if `start >= end`. `clippy` wants to help us from naively iterating over a `Range` like this! Thanks, `clippy`! However, we're not actually using the offending `addresses` variables for iteration. We're using them as a flat data structure with fields that happen to conceptually match. We can, therefore, sidestep this lint by "just" inlining into separate variables for start and end instead. [upstream `Range` docs]: https://doc.rust-lang.org/stable/std/ops/struct.Range.html * refactor: satisfy `clippy::pattern_type_mismatch` * chore: `allow(clippy::panic)` for `test` We definitely should let `panic!(...)` calls exist in `cfg(test)`! It's a very standard way to fail `#[test]` functions. It seems that previous test authors agree! 😅 * fixup! refactor: satisfy `clippy::pattern_type_mismatch` * fixup! refactor: satisfy `clippy::single_match`
2022-11-03 16:32:15 +00:00
destination: &Path,
2021-06-18 22:38:47 +00:00
file_name: &str,
stage: naga::ShaderStage,
ep_name: &str,
options: &naga::back::glsl::Options,
bounds_check_policies: naga::proc::BoundsCheckPolicies,
multiview: Option<std::num::NonZeroU32>,
) {
use naga::back::glsl;
println!("writing GLSL");
2021-06-27 04:26:12 +00:00
let pipeline_options = glsl::PipelineOptions {
shader_stage: stage,
entry_point: ep_name.to_string(),
multiview,
};
let mut buffer = String::new();
let mut writer = glsl::Writer::new(
&mut buffer,
module,
info,
options,
&pipeline_options,
bounds_check_policies,
)
.expect("GLSL init failed");
writer.write().expect("GLSL write failed");
2021-06-18 22:38:47 +00:00
fs::write(
destination.join(format!("glsl/{}.{}.{:?}.glsl", file_name, ep_name, stage)),
2021-06-18 22:38:47 +00:00
buffer,
)
.unwrap();
2020-12-08 05:23:29 +00:00
}
#[cfg(feature = "hlsl-out")]
2021-06-18 22:38:47 +00:00
fn write_output_hlsl(
module: &naga::Module,
info: &naga::valid::ModuleInfo,
Satisfy latest `clippy` lints (up to Rust 1.64) (#2081) * refactor: satisfy `clippy::borrow_deref_ref` * chore: satisfy `clippy::ptr_arg` * refactor: satisfy `clippy::needless_update` * chore: `allow(clippy::too_many_arguments)` on `write_output_glsl` test Since this is test code, I don't think there's a strong impetus to refactor types to consolidate or otherwise alter arguments here. Let's just `allow` this. * refactor: satisfy `clippy::single_match` I think it's sixes whether to keep this code as-is or to `allow(...)` as-is. 🤷🏻‍♂️ * refactor: satisfy `clippy::single_char_pattern` * refactor: satisfy `clippy::reversed_empty_ranges` The lint fires because it generally doesn't make sense to use a `Range` built this way; [upstream `Range` docs]) states: > It is empty if `start >= end`. `clippy` wants to help us from naively iterating over a `Range` like this! Thanks, `clippy`! However, we're not actually using the offending `addresses` variables for iteration. We're using them as a flat data structure with fields that happen to conceptually match. We can, therefore, sidestep this lint by "just" inlining into separate variables for start and end instead. [upstream `Range` docs]: https://doc.rust-lang.org/stable/std/ops/struct.Range.html * refactor: satisfy `clippy::pattern_type_mismatch` * chore: `allow(clippy::panic)` for `test` We definitely should let `panic!(...)` calls exist in `cfg(test)`! It's a very standard way to fail `#[test]` functions. It seems that previous test authors agree! 😅 * fixup! refactor: satisfy `clippy::pattern_type_mismatch` * fixup! refactor: satisfy `clippy::single_match`
2022-11-03 16:32:15 +00:00
destination: &Path,
2021-06-18 22:38:47 +00:00
file_name: &str,
options: &naga::back::hlsl::Options,
2021-06-18 22:38:47 +00:00
) {
use naga::back::hlsl;
use std::fmt::Write as _;
2021-07-18 04:10:19 +00:00
println!("writing HLSL");
let mut buffer = String::new();
2021-07-18 04:10:19 +00:00
let mut writer = hlsl::Writer::new(&mut buffer, options);
let reflection_info = writer.write(module, info).expect("HLSL write failed");
fs::write(destination.join(format!("hlsl/{}.hlsl", file_name)), buffer).unwrap();
2021-04-14 18:20:48 +00:00
// We need a config file for validation script
// This file contains an info about profiles (shader stages) contains inside generated shader
// This info will be passed to dxc
2021-07-18 04:10:19 +00:00
let mut config_str = String::new();
let mut vertex_str = String::from("vertex=(");
let mut fragment_str = String::from("fragment=(");
let mut compute_str = String::from("compute=(");
for (index, ep) in module.entry_points.iter().enumerate() {
2021-07-18 04:10:19 +00:00
let name = match reflection_info.entry_point_names[index] {
Ok(ref name) => name,
Err(_) => continue,
};
match ep.stage {
naga::ShaderStage::Vertex => {
write!(
vertex_str,
"{}:{}_{} ",
name,
ep.stage.to_hlsl_str(),
options.shader_model.to_str(),
)
.unwrap();
}
naga::ShaderStage::Fragment => {
write!(
fragment_str,
"{}:{}_{} ",
name,
ep.stage.to_hlsl_str(),
options.shader_model.to_str(),
)
.unwrap();
}
naga::ShaderStage::Compute => {
write!(
compute_str,
"{}:{}_{} ",
name,
ep.stage.to_hlsl_str(),
options.shader_model.to_str(),
)
.unwrap();
}
}
}
writeln!(
config_str,
"{})\n{})\n{})",
vertex_str, fragment_str, compute_str
)
.unwrap();
2021-06-18 22:38:47 +00:00
fs::write(
destination.join(format!("hlsl/{}.hlsl.config", file_name)),
config_str,
)
.unwrap();
}
#[cfg(feature = "wgsl-out")]
2021-06-18 22:38:47 +00:00
fn write_output_wgsl(
module: &naga::Module,
info: &naga::valid::ModuleInfo,
Satisfy latest `clippy` lints (up to Rust 1.64) (#2081) * refactor: satisfy `clippy::borrow_deref_ref` * chore: satisfy `clippy::ptr_arg` * refactor: satisfy `clippy::needless_update` * chore: `allow(clippy::too_many_arguments)` on `write_output_glsl` test Since this is test code, I don't think there's a strong impetus to refactor types to consolidate or otherwise alter arguments here. Let's just `allow` this. * refactor: satisfy `clippy::single_match` I think it's sixes whether to keep this code as-is or to `allow(...)` as-is. 🤷🏻‍♂️ * refactor: satisfy `clippy::single_char_pattern` * refactor: satisfy `clippy::reversed_empty_ranges` The lint fires because it generally doesn't make sense to use a `Range` built this way; [upstream `Range` docs]) states: > It is empty if `start >= end`. `clippy` wants to help us from naively iterating over a `Range` like this! Thanks, `clippy`! However, we're not actually using the offending `addresses` variables for iteration. We're using them as a flat data structure with fields that happen to conceptually match. We can, therefore, sidestep this lint by "just" inlining into separate variables for start and end instead. [upstream `Range` docs]: https://doc.rust-lang.org/stable/std/ops/struct.Range.html * refactor: satisfy `clippy::pattern_type_mismatch` * chore: `allow(clippy::panic)` for `test` We definitely should let `panic!(...)` calls exist in `cfg(test)`! It's a very standard way to fail `#[test]` functions. It seems that previous test authors agree! 😅 * fixup! refactor: satisfy `clippy::pattern_type_mismatch` * fixup! refactor: satisfy `clippy::single_match`
2022-11-03 16:32:15 +00:00
destination: &Path,
2021-06-18 22:38:47 +00:00
file_name: &str,
params: &WgslOutParameters,
2021-06-18 22:38:47 +00:00
) {
use naga::back::wgsl;
println!("writing WGSL");
let mut flags = wgsl::WriterFlags::empty();
flags.set(wgsl::WriterFlags::EXPLICIT_TYPES, params.explicit_types);
let string = wgsl::write_string(module, info, flags).expect("WGSL write failed");
2021-06-18 22:38:47 +00:00
fs::write(destination.join(format!("wgsl/{}.wgsl", file_name)), string).unwrap();
}
2020-12-13 06:20:39 +00:00
#[cfg(feature = "wgsl-in")]
#[test]
fn convert_wgsl() {
let _ = env_logger::try_init();
let root = env!("CARGO_MANIFEST_DIR");
let inputs = [
(
"empty",
Targets::SPIRV | Targets::METAL | Targets::GLSL | Targets::HLSL | Targets::WGSL,
),
(
"quad",
Targets::SPIRV
| Targets::METAL
| Targets::GLSL
| Targets::DOT
| Targets::HLSL
| Targets::WGSL,
),
(
"bits",
Targets::SPIRV | Targets::METAL | Targets::GLSL | Targets::WGSL,
),
(
"bitcast",
2022-10-20 06:27:30 +00:00
Targets::SPIRV | Targets::METAL | Targets::GLSL | Targets::HLSL | Targets::WGSL,
),
(
"boids",
2021-07-25 05:36:38 +00:00
Targets::SPIRV | Targets::METAL | Targets::GLSL | Targets::HLSL | Targets::WGSL,
),
(
"skybox",
Targets::SPIRV | Targets::METAL | Targets::GLSL | Targets::HLSL | Targets::WGSL,
),
(
"collatz",
2021-07-25 05:36:38 +00:00
Targets::SPIRV
| Targets::METAL
| Targets::IR
| Targets::ANALYSIS
| Targets::HLSL
| Targets::WGSL,
),
(
"shadow",
Targets::SPIRV | Targets::METAL | Targets::GLSL | Targets::HLSL | Targets::WGSL,
),
2021-07-16 10:08:48 +00:00
(
"image",
Targets::SPIRV | Targets::METAL | Targets::HLSL | Targets::WGSL | Targets::GLSL,
2021-07-16 10:08:48 +00:00
),
("extra", Targets::SPIRV | Targets::METAL | Targets::WGSL),
("push-constants", Targets::GLSL | Targets::HLSL),
(
"operators",
Targets::SPIRV | Targets::METAL | Targets::GLSL | Targets::HLSL | Targets::WGSL,
),
(
"functions",
Targets::SPIRV | Targets::METAL | Targets::GLSL | Targets::HLSL | Targets::WGSL,
),
("functions-webgl", Targets::GLSL),
(
"interpolate",
Targets::SPIRV | Targets::METAL | Targets::GLSL | Targets::HLSL | Targets::WGSL,
),
(
"access",
2021-08-06 05:18:51 +00:00
Targets::SPIRV | Targets::METAL | Targets::GLSL | Targets::HLSL | Targets::WGSL,
),
(
"padding",
Targets::SPIRV | Targets::METAL | Targets::GLSL | Targets::HLSL | Targets::WGSL,
),
("pointers", Targets::SPIRV | Targets::WGSL),
2021-05-03 04:18:35 +00:00
(
"control-flow",
Targets::SPIRV | Targets::METAL | Targets::GLSL | Targets::HLSL | Targets::WGSL,
),
(
"standard",
Targets::SPIRV | Targets::METAL | Targets::GLSL | Targets::HLSL | Targets::WGSL,
2021-05-03 04:18:35 +00:00
),
2021-05-18 02:00:12 +00:00
//TODO: GLSL https://github.com/gfx-rs/naga/issues/874
(
"interface",
Targets::SPIRV | Targets::METAL | Targets::HLSL | Targets::WGSL,
),
2021-05-29 01:49:50 +00:00
(
"globals",
Targets::SPIRV | Targets::METAL | Targets::GLSL | Targets::HLSL | Targets::WGSL,
2021-05-29 01:49:50 +00:00
),
("bounds-check-zero", Targets::SPIRV | Targets::METAL),
("bounds-check-zero-atomic", Targets::METAL),
("bounds-check-restrict", Targets::SPIRV | Targets::METAL),
(
"bounds-check-image-restrict",
Targets::SPIRV | Targets::METAL | Targets::GLSL,
),
(
"bounds-check-image-rzsw",
Targets::SPIRV | Targets::METAL | Targets::GLSL,
),
("policy-mix", Targets::SPIRV | Targets::METAL),
(
"texture-arg",
Targets::SPIRV | Targets::METAL | Targets::GLSL | Targets::HLSL | Targets::WGSL,
),
("cubeArrayShadow", Targets::GLSL),
(
"math-functions",
2021-12-27 02:57:47 +00:00
Targets::SPIRV | Targets::METAL | Targets::GLSL | Targets::HLSL | Targets::WGSL,
),
2022-04-19 18:23:07 +00:00
("cubeArrayShadow", Targets::GLSL),
(
"binding-arrays",
Targets::WGSL | Targets::HLSL | Targets::METAL | Targets::SPIRV,
),
("multiview", Targets::SPIRV | Targets::GLSL | Targets::WGSL),
("multiview_webgl", Targets::GLSL),
(
"break-if",
Targets::WGSL | Targets::GLSL | Targets::SPIRV | Targets::HLSL | Targets::METAL,
),
("lexical-scopes", Targets::WGSL),
];
for &(name, targets) in inputs.iter() {
println!("Processing '{}'", name);
2021-06-18 22:38:47 +00:00
// WGSL shaders lives in root dir as a privileged.
let file = fs::read_to_string(format!("{}/{}/{}.wgsl", root, BASE_DIR_IN, name))
.expect("Couldn't find wgsl file");
match naga::front::wgsl::parse_str(&file) {
Ok(module) => check_targets(&module, name, targets),
Err(e) => panic!("{}", e.emit_to_string(&file)),
}
}
2021-02-07 02:02:49 +00:00
}
2021-02-08 17:30:21 +00:00
#[cfg(feature = "spv-in")]
fn convert_spv(name: &str, adjust_coordinate_space: bool, targets: Targets) {
let _ = env_logger::try_init();
2021-04-14 18:20:48 +00:00
let root = env!("CARGO_MANIFEST_DIR");
2021-02-08 17:30:21 +00:00
let module = naga::front::spv::parse_u8_slice(
2021-06-18 22:38:47 +00:00
&fs::read(format!("{}/{}/spv/{}.spv", root, BASE_DIR_IN, name))
.expect("Couldn't find spv file"),
&naga::front::spv::Options {
adjust_coordinate_space,
strict_capabilities: false,
block_ctx_dump_prefix: None,
},
2021-02-08 17:30:21 +00:00
)
.unwrap();
check_targets(&module, name, targets);
2021-05-05 21:52:50 +00:00
naga::valid::Validator::new(
naga::valid::ValidationFlags::all(),
naga::valid::Capabilities::empty(),
)
.validate(&module)
.unwrap();
2021-02-08 17:30:21 +00:00
}
#[cfg(feature = "spv-in")]
#[test]
fn convert_spv_all() {
convert_spv(
"quad-vert",
false,
Targets::METAL | Targets::GLSL | Targets::HLSL | Targets::WGSL,
);
convert_spv("shadow", true, Targets::IR | Targets::ANALYSIS);
convert_spv(
"inv-hyperbolic-trig-functions",
true,
2021-08-20 19:43:17 +00:00
Targets::HLSL | Targets::WGSL,
);
convert_spv(
"empty-global-name",
true,
Targets::HLSL | Targets::WGSL | Targets::METAL,
);
convert_spv(
"empty-global-name",
true,
Targets::HLSL | Targets::WGSL | Targets::METAL,
);
convert_spv("degrees", false, Targets::empty());
}
#[cfg(feature = "glsl-in")]
#[test]
fn convert_glsl_variations_check() {
let root = env!("CARGO_MANIFEST_DIR");
let file = fs::read_to_string(format!("{}/{}/variations.glsl", root, BASE_DIR_IN))
.expect("Couldn't find glsl file");
let mut parser = naga::front::glsl::Parser::default();
let module = parser
.parse(
&naga::front::glsl::Options {
stage: naga::ShaderStage::Fragment,
defines: Default::default(),
},
&file,
)
.unwrap();
check_targets(&module, "variations-glsl", Targets::GLSL);
}
#[cfg(feature = "glsl-in")]
#[allow(unused_variables)]
#[test]
fn convert_glsl_folder() {
let _ = env_logger::try_init();
let root = env!("CARGO_MANIFEST_DIR");
2021-06-18 22:38:47 +00:00
for entry in std::fs::read_dir(format!("{}/{}/glsl", root, BASE_DIR_IN)).unwrap() {
let entry = entry.unwrap();
let file_name = entry.file_name().into_string().unwrap();
2021-06-18 22:38:47 +00:00
if file_name.ends_with(".ron") {
// No needed to validate ron files
continue;
}
println!("Processing {}", file_name);
let mut parser = naga::front::glsl::Parser::default();
let module = parser
.parse(
&naga::front::glsl::Options {
stage: match entry.path().extension().and_then(|s| s.to_str()).unwrap() {
"vert" => naga::ShaderStage::Vertex,
"frag" => naga::ShaderStage::Fragment,
"comp" => naga::ShaderStage::Compute,
ext => panic!("Unknown extension for glsl file {}", ext),
},
defines: Default::default(),
},
&fs::read_to_string(entry.path()).expect("Couldn't find glsl file"),
)
.unwrap();
let info = naga::valid::Validator::new(
naga::valid::ValidationFlags::all(),
naga::valid::Capabilities::all(),
)
.validate(&module)
.unwrap();
#[cfg(feature = "wgsl-out")]
2021-06-18 22:38:47 +00:00
{
let dest = PathBuf::from(root).join(BASE_DIR_OUT);
write_output_wgsl(
&module,
&info,
&dest,
Satisfy latest `clippy` lints (up to Rust 1.64) (#2081) * refactor: satisfy `clippy::borrow_deref_ref` * chore: satisfy `clippy::ptr_arg` * refactor: satisfy `clippy::needless_update` * chore: `allow(clippy::too_many_arguments)` on `write_output_glsl` test Since this is test code, I don't think there's a strong impetus to refactor types to consolidate or otherwise alter arguments here. Let's just `allow` this. * refactor: satisfy `clippy::single_match` I think it's sixes whether to keep this code as-is or to `allow(...)` as-is. 🤷🏻‍♂️ * refactor: satisfy `clippy::single_char_pattern` * refactor: satisfy `clippy::reversed_empty_ranges` The lint fires because it generally doesn't make sense to use a `Range` built this way; [upstream `Range` docs]) states: > It is empty if `start >= end`. `clippy` wants to help us from naively iterating over a `Range` like this! Thanks, `clippy`! However, we're not actually using the offending `addresses` variables for iteration. We're using them as a flat data structure with fields that happen to conceptually match. We can, therefore, sidestep this lint by "just" inlining into separate variables for start and end instead. [upstream `Range` docs]: https://doc.rust-lang.org/stable/std/ops/struct.Range.html * refactor: satisfy `clippy::pattern_type_mismatch` * chore: `allow(clippy::panic)` for `test` We definitely should let `panic!(...)` calls exist in `cfg(test)`! It's a very standard way to fail `#[test]` functions. It seems that previous test authors agree! 😅 * fixup! refactor: satisfy `clippy::pattern_type_mismatch` * fixup! refactor: satisfy `clippy::single_match`
2022-11-03 16:32:15 +00:00
&file_name.replace('.', "-"),
&WgslOutParameters::default(),
);
2021-06-18 22:38:47 +00:00
}
}
}