shader_resource.cpp 35 KB

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