shader_resource.cpp 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321
  1. /*
  2. * Copyright (c) 2012-2023 Daniele Bartolini et al.
  3. * SPDX-License-Identifier: MIT
  4. */
  5. #include "config.h"
  6. #include "core/containers/hash_map.inl"
  7. #include "core/containers/vector.inl"
  8. #include "core/filesystem/filesystem.h"
  9. #include "core/json/json_object.inl"
  10. #include "core/json/sjson.h"
  11. #include "core/memory/temp_allocator.inl"
  12. #include "core/process.h"
  13. #include "core/strings/dynamic_string.inl"
  14. #include "core/strings/string_stream.inl"
  15. #include "device/device.h"
  16. #include "resource/compile_options.inl"
  17. #include "resource/resource_manager.h"
  18. #include "resource/shader_resource.h"
  19. #include "world/shader_manager.h"
  20. namespace crown
  21. {
  22. namespace shader_resource_internal
  23. {
  24. void *load(File &file, Allocator &a)
  25. {
  26. return device()->_shader_manager->load(file, a);
  27. }
  28. void online(StringId64 id, ResourceManager &rm)
  29. {
  30. device()->_shader_manager->online(id, rm);
  31. }
  32. void offline(StringId64 id, ResourceManager &rm)
  33. {
  34. device()->_shader_manager->offline(id, rm);
  35. }
  36. void unload(Allocator &a, void *res)
  37. {
  38. device()->_shader_manager->unload(a, res);
  39. }
  40. } // namespace shader_resource_internal
  41. #if CROWN_CAN_COMPILE
  42. namespace shader_resource_internal
  43. {
  44. static const char *shaderc_platform[] =
  45. {
  46. "android", // Platform::ANDROID
  47. "android", // Platform::ANDROID_ARM64
  48. "asm.js", // Platform::HTML5
  49. "linux", // Platform::LINUX
  50. "windows" // Platform::WINDOWS
  51. };
  52. CE_STATIC_ASSERT(countof(shaderc_platform) == Platform::COUNT);
  53. static const char *shaderc_paths[] =
  54. {
  55. EXE_PATH("shaderc"),
  56. #if CROWN_DEBUG
  57. EXE_PATH("shaderc-debug")
  58. #elif CROWN_DEVELOPMENT
  59. EXE_PATH("shaderc-development")
  60. #else
  61. EXE_PATH("shaderc-release")
  62. #endif
  63. };
  64. struct DepthFunction
  65. {
  66. enum Enum
  67. {
  68. LESS,
  69. LEQUAL,
  70. EQUAL,
  71. GEQUAL,
  72. GREATER,
  73. NOTEQUAL,
  74. NEVER,
  75. ALWAYS,
  76. COUNT
  77. };
  78. };
  79. struct BlendFunction
  80. {
  81. enum Enum
  82. {
  83. ZERO,
  84. ONE,
  85. SRC_COLOR,
  86. INV_SRC_COLOR,
  87. SRC_ALPHA,
  88. INV_SRC_ALPHA,
  89. DST_ALPHA,
  90. INV_DST_ALPHA,
  91. DST_COLOR,
  92. INV_DST_COLOR,
  93. SRC_ALPHA_SAT,
  94. FACTOR,
  95. INV_FACTOR,
  96. COUNT
  97. };
  98. };
  99. struct BlendEquation
  100. {
  101. enum Enum
  102. {
  103. ADD,
  104. SUB,
  105. REVSUB,
  106. MIN,
  107. MAX,
  108. COUNT
  109. };
  110. };
  111. struct CullMode
  112. {
  113. enum Enum
  114. {
  115. CW,
  116. CCW,
  117. NONE,
  118. COUNT
  119. };
  120. };
  121. struct PrimitiveType
  122. {
  123. enum Enum
  124. {
  125. PT_TRIANGLES,
  126. PT_TRISTRIP,
  127. PT_LINES,
  128. PT_LINESTRIP,
  129. PT_POINTS,
  130. COUNT
  131. };
  132. };
  133. struct SamplerFilter
  134. {
  135. enum Enum
  136. {
  137. POINT,
  138. ANISOTROPIC,
  139. COUNT
  140. };
  141. };
  142. struct SamplerWrap
  143. {
  144. enum Enum
  145. {
  146. MIRROR,
  147. CLAMP,
  148. BORDER,
  149. COUNT
  150. };
  151. };
  152. struct DepthTestInfo
  153. {
  154. const char *name;
  155. DepthFunction::Enum value;
  156. };
  157. static const DepthTestInfo _depth_test_map[] =
  158. {
  159. { "less", DepthFunction::LESS },
  160. { "lequal", DepthFunction::LEQUAL },
  161. { "equal", DepthFunction::EQUAL },
  162. { "gequal", DepthFunction::GEQUAL },
  163. { "greater", DepthFunction::GREATER },
  164. { "notequal", DepthFunction::NOTEQUAL },
  165. { "never", DepthFunction::NEVER },
  166. { "always", DepthFunction::ALWAYS }
  167. };
  168. CE_STATIC_ASSERT(countof(_depth_test_map) == DepthFunction::COUNT);
  169. struct BlendFunctionInfo
  170. {
  171. const char *name;
  172. BlendFunction::Enum value;
  173. };
  174. static const BlendFunctionInfo _blend_func_map[] =
  175. {
  176. { "zero", BlendFunction::ZERO },
  177. { "one", BlendFunction::ONE },
  178. { "src_color", BlendFunction::SRC_COLOR },
  179. { "inv_src_color", BlendFunction::INV_SRC_COLOR },
  180. { "src_alpha", BlendFunction::SRC_ALPHA },
  181. { "inv_src_alpha", BlendFunction::INV_SRC_ALPHA },
  182. { "dst_alpha", BlendFunction::DST_ALPHA },
  183. { "inv_dst_alpha", BlendFunction::INV_DST_ALPHA },
  184. { "dst_color", BlendFunction::DST_COLOR },
  185. { "inv_dst_color", BlendFunction::INV_DST_COLOR },
  186. { "src_alpha_sat", BlendFunction::SRC_ALPHA_SAT },
  187. { "factor", BlendFunction::FACTOR },
  188. { "inv_factor", BlendFunction::INV_FACTOR }
  189. };
  190. CE_STATIC_ASSERT(countof(_blend_func_map) == BlendFunction::COUNT);
  191. struct BlendEquationInfo
  192. {
  193. const char *name;
  194. BlendEquation::Enum value;
  195. };
  196. static const BlendEquationInfo _blend_equation_map[] =
  197. {
  198. { "add", BlendEquation::ADD },
  199. { "sub", BlendEquation::SUB },
  200. { "revsub", BlendEquation::REVSUB },
  201. { "min", BlendEquation::MIN },
  202. { "max", BlendEquation::MAX }
  203. };
  204. CE_STATIC_ASSERT(countof(_blend_equation_map) == BlendEquation::COUNT);
  205. struct CullModeInfo
  206. {
  207. const char *name;
  208. CullMode::Enum value;
  209. };
  210. static const CullModeInfo _cull_mode_map[] =
  211. {
  212. { "cw", CullMode::CW },
  213. { "ccw", CullMode::CCW },
  214. { "none", CullMode::NONE }
  215. };
  216. CE_STATIC_ASSERT(countof(_cull_mode_map) == CullMode::COUNT);
  217. struct PrimitiveTypeInfo
  218. {
  219. const char *name;
  220. PrimitiveType::Enum value;
  221. };
  222. static const PrimitiveTypeInfo _primitive_type_map[] =
  223. {
  224. { "pt_triangles", PrimitiveType::PT_TRIANGLES },
  225. { "pt_tristrip", PrimitiveType::PT_TRISTRIP },
  226. { "pt_lines", PrimitiveType::PT_LINES },
  227. { "pt_linestrip", PrimitiveType::PT_LINESTRIP },
  228. { "pt_points", PrimitiveType::PT_POINTS }
  229. };
  230. CE_STATIC_ASSERT(countof(_primitive_type_map) == PrimitiveType::COUNT);
  231. struct SamplerFilterInfo
  232. {
  233. const char *name;
  234. SamplerFilter::Enum value;
  235. };
  236. static const SamplerFilterInfo _sampler_filter_map[] =
  237. {
  238. { "point", SamplerFilter::POINT },
  239. { "anisotropic", SamplerFilter::ANISOTROPIC }
  240. };
  241. CE_STATIC_ASSERT(countof(_sampler_filter_map) == SamplerFilter::COUNT);
  242. struct SamplerWrapInfo
  243. {
  244. const char *name;
  245. SamplerWrap::Enum value;
  246. };
  247. static const SamplerWrapInfo _sampler_wrap_map[] =
  248. {
  249. { "mirror", SamplerWrap::MIRROR },
  250. { "clamp", SamplerWrap::CLAMP },
  251. { "border", SamplerWrap::BORDER }
  252. };
  253. CE_STATIC_ASSERT(countof(_sampler_wrap_map) == SamplerWrap::COUNT);
  254. static const u64 _bgfx_depth_func_map[] =
  255. {
  256. BGFX_STATE_DEPTH_TEST_LESS, // DepthFunction::LESS
  257. BGFX_STATE_DEPTH_TEST_LEQUAL, // DepthFunction::LEQUAL
  258. BGFX_STATE_DEPTH_TEST_EQUAL, // DepthFunction::EQUAL
  259. BGFX_STATE_DEPTH_TEST_GEQUAL, // DepthFunction::GEQUAL
  260. BGFX_STATE_DEPTH_TEST_GREATER, // DepthFunction::GREATER
  261. BGFX_STATE_DEPTH_TEST_NOTEQUAL, // DepthFunction::NOTEQUAL
  262. BGFX_STATE_DEPTH_TEST_NEVER, // DepthFunction::NEVER
  263. BGFX_STATE_DEPTH_TEST_ALWAYS // DepthFunction::ALWAYS
  264. };
  265. CE_STATIC_ASSERT(countof(_bgfx_depth_func_map) == DepthFunction::COUNT);
  266. static const u64 _bgfx_blend_func_map[] =
  267. {
  268. BGFX_STATE_BLEND_ZERO, // BlendFunction::ZERO
  269. BGFX_STATE_BLEND_ONE, // BlendFunction::ONE
  270. BGFX_STATE_BLEND_SRC_COLOR, // BlendFunction::SRC_COLOR
  271. BGFX_STATE_BLEND_INV_SRC_COLOR, // BlendFunction::INV_SRC_COLOR
  272. BGFX_STATE_BLEND_SRC_ALPHA, // BlendFunction::SRC_ALPHA
  273. BGFX_STATE_BLEND_INV_SRC_ALPHA, // BlendFunction::INV_SRC_ALPHA
  274. BGFX_STATE_BLEND_DST_ALPHA, // BlendFunction::DST_ALPHA
  275. BGFX_STATE_BLEND_INV_DST_ALPHA, // BlendFunction::INV_DST_ALPHA
  276. BGFX_STATE_BLEND_DST_COLOR, // BlendFunction::DST_COLOR
  277. BGFX_STATE_BLEND_INV_DST_COLOR, // BlendFunction::INV_DST_COLOR
  278. BGFX_STATE_BLEND_SRC_ALPHA_SAT, // BlendFunction::SRC_ALPHA_SAT
  279. BGFX_STATE_BLEND_FACTOR, // BlendFunction::FACTOR
  280. BGFX_STATE_BLEND_INV_FACTOR // BlendFunction::INV_FACTOR
  281. };
  282. CE_STATIC_ASSERT(countof(_bgfx_blend_func_map) == BlendFunction::COUNT);
  283. static const u64 _bgfx_blend_equation_map[] =
  284. {
  285. BGFX_STATE_BLEND_EQUATION_ADD, // BlendEquation::ADD
  286. BGFX_STATE_BLEND_EQUATION_SUB, // BlendEquation::SUB
  287. BGFX_STATE_BLEND_EQUATION_REVSUB, // BlendEquation::REVSUB
  288. BGFX_STATE_BLEND_EQUATION_MIN, // BlendEquation::MIN
  289. BGFX_STATE_BLEND_EQUATION_MAX // BlendEquation::MAX
  290. };
  291. CE_STATIC_ASSERT(countof(_bgfx_blend_equation_map) == BlendEquation::COUNT);
  292. static const u64 _bgfx_cull_mode_map[] =
  293. {
  294. BGFX_STATE_CULL_CW, // CullMode::CW
  295. BGFX_STATE_CULL_CCW, // CullMode::CCW
  296. 0 // CullMode::NONE
  297. };
  298. CE_STATIC_ASSERT(countof(_bgfx_cull_mode_map) == CullMode::COUNT);
  299. static const u64 _bgfx_primitive_type_map[] =
  300. {
  301. 0, // PrimitiveType::PT_TRIANGLES
  302. BGFX_STATE_PT_TRISTRIP, // PrimitiveType::PT_TRISTRIP
  303. BGFX_STATE_PT_LINES, // PrimitiveType::PT_LINES
  304. BGFX_STATE_PT_LINESTRIP, // PrimitiveType::PT_LINESTRIP
  305. BGFX_STATE_PT_POINTS // PrimitiveType::PT_POINTS
  306. };
  307. CE_STATIC_ASSERT(countof(_bgfx_primitive_type_map) == PrimitiveType::COUNT);
  308. static const u32 _bgfx_sampler_filter_min_map[] =
  309. {
  310. BGFX_SAMPLER_MIN_POINT, // SamplerFilter::POINT
  311. BGFX_SAMPLER_MIN_ANISOTROPIC // SamplerFilter::ANISOTROPIC
  312. };
  313. CE_STATIC_ASSERT(countof(_bgfx_sampler_filter_min_map) == SamplerFilter::COUNT);
  314. static const u32 _bgfx_sampler_filter_mag_map[] =
  315. {
  316. BGFX_SAMPLER_MAG_POINT, // SamplerFilter::POINT
  317. BGFX_SAMPLER_MAG_ANISOTROPIC // SamplerFilter::ANISOTROPIC
  318. };
  319. CE_STATIC_ASSERT(countof(_bgfx_sampler_filter_mag_map) == SamplerFilter::COUNT);
  320. static const u32 _bgfx_sampler_wrap_u_map[] =
  321. {
  322. BGFX_SAMPLER_U_MIRROR, // SamplerWrap::MIRROR
  323. BGFX_SAMPLER_U_CLAMP, // SamplerWrap::CLAMP
  324. BGFX_SAMPLER_U_BORDER // SamplerWrap::BORDER
  325. };
  326. CE_STATIC_ASSERT(countof(_bgfx_sampler_wrap_u_map) == SamplerWrap::COUNT);
  327. static const u32 _bgfx_sampler_wrap_v_map[] =
  328. {
  329. BGFX_SAMPLER_V_MIRROR, // SamplerWrap::MIRROR
  330. BGFX_SAMPLER_V_CLAMP, // SamplerWrap::CLAMP
  331. BGFX_SAMPLER_V_BORDER // SamplerWrap::BORDER
  332. };
  333. CE_STATIC_ASSERT(countof(_bgfx_sampler_wrap_v_map) == SamplerWrap::COUNT);
  334. static const u32 _bgfx_sampler_wrap_w_map[] =
  335. {
  336. BGFX_SAMPLER_W_MIRROR, // SamplerWrap::MIRROR
  337. BGFX_SAMPLER_W_CLAMP, // SamplerWrap::CLAMP
  338. BGFX_SAMPLER_W_BORDER // SamplerWrap::BORDER
  339. };
  340. CE_STATIC_ASSERT(countof(_bgfx_sampler_wrap_w_map) == SamplerWrap::COUNT);
  341. static DepthFunction::Enum name_to_depth_func(const char *name)
  342. {
  343. for (u32 i = 0; i < countof(_depth_test_map); ++i) {
  344. if (strcmp(name, _depth_test_map[i].name) == 0)
  345. return _depth_test_map[i].value;
  346. }
  347. return DepthFunction::COUNT;
  348. }
  349. static BlendFunction::Enum name_to_blend_function(const char *name)
  350. {
  351. for (u32 i = 0; i < countof(_blend_func_map); ++i) {
  352. if (strcmp(name, _blend_func_map[i].name) == 0)
  353. return _blend_func_map[i].value;
  354. }
  355. return BlendFunction::COUNT;
  356. }
  357. static BlendEquation::Enum name_to_blend_equation(const char *name)
  358. {
  359. for (u32 i = 0; i < countof(_blend_equation_map); ++i) {
  360. if (strcmp(name, _blend_equation_map[i].name) == 0)
  361. return _blend_equation_map[i].value;
  362. }
  363. return BlendEquation::COUNT;
  364. }
  365. static CullMode::Enum name_to_cull_mode(const char *name)
  366. {
  367. for (u32 i = 0; i < countof(_cull_mode_map); ++i) {
  368. if (strcmp(name, _cull_mode_map[i].name) == 0)
  369. return _cull_mode_map[i].value;
  370. }
  371. return CullMode::COUNT;
  372. }
  373. static PrimitiveType::Enum name_to_primitive_type(const char *name)
  374. {
  375. for (u32 i = 0; i < countof(_primitive_type_map); ++i) {
  376. if (strcmp(name, _primitive_type_map[i].name) == 0)
  377. return _primitive_type_map[i].value;
  378. }
  379. return PrimitiveType::COUNT;
  380. }
  381. static SamplerFilter::Enum name_to_sampler_filter(const char *name)
  382. {
  383. for (u32 i = 0; i < countof(_sampler_filter_map); ++i) {
  384. if (strcmp(name, _sampler_filter_map[i].name) == 0)
  385. return _sampler_filter_map[i].value;
  386. }
  387. return SamplerFilter::COUNT;
  388. }
  389. static SamplerWrap::Enum name_to_sampler_wrap(const char *name)
  390. {
  391. for (u32 i = 0; i < countof(_sampler_wrap_map); ++i) {
  392. if (strcmp(name, _sampler_wrap_map[i].name) == 0)
  393. return _sampler_wrap_map[i].value;
  394. }
  395. return SamplerWrap::COUNT;
  396. }
  397. static s32 run_external_compiler(Process &pr
  398. , const char *shaderc
  399. , const char *infile
  400. , const char *outfile
  401. , const char *varying
  402. , const char *type
  403. , const char *platform
  404. )
  405. {
  406. const char *argv[] =
  407. {
  408. shaderc,
  409. "-f",
  410. infile,
  411. "-o",
  412. outfile,
  413. "--varyingdef",
  414. varying,
  415. "--type",
  416. type,
  417. "--platform",
  418. platform,
  419. NULL,
  420. NULL,
  421. NULL,
  422. };
  423. if (strcmp(platform, "android") == 0 || strcmp(platform, "asm.js") == 0) {
  424. argv[11] = "--profile";
  425. argv[12] = "300_es"; // GLES3
  426. } else if (strcmp(platform, "linux") == 0) {
  427. argv[11] = "--profile";
  428. argv[12] = "150"; // OpenGL 3.2+
  429. } else if (strcmp(platform, "windows") == 0) {
  430. argv[11] = "--profile";
  431. argv[12] = ((strcmp(type, "vertex") == 0) ? "vs_4_0" : "ps_4_0");
  432. } else {
  433. return -1;
  434. }
  435. return pr.spawn(argv, CROWN_PROCESS_STDOUT_PIPE | CROWN_PROCESS_STDERR_MERGE);
  436. }
  437. struct RenderState
  438. {
  439. bool _rgb_write_enable;
  440. bool _alpha_write_enable;
  441. bool _depth_write_enable;
  442. bool _depth_enable;
  443. bool _blend_enable;
  444. DepthFunction::Enum _depth_func;
  445. BlendFunction::Enum _blend_src;
  446. BlendFunction::Enum _blend_dst;
  447. BlendEquation::Enum _blend_equation;
  448. CullMode::Enum _cull_mode;
  449. PrimitiveType::Enum _primitive_type;
  450. RenderState()
  451. {
  452. reset();
  453. }
  454. void reset()
  455. {
  456. _rgb_write_enable = false;
  457. _alpha_write_enable = false;
  458. _depth_write_enable = false;
  459. _depth_enable = false;
  460. _blend_enable = false;
  461. _depth_func = DepthFunction::LEQUAL;
  462. _blend_src = BlendFunction::SRC_ALPHA;
  463. _blend_dst = BlendFunction::INV_SRC_ALPHA;
  464. _blend_equation = BlendEquation::ADD;
  465. _cull_mode = CullMode::CW;
  466. _primitive_type = PrimitiveType::PT_TRIANGLES;
  467. }
  468. u64 encode() const
  469. {
  470. const u64 depth_func = _depth_enable
  471. ? _bgfx_depth_func_map[_depth_func]
  472. : 0
  473. ;
  474. const u64 blend_func = _blend_enable && _blend_src != BlendFunction::COUNT && _blend_dst != BlendFunction::COUNT
  475. ? BGFX_STATE_BLEND_FUNC(_bgfx_blend_func_map[_blend_src], _bgfx_blend_func_map[_blend_dst])
  476. : 0
  477. ;
  478. const u64 blend_eq = _blend_enable && _blend_equation != BlendEquation::COUNT
  479. ? BGFX_STATE_BLEND_EQUATION(_bgfx_blend_equation_map[_blend_equation])
  480. : 0
  481. ;
  482. const u64 cull_mode = _cull_mode != CullMode::COUNT
  483. ? _bgfx_cull_mode_map[_cull_mode]
  484. : 0
  485. ;
  486. const u64 primitive_type = _primitive_type != PrimitiveType::COUNT
  487. ? _bgfx_primitive_type_map[_primitive_type]
  488. : 0
  489. ;
  490. u64 state = 0;
  491. state |= _rgb_write_enable ? BGFX_STATE_WRITE_RGB : 0;
  492. state |= _alpha_write_enable ? BGFX_STATE_WRITE_A : 0;
  493. state |= _depth_write_enable ? BGFX_STATE_WRITE_Z : 0;
  494. state |= depth_func;
  495. state |= blend_func;
  496. state |= blend_eq;
  497. state |= cull_mode;
  498. state |= primitive_type;
  499. return state;
  500. }
  501. };
  502. struct SamplerState
  503. {
  504. SamplerFilter::Enum _filter_min;
  505. SamplerFilter::Enum _filter_mag;
  506. SamplerWrap::Enum _wrap_u;
  507. SamplerWrap::Enum _wrap_v;
  508. SamplerWrap::Enum _wrap_w;
  509. SamplerState()
  510. {
  511. reset();
  512. }
  513. void reset()
  514. {
  515. _filter_min = SamplerFilter::COUNT;
  516. _filter_mag = SamplerFilter::COUNT;
  517. _wrap_u = SamplerWrap::COUNT;
  518. _wrap_v = SamplerWrap::COUNT;
  519. _wrap_w = SamplerWrap::COUNT;
  520. }
  521. u32 encode() const
  522. {
  523. u32 state = 0;
  524. state |= _filter_min != SamplerFilter::COUNT ? _bgfx_sampler_filter_min_map[_filter_min] : 0;
  525. state |= _filter_mag != SamplerFilter::COUNT ? _bgfx_sampler_filter_mag_map[_filter_mag] : 0;
  526. state |= _wrap_u != SamplerWrap::COUNT ? _bgfx_sampler_wrap_u_map[_wrap_u] : 0;
  527. state |= _wrap_v != SamplerWrap::COUNT ? _bgfx_sampler_wrap_v_map[_wrap_v] : 0;
  528. state |= _wrap_w != SamplerWrap::COUNT ? _bgfx_sampler_wrap_w_map[_wrap_w] : 0;
  529. return state;
  530. }
  531. };
  532. struct BgfxShader
  533. {
  534. ALLOCATOR_AWARE;
  535. DynamicString _includes;
  536. DynamicString _code;
  537. DynamicString _vs_code;
  538. DynamicString _fs_code;
  539. DynamicString _varying;
  540. DynamicString _vs_input_output;
  541. DynamicString _fs_input_output;
  542. HashMap<DynamicString, DynamicString> _samplers;
  543. explicit BgfxShader(Allocator &a)
  544. : _includes(a)
  545. , _code(a)
  546. , _vs_code(a)
  547. , _fs_code(a)
  548. , _varying(a)
  549. , _vs_input_output(a)
  550. , _fs_input_output(a)
  551. , _samplers(a)
  552. {
  553. }
  554. };
  555. struct ShaderPermutation
  556. {
  557. ALLOCATOR_AWARE;
  558. DynamicString _bgfx_shader;
  559. DynamicString _render_state;
  560. explicit ShaderPermutation(Allocator &a)
  561. : _bgfx_shader(a)
  562. , _render_state(a)
  563. {
  564. }
  565. };
  566. struct StaticCompile
  567. {
  568. ALLOCATOR_AWARE;
  569. DynamicString _shader;
  570. Vector<DynamicString> _defines;
  571. explicit StaticCompile(Allocator &a)
  572. : _shader(a)
  573. , _defines(a)
  574. {
  575. }
  576. };
  577. struct ShaderCompiler
  578. {
  579. CompileOptions &_opts;
  580. HashMap<DynamicString, RenderState> _render_states;
  581. HashMap<DynamicString, SamplerState> _sampler_states;
  582. HashMap<DynamicString, BgfxShader> _bgfx_shaders;
  583. HashMap<DynamicString, ShaderPermutation> _shaders;
  584. Vector<StaticCompile> _static_compile;
  585. DynamicString _vs_src_path;
  586. DynamicString _fs_src_path;
  587. DynamicString _varying_path;
  588. DynamicString _vs_out_path;
  589. DynamicString _fs_out_path;
  590. explicit ShaderCompiler(CompileOptions &opts)
  591. : _opts(opts)
  592. , _render_states(default_allocator())
  593. , _sampler_states(default_allocator())
  594. , _bgfx_shaders(default_allocator())
  595. , _shaders(default_allocator())
  596. , _static_compile(default_allocator())
  597. , _vs_src_path(default_allocator())
  598. , _fs_src_path(default_allocator())
  599. , _varying_path(default_allocator())
  600. , _vs_out_path(default_allocator())
  601. , _fs_out_path(default_allocator())
  602. {
  603. _opts.temporary_path(_vs_src_path, "vs_src.sc");
  604. _opts.temporary_path(_fs_src_path, "fs_src.sc");
  605. _opts.temporary_path(_varying_path, "varying.sc");
  606. _opts.temporary_path(_vs_out_path, "vs_out.bin");
  607. _opts.temporary_path(_fs_out_path, "fs_out.bin");
  608. }
  609. s32 parse(const char *path)
  610. {
  611. return parse(_opts.read(path));
  612. }
  613. s32 parse(Buffer buf)
  614. {
  615. TempAllocator4096 ta;
  616. JsonObject obj(ta);
  617. sjson::parse(obj, buf);
  618. if (json_object::has(obj, "include")) {
  619. JsonArray arr(ta);
  620. sjson::parse_array(arr, obj["include"]);
  621. for (u32 i = 0; i < array::size(arr); ++i) {
  622. DynamicString path(ta);
  623. sjson::parse_string(path, arr[i]);
  624. parse(path.c_str());
  625. }
  626. }
  627. if (json_object::has(obj, "render_states")) {
  628. s32 err = parse_render_states(obj["render_states"]);
  629. DATA_COMPILER_ENSURE(err == 0, _opts);
  630. }
  631. if (json_object::has(obj, "sampler_states")) {
  632. s32 err = parse_sampler_states(obj["sampler_states"]);
  633. DATA_COMPILER_ENSURE(err == 0, _opts);
  634. }
  635. if (json_object::has(obj, "bgfx_shaders")) {
  636. s32 err = parse_bgfx_shaders(obj["bgfx_shaders"]);
  637. DATA_COMPILER_ENSURE(err == 0, _opts);
  638. }
  639. if (json_object::has(obj, "shaders")) {
  640. s32 err = parse_shaders(obj["shaders"]);
  641. DATA_COMPILER_ENSURE(err == 0, _opts);
  642. }
  643. if (json_object::has(obj, "static_compile")) {
  644. s32 err = parse_static_compile(obj["static_compile"]);
  645. DATA_COMPILER_ENSURE(err == 0, _opts);
  646. }
  647. return 0;
  648. }
  649. s32 parse_render_states(const char *json)
  650. {
  651. TempAllocator4096 ta;
  652. JsonObject render_states(ta);
  653. sjson::parse_object(render_states, json);
  654. auto cur = json_object::begin(render_states);
  655. auto end = json_object::end(render_states);
  656. for (; cur != end; ++cur) {
  657. JSON_OBJECT_SKIP_HOLE(render_states, cur);
  658. JsonObject obj(ta);
  659. sjson::parse_object(obj, cur->second);
  660. const bool rgb_write_enable = sjson::parse_bool(obj["rgb_write_enable"]);
  661. const bool alpha_write_enable = sjson::parse_bool(obj["alpha_write_enable"]);
  662. const bool depth_write_enable = sjson::parse_bool(obj["depth_write_enable"]);
  663. const bool depth_enable = sjson::parse_bool(obj["depth_enable"]);
  664. const bool blend_enable = sjson::parse_bool(obj["blend_enable"]);
  665. const bool has_depth_func = json_object::has(obj, "depth_func");
  666. const bool has_blend_src = json_object::has(obj, "blend_src");
  667. const bool has_blend_dst = json_object::has(obj, "blend_dst");
  668. const bool has_blend_equation = json_object::has(obj, "blend_equation");
  669. const bool has_cull_mode = json_object::has(obj, "cull_mode");
  670. const bool has_primitive_type = json_object::has(obj, "primitive_type");
  671. RenderState rs;
  672. rs.reset();
  673. rs._rgb_write_enable = rgb_write_enable;
  674. rs._alpha_write_enable = alpha_write_enable;
  675. rs._depth_write_enable = depth_write_enable;
  676. rs._depth_enable = depth_enable;
  677. rs._blend_enable = blend_enable;
  678. DynamicString depth_func(ta);
  679. DynamicString blend_src(ta);
  680. DynamicString blend_dst(ta);
  681. DynamicString blend_equation(ta);
  682. DynamicString cull_mode(ta);
  683. DynamicString primitive_type(ta);
  684. if (has_depth_func) {
  685. sjson::parse_string(depth_func, obj["depth_func"]);
  686. rs._depth_func = name_to_depth_func(depth_func.c_str());
  687. DATA_COMPILER_ASSERT(rs._depth_func != DepthFunction::COUNT
  688. , _opts
  689. , "Unknown depth test: '%s'"
  690. , depth_func.c_str()
  691. );
  692. }
  693. if (has_blend_src) {
  694. sjson::parse_string(blend_src, obj["blend_src"]);
  695. rs._blend_src = name_to_blend_function(blend_src.c_str());
  696. DATA_COMPILER_ASSERT(rs._blend_src != BlendFunction::COUNT
  697. , _opts
  698. , "Unknown blend function: '%s'"
  699. , blend_src.c_str()
  700. );
  701. }
  702. if (has_blend_dst) {
  703. sjson::parse_string(blend_dst, obj["blend_dst"]);
  704. rs._blend_dst = name_to_blend_function(blend_dst.c_str());
  705. DATA_COMPILER_ASSERT(rs._blend_dst != BlendFunction::COUNT
  706. , _opts
  707. , "Unknown blend function: '%s'"
  708. , blend_dst.c_str()
  709. );
  710. }
  711. if (has_blend_equation) {
  712. sjson::parse_string(blend_equation, obj["blend_equation"]);
  713. rs._blend_equation = name_to_blend_equation(blend_equation.c_str());
  714. DATA_COMPILER_ASSERT(rs._blend_equation != BlendEquation::COUNT
  715. , _opts
  716. , "Unknown blend equation: '%s'"
  717. , blend_equation.c_str()
  718. );
  719. }
  720. if (has_cull_mode) {
  721. sjson::parse_string(cull_mode, obj["cull_mode"]);
  722. rs._cull_mode = name_to_cull_mode(cull_mode.c_str());
  723. DATA_COMPILER_ASSERT(rs._cull_mode != CullMode::COUNT
  724. , _opts
  725. , "Unknown cull mode: '%s'"
  726. , cull_mode.c_str()
  727. );
  728. }
  729. if (has_primitive_type) {
  730. sjson::parse_string(primitive_type, obj["primitive_type"]);
  731. rs._primitive_type = name_to_primitive_type(primitive_type.c_str());
  732. DATA_COMPILER_ASSERT(rs._primitive_type != PrimitiveType::COUNT
  733. , _opts
  734. , "Unknown primitive type: '%s'"
  735. , primitive_type.c_str()
  736. );
  737. }
  738. DynamicString key(ta);
  739. key = cur->first;
  740. DATA_COMPILER_ASSERT(!hash_map::has(_render_states, key)
  741. , _opts
  742. , "Render state redefined: '%s'"
  743. , key.c_str()
  744. );
  745. hash_map::set(_render_states, key, rs);
  746. }
  747. return 0;
  748. }
  749. s32 parse_sampler_states(const char *json)
  750. {
  751. TempAllocator4096 ta;
  752. JsonObject sampler_states(ta);
  753. sjson::parse_object(sampler_states, json);
  754. auto cur = json_object::begin(sampler_states);
  755. auto end = json_object::end(sampler_states);
  756. for (; cur != end; ++cur) {
  757. JSON_OBJECT_SKIP_HOLE(sampler_states, cur);
  758. JsonObject obj(ta);
  759. sjson::parse_object(obj, cur->second);
  760. const bool has_filter_min = json_object::has(obj, "filter_min");
  761. const bool has_filter_mag = json_object::has(obj, "filter_mag");
  762. const bool has_wrap_u = json_object::has(obj, "wrap_u");
  763. const bool has_wrap_v = json_object::has(obj, "wrap_v");
  764. const bool has_wrap_w = json_object::has(obj, "wrap_w");
  765. SamplerState ss;
  766. ss.reset();
  767. DynamicString filter_min(ta);
  768. DynamicString filter_mag(ta);
  769. DynamicString wrap_u(ta);
  770. DynamicString wrap_v(ta);
  771. DynamicString wrap_w(ta);
  772. if (has_filter_min) {
  773. sjson::parse_string(filter_min, obj["filter_min"]);
  774. ss._filter_min = name_to_sampler_filter(filter_min.c_str());
  775. DATA_COMPILER_ASSERT(ss._filter_min != SamplerFilter::COUNT
  776. , _opts
  777. , "Unknown sampler filter: '%s'"
  778. , filter_min.c_str()
  779. );
  780. }
  781. if (has_filter_mag) {
  782. sjson::parse_string(filter_mag, obj["filter_mag"]);
  783. ss._filter_mag = name_to_sampler_filter(filter_mag.c_str());
  784. DATA_COMPILER_ASSERT(ss._filter_mag != SamplerFilter::COUNT
  785. , _opts
  786. , "Unknown sampler filter: '%s'"
  787. , filter_mag.c_str()
  788. );
  789. }
  790. if (has_wrap_u) {
  791. sjson::parse_string(wrap_u, obj["wrap_u"]);
  792. ss._wrap_u = name_to_sampler_wrap(wrap_u.c_str());
  793. DATA_COMPILER_ASSERT(ss._wrap_u != SamplerWrap::COUNT
  794. , _opts
  795. , "Unknown wrap mode: '%s'"
  796. , wrap_u.c_str()
  797. );
  798. }
  799. if (has_wrap_v) {
  800. sjson::parse_string(wrap_v, obj["wrap_v"]);
  801. ss._wrap_v = name_to_sampler_wrap(wrap_v.c_str());
  802. DATA_COMPILER_ASSERT(ss._wrap_v != SamplerWrap::COUNT
  803. , _opts
  804. , "Unknown wrap mode: '%s'"
  805. , wrap_v.c_str()
  806. );
  807. }
  808. if (has_wrap_w) {
  809. sjson::parse_string(wrap_w, obj["wrap_w"]);
  810. ss._wrap_w = name_to_sampler_wrap(wrap_w.c_str());
  811. DATA_COMPILER_ASSERT(ss._wrap_w != SamplerWrap::COUNT
  812. , _opts
  813. , "Unknown wrap mode: '%s'"
  814. , wrap_w.c_str()
  815. );
  816. }
  817. DynamicString key(ta);
  818. key = cur->first;
  819. DATA_COMPILER_ASSERT(!hash_map::has(_sampler_states, key)
  820. , _opts
  821. , "Sampler state redefined: '%s'"
  822. , key.c_str()
  823. );
  824. hash_map::set(_sampler_states, key, ss);
  825. }
  826. return 0;
  827. }
  828. s32 parse_bgfx_shaders(const char *json)
  829. {
  830. TempAllocator4096 ta;
  831. JsonObject bgfx_shaders(ta);
  832. sjson::parse_object(bgfx_shaders, json);
  833. auto cur = json_object::begin(bgfx_shaders);
  834. auto end = json_object::end(bgfx_shaders);
  835. for (; cur != end; ++cur) {
  836. JSON_OBJECT_SKIP_HOLE(bgfx_shaders, cur);
  837. JsonObject shader(ta);
  838. sjson::parse_object(shader, cur->second);
  839. s32 err = 0;
  840. BgfxShader bgfxshader(default_allocator());
  841. if (json_object::has(shader, "includes"))
  842. sjson::parse_string(bgfxshader._includes, shader["includes"]);
  843. if (json_object::has(shader, "code"))
  844. sjson::parse_verbatim(bgfxshader._code, shader["code"]);
  845. if (json_object::has(shader, "vs_code"))
  846. sjson::parse_verbatim(bgfxshader._vs_code, shader["vs_code"]);
  847. if (json_object::has(shader, "fs_code"))
  848. sjson::parse_verbatim(bgfxshader._fs_code, shader["fs_code"]);
  849. if (json_object::has(shader, "varying"))
  850. sjson::parse_verbatim(bgfxshader._varying, shader["varying"]);
  851. if (json_object::has(shader, "vs_input_output"))
  852. sjson::parse_verbatim(bgfxshader._vs_input_output, shader["vs_input_output"]);
  853. if (json_object::has(shader, "fs_input_output"))
  854. sjson::parse_verbatim(bgfxshader._fs_input_output, shader["fs_input_output"]);
  855. if (json_object::has(shader, "samplers"))
  856. err = parse_bgfx_samplers(bgfxshader, shader["samplers"]);
  857. DATA_COMPILER_ENSURE(err == 0, _opts);
  858. DynamicString key(ta);
  859. key = cur->first;
  860. DATA_COMPILER_ASSERT(!hash_map::has(_bgfx_shaders, key)
  861. , _opts
  862. , "Bgfx shader redefined: '%s'"
  863. , key.c_str()
  864. );
  865. hash_map::set(_bgfx_shaders, key, bgfxshader);
  866. }
  867. return 0;
  868. }
  869. s32 parse_bgfx_samplers(BgfxShader &bgfxshader, const char *json)
  870. {
  871. TempAllocator4096 ta;
  872. JsonObject bgfx_samplers(ta);
  873. sjson::parse_object(bgfx_samplers, json);
  874. auto cur = json_object::begin(bgfx_samplers);
  875. auto end = json_object::end(bgfx_samplers);
  876. for (; cur != end; ++cur) {
  877. JSON_OBJECT_SKIP_HOLE(bgfx_samplers, cur);
  878. JsonObject sampler(ta);
  879. sjson::parse_object(sampler, cur->second);
  880. DynamicString sampler_state(ta);
  881. sjson::parse_string(sampler_state, sampler["sampler_state"]);
  882. DATA_COMPILER_ASSERT(hash_map::has(_sampler_states, sampler_state)
  883. , _opts
  884. , "Unknown sampler state: '%s'"
  885. , sampler_state.c_str()
  886. );
  887. DynamicString key(ta);
  888. key = cur->first;
  889. DATA_COMPILER_ASSERT(!hash_map::has(bgfxshader._samplers, key)
  890. , _opts
  891. , "Bgfx sampler redefined: '%s'"
  892. , key.c_str()
  893. );
  894. hash_map::set(bgfxshader._samplers, key, sampler_state);
  895. }
  896. return 0;
  897. }
  898. s32 parse_shaders(const char *json)
  899. {
  900. TempAllocator4096 ta;
  901. JsonObject shaders(ta);
  902. sjson::parse_object(shaders, json);
  903. auto cur = json_object::begin(shaders);
  904. auto end = json_object::end(shaders);
  905. for (; cur != end; ++cur) {
  906. JSON_OBJECT_SKIP_HOLE(shaders, cur);
  907. JsonObject obj(ta);
  908. sjson::parse_object(obj, cur->second);
  909. ShaderPermutation shader(default_allocator());
  910. sjson::parse_string(shader._bgfx_shader, obj["bgfx_shader"]);
  911. sjson::parse_string(shader._render_state, obj["render_state"]);
  912. DynamicString key(ta);
  913. key = cur->first;
  914. DATA_COMPILER_ASSERT(!hash_map::has(_shaders, key)
  915. , _opts
  916. , "Shader redefined: '%s'"
  917. , key.c_str()
  918. );
  919. hash_map::set(_shaders, key, shader);
  920. }
  921. return 0;
  922. }
  923. s32 parse_static_compile(const char *json)
  924. {
  925. TempAllocator4096 ta;
  926. JsonArray static_compile(ta);
  927. sjson::parse_array(static_compile, json);
  928. for (u32 ii = 0; ii < array::size(static_compile); ++ii) {
  929. JsonObject obj(ta);
  930. sjson::parse_object(obj, static_compile[ii]);
  931. StaticCompile sc(default_allocator());
  932. sjson::parse_string(sc._shader, obj["shader"]);
  933. JsonArray defines(ta);
  934. sjson::parse_array(defines, obj["defines"]);
  935. for (u32 jj = 0; jj < array::size(defines); ++jj) {
  936. DynamicString def(ta);
  937. sjson::parse_string(def, defines[jj]);
  938. vector::push_back(sc._defines, def);
  939. }
  940. vector::push_back(_static_compile, sc);
  941. }
  942. return 0;
  943. }
  944. void delete_temp_files()
  945. {
  946. _opts.delete_file(_vs_src_path.c_str());
  947. _opts.delete_file(_fs_src_path.c_str());
  948. _opts.delete_file(_varying_path.c_str());
  949. _opts.delete_file(_vs_out_path.c_str());
  950. _opts.delete_file(_fs_out_path.c_str());
  951. }
  952. s32 compile()
  953. {
  954. _opts.write(RESOURCE_HEADER(RESOURCE_VERSION_SHADER));
  955. _opts.write(vector::size(_static_compile));
  956. for (u32 ii = 0; ii < vector::size(_static_compile); ++ii) {
  957. const StaticCompile &sc = _static_compile[ii];
  958. const DynamicString &shader = sc._shader;
  959. const Vector<DynamicString> &defines = sc._defines;
  960. TempAllocator1024 ta;
  961. DynamicString str(ta);
  962. str = shader;
  963. for (u32 jj = 0; jj < vector::size(defines); ++jj) {
  964. str += "+";
  965. str += defines[jj];
  966. }
  967. const StringId32 shader_name(str.c_str());
  968. DATA_COMPILER_ASSERT(hash_map::has(_shaders, sc._shader)
  969. , _opts
  970. , "Unknown shader: '%s'"
  971. , shader.c_str()
  972. );
  973. const ShaderPermutation sp_default(default_allocator());
  974. const ShaderPermutation &sp = hash_map::get(_shaders, shader, sp_default);
  975. const DynamicString &bgfx_shader = sp._bgfx_shader;
  976. const DynamicString &render_state = sp._render_state;
  977. DATA_COMPILER_ASSERT(hash_map::has(_bgfx_shaders, sp._bgfx_shader)
  978. , _opts
  979. , "Unknown bgfx shader: '%s'"
  980. , bgfx_shader.c_str()
  981. );
  982. DATA_COMPILER_ASSERT(hash_map::has(_render_states, sp._render_state)
  983. , _opts
  984. , "Unknown render state: '%s'"
  985. , render_state.c_str()
  986. );
  987. const RenderState rs_default;
  988. const RenderState &rs = hash_map::get(_render_states, render_state, rs_default);
  989. _opts.write(shader_name._id); // Shader name
  990. _opts.write(rs.encode()); // Render state
  991. compile_sampler_states(bgfx_shader.c_str()); // Sampler states
  992. s32 err = compile_bgfx_shader(bgfx_shader.c_str(), defines); // Shader code
  993. DATA_COMPILER_ENSURE(err == 0, _opts);
  994. }
  995. return 0;
  996. }
  997. void compile_sampler_states(const char *bgfx_shader)
  998. {
  999. TempAllocator512 ta;
  1000. DynamicString key(ta);
  1001. key = bgfx_shader;
  1002. const BgfxShader shader_default(default_allocator());
  1003. const BgfxShader &shader = hash_map::get(_bgfx_shaders, key, shader_default);
  1004. _opts.write(hash_map::size(shader._samplers));
  1005. auto cur = hash_map::begin(shader._samplers);
  1006. auto end = hash_map::end(shader._samplers);
  1007. for (; cur != end; ++cur) {
  1008. HASH_MAP_SKIP_HOLE(shader._samplers, cur);
  1009. const DynamicString &name = cur->first;
  1010. const DynamicString &sampler_state = cur->second;
  1011. const SamplerState ss_default;
  1012. const SamplerState &ss = hash_map::get(_sampler_states, sampler_state, ss_default);
  1013. _opts.write(name.to_string_id());
  1014. _opts.write(ss.encode());
  1015. }
  1016. }
  1017. s32 compile_bgfx_shader(const char *bgfx_shader, const Vector<DynamicString> &defines)
  1018. {
  1019. TempAllocator512 taa;
  1020. DynamicString key(taa);
  1021. key = bgfx_shader;
  1022. const BgfxShader shader_default(default_allocator());
  1023. const BgfxShader &shader = hash_map::get(_bgfx_shaders, key, shader_default);
  1024. DynamicString included_code(default_allocator());
  1025. if (!(shader._includes == "")) {
  1026. const BgfxShader included_default(default_allocator());
  1027. const BgfxShader &included = hash_map::get(_bgfx_shaders, shader._includes, included_default);
  1028. included_code = included._code;
  1029. }
  1030. StringStream vs_code(default_allocator());
  1031. StringStream fs_code(default_allocator());
  1032. vs_code << shader._vs_input_output.c_str();
  1033. for (u32 i = 0; i < vector::size(defines); ++i) {
  1034. vs_code << "#define " << defines[i].c_str() << "\n";
  1035. }
  1036. vs_code << included_code.c_str();
  1037. vs_code << shader._code.c_str();
  1038. vs_code << shader._vs_code.c_str();
  1039. fs_code << shader._fs_input_output.c_str();
  1040. for (u32 i = 0; i < vector::size(defines); ++i) {
  1041. fs_code << "#define " << defines[i].c_str() << "\n";
  1042. }
  1043. fs_code << included_code.c_str();
  1044. fs_code << shader._code.c_str();
  1045. fs_code << shader._fs_code.c_str();
  1046. _opts.write_temporary(_vs_src_path.c_str(), vs_code);
  1047. _opts.write_temporary(_fs_src_path.c_str(), fs_code);
  1048. _opts.write_temporary(_varying_path.c_str(), shader._varying.c_str(), shader._varying.length());
  1049. const char *shaderc = _opts.exe_path(shaderc_paths, countof(shaderc_paths));
  1050. DATA_COMPILER_ASSERT(shaderc != NULL, _opts, "shaderc not found");
  1051. // Invoke shaderc
  1052. Process pr_vert;
  1053. Process pr_frag;
  1054. s32 sc;
  1055. sc = run_external_compiler(pr_vert
  1056. , shaderc
  1057. , _vs_src_path.c_str()
  1058. , _vs_out_path.c_str()
  1059. , _varying_path.c_str()
  1060. , "vertex"
  1061. , shaderc_platform[_opts._platform]
  1062. );
  1063. if (sc != 0) {
  1064. delete_temp_files();
  1065. DATA_COMPILER_ASSERT(sc == 0
  1066. , _opts
  1067. , "Failed to spawn `%s`"
  1068. , shaderc
  1069. );
  1070. }
  1071. sc = run_external_compiler(pr_frag
  1072. , shaderc
  1073. , _fs_src_path.c_str()
  1074. , _fs_out_path.c_str()
  1075. , _varying_path.c_str()
  1076. , "fragment"
  1077. , shaderc_platform[_opts._platform]
  1078. );
  1079. if (sc != 0) {
  1080. delete_temp_files();
  1081. DATA_COMPILER_ASSERT(sc == 0
  1082. , _opts
  1083. , "Failed to spawn `%s`"
  1084. , shaderc
  1085. );
  1086. }
  1087. // Check shaderc exit code
  1088. s32 ec;
  1089. TempAllocator4096 ta;
  1090. StringStream output_vert(ta);
  1091. StringStream output_frag(ta);
  1092. _opts.read_output(output_vert, pr_vert);
  1093. ec = pr_vert.wait();
  1094. if (ec != 0) {
  1095. pr_frag.wait();
  1096. delete_temp_files();
  1097. DATA_COMPILER_ASSERT(false
  1098. , _opts
  1099. , "Failed to compile vertex shader `%s`:\n%s"
  1100. , bgfx_shader
  1101. , string_stream::c_str(output_vert)
  1102. );
  1103. }
  1104. _opts.read_output(output_frag, pr_frag);
  1105. ec = pr_frag.wait();
  1106. if (ec != 0) {
  1107. delete_temp_files();
  1108. DATA_COMPILER_ASSERT(false
  1109. , _opts
  1110. , "Failed to compile fragment shader `%s`:\n%s"
  1111. , bgfx_shader
  1112. , string_stream::c_str(output_frag)
  1113. );
  1114. }
  1115. Buffer vs_data = _opts.read_temporary(_vs_out_path.c_str());
  1116. Buffer fs_data = _opts.read_temporary(_fs_out_path.c_str());
  1117. delete_temp_files();
  1118. // Write
  1119. _opts.write(array::size(vs_data));
  1120. _opts.write(vs_data);
  1121. _opts.write(array::size(fs_data));
  1122. _opts.write(fs_data);
  1123. return 0;
  1124. }
  1125. };
  1126. s32 compile(CompileOptions &opts)
  1127. {
  1128. ShaderCompiler sc(opts);
  1129. s32 err = sc.parse(opts.source_path());
  1130. DATA_COMPILER_ENSURE(err == 0, opts);
  1131. return sc.compile();
  1132. }
  1133. } // namespace shader_resource_internal
  1134. #endif // if CROWN_CAN_COMPILE
  1135. } // namespace crown