mirror of
https://github.com/gfx-rs/wgpu.git
synced 2024-11-21 22:33:49 +00:00
feat: implement requires
directives
This commit is contained in:
parent
bdd923d3a7
commit
18f33b0474
@ -85,7 +85,7 @@ By @bradwerth [#6216](https://github.com/gfx-rs/wgpu/pull/6216).
|
||||
- Support local `const` declarations in WGSL. By @sagudev in [#6156](https://github.com/gfx-rs/wgpu/pull/6156).
|
||||
- Implemented `const_assert` in WGSL. By @sagudev in [#6198](https://github.com/gfx-rs/wgpu/pull/6198).
|
||||
- Support polyfilling `inverse` in WGSL. By @chyyran in [#6385](https://github.com/gfx-rs/wgpu/pull/6385).
|
||||
- Add an internal skeleton for parsing `requires`, `enable`, and `diagnostic` directives that don't yet do anything besides emit nicer errors. By @ErichDonGubler in [#6352](https://github.com/gfx-rs/wgpu/pull/6352), [#6424](https://github.com/gfx-rs/wgpu/pull/6424).
|
||||
- Add an internal skeleton for parsing `requires`, `enable`, and `diagnostic` directives that don't yet do anything besides emit nicer errors. By @ErichDonGubler in [#6352](https://github.com/gfx-rs/wgpu/pull/6352), [#6424](https://github.com/gfx-rs/wgpu/pull/6424), [#6437](https://github.com/gfx-rs/wgpu/pull/6437).
|
||||
- Include error chain information as a message and notes in shader compilation messages. By @ErichDonGubler in [#6436](https://github.com/gfx-rs/wgpu/pull/6436).
|
||||
- Unify Naga CLI error output with the format of shader compilation messages. By @ErichDonGubler in [#6436](https://github.com/gfx-rs/wgpu/pull/6436).
|
||||
|
||||
|
@ -1,6 +1,9 @@
|
||||
use crate::front::wgsl::parse::directive::enable_extension::{
|
||||
EnableExtension, UnimplementedEnableExtension,
|
||||
};
|
||||
use crate::front::wgsl::parse::directive::language_extension::{
|
||||
LanguageExtension, UnimplementedLanguageExtension,
|
||||
};
|
||||
use crate::front::wgsl::parse::directive::{DirectiveKind, UnimplementedDirectiveKind};
|
||||
use crate::front::wgsl::parse::lexer::Token;
|
||||
use crate::front::wgsl::Scalar;
|
||||
@ -190,6 +193,7 @@ pub(crate) enum Error<'a> {
|
||||
UnknownStorageFormat(Span),
|
||||
UnknownConservativeDepth(Span),
|
||||
UnknownEnableExtension(Span, &'a str),
|
||||
UnknownLanguageExtension(Span, &'a str),
|
||||
SizeAttributeTooLow(Span, u32),
|
||||
AlignAttributeTooLow(Span, Alignment),
|
||||
NonPowerOfTwoAlignAttribute(Span),
|
||||
@ -287,6 +291,10 @@ pub(crate) enum Error<'a> {
|
||||
kind: EnableExtension,
|
||||
span: Span,
|
||||
},
|
||||
LanguageExtensionNotYetImplemented {
|
||||
kind: UnimplementedLanguageExtension,
|
||||
span: Span,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@ -545,6 +553,15 @@ impl<'a> Error<'a> {
|
||||
.into(),
|
||||
],
|
||||
},
|
||||
Error::UnknownLanguageExtension(span, name) => ParseError {
|
||||
message: format!("unknown language extension `{name}`"),
|
||||
labels: vec![(span, "".into())],
|
||||
notes: vec![concat!(
|
||||
"See available extensions at ",
|
||||
"<https://www.w3.org/TR/WGSL/#language-extensions-sec>."
|
||||
)
|
||||
.into()],
|
||||
},
|
||||
Error::SizeAttributeTooLow(bad_span, min_size) => ParseError {
|
||||
message: format!("struct member size must be at least {min_size}"),
|
||||
labels: vec![(bad_span, format!("must be at least {min_size}").into())],
|
||||
@ -976,6 +993,21 @@ impl<'a> Error<'a> {
|
||||
vec![]
|
||||
},
|
||||
},
|
||||
Error::LanguageExtensionNotYetImplemented { kind, span } => ParseError {
|
||||
message: format!(
|
||||
"the `{}` language extension is not yet supported",
|
||||
LanguageExtension::Unimplemented(kind).to_ident()
|
||||
),
|
||||
labels: vec![(span, "".into())],
|
||||
notes: vec![format!(
|
||||
concat!(
|
||||
"Let Naga maintainers know that you ran into this at ",
|
||||
"<https://github.com/gfx-rs/wgpu/issues/{}>, ",
|
||||
"so they can prioritize it!"
|
||||
),
|
||||
kind.tracking_issue_num()
|
||||
)],
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,12 +3,15 @@
|
||||
//! See also <https://www.w3.org/TR/WGSL/#directives>.
|
||||
|
||||
pub mod enable_extension;
|
||||
pub(crate) mod language_extension;
|
||||
|
||||
/// A parsed sentinel word indicating the type of directive to be parsed next.
|
||||
#[derive(Clone, Copy, Debug, Hash, Eq, PartialEq)]
|
||||
pub(crate) enum DirectiveKind {
|
||||
/// An [`enable_extension`].
|
||||
Enable,
|
||||
/// A language extension.
|
||||
Requires,
|
||||
Unimplemented(UnimplementedDirectiveKind),
|
||||
}
|
||||
|
||||
@ -22,7 +25,7 @@ impl DirectiveKind {
|
||||
Some(match s {
|
||||
Self::DIAGNOSTIC => Self::Unimplemented(UnimplementedDirectiveKind::Diagnostic),
|
||||
Self::ENABLE => Self::Enable,
|
||||
Self::REQUIRES => Self::Unimplemented(UnimplementedDirectiveKind::Requires),
|
||||
Self::REQUIRES => Self::Requires,
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
@ -31,9 +34,9 @@ impl DirectiveKind {
|
||||
pub const fn to_ident(self) -> &'static str {
|
||||
match self {
|
||||
Self::Enable => Self::ENABLE,
|
||||
Self::Requires => Self::REQUIRES,
|
||||
Self::Unimplemented(kind) => match kind {
|
||||
UnimplementedDirectiveKind::Diagnostic => Self::DIAGNOSTIC,
|
||||
UnimplementedDirectiveKind::Requires => Self::REQUIRES,
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -51,14 +54,12 @@ impl DirectiveKind {
|
||||
#[cfg_attr(test, derive(strum::EnumIter))]
|
||||
pub(crate) enum UnimplementedDirectiveKind {
|
||||
Diagnostic,
|
||||
Requires,
|
||||
}
|
||||
|
||||
impl UnimplementedDirectiveKind {
|
||||
pub const fn tracking_issue_num(self) -> u16 {
|
||||
match self {
|
||||
Self::Diagnostic => 5320,
|
||||
Self::Requires => 6350,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -88,19 +89,6 @@ error: `diagnostic` is not yet implemented
|
||||
│
|
||||
= note: Let Naga maintainers know that you ran into this at <https://github.com/gfx-rs/wgpu/issues/5320>, so they can prioritize it!
|
||||
|
||||
";
|
||||
}
|
||||
UnimplementedDirectiveKind::Requires => {
|
||||
shader = "requires readonly_and_readwrite_storage_textures";
|
||||
expected_msg = "\
|
||||
error: `requires` is not yet implemented
|
||||
┌─ wgsl:1:1
|
||||
│
|
||||
1 │ requires readonly_and_readwrite_storage_textures
|
||||
│ ^^^^^^^^ this global directive is standard, but not yet implemented
|
||||
│
|
||||
= note: Let Naga maintainers know that you ran into this at <https://github.com/gfx-rs/wgpu/issues/6350>, so they can prioritize it!
|
||||
|
||||
";
|
||||
}
|
||||
};
|
||||
@ -141,7 +129,7 @@ error: expected global declaration, but found a global directive
|
||||
|
||||
";
|
||||
}
|
||||
DirectiveKind::Unimplemented(UnimplementedDirectiveKind::Requires) => {
|
||||
DirectiveKind::Requires => {
|
||||
directive = "requires readonly_and_readwrite_storage_textures";
|
||||
expected_msg = "\
|
||||
error: expected global declaration, but found a global directive
|
||||
|
85
naga/src/front/wgsl/parse/directive/language_extension.rs
Normal file
85
naga/src/front/wgsl/parse/directive/language_extension.rs
Normal file
@ -0,0 +1,85 @@
|
||||
//! `requires …;` extensions in WGSL.
|
||||
//!
|
||||
//! The focal point of this module is the [`LanguageExtension`] API.
|
||||
|
||||
/// A language extension not guaranteed to be present in all environments.
|
||||
///
|
||||
/// WGSL spec.: <https://www.w3.org/TR/WGSL/#language-extensions-sec>
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
||||
pub(crate) enum LanguageExtension {
|
||||
#[allow(unused)]
|
||||
Implemented(ImplementedLanguageExtension),
|
||||
Unimplemented(UnimplementedLanguageExtension),
|
||||
}
|
||||
|
||||
impl LanguageExtension {
|
||||
const READONLY_AND_READWRITE_STORAGE_TEXTURES: &'static str =
|
||||
"readonly_and_readwrite_storage_textures";
|
||||
const PACKED4X8_INTEGER_DOT_PRODUCT: &'static str = "packed_4x8_integer_dot_product";
|
||||
const UNRESTRICTED_POINTER_PARAMETERS: &'static str = "unrestricted_pointer_parameters";
|
||||
const POINTER_COMPOSITE_ACCESS: &'static str = "pointer_composite_access";
|
||||
|
||||
/// Convert from a sentinel word in WGSL into its associated [`LanguageExtension`], if possible.
|
||||
pub fn from_ident(s: &str) -> Option<Self> {
|
||||
Some(match s {
|
||||
Self::READONLY_AND_READWRITE_STORAGE_TEXTURES => Self::Unimplemented(
|
||||
UnimplementedLanguageExtension::ReadOnlyAndReadWriteStorageTextures,
|
||||
),
|
||||
Self::PACKED4X8_INTEGER_DOT_PRODUCT => {
|
||||
Self::Unimplemented(UnimplementedLanguageExtension::Packed4x8IntegerDotProduct)
|
||||
}
|
||||
Self::UNRESTRICTED_POINTER_PARAMETERS => {
|
||||
Self::Unimplemented(UnimplementedLanguageExtension::UnrestrictedPointerParameters)
|
||||
}
|
||||
Self::POINTER_COMPOSITE_ACCESS => {
|
||||
Self::Unimplemented(UnimplementedLanguageExtension::PointerCompositeAccess)
|
||||
}
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
|
||||
/// Maps this [`LanguageExtension`] into the sentinel word associated with it in WGSL.
|
||||
pub const fn to_ident(self) -> &'static str {
|
||||
match self {
|
||||
Self::Implemented(kind) => match kind {},
|
||||
Self::Unimplemented(kind) => match kind {
|
||||
UnimplementedLanguageExtension::ReadOnlyAndReadWriteStorageTextures => {
|
||||
Self::READONLY_AND_READWRITE_STORAGE_TEXTURES
|
||||
}
|
||||
UnimplementedLanguageExtension::Packed4x8IntegerDotProduct => {
|
||||
Self::PACKED4X8_INTEGER_DOT_PRODUCT
|
||||
}
|
||||
UnimplementedLanguageExtension::UnrestrictedPointerParameters => {
|
||||
Self::UNRESTRICTED_POINTER_PARAMETERS
|
||||
}
|
||||
UnimplementedLanguageExtension::PointerCompositeAccess => {
|
||||
Self::POINTER_COMPOSITE_ACCESS
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A variant of [`LanguageExtension::Implemented`].
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
||||
pub(crate) enum ImplementedLanguageExtension {}
|
||||
|
||||
/// A variant of [`LanguageExtension::Unimplemented`].
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
||||
pub(crate) enum UnimplementedLanguageExtension {
|
||||
ReadOnlyAndReadWriteStorageTextures,
|
||||
Packed4x8IntegerDotProduct,
|
||||
UnrestrictedPointerParameters,
|
||||
PointerCompositeAccess,
|
||||
}
|
||||
|
||||
impl UnimplementedLanguageExtension {
|
||||
pub(crate) const fn tracking_issue_num(self) -> u16 {
|
||||
match self {
|
||||
Self::ReadOnlyAndReadWriteStorageTextures => 6204,
|
||||
Self::Packed4x8IntegerDotProduct => 6445,
|
||||
Self::UnrestrictedPointerParameters => 5158,
|
||||
Self::PointerCompositeAccess => 6192,
|
||||
}
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@ use crate::front::wgsl::error::{Error, ExpectedToken};
|
||||
use crate::front::wgsl::parse::directive::enable_extension::{
|
||||
EnableExtension, EnableExtensions, UnimplementedEnableExtension,
|
||||
};
|
||||
use crate::front::wgsl::parse::directive::language_extension::LanguageExtension;
|
||||
use crate::front::wgsl::parse::directive::DirectiveKind;
|
||||
use crate::front::wgsl::parse::lexer::{Lexer, Token};
|
||||
use crate::front::wgsl::parse::number::Number;
|
||||
@ -2544,6 +2545,23 @@ impl Parser {
|
||||
Ok(())
|
||||
})?;
|
||||
}
|
||||
DirectiveKind::Requires => {
|
||||
self.directive_ident_list(&mut lexer, |ident, span| {
|
||||
match LanguageExtension::from_ident(ident) {
|
||||
Some(LanguageExtension::Implemented(_kind)) => {
|
||||
// NOTE: No further validation is needed for an extension, so
|
||||
// just throw parsed information away. If we ever want to apply
|
||||
// what we've parsed to diagnostics, maybe we'll want to refer
|
||||
// to enabled extensions later?
|
||||
Ok(())
|
||||
}
|
||||
Some(LanguageExtension::Unimplemented(kind)) => {
|
||||
Err(Error::LanguageExtensionNotYetImplemented { kind, span })
|
||||
}
|
||||
None => Err(Error::UnknownLanguageExtension(span, ident)),
|
||||
}
|
||||
})?;
|
||||
}
|
||||
DirectiveKind::Unimplemented(kind) => {
|
||||
return Err(Error::DirectiveNotYetImplemented { kind, span })
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user