11use std:: {
2+ collections:: BTreeMap ,
23 error:: Error ,
34 path:: { Path , PathBuf } ,
45 str:: FromStr ,
56} ;
67
8+ use rust_gpu_builder_shared:: { RustGpuBuilderModules , RustGpuBuilderOutput } ;
9+
710use clap:: { error:: ErrorKind , Parser } ;
811
912use async_channel:: { unbounded, Receiver , Sender } ;
@@ -25,6 +28,8 @@ use tracing::{error, info};
2528struct ShaderBuilder {
2629 /// Shader crate to compile.
2730 path_to_crate : PathBuf ,
31+ /// If set, combined SPIR-V and entrypoint metadata will be written to this file on succesful compile.
32+ output_path : Option < PathBuf > ,
2833 /// rust-gpu compile target.
2934 #[ arg( short, long, default_value = "spirv-unknown-vulkan1.2" ) ]
3035 target : String ,
@@ -184,6 +189,66 @@ async fn async_watch<P: AsRef<Path>>(
184189 Ok ( ( ) )
185190}
186191
192+ async fn handle_compile_result ( result : CompileResult , output_path : Option < PathBuf > ) {
193+ info ! ( "Entry Points:" ) ;
194+ for entry in & result. entry_points {
195+ println ! ( "{entry:}" ) ;
196+ }
197+
198+ let entry_points = result. entry_points ;
199+
200+ println ! ( ) ;
201+
202+ info ! ( "Modules:" ) ;
203+ match & result. module {
204+ spirv_builder:: ModuleResult :: SingleModule ( single) => {
205+ println ! ( "{single:?}" ) ;
206+ }
207+
208+ spirv_builder:: ModuleResult :: MultiModule ( multi) => {
209+ for ( k, module) in multi {
210+ println ! ( "{k:}: {module:?}" ) ;
211+ }
212+ }
213+ } ;
214+
215+ let Some ( output_path) = output_path else {
216+ return
217+ } ;
218+
219+ let modules = match result. module {
220+ spirv_builder:: ModuleResult :: SingleModule ( single) => {
221+ let module = async_fs:: read ( single)
222+ . await
223+ . expect ( "Failed to read module file" ) ;
224+ RustGpuBuilderModules :: Single ( module)
225+ }
226+
227+ spirv_builder:: ModuleResult :: MultiModule ( multi) => {
228+ let mut out = BTreeMap :: default ( ) ;
229+ for ( k, module) in multi {
230+ let module = async_fs:: read ( module)
231+ . await
232+ . expect ( "Failed to read module file" ) ;
233+ out. insert ( k, module) ;
234+ }
235+ RustGpuBuilderModules :: Multi ( out)
236+ }
237+ } ;
238+
239+ let out = RustGpuBuilderOutput {
240+ entry_points,
241+ modules,
242+ } ;
243+
244+ let out = serde_json:: to_string_pretty ( & out) . expect ( "Failed to serialize output" ) ;
245+ async_fs:: write ( & output_path, out)
246+ . await
247+ . expect ( "Failed to write output" ) ;
248+ println ! ( ) ;
249+ info ! ( "Wrote output to {output_path:?}" ) ;
250+ }
251+
187252fn main ( ) {
188253 tracing_subscriber:: fmt ( ) . init ( ) ;
189254
@@ -194,8 +259,9 @@ fn main() {
194259 println ! ( ) ;
195260
196261 info ! ( "Building shader..." ) ;
197- if args. build_shader ( ) . is_ok ( ) {
198- info ! ( "Build complete!" ) ;
262+ println ! ( ) ;
263+ if let Ok ( result) = args. build_shader ( ) {
264+ future:: block_on ( handle_compile_result ( result, args. output_path . clone ( ) ) ) ;
199265 } else {
200266 error ! ( "Build failed!" ) ;
201267 }
@@ -227,7 +293,9 @@ fn main() {
227293 Ok ( Msg :: Change ) => {
228294 if !building {
229295 building = true ;
296+ println ! ( ) ;
230297 info ! ( "Building shader..." ) ;
298+ println ! ( ) ;
231299 ex. spawn ( {
232300 let build_tx = build_tx. clone ( ) ;
233301 let args = args. clone ( ) ;
@@ -242,8 +310,10 @@ fn main() {
242310 }
243311 }
244312 Ok ( Msg :: Build ( result) ) => {
245- if result. is_ok ( ) {
246- info ! ( "Build complete!" ) ;
313+ if let Ok ( result) = result {
314+ let output_path = args. output_path . clone ( ) ;
315+ ex. spawn ( handle_compile_result ( result, output_path) )
316+ . detach ( ) ;
247317 } else {
248318 error ! ( "Build failed!" ) ;
249319 }
0 commit comments