2021-11-26 17:10:43 +00:00
|
|
|
// A lot of the code can be unused based on configuration flags,
|
|
|
|
// the corresponding warnings aren't helpful.
|
2022-12-09 22:57:07 +00:00
|
|
|
#![allow(dead_code, unused_imports)]
|
2021-11-26 17:10:43 +00:00
|
|
|
|
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! {
|
2021-02-18 02:46:32 +00:00
|
|
|
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;
|
2021-04-11 15:36:26 +00:00
|
|
|
const HLSL = 0x40;
|
2021-04-19 13:19:03 +00:00
|
|
|
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)]
|
2021-09-27 23:00:10 +00:00
|
|
|
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)]
|
2021-11-26 16:29:35 +00:00
|
|
|
struct WgslOutParameters {
|
2021-05-06 04:04:43 +00:00
|
|
|
#[serde(default)]
|
2021-11-26 16:29:35 +00:00
|
|
|
explicit_types: bool,
|
|
|
|
}
|
2021-05-27 22:02:38 +00:00
|
|
|
|
2021-11-26 16:29:35 +00:00
|
|
|
#[derive(Default, serde::Deserialize)]
|
|
|
|
struct Parameters {
|
2021-05-27 22:02:38 +00:00
|
|
|
#[serde(default)]
|
2021-11-26 16:29:35 +00:00
|
|
|
god_mode: bool,
|
|
|
|
#[cfg(feature = "deserialize")]
|
2021-08-25 01:26:22 +00:00
|
|
|
#[serde(default)]
|
2021-11-26 16:29:35 +00:00
|
|
|
bounds_check_policies: naga::proc::BoundsCheckPolicies,
|
2021-05-19 05:18:27 +00:00
|
|
|
#[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,
|
2021-10-03 03:22:49 +00:00
|
|
|
#[serde(default)]
|
2021-11-26 16:29:35 +00:00
|
|
|
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)]
|
2021-11-26 16:29:35 +00:00
|
|
|
wgsl: WgslOutParameters,
|
2022-06-30 16:58:47 +00:00
|
|
|
#[cfg(all(feature = "deserialize", feature = "glsl-out"))]
|
|
|
|
#[serde(default)]
|
|
|
|
glsl_multiview: Option<std::num::NonZeroU32>,
|
2020-12-08 05:23:29 +00:00
|
|
|
}
|
|
|
|
|
2021-11-26 17:10:43 +00:00
|
|
|
#[allow(unused_variables)]
|
2021-02-18 02:46:32 +00:00
|
|
|
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)) {
|
2021-08-25 17:40:47 +00:00
|
|
|
Ok(string) => ron::de::from_str(&string).expect("Couldn't parse param file"),
|
2021-02-18 02:46:32 +00:00
|
|
|
Err(_) => Parameters::default(),
|
|
|
|
};
|
2021-10-19 16:37:59 +00:00
|
|
|
|
2021-05-06 04:04:43 +00:00
|
|
|
let capabilities = if params.god_mode {
|
|
|
|
naga::valid::Capabilities::all()
|
|
|
|
} else {
|
|
|
|
naga::valid::Capabilities::empty()
|
|
|
|
};
|
2021-02-18 02:46:32 +00:00
|
|
|
|
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
|
|
|
|
2021-02-18 02:46:32 +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();
|
2021-02-18 02:46:32 +00:00
|
|
|
}
|
2021-09-15 00:11:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
let info = naga::valid::Validator::new(naga::valid::ValidationFlags::all(), capabilities)
|
|
|
|
.validate(module)
|
2021-09-28 17:42:26 +00:00
|
|
|
.expect("Naga module validation failed");
|
2021-09-15 00:11:39 +00:00
|
|
|
|
|
|
|
#[cfg(feature = "serialize")]
|
|
|
|
{
|
2021-02-18 02:46:32 +00:00
|
|
|
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();
|
2021-02-18 02:46:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-11-26 17:10:43 +00:00
|
|
|
#[cfg(all(feature = "deserialize", feature = "spv-out"))]
|
2021-02-18 02:46:32 +00:00
|
|
|
{
|
|
|
|
if targets.contains(Targets::SPIRV) {
|
2021-11-26 16:29:35 +00:00
|
|
|
write_output_spv(
|
|
|
|
module,
|
|
|
|
&info,
|
|
|
|
&dest,
|
|
|
|
name,
|
|
|
|
¶ms.spv,
|
|
|
|
params.bounds_check_policies,
|
|
|
|
);
|
2021-02-18 02:46:32 +00:00
|
|
|
}
|
|
|
|
}
|
2021-11-26 17:10:43 +00:00
|
|
|
#[cfg(all(feature = "deserialize", feature = "msl-out"))]
|
2021-02-18 02:46:32 +00:00
|
|
|
{
|
|
|
|
if targets.contains(Targets::METAL) {
|
2021-10-19 16:37:59 +00:00
|
|
|
write_output_msl(
|
|
|
|
module,
|
|
|
|
&info,
|
|
|
|
&dest,
|
|
|
|
name,
|
|
|
|
¶ms.msl,
|
2022-01-18 20:17:59 +00:00
|
|
|
¶ms.msl_pipeline,
|
2021-10-19 16:37:59 +00:00
|
|
|
params.bounds_check_policies,
|
|
|
|
);
|
2021-02-18 02:46:32 +00:00
|
|
|
}
|
|
|
|
}
|
2021-11-26 17:10:43 +00:00
|
|
|
#[cfg(all(feature = "deserialize", feature = "glsl-out"))]
|
2021-02-18 02:46:32 +00:00
|
|
|
{
|
|
|
|
if targets.contains(Targets::GLSL) {
|
2021-03-07 03:47:21 +00:00
|
|
|
for ep in module.entry_points.iter() {
|
2021-11-26 16:29:35 +00:00
|
|
|
if params.glsl_exclude_list.contains(&ep.name) {
|
2021-12-18 01:23:51 +00:00
|
|
|
continue;
|
2021-11-26 16:29:35 +00:00
|
|
|
}
|
2022-05-30 19:13:58 +00:00
|
|
|
write_output_glsl(
|
|
|
|
module,
|
|
|
|
&info,
|
|
|
|
&dest,
|
|
|
|
name,
|
|
|
|
ep.stage,
|
|
|
|
&ep.name,
|
|
|
|
¶ms.glsl,
|
|
|
|
params.bounds_check_policies,
|
2022-06-30 16:58:47 +00:00
|
|
|
params.glsl_multiview,
|
2022-05-30 19:13:58 +00:00
|
|
|
);
|
2021-02-18 02:46:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-03-02 06:28:32 +00:00
|
|
|
#[cfg(feature = "dot-out")]
|
|
|
|
{
|
|
|
|
if targets.contains(Targets::DOT) {
|
2022-06-15 20:02:07 +00:00
|
|
|
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
|
|
|
}
|
|
|
|
}
|
2021-11-26 17:10:43 +00:00
|
|
|
#[cfg(all(feature = "deserialize", feature = "hlsl-out"))]
|
2021-04-11 15:36:26 +00:00
|
|
|
{
|
|
|
|
if targets.contains(Targets::HLSL) {
|
2021-11-26 16:29:35 +00:00
|
|
|
write_output_hlsl(module, &info, &dest, name, ¶ms.hlsl);
|
2021-04-11 15:36:26 +00:00
|
|
|
}
|
|
|
|
}
|
2021-11-26 17:10:43 +00:00
|
|
|
#[cfg(all(feature = "deserialize", feature = "wgsl-out"))]
|
2021-04-19 13:19:03 +00:00
|
|
|
{
|
|
|
|
if targets.contains(Targets::WGSL) {
|
2021-11-26 16:29:35 +00:00
|
|
|
write_output_wgsl(module, &info, &dest, name, ¶ms.wgsl);
|
2021-04-19 13:19:03 +00:00
|
|
|
}
|
|
|
|
}
|
2021-02-18 02:46:32 +00:00
|
|
|
}
|
|
|
|
|
2020-12-11 06:45:28 +00:00
|
|
|
#[cfg(feature = "spv-out")]
|
2021-06-18 22:38:47 +00:00
|
|
|
fn write_output_spv(
|
2021-02-17 19:55:46 +00:00
|
|
|
module: &naga::Module,
|
2021-03-20 05:09:29 +00:00
|
|
|
info: &naga::valid::ModuleInfo,
|
2022-11-03 16:32:15 +00:00
|
|
|
destination: &Path,
|
2021-06-18 22:38:47 +00:00
|
|
|
file_name: &str,
|
2021-11-26 16:29:35 +00:00
|
|
|
params: &SpirvOutParameters,
|
|
|
|
bounds_check_policies: naga::proc::BoundsCheckPolicies,
|
2021-02-17 19:55:46 +00:00
|
|
|
) {
|
2020-12-11 06:45:28 +00:00
|
|
|
use naga::back::spv;
|
|
|
|
use rspirv::binary::Disassemble;
|
|
|
|
|
2021-09-28 17:42:26 +00:00
|
|
|
println!("writing SPIR-V");
|
2021-11-26 16:29:35 +00:00
|
|
|
|
2021-09-08 13:45:02 +00:00
|
|
|
let mut flags = spv::WriterFlags::LABEL_VARYINGS;
|
2021-11-26 16:29:35 +00:00
|
|
|
flags.set(spv::WriterFlags::DEBUG, params.debug);
|
2021-09-08 13:45:02 +00:00
|
|
|
flags.set(
|
|
|
|
spv::WriterFlags::ADJUST_COORDINATE_SPACE,
|
2021-11-26 16:29:35 +00:00
|
|
|
params.adjust_coordinate_space,
|
2021-09-27 23:00:10 +00:00
|
|
|
);
|
2021-11-26 16:29:35 +00:00
|
|
|
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 {
|
2021-11-26 16:29:35 +00:00
|
|
|
lang_version: (params.version.0, params.version.1),
|
2021-04-02 05:12:36 +00:00
|
|
|
flags,
|
2021-11-26 16:29:35 +00:00
|
|
|
capabilities: if params.capabilities.is_empty() {
|
2021-05-19 05:18:27 +00:00
|
|
|
None
|
|
|
|
} else {
|
2021-11-26 16:29:35 +00:00
|
|
|
Some(params.capabilities.clone())
|
2021-08-26 20:45:55 +00:00
|
|
|
},
|
2021-11-26 16:29:35 +00:00
|
|
|
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
|
|
|
};
|
|
|
|
|
2021-11-26 16:29:35 +00:00
|
|
|
if params.separate_entry_points {
|
2021-09-07 14:42:29 +00:00
|
|
|
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-11 06:45:28 +00:00
|
|
|
}
|
|
|
|
|
2020-12-08 05:23:29 +00:00
|
|
|
#[cfg(feature = "msl-out")]
|
2021-06-18 22:38:47 +00:00
|
|
|
fn write_output_msl(
|
2021-02-12 06:39:08 +00:00
|
|
|
module: &naga::Module,
|
2021-03-20 05:09:29 +00:00
|
|
|
info: &naga::valid::ModuleInfo,
|
2022-11-03 16:32:15 +00:00
|
|
|
destination: &Path,
|
2021-06-18 22:38:47 +00:00
|
|
|
file_name: &str,
|
2021-11-26 16:29:35 +00:00
|
|
|
options: &naga::back::msl::Options,
|
2022-01-18 20:17:59 +00:00
|
|
|
pipeline_options: &naga::back::msl::PipelineOptions,
|
2021-10-19 16:37:59 +00:00
|
|
|
bounds_check_policies: naga::proc::BoundsCheckPolicies,
|
2021-02-12 06:39:08 +00:00
|
|
|
) {
|
2020-12-08 05:23:29 +00:00
|
|
|
use naga::back::msl;
|
2020-12-11 06:45:28 +00:00
|
|
|
|
2021-09-28 17:42:26 +00:00
|
|
|
println!("writing MSL");
|
|
|
|
|
2021-10-19 16:37:59 +00:00
|
|
|
let mut options = options.clone();
|
|
|
|
options.bounds_check_policies = bounds_check_policies;
|
2022-04-25 04:17:51 +00:00
|
|
|
let (string, tr_info) = msl::write_string(module, info, &options, pipeline_options)
|
|
|
|
.unwrap_or_else(|err| panic!("Metal write failed: {}", err));
|
2021-04-30 17:38:20 +00:00
|
|
|
|
|
|
|
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-02-07 23:01:58 +00:00
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2020-12-11 06:45:28 +00:00
|
|
|
#[cfg(feature = "glsl-out")]
|
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(
|
2021-02-14 22:26:31 +00:00
|
|
|
module: &naga::Module,
|
2021-03-20 05:09:29 +00:00
|
|
|
info: &naga::valid::ModuleInfo,
|
2022-11-03 16:32:15 +00:00
|
|
|
destination: &Path,
|
2021-06-18 22:38:47 +00:00
|
|
|
file_name: &str,
|
2021-02-14 22:26:31 +00:00
|
|
|
stage: naga::ShaderStage,
|
|
|
|
ep_name: &str,
|
2021-11-26 16:29:35 +00:00
|
|
|
options: &naga::back::glsl::Options,
|
2022-05-30 19:13:58 +00:00
|
|
|
bounds_check_policies: naga::proc::BoundsCheckPolicies,
|
2022-06-30 16:58:47 +00:00
|
|
|
multiview: Option<std::num::NonZeroU32>,
|
2021-02-14 22:26:31 +00:00
|
|
|
) {
|
2020-12-11 06:45:28 +00:00
|
|
|
use naga::back::glsl;
|
|
|
|
|
2021-09-28 17:42:26 +00:00
|
|
|
println!("writing GLSL");
|
|
|
|
|
2021-06-27 04:26:12 +00:00
|
|
|
let pipeline_options = glsl::PipelineOptions {
|
2021-02-18 12:14:04 +00:00
|
|
|
shader_stage: stage,
|
|
|
|
entry_point: ep_name.to_string(),
|
2022-06-30 16:58:47 +00:00
|
|
|
multiview,
|
2020-12-11 06:45:28 +00:00
|
|
|
};
|
|
|
|
|
2021-04-20 11:52:06 +00:00
|
|
|
let mut buffer = String::new();
|
2022-05-30 19:13:58 +00:00
|
|
|
let mut writer = glsl::Writer::new(
|
|
|
|
&mut buffer,
|
|
|
|
module,
|
|
|
|
info,
|
|
|
|
options,
|
|
|
|
&pipeline_options,
|
|
|
|
bounds_check_policies,
|
|
|
|
)
|
|
|
|
.expect("GLSL init failed");
|
2021-09-27 22:49:28 +00:00
|
|
|
writer.write().expect("GLSL write failed");
|
2020-12-11 06:45:28 +00:00
|
|
|
|
2021-06-18 22:38:47 +00:00
|
|
|
fs::write(
|
2021-06-23 16:47:49 +00:00
|
|
|
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
|
|
|
}
|
|
|
|
|
2021-04-11 15:36:26 +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,
|
2022-11-03 16:32:15 +00:00
|
|
|
destination: &Path,
|
2021-06-18 22:38:47 +00:00
|
|
|
file_name: &str,
|
2021-11-26 16:29:35 +00:00
|
|
|
options: &naga::back::hlsl::Options,
|
2021-06-18 22:38:47 +00:00
|
|
|
) {
|
2021-04-11 15:36:26 +00:00
|
|
|
use naga::back::hlsl;
|
2021-11-26 16:29:35 +00:00
|
|
|
use std::fmt::Write as _;
|
2021-07-18 04:10:19 +00:00
|
|
|
|
2021-09-28 17:42:26 +00:00
|
|
|
println!("writing HLSL");
|
|
|
|
|
2021-06-24 10:59:35 +00:00
|
|
|
let mut buffer = String::new();
|
2021-07-18 04:10:19 +00:00
|
|
|
let mut writer = hlsl::Writer::new(&mut buffer, options);
|
2021-09-27 22:49:28 +00:00
|
|
|
let reflection_info = writer.write(module, info).expect("HLSL write failed");
|
2021-04-11 15:36:26 +00:00
|
|
|
|
2021-06-24 10:59:35 +00:00
|
|
|
fs::write(destination.join(format!("hlsl/{}.hlsl", file_name)), buffer).unwrap();
|
2021-04-14 18:20:48 +00:00
|
|
|
|
2021-06-14 21:29:20 +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();
|
2021-07-18 21:10:07 +00:00
|
|
|
let mut vertex_str = String::from("vertex=(");
|
|
|
|
let mut fragment_str = String::from("fragment=(");
|
|
|
|
let mut compute_str = String::from("compute=(");
|
2021-07-05 13:35:48 +00:00
|
|
|
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,
|
|
|
|
};
|
2021-07-18 21:10:07 +00:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
}
|
2021-06-14 21:29:20 +00:00
|
|
|
}
|
2021-07-18 21:10:07 +00:00
|
|
|
|
|
|
|
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();
|
2021-04-11 15:36:26 +00:00
|
|
|
}
|
|
|
|
|
2021-04-19 13:19:03 +00:00
|
|
|
#[cfg(feature = "wgsl-out")]
|
2021-06-18 22:38:47 +00:00
|
|
|
fn write_output_wgsl(
|
|
|
|
module: &naga::Module,
|
|
|
|
info: &naga::valid::ModuleInfo,
|
2022-11-03 16:32:15 +00:00
|
|
|
destination: &Path,
|
2021-06-18 22:38:47 +00:00
|
|
|
file_name: &str,
|
2021-11-26 16:29:35 +00:00
|
|
|
params: &WgslOutParameters,
|
2021-06-18 22:38:47 +00:00
|
|
|
) {
|
2021-04-19 13:19:03 +00:00
|
|
|
use naga::back::wgsl;
|
|
|
|
|
2021-09-28 17:42:26 +00:00
|
|
|
println!("writing WGSL");
|
|
|
|
|
2021-11-26 16:29:35 +00:00
|
|
|
let mut flags = wgsl::WriterFlags::empty();
|
2021-11-26 16:32:00 +00:00
|
|
|
flags.set(wgsl::WriterFlags::EXPLICIT_TYPES, params.explicit_types);
|
2021-11-26 16:29:35 +00:00
|
|
|
|
|
|
|
let string = wgsl::write_string(module, info, flags).expect("WGSL write failed");
|
2021-04-19 13:19:03 +00:00
|
|
|
|
2021-06-18 22:38:47 +00:00
|
|
|
fs::write(destination.join(format!("wgsl/{}.wgsl", file_name)), string).unwrap();
|
2021-04-19 13:19:03 +00:00
|
|
|
}
|
|
|
|
|
2020-12-13 06:20:39 +00:00
|
|
|
#[cfg(feature = "wgsl-in")]
|
|
|
|
#[test]
|
2021-04-14 14:05:48 +00:00
|
|
|
fn convert_wgsl() {
|
2021-07-17 03:09:48 +00:00
|
|
|
let _ = env_logger::try_init();
|
|
|
|
|
2021-04-14 14:05:48 +00:00
|
|
|
let root = env!("CARGO_MANIFEST_DIR");
|
|
|
|
let inputs = [
|
|
|
|
(
|
|
|
|
"empty",
|
2021-04-19 13:19:03 +00:00
|
|
|
Targets::SPIRV | Targets::METAL | Targets::GLSL | Targets::HLSL | Targets::WGSL,
|
2021-04-14 14:05:48 +00:00
|
|
|
),
|
|
|
|
(
|
|
|
|
"quad",
|
2021-06-14 21:29:20 +00:00
|
|
|
Targets::SPIRV
|
|
|
|
| Targets::METAL
|
|
|
|
| Targets::GLSL
|
|
|
|
| Targets::DOT
|
|
|
|
| Targets::HLSL
|
|
|
|
| Targets::WGSL,
|
2021-04-14 14:05:48 +00:00
|
|
|
),
|
2021-10-06 00:32:57 +00:00
|
|
|
(
|
|
|
|
"bits",
|
|
|
|
Targets::SPIRV | Targets::METAL | Targets::GLSL | Targets::WGSL,
|
|
|
|
),
|
2022-06-21 05:25:13 +00:00
|
|
|
(
|
|
|
|
"bitcast",
|
2022-10-20 06:27:30 +00:00
|
|
|
Targets::SPIRV | Targets::METAL | Targets::GLSL | Targets::HLSL | Targets::WGSL,
|
2022-06-21 05:25:13 +00:00
|
|
|
),
|
2021-05-15 22:09:58 +00:00
|
|
|
(
|
|
|
|
"boids",
|
2021-07-25 05:36:38 +00:00
|
|
|
Targets::SPIRV | Targets::METAL | Targets::GLSL | Targets::HLSL | Targets::WGSL,
|
2021-05-15 22:09:58 +00:00
|
|
|
),
|
|
|
|
(
|
|
|
|
"skybox",
|
2021-07-18 02:38:04 +00:00
|
|
|
Targets::SPIRV | Targets::METAL | Targets::GLSL | Targets::HLSL | Targets::WGSL,
|
2021-05-15 22:09:58 +00:00
|
|
|
),
|
2021-04-14 14:05:48 +00:00
|
|
|
(
|
|
|
|
"collatz",
|
2021-07-25 05:36:38 +00:00
|
|
|
Targets::SPIRV
|
|
|
|
| Targets::METAL
|
|
|
|
| Targets::IR
|
|
|
|
| Targets::ANALYSIS
|
|
|
|
| Targets::HLSL
|
|
|
|
| Targets::WGSL,
|
2021-05-15 22:09:58 +00:00
|
|
|
),
|
|
|
|
(
|
|
|
|
"shadow",
|
2021-07-18 05:29:41 +00:00
|
|
|
Targets::SPIRV | Targets::METAL | Targets::GLSL | Targets::HLSL | Targets::WGSL,
|
2021-04-14 14:05:48 +00:00
|
|
|
),
|
2021-07-16 10:08:48 +00:00
|
|
|
(
|
|
|
|
"image",
|
2021-10-04 03:01:44 +00:00
|
|
|
Targets::SPIRV | Targets::METAL | Targets::HLSL | Targets::WGSL | Targets::GLSL,
|
2021-07-16 10:08:48 +00:00
|
|
|
),
|
2021-05-15 22:09:58 +00:00
|
|
|
("extra", Targets::SPIRV | Targets::METAL | Targets::WGSL),
|
2022-08-29 10:58:02 +00:00
|
|
|
("push-constants", Targets::GLSL | Targets::HLSL),
|
2021-05-15 22:09:58 +00:00
|
|
|
(
|
|
|
|
"operators",
|
2021-06-28 19:12:31 +00:00
|
|
|
Targets::SPIRV | Targets::METAL | Targets::GLSL | Targets::HLSL | Targets::WGSL,
|
2021-05-15 22:09:58 +00:00
|
|
|
),
|
2021-12-22 14:41:07 +00:00
|
|
|
(
|
|
|
|
"functions",
|
|
|
|
Targets::SPIRV | Targets::METAL | Targets::GLSL | Targets::HLSL | Targets::WGSL,
|
|
|
|
),
|
|
|
|
("functions-webgl", Targets::GLSL),
|
2021-04-16 20:16:15 +00:00
|
|
|
(
|
|
|
|
"interpolate",
|
2021-07-05 22:30:04 +00:00
|
|
|
Targets::SPIRV | Targets::METAL | Targets::GLSL | Targets::HLSL | Targets::WGSL,
|
2021-04-16 20:16:15 +00:00
|
|
|
),
|
2021-07-24 06:21:54 +00:00
|
|
|
(
|
|
|
|
"access",
|
2021-08-06 05:18:51 +00:00
|
|
|
Targets::SPIRV | Targets::METAL | Targets::GLSL | Targets::HLSL | Targets::WGSL,
|
2021-07-24 06:21:54 +00:00
|
|
|
),
|
2022-12-13 09:47:28 +00:00
|
|
|
("atomicCompareExchange", Targets::SPIRV | Targets::WGSL),
|
2022-04-12 03:34:06 +00:00
|
|
|
(
|
|
|
|
"padding",
|
|
|
|
Targets::SPIRV | Targets::METAL | Targets::GLSL | Targets::HLSL | Targets::WGSL,
|
|
|
|
),
|
2021-09-16 23:03:20 +00:00
|
|
|
("pointers", Targets::SPIRV | Targets::WGSL),
|
2021-05-03 04:18:35 +00:00
|
|
|
(
|
|
|
|
"control-flow",
|
2021-08-27 22:44:57 +00:00
|
|
|
Targets::SPIRV | Targets::METAL | Targets::GLSL | Targets::HLSL | Targets::WGSL,
|
2021-05-15 22:09:58 +00:00
|
|
|
),
|
|
|
|
(
|
|
|
|
"standard",
|
2021-06-28 17:06:53 +00:00
|
|
|
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
|
2021-07-05 10:54:42 +00:00
|
|
|
(
|
|
|
|
"interface",
|
|
|
|
Targets::SPIRV | Targets::METAL | Targets::HLSL | Targets::WGSL,
|
|
|
|
),
|
2021-05-29 01:49:50 +00:00
|
|
|
(
|
|
|
|
"globals",
|
2021-07-18 05:32:10 +00:00
|
|
|
Targets::SPIRV | Targets::METAL | Targets::GLSL | Targets::HLSL | Targets::WGSL,
|
2021-05-29 01:49:50 +00:00
|
|
|
),
|
2021-10-19 16:37:59 +00:00
|
|
|
("bounds-check-zero", Targets::SPIRV | Targets::METAL),
|
2022-02-02 00:37:09 +00:00
|
|
|
("bounds-check-zero-atomic", Targets::METAL),
|
2021-10-19 16:37:59 +00:00
|
|
|
("bounds-check-restrict", Targets::SPIRV | Targets::METAL),
|
2022-02-21 23:08:14 +00:00
|
|
|
(
|
|
|
|
"bounds-check-image-restrict",
|
2022-05-30 19:13:58 +00:00
|
|
|
Targets::SPIRV | Targets::METAL | Targets::GLSL,
|
|
|
|
),
|
|
|
|
(
|
|
|
|
"bounds-check-image-rzsw",
|
|
|
|
Targets::SPIRV | Targets::METAL | Targets::GLSL,
|
2022-02-21 23:08:14 +00:00
|
|
|
),
|
2021-10-19 16:37:59 +00:00
|
|
|
("policy-mix", Targets::SPIRV | Targets::METAL),
|
2021-06-30 16:15:35 +00:00
|
|
|
(
|
|
|
|
"texture-arg",
|
2021-07-24 06:21:54 +00:00
|
|
|
Targets::SPIRV | Targets::METAL | Targets::GLSL | Targets::HLSL | Targets::WGSL,
|
2021-06-30 16:15:35 +00:00
|
|
|
),
|
2021-09-21 15:57:37 +00:00
|
|
|
("cubeArrayShadow", Targets::GLSL),
|
2021-12-27 00:29:33 +00:00
|
|
|
(
|
|
|
|
"math-functions",
|
2021-12-27 02:57:47 +00:00
|
|
|
Targets::SPIRV | Targets::METAL | Targets::GLSL | Targets::HLSL | Targets::WGSL,
|
2021-12-27 00:29:33 +00:00
|
|
|
),
|
2022-04-19 18:23:07 +00:00
|
|
|
("cubeArrayShadow", Targets::GLSL),
|
|
|
|
(
|
|
|
|
"binding-arrays",
|
|
|
|
Targets::WGSL | Targets::HLSL | Targets::METAL | Targets::SPIRV,
|
|
|
|
),
|
2022-06-30 16:58:47 +00:00
|
|
|
("multiview", Targets::SPIRV | Targets::GLSL | Targets::WGSL),
|
|
|
|
("multiview_webgl", Targets::GLSL),
|
2022-06-16 21:45:21 +00:00
|
|
|
(
|
|
|
|
"break-if",
|
|
|
|
Targets::WGSL | Targets::GLSL | Targets::SPIRV | Targets::HLSL | Targets::METAL,
|
|
|
|
),
|
2022-08-06 19:53:04 +00:00
|
|
|
("lexical-scopes", Targets::WGSL),
|
2021-04-14 14:05:48 +00:00
|
|
|
];
|
|
|
|
|
|
|
|
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))
|
2021-04-14 14:05:48 +00:00
|
|
|
.expect("Couldn't find wgsl file");
|
|
|
|
match naga::front::wgsl::parse_str(&file) {
|
|
|
|
Ok(module) => check_targets(&module, name, targets),
|
2021-08-23 02:31:11 +00:00
|
|
|
Err(e) => panic!("{}", e.emit_to_string(&file)),
|
2021-04-14 14:05:48 +00:00
|
|
|
}
|
|
|
|
}
|
2021-02-07 02:02:49 +00:00
|
|
|
}
|
2021-02-08 17:30:21 +00:00
|
|
|
|
|
|
|
#[cfg(feature = "spv-in")]
|
2021-04-02 04:16:11 +00:00
|
|
|
fn convert_spv(name: &str, adjust_coordinate_space: bool, targets: Targets) {
|
2021-07-17 03:09:48 +00:00
|
|
|
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"),
|
2021-04-02 04:16:11 +00:00
|
|
|
&naga::front::spv::Options {
|
|
|
|
adjust_coordinate_space,
|
2021-04-25 22:20:04 +00:00
|
|
|
strict_capabilities: false,
|
2021-09-10 15:51:05 +00:00
|
|
|
block_ctx_dump_prefix: None,
|
2021-04-02 04:16:11 +00:00
|
|
|
},
|
2021-02-08 17:30:21 +00:00
|
|
|
)
|
|
|
|
.unwrap();
|
2021-02-18 02:46:32 +00:00
|
|
|
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
|
|
|
}
|
|
|
|
|
2021-03-27 02:07:40 +00:00
|
|
|
#[cfg(feature = "spv-in")]
|
|
|
|
#[test]
|
2021-11-09 16:53:55 +00:00
|
|
|
fn convert_spv_all() {
|
2021-05-13 05:26:08 +00:00
|
|
|
convert_spv(
|
|
|
|
"quad-vert",
|
|
|
|
false,
|
2021-06-17 21:41:13 +00:00
|
|
|
Targets::METAL | Targets::GLSL | Targets::HLSL | Targets::WGSL,
|
2021-05-13 05:26:08 +00:00
|
|
|
);
|
2021-04-02 04:16:11 +00:00
|
|
|
convert_spv("shadow", true, Targets::IR | Targets::ANALYSIS);
|
2021-08-20 16:11:55 +00:00
|
|
|
convert_spv(
|
|
|
|
"inv-hyperbolic-trig-functions",
|
|
|
|
true,
|
2021-08-20 19:43:17 +00:00
|
|
|
Targets::HLSL | Targets::WGSL,
|
2021-08-20 16:11:55 +00:00
|
|
|
);
|
2021-11-01 18:07:11 +00:00
|
|
|
convert_spv(
|
|
|
|
"empty-global-name",
|
|
|
|
true,
|
|
|
|
Targets::HLSL | Targets::WGSL | Targets::METAL,
|
|
|
|
);
|
2021-11-09 16:53:55 +00:00
|
|
|
convert_spv(
|
|
|
|
"empty-global-name",
|
|
|
|
true,
|
|
|
|
Targets::HLSL | Targets::WGSL | Targets::METAL,
|
|
|
|
);
|
|
|
|
convert_spv("degrees", false, Targets::empty());
|
2021-11-01 18:07:11 +00:00
|
|
|
}
|
|
|
|
|
2022-02-19 10:04:11 +00:00
|
|
|
#[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);
|
|
|
|
}
|
|
|
|
|
2021-06-03 19:34:54 +00:00
|
|
|
#[cfg(feature = "glsl-in")]
|
|
|
|
#[allow(unused_variables)]
|
|
|
|
#[test]
|
|
|
|
fn convert_glsl_folder() {
|
2021-07-17 03:09:48 +00:00
|
|
|
let _ = env_logger::try_init();
|
2021-07-14 16:42:02 +00:00
|
|
|
|
2021-06-03 19:34:54 +00:00
|
|
|
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() {
|
2021-06-03 19:34:54 +00:00
|
|
|
let entry = entry.unwrap();
|
|
|
|
let file_name = entry.file_name().into_string().unwrap();
|
2021-07-14 15:55:58 +00:00
|
|
|
|
2021-06-18 22:38:47 +00:00
|
|
|
if file_name.ends_with(".ron") {
|
|
|
|
// No needed to validate ron files
|
|
|
|
continue;
|
|
|
|
}
|
2021-06-03 19:34:54 +00:00
|
|
|
println!("Processing {}", file_name);
|
|
|
|
|
2021-08-06 15:39:04 +00:00
|
|
|
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(),
|
2021-08-03 23:39:25 +00:00
|
|
|
},
|
2021-08-06 15:39:04 +00:00
|
|
|
&fs::read_to_string(entry.path()).expect("Couldn't find glsl file"),
|
|
|
|
)
|
|
|
|
.unwrap();
|
2021-06-03 19:34:54 +00:00
|
|
|
|
|
|
|
let info = naga::valid::Validator::new(
|
|
|
|
naga::valid::ValidationFlags::all(),
|
|
|
|
naga::valid::Capabilities::all(),
|
|
|
|
)
|
|
|
|
.validate(&module)
|
|
|
|
.unwrap();
|
|
|
|
|
2021-06-17 19:30:47 +00:00
|
|
|
#[cfg(feature = "wgsl-out")]
|
2021-06-18 22:38:47 +00:00
|
|
|
{
|
|
|
|
let dest = PathBuf::from(root).join(BASE_DIR_OUT);
|
2021-11-26 16:29:35 +00:00
|
|
|
write_output_wgsl(
|
|
|
|
&module,
|
|
|
|
&info,
|
|
|
|
&dest,
|
2022-11-03 16:32:15 +00:00
|
|
|
&file_name.replace('.', "-"),
|
2021-11-26 16:29:35 +00:00
|
|
|
&WgslOutParameters::default(),
|
|
|
|
);
|
2021-06-18 22:38:47 +00:00
|
|
|
}
|
2021-06-03 19:34:54 +00:00
|
|
|
}
|
|
|
|
}
|