effect-parser.c 50 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958
  1. /******************************************************************************
  2. Copyright (C) 2023 by Lain Bailey <[email protected]>
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>.
  13. ******************************************************************************/
  14. #include <assert.h>
  15. #include <limits.h>
  16. #include "../util/platform.h"
  17. #include "effect-parser.h"
  18. #include "effect.h"
  19. typedef DARRAY(struct dstr) dstr_array_t;
  20. static inline bool ep_parse_param_assign(struct effect_parser *ep, struct ep_param *param);
  21. static enum gs_shader_param_type get_effect_param_type(const char *type)
  22. {
  23. if (strcmp(type, "float") == 0)
  24. return GS_SHADER_PARAM_FLOAT;
  25. else if (strcmp(type, "float2") == 0)
  26. return GS_SHADER_PARAM_VEC2;
  27. else if (strcmp(type, "float3") == 0)
  28. return GS_SHADER_PARAM_VEC3;
  29. else if (strcmp(type, "float4") == 0)
  30. return GS_SHADER_PARAM_VEC4;
  31. else if (strcmp(type, "int2") == 0)
  32. return GS_SHADER_PARAM_INT2;
  33. else if (strcmp(type, "int3") == 0)
  34. return GS_SHADER_PARAM_INT3;
  35. else if (strcmp(type, "int4") == 0)
  36. return GS_SHADER_PARAM_INT4;
  37. else if (astrcmp_n(type, "texture", 7) == 0)
  38. return GS_SHADER_PARAM_TEXTURE;
  39. else if (strcmp(type, "float4x4") == 0)
  40. return GS_SHADER_PARAM_MATRIX4X4;
  41. else if (strcmp(type, "bool") == 0)
  42. return GS_SHADER_PARAM_BOOL;
  43. else if (strcmp(type, "int") == 0)
  44. return GS_SHADER_PARAM_INT;
  45. else if (strcmp(type, "string") == 0)
  46. return GS_SHADER_PARAM_STRING;
  47. return GS_SHADER_PARAM_UNKNOWN;
  48. }
  49. void ep_free(struct effect_parser *ep)
  50. {
  51. size_t i;
  52. for (i = 0; i < ep->params.num; i++)
  53. ep_param_free(ep->params.array + i);
  54. for (i = 0; i < ep->structs.num; i++)
  55. ep_struct_free(ep->structs.array + i);
  56. for (i = 0; i < ep->funcs.num; i++)
  57. ep_func_free(ep->funcs.array + i);
  58. for (i = 0; i < ep->samplers.num; i++)
  59. ep_sampler_free(ep->samplers.array + i);
  60. for (i = 0; i < ep->techniques.num; i++)
  61. ep_technique_free(ep->techniques.array + i);
  62. ep->cur_pass = NULL;
  63. cf_parser_free(&ep->cfp);
  64. da_free(ep->params);
  65. da_free(ep->structs);
  66. da_free(ep->funcs);
  67. da_free(ep->samplers);
  68. da_free(ep->techniques);
  69. }
  70. static inline struct ep_func *ep_getfunc(struct effect_parser *ep, const char *name)
  71. {
  72. size_t i;
  73. for (i = 0; i < ep->funcs.num; i++) {
  74. if (strcmp(name, ep->funcs.array[i].name) == 0)
  75. return ep->funcs.array + i;
  76. }
  77. return NULL;
  78. }
  79. static inline struct ep_struct *ep_getstruct(struct effect_parser *ep, const char *name)
  80. {
  81. size_t i;
  82. for (i = 0; i < ep->structs.num; i++) {
  83. if (strcmp(name, ep->structs.array[i].name) == 0)
  84. return ep->structs.array + i;
  85. }
  86. return NULL;
  87. }
  88. static inline struct ep_sampler *ep_getsampler(struct effect_parser *ep, const char *name)
  89. {
  90. size_t i;
  91. for (i = 0; i < ep->samplers.num; i++) {
  92. if (strcmp(name, ep->samplers.array[i].name) == 0)
  93. return ep->samplers.array + i;
  94. }
  95. return NULL;
  96. }
  97. static inline struct ep_param *ep_getparam(struct effect_parser *ep, const char *name)
  98. {
  99. size_t i;
  100. for (i = 0; i < ep->params.num; i++) {
  101. if (strcmp(name, ep->params.array[i].name) == 0)
  102. return ep->params.array + i;
  103. }
  104. return NULL;
  105. }
  106. static inline struct ep_param *ep_getannotation(struct ep_param *param, const char *name)
  107. {
  108. size_t i;
  109. for (i = 0; i < param->annotations.num; i++) {
  110. if (strcmp(name, param->annotations.array[i].name) == 0)
  111. return param->annotations.array + i;
  112. }
  113. return NULL;
  114. }
  115. static inline struct ep_func *ep_getfunc_strref(struct effect_parser *ep, const struct strref *ref)
  116. {
  117. size_t i;
  118. for (i = 0; i < ep->funcs.num; i++) {
  119. if (strref_cmp(ref, ep->funcs.array[i].name) == 0)
  120. return ep->funcs.array + i;
  121. }
  122. return NULL;
  123. }
  124. static inline struct ep_struct *ep_getstruct_strref(struct effect_parser *ep, const struct strref *ref)
  125. {
  126. size_t i;
  127. for (i = 0; i < ep->structs.num; i++) {
  128. if (strref_cmp(ref, ep->structs.array[i].name) == 0)
  129. return ep->structs.array + i;
  130. }
  131. return NULL;
  132. }
  133. static inline struct ep_sampler *ep_getsampler_strref(struct effect_parser *ep, const struct strref *ref)
  134. {
  135. size_t i;
  136. for (i = 0; i < ep->samplers.num; i++) {
  137. if (strref_cmp(ref, ep->samplers.array[i].name) == 0)
  138. return ep->samplers.array + i;
  139. }
  140. return NULL;
  141. }
  142. static inline struct ep_param *ep_getparam_strref(struct effect_parser *ep, const struct strref *ref)
  143. {
  144. size_t i;
  145. for (i = 0; i < ep->params.num; i++) {
  146. if (strref_cmp(ref, ep->params.array[i].name) == 0)
  147. return ep->params.array + i;
  148. }
  149. return NULL;
  150. }
  151. static inline int ep_parse_struct_var(struct effect_parser *ep, struct ep_var *var)
  152. {
  153. int code;
  154. /* -------------------------------------- */
  155. /* variable type */
  156. if (!cf_next_valid_token(&ep->cfp))
  157. return PARSE_EOF;
  158. if (cf_token_is(&ep->cfp, ";"))
  159. return PARSE_CONTINUE;
  160. if (cf_token_is(&ep->cfp, "}"))
  161. return PARSE_BREAK;
  162. code = cf_token_is_type(&ep->cfp, CFTOKEN_NAME, "type name", ";");
  163. if (code != PARSE_SUCCESS)
  164. return code;
  165. cf_copy_token(&ep->cfp, &var->type);
  166. /* -------------------------------------- */
  167. /* variable name */
  168. if (!cf_next_valid_token(&ep->cfp))
  169. return PARSE_EOF;
  170. if (cf_token_is(&ep->cfp, ";"))
  171. return PARSE_UNEXPECTED_CONTINUE;
  172. if (cf_token_is(&ep->cfp, "}"))
  173. return PARSE_UNEXPECTED_BREAK;
  174. code = cf_token_is_type(&ep->cfp, CFTOKEN_NAME, "variable name", ";");
  175. if (code != PARSE_SUCCESS)
  176. return code;
  177. cf_copy_token(&ep->cfp, &var->name);
  178. /* -------------------------------------- */
  179. /* variable mapping if any (POSITION, TEXCOORD, etc) */
  180. if (!cf_next_valid_token(&ep->cfp))
  181. return PARSE_EOF;
  182. if (cf_token_is(&ep->cfp, ":")) {
  183. if (!cf_next_valid_token(&ep->cfp))
  184. return PARSE_EOF;
  185. if (cf_token_is(&ep->cfp, ";"))
  186. return PARSE_UNEXPECTED_CONTINUE;
  187. if (cf_token_is(&ep->cfp, "}"))
  188. return PARSE_UNEXPECTED_BREAK;
  189. code = cf_token_is_type(&ep->cfp, CFTOKEN_NAME, "mapping name", ";");
  190. if (code != PARSE_SUCCESS)
  191. return code;
  192. cf_copy_token(&ep->cfp, &var->mapping);
  193. if (!cf_next_valid_token(&ep->cfp))
  194. return PARSE_EOF;
  195. }
  196. /* -------------------------------------- */
  197. if (!cf_token_is(&ep->cfp, ";")) {
  198. if (!cf_go_to_valid_token(&ep->cfp, ";", "}"))
  199. return PARSE_EOF;
  200. return PARSE_CONTINUE;
  201. }
  202. return PARSE_SUCCESS;
  203. }
  204. static void ep_parse_struct(struct effect_parser *ep)
  205. {
  206. struct ep_struct eps;
  207. ep_struct_init(&eps);
  208. if (cf_next_name(&ep->cfp, &eps.name, "name", ";") != PARSE_SUCCESS)
  209. goto error;
  210. if (cf_next_token_should_be(&ep->cfp, "{", ";", NULL) != PARSE_SUCCESS)
  211. goto error;
  212. /* get structure variables */
  213. while (true) {
  214. bool do_break = false;
  215. struct ep_var var;
  216. ep_var_init(&var);
  217. switch (ep_parse_struct_var(ep, &var)) {
  218. case PARSE_UNEXPECTED_CONTINUE:
  219. cf_adderror_syntax_error(&ep->cfp);
  220. /* Falls through. */
  221. case PARSE_CONTINUE:
  222. ep_var_free(&var);
  223. continue;
  224. case PARSE_UNEXPECTED_BREAK:
  225. cf_adderror_syntax_error(&ep->cfp);
  226. /* Falls through. */
  227. case PARSE_BREAK:
  228. ep_var_free(&var);
  229. do_break = true;
  230. break;
  231. case PARSE_EOF:
  232. ep_var_free(&var);
  233. goto error;
  234. }
  235. if (do_break)
  236. break;
  237. da_push_back(eps.vars, &var);
  238. }
  239. if (cf_next_token_should_be(&ep->cfp, ";", NULL, NULL) != PARSE_SUCCESS)
  240. goto error;
  241. da_push_back(ep->structs, &eps);
  242. return;
  243. error:
  244. ep_struct_free(&eps);
  245. }
  246. static inline int ep_parse_param_annotation_var(struct effect_parser *ep, struct ep_param *var)
  247. {
  248. int code;
  249. /* -------------------------------------- */
  250. /* variable type */
  251. if (!cf_next_valid_token(&ep->cfp))
  252. return PARSE_EOF;
  253. if (cf_token_is(&ep->cfp, ";"))
  254. return PARSE_CONTINUE;
  255. if (cf_token_is(&ep->cfp, ">"))
  256. return PARSE_BREAK;
  257. code = cf_token_is_type(&ep->cfp, CFTOKEN_NAME, "type name", ";");
  258. if (code != PARSE_SUCCESS)
  259. return code;
  260. bfree(var->type);
  261. cf_copy_token(&ep->cfp, &var->type);
  262. /* -------------------------------------- */
  263. /* variable name */
  264. if (!cf_next_valid_token(&ep->cfp))
  265. return PARSE_EOF;
  266. if (cf_token_is(&ep->cfp, ";")) {
  267. cf_adderror_expecting(&ep->cfp, "variable name");
  268. return PARSE_UNEXPECTED_CONTINUE;
  269. }
  270. if (cf_token_is(&ep->cfp, ">")) {
  271. cf_adderror_expecting(&ep->cfp, "variable name");
  272. return PARSE_UNEXPECTED_BREAK;
  273. }
  274. code = cf_token_is_type(&ep->cfp, CFTOKEN_NAME, "variable name", ";");
  275. if (code != PARSE_SUCCESS)
  276. return code;
  277. bfree(var->name);
  278. cf_copy_token(&ep->cfp, &var->name);
  279. /* -------------------------------------- */
  280. /* variable mapping if any (POSITION, TEXCOORD, etc) */
  281. if (!cf_next_valid_token(&ep->cfp))
  282. return PARSE_EOF;
  283. if (cf_token_is(&ep->cfp, ":")) {
  284. cf_adderror_expecting(&ep->cfp, "= or ;");
  285. return PARSE_UNEXPECTED_BREAK;
  286. } else if (cf_token_is(&ep->cfp, ">")) {
  287. cf_adderror_expecting(&ep->cfp, "= or ;");
  288. return PARSE_UNEXPECTED_BREAK;
  289. } else if (cf_token_is(&ep->cfp, "=")) {
  290. if (!ep_parse_param_assign(ep, var)) {
  291. cf_adderror_expecting(&ep->cfp, "assignment value");
  292. return PARSE_UNEXPECTED_BREAK;
  293. }
  294. }
  295. /* -------------------------------------- */
  296. if (!cf_token_is(&ep->cfp, ";")) {
  297. if (!cf_go_to_valid_token(&ep->cfp, ";", ">")) {
  298. cf_adderror_expecting(&ep->cfp, "; or >");
  299. return PARSE_EOF;
  300. }
  301. return PARSE_CONTINUE;
  302. }
  303. return PARSE_SUCCESS;
  304. }
  305. static int ep_parse_annotations(struct effect_parser *ep, ep_param_array_t *annotations)
  306. {
  307. if (!cf_token_is(&ep->cfp, "<")) {
  308. cf_adderror_expecting(&ep->cfp, "<");
  309. goto error;
  310. }
  311. /* get annotation variables */
  312. while (true) {
  313. bool do_break = false;
  314. struct ep_param var;
  315. ep_param_init(&var, bstrdup(""), bstrdup(""), false, false, false);
  316. switch (ep_parse_param_annotation_var(ep, &var)) {
  317. case PARSE_UNEXPECTED_CONTINUE:
  318. cf_adderror_syntax_error(&ep->cfp);
  319. /* Falls through. */
  320. case PARSE_CONTINUE:
  321. ep_param_free(&var);
  322. continue;
  323. case PARSE_UNEXPECTED_BREAK:
  324. cf_adderror_syntax_error(&ep->cfp);
  325. /* Falls through. */
  326. case PARSE_BREAK:
  327. ep_param_free(&var);
  328. do_break = true;
  329. break;
  330. case PARSE_EOF:
  331. ep_param_free(&var);
  332. goto error;
  333. }
  334. if (do_break)
  335. break;
  336. da_push_back(*annotations, &var);
  337. }
  338. if (!cf_token_is(&ep->cfp, ">")) {
  339. cf_adderror_expecting(&ep->cfp, ">");
  340. goto error;
  341. }
  342. if (!cf_next_valid_token(&ep->cfp))
  343. goto error;
  344. return true;
  345. error:
  346. return false;
  347. }
  348. static int ep_parse_param_annotations(struct effect_parser *ep, struct ep_param *param)
  349. {
  350. return ep_parse_annotations(ep, &param->annotations);
  351. }
  352. static inline int ep_parse_pass_command_call(struct effect_parser *ep, cf_token_array_t *call)
  353. {
  354. struct cf_token end_token;
  355. cf_token_clear(&end_token);
  356. while (!cf_token_is(&ep->cfp, ";")) {
  357. if (cf_token_is(&ep->cfp, "}")) {
  358. cf_adderror_expecting(&ep->cfp, ";");
  359. return PARSE_CONTINUE;
  360. }
  361. da_push_back(*call, ep->cfp.cur_token);
  362. if (!cf_next_valid_token(&ep->cfp))
  363. return PARSE_EOF;
  364. }
  365. da_push_back(*call, ep->cfp.cur_token);
  366. da_push_back(*call, &end_token);
  367. return PARSE_SUCCESS;
  368. }
  369. static int ep_parse_pass_command(struct effect_parser *ep, struct ep_pass *pass)
  370. {
  371. cf_token_array_t *call;
  372. if (!cf_next_valid_token(&ep->cfp))
  373. return PARSE_EOF;
  374. if (cf_token_is(&ep->cfp, "vertex_shader") || cf_token_is(&ep->cfp, "vertex_program")) {
  375. call = &pass->vertex_program;
  376. } else if (cf_token_is(&ep->cfp, "pixel_shader") || cf_token_is(&ep->cfp, "pixel_program")) {
  377. call = &pass->fragment_program;
  378. } else {
  379. cf_adderror_syntax_error(&ep->cfp);
  380. if (!cf_go_to_valid_token(&ep->cfp, ";", "}"))
  381. return PARSE_EOF;
  382. return PARSE_CONTINUE;
  383. }
  384. if (cf_next_token_should_be(&ep->cfp, "=", ";", "}") != PARSE_SUCCESS)
  385. return PARSE_CONTINUE;
  386. if (!cf_next_valid_token(&ep->cfp))
  387. return PARSE_EOF;
  388. if (cf_token_is(&ep->cfp, "compile")) {
  389. cf_adderror(&ep->cfp, "compile keyword not necessary", LEX_WARNING, NULL, NULL, NULL);
  390. if (!cf_next_valid_token(&ep->cfp))
  391. return PARSE_EOF;
  392. }
  393. return ep_parse_pass_command_call(ep, call);
  394. }
  395. static int ep_parse_pass(struct effect_parser *ep, struct ep_pass *pass)
  396. {
  397. struct cf_token peek;
  398. if (!cf_token_is(&ep->cfp, "pass"))
  399. return PARSE_UNEXPECTED_CONTINUE;
  400. if (!cf_next_valid_token(&ep->cfp))
  401. return PARSE_EOF;
  402. if (!cf_token_is(&ep->cfp, "{")) {
  403. pass->name = bstrdup_n(ep->cfp.cur_token->str.array, ep->cfp.cur_token->str.len);
  404. if (!cf_next_valid_token(&ep->cfp))
  405. return PARSE_EOF;
  406. }
  407. if (!cf_peek_valid_token(&ep->cfp, &peek))
  408. return PARSE_EOF;
  409. while (strref_cmp(&peek.str, "}") != 0) {
  410. int ret = ep_parse_pass_command(ep, pass);
  411. if (ret < 0 && ret != PARSE_CONTINUE)
  412. return ret;
  413. if (!cf_peek_valid_token(&ep->cfp, &peek))
  414. return PARSE_EOF;
  415. }
  416. /* token is '}' */
  417. cf_next_token(&ep->cfp);
  418. return PARSE_SUCCESS;
  419. }
  420. static void ep_parse_technique(struct effect_parser *ep)
  421. {
  422. struct ep_technique ept;
  423. ep_technique_init(&ept);
  424. if (cf_next_name(&ep->cfp, &ept.name, "name", ";") != PARSE_SUCCESS)
  425. goto error;
  426. if (!cf_next_valid_token(&ep->cfp))
  427. return;
  428. if (!cf_token_is(&ep->cfp, "{")) {
  429. if (!cf_go_to_token(&ep->cfp, ";", NULL)) {
  430. cf_adderror_expecting(&ep->cfp, ";");
  431. return;
  432. }
  433. cf_adderror_expecting(&ep->cfp, "{");
  434. goto error;
  435. }
  436. if (!cf_next_valid_token(&ep->cfp))
  437. goto error;
  438. while (!cf_token_is(&ep->cfp, "}")) {
  439. struct ep_pass pass;
  440. ep_pass_init(&pass);
  441. switch (ep_parse_pass(ep, &pass)) {
  442. case PARSE_UNEXPECTED_CONTINUE:
  443. ep_pass_free(&pass);
  444. if (!cf_go_to_token(&ep->cfp, "}", NULL))
  445. goto error;
  446. continue;
  447. case PARSE_EOF:
  448. ep_pass_free(&pass);
  449. goto error;
  450. }
  451. da_push_back(ept.passes, &pass);
  452. if (!cf_next_valid_token(&ep->cfp))
  453. goto error;
  454. }
  455. /* pass the current token (which is '}') if we reached here */
  456. cf_next_token(&ep->cfp);
  457. da_push_back(ep->techniques, &ept);
  458. return;
  459. error:
  460. cf_next_token(&ep->cfp);
  461. ep_technique_free(&ept);
  462. }
  463. static int ep_parse_sampler_state_item(struct effect_parser *ep, struct ep_sampler *eps)
  464. {
  465. int ret;
  466. char *state = NULL;
  467. struct dstr value = {0};
  468. ret = cf_next_name(&ep->cfp, &state, "state name", ";");
  469. if (ret != PARSE_SUCCESS)
  470. goto fail;
  471. ret = cf_next_token_should_be(&ep->cfp, "=", ";", NULL);
  472. if (ret != PARSE_SUCCESS)
  473. goto fail;
  474. for (;;) {
  475. const char *cur_str;
  476. if (!cf_next_valid_token(&ep->cfp))
  477. return PARSE_EOF;
  478. cur_str = ep->cfp.cur_token->str.array;
  479. if (*cur_str == ';')
  480. break;
  481. dstr_ncat(&value, cur_str, ep->cfp.cur_token->str.len);
  482. }
  483. if (value.len) {
  484. da_push_back(eps->states, &state);
  485. da_push_back(eps->values, &value.array);
  486. }
  487. return ret;
  488. fail:
  489. bfree(state);
  490. dstr_free(&value);
  491. return ret;
  492. }
  493. static void ep_parse_sampler_state(struct effect_parser *ep)
  494. {
  495. struct ep_sampler eps;
  496. struct cf_token peek;
  497. ep_sampler_init(&eps);
  498. if (cf_next_name(&ep->cfp, &eps.name, "name", ";") != PARSE_SUCCESS)
  499. goto error;
  500. if (cf_next_token_should_be(&ep->cfp, "{", ";", NULL) != PARSE_SUCCESS)
  501. goto error;
  502. if (!cf_peek_valid_token(&ep->cfp, &peek))
  503. goto error;
  504. while (strref_cmp(&peek.str, "}") != 0) {
  505. int ret = ep_parse_sampler_state_item(ep, &eps);
  506. if (ret == PARSE_EOF)
  507. goto error;
  508. if (!cf_peek_valid_token(&ep->cfp, &peek))
  509. goto error;
  510. }
  511. if (cf_next_token_should_be(&ep->cfp, "}", ";", NULL) != PARSE_SUCCESS)
  512. goto error;
  513. if (cf_next_token_should_be(&ep->cfp, ";", NULL, NULL) != PARSE_SUCCESS)
  514. goto error;
  515. da_push_back(ep->samplers, &eps);
  516. return;
  517. error:
  518. ep_sampler_free(&eps);
  519. }
  520. static inline int ep_check_for_keyword(struct effect_parser *ep, const char *keyword, bool *val)
  521. {
  522. bool new_val = cf_token_is(&ep->cfp, keyword);
  523. if (new_val) {
  524. if (!cf_next_valid_token(&ep->cfp))
  525. return PARSE_EOF;
  526. if (new_val && *val)
  527. cf_adderror(&ep->cfp, "'$1' keyword already specified", LEX_WARNING, keyword, NULL, NULL);
  528. *val = new_val;
  529. return PARSE_CONTINUE;
  530. }
  531. return PARSE_SUCCESS;
  532. }
  533. static inline int ep_parse_func_param(struct effect_parser *ep, struct ep_func *func, struct ep_var *var)
  534. {
  535. int code;
  536. bool var_type_keyword = false;
  537. if (!cf_next_valid_token(&ep->cfp))
  538. return PARSE_EOF;
  539. code = ep_check_for_keyword(ep, "in", &var_type_keyword);
  540. if (code == PARSE_EOF)
  541. return PARSE_EOF;
  542. else if (var_type_keyword)
  543. var->var_type = EP_VAR_IN;
  544. if (!var_type_keyword) {
  545. code = ep_check_for_keyword(ep, "inout", &var_type_keyword);
  546. if (code == PARSE_EOF)
  547. return PARSE_EOF;
  548. else if (var_type_keyword)
  549. var->var_type = EP_VAR_INOUT;
  550. }
  551. if (!var_type_keyword) {
  552. code = ep_check_for_keyword(ep, "out", &var_type_keyword);
  553. if (code == PARSE_EOF)
  554. return PARSE_EOF;
  555. else if (var_type_keyword)
  556. var->var_type = EP_VAR_OUT;
  557. }
  558. if (!var_type_keyword) {
  559. code = ep_check_for_keyword(ep, "uniform", &var_type_keyword);
  560. if (code == PARSE_EOF)
  561. return PARSE_EOF;
  562. else if (var_type_keyword)
  563. var->var_type = EP_VAR_UNIFORM;
  564. }
  565. code = cf_get_name(&ep->cfp, &var->type, "type", ")");
  566. if (code != PARSE_SUCCESS)
  567. return code;
  568. code = cf_next_name(&ep->cfp, &var->name, "name", ")");
  569. if (code != PARSE_SUCCESS)
  570. return code;
  571. if (!cf_next_valid_token(&ep->cfp))
  572. return PARSE_EOF;
  573. if (cf_token_is(&ep->cfp, ":")) {
  574. code = cf_next_name(&ep->cfp, &var->mapping, "mapping specifier", ")");
  575. if (code != PARSE_SUCCESS)
  576. return code;
  577. if (!cf_next_valid_token(&ep->cfp))
  578. return PARSE_EOF;
  579. }
  580. if (ep_getstruct(ep, var->type) != NULL)
  581. da_push_back(func->struct_deps, &var->type);
  582. else if (ep_getsampler(ep, var->type) != NULL)
  583. da_push_back(func->sampler_deps, &var->type);
  584. return PARSE_SUCCESS;
  585. }
  586. static bool ep_parse_func_params(struct effect_parser *ep, struct ep_func *func)
  587. {
  588. struct cf_token peek;
  589. int code;
  590. cf_token_clear(&peek);
  591. if (!cf_peek_valid_token(&ep->cfp, &peek))
  592. return false;
  593. if (*peek.str.array == ')') {
  594. cf_next_token(&ep->cfp);
  595. goto exit;
  596. }
  597. do {
  598. struct ep_var var;
  599. ep_var_init(&var);
  600. if (!cf_token_is(&ep->cfp, "(") && !cf_token_is(&ep->cfp, ","))
  601. cf_adderror_syntax_error(&ep->cfp);
  602. code = ep_parse_func_param(ep, func, &var);
  603. if (code != PARSE_SUCCESS) {
  604. ep_var_free(&var);
  605. if (code == PARSE_CONTINUE)
  606. goto exit;
  607. else if (code == PARSE_EOF)
  608. return false;
  609. }
  610. da_push_back(func->param_vars, &var);
  611. } while (!cf_token_is(&ep->cfp, ")"));
  612. exit:
  613. return true;
  614. }
  615. static inline bool ep_process_struct_dep(struct effect_parser *ep, struct ep_func *func)
  616. {
  617. struct ep_struct *val = ep_getstruct_strref(ep, &ep->cfp.cur_token->str);
  618. if (val)
  619. da_push_back(func->struct_deps, &val->name);
  620. return val != NULL;
  621. }
  622. static inline bool ep_process_func_dep(struct effect_parser *ep, struct ep_func *func)
  623. {
  624. struct ep_func *val = ep_getfunc_strref(ep, &ep->cfp.cur_token->str);
  625. if (val)
  626. da_push_back(func->func_deps, &val->name);
  627. return val != NULL;
  628. }
  629. static inline bool ep_process_sampler_dep(struct effect_parser *ep, struct ep_func *func)
  630. {
  631. struct ep_sampler *val = ep_getsampler_strref(ep, &ep->cfp.cur_token->str);
  632. if (val)
  633. da_push_back(func->sampler_deps, &val->name);
  634. return val != NULL;
  635. }
  636. static inline bool ep_process_param_dep(struct effect_parser *ep, struct ep_func *func)
  637. {
  638. struct ep_param *val = ep_getparam_strref(ep, &ep->cfp.cur_token->str);
  639. if (val)
  640. da_push_back(func->param_deps, &val->name);
  641. return val != NULL;
  642. }
  643. static inline bool ep_parse_func_contents(struct effect_parser *ep, struct ep_func *func)
  644. {
  645. int braces = 1;
  646. dstr_cat_strref(&func->contents, &ep->cfp.cur_token->str);
  647. while (braces > 0) {
  648. if ((ep->cfp.cur_token++)->type == CFTOKEN_NONE)
  649. return false;
  650. if (ep->cfp.cur_token->type == CFTOKEN_SPACETAB || ep->cfp.cur_token->type == CFTOKEN_NEWLINE) {
  651. } else if (cf_token_is(&ep->cfp, "{")) {
  652. braces++;
  653. } else if (cf_token_is(&ep->cfp, "}")) {
  654. braces--;
  655. } else if (ep_process_struct_dep(ep, func) || ep_process_func_dep(ep, func) ||
  656. ep_process_sampler_dep(ep, func) || ep_process_param_dep(ep, func)) {
  657. }
  658. dstr_cat_strref(&func->contents, &ep->cfp.cur_token->str);
  659. }
  660. return true;
  661. }
  662. static void ep_parse_function(struct effect_parser *ep, char *type, char *name)
  663. {
  664. struct ep_func func;
  665. int code;
  666. ep_func_init(&func, type, name);
  667. if (ep_getstruct(ep, type))
  668. da_push_back(func.struct_deps, &func.ret_type);
  669. if (!ep_parse_func_params(ep, &func))
  670. goto error;
  671. if (!cf_next_valid_token(&ep->cfp))
  672. goto error;
  673. /* if function is mapped to something, for example COLOR */
  674. if (cf_token_is(&ep->cfp, ":")) {
  675. code = cf_next_name(&ep->cfp, &func.mapping, "mapping specifier", "{");
  676. if (code == PARSE_EOF)
  677. goto error;
  678. else if (code != PARSE_CONTINUE) {
  679. if (!cf_next_valid_token(&ep->cfp))
  680. goto error;
  681. }
  682. }
  683. if (!cf_token_is(&ep->cfp, "{")) {
  684. cf_adderror_expecting(&ep->cfp, "{");
  685. goto error;
  686. }
  687. if (!ep_parse_func_contents(ep, &func))
  688. goto error;
  689. /* it is established that the current token is '}' if we reach this */
  690. cf_next_token(&ep->cfp);
  691. da_push_back(ep->funcs, &func);
  692. return;
  693. error:
  694. ep_func_free(&func);
  695. }
  696. /* parses "array[count]" */
  697. static bool ep_parse_param_array(struct effect_parser *ep, struct ep_param *param)
  698. {
  699. if (!cf_next_valid_token(&ep->cfp))
  700. return false;
  701. if (ep->cfp.cur_token->type != CFTOKEN_NUM ||
  702. !valid_int_str(ep->cfp.cur_token->str.array, ep->cfp.cur_token->str.len))
  703. return false;
  704. param->array_count = (int)strtol(ep->cfp.cur_token->str.array, NULL, 10);
  705. if (cf_next_token_should_be(&ep->cfp, "]", ";", NULL) == PARSE_EOF)
  706. return false;
  707. if (!cf_next_valid_token(&ep->cfp))
  708. return false;
  709. return true;
  710. }
  711. static inline int ep_parse_param_assign_texture(struct effect_parser *ep, struct ep_param *param)
  712. {
  713. int code;
  714. char *str;
  715. if (!cf_next_valid_token(&ep->cfp))
  716. return PARSE_EOF;
  717. code = cf_token_is_type(&ep->cfp, CFTOKEN_STRING, "texture path string", ";");
  718. if (code != PARSE_SUCCESS)
  719. return code;
  720. str = cf_literal_to_str(ep->cfp.cur_token->str.array, ep->cfp.cur_token->str.len);
  721. if (str) {
  722. da_copy_array(param->default_val, str, strlen(str) + 1);
  723. bfree(str);
  724. }
  725. return PARSE_SUCCESS;
  726. }
  727. static inline int ep_parse_param_assign_string(struct effect_parser *ep, struct ep_param *param)
  728. {
  729. int code;
  730. char *str = NULL;
  731. if (!cf_next_valid_token(&ep->cfp))
  732. return PARSE_EOF;
  733. code = cf_token_is_type(&ep->cfp, CFTOKEN_STRING, "string", ";");
  734. if (code != PARSE_SUCCESS)
  735. return code;
  736. str = cf_literal_to_str(ep->cfp.cur_token->str.array, ep->cfp.cur_token->str.len);
  737. if (str) {
  738. da_copy_array(param->default_val, str, strlen(str) + 1);
  739. bfree(str);
  740. }
  741. return PARSE_SUCCESS;
  742. }
  743. static inline int ep_parse_param_assign_intfloat(struct effect_parser *ep, struct ep_param *param, bool is_float)
  744. {
  745. int code;
  746. bool is_negative = false;
  747. if (!cf_next_valid_token(&ep->cfp))
  748. return PARSE_EOF;
  749. if (cf_token_is(&ep->cfp, "-")) {
  750. is_negative = true;
  751. if (!cf_next_token(&ep->cfp))
  752. return PARSE_EOF;
  753. }
  754. code = cf_token_is_type(&ep->cfp, CFTOKEN_NUM, "numeric value", ";");
  755. if (code != PARSE_SUCCESS)
  756. return code;
  757. if (is_float) {
  758. float f = (float)os_strtod(ep->cfp.cur_token->str.array);
  759. if (is_negative)
  760. f = -f;
  761. da_push_back_array(param->default_val, (uint8_t *)&f, sizeof(float));
  762. } else {
  763. long l = strtol(ep->cfp.cur_token->str.array, NULL, 10);
  764. if (is_negative)
  765. l = -l;
  766. da_push_back_array(param->default_val, (uint8_t *)&l, sizeof(long));
  767. }
  768. return PARSE_SUCCESS;
  769. }
  770. static inline int ep_parse_param_assign_bool(struct effect_parser *ep, struct ep_param *param)
  771. {
  772. if (!cf_next_valid_token(&ep->cfp))
  773. return PARSE_EOF;
  774. if (cf_token_is(&ep->cfp, "true")) {
  775. long l = 1;
  776. da_push_back_array(param->default_val, (uint8_t *)&l, sizeof(long));
  777. return PARSE_SUCCESS;
  778. } else if (cf_token_is(&ep->cfp, "false")) {
  779. long l = 0;
  780. da_push_back_array(param->default_val, (uint8_t *)&l, sizeof(long));
  781. return PARSE_SUCCESS;
  782. }
  783. cf_adderror_expecting(&ep->cfp, "true or false");
  784. return PARSE_EOF;
  785. }
  786. /*
  787. * parses assignment for float1, float2, float3, float4, int1, int2, int3, int4,
  788. * and any combination for float3x3, float4x4, int3x3, int4x4, etc
  789. */
  790. static inline int ep_parse_param_assign_intfloat_array(struct effect_parser *ep, struct ep_param *param, bool is_float)
  791. {
  792. const char *intfloat_type = param->type + (is_float ? 5 : 3);
  793. int intfloat_count = 0, code, i;
  794. /* -------------------------------------------- */
  795. if (intfloat_type[0] < '1' || intfloat_type[0] > '4')
  796. cf_adderror(&ep->cfp, "Invalid row count", LEX_ERROR, NULL, NULL, NULL);
  797. intfloat_count = intfloat_type[0] - '0';
  798. if (intfloat_type[1] == 'x') {
  799. if (intfloat_type[2] < '1' || intfloat_type[2] > '4')
  800. cf_adderror(&ep->cfp, "Invalid column count", LEX_ERROR, NULL, NULL, NULL);
  801. intfloat_count *= intfloat_type[2] - '0';
  802. }
  803. /* -------------------------------------------- */
  804. code = cf_next_token_should_be(&ep->cfp, "{", ";", NULL);
  805. if (code != PARSE_SUCCESS)
  806. return code;
  807. for (i = 0; i < intfloat_count; i++) {
  808. char *next = ((i + 1) < intfloat_count) ? "," : "}";
  809. code = ep_parse_param_assign_intfloat(ep, param, is_float);
  810. if (code != PARSE_SUCCESS)
  811. return code;
  812. code = cf_next_token_should_be(&ep->cfp, next, ";", NULL);
  813. if (code != PARSE_SUCCESS)
  814. return code;
  815. }
  816. return PARSE_SUCCESS;
  817. }
  818. static int ep_parse_param_assignment_val(struct effect_parser *ep, struct ep_param *param)
  819. {
  820. if (param->is_texture)
  821. return ep_parse_param_assign_texture(ep, param);
  822. else if (strcmp(param->type, "int") == 0)
  823. return ep_parse_param_assign_intfloat(ep, param, false);
  824. else if (strcmp(param->type, "float") == 0)
  825. return ep_parse_param_assign_intfloat(ep, param, true);
  826. else if (astrcmp_n(param->type, "int", 3) == 0)
  827. return ep_parse_param_assign_intfloat_array(ep, param, false);
  828. else if (astrcmp_n(param->type, "float", 5) == 0)
  829. return ep_parse_param_assign_intfloat_array(ep, param, true);
  830. else if (astrcmp_n(param->type, "string", 6) == 0)
  831. return ep_parse_param_assign_string(ep, param);
  832. else if (strcmp(param->type, "bool") == 0)
  833. return ep_parse_param_assign_bool(ep, param);
  834. cf_adderror(&ep->cfp, "Invalid type '$1' used for assignment", LEX_ERROR, param->type, NULL, NULL);
  835. return PARSE_CONTINUE;
  836. }
  837. static inline bool ep_parse_param_assign(struct effect_parser *ep, struct ep_param *param)
  838. {
  839. if (ep_parse_param_assignment_val(ep, param) != PARSE_SUCCESS)
  840. return false;
  841. if (!cf_next_valid_token(&ep->cfp))
  842. return false;
  843. return true;
  844. }
  845. /* static bool ep_parse_param_property(struct effect_parser *ep,
  846. struct ep_param *param)
  847. {
  848. } */
  849. static void ep_parse_param(struct effect_parser *ep, char *type, char *name, bool is_property, bool is_const,
  850. bool is_uniform)
  851. {
  852. struct ep_param param;
  853. ep_param_init(&param, type, name, is_property, is_const, is_uniform);
  854. if (cf_token_is(&ep->cfp, ";"))
  855. goto complete;
  856. if (cf_token_is(&ep->cfp, "[") && !ep_parse_param_array(ep, &param))
  857. goto error;
  858. if (cf_token_is(&ep->cfp, "<") && !ep_parse_param_annotations(ep, &param))
  859. goto error;
  860. if (cf_token_is(&ep->cfp, "=") && !ep_parse_param_assign(ep, &param))
  861. goto error;
  862. /*
  863. if (cf_token_is(&ep->cfp, "<") && !ep_parse_param_property(ep, &param))
  864. goto error; */
  865. if (!cf_token_is(&ep->cfp, ";"))
  866. goto error;
  867. complete:
  868. da_push_back(ep->params, &param);
  869. return;
  870. error:
  871. ep_param_free(&param);
  872. }
  873. static bool ep_get_var_specifiers(struct effect_parser *ep, bool *is_property, bool *is_const, bool *is_uniform)
  874. {
  875. while (true) {
  876. int code;
  877. code = ep_check_for_keyword(ep, "property", is_property);
  878. if (code == PARSE_EOF)
  879. return false;
  880. else if (code == PARSE_CONTINUE)
  881. continue;
  882. code = ep_check_for_keyword(ep, "const", is_const);
  883. if (code == PARSE_EOF)
  884. return false;
  885. else if (code == PARSE_CONTINUE)
  886. continue;
  887. code = ep_check_for_keyword(ep, "uniform", is_uniform);
  888. if (code == PARSE_EOF)
  889. return false;
  890. else if (code == PARSE_CONTINUE)
  891. continue;
  892. break;
  893. }
  894. return true;
  895. }
  896. static inline void report_invalid_func_keyword(struct effect_parser *ep, const char *name, bool val)
  897. {
  898. if (val)
  899. cf_adderror(&ep->cfp,
  900. "'$1' keyword cannot be used with a "
  901. "function",
  902. LEX_ERROR, name, NULL, NULL);
  903. }
  904. static void ep_parse_other(struct effect_parser *ep)
  905. {
  906. bool is_property = false, is_const = false, is_uniform = false;
  907. char *type = NULL, *name = NULL;
  908. if (!ep_get_var_specifiers(ep, &is_property, &is_const, &is_uniform))
  909. goto error;
  910. if (cf_get_name(&ep->cfp, &type, "type", ";") != PARSE_SUCCESS)
  911. goto error;
  912. if (cf_next_name(&ep->cfp, &name, "name", ";") != PARSE_SUCCESS)
  913. goto error;
  914. if (!cf_next_valid_token(&ep->cfp))
  915. goto error;
  916. if (cf_token_is(&ep->cfp, "(")) {
  917. report_invalid_func_keyword(ep, "property", is_property);
  918. report_invalid_func_keyword(ep, "const", is_const);
  919. report_invalid_func_keyword(ep, "uniform", is_uniform);
  920. ep_parse_function(ep, type, name);
  921. return;
  922. } else {
  923. ep_parse_param(ep, type, name, is_property, is_const, is_uniform);
  924. return;
  925. }
  926. error:
  927. bfree(type);
  928. bfree(name);
  929. }
  930. static bool ep_compile(struct effect_parser *ep);
  931. extern const char *gs_preprocessor_name(void);
  932. #if defined(_DEBUG) && defined(_DEBUG_SHADERS)
  933. static void debug_get_default_value(struct gs_effect_param *param, char *buffer, unsigned long long buf_size)
  934. {
  935. if (param->default_val.num == 0) {
  936. snprintf(buffer, buf_size, "(null)");
  937. return;
  938. }
  939. switch (param->type) {
  940. case GS_SHADER_PARAM_STRING:
  941. snprintf(buffer, buf_size, "'%.*s'", param->default_val.num, param->default_val.array);
  942. break;
  943. case GS_SHADER_PARAM_INT:
  944. snprintf(buffer, buf_size, "%ld", *(int *)(param->default_val.array + 0));
  945. break;
  946. case GS_SHADER_PARAM_INT2:
  947. snprintf(buffer, buf_size, "%ld,%ld", *(int *)(param->default_val.array + 0),
  948. *(int *)(param->default_val.array + 4));
  949. break;
  950. case GS_SHADER_PARAM_INT3:
  951. snprintf(buffer, buf_size, "%ld,%ld,%ld", *(int *)(param->default_val.array + 0),
  952. *(int *)(param->default_val.array + 4), *(int *)(param->default_val.array + 8));
  953. break;
  954. case GS_SHADER_PARAM_INT4:
  955. snprintf(buffer, buf_size, "%ld,%ld,%ld,%ld", *(int *)(param->default_val.array + 0),
  956. *(int *)(param->default_val.array + 4), *(int *)(param->default_val.array + 8),
  957. *(int *)(param->default_val.array + 12));
  958. break;
  959. case GS_SHADER_PARAM_FLOAT:
  960. snprintf(buffer, buf_size, "%e", *(float *)(param->default_val.array + 0));
  961. break;
  962. case GS_SHADER_PARAM_VEC2:
  963. snprintf(buffer, buf_size, "%e,%e", *(float *)(param->default_val.array + 0),
  964. *(float *)(param->default_val.array + 4));
  965. break;
  966. case GS_SHADER_PARAM_VEC3:
  967. snprintf(buffer, buf_size, "%e,%e,%e", *(float *)(param->default_val.array + 0),
  968. *(float *)(param->default_val.array + 4), *(float *)(param->default_val.array + 8));
  969. break;
  970. case GS_SHADER_PARAM_VEC4:
  971. snprintf(buffer, buf_size, "%e,%e,%e,%e", *(float *)(param->default_val.array + 0),
  972. *(float *)(param->default_val.array + 4), *(float *)(param->default_val.array + 8),
  973. *(float *)(param->default_val.array + 12));
  974. break;
  975. case GS_SHADER_PARAM_MATRIX4X4:
  976. snprintf(buffer, buf_size,
  977. "[[%e,%e,%e,%e],[%e,%e,%e,%e],"
  978. "[%e,%e,%e,%e],[%e,%e,%e,%e]]",
  979. *(float *)(param->default_val.array + 0), *(float *)(param->default_val.array + 4),
  980. *(float *)(param->default_val.array + 8), *(float *)(param->default_val.array + 12),
  981. *(float *)(param->default_val.array + 16), *(float *)(param->default_val.array + 20),
  982. *(float *)(param->default_val.array + 24), *(float *)(param->default_val.array + 28),
  983. *(float *)(param->default_val.array + 32), *(float *)(param->default_val.array + 36),
  984. *(float *)(param->default_val.array + 40), *(float *)(param->default_val.array + 44),
  985. *(float *)(param->default_val.array + 48), *(float *)(param->default_val.array + 52),
  986. *(float *)(param->default_val.array + 56), *(float *)(param->default_val.array + 60));
  987. break;
  988. case GS_SHADER_PARAM_BOOL:
  989. snprintf(buffer, buf_size, "%s", (*param->default_val.array) != 0 ? "true\0" : "false\0");
  990. break;
  991. case GS_SHADER_PARAM_UNKNOWN:
  992. case GS_SHADER_PARAM_TEXTURE:
  993. snprintf(buffer, buf_size, "<unknown>");
  994. break;
  995. }
  996. }
  997. static void debug_param(struct gs_effect_param *param, struct ep_param *param_in, unsigned long long idx,
  998. const char *offset)
  999. {
  1000. char _debug_type[4096];
  1001. switch (param->type) {
  1002. case GS_SHADER_PARAM_STRING:
  1003. snprintf(_debug_type, sizeof(_debug_type), "string");
  1004. break;
  1005. case GS_SHADER_PARAM_INT:
  1006. snprintf(_debug_type, sizeof(_debug_type), "int");
  1007. break;
  1008. case GS_SHADER_PARAM_INT2:
  1009. snprintf(_debug_type, sizeof(_debug_type), "int2");
  1010. break;
  1011. case GS_SHADER_PARAM_INT3:
  1012. snprintf(_debug_type, sizeof(_debug_type), "int3");
  1013. break;
  1014. case GS_SHADER_PARAM_INT4:
  1015. snprintf(_debug_type, sizeof(_debug_type), "int4");
  1016. break;
  1017. case GS_SHADER_PARAM_FLOAT:
  1018. snprintf(_debug_type, sizeof(_debug_type), "float");
  1019. break;
  1020. case GS_SHADER_PARAM_VEC2:
  1021. snprintf(_debug_type, sizeof(_debug_type), "float2");
  1022. break;
  1023. case GS_SHADER_PARAM_VEC3:
  1024. snprintf(_debug_type, sizeof(_debug_type), "float3");
  1025. break;
  1026. case GS_SHADER_PARAM_VEC4:
  1027. snprintf(_debug_type, sizeof(_debug_type), "float4");
  1028. break;
  1029. case GS_SHADER_PARAM_MATRIX4X4:
  1030. snprintf(_debug_type, sizeof(_debug_type), "float4x4");
  1031. break;
  1032. case GS_SHADER_PARAM_BOOL:
  1033. snprintf(_debug_type, sizeof(_debug_type), "bool");
  1034. break;
  1035. case GS_SHADER_PARAM_UNKNOWN:
  1036. snprintf(_debug_type, sizeof(_debug_type), "unknown");
  1037. break;
  1038. case GS_SHADER_PARAM_TEXTURE:
  1039. snprintf(_debug_type, sizeof(_debug_type), "texture");
  1040. break;
  1041. }
  1042. char _debug_buf[4096];
  1043. debug_get_default_value(param, _debug_buf, sizeof(_debug_buf));
  1044. if (param->annotations.num > 0) {
  1045. blog(LOG_DEBUG, "%s[%4lld] %.*s '%s' with value %.*s and %lld annotations:", offset, idx,
  1046. sizeof(_debug_type), _debug_type, param->name, sizeof(_debug_buf), _debug_buf,
  1047. param->annotations.num);
  1048. } else {
  1049. blog(LOG_DEBUG, "%s[%4lld] %.*s '%s' with value %.*s.", offset, idx, sizeof(_debug_type), _debug_type,
  1050. param->name, sizeof(_debug_buf), _debug_buf);
  1051. }
  1052. }
  1053. static void debug_param_annotation(struct gs_effect_param *param, struct ep_param *param_in, unsigned long long idx,
  1054. const char *offset)
  1055. {
  1056. char _debug_buf[4096];
  1057. debug_get_default_value(param, _debug_buf, sizeof(_debug_buf));
  1058. blog(LOG_DEBUG, "%s[%4lld] %s '%s' with value %.*s", offset, idx, param_in->type, param->name,
  1059. sizeof(_debug_buf), _debug_buf);
  1060. }
  1061. static void debug_print_string(const char *offset, const char *str)
  1062. {
  1063. // Bypass 4096 limit in def_log_handler.
  1064. char const *begin = str;
  1065. unsigned long long line = 1;
  1066. for (char const *here = begin; here[0] != '\0'; here++) {
  1067. char const *str = begin;
  1068. unsigned long long len = here - begin;
  1069. bool is_line = false;
  1070. if (here[0] == '\r') {
  1071. is_line = true;
  1072. if (here[1] == '\n') {
  1073. here += 1;
  1074. }
  1075. begin = here + 1;
  1076. } else if (here[0] == '\n') {
  1077. is_line = true;
  1078. begin = here + 1;
  1079. }
  1080. if (is_line) {
  1081. blog(LOG_DEBUG, "\t\t\t\t[%4lld] %.*s", line, len, str);
  1082. line++;
  1083. }
  1084. }
  1085. if (begin[0] != '\0') {
  1086. // Final line was not written.
  1087. blog(LOG_DEBUG, "\t\t\t\t[%4lld] %*s", line, strlen(begin), begin);
  1088. }
  1089. }
  1090. #endif
  1091. bool ep_parse(struct effect_parser *ep, gs_effect_t *effect, const char *effect_string, const char *file)
  1092. {
  1093. bool success;
  1094. const char *graphics_preprocessor = gs_preprocessor_name();
  1095. if (graphics_preprocessor) {
  1096. struct cf_def def;
  1097. cf_def_init(&def);
  1098. def.name.str.array = graphics_preprocessor;
  1099. def.name.str.len = strlen(graphics_preprocessor);
  1100. strref_copy(&def.name.unmerged_str, &def.name.str);
  1101. cf_preprocessor_add_def(&ep->cfp.pp, &def);
  1102. }
  1103. ep->effect = effect;
  1104. if (!cf_parser_parse(&ep->cfp, effect_string, file))
  1105. return false;
  1106. while (ep->cfp.cur_token && ep->cfp.cur_token->type != CFTOKEN_NONE) {
  1107. if (cf_token_is(&ep->cfp, ";") || is_whitespace(*ep->cfp.cur_token->str.array)) {
  1108. /* do nothing */
  1109. ep->cfp.cur_token++;
  1110. } else if (cf_token_is(&ep->cfp, "struct")) {
  1111. ep_parse_struct(ep);
  1112. } else if (cf_token_is(&ep->cfp, "technique")) {
  1113. ep_parse_technique(ep);
  1114. } else if (cf_token_is(&ep->cfp, "sampler_state")) {
  1115. ep_parse_sampler_state(ep);
  1116. } else if (cf_token_is(&ep->cfp, "{")) {
  1117. /* add error and pass braces */
  1118. cf_adderror(&ep->cfp, "Unexpected code segment", LEX_ERROR, NULL, NULL, NULL);
  1119. cf_pass_pair(&ep->cfp, '{', '}');
  1120. } else {
  1121. /* parameters and functions */
  1122. ep_parse_other(ep);
  1123. }
  1124. }
  1125. #if defined(_DEBUG) && defined(_DEBUG_SHADERS)
  1126. blog(LOG_DEBUG, "================================================================================");
  1127. blog(LOG_DEBUG, "Effect Parser reformatted shader '%s' to:", file);
  1128. debug_print_string("\t", ep->cfp.lex.reformatted);
  1129. #endif
  1130. success = !error_data_has_errors(&ep->cfp.error_list);
  1131. if (success)
  1132. success = ep_compile(ep);
  1133. #if defined(_DEBUG) && defined(_DEBUG_SHADERS)
  1134. blog(LOG_DEBUG, "================================================================================");
  1135. #endif
  1136. return success;
  1137. }
  1138. /* ------------------------------------------------------------------------- */
  1139. static inline void ep_write_param(struct dstr *shader, struct ep_param *param, dstr_array_t *used_params)
  1140. {
  1141. if (param->written)
  1142. return;
  1143. if (param->is_const) {
  1144. dstr_cat(shader, "const ");
  1145. } else if (param->is_uniform) {
  1146. struct dstr new;
  1147. dstr_init_copy(&new, param->name);
  1148. da_push_back(*used_params, &new);
  1149. dstr_cat(shader, "uniform ");
  1150. }
  1151. dstr_cat(shader, param->type);
  1152. dstr_cat(shader, " ");
  1153. dstr_cat(shader, param->name);
  1154. if (param->array_count)
  1155. dstr_catf(shader, "[%u]", param->array_count);
  1156. dstr_cat(shader, ";\n");
  1157. param->written = true;
  1158. }
  1159. static inline void ep_write_func_param_deps(struct effect_parser *ep, struct dstr *shader, struct ep_func *func,
  1160. dstr_array_t *used_params)
  1161. {
  1162. size_t i;
  1163. for (i = 0; i < func->param_deps.num; i++) {
  1164. const char *name = func->param_deps.array[i];
  1165. struct ep_param *param = ep_getparam(ep, name);
  1166. ep_write_param(shader, param, used_params);
  1167. }
  1168. if (func->param_deps.num)
  1169. dstr_cat(shader, "\n\n");
  1170. }
  1171. static void ep_write_sampler(struct dstr *shader, struct ep_sampler *sampler)
  1172. {
  1173. size_t i;
  1174. if (sampler->written)
  1175. return;
  1176. dstr_cat(shader, "sampler_state ");
  1177. dstr_cat(shader, sampler->name);
  1178. dstr_cat(shader, " {");
  1179. for (i = 0; i < sampler->values.num; i++) {
  1180. dstr_cat(shader, "\n\t");
  1181. dstr_cat(shader, sampler->states.array[i]);
  1182. dstr_cat(shader, " = ");
  1183. dstr_cat(shader, sampler->values.array[i]);
  1184. dstr_cat(shader, ";\n");
  1185. }
  1186. dstr_cat(shader, "\n};\n");
  1187. sampler->written = true;
  1188. }
  1189. static inline void ep_write_func_sampler_deps(struct effect_parser *ep, struct dstr *shader, struct ep_func *func)
  1190. {
  1191. size_t i;
  1192. for (i = 0; i < func->sampler_deps.num; i++) {
  1193. const char *name = func->sampler_deps.array[i];
  1194. struct ep_sampler *sampler = ep_getsampler(ep, name);
  1195. ep_write_sampler(shader, sampler);
  1196. dstr_cat(shader, "\n");
  1197. }
  1198. }
  1199. static inline void ep_write_var(struct dstr *shader, struct ep_var *var)
  1200. {
  1201. if (var->var_type == EP_VAR_INOUT)
  1202. dstr_cat(shader, "inout ");
  1203. else if (var->var_type == EP_VAR_OUT)
  1204. dstr_cat(shader, "out ");
  1205. else if (var->var_type == EP_VAR_UNIFORM)
  1206. dstr_cat(shader, "uniform ");
  1207. // The "in" input modifier is implied by default, so leave it blank
  1208. // in that case.
  1209. dstr_cat(shader, var->type);
  1210. dstr_cat(shader, " ");
  1211. dstr_cat(shader, var->name);
  1212. if (var->mapping) {
  1213. dstr_cat(shader, " : ");
  1214. dstr_cat(shader, var->mapping);
  1215. }
  1216. }
  1217. static void ep_write_struct(struct dstr *shader, struct ep_struct *st)
  1218. {
  1219. size_t i;
  1220. if (st->written)
  1221. return;
  1222. dstr_cat(shader, "struct ");
  1223. dstr_cat(shader, st->name);
  1224. dstr_cat(shader, " {");
  1225. for (i = 0; i < st->vars.num; i++) {
  1226. dstr_cat(shader, "\n\t");
  1227. ep_write_var(shader, st->vars.array + i);
  1228. dstr_cat(shader, ";");
  1229. }
  1230. dstr_cat(shader, "\n};\n");
  1231. st->written = true;
  1232. }
  1233. static inline void ep_write_func_struct_deps(struct effect_parser *ep, struct dstr *shader, struct ep_func *func)
  1234. {
  1235. size_t i;
  1236. for (i = 0; i < func->struct_deps.num; i++) {
  1237. const char *name = func->struct_deps.array[i];
  1238. struct ep_struct *st = ep_getstruct(ep, name);
  1239. if (!st->written) {
  1240. ep_write_struct(shader, st);
  1241. dstr_cat(shader, "\n");
  1242. st->written = true;
  1243. }
  1244. }
  1245. }
  1246. static void ep_write_func(struct effect_parser *ep, struct dstr *shader, struct ep_func *func,
  1247. dstr_array_t *used_params);
  1248. static inline void ep_write_func_func_deps(struct effect_parser *ep, struct dstr *shader, struct ep_func *func,
  1249. dstr_array_t *used_params)
  1250. {
  1251. size_t i;
  1252. for (i = 0; i < func->func_deps.num; i++) {
  1253. const char *name = func->func_deps.array[i];
  1254. struct ep_func *func_dep = ep_getfunc(ep, name);
  1255. if (!func_dep->written) {
  1256. ep_write_func(ep, shader, func_dep, used_params);
  1257. dstr_cat(shader, "\n\n");
  1258. }
  1259. }
  1260. }
  1261. static void ep_write_func(struct effect_parser *ep, struct dstr *shader, struct ep_func *func,
  1262. dstr_array_t *used_params)
  1263. {
  1264. size_t i;
  1265. func->written = true;
  1266. ep_write_func_param_deps(ep, shader, func, used_params);
  1267. ep_write_func_sampler_deps(ep, shader, func);
  1268. ep_write_func_struct_deps(ep, shader, func);
  1269. ep_write_func_func_deps(ep, shader, func, used_params);
  1270. /* ------------------------------------ */
  1271. dstr_cat(shader, func->ret_type);
  1272. dstr_cat(shader, " ");
  1273. dstr_cat(shader, func->name);
  1274. dstr_cat(shader, "(");
  1275. for (i = 0; i < func->param_vars.num; i++) {
  1276. struct ep_var *var = func->param_vars.array + i;
  1277. if (i)
  1278. dstr_cat(shader, ", ");
  1279. ep_write_var(shader, var);
  1280. }
  1281. dstr_cat(shader, ")\n");
  1282. dstr_cat_dstr(shader, &func->contents);
  1283. dstr_cat(shader, "\n");
  1284. }
  1285. /* writes mapped vars used by the call as parameters for main */
  1286. static void ep_write_main_params(struct effect_parser *ep, struct dstr *shader, struct dstr *param_str,
  1287. struct ep_func *func)
  1288. {
  1289. size_t i;
  1290. bool empty_params = dstr_is_empty(param_str);
  1291. for (i = 0; i < func->param_vars.num; i++) {
  1292. struct ep_var *var = func->param_vars.array + i;
  1293. struct ep_struct *st = NULL;
  1294. bool mapped = (var->mapping != NULL);
  1295. if (!mapped) {
  1296. st = ep_getstruct(ep, var->type);
  1297. if (st)
  1298. mapped = ep_struct_mapped(st);
  1299. }
  1300. if (mapped) {
  1301. dstr_cat(shader, var->type);
  1302. dstr_cat(shader, " ");
  1303. dstr_cat(shader, var->name);
  1304. if (!st) {
  1305. dstr_cat(shader, " : ");
  1306. dstr_cat(shader, var->mapping);
  1307. }
  1308. if (!dstr_is_empty(param_str))
  1309. dstr_cat(param_str, ", ");
  1310. dstr_cat(param_str, var->name);
  1311. }
  1312. }
  1313. if (!empty_params)
  1314. dstr_cat(param_str, ", ");
  1315. }
  1316. static void ep_write_main(struct effect_parser *ep, struct dstr *shader, struct ep_func *func, struct dstr *call_str)
  1317. {
  1318. struct dstr param_str;
  1319. struct dstr adjusted_call;
  1320. dstr_init(&param_str);
  1321. dstr_init_copy_dstr(&adjusted_call, call_str);
  1322. dstr_cat(shader, "\n");
  1323. dstr_cat(shader, func->ret_type);
  1324. dstr_cat(shader, " main(");
  1325. ep_write_main_params(ep, shader, &param_str, func);
  1326. dstr_cat(shader, ")");
  1327. if (func->mapping) {
  1328. dstr_cat(shader, " : ");
  1329. dstr_cat(shader, func->mapping);
  1330. }
  1331. dstr_cat(shader, "\n{\n\treturn ");
  1332. dstr_cat_dstr(shader, &adjusted_call);
  1333. dstr_cat(shader, "\n}\n");
  1334. dstr_free(&adjusted_call);
  1335. dstr_free(&param_str);
  1336. }
  1337. static inline void ep_reset_written(struct effect_parser *ep)
  1338. {
  1339. size_t i;
  1340. for (i = 0; i < ep->params.num; i++)
  1341. ep->params.array[i].written = false;
  1342. for (i = 0; i < ep->structs.num; i++)
  1343. ep->structs.array[i].written = false;
  1344. for (i = 0; i < ep->funcs.num; i++)
  1345. ep->funcs.array[i].written = false;
  1346. for (i = 0; i < ep->samplers.num; i++)
  1347. ep->samplers.array[i].written = false;
  1348. }
  1349. static void ep_makeshaderstring(struct effect_parser *ep, struct dstr *shader, cf_token_array_t *shader_call,
  1350. dstr_array_t *used_params)
  1351. {
  1352. struct cf_token *token = shader_call->array;
  1353. struct cf_token *func_name;
  1354. struct ep_func *func;
  1355. struct dstr call_str;
  1356. dstr_init(&call_str);
  1357. if (!token)
  1358. return;
  1359. while (token->type != CFTOKEN_NONE && is_whitespace(*token->str.array))
  1360. token++;
  1361. if (token->type == CFTOKEN_NONE || strref_cmp(&token->str, "NULL") == 0)
  1362. return;
  1363. func_name = token;
  1364. while (token->type != CFTOKEN_NONE) {
  1365. struct ep_param *param = ep_getparam_strref(ep, &token->str);
  1366. if (param)
  1367. ep_write_param(shader, param, used_params);
  1368. dstr_cat_strref(&call_str, &token->str);
  1369. token++;
  1370. }
  1371. func = ep_getfunc_strref(ep, &func_name->str);
  1372. if (!func)
  1373. return;
  1374. ep_write_func(ep, shader, func, used_params);
  1375. ep_write_main(ep, shader, func, &call_str);
  1376. dstr_free(&call_str);
  1377. ep_reset_written(ep);
  1378. }
  1379. static void ep_compile_annotations(ep_param_array_t *ep_annotations, gs_effect_param_array_t *gsp_annotations,
  1380. struct effect_parser *ep)
  1381. {
  1382. da_resize(*gsp_annotations, ep_annotations->num);
  1383. size_t i;
  1384. for (i = 0; i < ep_annotations->num; i++) {
  1385. struct gs_effect_param *param = gsp_annotations->array + i;
  1386. struct ep_param *param_in = ep_annotations->array + i;
  1387. param->name = bstrdup(param_in->name);
  1388. param->section = EFFECT_ANNOTATION;
  1389. param->effect = ep->effect;
  1390. da_move(param->default_val, param_in->default_val);
  1391. param->type = get_effect_param_type(param_in->type);
  1392. #if defined(_DEBUG) && defined(_DEBUG_SHADERS)
  1393. debug_param(param, param_in, i, "\t\t");
  1394. #endif
  1395. }
  1396. }
  1397. static void ep_compile_param_annotations(struct ep_param *ep_param_input, struct gs_effect_param *gs_effect_input,
  1398. struct effect_parser *ep)
  1399. {
  1400. ep_compile_annotations(&(ep_param_input->annotations), &(gs_effect_input->annotations), ep);
  1401. }
  1402. static void ep_compile_param(struct effect_parser *ep, size_t idx)
  1403. {
  1404. struct gs_effect_param *param;
  1405. struct ep_param *param_in;
  1406. param = ep->effect->params.array + idx;
  1407. param_in = ep->params.array + idx;
  1408. param_in->param = param;
  1409. param->name = bstrdup(param_in->name);
  1410. param->section = EFFECT_PARAM;
  1411. param->effect = ep->effect;
  1412. da_move(param->default_val, param_in->default_val);
  1413. param->type = get_effect_param_type(param_in->type);
  1414. if (strcmp(param_in->name, "ViewProj") == 0)
  1415. ep->effect->view_proj = param;
  1416. else if (strcmp(param_in->name, "World") == 0)
  1417. ep->effect->world = param;
  1418. #if defined(_DEBUG) && defined(_DEBUG_SHADERS)
  1419. debug_param(param, param_in, idx, "\t");
  1420. #endif
  1421. ep_compile_param_annotations(param_in, param, ep);
  1422. }
  1423. static bool ep_compile_pass_shaderparams(struct effect_parser *ep, pass_shaderparam_array_t *pass_params,
  1424. dstr_array_t *used_params, gs_shader_t *shader)
  1425. {
  1426. size_t i;
  1427. da_resize(*pass_params, used_params->num);
  1428. for (i = 0; i < pass_params->num; i++) {
  1429. struct dstr *param_name = used_params->array + i;
  1430. struct pass_shaderparam *param = pass_params->array + i;
  1431. param->eparam = gs_effect_get_param_by_name(ep->effect, param_name->array);
  1432. param->sparam = gs_shader_get_param_by_name(shader, param_name->array);
  1433. #if defined(_DEBUG) && defined(_DEBUG_SHADERS)
  1434. debug_param(param->eparam, 0, i, "\t\t\t\t");
  1435. #endif
  1436. if (!param->sparam) {
  1437. blog(LOG_ERROR, "Effect shader parameter not found");
  1438. return false;
  1439. }
  1440. }
  1441. return true;
  1442. }
  1443. static inline bool ep_compile_pass_shader(struct effect_parser *ep, struct gs_effect_technique *tech,
  1444. struct gs_effect_pass *pass, struct ep_pass *pass_in, size_t pass_idx,
  1445. enum gs_shader_type type)
  1446. {
  1447. struct dstr shader_str;
  1448. struct dstr location;
  1449. dstr_array_t used_params;
  1450. pass_shaderparam_array_t *pass_params = NULL;
  1451. gs_shader_t *shader = NULL;
  1452. bool success = true;
  1453. char *errors = NULL;
  1454. dstr_init(&shader_str);
  1455. da_init(used_params);
  1456. dstr_init(&location);
  1457. dstr_copy(&location, ep->cfp.lex.file);
  1458. if (type == GS_SHADER_VERTEX)
  1459. dstr_cat(&location, " (Vertex ");
  1460. else if (type == GS_SHADER_PIXEL)
  1461. dstr_cat(&location, " (Pixel ");
  1462. /*else if (type == SHADER_GEOMETRY)
  1463. dstr_cat(&location, " (Geometry ");*/
  1464. assert(pass_idx <= UINT_MAX);
  1465. dstr_catf(&location, "shader, technique %s, pass %u)", tech->name, (unsigned)pass_idx);
  1466. if (type == GS_SHADER_VERTEX) {
  1467. ep_makeshaderstring(ep, &shader_str, &pass_in->vertex_program, &used_params);
  1468. pass->vertshader = gs_vertexshader_create(shader_str.array, location.array, &errors);
  1469. shader = pass->vertshader;
  1470. pass_params = &pass->vertshader_params;
  1471. } else if (type == GS_SHADER_PIXEL) {
  1472. ep_makeshaderstring(ep, &shader_str, &pass_in->fragment_program, &used_params);
  1473. pass->pixelshader = gs_pixelshader_create(shader_str.array, location.array, &errors);
  1474. shader = pass->pixelshader;
  1475. pass_params = &pass->pixelshader_params;
  1476. }
  1477. if (errors && strlen(errors)) {
  1478. cf_adderror(&ep->cfp, "Error creating shader: $1", LEX_ERROR, errors, NULL, NULL);
  1479. }
  1480. bfree(errors);
  1481. #if defined(_DEBUG) && defined(_DEBUG_SHADERS)
  1482. blog(LOG_DEBUG, "\t\t\t%s Shader:", type == GS_SHADER_VERTEX ? "Vertex" : "Fragment");
  1483. blog(LOG_DEBUG, "\t\t\tCode:");
  1484. debug_print_string("\t\t\t\t\t", shader_str.array);
  1485. blog(LOG_DEBUG, "\t\t\tParameters:");
  1486. #endif
  1487. if (shader)
  1488. success = ep_compile_pass_shaderparams(ep, pass_params, &used_params, shader);
  1489. else
  1490. success = false;
  1491. dstr_free(&location);
  1492. dstr_array_free(used_params.array, used_params.num);
  1493. da_free(used_params);
  1494. dstr_free(&shader_str);
  1495. return success;
  1496. }
  1497. static bool ep_compile_pass(struct effect_parser *ep, struct gs_effect_technique *tech, struct ep_technique *tech_in,
  1498. size_t idx)
  1499. {
  1500. struct gs_effect_pass *pass;
  1501. struct ep_pass *pass_in;
  1502. bool success = true;
  1503. pass = tech->passes.array + idx;
  1504. pass_in = tech_in->passes.array + idx;
  1505. pass->name = bstrdup(pass_in->name);
  1506. pass->section = EFFECT_PASS;
  1507. #if defined(_DEBUG) && defined(_DEBUG_SHADERS)
  1508. blog(LOG_DEBUG, "\t\t[%4lld] Pass '%s':", idx, pass->name);
  1509. #endif
  1510. if (!ep_compile_pass_shader(ep, tech, pass, pass_in, idx, GS_SHADER_VERTEX)) {
  1511. success = false;
  1512. blog(LOG_ERROR, "Pass (%zu) <%s> missing vertex shader!", idx, pass->name ? pass->name : "");
  1513. }
  1514. if (!ep_compile_pass_shader(ep, tech, pass, pass_in, idx, GS_SHADER_PIXEL)) {
  1515. success = false;
  1516. blog(LOG_ERROR, "Pass (%zu) <%s> missing pixel shader!", idx, pass->name ? pass->name : "");
  1517. }
  1518. return success;
  1519. }
  1520. static inline bool ep_compile_technique(struct effect_parser *ep, size_t idx)
  1521. {
  1522. struct gs_effect_technique *tech;
  1523. struct ep_technique *tech_in;
  1524. bool success = true;
  1525. size_t i;
  1526. tech = ep->effect->techniques.array + idx;
  1527. tech_in = ep->techniques.array + idx;
  1528. tech->name = bstrdup(tech_in->name);
  1529. tech->section = EFFECT_TECHNIQUE;
  1530. tech->effect = ep->effect;
  1531. da_resize(tech->passes, tech_in->passes.num);
  1532. #if defined(_DEBUG) && defined(_DEBUG_SHADERS)
  1533. blog(LOG_DEBUG, "\t[%4lld] Technique '%s' has %lld passes:", idx, tech->name, tech->passes.num);
  1534. #endif
  1535. for (i = 0; i < tech->passes.num; i++) {
  1536. if (!ep_compile_pass(ep, tech, tech_in, i))
  1537. success = false;
  1538. }
  1539. return success;
  1540. }
  1541. static bool ep_compile(struct effect_parser *ep)
  1542. {
  1543. bool success = true;
  1544. size_t i;
  1545. assert(ep->effect);
  1546. da_resize(ep->effect->params, ep->params.num);
  1547. da_resize(ep->effect->techniques, ep->techniques.num);
  1548. #if defined(_DEBUG) && defined(_DEBUG_SHADERS)
  1549. blog(LOG_DEBUG, "Shader has %lld parameters:", ep->params.num);
  1550. #endif
  1551. for (i = 0; i < ep->params.num; i++)
  1552. ep_compile_param(ep, i);
  1553. #if defined(_DEBUG) && defined(_DEBUG_SHADERS)
  1554. blog(LOG_DEBUG, "Shader has %lld techniques:", ep->techniques.num);
  1555. #endif
  1556. for (i = 0; i < ep->techniques.num; i++) {
  1557. if (!ep_compile_technique(ep, i))
  1558. success = false;
  1559. }
  1560. return success;
  1561. }