glsl2: Add and use new variable mode ir_var_temporary
[mesa.git] / src / glsl / ir_variable.cpp
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
29 #ifndef Elements
30 #define Elements(x) (sizeof(x)/sizeof(*(x)))
31 #endif
32
33 static void generate_ARB_draw_buffers_variables(exec_list *,
34 struct _mesa_glsl_parse_state *,
35 bool, _mesa_glsl_parser_targets);
36
37 static ir_variable *
38 add_variable(const char *name, enum ir_variable_mode mode, int slot,
39 const glsl_type *type, exec_list *instructions,
40 glsl_symbol_table *symtab)
41 {
42 ir_variable *var = new(symtab) ir_variable(type, name, mode);
43
44 switch (var->mode) {
45 case ir_var_auto:
46 var->read_only = true;
47 break;
48 case ir_var_in:
49 var->shader_in = true;
50 var->read_only = true;
51 break;
52 case ir_var_inout:
53 var->shader_in = true;
54 var->shader_out = true;
55 break;
56 case ir_var_out:
57 var->shader_out = true;
58 break;
59 case ir_var_uniform:
60 var->shader_in = true;
61 var->read_only = true;
62 break;
63 default:
64 assert(0);
65 break;
66 }
67
68 var->location = slot;
69
70 /* Once the variable is created an initialized, add it to the symbol table
71 * and add the declaration to the IR stream.
72 */
73 instructions->push_tail(var);
74
75 symtab->add_variable(var->name, var);
76 return var;
77 }
78
79
80 static void
81 add_builtin_variable(const builtin_variable *proto, exec_list *instructions,
82 glsl_symbol_table *symtab)
83 {
84 /* Create a new variable declaration from the description supplied by
85 * the caller.
86 */
87 const glsl_type *const type = symtab->get_type(proto->type);
88
89 assert(type != NULL);
90
91 add_variable(proto->name, proto->mode, proto->slot, type, instructions,
92 symtab);
93 }
94
95 static void
96 add_builtin_constant(exec_list *instructions,
97 struct _mesa_glsl_parse_state *state,
98 const char *name, int value)
99 {
100 ir_variable *const var = add_variable(name, ir_var_auto,
101 -1, glsl_type::int_type,
102 instructions, state->symbols);
103 var->constant_value = new(var) ir_constant(value);
104 }
105
106 static void
107 generate_110_uniforms(exec_list *instructions,
108 struct _mesa_glsl_parse_state *state)
109 {
110 for (unsigned i = 0
111 ; i < Elements(builtin_110_deprecated_uniforms)
112 ; i++) {
113 add_builtin_variable(& builtin_110_deprecated_uniforms[i],
114 instructions, state->symbols);
115 }
116
117 add_builtin_constant(instructions, state, "gl_MaxLights",
118 state->Const.MaxLights);
119 add_builtin_constant(instructions, state, "gl_MaxClipPlanes",
120 state->Const.MaxClipPlanes);
121 add_builtin_constant(instructions, state, "gl_MaxTextureUnits",
122 state->Const.MaxTextureUnits);
123 add_builtin_constant(instructions, state, "gl_MaxTextureCoords",
124 state->Const.MaxTextureCoords);
125 add_builtin_constant(instructions, state, "gl_MaxVertexAttribs",
126 state->Const.MaxVertexAttribs);
127 add_builtin_constant(instructions, state, "gl_MaxVertexUniformComponents",
128 state->Const.MaxVertexUniformComponents);
129 add_builtin_constant(instructions, state, "gl_MaxVaryingFloats",
130 state->Const.MaxVaryingFloats);
131 add_builtin_constant(instructions, state, "gl_MaxVertexTextureImageUnits",
132 state->Const.MaxVertexTextureImageUnits);
133 add_builtin_constant(instructions, state, "gl_MaxCombinedTextureImageUnits",
134 state->Const.MaxCombinedTextureImageUnits);
135 add_builtin_constant(instructions, state, "gl_MaxTextureImageUnits",
136 state->Const.MaxTextureImageUnits);
137 add_builtin_constant(instructions, state, "gl_MaxFragmentUniformComponents",
138 state->Const.MaxFragmentUniformComponents);
139
140 const glsl_type *const mat4_array_type =
141 glsl_type::get_array_instance(state->symbols, glsl_type::mat4_type,
142 state->Const.MaxTextureCoords);
143
144 add_variable("gl_TextureMatrix", ir_var_uniform, -1, mat4_array_type,
145 instructions, state->symbols);
146
147 /* FINISHME: Add support for gl_DepthRangeParameters */
148 /* FINISHME: Add support for gl_ClipPlane[] */
149 /* FINISHME: Add support for gl_PointParameters */
150
151 /* FINISHME: Add support for gl_MaterialParameters
152 * FINISHME: (glFrontMaterial, glBackMaterial)
153 */
154
155 /* FINISHME: The size of this array is implementation dependent based on the
156 * FINISHME: value of GL_MAX_TEXTURE_LIGHTS. GL_MAX_TEXTURE_LIGHTS must be
157 * FINISHME: at least 8, so hard-code 8 for now.
158 */
159 const glsl_type *const light_source_array_type =
160 glsl_type::get_array_instance(state->symbols,
161 state->symbols->get_type("gl_LightSourceParameters"), 8);
162
163 add_variable("gl_LightSource", ir_var_uniform, -1, light_source_array_type,
164 instructions, state->symbols);
165
166 /* FINISHME: Add support for gl_LightModel */
167 /* FINISHME: Add support for gl_FrontLightProduct[], gl_BackLightProduct[] */
168 /* FINISHME: Add support for gl_TextureEnvColor[] */
169 /* FINISHME: Add support for gl_ObjectPlane*[], gl_EyePlane*[] */
170 /* FINISHME: Add support for gl_Fog */
171 }
172
173 static void
174 generate_110_vs_variables(exec_list *instructions,
175 struct _mesa_glsl_parse_state *state)
176 {
177 for (unsigned i = 0; i < Elements(builtin_core_vs_variables); i++) {
178 add_builtin_variable(& builtin_core_vs_variables[i],
179 instructions, state->symbols);
180 }
181
182 for (unsigned i = 0
183 ; i < Elements(builtin_110_deprecated_vs_variables)
184 ; i++) {
185 add_builtin_variable(& builtin_110_deprecated_vs_variables[i],
186 instructions, state->symbols);
187 }
188 generate_110_uniforms(instructions, state);
189
190 /* From page 54 (page 60 of the PDF) of the GLSL 1.20 spec:
191 *
192 * "As with all arrays, indices used to subscript gl_TexCoord must
193 * either be an integral constant expressions, or this array must be
194 * re-declared by the shader with a size. The size can be at most
195 * gl_MaxTextureCoords. Using indexes close to 0 may aid the
196 * implementation in preserving varying resources."
197 */
198 const glsl_type *const vec4_array_type =
199 glsl_type::get_array_instance(state->symbols, glsl_type::vec4_type, 0);
200
201 add_variable("gl_TexCoord", ir_var_out, VERT_RESULT_TEX0, vec4_array_type,
202 instructions, state->symbols);
203
204 generate_ARB_draw_buffers_variables(instructions, state, false,
205 vertex_shader);
206 }
207
208
209 static void
210 generate_120_vs_variables(exec_list *instructions,
211 struct _mesa_glsl_parse_state *state)
212 {
213 /* GLSL version 1.20 did not add any built-in variables in the vertex
214 * shader.
215 */
216 generate_110_vs_variables(instructions, state);
217 }
218
219
220 static void
221 generate_130_vs_variables(exec_list *instructions,
222 struct _mesa_glsl_parse_state *state)
223 {
224 void *ctx = state->symbols;
225 generate_120_vs_variables(instructions, state);
226
227 for (unsigned i = 0; i < Elements(builtin_130_vs_variables); i++) {
228 add_builtin_variable(& builtin_130_vs_variables[i],
229 instructions, state->symbols);
230 }
231
232 /* FINISHME: The size of this array is implementation dependent based on
233 * FINISHME: the value of GL_MAX_CLIP_DISTANCES.
234 */
235 const glsl_type *const clip_distance_array_type =
236 glsl_type::get_array_instance(ctx, glsl_type::float_type, 8);
237
238 /* FINISHME: gl_ClipDistance needs a real location assigned. */
239 add_variable("gl_ClipDistance", ir_var_out, -1, clip_distance_array_type,
240 instructions, state->symbols);
241
242 }
243
244
245 static void
246 initialize_vs_variables(exec_list *instructions,
247 struct _mesa_glsl_parse_state *state)
248 {
249
250 switch (state->language_version) {
251 case 110:
252 generate_110_vs_variables(instructions, state);
253 break;
254 case 120:
255 generate_120_vs_variables(instructions, state);
256 break;
257 case 130:
258 generate_130_vs_variables(instructions, state);
259 break;
260 }
261 }
262
263 static void
264 generate_110_fs_variables(exec_list *instructions,
265 struct _mesa_glsl_parse_state *state)
266 {
267 for (unsigned i = 0; i < Elements(builtin_core_fs_variables); i++) {
268 add_builtin_variable(& builtin_core_fs_variables[i],
269 instructions, state->symbols);
270 }
271
272 for (unsigned i = 0
273 ; i < Elements(builtin_110_deprecated_fs_variables)
274 ; i++) {
275 add_builtin_variable(& builtin_110_deprecated_fs_variables[i],
276 instructions, state->symbols);
277 }
278 generate_110_uniforms(instructions, state);
279
280 /* From page 54 (page 60 of the PDF) of the GLSL 1.20 spec:
281 *
282 * "As with all arrays, indices used to subscript gl_TexCoord must
283 * either be an integral constant expressions, or this array must be
284 * re-declared by the shader with a size. The size can be at most
285 * gl_MaxTextureCoords. Using indexes close to 0 may aid the
286 * implementation in preserving varying resources."
287 */
288 const glsl_type *const vec4_array_type =
289 glsl_type::get_array_instance(state->symbols, glsl_type::vec4_type, 0);
290
291 add_variable("gl_TexCoord", ir_var_in, FRAG_ATTRIB_TEX0, vec4_array_type,
292 instructions, state->symbols);
293
294 generate_ARB_draw_buffers_variables(instructions, state, false,
295 fragment_shader);
296 }
297
298
299 static void
300 generate_ARB_draw_buffers_variables(exec_list *instructions,
301 struct _mesa_glsl_parse_state *state,
302 bool warn, _mesa_glsl_parser_targets target)
303 {
304 /* gl_MaxDrawBuffers is available in all shader stages.
305 */
306 ir_variable *const mdb =
307 add_variable("gl_MaxDrawBuffers", ir_var_auto, -1,
308 glsl_type::int_type, instructions, state->symbols);
309
310 if (warn)
311 mdb->warn_extension = "GL_ARB_draw_buffers";
312
313 mdb->constant_value = new(mdb)
314 ir_constant(int(state->Const.MaxDrawBuffers));
315
316
317 /* gl_FragData is only available in the fragment shader.
318 */
319 if (target == fragment_shader) {
320 const glsl_type *const vec4_array_type =
321 glsl_type::get_array_instance(state->symbols, glsl_type::vec4_type,
322 state->Const.MaxDrawBuffers);
323
324 ir_variable *const fd =
325 add_variable("gl_FragData", ir_var_out, FRAG_RESULT_DATA0,
326 vec4_array_type, instructions, state->symbols);
327
328 if (warn)
329 fd->warn_extension = "GL_ARB_draw_buffers";
330 }
331 }
332
333
334 static void
335 generate_120_fs_variables(exec_list *instructions,
336 struct _mesa_glsl_parse_state *state)
337 {
338 generate_110_fs_variables(instructions, state);
339
340 for (unsigned i = 0
341 ; i < Elements(builtin_120_fs_variables)
342 ; i++) {
343 add_builtin_variable(& builtin_120_fs_variables[i],
344 instructions, state->symbols);
345 }
346 }
347
348 static void
349 generate_130_fs_variables(exec_list *instructions,
350 struct _mesa_glsl_parse_state *state)
351 {
352 void *ctx = state->symbols;
353 generate_120_fs_variables(instructions, state);
354
355 /* FINISHME: The size of this array is implementation dependent based on
356 * FINISHME: the value of GL_MAX_CLIP_DISTANCES.
357 */
358 const glsl_type *const clip_distance_array_type =
359 glsl_type::get_array_instance(ctx, glsl_type::float_type, 8);
360
361 /* FINISHME: gl_ClipDistance needs a real location assigned. */
362 add_variable("gl_ClipDistance", ir_var_in, -1, clip_distance_array_type,
363 instructions, state->symbols);
364 }
365
366 static void
367 initialize_fs_variables(exec_list *instructions,
368 struct _mesa_glsl_parse_state *state)
369 {
370
371 switch (state->language_version) {
372 case 110:
373 generate_110_fs_variables(instructions, state);
374 break;
375 case 120:
376 generate_120_fs_variables(instructions, state);
377 break;
378 case 130:
379 generate_130_fs_variables(instructions, state);
380 break;
381 }
382 }
383
384 void
385 _mesa_glsl_initialize_variables(exec_list *instructions,
386 struct _mesa_glsl_parse_state *state)
387 {
388 switch (state->target) {
389 case vertex_shader:
390 initialize_vs_variables(instructions, state);
391 break;
392 case geometry_shader:
393 break;
394 case fragment_shader:
395 initialize_fs_variables(instructions, state);
396 break;
397 case ir_shader:
398 fprintf(stderr, "ir reader has no builtin variables");
399 exit(1);
400 break;
401 }
402 }