effect-parser.h 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  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. #pragma once
  15. #include "../util/darray.h"
  16. #include "../util/cf-parser.h"
  17. #include "graphics.h"
  18. #include "shader-parser.h"
  19. #ifdef __cplusplus
  20. extern "C" {
  21. #endif
  22. struct dstr;
  23. typedef DARRAY(struct ep_param) ep_param_array_t;
  24. typedef DARRAY(struct ep_var) ep_var_array_t;
  25. /*
  26. * The effect parser takes an effect file and converts it into individual
  27. * shaders for each technique's pass. It automatically writes all dependent
  28. * structures/functions/parameters to the shader and builds shader text for
  29. * each shader component of each pass.
  30. */
  31. /* ------------------------------------------------------------------------- */
  32. /* effect parser var data */
  33. enum ep_var_type {
  34. EP_VAR_NONE,
  35. EP_VAR_IN = EP_VAR_NONE,
  36. EP_VAR_INOUT,
  37. EP_VAR_OUT,
  38. EP_VAR_UNIFORM
  39. };
  40. struct ep_var {
  41. char *type, *name, *mapping;
  42. enum ep_var_type var_type;
  43. };
  44. static inline void ep_var_init(struct ep_var *epv)
  45. {
  46. memset(epv, 0, sizeof(struct ep_var));
  47. }
  48. static inline void ep_var_free(struct ep_var *epv)
  49. {
  50. bfree(epv->type);
  51. bfree(epv->name);
  52. bfree(epv->mapping);
  53. }
  54. /* ------------------------------------------------------------------------- */
  55. /* effect parser param data */
  56. struct ep_param {
  57. char *type, *name;
  58. DARRAY(uint8_t) default_val;
  59. DARRAY(char *) properties;
  60. struct gs_effect_param *param;
  61. bool is_const, is_property, is_uniform, is_texture, written;
  62. int writeorder, array_count;
  63. ep_param_array_t annotations;
  64. };
  65. static inline void ep_param_init(struct ep_param *epp, char *type, char *name,
  66. bool is_property, bool is_const,
  67. bool is_uniform)
  68. {
  69. epp->type = type;
  70. epp->name = name;
  71. epp->is_property = is_property;
  72. epp->is_const = is_const;
  73. epp->is_uniform = is_uniform;
  74. epp->is_texture = (astrcmp_n(epp->type, "texture", 7) == 0);
  75. epp->written = false;
  76. epp->writeorder = false;
  77. epp->array_count = 0;
  78. da_init(epp->default_val);
  79. da_init(epp->properties);
  80. da_init(epp->annotations);
  81. }
  82. static inline void ep_param_free(struct ep_param *epp)
  83. {
  84. bfree(epp->type);
  85. bfree(epp->name);
  86. da_free(epp->default_val);
  87. da_free(epp->properties);
  88. for (size_t i = 0; i < epp->annotations.num; i++)
  89. ep_param_free(epp->annotations.array + i);
  90. da_free(epp->annotations);
  91. }
  92. /* ------------------------------------------------------------------------- */
  93. /* effect parser struct data */
  94. struct ep_struct {
  95. char *name;
  96. ep_var_array_t vars; /* struct ep_var */
  97. bool written;
  98. };
  99. static inline bool ep_struct_mapped(struct ep_struct *eps)
  100. {
  101. if (eps->vars.num > 0)
  102. return eps->vars.array[0].mapping != NULL;
  103. return false;
  104. }
  105. static inline void ep_struct_init(struct ep_struct *eps)
  106. {
  107. memset(eps, 0, sizeof(struct ep_struct));
  108. }
  109. static inline void ep_struct_free(struct ep_struct *eps)
  110. {
  111. size_t i;
  112. bfree(eps->name);
  113. for (i = 0; i < eps->vars.num; i++)
  114. ep_var_free(eps->vars.array + i);
  115. da_free(eps->vars);
  116. }
  117. /* ------------------------------------------------------------------------- */
  118. /* effect parser sampler data */
  119. struct ep_sampler {
  120. char *name;
  121. DARRAY(char *) states;
  122. DARRAY(char *) values;
  123. bool written;
  124. };
  125. static inline void ep_sampler_init(struct ep_sampler *eps)
  126. {
  127. memset(eps, 0, sizeof(struct ep_sampler));
  128. }
  129. static inline void ep_sampler_free(struct ep_sampler *eps)
  130. {
  131. size_t i;
  132. for (i = 0; i < eps->states.num; i++)
  133. bfree(eps->states.array[i]);
  134. for (i = 0; i < eps->values.num; i++)
  135. bfree(eps->values.array[i]);
  136. bfree(eps->name);
  137. da_free(eps->states);
  138. da_free(eps->values);
  139. }
  140. /* ------------------------------------------------------------------------- */
  141. /* effect parser pass data */
  142. struct ep_pass {
  143. char *name;
  144. cf_token_array_t vertex_program;
  145. cf_token_array_t fragment_program;
  146. struct gs_effect_pass *pass;
  147. };
  148. static inline void ep_pass_init(struct ep_pass *epp)
  149. {
  150. memset(epp, 0, sizeof(struct ep_pass));
  151. }
  152. static inline void ep_pass_free(struct ep_pass *epp)
  153. {
  154. bfree(epp->name);
  155. da_free(epp->vertex_program);
  156. da_free(epp->fragment_program);
  157. }
  158. /* ------------------------------------------------------------------------- */
  159. /* effect parser technique data */
  160. struct ep_technique {
  161. char *name;
  162. DARRAY(struct ep_pass) passes; /* struct ep_pass */
  163. };
  164. static inline void ep_technique_init(struct ep_technique *ept)
  165. {
  166. memset(ept, 0, sizeof(struct ep_technique));
  167. }
  168. static inline void ep_technique_free(struct ep_technique *ept)
  169. {
  170. size_t i;
  171. for (i = 0; i < ept->passes.num; i++)
  172. ep_pass_free(ept->passes.array + i);
  173. bfree(ept->name);
  174. da_free(ept->passes);
  175. }
  176. /* ------------------------------------------------------------------------- */
  177. /* effect parser function data */
  178. struct ep_func {
  179. char *name, *ret_type, *mapping;
  180. struct dstr contents;
  181. ep_var_array_t param_vars;
  182. DARRAY(char *) func_deps;
  183. DARRAY(char *) struct_deps;
  184. DARRAY(char *) param_deps;
  185. DARRAY(char *) sampler_deps;
  186. bool written;
  187. };
  188. static inline void ep_func_init(struct ep_func *epf, char *ret_type, char *name)
  189. {
  190. memset(epf, 0, sizeof(struct ep_func));
  191. epf->name = name;
  192. epf->ret_type = ret_type;
  193. }
  194. static inline void ep_func_free(struct ep_func *epf)
  195. {
  196. size_t i;
  197. for (i = 0; i < epf->param_vars.num; i++)
  198. ep_var_free(epf->param_vars.array + i);
  199. bfree(epf->name);
  200. bfree(epf->ret_type);
  201. bfree(epf->mapping);
  202. dstr_free(&epf->contents);
  203. da_free(epf->param_vars);
  204. da_free(epf->func_deps);
  205. da_free(epf->struct_deps);
  206. da_free(epf->param_deps);
  207. da_free(epf->sampler_deps);
  208. }
  209. /* ------------------------------------------------------------------------- */
  210. struct effect_parser {
  211. gs_effect_t *effect;
  212. ep_param_array_t params;
  213. DARRAY(struct ep_struct) structs;
  214. DARRAY(struct ep_func) funcs;
  215. DARRAY(struct ep_sampler) samplers;
  216. DARRAY(struct ep_technique) techniques;
  217. /* internal vars */
  218. DARRAY(struct cf_lexer) files;
  219. cf_token_array_t tokens;
  220. struct gs_effect_pass *cur_pass;
  221. struct cf_parser cfp;
  222. };
  223. static inline void ep_init(struct effect_parser *ep)
  224. {
  225. da_init(ep->params);
  226. da_init(ep->structs);
  227. da_init(ep->funcs);
  228. da_init(ep->samplers);
  229. da_init(ep->techniques);
  230. da_init(ep->files);
  231. da_init(ep->tokens);
  232. ep->cur_pass = NULL;
  233. cf_parser_init(&ep->cfp);
  234. }
  235. extern void ep_free(struct effect_parser *ep);
  236. extern bool ep_parse(struct effect_parser *ep, gs_effect_t *effect,
  237. const char *effect_string, const char *file);
  238. #ifdef __cplusplus
  239. }
  240. #endif