Skip to content

Commit

Permalink
[naga] implement pointer_composite_access WGSL language extension (#…
Browse files Browse the repository at this point in the history
…6913)

Co-authored-by: Erich Gubler <[email protected]>
  • Loading branch information
sagudev and ErichDonGubler authored Jan 23, 2025
1 parent a8bd1fe commit 04aff59
Show file tree
Hide file tree
Showing 18 changed files with 2,138 additions and 499 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ By @ErichDonGubler in [#6456](https://github.com/gfx-rs/wgpu/pull/6456), [#6148]
- Add support for OpAtomicCompareExchange in SPIR-V frontend. By @schell in [#6590](https://github.com/gfx-rs/wgpu/pull/6590).
- Implement type inference for abstract arguments to user-defined functions. By @jamienicol in [#6577](https://github.com/gfx-rs/wgpu/pull/6577).
- Allow for override-expressions in array sizes. By @KentSlaney in [#6654](https://github.com/gfx-rs/wgpu/pull/6654).
- [`pointer_composite_access` WGSL language extension](https://www.w3.org/TR/WGSL/#language_extension-pointer_composite_access) is implemented. By @sagudev in [#6913](https://github.com/gfx-rs/wgpu/pull/6913)

##### General

Expand Down
6 changes: 0 additions & 6 deletions naga/src/front/wgsl/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,6 @@ pub(crate) enum Error<'a> {
InvalidAtomicPointer(Span),
InvalidAtomicOperandType(Span),
InvalidRayQueryPointer(Span),
Pointer(&'static str, Span),
NotPointer(Span),
NotReference(&'static str, Span),
InvalidAssignment {
Expand Down Expand Up @@ -719,11 +718,6 @@ impl<'a> Error<'a> {
notes,
}
}
Error::Pointer(what, span) => ParseError {
message: format!("{what} must not be a pointer"),
labels: vec![(span, "expression is a pointer".into())],
notes: vec![],
},
Error::ReservedKeyword(name_span) => ParseError {
message: format!("name `{}` is a reserved keyword", &source[name_span]),
labels: vec![(
Expand Down
30 changes: 14 additions & 16 deletions naga/src/front/wgsl/lower/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1998,15 +1998,14 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
return Ok(Typed::Plain(handle));
}
ast::Expression::Index { base, index } => {
let lowered_base = self.expression_for_reference(base, ctx)?;
let mut lowered_base = self.expression_for_reference(base, ctx)?;
let index = self.expression(index, ctx)?;

// <https://www.w3.org/TR/WGSL/#language_extension-pointer_composite_access>
// Declare pointer as reference
if let Typed::Plain(handle) = lowered_base {
if resolve_inner!(ctx, handle).pointer_space().is_some() {
return Err(Error::Pointer(
"the value indexed by a `[]` subscripting expression",
ctx.ast_expressions.get_span(base),
));
lowered_base = Typed::Reference(handle);
}
}

Expand All @@ -2016,7 +2015,15 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
})
}
ast::Expression::Member { base, ref field } => {
let lowered_base = self.expression_for_reference(base, ctx)?;
let mut lowered_base = self.expression_for_reference(base, ctx)?;

// <https://www.w3.org/TR/WGSL/#language_extension-pointer_composite_access>
// Declare pointer as reference
if let Typed::Plain(handle) = lowered_base {
if resolve_inner!(ctx, handle).pointer_space().is_some() {
lowered_base = Typed::Reference(handle);
}
}

let temp_inner;
let composite_type: &crate::TypeInner = match lowered_base {
Expand Down Expand Up @@ -2045,16 +2052,7 @@ impl<'source, 'temp> Lowerer<'source, 'temp> {
}

Typed::Plain(handle) => {
let inner = resolve_inner!(ctx, handle);
if let crate::TypeInner::Pointer { .. }
| crate::TypeInner::ValuePointer { .. } = *inner
{
return Err(Error::Pointer(
"the value accessed by a `.member` expression",
ctx.ast_expressions.get_span(base),
));
}
inner
resolve_inner!(ctx, handle)
}
};

Expand Down
17 changes: 9 additions & 8 deletions naga/src/front/wgsl/parse/directive/language_extension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ impl LanguageExtension {
Self::Unimplemented(UnimplementedLanguageExtension::UnrestrictedPointerParameters)
}
Self::POINTER_COMPOSITE_ACCESS => {
Self::Unimplemented(UnimplementedLanguageExtension::PointerCompositeAccess)
Self::Implemented(ImplementedLanguageExtension::PointerCompositeAccess)
}
_ => return None,
})
Expand All @@ -54,17 +54,16 @@ impl LanguageExtension {
UnimplementedLanguageExtension::UnrestrictedPointerParameters => {
Self::UNRESTRICTED_POINTER_PARAMETERS
}
UnimplementedLanguageExtension::PointerCompositeAccess => {
Self::POINTER_COMPOSITE_ACCESS
}
},
}
}
}

/// A variant of [`LanguageExtension::Implemented`].
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, VariantArray)]
pub enum ImplementedLanguageExtension {}
pub enum ImplementedLanguageExtension {
PointerCompositeAccess,
}

impl ImplementedLanguageExtension {
/// Returns slice of all variants of [`ImplementedLanguageExtension`].
Expand All @@ -74,7 +73,11 @@ impl ImplementedLanguageExtension {

/// Maps this [`ImplementedLanguageExtension`] into the sentinel word associated with it in WGSL.
pub const fn to_ident(self) -> &'static str {
match self {}
match self {
ImplementedLanguageExtension::PointerCompositeAccess => {
LanguageExtension::POINTER_COMPOSITE_ACCESS
}
}
}
}

Expand All @@ -84,7 +87,6 @@ pub enum UnimplementedLanguageExtension {
ReadOnlyAndReadWriteStorageTextures,
Packed4x8IntegerDotProduct,
UnrestrictedPointerParameters,
PointerCompositeAccess,
}

impl UnimplementedLanguageExtension {
Expand All @@ -93,7 +95,6 @@ impl UnimplementedLanguageExtension {
Self::ReadOnlyAndReadWriteStorageTextures => 6204,
Self::Packed4x8IntegerDotProduct => 6445,
Self::UnrestrictedPointerParameters => 5158,
Self::PointerCompositeAccess => 6192,
}
}
}
44 changes: 44 additions & 0 deletions naga/tests/in/access.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -198,3 +198,47 @@ fn assign_to_ptr_components() {
assign_to_arg_ptr_array_element(&a1);
fetch_arg_ptr_array_element(&a1);
}

fn index_ptr(value: bool) -> bool {
var a = array<bool, 1>(value);
let p = &a;
return p[0];
}

struct S { m: i32 };

fn member_ptr() -> i32 {
var s: S = S(42);
let p = &s;
return p.m;
}

struct Inner { delicious: i32 }

struct Outer { om_nom_nom: Inner, thing: u32 }

fn let_members_of_members() -> i32 {
let thing = Outer();

let inner = thing.om_nom_nom;
let delishus = inner.delicious;

if (thing.thing != u32(delishus)) {
// LOL
}

return thing.om_nom_nom.delicious;
}

fn var_members_of_members() -> i32 {
var thing = Outer();

var inner = thing.om_nom_nom;
var delishus = inner.delicious;

if (thing.thing != u32(delishus)) {
// LOL
}

return thing.om_nom_nom.delicious;
}
Loading

0 comments on commit 04aff59

Please sign in to comment.