glsl_builders.py 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. """Functions used to generate source files during build time
  2. All such functions are invoked in a subprocess on Windows to prevent build flakiness.
  3. """
  4. from platform_methods import subprocess_main
  5. class RDHeaderStruct:
  6. def __init__(self):
  7. self.vertex_lines = []
  8. self.fragment_lines = []
  9. self.compute_lines = []
  10. self.vertex_included_files = []
  11. self.fragment_included_files = []
  12. self.compute_included_files = []
  13. self.reading = ""
  14. self.line_offset = 0
  15. self.vertex_offset = 0
  16. self.fragment_offset = 0
  17. self.compute_offset = 0
  18. def include_file_in_rd_header(filename, header_data, depth):
  19. fs = open(filename, "r")
  20. line = fs.readline()
  21. while line:
  22. if line.find("#[vertex]") != -1:
  23. header_data.reading = "vertex"
  24. line = fs.readline()
  25. header_data.line_offset += 1
  26. header_data.vertex_offset = header_data.line_offset
  27. continue
  28. if line.find("#[fragment]") != -1:
  29. header_data.reading = "fragment"
  30. line = fs.readline()
  31. header_data.line_offset += 1
  32. header_data.fragment_offset = header_data.line_offset
  33. continue
  34. if line.find("#[compute]") != -1:
  35. header_data.reading = "compute"
  36. line = fs.readline()
  37. header_data.line_offset += 1
  38. header_data.compute_offset = header_data.line_offset
  39. continue
  40. while line.find("#include ") != -1:
  41. includeline = line.replace("#include ", "").strip()[1:-1]
  42. import os.path
  43. included_file = os.path.relpath(os.path.dirname(filename) + "/" + includeline)
  44. if not included_file in header_data.vertex_included_files and header_data.reading == "vertex":
  45. header_data.vertex_included_files += [included_file]
  46. if include_file_in_rd_header(included_file, header_data, depth + 1) is None:
  47. print("Error in file '" + filename + "': #include " + includeline + "could not be found!")
  48. elif not included_file in header_data.fragment_included_files and header_data.reading == "fragment":
  49. header_data.fragment_included_files += [included_file]
  50. if include_file_in_rd_header(included_file, header_data, depth + 1) is None:
  51. print("Error in file '" + filename + "': #include " + includeline + "could not be found!")
  52. elif not included_file in header_data.compute_included_files and header_data.reading == "compute":
  53. header_data.compute_included_files += [included_file]
  54. if include_file_in_rd_header(included_file, header_data, depth + 1) is None:
  55. print("Error in file '" + filename + "': #include " + includeline + "could not be found!")
  56. line = fs.readline()
  57. line = line.replace("\r", "")
  58. line = line.replace("\n", "")
  59. if header_data.reading == "vertex":
  60. header_data.vertex_lines += [line]
  61. if header_data.reading == "fragment":
  62. header_data.fragment_lines += [line]
  63. if header_data.reading == "compute":
  64. header_data.compute_lines += [line]
  65. line = fs.readline()
  66. header_data.line_offset += 1
  67. fs.close()
  68. return header_data
  69. def build_rd_header(filename):
  70. header_data = RDHeaderStruct()
  71. include_file_in_rd_header(filename, header_data, 0)
  72. out_file = filename + ".gen.h"
  73. fd = open(out_file, "w")
  74. fd.write("/* WARNING, THIS FILE WAS GENERATED, DO NOT EDIT */\n")
  75. out_file_base = out_file
  76. out_file_base = out_file_base[out_file_base.rfind("/") + 1 :]
  77. out_file_base = out_file_base[out_file_base.rfind("\\") + 1 :]
  78. out_file_ifdef = out_file_base.replace(".", "_").upper()
  79. fd.write("#ifndef " + out_file_ifdef + "_RD\n")
  80. fd.write("#define " + out_file_ifdef + "_RD\n")
  81. out_file_class = out_file_base.replace(".glsl.gen.h", "").title().replace("_", "").replace(".", "") + "ShaderRD"
  82. fd.write("\n")
  83. fd.write('#include "servers/rendering/renderer_rd/shader_rd.h"\n\n')
  84. fd.write("class " + out_file_class + " : public ShaderRD {\n\n")
  85. fd.write("public:\n\n")
  86. fd.write("\t" + out_file_class + "() {\n\n")
  87. if len(header_data.compute_lines):
  88. fd.write("\t\tstatic const char _compute_code[] = {\n")
  89. for x in header_data.compute_lines:
  90. for c in x:
  91. fd.write(str(ord(c)) + ",")
  92. fd.write(str(ord("\n")) + ",")
  93. fd.write("\t\t0};\n\n")
  94. fd.write('\t\tsetup(nullptr, nullptr, _compute_code, "' + out_file_class + '");\n')
  95. fd.write("\t}\n")
  96. else:
  97. fd.write("\t\tstatic const char _vertex_code[] = {\n")
  98. for x in header_data.vertex_lines:
  99. for c in x:
  100. fd.write(str(ord(c)) + ",")
  101. fd.write(str(ord("\n")) + ",")
  102. fd.write("\t\t0};\n\n")
  103. fd.write("\t\tstatic const char _fragment_code[]={\n")
  104. for x in header_data.fragment_lines:
  105. for c in x:
  106. fd.write(str(ord(c)) + ",")
  107. fd.write(str(ord("\n")) + ",")
  108. fd.write("\t\t0};\n\n")
  109. fd.write('\t\tsetup(_vertex_code, _fragment_code, nullptr, "' + out_file_class + '");\n')
  110. fd.write("\t}\n")
  111. fd.write("};\n\n")
  112. fd.write("#endif\n")
  113. fd.close()
  114. def build_rd_headers(target, source, env):
  115. for x in source:
  116. build_rd_header(str(x))
  117. class RAWHeaderStruct:
  118. def __init__(self):
  119. self.code = ""
  120. def include_file_in_raw_header(filename, header_data, depth):
  121. fs = open(filename, "r")
  122. line = fs.readline()
  123. while line:
  124. while line.find("#include ") != -1:
  125. includeline = line.replace("#include ", "").strip()[1:-1]
  126. import os.path
  127. included_file = os.path.relpath(os.path.dirname(filename) + "/" + includeline)
  128. include_file_in_raw_header(included_file, header_data, depth + 1)
  129. line = fs.readline()
  130. header_data.code += line
  131. line = fs.readline()
  132. fs.close()
  133. def build_raw_header(filename):
  134. header_data = RAWHeaderStruct()
  135. include_file_in_raw_header(filename, header_data, 0)
  136. out_file = filename + ".gen.h"
  137. fd = open(out_file, "w")
  138. fd.write("/* WARNING, THIS FILE WAS GENERATED, DO NOT EDIT */\n")
  139. out_file_base = out_file.replace(".glsl.gen.h", "_shader_glsl")
  140. out_file_base = out_file_base[out_file_base.rfind("/") + 1 :]
  141. out_file_base = out_file_base[out_file_base.rfind("\\") + 1 :]
  142. out_file_ifdef = out_file_base.replace(".", "_").upper()
  143. fd.write("#ifndef " + out_file_ifdef + "_RAW_H\n")
  144. fd.write("#define " + out_file_ifdef + "_RAW_H\n")
  145. fd.write("\n")
  146. fd.write("static const char " + out_file_base + "[] = {\n")
  147. for c in header_data.code:
  148. fd.write(str(ord(c)) + ",")
  149. fd.write("\t\t0};\n\n")
  150. fd.write("#endif\n")
  151. fd.close()
  152. def build_raw_headers(target, source, env):
  153. for x in source:
  154. build_raw_header(str(x))
  155. if __name__ == "__main__":
  156. subprocess_main(globals())