shader-nodes feature: put shader nodes behind feature gate

This commit is contained in:
firestar99
2025-09-05 00:16:04 +02:00
parent 1128271b41
commit 676aea33fe
4 changed files with 30 additions and 22 deletions
+1 -1
View File
@@ -7,7 +7,7 @@ pub mod cubic_spline;
pub mod fullscreen_vertex; pub mod fullscreen_vertex;
/// required by shader macro /// required by shader macro
#[cfg(feature = "std")] #[cfg(feature = "shader-nodes")]
pub use graphene_raster_nodes_shaders::WGSL_SHADER; pub use graphene_raster_nodes_shaders::WGSL_SHADER;
#[cfg(feature = "std")] #[cfg(feature = "std")]
+1 -1
View File
@@ -295,7 +295,7 @@ pub(crate) fn generate_node_code(parsed: &ParsedNodeFn) -> syn::Result<TokenStre
let cfg = crate::shader_nodes::modify_cfg(attributes); let cfg = crate::shader_nodes::modify_cfg(attributes);
let node_input_accessor = generate_node_input_references(parsed, fn_generics, &field_idents, &graphene_core, &identifier, &cfg); let node_input_accessor = generate_node_input_references(parsed, fn_generics, &field_idents, &graphene_core, &identifier, &cfg);
let ShaderTokens { shader_entry_point, gpu_node } = attributes.shader_node.as_ref().map(|n| n.codegen(parsed, &cfg)).unwrap_or(Ok(ShaderTokens::default()))?; let ShaderTokens { shader_entry_point, gpu_node } = attributes.shader_node.as_ref().map(|n| n.codegen(parsed)).unwrap_or(Ok(ShaderTokens::default()))?;
Ok(quote! { Ok(quote! {
/// Underlying implementation for [#struct_name] /// Underlying implementation for [#struct_name]
+24 -13
View File
@@ -3,28 +3,38 @@ use crate::shader_nodes::per_pixel_adjust::PerPixelAdjust;
use proc_macro2::{Ident, TokenStream}; use proc_macro2::{Ident, TokenStream};
use quote::quote; use quote::quote;
use strum::VariantNames; use strum::VariantNames;
use syn::Error;
use syn::parse::{Parse, ParseStream}; use syn::parse::{Parse, ParseStream};
use syn::punctuated::Punctuated;
use syn::{Error, Token};
pub mod per_pixel_adjust; pub mod per_pixel_adjust;
pub const STD_FEATURE_GATE: &str = "std"; pub const STD_FEATURE_GATE: &str = "std";
pub const SHADER_NODES_FEATURE_GATE: &str = "shader-nodes";
pub fn modify_cfg(attributes: &NodeFnAttributes) -> TokenStream { pub fn modify_cfg(attributes: &NodeFnAttributes) -> TokenStream {
match (&attributes.cfg, &attributes.shader_node) { let feature_gate = match &attributes.shader_node {
(Some(cfg), Some(_)) => quote!(#[cfg(all(#cfg, feature = #STD_FEATURE_GATE))]), // shader node cfg is done on the mod
(Some(cfg), None) => quote!(#[cfg(#cfg)]), Some(ShaderNodeType::ShaderNode) => quote!(),
(None, Some(_)) => quote!(#[cfg(feature = #STD_FEATURE_GATE)]), Some(_) => quote!(feature = #STD_FEATURE_GATE),
(None, None) => quote!(), 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)] #[derive(Debug, Clone, VariantNames)]
pub(crate) enum ShaderNodeType { 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 /// 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 /// 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. /// `#[cfg(feature = "std")]` feature gate around it's impl.
GpuNode, ShaderNode,
PerPixelAdjust(PerPixelAdjust), PerPixelAdjust(PerPixelAdjust),
} }
@@ -32,6 +42,7 @@ impl Parse for ShaderNodeType {
fn parse(input: ParseStream) -> syn::Result<Self> { fn parse(input: ParseStream) -> syn::Result<Self> {
let ident: Ident = input.parse()?; let ident: Ident = input.parse()?;
Ok(match ident.to_string().as_str() { Ok(match ident.to_string().as_str() {
"None" => ShaderNodeType::None,
"PerPixelAdjust" => ShaderNodeType::PerPixelAdjust(PerPixelAdjust::parse(input)?), "PerPixelAdjust" => ShaderNodeType::PerPixelAdjust(PerPixelAdjust::parse(input)?),
_ => return Err(Error::new_spanned(&ident, format!("attr 'shader_node' must be one of {:?}", Self::VARIANTS))), _ => 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 { pub trait ShaderCodegen {
fn codegen(&self, parsed: &ParsedNodeFn, node_cfg: &TokenStream) -> syn::Result<ShaderTokens>; fn codegen(&self, parsed: &ParsedNodeFn) -> syn::Result<ShaderTokens>;
} }
impl ShaderCodegen for ShaderNodeType { impl ShaderCodegen for ShaderNodeType {
fn codegen(&self, parsed: &ParsedNodeFn, node_cfg: &TokenStream) -> syn::Result<ShaderTokens> { fn codegen(&self, parsed: &ParsedNodeFn) -> syn::Result<ShaderTokens> {
match self { match self {
ShaderNodeType::GpuNode => (), ShaderNodeType::None | ShaderNodeType::ShaderNode => (),
_ => { _ => {
if parsed.is_async { if parsed.is_async {
return Err(Error::new_spanned(&parsed.fn_name, "Shader nodes must not be 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 { match self {
ShaderNodeType::GpuNode => Ok(ShaderTokens::default()), ShaderNodeType::None | ShaderNodeType::ShaderNode => Ok(ShaderTokens::default()),
ShaderNodeType::PerPixelAdjust(x) => x.codegen(parsed, node_cfg), ShaderNodeType::PerPixelAdjust(x) => x.codegen(parsed),
} }
} }
} }
@@ -1,5 +1,5 @@
use crate::parsing::{Input, NodeFnAttributes, ParsedField, ParsedFieldType, ParsedNodeFn, RegularParsedField}; 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 convert_case::{Case, Casing};
use proc_macro_crate::FoundCrate; use proc_macro_crate::FoundCrate;
use proc_macro2::{Ident, TokenStream}; use proc_macro2::{Ident, TokenStream};
@@ -19,7 +19,7 @@ impl Parse for PerPixelAdjust {
} }
impl ShaderCodegen for PerPixelAdjust { impl ShaderCodegen for PerPixelAdjust {
fn codegen(&self, parsed: &ParsedNodeFn, node_cfg: &TokenStream) -> syn::Result<ShaderTokens> { fn codegen(&self, parsed: &ParsedNodeFn) -> syn::Result<ShaderTokens> {
let fn_name = &parsed.fn_name; let fn_name = &parsed.fn_name;
let mut params; let mut params;
@@ -75,7 +75,6 @@ impl ShaderCodegen for PerPixelAdjust {
let codegen = PerPixelAdjustCodegen { let codegen = PerPixelAdjustCodegen {
parsed, parsed,
node_cfg,
params, params,
has_uniform, has_uniform,
entry_point_mod, entry_point_mod,
@@ -95,7 +94,6 @@ impl ShaderCodegen for PerPixelAdjust {
pub struct PerPixelAdjustCodegen<'a> { pub struct PerPixelAdjustCodegen<'a> {
parsed: &'a ParsedNodeFn, parsed: &'a ParsedNodeFn,
node_cfg: &'a TokenStream,
params: Vec<Param<'a>>, params: Vec<Param<'a>>,
has_uniform: bool, has_uniform: bool,
entry_point_mod: Ident, entry_point_mod: Ident,
@@ -285,7 +283,7 @@ impl PerPixelAdjustCodegen<'_> {
let mut parsed_node_fn = ParsedNodeFn { let mut parsed_node_fn = ParsedNodeFn {
vis: self.parsed.vis.clone(), vis: self.parsed.vis.clone(),
attributes: NodeFnAttributes { attributes: NodeFnAttributes {
shader_node: Some(ShaderNodeType::GpuNode), shader_node: Some(ShaderNodeType::ShaderNode),
..self.parsed.attributes.clone() ..self.parsed.attributes.clone()
}, },
fn_name: self.gpu_node_mod.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)?; let gpu_node_impl = crate::codegen::generate_node_code(&parsed_node_fn)?;
// wrap node in `mod #gpu_node_mod` // wrap node in `mod #gpu_node_mod`
let node_cfg = self.node_cfg;
let gpu_node_mod = &self.gpu_node_mod; let gpu_node_mod = &self.gpu_node_mod;
Ok(quote! { Ok(quote! {
#node_cfg #[cfg(feature = #SHADER_NODES_FEATURE_GATE)]
mod #gpu_node_mod { mod #gpu_node_mod {
use super::*; use super::*;
use wgpu_executor::WgpuExecutor; use wgpu_executor::WgpuExecutor;