@@ -17,33 +17,70 @@ pub struct EnableExtensions {
1717 /// Whether `enable clip_distances;` was written earlier in the shader module.
1818 clip_distances : bool ,
1919 /// Native-only extensions.
20- wgpu : WgpuEnableExtensions ,
20+ wgpu : NativeOnly < WgpuEnableExtensions > ,
2121}
2222
2323impl EnableExtensions {
24- pub ( crate ) const fn empty ( ) -> Self {
24+ pub ( crate ) const fn empty ( native_only : NativeOnly < ( ) > ) -> Self {
25+ // TODO: It'd be nice to use a `const` `map` helper here, once
26+ // <https://github.com/rust-lang/rust/issues/73255> has landed.
27+ let wgpu = match native_only {
28+ NativeOnly :: NotAllowed {
29+ can_suggest_in_diagnostics,
30+ } => NativeOnly :: NotAllowed {
31+ can_suggest_in_diagnostics,
32+ } ,
33+ NativeOnly :: Allowed ( ( ) ) => NativeOnly :: Allowed ( WgpuEnableExtensions :: empty ( ) ) ,
34+ } ;
2535 Self {
26- wgpu : WgpuEnableExtensions :: empty ( ) ,
36+ wgpu,
2737 f16 : false ,
2838 dual_source_blending : false ,
2939 clip_distances : false ,
3040 }
3141 }
3242
3343 /// Add an enable-extension to the set requested by a module.
34- pub ( crate ) fn add ( & mut self , ext : ImplementedEnableExtension ) {
44+ pub ( crate ) fn enable (
45+ & mut self ,
46+ span : Span ,
47+ ext : ImplementedEnableExtension ,
48+ ) -> core:: result:: Result < ( ) , EnableExtensionNotAvailableError > {
49+ macro_rules! check_wgpu {
50+ ( $f: expr) => { {
51+ let f: fn ( & mut WgpuEnableExtensions ) -> & mut bool = $f;
52+ match & mut self . wgpu {
53+ & mut NativeOnly :: Allowed ( ref mut wgpu) => Ok ( f( wgpu) ) ,
54+ & mut NativeOnly :: NotAllowed {
55+ can_suggest_in_diagnostics,
56+ } => Err ( EnableExtensionNotAvailableError {
57+ span,
58+ extension: ext,
59+ reason: EnableExtensionNotAvailableErrorReason :: NotAllowed {
60+ can_suggest_in_diagnostics,
61+ } ,
62+ } ) ,
63+ }
64+ } } ;
65+ }
3566 let field = match ext {
36- ImplementedEnableExtension :: WgpuMeshShader => & mut self . wgpu . mesh_shader ,
37- ImplementedEnableExtension :: WgpuRayQuery => & mut self . wgpu . ray_query ,
67+ ImplementedEnableExtension :: WgpuMeshShader => {
68+ check_wgpu ! ( |wgpu| & mut wgpu. mesh_shader) ?
69+ }
70+ ImplementedEnableExtension :: WgpuRayQuery => check_wgpu ! ( |wgpu| & mut wgpu. ray_query) ?,
3871 ImplementedEnableExtension :: WgpuRayQueryVertexReturn => {
39- & mut self . wgpu . ray_query_vertex_return
72+ check_wgpu ! ( |wgpu| & mut wgpu. ray_query_vertex_return) ?
4073 }
4174 ImplementedEnableExtension :: DualSourceBlending => & mut self . dual_source_blending ,
4275 ImplementedEnableExtension :: F16 => & mut self . f16 ,
4376 ImplementedEnableExtension :: ClipDistances => & mut self . clip_distances ,
44- ImplementedEnableExtension :: WgpuCooperativeMatrix => & mut self . wgpu . cooperative_matrix ,
77+ ImplementedEnableExtension :: WgpuCooperativeMatrix => {
78+ check_wgpu ! ( |wgpu| & mut wgpu. cooperative_matrix) ?
79+ }
4580 } ;
4681 * field = true ;
82+
83+ Ok ( ( ) )
4784 }
4885
4986 /// Query whether an enable-extension tracked here has been requested.
@@ -52,16 +89,31 @@ impl EnableExtensions {
5289 span : Span ,
5390 extension : ImplementedEnableExtension ,
5491 ) -> core:: result:: Result < ( ) , EnableExtensionNotAvailableError > {
92+ let check_wgpu = |f : fn ( & WgpuEnableExtensions ) -> bool | match & self . wgpu {
93+ & NativeOnly :: Allowed ( ref wgpu) => Ok ( f ( wgpu) ) ,
94+ & NativeOnly :: NotAllowed {
95+ can_suggest_in_diagnostics,
96+ } => Err ( EnableExtensionNotAvailableError {
97+ span,
98+ extension,
99+ reason : EnableExtensionNotAvailableErrorReason :: NotAllowed {
100+ can_suggest_in_diagnostics,
101+ } ,
102+ } ) ,
103+ } ;
104+
55105 let is_enabled = match extension {
56- ImplementedEnableExtension :: WgpuMeshShader => self . wgpu . mesh_shader ,
57- ImplementedEnableExtension :: WgpuRayQuery => self . wgpu . ray_query ,
106+ ImplementedEnableExtension :: WgpuMeshShader => check_wgpu ( | wgpu| wgpu . mesh_shader ) ? ,
107+ ImplementedEnableExtension :: WgpuRayQuery => check_wgpu ( | wgpu| wgpu . ray_query ) ? ,
58108 ImplementedEnableExtension :: WgpuRayQueryVertexReturn => {
59- self . wgpu . ray_query_vertex_return
109+ check_wgpu ( | wgpu| wgpu . ray_query_vertex_return ) ?
60110 }
61111 ImplementedEnableExtension :: DualSourceBlending => self . dual_source_blending ,
62112 ImplementedEnableExtension :: F16 => self . f16 ,
63113 ImplementedEnableExtension :: ClipDistances => self . clip_distances ,
64- ImplementedEnableExtension :: WgpuCooperativeMatrix => self . wgpu . cooperative_matrix ,
114+ ImplementedEnableExtension :: WgpuCooperativeMatrix => {
115+ check_wgpu ( |wgpu| wgpu. cooperative_matrix ) ?
116+ }
65117 } ;
66118
67119 if is_enabled {
@@ -78,7 +130,45 @@ impl EnableExtensions {
78130
79131impl Default for EnableExtensions {
80132 fn default ( ) -> Self {
81- Self :: empty ( )
133+ Self :: empty ( NativeOnly :: default ( ) )
134+ }
135+ }
136+
137+ /// Native-only extensions under [`EnableExtensions::wgpu`].
138+ #[ derive( Clone , Debug , Eq , PartialEq ) ]
139+ pub enum NativeOnly < T > {
140+ NotAllowed {
141+ /// Whether the diagnostic of a validation check encountering this case may contain a hint
142+ /// about enabling native-only extensions.
143+ ///
144+ /// Set this to `false` when you are running user-provided shaders in non-native
145+ /// environments.
146+ can_suggest_in_diagnostics : bool ,
147+ } ,
148+ Allowed ( T ) ,
149+ }
150+
151+ impl < T > NativeOnly < T > {
152+ pub fn map < U , F > ( self , f : F ) -> NativeOnly < U >
153+ where
154+ F : FnOnce ( T ) -> U ,
155+ {
156+ match self {
157+ Self :: NotAllowed {
158+ can_suggest_in_diagnostics,
159+ } => NativeOnly :: NotAllowed {
160+ can_suggest_in_diagnostics,
161+ } ,
162+ Self :: Allowed ( t) => NativeOnly :: Allowed ( f ( t) ) ,
163+ }
164+ }
165+ }
166+
167+ impl < T > Default for NativeOnly < T > {
168+ fn default ( ) -> Self {
169+ Self :: NotAllowed {
170+ can_suggest_in_diagnostics : false ,
171+ }
82172 }
83173}
84174
@@ -124,6 +214,7 @@ pub struct EnableExtensionNotAvailableError {
124214#[ derive( Clone , Debug , Eq , PartialEq ) ]
125215pub enum EnableExtensionNotAvailableErrorReason {
126216 NotEnabled ,
217+ NotAllowed { can_suggest_in_diagnostics : bool } ,
127218}
128219
129220/// An enable-extension not guaranteed to be present in all environments.
0 commit comments