@@ -845,85 +845,88 @@ def generateSPV( # noqa: C901
845
845
) -> Dict [str , str ]:
846
846
output_file_map = {}
847
847
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
849
851
src_file_name = shader_paths_pair [0 ]
850
-
852
+ # path of template file used for codegen
851
853
src_file_fullpath = shader_paths_pair [1 ][0 ]
854
+ # args to be used for codegen
852
855
codegen_params = shader_paths_pair [1 ][1 ]
853
856
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.
858
859
src_file_ext = extract_extension (src_file_fullpath )
859
860
out_file_ext = src_file_ext
860
- compile_spv = False
861
861
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 )
864
881
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)
865
895
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" )
869
903
870
904
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.
875
907
cached_gen_out_path = os .path .join (
876
908
cache_dir , f"{ src_file_name } .{ out_file_ext } "
877
909
)
878
910
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
879
913
if (
880
914
not force_rebuild
881
- and os .path .exists (cached_src_file_fullpath )
882
915
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 )
885
917
):
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 )
906
926
return (spv_out_path , gen_out_path )
907
927
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 :
927
930
cmd_base = [
928
931
self .glslc_path ,
929
932
"-fshader-stage=compute" ,
@@ -961,10 +964,15 @@ def process_shader(shader_paths_pair):
961
964
962
965
return (spv_out_path , gen_out_path )
963
966
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
965
973
with ThreadPool (os .cpu_count ()) as pool :
966
974
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 ()
968
976
):
969
977
output_file_map [spv_out_path ] = glsl_out_path
970
978
0 commit comments