Clone of mesa.
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

ast_function.cpp 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. /*
  2. * Copyright © 2010 Intel Corporation
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a
  5. * copy of this software and associated documentation files (the "Software"),
  6. * to deal in the Software without restriction, including without limitation
  7. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. * and/or sell copies of the Software, and to permit persons to whom the
  9. * Software is furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice (including the next
  12. * paragraph) shall be included in all copies or substantial portions of the
  13. * Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  18. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  21. * DEALINGS IN THE SOFTWARE.
  22. */
  23. #include <cstdio>
  24. #include "glsl_symbol_table.h"
  25. #include "ast.h"
  26. #include "glsl_types.h"
  27. #include "ir.h"
  28. static ir_rvalue *
  29. match_function_by_name(exec_list *instructions, const char *name,
  30. YYLTYPE *loc, simple_node *parameters,
  31. struct _mesa_glsl_parse_state *state)
  32. {
  33. ir_function *f = state->symbols->get_function(name);
  34. if (f == NULL) {
  35. _mesa_glsl_error(loc, state, "function `%s' undeclared", name);
  36. return ir_call::get_error_instruction();
  37. }
  38. /* Once we've determined that the function being called might exist,
  39. * process the parameters.
  40. */
  41. exec_list actual_parameters;
  42. simple_node *const first = parameters;
  43. if (first != NULL) {
  44. simple_node *ptr = first;
  45. do {
  46. ir_instruction *const result =
  47. ((ast_node *) ptr)->hir(instructions, state);
  48. ptr = ptr->next;
  49. actual_parameters.push_tail(result);
  50. } while (ptr != first);
  51. }
  52. /* After processing the function's actual parameters, try to find an
  53. * overload of the function that matches.
  54. */
  55. const ir_function_signature *sig =
  56. f->matching_signature(& actual_parameters);
  57. if (sig != NULL) {
  58. /* FINISHME: The list of actual parameters needs to be modified to
  59. * FINISHME: include any necessary conversions.
  60. */
  61. return new ir_call(sig, & actual_parameters);
  62. } else {
  63. /* FINISHME: Log a better error message here. G++ will show the types
  64. * FINISHME: of the actual parameters and the set of candidate
  65. * FINISHME: functions. A different error should also be logged when
  66. * FINISHME: multiple functions match.
  67. */
  68. _mesa_glsl_error(loc, state, "no matching function for call to `%s'",
  69. name);
  70. return ir_call::get_error_instruction();
  71. }
  72. }
  73. /**
  74. * Perform automatic type conversion of constructor parameters
  75. */
  76. static ir_rvalue *
  77. convert_component(ir_rvalue *src, const glsl_type *desired_type)
  78. {
  79. const unsigned a = desired_type->base_type;
  80. const unsigned b = src->type->base_type;
  81. if (src->type->is_error())
  82. return src;
  83. assert(a <= GLSL_TYPE_BOOL);
  84. assert(b <= GLSL_TYPE_BOOL);
  85. if ((a == b) || (src->type->is_integer() && desired_type->is_integer()))
  86. return src;
  87. switch (a) {
  88. case GLSL_TYPE_UINT:
  89. case GLSL_TYPE_INT:
  90. if (b == GLSL_TYPE_FLOAT)
  91. return new ir_expression(ir_unop_f2i, desired_type, src, NULL);
  92. else {
  93. assert(b == GLSL_TYPE_BOOL);
  94. assert(!"FINISHME: Convert bool to int / uint.");
  95. }
  96. case GLSL_TYPE_FLOAT:
  97. switch (b) {
  98. case GLSL_TYPE_UINT:
  99. return new ir_expression(ir_unop_u2f, desired_type, src, NULL);
  100. case GLSL_TYPE_INT:
  101. return new ir_expression(ir_unop_i2f, desired_type, src, NULL);
  102. case GLSL_TYPE_BOOL:
  103. assert(!"FINISHME: Convert bool to float.");
  104. }
  105. break;
  106. case GLSL_TYPE_BOOL: {
  107. int z = 0;
  108. ir_constant *const zero = new ir_constant(src->type, &z);
  109. return new ir_expression(ir_binop_nequal, desired_type, src, zero);
  110. }
  111. }
  112. assert(!"Should not get here.");
  113. return NULL;
  114. }
  115. /**
  116. * Dereference a specific component from a scalar, vector, or matrix
  117. */
  118. static ir_rvalue *
  119. dereference_component(ir_rvalue *src, unsigned component)
  120. {
  121. assert(component < src->type->components());
  122. if (src->type->is_scalar()) {
  123. return src;
  124. } else if (src->type->is_vector()) {
  125. return new ir_swizzle(src, component, 0, 0, 0, 1);
  126. } else {
  127. assert(src->type->is_matrix());
  128. /* Dereference a row of the matrix, then call this function again to get
  129. * a specific element from that row.
  130. */
  131. const int c = component / src->type->column_type()->vector_elements;
  132. const int r = component % src->type->column_type()->vector_elements;
  133. ir_constant *const col_index = new ir_constant(glsl_type::int_type, &c);
  134. ir_dereference *const col = new ir_dereference(src, col_index);
  135. col->type = src->type->column_type();
  136. return dereference_component(col, r);
  137. }
  138. assert(!"Should not get here.");
  139. return NULL;
  140. }
  141. ir_rvalue *
  142. ast_function_expression::hir(exec_list *instructions,
  143. struct _mesa_glsl_parse_state *state)
  144. {
  145. /* There are three sorts of function calls.
  146. *
  147. * 1. contstructors - The first subexpression is an ast_type_specifier.
  148. * 2. methods - Only the .length() method of array types.
  149. * 3. functions - Calls to regular old functions.
  150. *
  151. * Method calls are actually detected when the ast_field_selection
  152. * expression is handled.
  153. */
  154. if (is_constructor()) {
  155. const ast_type_specifier *type = (ast_type_specifier *) subexpressions[0];
  156. YYLTYPE loc = type->get_location();
  157. const glsl_type *const constructor_type =
  158. state->symbols->get_type(type->type_name);
  159. /* Constructors for samplers are illegal.
  160. */
  161. if (constructor_type->is_sampler()) {
  162. _mesa_glsl_error(& loc, state, "cannot construct sampler type `%s'",
  163. constructor_type->name);
  164. return ir_call::get_error_instruction();
  165. }
  166. /* There are two kinds of constructor call. Constructors for built-in
  167. * language types, such as mat4 and vec2, are free form. The only
  168. * requirement is that the parameters must provide enough values of the
  169. * correct scalar type. Constructors for arrays and structures must
  170. * have the exact number of parameters with matching types in the
  171. * correct order. These constructors follow essentially the same type
  172. * matching rules as functions.
  173. */
  174. if (constructor_type->is_numeric() || constructor_type->is_boolean()) {
  175. /* Constructing a numeric type has a couple steps. First all values
  176. * passed to the constructor are broken into individual parameters
  177. * and type converted to the base type of the thing being constructed.
  178. *
  179. * At that point we have some number of values that match the base
  180. * type of the thing being constructed. Now the constructor can be
  181. * treated like a function call. Each numeric type has a small set
  182. * of constructor functions. The set of new parameters will either
  183. * match one of those functions or the original constructor is
  184. * invalid.
  185. */
  186. const glsl_type *const base_type = constructor_type->get_base_type();
  187. /* Total number of components of the type being constructed.
  188. */
  189. const unsigned type_components = constructor_type->components();
  190. /* Number of components from parameters that have actually been
  191. * consumed. This is used to perform several kinds of error checking.
  192. */
  193. unsigned components_used = 0;
  194. unsigned matrix_parameters = 0;
  195. unsigned nonmatrix_parameters = 0;
  196. exec_list actual_parameters;
  197. simple_node *const first = subexpressions[1];
  198. assert(first != NULL);
  199. if (first != NULL) {
  200. simple_node *ptr = first;
  201. do {
  202. ir_rvalue *const result =
  203. ((ast_node *) ptr)->hir(instructions, state)->as_rvalue();
  204. ptr = ptr->next;
  205. /* From page 50 (page 56 of the PDF) of the GLSL 1.50 spec:
  206. *
  207. * "It is an error to provide extra arguments beyond this
  208. * last used argument."
  209. */
  210. if (components_used >= type_components) {
  211. _mesa_glsl_error(& loc, state, "too many parameters to `%s' "
  212. "constructor",
  213. constructor_type->name);
  214. return ir_call::get_error_instruction();
  215. }
  216. if (!result->type->is_numeric() && !result->type->is_boolean()) {
  217. _mesa_glsl_error(& loc, state, "cannot construct `%s' from a "
  218. "non-numeric data type",
  219. constructor_type->name);
  220. return ir_call::get_error_instruction();
  221. }
  222. /* Count the number of matrix and nonmatrix parameters. This
  223. * is used below to enforce some of the constructor rules.
  224. */
  225. if (result->type->is_matrix())
  226. matrix_parameters++;
  227. else
  228. nonmatrix_parameters++;
  229. /* Process each of the components of the parameter. Dereference
  230. * each component individually, perform any type conversions, and
  231. * add it to the parameter list for the constructor.
  232. */
  233. for (unsigned i = 0; i < result->type->components(); i++) {
  234. if (components_used >= type_components)
  235. break;
  236. ir_rvalue *const component =
  237. convert_component(dereference_component(result, i),
  238. base_type);
  239. /* All cases that could result in component->type being the
  240. * error type should have already been caught above.
  241. */
  242. assert(component->type == base_type);
  243. /* Don't actually generate constructor calls for scalars.
  244. * Instead, do the usual component selection and conversion,
  245. * and return the single component.
  246. */
  247. if (constructor_type->is_scalar())
  248. return component;
  249. actual_parameters.push_tail(component);
  250. components_used++;
  251. }
  252. } while (ptr != first);
  253. }
  254. /* From page 28 (page 34 of the PDF) of the GLSL 1.10 spec:
  255. *
  256. * "It is an error to construct matrices from other matrices. This
  257. * is reserved for future use."
  258. */
  259. if ((state->language_version <= 110) && (matrix_parameters > 0)
  260. && constructor_type->is_matrix()) {
  261. _mesa_glsl_error(& loc, state, "cannot construct `%s' from a "
  262. "matrix in GLSL 1.10",
  263. constructor_type->name);
  264. return ir_call::get_error_instruction();
  265. }
  266. /* From page 50 (page 56 of the PDF) of the GLSL 1.50 spec:
  267. *
  268. * "If a matrix argument is given to a matrix constructor, it is
  269. * an error to have any other arguments."
  270. */
  271. if ((matrix_parameters > 0)
  272. && ((matrix_parameters + nonmatrix_parameters) > 1)
  273. && constructor_type->is_matrix()) {
  274. _mesa_glsl_error(& loc, state, "for matrix `%s' constructor, "
  275. "matrix must be only parameter",
  276. constructor_type->name);
  277. return ir_call::get_error_instruction();
  278. }
  279. /* From page 28 (page 34 of the PDF) of the GLSL 1.10 spec:
  280. *
  281. * "In these cases, there must be enough components provided in the
  282. * arguments to provide an initializer for every component in the
  283. * constructed value."
  284. */
  285. if (components_used < type_components) {
  286. _mesa_glsl_error(& loc, state, "too few components to construct "
  287. "`%s'",
  288. constructor_type->name);
  289. return ir_call::get_error_instruction();
  290. }
  291. ir_function *f = state->symbols->get_function(constructor_type->name);
  292. if (f == NULL) {
  293. _mesa_glsl_error(& loc, state, "no constructor for type `%s'",
  294. constructor_type->name);
  295. return ir_call::get_error_instruction();
  296. }
  297. const ir_function_signature *sig =
  298. f->matching_signature(& actual_parameters);
  299. if (sig != NULL) {
  300. return new ir_call(sig, & actual_parameters);
  301. } else {
  302. /* FINISHME: Log a better error message here. G++ will show the
  303. * FINSIHME: types of the actual parameters and the set of
  304. * FINSIHME: candidate functions. A different error should also be
  305. * FINSIHME: logged when multiple functions match.
  306. */
  307. _mesa_glsl_error(& loc, state, "no matching constructor for `%s'",
  308. constructor_type->name);
  309. return ir_call::get_error_instruction();
  310. }
  311. }
  312. return ir_call::get_error_instruction();
  313. } else {
  314. const ast_expression *id = subexpressions[0];
  315. YYLTYPE loc = id->get_location();
  316. return match_function_by_name(instructions,
  317. id->primary_expression.identifier, & loc,
  318. subexpressions[1], state);
  319. }
  320. return ir_call::get_error_instruction();
  321. }