-
Notifications
You must be signed in to change notification settings - Fork 962
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'trunk' into ad/i64-atomics
- Loading branch information
Showing
4 changed files
with
272 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
mod example_wgsl; | ||
mod snapshots; | ||
mod spirv_capabilities; | ||
mod validation; | ||
mod wgsl_errors; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,230 @@ | ||
use naga::{valid, Expression, Function, Scalar}; | ||
|
||
#[test] | ||
fn emit_atomic_result() { | ||
use naga::{Module, Type, TypeInner}; | ||
|
||
// We want to ensure that the *only* problem with the code is the | ||
// use of an `Emit` statement instead of an `Atomic` statement. So | ||
// validate two versions of the module varying only in that | ||
// aspect. | ||
// | ||
// Looking at uses of the `atomic` makes it easy to identify the | ||
// differences between the two variants. | ||
fn variant( | ||
atomic: bool, | ||
) -> Result<naga::valid::ModuleInfo, naga::WithSpan<naga::valid::ValidationError>> { | ||
let span = naga::Span::default(); | ||
let mut module = Module::default(); | ||
let ty_u32 = module.types.insert( | ||
Type { | ||
name: Some("u32".into()), | ||
inner: TypeInner::Scalar(Scalar::U32), | ||
}, | ||
span, | ||
); | ||
let ty_atomic_u32 = module.types.insert( | ||
Type { | ||
name: Some("atomic<u32>".into()), | ||
inner: TypeInner::Atomic(Scalar::U32), | ||
}, | ||
span, | ||
); | ||
let var_atomic = module.global_variables.append( | ||
naga::GlobalVariable { | ||
name: Some("atomic_global".into()), | ||
space: naga::AddressSpace::WorkGroup, | ||
binding: None, | ||
ty: ty_atomic_u32, | ||
init: None, | ||
}, | ||
span, | ||
); | ||
|
||
let mut fun = Function::default(); | ||
let ex_global = fun | ||
.expressions | ||
.append(Expression::GlobalVariable(var_atomic), span); | ||
let ex_42 = fun | ||
.expressions | ||
.append(Expression::Literal(naga::Literal::U32(42)), span); | ||
let ex_result = fun.expressions.append( | ||
Expression::AtomicResult { | ||
ty: ty_u32, | ||
comparison: false, | ||
}, | ||
span, | ||
); | ||
|
||
if atomic { | ||
fun.body.push( | ||
naga::Statement::Atomic { | ||
pointer: ex_global, | ||
fun: naga::AtomicFunction::Add, | ||
value: ex_42, | ||
result: ex_result, | ||
}, | ||
span, | ||
); | ||
} else { | ||
fun.body.push( | ||
naga::Statement::Emit(naga::Range::new_from_bounds(ex_result, ex_result)), | ||
span, | ||
); | ||
} | ||
|
||
module.functions.append(fun, span); | ||
|
||
valid::Validator::new( | ||
valid::ValidationFlags::default(), | ||
valid::Capabilities::all(), | ||
) | ||
.validate(&module) | ||
} | ||
|
||
variant(true).expect("module should validate"); | ||
assert!(variant(false).is_err()); | ||
} | ||
|
||
#[test] | ||
fn emit_call_result() { | ||
use naga::{Module, Type, TypeInner}; | ||
|
||
// We want to ensure that the *only* problem with the code is the | ||
// use of an `Emit` statement instead of a `Call` statement. So | ||
// validate two versions of the module varying only in that | ||
// aspect. | ||
// | ||
// Looking at uses of the `call` makes it easy to identify the | ||
// differences between the two variants. | ||
fn variant( | ||
call: bool, | ||
) -> Result<naga::valid::ModuleInfo, naga::WithSpan<naga::valid::ValidationError>> { | ||
let span = naga::Span::default(); | ||
let mut module = Module::default(); | ||
let ty_u32 = module.types.insert( | ||
Type { | ||
name: Some("u32".into()), | ||
inner: TypeInner::Scalar(Scalar::U32), | ||
}, | ||
span, | ||
); | ||
|
||
let mut fun_callee = Function { | ||
result: Some(naga::FunctionResult { | ||
ty: ty_u32, | ||
binding: None, | ||
}), | ||
..Function::default() | ||
}; | ||
let ex_42 = fun_callee | ||
.expressions | ||
.append(Expression::Literal(naga::Literal::U32(42)), span); | ||
fun_callee | ||
.body | ||
.push(naga::Statement::Return { value: Some(ex_42) }, span); | ||
let fun_callee = module.functions.append(fun_callee, span); | ||
|
||
let mut fun_caller = Function::default(); | ||
let ex_result = fun_caller | ||
.expressions | ||
.append(Expression::CallResult(fun_callee), span); | ||
|
||
if call { | ||
fun_caller.body.push( | ||
naga::Statement::Call { | ||
function: fun_callee, | ||
arguments: vec![], | ||
result: Some(ex_result), | ||
}, | ||
span, | ||
); | ||
} else { | ||
fun_caller.body.push( | ||
naga::Statement::Emit(naga::Range::new_from_bounds(ex_result, ex_result)), | ||
span, | ||
); | ||
} | ||
|
||
module.functions.append(fun_caller, span); | ||
|
||
valid::Validator::new( | ||
valid::ValidationFlags::default(), | ||
valid::Capabilities::all(), | ||
) | ||
.validate(&module) | ||
} | ||
|
||
variant(true).expect("should validate"); | ||
assert!(variant(false).is_err()); | ||
} | ||
|
||
#[test] | ||
fn emit_workgroup_uniform_load_result() { | ||
use naga::{Module, Type, TypeInner}; | ||
|
||
// We want to ensure that the *only* problem with the code is the | ||
// use of an `Emit` statement instead of an `Atomic` statement. So | ||
// validate two versions of the module varying only in that | ||
// aspect. | ||
// | ||
// Looking at uses of the `wg_load` makes it easy to identify the | ||
// differences between the two variants. | ||
fn variant( | ||
wg_load: bool, | ||
) -> Result<naga::valid::ModuleInfo, naga::WithSpan<naga::valid::ValidationError>> { | ||
let span = naga::Span::default(); | ||
let mut module = Module::default(); | ||
let ty_u32 = module.types.insert( | ||
Type { | ||
name: Some("u32".into()), | ||
inner: TypeInner::Scalar(Scalar::U32), | ||
}, | ||
span, | ||
); | ||
let var_workgroup = module.global_variables.append( | ||
naga::GlobalVariable { | ||
name: Some("workgroup_global".into()), | ||
space: naga::AddressSpace::WorkGroup, | ||
binding: None, | ||
ty: ty_u32, | ||
init: None, | ||
}, | ||
span, | ||
); | ||
|
||
let mut fun = Function::default(); | ||
let ex_global = fun | ||
.expressions | ||
.append(Expression::GlobalVariable(var_workgroup), span); | ||
let ex_result = fun | ||
.expressions | ||
.append(Expression::WorkGroupUniformLoadResult { ty: ty_u32 }, span); | ||
|
||
if wg_load { | ||
fun.body.push( | ||
naga::Statement::WorkGroupUniformLoad { | ||
pointer: ex_global, | ||
result: ex_result, | ||
}, | ||
span, | ||
); | ||
} else { | ||
fun.body.push( | ||
naga::Statement::Emit(naga::Range::new_from_bounds(ex_result, ex_result)), | ||
span, | ||
); | ||
} | ||
|
||
module.functions.append(fun, span); | ||
|
||
valid::Validator::new( | ||
valid::ValidationFlags::default(), | ||
valid::Capabilities::all(), | ||
) | ||
.validate(&module) | ||
} | ||
|
||
variant(true).expect("module should validate"); | ||
assert!(variant(false).is_err()); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters