diff --git a/node-graph/graster-nodes/src/lib.rs b/node-graph/graster-nodes/src/lib.rs index d5383df034..080504f9ea 100644 --- a/node-graph/graster-nodes/src/lib.rs +++ b/node-graph/graster-nodes/src/lib.rs @@ -7,7 +7,7 @@ pub mod cubic_spline; pub mod fullscreen_vertex; /// required by shader macro -#[cfg(feature = "std")] +#[cfg(feature = "shader-nodes")] pub use graphene_raster_nodes_shaders::WGSL_SHADER; #[cfg(feature = "std")] diff --git a/node-graph/node-macro/src/codegen.rs b/node-graph/node-macro/src/codegen.rs index b3a1b28be3..98bb5588a9 100644 --- a/node-graph/node-macro/src/codegen.rs +++ b/node-graph/node-macro/src/codegen.rs @@ -295,7 +295,7 @@ pub(crate) fn generate_node_code(parsed: &ParsedNodeFn) -> syn::Result TokenStream { - match (&attributes.cfg, &attributes.shader_node) { - (Some(cfg), Some(_)) => quote!(#[cfg(all(#cfg, feature = #STD_FEATURE_GATE))]), - (Some(cfg), None) => quote!(#[cfg(#cfg)]), - (None, Some(_)) => quote!(#[cfg(feature = #STD_FEATURE_GATE)]), - (None, None) => quote!(), - } + let feature_gate = match &attributes.shader_node { + // shader node cfg is done on the mod + Some(ShaderNodeType::ShaderNode) => quote!(), + Some(_) => quote!(feature = #STD_FEATURE_GATE), + None => quote!(), + }; + let cfgs: Punctuated<_, Token![,]> = match &attributes.cfg { + None => [&feature_gate].into_iter().collect(), + Some(cfg) => [cfg, &feature_gate].into_iter().collect(), + }; + quote!(#[cfg(all(#cfgs))]) } #[derive(Debug, Clone, VariantNames)] pub(crate) enum ShaderNodeType { + /// Marker for this node being in a gpu node crate, but not having a gpu implementation. This is distinct from not + /// declaring `shader_node` at all, as it will wrap the CPU node with a `#[cfg(feature = "std")]` feature gate. + None, /// Marker for this node being a generated gpu node implementation, that should not emit anything to prevent /// recursively generating more gpu nodes. But it still counts as a gpu node and will get the /// `#[cfg(feature = "std")]` feature gate around it's impl. - GpuNode, + ShaderNode, PerPixelAdjust(PerPixelAdjust), } @@ -32,6 +42,7 @@ impl Parse for ShaderNodeType { fn parse(input: ParseStream) -> syn::Result { let ident: Ident = input.parse()?; Ok(match ident.to_string().as_str() { + "None" => ShaderNodeType::None, "PerPixelAdjust" => ShaderNodeType::PerPixelAdjust(PerPixelAdjust::parse(input)?), _ => return Err(Error::new_spanned(&ident, format!("attr 'shader_node' must be one of {:?}", Self::VARIANTS))), }) @@ -39,13 +50,13 @@ impl Parse for ShaderNodeType { } pub trait ShaderCodegen { - fn codegen(&self, parsed: &ParsedNodeFn, node_cfg: &TokenStream) -> syn::Result; + fn codegen(&self, parsed: &ParsedNodeFn) -> syn::Result; } impl ShaderCodegen for ShaderNodeType { - fn codegen(&self, parsed: &ParsedNodeFn, node_cfg: &TokenStream) -> syn::Result { + fn codegen(&self, parsed: &ParsedNodeFn) -> syn::Result { match self { - ShaderNodeType::GpuNode => (), + ShaderNodeType::None | ShaderNodeType::ShaderNode => (), _ => { if parsed.is_async { return Err(Error::new_spanned(&parsed.fn_name, "Shader nodes must not be async")); @@ -54,8 +65,8 @@ impl ShaderCodegen for ShaderNodeType { } match self { - ShaderNodeType::GpuNode => Ok(ShaderTokens::default()), - ShaderNodeType::PerPixelAdjust(x) => x.codegen(parsed, node_cfg), + ShaderNodeType::None | ShaderNodeType::ShaderNode => Ok(ShaderTokens::default()), + ShaderNodeType::PerPixelAdjust(x) => x.codegen(parsed), } } } diff --git a/node-graph/node-macro/src/shader_nodes/per_pixel_adjust.rs b/node-graph/node-macro/src/shader_nodes/per_pixel_adjust.rs index 57e4fcefa9..cd0d911694 100644 --- a/node-graph/node-macro/src/shader_nodes/per_pixel_adjust.rs +++ b/node-graph/node-macro/src/shader_nodes/per_pixel_adjust.rs @@ -1,5 +1,5 @@ use crate::parsing::{Input, NodeFnAttributes, ParsedField, ParsedFieldType, ParsedNodeFn, RegularParsedField}; -use crate::shader_nodes::{ShaderCodegen, ShaderNodeType, ShaderTokens}; +use crate::shader_nodes::{SHADER_NODES_FEATURE_GATE, ShaderCodegen, ShaderNodeType, ShaderTokens}; use convert_case::{Case, Casing}; use proc_macro_crate::FoundCrate; use proc_macro2::{Ident, TokenStream}; @@ -19,7 +19,7 @@ impl Parse for PerPixelAdjust { } impl ShaderCodegen for PerPixelAdjust { - fn codegen(&self, parsed: &ParsedNodeFn, node_cfg: &TokenStream) -> syn::Result { + fn codegen(&self, parsed: &ParsedNodeFn) -> syn::Result { let fn_name = &parsed.fn_name; let mut params; @@ -75,7 +75,6 @@ impl ShaderCodegen for PerPixelAdjust { let codegen = PerPixelAdjustCodegen { parsed, - node_cfg, params, has_uniform, entry_point_mod, @@ -95,7 +94,6 @@ impl ShaderCodegen for PerPixelAdjust { pub struct PerPixelAdjustCodegen<'a> { parsed: &'a ParsedNodeFn, - node_cfg: &'a TokenStream, params: Vec>, has_uniform: bool, entry_point_mod: Ident, @@ -285,7 +283,7 @@ impl PerPixelAdjustCodegen<'_> { let mut parsed_node_fn = ParsedNodeFn { vis: self.parsed.vis.clone(), attributes: NodeFnAttributes { - shader_node: Some(ShaderNodeType::GpuNode), + shader_node: Some(ShaderNodeType::ShaderNode), ..self.parsed.attributes.clone() }, fn_name: self.gpu_node_mod.clone(), @@ -309,10 +307,9 @@ impl PerPixelAdjustCodegen<'_> { let gpu_node_impl = crate::codegen::generate_node_code(&parsed_node_fn)?; // wrap node in `mod #gpu_node_mod` - let node_cfg = self.node_cfg; let gpu_node_mod = &self.gpu_node_mod; Ok(quote! { - #node_cfg + #[cfg(feature = #SHADER_NODES_FEATURE_GATE)] mod #gpu_node_mod { use super::*; use wgpu_executor::WgpuExecutor;