Skip to content

Commit

Permalink
wgsl-in <-> msl-out are working and tests are passing!
Browse files Browse the repository at this point in the history
try via
```
cargo nextest run -p naga --no-default-features --features wgsl-in,msl-out,validate,span,serialize,deserialize
```
  • Loading branch information
teoxoy committed Mar 22, 2023
1 parent 4f9f418 commit f80a43d
Show file tree
Hide file tree
Showing 34 changed files with 1,115 additions and 1,518 deletions.
89 changes: 31 additions & 58 deletions src/back/msl/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,6 @@ impl<'a> Display for TypeContext<'a> {
{
write!(out, "{NAMESPACE}::array<{base_tyname}, {override_size}>")
} else if let crate::ArraySize::Constant(size) = size {
let size = self.gctx.to_array_length(size).unwrap();
write!(out, "{NAMESPACE}::array<{base_tyname}, {size}>")
} else {
unreachable!("metal requires all arrays be constant sized");
Expand Down Expand Up @@ -1273,12 +1272,12 @@ impl<W: Write> Writer<W> {
self.put_expression_stack_pointers
.insert(&expr_handle as *const _ as *const ());

if let Some(name) = self.named_expressions.get(&expr_handle) {
write!(self.out, "{name}")?;
return Ok(());
}

let expression = if let Some(ctx) = context {
if let Some(name) = self.named_expressions.get(&expr_handle) {
write!(self.out, "{name}")?;
return Ok(());
}

&ctx.function.expressions[expr_handle]
} else {
&module.const_expressions[expr_handle]
Expand Down Expand Up @@ -1361,8 +1360,16 @@ impl<W: Write> Writer<W> {
crate::Expression::Constant(handle) => {
write!(self.out, "{}", self.names[&NameKey::Constant(handle)])?;
}
crate::Expression::New(_) => {
write!(self.out, "{{}}")?;
crate::Expression::New(ty) => {
let ty_name = TypeContext {
handle: ty,
gctx: module.to_ctx(),
names: &self.names,
access: crate::StorageAccess::empty(),
binding: None,
first_time: false,
};
write!(self.out, "{ty_name} {{}}")?;
}
crate::Expression::Compose { ty, ref components } => {
self.put_compose(ty, components, module, context)?;
Expand Down Expand Up @@ -1430,14 +1437,13 @@ impl<W: Write> Writer<W> {

self.put_image_sample_level(image, level, module, context)?;

// TODO: offset & gather are no longer in const_expressions
if let Some(offset) = offset {
write!(self.out, ", ")?;
self.put_expression(offset, module, None, false)?;
}

match gather {
None => {}
None | Some(crate::SwizzleComponent::X) => {}
Some(component) => {
let is_cube_map = match *resolve_type(image, module, context) {
crate::TypeInner::Image {
Expand All @@ -1451,8 +1457,7 @@ impl<W: Write> Writer<W> {
if offset.is_none() && !is_cube_map {
write!(self.out, ", {NAMESPACE}::int2(0)")?;
}
let letter = back::COMPONENTS
[module.to_ctx().to_array_length(component).unwrap() as usize];
let letter = back::COMPONENTS[component as usize];
write!(self.out, ", {NAMESPACE}::component::{letter}")?;
}
}
Expand Down Expand Up @@ -2237,15 +2242,10 @@ impl<W: Write> Writer<W> {
module: &crate::Module,
context: Option<&ExpressionContext>,
) -> BackendResult {
let is_atomic = match *resolve_type(pointer, module, context) {
crate::TypeInner::Pointer { base, .. } => match module.types[base].inner {
crate::TypeInner::Atomic { .. } => true,
_ => false,
},
_ => false,
};
let is_atomic_pointer =
resolve_type(pointer, module, context).is_atomic_pointer(&module.types);

if is_atomic {
if is_atomic_pointer {
write!(
self.out,
"{NAMESPACE}::atomic_load_explicit({ATOMIC_REFERENCE}"
Expand Down Expand Up @@ -2311,13 +2311,12 @@ impl<W: Write> Writer<W> {
// to convert from a wrapped struct to a raw array, e.g.
// `float gl_ClipDistance1 [[clip_distance]] [1];`.
if let crate::TypeInner::Array {
size: crate::ArraySize::Constant(const_handle),
size: crate::ArraySize::Constant(size),
..
} = module.types[member.ty].inner
{
let size = module.to_ctx().to_array_length(const_handle).unwrap();
write!(self.out, "{comma} {{")?;
for j in 0..size {
for j in 0..size.get() {
if j != 0 {
write!(self.out, ",")?;
}
Expand Down Expand Up @@ -2940,32 +2939,10 @@ impl<W: Write> Writer<W> {
level: back::Level,
context: &StatementContext,
) -> BackendResult {
let pointer_inner = resolve_type(pointer, context.module, Some(&context.expression));
let (array_size, is_atomic) = match *pointer_inner {
crate::TypeInner::Pointer { base, .. } => match context.module.types[base].inner {
crate::TypeInner::Array {
size: crate::ArraySize::Constant(ch),
..
} => (Some(ch), false),
crate::TypeInner::Atomic { .. } => (None, true),
_ => (None, false),
},
_ => (None, false),
};
let is_atomic_pointer = resolve_type(pointer, context.module, Some(&context.expression))
.is_atomic_pointer(&context.module.types);

// we can't assign fixed-size arrays
if let Some(const_handle) = array_size {
let size = context
.module
.to_ctx()
.to_array_length(const_handle)
.unwrap();
write!(self.out, "{level}for(int _i=0; _i<{size}; ++_i) ")?;
self.put_access_chain(pointer, policy, context.module, Some(&context.expression))?;
write!(self.out, ".{WRAPPED_ARRAY_FIELD}[_i] = ")?;
self.put_expression(value, context.module, Some(&context.expression), true)?;
writeln!(self.out, ".{WRAPPED_ARRAY_FIELD}[_i];")?;
} else if is_atomic {
if is_atomic_pointer {
write!(
self.out,
"{level}{NAMESPACE}::atomic_store_explicit({ATOMIC_REFERENCE}"
Expand Down Expand Up @@ -3099,15 +3076,15 @@ impl<W: Write> Writer<W> {
};

match size {
crate::ArraySize::Constant(const_handle) => {
crate::ArraySize::Constant(size) => {
writeln!(self.out, "struct {name} {{")?;
writeln!(
self.out,
"{}{} {}[{}];",
back::INDENT,
base_name,
WRAPPED_ARRAY_FIELD,
module.to_ctx().to_array_length(const_handle).unwrap()
size
)?;
writeln!(self.out, "}};")?;
}
Expand Down Expand Up @@ -3203,13 +3180,9 @@ impl<W: Write> Writer<W> {
first_time: false,
};
let name = &self.names[&NameKey::Constant(handle)];
write!(self.out, "constexpr constant {ty_name} {name} = ")?;
write!(self.out, "constant {ty_name} {name} = ")?;
self.put_expression(constant.init.unwrap(), module, None, false)?;
}

if !module.constants.is_empty() {
// Add extra newline for readability
writeln!(self.out)?;
writeln!(self.out, ";")?;
}

Ok(())
Expand Down Expand Up @@ -3652,9 +3625,9 @@ impl<W: Write> Writer<W> {

let array_len = match module.types[ty].inner {
crate::TypeInner::Array {
size: crate::ArraySize::Constant(handle),
size: crate::ArraySize::Constant(size),
..
} => module.to_ctx().to_array_length(handle),
} => Some(size),
_ => None,
};
let resolved = options.resolve_local_binding(binding, out_mode)?;
Expand Down
26 changes: 9 additions & 17 deletions src/back/wgsl/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -707,14 +707,12 @@ impl<W: Write> Writer<W> {
Statement::Store { pointer, value } => {
write!(self.out, "{level}")?;

let is_atomic = match *func_ctx.info[pointer].ty.inner_with(&module.types) {
crate::TypeInner::Pointer { base, .. } => match module.types[base].inner {
crate::TypeInner::Atomic { .. } => true,
_ => false,
},
_ => false,
};
if is_atomic {
let is_atomic_pointer = func_ctx.info[pointer]
.ty
.inner_with(&module.types)
.is_atomic_pointer(&module.types);

if is_atomic_pointer {
write!(self.out, "atomicStore(")?;
self.write_expr(module, pointer, Some(func_ctx))?;
write!(self.out, ", ")?;
Expand Down Expand Up @@ -1446,18 +1444,12 @@ impl<W: Write> Writer<W> {
write!(self.out, ")")?;
}
Expression::Load { pointer } => {
let is_atomic = match *func_ctx.expect("non-global context").info[pointer]
let is_atomic_pointer = func_ctx.expect("non-global context").info[pointer]
.ty
.inner_with(&module.types)
{
crate::TypeInner::Pointer { base, .. } => match module.types[base].inner {
crate::TypeInner::Atomic { .. } => true,
_ => false,
},
_ => false,
};
.is_atomic_pointer(&module.types);

if is_atomic {
if is_atomic_pointer {
write!(self.out, "atomicLoad(")?;
self.write_expr(module, pointer, func_ctx)?;
write!(self.out, ")")?;
Expand Down
13 changes: 13 additions & 0 deletions src/front/wgsl/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,8 @@ pub enum Error<'a> {
},
FunctionReturnsVoid(Span),
Other,
ExpectedArraySize(Span),
NonPositiveArrayLength(Span),
}

impl<'a> Error<'a> {
Expand Down Expand Up @@ -679,6 +681,17 @@ impl<'a> Error<'a> {
labels: vec![],
notes: vec![],
},
Error::ExpectedArraySize(span) => ParseError {
message: "array element count must resolve to an integer scalar (u32, i32)"
.to_string(),
labels: vec![(span, "must resolve to u32/i32".into())],
notes: vec![],
},
Error::NonPositiveArrayLength(span) => ParseError {
message: "array element count must be positive".to_string(),
labels: vec![(span, "must be positive".into())],
notes: vec![],
},
}
}
}
14 changes: 7 additions & 7 deletions src/front/wgsl/lower/construction.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::num::NonZeroU32;

use crate::front::wgsl::parse::ast;
use crate::{Handle, Span};

Expand Down Expand Up @@ -452,14 +454,11 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {

let base = ctx.register_type(components[0])?;

let size_expr = ctx.module.const_expressions.append(
crate::Expression::Literal(crate::Literal::U32(components.len() as _)),
span,
);

let inner = crate::TypeInner::Array {
base,
size: crate::ArraySize::Constant(size_expr),
size: crate::ArraySize::Constant(
NonZeroU32::new(u32::try_from(components.len()).unwrap()).unwrap(),
),
stride: {
self.layouter.update(ctx.module.to_ctx()).unwrap();
self.layouter[base].to_stride()
Expand Down Expand Up @@ -583,7 +582,8 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
let base = self.resolve_ast_type(base, ctx.as_global())?;
let size = match size {
ast::ArraySize::Constant(expr) => {
crate::ArraySize::Constant(self.expression(expr, ctx.as_const())?)
let const_expr = self.expression(expr, ctx.as_const())?;
crate::ArraySize::Constant(ctx.array_length(const_expr)?)
}
ast::ArraySize::Dynamic => crate::ArraySize::Dynamic,
};
Expand Down
Loading

0 comments on commit f80a43d

Please sign in to comment.