@@ -7,7 +7,7 @@ use quote::{ToTokens, format_ident, quote};
7
7
use std:: borrow:: Cow ;
8
8
use syn:: parse:: { Parse , ParseStream } ;
9
9
use syn:: punctuated:: Punctuated ;
10
- use syn:: { Type , parse_quote} ;
10
+ use syn:: { PatIdent , Type , parse_quote} ;
11
11
12
12
#[ derive( Debug , Clone ) ]
13
13
pub struct PerPixelAdjust { }
@@ -20,15 +20,14 @@ impl Parse for PerPixelAdjust {
20
20
21
21
impl ShaderCodegen for PerPixelAdjust {
22
22
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 } )
27
26
}
28
27
}
29
28
30
29
impl 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 ) > {
32
31
let fn_name = & parsed. fn_name ;
33
32
let gpu_mod = format_ident ! ( "{}_gpu_entry_point" , fn_name) ;
34
33
let spirv_image_ty = quote ! ( Image2d ) ;
@@ -82,7 +81,10 @@ impl PerPixelAdjust {
82
81
. collect :: < Vec < _ > > ( ) ;
83
82
let context = quote ! ( ( ) ) ;
84
83
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 ! {
86
88
pub mod #gpu_mod {
87
89
use super :: * ;
88
90
use graphene_core_shaders:: color:: Color ;
@@ -91,6 +93,8 @@ impl PerPixelAdjust {
91
93
use spirv_std:: image:: { Image2d , ImageWithMethods } ;
92
94
use spirv_std:: image:: sample_with:: lod;
93
95
96
+ pub const #entry_point_name: & str = core:: concat!( core:: module_path!( ) , "::entry_point" ) ;
97
+
94
98
pub struct Uniform {
95
99
#( #uniform_members) , *
96
100
}
@@ -107,10 +111,11 @@ impl PerPixelAdjust {
107
111
* color_out = color. to_vec4( ) ;
108
112
}
109
113
}
110
- } )
114
+ } ;
115
+ Ok ( ( shader_entry_point, entry_point_sym) )
111
116
}
112
117
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 > {
114
119
let fn_name = format_ident ! ( "{}_gpu" , parsed. fn_name) ;
115
120
let struct_name = format_ident ! ( "{}" , fn_name. to_string( ) . to_case( Case :: Pascal ) ) ;
116
121
let mod_name = fn_name. clone ( ) ;
@@ -121,7 +126,8 @@ impl PerPixelAdjust {
121
126
} ;
122
127
let raster_gpu: Type = parse_quote ! ( #gcore:: table:: Table <#gcore:: raster_types:: Raster <#gcore:: raster_types:: GPU >>) ;
123
128
124
- let fields = parsed
129
+ // adapt fields for gpu node
130
+ let mut fields = parsed
125
131
. fields
126
132
. iter ( )
127
133
. map ( |f| match & f. ty {
@@ -136,11 +142,55 @@ impl PerPixelAdjust {
136
142
ParsedFieldType :: Regular ( RegularParsedField { gpu_image : false , .. } ) => Ok ( f. clone ( ) ) ,
137
143
ParsedFieldType :: Node { .. } => Err ( syn:: Error :: new_spanned ( & f. pat_ident , "PerPixelAdjust shader nodes cannot accept other nodes as generics" ) ) ,
138
144
} )
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 ;
140
187
141
188
let body = quote ! {
142
189
{
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
144
194
}
145
195
} ;
146
196
@@ -174,6 +224,7 @@ impl PerPixelAdjust {
174
224
#node_cfg
175
225
mod #mod_name {
176
226
use super :: * ;
227
+ use wgpu_executor:: WgpuExecutor ;
177
228
178
229
#gpu_node
179
230
}
0 commit comments