gles3_builders.py 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559
  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 GLES3HeaderStruct:
  6. def __init__(self):
  7. self.vertex_lines = []
  8. self.fragment_lines = []
  9. self.uniforms = []
  10. self.fbos = []
  11. self.texunits = []
  12. self.texunit_names = []
  13. self.ubos = []
  14. self.ubo_names = []
  15. self.vertex_included_files = []
  16. self.fragment_included_files = []
  17. self.reading = ""
  18. self.line_offset = 0
  19. self.vertex_offset = 0
  20. self.fragment_offset = 0
  21. self.variant_defines = []
  22. self.variant_names = []
  23. self.specialization_names = []
  24. self.specialization_values = []
  25. def include_file_in_gles3_header(filename, header_data, depth):
  26. fs = open(filename, "r")
  27. line = fs.readline()
  28. while line:
  29. if line.find("=") != -1 and header_data.reading == "":
  30. # Mode
  31. eqpos = line.find("=")
  32. defname = line[:eqpos].strip().upper()
  33. define = line[eqpos + 1 :].strip()
  34. header_data.variant_names.append(defname)
  35. header_data.variant_defines.append(define)
  36. line = fs.readline()
  37. header_data.line_offset += 1
  38. header_data.vertex_offset = header_data.line_offset
  39. continue
  40. if line.find("=") != -1 and header_data.reading == "specializations":
  41. # Specialization
  42. eqpos = line.find("=")
  43. specname = line[:eqpos].strip()
  44. specvalue = line[eqpos + 1 :]
  45. header_data.specialization_names.append(specname)
  46. header_data.specialization_values.append(specvalue)
  47. line = fs.readline()
  48. header_data.line_offset += 1
  49. header_data.vertex_offset = header_data.line_offset
  50. continue
  51. if line.find("#[modes]") != -1:
  52. # Nothing really, just skip
  53. line = fs.readline()
  54. header_data.line_offset += 1
  55. header_data.vertex_offset = header_data.line_offset
  56. continue
  57. if line.find("#[specializations]") != -1:
  58. header_data.reading = "specializations"
  59. line = fs.readline()
  60. header_data.line_offset += 1
  61. header_data.vertex_offset = header_data.line_offset
  62. continue
  63. if line.find("#[vertex]") != -1:
  64. header_data.reading = "vertex"
  65. line = fs.readline()
  66. header_data.line_offset += 1
  67. header_data.vertex_offset = header_data.line_offset
  68. continue
  69. if line.find("#[fragment]") != -1:
  70. header_data.reading = "fragment"
  71. line = fs.readline()
  72. header_data.line_offset += 1
  73. header_data.fragment_offset = header_data.line_offset
  74. continue
  75. while line.find("#include ") != -1:
  76. includeline = line.replace("#include ", "").strip()[1:-1]
  77. import os.path
  78. included_file = os.path.relpath(os.path.dirname(filename) + "/" + includeline)
  79. if not included_file in header_data.vertex_included_files and header_data.reading == "vertex":
  80. header_data.vertex_included_files += [included_file]
  81. if include_file_in_gles3_header(included_file, header_data, depth + 1) is None:
  82. print("Error in file '" + filename + "': #include " + includeline + "could not be found!")
  83. elif not included_file in header_data.fragment_included_files and header_data.reading == "fragment":
  84. header_data.fragment_included_files += [included_file]
  85. if include_file_in_gles3_header(included_file, header_data, depth + 1) is None:
  86. print("Error in file '" + filename + "': #include " + includeline + "could not be found!")
  87. line = fs.readline()
  88. if line.find("uniform") != -1 and line.lower().find("texunit:") != -1:
  89. # texture unit
  90. texunitstr = line[line.find(":") + 1 :].strip()
  91. if texunitstr == "auto":
  92. texunit = "-1"
  93. else:
  94. texunit = str(int(texunitstr))
  95. uline = line[: line.lower().find("//")]
  96. uline = uline.replace("uniform", "")
  97. uline = uline.replace("highp", "")
  98. uline = uline.replace(";", "")
  99. lines = uline.split(",")
  100. for x in lines:
  101. x = x.strip()
  102. x = x[x.rfind(" ") + 1 :]
  103. if x.find("[") != -1:
  104. # unfiorm array
  105. x = x[: x.find("[")]
  106. if not x in header_data.texunit_names:
  107. header_data.texunits += [(x, texunit)]
  108. header_data.texunit_names += [x]
  109. elif line.find("uniform") != -1 and line.lower().find("ubo:") != -1:
  110. # uniform buffer object
  111. ubostr = line[line.find(":") + 1 :].strip()
  112. ubo = str(int(ubostr))
  113. uline = line[: line.lower().find("//")]
  114. uline = uline[uline.find("uniform") + len("uniform") :]
  115. uline = uline.replace("highp", "")
  116. uline = uline.replace(";", "")
  117. uline = uline.replace("{", "").strip()
  118. lines = uline.split(",")
  119. for x in lines:
  120. x = x.strip()
  121. x = x[x.rfind(" ") + 1 :]
  122. if x.find("[") != -1:
  123. # unfiorm array
  124. x = x[: x.find("[")]
  125. if not x in header_data.ubo_names:
  126. header_data.ubos += [(x, ubo)]
  127. header_data.ubo_names += [x]
  128. elif line.find("uniform") != -1 and line.find("{") == -1 and line.find(";") != -1:
  129. uline = line.replace("uniform", "")
  130. uline = uline.replace(";", "")
  131. lines = uline.split(",")
  132. for x in lines:
  133. x = x.strip()
  134. x = x[x.rfind(" ") + 1 :]
  135. if x.find("[") != -1:
  136. # unfiorm array
  137. x = x[: x.find("[")]
  138. if not x in header_data.uniforms:
  139. header_data.uniforms += [x]
  140. line = line.replace("\r", "")
  141. line = line.replace("\n", "")
  142. if header_data.reading == "vertex":
  143. header_data.vertex_lines += [line]
  144. if header_data.reading == "fragment":
  145. header_data.fragment_lines += [line]
  146. line = fs.readline()
  147. header_data.line_offset += 1
  148. fs.close()
  149. return header_data
  150. def build_gles3_header(filename, include, class_suffix, output_attribs):
  151. header_data = GLES3HeaderStruct()
  152. include_file_in_gles3_header(filename, header_data, 0)
  153. out_file = filename + ".gen.h"
  154. fd = open(out_file, "w")
  155. defspec = 0
  156. defvariant = ""
  157. enum_constants = []
  158. fd.write("/* WARNING, THIS FILE WAS GENERATED, DO NOT EDIT */\n")
  159. out_file_base = out_file
  160. out_file_base = out_file_base[out_file_base.rfind("/") + 1 :]
  161. out_file_base = out_file_base[out_file_base.rfind("\\") + 1 :]
  162. out_file_ifdef = out_file_base.replace(".", "_").upper()
  163. fd.write("#ifndef " + out_file_ifdef + class_suffix + "_GLES3\n")
  164. fd.write("#define " + out_file_ifdef + class_suffix + "_GLES3\n")
  165. out_file_class = (
  166. out_file_base.replace(".glsl.gen.h", "").title().replace("_", "").replace(".", "") + "Shader" + class_suffix
  167. )
  168. fd.write("\n\n")
  169. fd.write('#include "' + include + '"\n\n\n')
  170. fd.write("class " + out_file_class + " : public Shader" + class_suffix + " {\n\n")
  171. fd.write("public:\n\n")
  172. if header_data.uniforms:
  173. fd.write("\tenum Uniforms {\n")
  174. for x in header_data.uniforms:
  175. fd.write("\t\t" + x.upper() + ",\n")
  176. fd.write("\t};\n\n")
  177. if header_data.variant_names:
  178. fd.write("\tenum ShaderVariant {\n")
  179. for x in header_data.variant_names:
  180. fd.write("\t\t" + x + ",\n")
  181. fd.write("\t};\n\n")
  182. else:
  183. fd.write("\tenum ShaderVariant { DEFAULT };\n\n")
  184. defvariant = "=DEFAULT"
  185. if header_data.specialization_names:
  186. fd.write("\tenum Specializations {\n")
  187. counter = 0
  188. for x in header_data.specialization_names:
  189. fd.write("\t\t" + x.upper() + "=" + str(1 << counter) + ",\n")
  190. counter += 1
  191. fd.write("\t};\n\n")
  192. for i in range(len(header_data.specialization_names)):
  193. defval = header_data.specialization_values[i].strip()
  194. if defval.upper() == "TRUE" or defval == "1":
  195. defspec |= 1 << i
  196. fd.write(
  197. "\t_FORCE_INLINE_ void version_bind_shader(RID p_version,ShaderVariant p_variant"
  198. + defvariant
  199. + ",uint64_t p_specialization="
  200. + str(defspec)
  201. + ") { _version_bind_shader(p_version,p_variant,p_specialization); }\n\n"
  202. )
  203. if header_data.uniforms:
  204. fd.write(
  205. "\t_FORCE_INLINE_ int version_get_uniform(Uniforms p_uniform,RID p_version,ShaderVariant p_variant"
  206. + defvariant
  207. + ",uint64_t p_specialization="
  208. + str(defspec)
  209. + ") { return _version_get_uniform(p_uniform,p_version,p_variant,p_specialization); }\n\n"
  210. )
  211. fd.write(
  212. "\t#define _FU if (version_get_uniform(p_uniform,p_version,p_variant,p_specialization)<0) return; \n\n "
  213. )
  214. fd.write(
  215. "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, float p_value,RID p_version,ShaderVariant p_variant"
  216. + defvariant
  217. + ",uint64_t p_specialization="
  218. + str(defspec)
  219. + ") { _FU glUniform1f(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_value); }\n\n"
  220. )
  221. fd.write(
  222. "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, double p_value,RID p_version,ShaderVariant p_variant"
  223. + defvariant
  224. + ",uint64_t p_specialization="
  225. + str(defspec)
  226. + ") { _FU glUniform1f(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_value); }\n\n"
  227. )
  228. fd.write(
  229. "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, uint8_t p_value,RID p_version,ShaderVariant p_variant"
  230. + defvariant
  231. + ",uint64_t p_specialization="
  232. + str(defspec)
  233. + ") { _FU glUniform1i(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_value); }\n\n"
  234. )
  235. fd.write(
  236. "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, int8_t p_value,RID p_version,ShaderVariant p_variant"
  237. + defvariant
  238. + ",uint64_t p_specialization="
  239. + str(defspec)
  240. + ") { _FU glUniform1i(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_value); }\n\n"
  241. )
  242. fd.write(
  243. "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, uint16_t p_value,RID p_version,ShaderVariant p_variant"
  244. + defvariant
  245. + ",uint64_t p_specialization="
  246. + str(defspec)
  247. + ") { _FU glUniform1i(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_value); }\n\n"
  248. )
  249. fd.write(
  250. "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, int16_t p_value,RID p_version,ShaderVariant p_variant"
  251. + defvariant
  252. + ",uint64_t p_specialization="
  253. + str(defspec)
  254. + ") { _FU glUniform1i(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_value); }\n\n"
  255. )
  256. fd.write(
  257. "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, uint32_t p_value,RID p_version,ShaderVariant p_variant"
  258. + defvariant
  259. + ",uint64_t p_specialization="
  260. + str(defspec)
  261. + ") { _FU glUniform1i(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_value); }\n\n"
  262. )
  263. fd.write(
  264. "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, int32_t p_value,RID p_version,ShaderVariant p_variant"
  265. + defvariant
  266. + ",uint64_t p_specialization="
  267. + str(defspec)
  268. + ") { _FU glUniform1i(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_value); }\n\n"
  269. )
  270. fd.write(
  271. "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const Color& p_color,RID p_version,ShaderVariant p_variant"
  272. + defvariant
  273. + ",uint64_t p_specialization="
  274. + str(defspec)
  275. + ") { _FU GLfloat col[4]={p_color.r,p_color.g,p_color.b,p_color.a}; glUniform4fv(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),1,col); }\n\n"
  276. )
  277. fd.write(
  278. "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const Vector2& p_vec2,RID p_version,ShaderVariant p_variant"
  279. + defvariant
  280. + ",uint64_t p_specialization="
  281. + str(defspec)
  282. + ") { _FU GLfloat vec2[2]={float(p_vec2.x),float(p_vec2.y)}; glUniform2fv(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),1,vec2); }\n\n"
  283. )
  284. fd.write(
  285. "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const Size2i& p_vec2,RID p_version,ShaderVariant p_variant"
  286. + defvariant
  287. + ",uint64_t p_specialization="
  288. + str(defspec)
  289. + ") { _FU GLint vec2[2]={GLint(p_vec2.x),GLint(p_vec2.y)}; glUniform2iv(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),1,vec2); }\n\n"
  290. )
  291. fd.write(
  292. "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const Vector3& p_vec3,RID p_version,ShaderVariant p_variant"
  293. + defvariant
  294. + ",uint64_t p_specialization="
  295. + str(defspec)
  296. + ") { _FU GLfloat vec3[3]={float(p_vec3.x),float(p_vec3.y),float(p_vec3.z)}; glUniform3fv(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),1,vec3); }\n\n"
  297. )
  298. fd.write(
  299. "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, float p_a, float p_b,RID p_version,ShaderVariant p_variant"
  300. + defvariant
  301. + ",uint64_t p_specialization="
  302. + str(defspec)
  303. + ") { _FU glUniform2f(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_a,p_b); }\n\n"
  304. )
  305. fd.write(
  306. "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, float p_a, float p_b, float p_c,RID p_version,ShaderVariant p_variant"
  307. + defvariant
  308. + ",uint64_t p_specialization="
  309. + str(defspec)
  310. + ") { _FU glUniform3f(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_a,p_b,p_c); }\n\n"
  311. )
  312. fd.write(
  313. "\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, float p_a, float p_b, float p_c, float p_d,RID p_version,ShaderVariant p_variant"
  314. + defvariant
  315. + ",uint64_t p_specialization="
  316. + str(defspec)
  317. + ") { _FU glUniform4f(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),p_a,p_b,p_c,p_d); }\n\n"
  318. )
  319. fd.write(
  320. """\t_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const Transform3D& p_transform,RID p_version,ShaderVariant p_variant"""
  321. + defvariant
  322. + """,uint64_t p_specialization="""
  323. + str(defspec)
  324. + """) { _FU
  325. const Transform3D &tr = p_transform;
  326. GLfloat matrix[16]={ /* build a 16x16 matrix */
  327. (GLfloat)tr.basis.elements[0][0],
  328. (GLfloat)tr.basis.elements[1][0],
  329. (GLfloat)tr.basis.elements[2][0],
  330. (GLfloat)0,
  331. (GLfloat)tr.basis.elements[0][1],
  332. (GLfloat)tr.basis.elements[1][1],
  333. (GLfloat)tr.basis.elements[2][1],
  334. (GLfloat)0,
  335. (GLfloat)tr.basis.elements[0][2],
  336. (GLfloat)tr.basis.elements[1][2],
  337. (GLfloat)tr.basis.elements[2][2],
  338. (GLfloat)0,
  339. (GLfloat)tr.origin.x,
  340. (GLfloat)tr.origin.y,
  341. (GLfloat)tr.origin.z,
  342. (GLfloat)1
  343. };
  344. glUniformMatrix4fv(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),1,false,matrix);
  345. }
  346. """
  347. )
  348. fd.write(
  349. """_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const Transform2D& p_transform,RID p_version,ShaderVariant p_variant"""
  350. + defvariant
  351. + """,uint64_t p_specialization="""
  352. + str(defspec)
  353. + """) { _FU
  354. const Transform2D &tr = p_transform;
  355. GLfloat matrix[16]={ /* build a 16x16 matrix */
  356. (GLfloat)tr.elements[0][0],
  357. (GLfloat)tr.elements[0][1],
  358. (GLfloat)0,
  359. (GLfloat)0,
  360. (GLfloat)tr.elements[1][0],
  361. (GLfloat)tr.elements[1][1],
  362. (GLfloat)0,
  363. (GLfloat)0,
  364. (GLfloat)0,
  365. (GLfloat)0,
  366. (GLfloat)1,
  367. (GLfloat)0,
  368. (GLfloat)tr.elements[2][0],
  369. (GLfloat)tr.elements[2][1],
  370. (GLfloat)0,
  371. (GLfloat)1
  372. };
  373. glUniformMatrix4fv(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),1,false,matrix);
  374. }
  375. """
  376. )
  377. fd.write(
  378. """_FORCE_INLINE_ void version_set_uniform(Uniforms p_uniform, const CameraMatrix& p_matrix,RID p_version,ShaderVariant p_variant"""
  379. + defvariant
  380. + """,uint64_t p_specialization="""
  381. + str(defspec)
  382. + """) { _FU
  383. GLfloat matrix[16];
  384. for (int i=0;i<4;i++) {
  385. for (int j=0;j<4;j++) {
  386. matrix[i*4+j]=p_matrix.matrix[i][j];
  387. }
  388. }
  389. glUniformMatrix4fv(version_get_uniform(p_uniform,p_version,p_variant,p_specialization),1,false,matrix);
  390. }"""
  391. )
  392. fd.write("\n\n#undef _FU\n\n\n")
  393. fd.write("protected:\n\n")
  394. fd.write("\tvirtual void _init() override {\n\n")
  395. if header_data.uniforms:
  396. fd.write("\t\tstatic const char* _uniform_strings[]={\n")
  397. if header_data.uniforms:
  398. for x in header_data.uniforms:
  399. fd.write('\t\t\t"' + x + '",\n')
  400. fd.write("\t\t};\n\n")
  401. else:
  402. fd.write("\t\tstatic const char **_uniform_strings=nullptr;\n")
  403. variant_count = 1
  404. if len(header_data.variant_defines) > 0:
  405. fd.write("\t\tstatic const char* _variant_defines[]={\n")
  406. for x in header_data.variant_defines:
  407. fd.write('\t\t\t"' + x + '",\n')
  408. fd.write("\t\t};\n\n")
  409. variant_count = len(header_data.variant_defines)
  410. else:
  411. fd.write("\t\tstatic const char **_variant_defines[]={" "};\n")
  412. if header_data.texunits:
  413. fd.write("\t\tstatic TexUnitPair _texunit_pairs[]={\n")
  414. for x in header_data.texunits:
  415. fd.write('\t\t\t{"' + x[0] + '",' + x[1] + "},\n")
  416. fd.write("\t\t};\n\n")
  417. else:
  418. fd.write("\t\tstatic TexUnitPair *_texunit_pairs=nullptr;\n")
  419. if header_data.ubos:
  420. fd.write("\t\tstatic UBOPair _ubo_pairs[]={\n")
  421. for x in header_data.ubos:
  422. fd.write('\t\t\t{"' + x[0] + '",' + x[1] + "},\n")
  423. fd.write("\t\t};\n\n")
  424. else:
  425. fd.write("\t\tstatic UBOPair *_ubo_pairs=nullptr;\n")
  426. if header_data.specialization_names:
  427. fd.write("\t\tstatic Specialization _spec_pairs[]={\n")
  428. for i in range(len(header_data.specialization_names)):
  429. defval = header_data.specialization_values[i].strip()
  430. if defval.upper() == "TRUE" or defval == "1":
  431. defval = "true"
  432. else:
  433. defval = "false"
  434. fd.write('\t\t\t{"' + header_data.specialization_names[i] + '",' + defval + "},\n")
  435. fd.write("\t\t};\n\n")
  436. else:
  437. fd.write("\t\tstatic Specialization *_spec_pairs=nullptr;\n")
  438. fd.write("\t\tstatic const char _vertex_code[]={\n")
  439. for x in header_data.vertex_lines:
  440. for c in x:
  441. fd.write(str(ord(c)) + ",")
  442. fd.write(str(ord("\n")) + ",")
  443. fd.write("\t\t0};\n\n")
  444. fd.write("\t\tstatic const char _fragment_code[]={\n")
  445. for x in header_data.fragment_lines:
  446. for c in x:
  447. fd.write(str(ord(c)) + ",")
  448. fd.write(str(ord("\n")) + ",")
  449. fd.write("\t\t0};\n\n")
  450. fd.write(
  451. '\t\t_setup(_vertex_code,_fragment_code,"'
  452. + out_file_class
  453. + '",'
  454. + str(len(header_data.uniforms))
  455. + ",_uniform_strings,"
  456. + str(len(header_data.ubos))
  457. + ",_ubo_pairs,"
  458. + str(len(header_data.texunits))
  459. + ",_texunit_pairs,"
  460. + str(len(header_data.specialization_names))
  461. + ",_spec_pairs,"
  462. + str(variant_count)
  463. + ",_variant_defines);\n"
  464. )
  465. fd.write("\t}\n\n")
  466. fd.write("};\n\n")
  467. fd.write("#endif\n\n")
  468. fd.close()
  469. def build_gles3_headers(target, source, env):
  470. for x in source:
  471. build_gles3_header(str(x), include="drivers/gles3/shader_gles3.h", class_suffix="GLES3", output_attribs=True)
  472. if __name__ == "__main__":
  473. subprocess_main(globals())