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
24#include "ir.h"
25#include "glsl_parser_extras.h"
26#include "glsl_symbol_table.h"
27#include "builtin_variables.h"
28
29static void generate_ARB_draw_buffers_variables(exec_list *,
30						struct _mesa_glsl_parse_state *,
31						bool, _mesa_glsl_parser_targets);
32
33static ir_variable *
34add_variable(const char *name, enum ir_variable_mode mode, int slot,
35	     const glsl_type *type, exec_list *instructions,
36		     glsl_symbol_table *symtab)
37{
38   ir_variable *var = new(symtab) ir_variable(type, name, mode);
39
40   switch (var->mode) {
41   case ir_var_auto:
42   case ir_var_in:
43   case ir_var_uniform:
44      var->read_only = true;
45      break;
46   case ir_var_inout:
47   case ir_var_out:
48      break;
49   default:
50      assert(0);
51      break;
52   }
53
54   var->location = slot;
55   var->explicit_location = (slot >= 0);
56
57   /* Once the variable is created an initialized, add it to the symbol table
58    * and add the declaration to the IR stream.
59    */
60   instructions->push_tail(var);
61
62   symtab->add_variable(var);
63   return var;
64}
65
66static ir_variable *
67add_uniform(exec_list *instructions,
68	    struct _mesa_glsl_parse_state *state,
69	    const char *name, const glsl_type *type)
70{
71   return add_variable(name, ir_var_uniform, -1, type, instructions,
72		       state->symbols);
73}
74
75static void
76add_builtin_variable(const builtin_variable *proto, exec_list *instructions,
77		     glsl_symbol_table *symtab)
78{
79   /* Create a new variable declaration from the description supplied by
80    * the caller.
81    */
82   const glsl_type *const type = symtab->get_type(proto->type);
83
84   assert(type != NULL);
85
86   add_variable(proto->name, proto->mode, proto->slot, type, instructions,
87		symtab);
88}
89
90static void
91add_builtin_constant(exec_list *instructions,
92		     struct _mesa_glsl_parse_state *state,
93		     const char *name, int value)
94{
95   ir_variable *const var = add_variable(name, ir_var_auto,
96					 -1, glsl_type::int_type,
97					 instructions, state->symbols);
98   var->constant_value = new(var) ir_constant(value);
99}
100
101/* Several constants in GLSL ES have different names than normal desktop GLSL.
102 * Therefore, this function should only be called on the ES path.
103 */
104static void
105generate_100ES_uniforms(exec_list *instructions,
106		     struct _mesa_glsl_parse_state *state)
107{
108   add_builtin_constant(instructions, state, "gl_MaxVertexAttribs",
109			state->Const.MaxVertexAttribs);
110   add_builtin_constant(instructions, state, "gl_MaxVertexUniformVectors",
111			state->Const.MaxVertexUniformComponents);
112   add_builtin_constant(instructions, state, "gl_MaxVaryingVectors",
113			state->Const.MaxVaryingFloats / 4);
114   add_builtin_constant(instructions, state, "gl_MaxVertexTextureImageUnits",
115			state->Const.MaxVertexTextureImageUnits);
116   add_builtin_constant(instructions, state, "gl_MaxCombinedTextureImageUnits",
117			state->Const.MaxCombinedTextureImageUnits);
118   add_builtin_constant(instructions, state, "gl_MaxTextureImageUnits",
119			state->Const.MaxTextureImageUnits);
120   add_builtin_constant(instructions, state, "gl_MaxFragmentUniformVectors",
121			state->Const.MaxFragmentUniformComponents);
122
123   add_uniform(instructions, state, "gl_DepthRange",
124	       state->symbols->get_type("gl_DepthRangeParameters"));
125}
126
127static void
128generate_110_uniforms(exec_list *instructions,
129		      struct _mesa_glsl_parse_state *state)
130{
131   for (unsigned i = 0
132	   ; i < Elements(builtin_110_deprecated_uniforms)
133	   ; i++) {
134      add_builtin_variable(& builtin_110_deprecated_uniforms[i],
135			   instructions, state->symbols);
136   }
137
138   add_builtin_constant(instructions, state, "gl_MaxLights",
139			state->Const.MaxLights);
140   add_builtin_constant(instructions, state, "gl_MaxClipPlanes",
141			state->Const.MaxClipPlanes);
142   add_builtin_constant(instructions, state, "gl_MaxTextureUnits",
143			state->Const.MaxTextureUnits);
144   add_builtin_constant(instructions, state, "gl_MaxTextureCoords",
145			state->Const.MaxTextureCoords);
146   add_builtin_constant(instructions, state, "gl_MaxVertexAttribs",
147			state->Const.MaxVertexAttribs);
148   add_builtin_constant(instructions, state, "gl_MaxVertexUniformComponents",
149			state->Const.MaxVertexUniformComponents);
150   add_builtin_constant(instructions, state, "gl_MaxVaryingFloats",
151			state->Const.MaxVaryingFloats);
152   add_builtin_constant(instructions, state, "gl_MaxVertexTextureImageUnits",
153			state->Const.MaxVertexTextureImageUnits);
154   add_builtin_constant(instructions, state, "gl_MaxCombinedTextureImageUnits",
155			state->Const.MaxCombinedTextureImageUnits);
156   add_builtin_constant(instructions, state, "gl_MaxTextureImageUnits",
157			state->Const.MaxTextureImageUnits);
158   add_builtin_constant(instructions, state, "gl_MaxFragmentUniformComponents",
159			state->Const.MaxFragmentUniformComponents);
160
161   const glsl_type *const mat4_array_type =
162      glsl_type::get_array_instance(glsl_type::mat4_type,
163				    state->Const.MaxTextureCoords);
164
165   add_uniform(instructions, state, "gl_TextureMatrix", mat4_array_type);
166   add_uniform(instructions, state, "gl_TextureMatrixInverse", mat4_array_type);
167   add_uniform(instructions, state, "gl_TextureMatrixTranspose", mat4_array_type);
168   add_uniform(instructions, state, "gl_TextureMatrixInverseTranspose", mat4_array_type);
169
170   add_uniform(instructions, state, "gl_DepthRange",
171		state->symbols->get_type("gl_DepthRangeParameters"));
172
173   add_uniform(instructions, state, "gl_ClipPlane",
174	       glsl_type::get_array_instance(glsl_type::vec4_type,
175					     state->Const.MaxClipPlanes));
176   add_uniform(instructions, state, "gl_Point",
177	       state->symbols->get_type("gl_PointParameters"));
178
179   const glsl_type *const material_parameters_type =
180      state->symbols->get_type("gl_MaterialParameters");
181   add_uniform(instructions, state, "gl_FrontMaterial", material_parameters_type);
182   add_uniform(instructions, state, "gl_BackMaterial", material_parameters_type);
183
184   const glsl_type *const light_source_array_type =
185      glsl_type::get_array_instance(state->symbols->get_type("gl_LightSourceParameters"), state->Const.MaxLights);
186
187   add_uniform(instructions, state, "gl_LightSource", light_source_array_type);
188
189   const glsl_type *const light_model_products_type =
190      state->symbols->get_type("gl_LightModelProducts");
191   add_uniform(instructions, state, "gl_FrontLightModelProduct",
192	       light_model_products_type);
193   add_uniform(instructions, state, "gl_BackLightModelProduct",
194	       light_model_products_type);
195
196   const glsl_type *const light_products_type =
197      glsl_type::get_array_instance(state->symbols->get_type("gl_LightProducts"),
198				    state->Const.MaxLights);
199   add_uniform(instructions, state, "gl_FrontLightProduct", light_products_type);
200   add_uniform(instructions, state, "gl_BackLightProduct", light_products_type);
201
202   add_uniform(instructions, state, "gl_TextureEnvColor",
203	       glsl_type::get_array_instance(glsl_type::vec4_type,
204					     state->Const.MaxTextureUnits));
205
206   const glsl_type *const texcoords_vec4 =
207      glsl_type::get_array_instance(glsl_type::vec4_type,
208				    state->Const.MaxTextureCoords);
209   add_uniform(instructions, state, "gl_EyePlaneS", texcoords_vec4);
210   add_uniform(instructions, state, "gl_EyePlaneT", texcoords_vec4);
211   add_uniform(instructions, state, "gl_EyePlaneR", texcoords_vec4);
212   add_uniform(instructions, state, "gl_EyePlaneQ", texcoords_vec4);
213   add_uniform(instructions, state, "gl_ObjectPlaneS", texcoords_vec4);
214   add_uniform(instructions, state, "gl_ObjectPlaneT", texcoords_vec4);
215   add_uniform(instructions, state, "gl_ObjectPlaneR", texcoords_vec4);
216   add_uniform(instructions, state, "gl_ObjectPlaneQ", texcoords_vec4);
217
218   add_uniform(instructions, state, "gl_Fog",
219	       state->symbols->get_type("gl_FogParameters"));
220}
221
222/* This function should only be called for ES, not desktop GL. */
223static void
224generate_100ES_vs_variables(exec_list *instructions,
225			  struct _mesa_glsl_parse_state *state)
226{
227   for (unsigned i = 0; i < Elements(builtin_core_vs_variables); i++) {
228      add_builtin_variable(& builtin_core_vs_variables[i],
229			   instructions, state->symbols);
230   }
231
232   generate_100ES_uniforms(instructions, state);
233
234   generate_ARB_draw_buffers_variables(instructions, state, false,
235				       vertex_shader);
236}
237
238
239static void
240generate_110_vs_variables(exec_list *instructions,
241			  struct _mesa_glsl_parse_state *state)
242{
243   for (unsigned i = 0; i < Elements(builtin_core_vs_variables); i++) {
244      add_builtin_variable(& builtin_core_vs_variables[i],
245			   instructions, state->symbols);
246   }
247
248   for (unsigned i = 0
249	   ; i < Elements(builtin_110_deprecated_vs_variables)
250	   ; i++) {
251      add_builtin_variable(& builtin_110_deprecated_vs_variables[i],
252			   instructions, state->symbols);
253   }
254   generate_110_uniforms(instructions, state);
255
256   /* From page 54 (page 60 of the PDF) of the GLSL 1.20 spec:
257    *
258    *     "As with all arrays, indices used to subscript gl_TexCoord must
259    *     either be an integral constant expressions, or this array must be
260    *     re-declared by the shader with a size. The size can be at most
261    *     gl_MaxTextureCoords. Using indexes close to 0 may aid the
262    *     implementation in preserving varying resources."
263    */
264   const glsl_type *const vec4_array_type =
265      glsl_type::get_array_instance(glsl_type::vec4_type, 0);
266
267   add_variable("gl_TexCoord", ir_var_out, VERT_RESULT_TEX0, vec4_array_type,
268		instructions, state->symbols);
269
270   generate_ARB_draw_buffers_variables(instructions, state, false,
271				       vertex_shader);
272}
273
274
275static void
276generate_120_vs_variables(exec_list *instructions,
277			  struct _mesa_glsl_parse_state *state)
278{
279   /* GLSL version 1.20 did not add any built-in variables in the vertex
280    * shader.
281    */
282   generate_110_vs_variables(instructions, state);
283}
284
285
286static void
287generate_130_vs_variables(exec_list *instructions,
288			  struct _mesa_glsl_parse_state *state)
289{
290   generate_120_vs_variables(instructions, state);
291
292   for (unsigned i = 0; i < Elements(builtin_130_vs_variables); i++) {
293      add_builtin_variable(& builtin_130_vs_variables[i],
294			   instructions, state->symbols);
295   }
296
297   const glsl_type *const clip_distance_array_type =
298      glsl_type::get_array_instance(glsl_type::float_type,
299				    state->Const.MaxClipPlanes);
300
301   /* FINISHME: gl_ClipDistance needs a real location assigned. */
302   add_variable("gl_ClipDistance", ir_var_out, -1, clip_distance_array_type,
303		instructions, state->symbols);
304
305}
306
307
308static void
309initialize_vs_variables(exec_list *instructions,
310			struct _mesa_glsl_parse_state *state)
311{
312
313   switch (state->language_version) {
314   case 100:
315      generate_100ES_vs_variables(instructions, state);
316      break;
317   case 110:
318      generate_110_vs_variables(instructions, state);
319      break;
320   case 120:
321      generate_120_vs_variables(instructions, state);
322      break;
323   case 130:
324      generate_130_vs_variables(instructions, state);
325      break;
326   }
327}
328
329/* This function should only be called for ES, not desktop GL. */
330static void
331generate_100ES_fs_variables(exec_list *instructions,
332			  struct _mesa_glsl_parse_state *state)
333{
334   for (unsigned i = 0; i < Elements(builtin_core_fs_variables); i++) {
335      add_builtin_variable(& builtin_core_fs_variables[i],
336			   instructions, state->symbols);
337   }
338
339   for (unsigned i = 0; i < Elements(builtin_100ES_fs_variables); i++) {
340      add_builtin_variable(& builtin_100ES_fs_variables[i],
341			   instructions, state->symbols);
342   }
343
344   generate_100ES_uniforms(instructions, state);
345
346   generate_ARB_draw_buffers_variables(instructions, state, false,
347				       fragment_shader);
348}
349
350static void
351generate_110_fs_variables(exec_list *instructions,
352			  struct _mesa_glsl_parse_state *state)
353{
354   for (unsigned i = 0; i < Elements(builtin_core_fs_variables); i++) {
355      add_builtin_variable(& builtin_core_fs_variables[i],
356			   instructions, state->symbols);
357   }
358
359   for (unsigned i = 0; i < Elements(builtin_110_fs_variables); i++) {
360      add_builtin_variable(& builtin_110_fs_variables[i],
361			   instructions, state->symbols);
362   }
363
364   for (unsigned i = 0
365	   ; i < Elements(builtin_110_deprecated_fs_variables)
366	   ; i++) {
367      add_builtin_variable(& builtin_110_deprecated_fs_variables[i],
368			   instructions, state->symbols);
369   }
370   generate_110_uniforms(instructions, state);
371
372   /* From page 54 (page 60 of the PDF) of the GLSL 1.20 spec:
373    *
374    *     "As with all arrays, indices used to subscript gl_TexCoord must
375    *     either be an integral constant expressions, or this array must be
376    *     re-declared by the shader with a size. The size can be at most
377    *     gl_MaxTextureCoords. Using indexes close to 0 may aid the
378    *     implementation in preserving varying resources."
379    */
380   const glsl_type *const vec4_array_type =
381      glsl_type::get_array_instance(glsl_type::vec4_type, 0);
382
383   add_variable("gl_TexCoord", ir_var_in, FRAG_ATTRIB_TEX0, vec4_array_type,
384		instructions, state->symbols);
385
386   generate_ARB_draw_buffers_variables(instructions, state, false,
387				       fragment_shader);
388}
389
390
391static void
392generate_ARB_draw_buffers_variables(exec_list *instructions,
393				    struct _mesa_glsl_parse_state *state,
394				    bool warn, _mesa_glsl_parser_targets target)
395{
396   /* gl_MaxDrawBuffers is available in all shader stages.
397    */
398   ir_variable *const mdb =
399      add_variable("gl_MaxDrawBuffers", ir_var_auto, -1,
400		   glsl_type::int_type, instructions, state->symbols);
401
402   if (warn)
403      mdb->warn_extension = "GL_ARB_draw_buffers";
404
405   mdb->constant_value = new(mdb)
406      ir_constant(int(state->Const.MaxDrawBuffers));
407
408
409   /* gl_FragData is only available in the fragment shader.
410    */
411   if (target == fragment_shader) {
412      const glsl_type *const vec4_array_type =
413	 glsl_type::get_array_instance(glsl_type::vec4_type,
414				       state->Const.MaxDrawBuffers);
415
416      ir_variable *const fd =
417	 add_variable("gl_FragData", ir_var_out, FRAG_RESULT_DATA0,
418		      vec4_array_type, instructions, state->symbols);
419
420      if (warn)
421	 fd->warn_extension = "GL_ARB_draw_buffers";
422   }
423}
424
425static void
426generate_ARB_shader_stencil_export_variables(exec_list *instructions,
427					     struct _mesa_glsl_parse_state *state,
428					     bool warn)
429{
430   /* gl_FragStencilRefARB is only available in the fragment shader.
431    */
432   ir_variable *const fd =
433      add_variable("gl_FragStencilRefARB", ir_var_out, FRAG_RESULT_STENCIL,
434		   glsl_type::int_type, instructions, state->symbols);
435
436   if (warn)
437      fd->warn_extension = "GL_ARB_shader_stencil_export";
438}
439
440static void
441generate_120_fs_variables(exec_list *instructions,
442			  struct _mesa_glsl_parse_state *state)
443{
444   generate_110_fs_variables(instructions, state);
445
446   for (unsigned i = 0
447	   ; i < Elements(builtin_120_fs_variables)
448	   ; i++) {
449      add_builtin_variable(& builtin_120_fs_variables[i],
450			   instructions, state->symbols);
451   }
452}
453
454static void
455generate_130_fs_variables(exec_list *instructions,
456			  struct _mesa_glsl_parse_state *state)
457{
458   generate_120_fs_variables(instructions, state);
459
460   const glsl_type *const clip_distance_array_type =
461      glsl_type::get_array_instance(glsl_type::float_type,
462				    state->Const.MaxClipPlanes);
463
464   /* FINISHME: gl_ClipDistance needs a real location assigned. */
465   add_variable("gl_ClipDistance", ir_var_in, -1, clip_distance_array_type,
466		instructions, state->symbols);
467}
468
469static void
470initialize_fs_variables(exec_list *instructions,
471			struct _mesa_glsl_parse_state *state)
472{
473
474   switch (state->language_version) {
475   case 100:
476      generate_100ES_fs_variables(instructions, state);
477      break;
478   case 110:
479      generate_110_fs_variables(instructions, state);
480      break;
481   case 120:
482      generate_120_fs_variables(instructions, state);
483      break;
484   case 130:
485      generate_130_fs_variables(instructions, state);
486      break;
487   }
488
489   if (state->ARB_shader_stencil_export_enable)
490      generate_ARB_shader_stencil_export_variables(instructions, state,
491						   state->ARB_shader_stencil_export_warn);
492}
493
494void
495_mesa_glsl_initialize_variables(exec_list *instructions,
496				struct _mesa_glsl_parse_state *state)
497{
498   switch (state->target) {
499   case vertex_shader:
500      initialize_vs_variables(instructions, state);
501      break;
502   case geometry_shader:
503      break;
504   case fragment_shader:
505      initialize_fs_variables(instructions, state);
506      break;
507   }
508}
509