Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deterministic output #75

Merged
merged 5 commits into from
Feb 2, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "naga_oil"
version = "0.11.0"
version = "0.12.0"
edition = "2021"
license = "MIT OR Apache-2.0"
description = "a crate for combining and manipulating shaders using naga IR"
Expand Down
21 changes: 11 additions & 10 deletions src/compose/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use indexmap::IndexMap;
/// the compose module allows construction of shaders from modules (which are themselves shaders).
///
/// it does this by treating shaders as modules, and
Expand Down Expand Up @@ -235,7 +236,7 @@ pub struct ComposableModule {
pub virtual_functions: HashSet<String>,
// overriding functions defined in this module
// target function -> Vec<replacement functions>
pub override_functions: HashMap<String, Vec<String>>,
pub override_functions: IndexMap<String, Vec<String>>,
// naga module, built against headers for any imports
module_ir: naga::Module,
// headers in different shader languages, used for building modules/shaders that import this module
Expand Down Expand Up @@ -397,7 +398,7 @@ const DECORATION_OVERRIDE_PRE: &str = "X_naga_oil_vrt_X";
struct IrBuildResult {
module: naga::Module,
start_offset: usize,
override_functions: HashMap<String, Vec<String>>,
override_functions: IndexMap<String, Vec<String>>,
}

impl Composer {
Expand Down Expand Up @@ -583,7 +584,7 @@ impl Composer {
ShaderLanguage::Glsl => String::from("#version 450\n"),
};

let mut override_functions: HashMap<String, Vec<String>> = HashMap::default();
let mut override_functions: IndexMap<String, Vec<String>> = IndexMap::default();
let mut added_imports: HashSet<String> = HashSet::new();
let mut header_module = DerivedModule::default();

Expand Down Expand Up @@ -611,7 +612,7 @@ impl Composer {
if !module.override_functions.is_empty() {
for (original, replacements) in &module.override_functions {
match override_functions.entry(original.clone()) {
Entry::Occupied(o) => {
indexmap::map::Entry::Occupied(o) => {
let existing = o.into_mut();
let new_replacements: Vec<_> = replacements
.iter()
Expand All @@ -620,7 +621,7 @@ impl Composer {
.collect();
existing.extend(new_replacements);
}
Entry::Vacant(v) => {
indexmap::map::Entry::Vacant(v) => {
v.insert(replacements.clone());
}
}
Expand Down Expand Up @@ -723,7 +724,7 @@ impl Composer {
})?,
};

let recompiled_types: HashMap<_, _> = recompiled
let recompiled_types: IndexMap<_, _> = recompiled
.types
.iter()
.flat_map(|(h, ty)| ty.name.as_deref().map(|name| (name, h)))
Expand Down Expand Up @@ -869,7 +870,7 @@ impl Composer {
});

// record and rename override functions
let mut local_override_functions: HashMap<String, String> = Default::default();
let mut local_override_functions: IndexMap<String, String> = Default::default();

#[cfg(not(feature = "override_any"))]
let mut override_error = None;
Expand Down Expand Up @@ -992,7 +993,7 @@ impl Composer {
}

// rename and record owned items (except types which can't be mutably accessed)
let mut owned_constants = HashMap::new();
let mut owned_constants = IndexMap::new();
for (h, c) in source_ir.constants.iter_mut() {
if let Some(name) = c.name.as_mut() {
if !name.contains(DECORATION_PRE) {
Expand All @@ -1002,7 +1003,7 @@ impl Composer {
}
}

let mut owned_vars = HashMap::new();
let mut owned_vars = IndexMap::new();
for (h, gv) in source_ir.global_variables.iter_mut() {
if let Some(name) = gv.name.as_mut() {
if !name.contains(DECORATION_PRE) {
Expand All @@ -1013,7 +1014,7 @@ impl Composer {
}
}

let mut owned_functions = HashMap::new();
let mut owned_functions = IndexMap::new();
for (h_f, f) in source_ir.functions.iter_mut() {
if let Some(name) = f.name.as_mut() {
if !name.contains(DECORATION_PRE) {
Expand Down
34 changes: 17 additions & 17 deletions src/compose/parse_imports.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::collections::HashMap;
use indexmap::IndexMap;

use super::{
tokenizer::{Token, Tokenizer},
Expand All @@ -7,7 +7,7 @@ use super::{

pub fn parse_imports<'a>(
input: &'a str,
declared_imports: &mut HashMap<String, Vec<String>>,
declared_imports: &mut IndexMap<String, Vec<String>>,
) -> Result<(), (&'a str, usize)> {
let mut tokens = Tokenizer::new(input, false).peekable();

Expand Down Expand Up @@ -116,8 +116,8 @@ pub fn parse_imports<'a>(
pub fn substitute_identifiers(
input: &str,
offset: usize,
declared_imports: &HashMap<String, Vec<String>>,
used_imports: &mut HashMap<String, ImportDefWithOffset>,
declared_imports: &IndexMap<String, Vec<String>>,
used_imports: &mut IndexMap<String, ImportDefWithOffset>,
allow_ambiguous: bool,
) -> Result<String, usize> {
let tokens = Tokenizer::new(input, true);
Expand Down Expand Up @@ -193,8 +193,8 @@ pub fn substitute_identifiers(
}

#[cfg(test)]
fn test_parse(input: &str) -> Result<HashMap<String, Vec<String>>, (&str, usize)> {
let mut declared_imports = HashMap::default();
fn test_parse(input: &str) -> Result<IndexMap<String, Vec<String>>, (&str, usize)> {
let mut declared_imports = IndexMap::default();
parse_imports(input, &mut declared_imports)?;
Ok(declared_imports)
}
Expand All @@ -206,7 +206,7 @@ fn import_tokens() {
";
assert_eq!(
test_parse(input),
Ok(HashMap::from_iter([(
Ok(IndexMap::from_iter([(
"b".to_owned(),
vec!("a::b".to_owned())
)]))
Expand All @@ -217,7 +217,7 @@ fn import_tokens() {
";
assert_eq!(
test_parse(input),
Ok(HashMap::from_iter([
Ok(IndexMap::from_iter([
("b".to_owned(), vec!("a::b".to_owned())),
("c".to_owned(), vec!("a::c".to_owned())),
]))
Expand All @@ -228,7 +228,7 @@ fn import_tokens() {
";
assert_eq!(
test_parse(input),
Ok(HashMap::from_iter([
Ok(IndexMap::from_iter([
("d".to_owned(), vec!("a::b".to_owned())),
("c".to_owned(), vec!("a::c".to_owned())),
]))
Expand All @@ -239,7 +239,7 @@ fn import_tokens() {
";
assert_eq!(
test_parse(input),
Ok(HashMap::from_iter([
Ok(IndexMap::from_iter([
("c".to_owned(), vec!("a::b::c".to_owned())),
("d".to_owned(), vec!("a::b::d".to_owned())),
("e".to_owned(), vec!("a::e".to_owned())),
Expand All @@ -251,7 +251,7 @@ fn import_tokens() {
";
assert_eq!(
test_parse(input),
Ok(HashMap::from_iter([
Ok(IndexMap::from_iter([
("c".to_owned(), vec!("a::b::c".to_owned())),
("d".to_owned(), vec!("a::b::d".to_owned())),
("e".to_owned(), vec!("e".to_owned())),
Expand All @@ -263,7 +263,7 @@ fn import_tokens() {
";
assert_eq!(
test_parse(input),
Ok(HashMap::from_iter([
Ok(IndexMap::from_iter([
("a".to_owned(), vec!("a".to_owned())),
("b".to_owned(), vec!("b".to_owned())),
]))
Expand All @@ -274,7 +274,7 @@ fn import_tokens() {
";
assert_eq!(
test_parse(input),
Ok(HashMap::from_iter([
Ok(IndexMap::from_iter([
("c".to_owned(), vec!("a::b::c".to_owned())),
("d".to_owned(), vec!("a::b::d".to_owned())),
]))
Expand All @@ -285,7 +285,7 @@ fn import_tokens() {
";
assert_eq!(
test_parse(input),
Ok(HashMap::from_iter([(
Ok(IndexMap::from_iter([(
"c".to_owned(),
vec!("a::b::c".to_owned())
),]))
Expand All @@ -296,7 +296,7 @@ fn import_tokens() {
";
assert_eq!(
test_parse(input),
Ok(HashMap::from_iter([
Ok(IndexMap::from_iter([
("d".to_owned(), vec!("a::b::c::d".to_owned())),
("e".to_owned(), vec!("a::b::c::e".to_owned())),
("f".to_owned(), vec!("a::b::f".to_owned())),
Expand All @@ -317,7 +317,7 @@ fn import_tokens() {
";
assert_eq!(
test_parse(input),
Ok(HashMap::from_iter([
Ok(IndexMap::from_iter([
("d".to_owned(), vec!("a::b::c::d".to_owned())),
("e".to_owned(), vec!("a::b::c::e".to_owned())),
("f".to_owned(), vec!("a::b::f".to_owned())),
Expand All @@ -331,7 +331,7 @@ fn import_tokens() {
"#;
assert_eq!(
test_parse(input),
Ok(HashMap::from_iter([
Ok(IndexMap::from_iter([
(
"a".to_owned(),
vec!(r#""path//with\ all sorts of .stuff"::a"#.to_owned())
Expand Down
9 changes: 5 additions & 4 deletions src/compose/preprocess.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use std::collections::{HashMap, HashSet};

use indexmap::IndexMap;
use regex::Regex;

use super::{
Expand Down Expand Up @@ -234,8 +235,8 @@ impl Preprocessor {
shader_defs: &HashMap<String, ShaderDefValue>,
validate_len: bool,
) -> Result<PreprocessOutput, ComposerErrorInner> {
let mut declared_imports = HashMap::new();
let mut used_imports = HashMap::new();
let mut declared_imports = IndexMap::new();
let mut used_imports = IndexMap::new();
let mut scope = Scope::new();
let mut final_string = String::new();
let mut offset = 0;
Expand Down Expand Up @@ -390,8 +391,8 @@ impl Preprocessor {
shader_str: &str,
allow_defines: bool,
) -> Result<PreprocessorMetaData, ComposerErrorInner> {
let mut declared_imports = HashMap::default();
let mut used_imports = HashMap::default();
let mut declared_imports = IndexMap::default();
let mut used_imports = IndexMap::default();
let mut name = None;
let mut offset = 0;
let mut defines = HashMap::default();
Expand Down
26 changes: 1 addition & 25 deletions src/compose/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,6 @@ mod test {
naga::back::wgsl::WriterFlags::EXPLICIT_TYPES,
)
.unwrap();
let mut wgsl: Vec<_> = wgsl.lines().collect();
wgsl.sort();
let wgsl = wgsl.join("\n");

// println!("{}", wgsl);
// let mut f = std::fs::File::create("dup_import.txt").unwrap();
Expand Down Expand Up @@ -338,21 +335,11 @@ mod test {
)
.unwrap();

// unfortunately glsl variables are emitted in random order...
// so this is better than nothing
let mut wgsl: Vec<_> = wgsl.lines().collect();
wgsl.sort();
let wgsl = wgsl.join("\n");

// let mut f = std::fs::File::create("wgsl_call_glsl.txt").unwrap();
// f.write_all(wgsl.as_bytes()).unwrap();
// drop(f);

// assert_eq!(wgsl, include_str!("tests/expected/wgsl_call_glsl.txt"));

// actually it's worse than that ... glsl output seems volatile over struct names
// i suppose at least we are testing that it doesn't throw any errors ..?
let _ = wgsl;
output_eq!(wgsl, "tests/expected/wgsl_call_glsl.txt");
}

#[cfg(feature = "glsl")]
Expand Down Expand Up @@ -852,11 +839,6 @@ mod test {
)
.unwrap();

// println!("{}", wgsl);
let mut wgsl = wgsl.lines().collect::<Vec<_>>();
wgsl.sort();
let wgsl = wgsl.join("\n");

// let mut f = std::fs::File::create("item_import_test.txt").unwrap();
// f.write_all(wgsl.as_bytes()).unwrap();
// drop(f);
Expand Down Expand Up @@ -923,9 +905,6 @@ mod test {
naga::back::wgsl::WriterFlags::EXPLICIT_TYPES,
)
.unwrap();
let mut wgsl: Vec<_> = wgsl.lines().collect();
wgsl.sort();
let wgsl = wgsl.join("\n");

// let mut f = std::fs::File::create("bad_identifiers.txt").unwrap();
// f.write_all(wgsl.as_bytes()).unwrap();
Expand Down Expand Up @@ -992,9 +971,6 @@ mod test {
naga::back::wgsl::WriterFlags::EXPLICIT_TYPES,
)
.unwrap();
let mut wgsl: Vec<_> = wgsl.lines().collect();
wgsl.sort();
let wgsl = wgsl.join("\n");

// let mut f = std::fs::File::create("dup_struct_import.txt").unwrap();
// f.write_all(wgsl.as_bytes()).unwrap();
Expand Down
50 changes: 25 additions & 25 deletions src/compose/tests/expected/bad_identifiers.txt
Original file line number Diff line number Diff line change
@@ -1,39 +1,39 @@
struct IsFineX_naga_oil_mod_XON2HE5LDORZQX {
fine: f32,
}

struct Isbad_X_naga_oil_mod_XON2HE5LDORZQX {
fine_member: f32,
}

const fineX_naga_oil_mod_XMNXW443UOMX: f32 = 1f;
const bad_X_naga_oil_mod_XMNXW443UOMX: f32 = 1f;

var<private> fineX_naga_oil_mod_XM5WG6YTBNRZQX: f32 = 1f;
var<private> bad_X_naga_oil_mod_XM5WG6YTBNRZQX: f32 = 1f;

fn fineX_naga_oil_mod_XMZXHGX(in: f32) -> f32 {
return in;
}

fn bad_X_naga_oil_mod_XMZXHGX(in_1: f32) -> f32 {
return in_1;
}

fn main() -> f32 {
var d: IsFineX_naga_oil_mod_XON2HE5LDORZQX;
var e: Isbad_X_naga_oil_mod_XON2HE5LDORZQX;


d.fine = 3f;
e.fine_member = 4f;
fine: f32,
fine_member: f32,
let _e1: f32 = fineX_naga_oil_mod_XMZXHGX(1f);
let _e20: f32 = d.fine;
let _e23: f32 = e.fine_member;
let _e3: f32 = bad_X_naga_oil_mod_XMZXHGX(2f);
let b: f32 = (_e1 + _e3);
let _e6: f32 = fineX_naga_oil_mod_XM5WG6YTBNRZQX;
let _e8: f32 = bad_X_naga_oil_mod_XM5WG6YTBNRZQX;
let b: f32 = (_e1 + _e3);
let c: f32 = (_e6 + _e8);
d.fine = 3f;
e.fine_member = 4f;
let _e20: f32 = d.fine;
let _e23: f32 = e.fine_member;
return ((((2f + b) + c) + _e20) + _e23);
return in;
return in_1;
var d: IsFineX_naga_oil_mod_XON2HE5LDORZQX;
var e: Isbad_X_naga_oil_mod_XON2HE5LDORZQX;
const bad_X_naga_oil_mod_XMNXW443UOMX: f32 = 1f;
const fineX_naga_oil_mod_XMNXW443UOMX: f32 = 1f;
fn bad_X_naga_oil_mod_XMZXHGX(in_1: f32) -> f32 {
fn fineX_naga_oil_mod_XMZXHGX(in: f32) -> f32 {
fn main() -> f32 {
struct IsFineX_naga_oil_mod_XON2HE5LDORZQX {
struct Isbad_X_naga_oil_mod_XON2HE5LDORZQX {
var<private> bad_X_naga_oil_mod_XM5WG6YTBNRZQX: f32 = 1f;
var<private> fineX_naga_oil_mod_XM5WG6YTBNRZQX: f32 = 1f;
}
}
}
}
}

Loading
Loading