mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-10-03 02:38:12 +08:00
shader-nodes feature: put shader nodes behind feature gate
This commit is contained in:
@@ -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")]
|
||||||
|
|||||||
@@ -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]
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user