@@ -7,7 +7,7 @@ use quote::{ToTokens, format_ident, quote};
77use std:: borrow:: Cow ;
88use syn:: parse:: { Parse , ParseStream } ;
99use syn:: punctuated:: Punctuated ;
10- use syn:: { Type , parse_quote} ;
10+ use syn:: { PatIdent , Type , parse_quote} ;
1111
1212#[ derive( Debug , Clone ) ]
1313pub struct PerPixelAdjust { }
@@ -20,15 +20,14 @@ impl Parse for PerPixelAdjust {
2020
2121impl ShaderCodegen for PerPixelAdjust {
2222 fn codegen ( & self , parsed : & ParsedNodeFn , node_cfg : & TokenStream ) -> syn:: Result < ShaderTokens > {
23- Ok ( ShaderTokens {
24- shader_entry_point : self . codegen_shader_entry_point ( parsed) ?,
25- gpu_node : self . codegen_gpu_node ( parsed, node_cfg) ?,
26- } )
23+ let ( shader_entry_point, entry_point_name) = self . codegen_shader_entry_point ( parsed) ?;
24+ let gpu_node = self . codegen_gpu_node ( parsed, node_cfg, & entry_point_name) ?;
25+ Ok ( ShaderTokens { shader_entry_point, gpu_node } )
2726 }
2827}
2928
3029impl PerPixelAdjust {
31- fn codegen_shader_entry_point ( & self , parsed : & ParsedNodeFn ) -> syn:: Result < TokenStream > {
30+ fn codegen_shader_entry_point ( & self , parsed : & ParsedNodeFn ) -> syn:: Result < ( TokenStream , TokenStream ) > {
3231 let fn_name = & parsed. fn_name ;
3332 let gpu_mod = format_ident ! ( "{}_gpu_entry_point" , fn_name) ;
3433 let spirv_image_ty = quote ! ( Image2d ) ;
@@ -82,7 +81,10 @@ impl PerPixelAdjust {
8281 . collect :: < Vec < _ > > ( ) ;
8382 let context = quote ! ( ( ) ) ;
8483
85- Ok ( quote ! {
84+ let entry_point_name = format_ident ! ( "ENTRY_POINT_NAME" ) ;
85+ let entry_point_sym = quote ! ( #gpu_mod:: #entry_point_name) ;
86+
87+ let shader_entry_point = quote ! {
8688 pub mod #gpu_mod {
8789 use super :: * ;
8890 use graphene_core_shaders:: color:: Color ;
@@ -91,6 +93,8 @@ impl PerPixelAdjust {
9193 use spirv_std:: image:: { Image2d , ImageWithMethods } ;
9294 use spirv_std:: image:: sample_with:: lod;
9395
96+ pub const #entry_point_name: & str = core:: concat!( core:: module_path!( ) , "::entry_point" ) ;
97+
9498 pub struct Uniform {
9599 #( #uniform_members) , *
96100 }
@@ -107,10 +111,11 @@ impl PerPixelAdjust {
107111 * color_out = color. to_vec4( ) ;
108112 }
109113 }
110- } )
114+ } ;
115+ Ok ( ( shader_entry_point, entry_point_sym) )
111116 }
112117
113- fn codegen_gpu_node ( & self , parsed : & ParsedNodeFn , node_cfg : & TokenStream ) -> syn:: Result < TokenStream > {
118+ fn codegen_gpu_node ( & self , parsed : & ParsedNodeFn , node_cfg : & TokenStream , entry_point_name : & TokenStream ) -> syn:: Result < TokenStream > {
114119 let fn_name = format_ident ! ( "{}_gpu" , parsed. fn_name) ;
115120 let struct_name = format_ident ! ( "{}" , fn_name. to_string( ) . to_case( Case :: Pascal ) ) ;
116121 let mod_name = fn_name. clone ( ) ;
@@ -121,7 +126,8 @@ impl PerPixelAdjust {
121126 } ;
122127 let raster_gpu: Type = parse_quote ! ( #gcore:: table:: Table <#gcore:: raster_types:: Raster <#gcore:: raster_types:: GPU >>) ;
123128
124- let fields = parsed
129+ // adapt fields for gpu node
130+ let mut fields = parsed
125131 . fields
126132 . iter ( )
127133 . map ( |f| match & f. ty {
@@ -136,11 +142,55 @@ impl PerPixelAdjust {
136142 ParsedFieldType :: Regular ( RegularParsedField { gpu_image : false , .. } ) => Ok ( f. clone ( ) ) ,
137143 ParsedFieldType :: Node { .. } => Err ( syn:: Error :: new_spanned ( & f. pat_ident , "PerPixelAdjust shader nodes cannot accept other nodes as generics" ) ) ,
138144 } )
139- . collect :: < syn:: Result < _ > > ( ) ?;
145+ . collect :: < syn:: Result < Vec < _ > > > ( ) ?;
146+
147+ // wgpu_executor field
148+ let wgpu_executor = format_ident ! ( "__wgpu_executor" ) ;
149+ fields. push ( ParsedField {
150+ pat_ident : PatIdent {
151+ attrs : vec ! [ ] ,
152+ by_ref : None ,
153+ mutability : None ,
154+ ident : parse_quote ! ( #wgpu_executor) ,
155+ subpat : None ,
156+ } ,
157+ name : None ,
158+ description : "" . to_string ( ) ,
159+ widget_override : Default :: default ( ) ,
160+ ty : ParsedFieldType :: Regular ( RegularParsedField {
161+ ty : parse_quote ! ( WgpuExecutor ) ,
162+ exposed : false ,
163+ value_source : Default :: default ( ) ,
164+ number_soft_min : None ,
165+ number_soft_max : None ,
166+ number_hard_min : None ,
167+ number_hard_max : None ,
168+ number_mode_range : None ,
169+ implementations : Default :: default ( ) ,
170+ gpu_image : false ,
171+ } ) ,
172+ number_display_decimal_places : None ,
173+ number_step : None ,
174+ unit : None ,
175+ } ) ;
176+
177+ // exactly one gpu_image field, may be expanded later
178+ let gpu_image_field = {
179+ let mut iter = fields. iter ( ) . filter ( |f| matches ! ( f. ty, ParsedFieldType :: Regular ( RegularParsedField { gpu_image: true , .. } ) ) ) ;
180+ match ( iter. next ( ) , iter. next ( ) ) {
181+ ( Some ( v) , None ) => Ok ( v) ,
182+ ( Some ( _) , Some ( more) ) => Err ( syn:: Error :: new_spanned ( & more. pat_ident , "No more than one parameter must be annotated with `#[gpu_image]`" ) ) ,
183+ ( None , _) => Err ( syn:: Error :: new_spanned ( & parsed. fn_name , "At least one parameter must be annotated with `#[gpu_image]`" ) ) ,
184+ } ?
185+ } ;
186+ let gpu_image = & gpu_image_field. pat_ident . ident ;
140187
141188 let body = quote ! {
142189 {
143-
190+ #wgpu_executor. shader_runtime. run_per_pixel_adjust( #gpu_image, & :: wgpu_executor:: shader_runtime:: per_pixel_adjust_runtime:: PerPixelAdjustInfo {
191+ wgsl_shader: crate :: WGSL_SHADER ,
192+ fragment_shader_name: super :: #entry_point_name,
193+ } ) . await
144194 }
145195 } ;
146196
@@ -174,6 +224,7 @@ impl PerPixelAdjust {
174224 #node_cfg
175225 mod #mod_name {
176226 use super :: * ;
227+ use wgpu_executor:: WgpuExecutor ;
177228
178229 #gpu_node
179230 }
0 commit comments