@@ -845,85 +845,88 @@ def generateSPV( # noqa: C901
845845 ) -> Dict [str , str ]:
846846 output_file_map = {}
847847
848- def process_shader (shader_paths_pair ):
848+ def generate_src_file (shader_paths_pair ):
849+ # Extract components from the input tuple
850+ # name of .glsl, .glslh, or .h to be generated
849851 src_file_name = shader_paths_pair [0 ]
850-
852+ # path of template file used for codegen
851853 src_file_fullpath = shader_paths_pair [1 ][0 ]
854+ # args to be used for codegen
852855 codegen_params = shader_paths_pair [1 ][1 ]
853856
854- requires_codegen = True
855- if "YAML_SRC_FULLPATH" not in codegen_params :
856- requires_codegen = False
857-
857+ # Assume that generated files will have the same file extension as the
858+ # source template file.
858859 src_file_ext = extract_extension (src_file_fullpath )
859860 out_file_ext = src_file_ext
860- compile_spv = False
861861
862- if out_file_ext == "glsl" :
863- compile_spv = True
862+ # Construct generated file name
863+ gen_out_path = os .path .join (output_dir , f"{ src_file_name } .{ out_file_ext } " )
864+ # Construct path of cached generated file
865+ cached_gen_out_path = os .path .join (
866+ cache_dir , f"{ src_file_name } .{ out_file_ext } "
867+ )
868+
869+ # Execute codegen to generate the output file
870+ with codecs .open (src_file_fullpath , "r" , encoding = "utf-8" ) as input_file :
871+ input_text = input_file .read ()
872+ input_text = self .maybe_replace_u16vecn (input_text )
873+ output_text = preprocess (input_text , codegen_params )
874+
875+ with codecs .open (gen_out_path , "w" , encoding = "utf-8" ) as output_file :
876+ output_file .write (output_text )
877+
878+ if cache_dir is not None :
879+ # Store the generated file in the cache for SPIR-V compilation
880+ shutil .copyfile (gen_out_path , cached_gen_out_path )
864881
882+ def compile_spirv (shader_paths_pair ):
883+ # Extract components from the input tuple
884+ # name of generated .glsl, .glslh, or .h
885+ src_file_name = shader_paths_pair [0 ]
886+ # path of template file used for codegen
887+ src_file_fullpath = shader_paths_pair [1 ][0 ]
888+
889+ # Assume that generated files will have the same file extension as the
890+ # source template file.
891+ src_file_ext = extract_extension (src_file_fullpath )
892+ out_file_ext = src_file_ext
893+
894+ # Infer name of generated file (created by generate_src_file)
865895 gen_out_path = os .path .join (output_dir , f"{ src_file_name } .{ out_file_ext } " )
866- spv_out_path = None
867- if compile_spv :
868- spv_out_path = os .path .join (output_dir , f"{ src_file_name } .spv" )
896+
897+ # Only proceed if GLSL -> SPIR-V compilation is required for this file
898+ if out_file_ext != "glsl" :
899+ return (None , gen_out_path )
900+
901+ # Construct name of SPIR-V file to be compiled, if needed
902+ spv_out_path = os .path .join (output_dir , f"{ src_file_name } .spv" )
869903
870904 if cache_dir is not None :
871- cached_src_file_fullpath = os .path .join (
872- cache_dir , os .path .basename (src_file_fullpath ) + ".t"
873- )
874- cached_codegen_yaml = os .path .join (cache_dir , f"{ src_file_name } .yaml" )
905+ # Construct the file names of cached SPIR-V file to check if they exist
906+ # in the cache.
875907 cached_gen_out_path = os .path .join (
876908 cache_dir , f"{ src_file_name } .{ out_file_ext } "
877909 )
878910 cached_spv_out_path = os .path .join (cache_dir , f"{ src_file_name } .spv" )
911+
912+ # Only use cached artifacts if all of the expected artifacts are present
879913 if (
880914 not force_rebuild
881- and os .path .exists (cached_src_file_fullpath )
882915 and os .path .exists (cached_gen_out_path )
883- and (not requires_codegen or os .path .exists (cached_codegen_yaml ))
884- and (not compile_spv or os .path .exists (cached_spv_out_path ))
916+ and os .path .exists (cached_spv_out_path )
885917 ):
886- current_checksum = self .get_md5_checksum (src_file_fullpath )
887- cached_checksum = self .get_md5_checksum (cached_src_file_fullpath )
888- yaml_unchanged = True
889- if requires_codegen :
890- yaml_file_fullpath = codegen_params ["YAML_SRC_FULLPATH" ]
891- current_yaml_checksum = self .get_md5_checksum (
892- yaml_file_fullpath
893- )
894- cached_yaml_checksum = self .get_md5_checksum (
895- cached_codegen_yaml
896- )
897- yaml_unchanged = current_yaml_checksum == cached_yaml_checksum
898- # If the cached source GLSL template is the same as the current GLSL
899- # source file, then assume that the generated GLSL and SPIR-V will
900- # not have changed. In that case, just copy over the GLSL and SPIR-V
901- # files from the cache.
902- if yaml_unchanged and current_checksum == cached_checksum :
903- shutil .copyfile (cached_gen_out_path , gen_out_path )
904- if compile_spv :
905- shutil .copyfile (cached_spv_out_path , spv_out_path )
918+ current_checksum = self .get_md5_checksum (gen_out_path )
919+ cached_checksum = self .get_md5_checksum (cached_gen_out_path )
920+ # If the cached generated GLSL file is the same as the current GLSL
921+ # generated file, then assume that the generated GLSL and SPIR-V
922+ # will not have changed. In that case, just copy over the GLSL and
923+ # SPIR-V files from the cache and return.
924+ if current_checksum == cached_checksum :
925+ shutil .copyfile (cached_spv_out_path , spv_out_path )
906926 return (spv_out_path , gen_out_path )
907927
908- with codecs .open (src_file_fullpath , "r" , encoding = "utf-8" ) as input_file :
909- input_text = input_file .read ()
910- input_text = self .maybe_replace_u16vecn (input_text )
911- output_text = preprocess (input_text , codegen_params )
912-
913- with codecs .open (gen_out_path , "w" , encoding = "utf-8" ) as output_file :
914- output_file .write (output_text )
915-
916- if cache_dir is not None :
917- # Otherwise, store the generated GLSL files in the cache
918- shutil .copyfile (gen_out_path , cached_gen_out_path )
919- # If a YAML file was used to configure codegen, cache it as well
920- if requires_codegen :
921- yaml_file_fullpath = codegen_params ["YAML_SRC_FULLPATH" ]
922- shutil .copyfile (yaml_file_fullpath , cached_codegen_yaml )
923-
924- # If no GLSL compiler is specified, or the source file is not a GLSL shader
925- # then only write out the generated GLSL shaders.
926- if compile_spv and self .glslc_path is not None :
928+ # Only proceed if a GLSL compiler was specified
929+ if self .glslc_path is not None :
927930 cmd_base = [
928931 self .glslc_path ,
929932 "-fshader-stage=compute" ,
@@ -961,10 +964,15 @@ def process_shader(shader_paths_pair):
961964
962965 return (spv_out_path , gen_out_path )
963966
964- # Parallelize shader compilation as much as possible to optimize build time.
967+ # Run codegen serially to ensure that all .glsl, .glslh, and .h files are up to
968+ # date before compilation
969+ for generated_file_tuple in self .output_file_map .items ():
970+ generate_src_file (generated_file_tuple )
971+
972+ # Parallelize SPIR-V compilation to optimize build time
965973 with ThreadPool (os .cpu_count ()) as pool :
966974 for spv_out_path , glsl_out_path in pool .map (
967- process_shader , self .output_file_map .items ()
975+ compile_spirv , self .output_file_map .items ()
968976 ):
969977 output_file_map [spv_out_path ] = glsl_out_path
970978
0 commit comments