blob: 314db0bb0f772a5beb8e492cc580a1f44b9a3503 [file] [log] [blame]
Ian Romanick832dfa52010-06-17 15:04:20 -07001/*
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/**
25 * \file linker.cpp
26 * GLSL linker implementation
27 *
28 * Given a set of shaders that are to be linked to generate a final program,
29 * there are three distinct stages.
30 *
31 * In the first stage shaders are partitioned into groups based on the shader
32 * type. All shaders of a particular type (e.g., vertex shaders) are linked
33 * together.
34 *
35 * - Undefined references in each shader are resolve to definitions in
36 * another shader.
37 * - Types and qualifiers of uniforms, outputs, and global variables defined
38 * in multiple shaders with the same name are verified to be the same.
39 * - Initializers for uniforms and global variables defined
40 * in multiple shaders with the same name are verified to be the same.
41 *
42 * The result, in the terminology of the GLSL spec, is a set of shader
43 * executables for each processing unit.
44 *
45 * After the first stage is complete, a series of semantic checks are performed
46 * on each of the shader executables.
47 *
48 * - Each shader executable must define a \c main function.
49 * - Each vertex shader executable must write to \c gl_Position.
50 * - Each fragment shader executable must write to either \c gl_FragData or
51 * \c gl_FragColor.
52 *
53 * In the final stage individual shader executables are linked to create a
54 * complete exectuable.
55 *
56 * - Types of uniforms defined in multiple shader stages with the same name
57 * are verified to be the same.
58 * - Initializers for uniforms defined in multiple shader stages with the
59 * same name are verified to be the same.
60 * - Types and qualifiers of outputs defined in one stage are verified to
61 * be the same as the types and qualifiers of inputs defined with the same
62 * name in a later stage.
63 *
64 * \author Ian Romanick <ian.d.romanick@intel.com>
65 */
66#include <cstdlib>
67#include <cstdio>
68
Ian Romanick0ad22cd2010-06-21 17:18:31 -070069#include "main/mtypes.h"
Ian Romanick832dfa52010-06-17 15:04:20 -070070#include "glsl_symbol_table.h"
71#include "glsl_parser_extras.h"
72#include "ir.h"
Ian Romanick019a59b2010-06-21 16:10:42 -070073#include "ir_optimization.h"
Ian Romanick832dfa52010-06-17 15:04:20 -070074#include "program.h"
Ian Romanick019a59b2010-06-21 16:10:42 -070075#include "hash_table.h"
Ian Romanick832dfa52010-06-17 15:04:20 -070076
77/**
78 * Visitor that determines whether or not a variable is ever written.
79 */
80class find_assignment_visitor : public ir_hierarchical_visitor {
81public:
82 find_assignment_visitor(const char *name)
83 : name(name), found(false)
84 {
85 /* empty */
86 }
87
88 virtual ir_visitor_status visit_enter(ir_assignment *ir)
89 {
90 ir_variable *const var = ir->lhs->variable_referenced();
91
92 if (strcmp(name, var->name) == 0) {
93 found = true;
94 return visit_stop;
95 }
96
97 return visit_continue_with_parent;
98 }
99
100 bool variable_found()
101 {
102 return found;
103 }
104
105private:
106 const char *name; /**< Find writes to a variable with this name. */
107 bool found; /**< Was a write to the variable found? */
108};
109
Ian Romanickc93b8f12010-06-17 15:20:22 -0700110
Ian Romanick0ad22cd2010-06-21 17:18:31 -0700111void
112invalidate_variable_locations(glsl_shader *sh, enum ir_variable_mode mode,
113 int generic_base)
114{
115 foreach_list(node, &sh->ir) {
116 ir_variable *const var = ((ir_instruction *) node)->as_variable();
117
118 if ((var == NULL) || (var->mode != (unsigned) mode))
119 continue;
120
121 /* Only assign locations for generic attributes / varyings / etc.
122 */
123 if (var->location >= generic_base)
124 var->location = -1;
125 }
126}
127
128
Ian Romanickc93b8f12010-06-17 15:20:22 -0700129/**
130 * Verify that a vertex shader executable meets all semantic requirements
131 *
132 * \param shader Vertex shader executable to be verified
133 */
Ian Romanick832dfa52010-06-17 15:04:20 -0700134bool
135validate_vertex_shader_executable(struct glsl_shader *shader)
136{
137 if (shader == NULL)
138 return true;
139
140 if (!shader->symbols->get_function("main")) {
141 printf("error: vertex shader lacks `main'\n");
142 return false;
143 }
144
145 find_assignment_visitor find("gl_Position");
146 find.run(&shader->ir);
147 if (!find.variable_found()) {
148 printf("error: vertex shader does not write to `gl_Position'\n");
149 return false;
150 }
151
152 return true;
153}
154
155
Ian Romanickc93b8f12010-06-17 15:20:22 -0700156/**
157 * Verify that a fragment shader executable meets all semantic requirements
158 *
159 * \param shader Fragment shader executable to be verified
160 */
Ian Romanick832dfa52010-06-17 15:04:20 -0700161bool
162validate_fragment_shader_executable(struct glsl_shader *shader)
163{
164 if (shader == NULL)
165 return true;
166
167 if (!shader->symbols->get_function("main")) {
168 printf("error: fragment shader lacks `main'\n");
169 return false;
170 }
171
172 find_assignment_visitor frag_color("gl_FragColor");
173 find_assignment_visitor frag_data("gl_FragData");
174
175 frag_color.run(&shader->ir);
176 frag_data.run(&shader->ir);
177
178 if (!frag_color.variable_found() && !frag_data.variable_found()) {
179 printf("error: fragment shader does not write to `gl_FragColor' or "
180 "`gl_FragData'\n");
181 return false;
182 }
183
184 if (frag_color.variable_found() && frag_data.variable_found()) {
185 printf("error: fragment shader write to both `gl_FragColor' and "
186 "`gl_FragData'\n");
187 return false;
188 }
189
190 return true;
191}
192
193
Ian Romanickcc22c5a2010-06-18 17:13:42 -0700194/**
195 * Perform validation of uniforms used across multiple shader stages
196 */
197bool
198cross_validate_uniforms(struct glsl_shader **shaders, unsigned num_shaders)
199{
200 /* Examine all of the uniforms in all of the shaders and cross validate
201 * them.
202 */
203 glsl_symbol_table uniforms;
204 for (unsigned i = 0; i < num_shaders; i++) {
205 foreach_list(node, &shaders[i]->ir) {
206 ir_variable *const var = ((ir_instruction *) node)->as_variable();
207
208 if ((var == NULL) || (var->mode != ir_var_uniform))
209 continue;
210
211 /* If a uniform with this name has already been seen, verify that the
212 * new instance has the same type. In addition, if the uniforms have
213 * initializers, the values of the initializers must be the same.
214 */
215 ir_variable *const existing = uniforms.get_variable(var->name);
216 if (existing != NULL) {
217 if (var->type != existing->type) {
218 printf("error: uniform `%s' declared as type `%s' and "
219 "type `%s'\n",
220 var->name, var->type->name, existing->type->name);
221 return false;
222 }
223
224 if (var->constant_value != NULL) {
225 if (existing->constant_value != NULL) {
226 if (!var->constant_value->has_value(existing->constant_value)) {
227 printf("error: initializers for uniform `%s' have "
228 "differing values\n",
229 var->name);
230 return false;
231 }
232 } else
233 /* If the first-seen instance of a particular uniform did not
234 * have an initializer but a later instance does, copy the
235 * initializer to the version stored in the symbol table.
236 */
237 existing->constant_value = var->constant_value->clone();
238 }
239 } else
240 uniforms.add_variable(var->name, var);
241 }
242 }
243
244 return true;
245}
246
247
Ian Romanick37101922010-06-18 19:02:10 -0700248/**
249 * Validate that outputs from one stage match inputs of another
250 */
251bool
252cross_validate_outputs_to_inputs(glsl_shader *producer, glsl_shader *consumer)
253{
254 glsl_symbol_table parameters;
255 /* FINISHME: Figure these out dynamically. */
256 const char *const producer_stage = "vertex";
257 const char *const consumer_stage = "fragment";
258
259 /* Find all shader outputs in the "producer" stage.
260 */
261 foreach_list(node, &producer->ir) {
262 ir_variable *const var = ((ir_instruction *) node)->as_variable();
263
264 /* FINISHME: For geometry shaders, this should also look for inout
265 * FINISHME: variables.
266 */
267 if ((var == NULL) || (var->mode != ir_var_out))
268 continue;
269
270 parameters.add_variable(var->name, var);
271 }
272
273
274 /* Find all shader inputs in the "consumer" stage. Any variables that have
275 * matching outputs already in the symbol table must have the same type and
276 * qualifiers.
277 */
278 foreach_list(node, &consumer->ir) {
279 ir_variable *const input = ((ir_instruction *) node)->as_variable();
280
281 /* FINISHME: For geometry shaders, this should also look for inout
282 * FINISHME: variables.
283 */
284 if ((input == NULL) || (input->mode != ir_var_in))
285 continue;
286
287 ir_variable *const output = parameters.get_variable(input->name);
288 if (output != NULL) {
289 /* Check that the types match between stages.
290 */
291 if (input->type != output->type) {
292 printf("error: %s shader output `%s' delcared as type `%s', but "
293 "%s shader input declared as type `%s'\n",
294 producer_stage, output->name, output->type->name,
295 consumer_stage, input->type->name);
296 return false;
297 }
298
299 /* Check that all of the qualifiers match between stages.
300 */
301 if (input->centroid != output->centroid) {
302 printf("error: %s shader output `%s' %s centroid qualifier, but "
303 "%s shader input %s centroid qualifier\n",
304 producer_stage,
305 output->name,
306 (output->centroid) ? "has" : "lacks",
307 consumer_stage,
308 (input->centroid) ? "has" : "lacks");
309 return false;
310 }
311
312 if (input->invariant != output->invariant) {
313 printf("error: %s shader output `%s' %s invariant qualifier, but "
314 "%s shader input %s invariant qualifier\n",
315 producer_stage,
316 output->name,
317 (output->invariant) ? "has" : "lacks",
318 consumer_stage,
319 (input->invariant) ? "has" : "lacks");
320 return false;
321 }
322
323 if (input->interpolation != output->interpolation) {
324 printf("error: %s shader output `%s' specifies %s interpolation "
325 "qualifier, "
326 "but %s shader input specifies %s interpolation "
327 "qualifier\n",
328 producer_stage,
329 output->name,
330 output->interpolation_string(),
331 consumer_stage,
332 input->interpolation_string());
333 return false;
334 }
335 }
336 }
337
338 return true;
339}
340
341
Ian Romanick019a59b2010-06-21 16:10:42 -0700342struct uniform_node {
343 exec_node link;
344 struct gl_uniform *u;
345 unsigned slots;
346};
347
Ian Romanickabee16e2010-06-21 16:16:05 -0700348void
349assign_uniform_locations(struct glsl_program *prog)
Ian Romanick019a59b2010-06-21 16:10:42 -0700350{
351 /* */
352 exec_list uniforms;
353 unsigned total_uniforms = 0;
354 hash_table *ht = hash_table_ctor(32, hash_table_string_hash,
355 hash_table_string_compare);
356
Ian Romanickabee16e2010-06-21 16:16:05 -0700357 for (unsigned i = 0; i < prog->_NumLinkedShaders; i++) {
Ian Romanick019a59b2010-06-21 16:10:42 -0700358 unsigned next_position = 0;
359
Ian Romanickabee16e2010-06-21 16:16:05 -0700360 foreach_list(node, &prog->_LinkedShaders[i]->ir) {
Ian Romanick019a59b2010-06-21 16:10:42 -0700361 ir_variable *const var = ((ir_instruction *) node)->as_variable();
362
363 if ((var == NULL) || (var->mode != ir_var_uniform))
364 continue;
365
366 const unsigned vec4_slots = (var->component_slots() + 3) / 4;
367 assert(vec4_slots != 0);
368
369 uniform_node *n = (uniform_node *) hash_table_find(ht, var->name);
370 if (n == NULL) {
371 n = (uniform_node *) calloc(1, sizeof(struct uniform_node));
372 n->u = (gl_uniform *) calloc(vec4_slots, sizeof(struct gl_uniform));
373 n->slots = vec4_slots;
374
375 n->u[0].Name = strdup(var->name);
376 for (unsigned j = 1; j < vec4_slots; j++)
377 n->u[j].Name = n->u[0].Name;
378
379 hash_table_insert(ht, n, n->u[0].Name);
380 uniforms.push_tail(& n->link);
381 total_uniforms += vec4_slots;
382 }
383
384 if (var->constant_value != NULL)
385 for (unsigned j = 0; j < vec4_slots; j++)
386 n->u[j].Initialized = true;
387
388 var->location = next_position;
389
390 for (unsigned j = 0; j < vec4_slots; j++) {
Ian Romanickabee16e2010-06-21 16:16:05 -0700391 switch (prog->_LinkedShaders[i]->Type) {
Ian Romanick019a59b2010-06-21 16:10:42 -0700392 case GL_VERTEX_SHADER:
393 n->u[j].VertPos = next_position;
394 break;
395 case GL_FRAGMENT_SHADER:
396 n->u[j].FragPos = next_position;
397 break;
398 case GL_GEOMETRY_SHADER:
399 /* FINISHME: Support geometry shaders. */
Ian Romanickabee16e2010-06-21 16:16:05 -0700400 assert(prog->_LinkedShaders[i]->Type != GL_GEOMETRY_SHADER);
Ian Romanick019a59b2010-06-21 16:10:42 -0700401 break;
402 }
403
404 next_position++;
405 }
406 }
407 }
408
409 gl_uniform_list *ul = (gl_uniform_list *)
410 calloc(1, sizeof(gl_uniform_list));
411
412 ul->Size = total_uniforms;
413 ul->NumUniforms = total_uniforms;
414 ul->Uniforms = (gl_uniform *) calloc(total_uniforms, sizeof(gl_uniform));
415
416 unsigned idx = 0;
417 uniform_node *next;
418 for (uniform_node *node = (uniform_node *) uniforms.head
419 ; node->link.next != NULL
420 ; node = next) {
421 next = (uniform_node *) node->link.next;
422
423 node->link.remove();
424 memcpy(&ul->Uniforms[idx], node->u, sizeof(gl_uniform) * node->slots);
425 idx += node->slots;
426
427 free(node->u);
428 free(node);
429 }
430
431 hash_table_dtor(ht);
432
Ian Romanickabee16e2010-06-21 16:16:05 -0700433 prog->Uniforms = ul;
Ian Romanick019a59b2010-06-21 16:10:42 -0700434}
435
436
Ian Romanick832dfa52010-06-17 15:04:20 -0700437void
Ian Romanick0ad22cd2010-06-21 17:18:31 -0700438assign_attribute_locations(glsl_shader *sh,
439 struct gl_program_parameter_list *attrib)
440{
441 unsigned used_locations = 0;
442
443 assert(sh->Type == GL_VERTEX_SHADER);
444
445 /* Operate in a total of three passes.
446 *
447 * 1. Invalidate the location assignments for all vertex shader inputs.
448 *
449 * 2. Assign locations for inputs that have user-defined (via
450 * glBindVertexAttribLocation) locatoins.
451 *
452 * 3. Assign locations to any inputs without assigned locations.
453 */
454
455 invalidate_variable_locations(sh, ir_var_in, VERT_ATTRIB_GENERIC0);
456
457 if (attrib != NULL) {
458 for (unsigned i = 0; i < attrib->NumParameters; i++) {
459 ir_variable *const var =
460 sh->symbols->get_variable(attrib->Parameters[i].Name);
461
462 if (var == NULL)
463 continue;
464
465 const int attr = attrib->Parameters[i].StateIndexes[0];
466
467 var->location = VERT_ATTRIB_GENERIC0 + attr;
468 used_locations |= (1 << attr);
469 }
470 }
471
472 foreach_list(node, &sh->ir) {
473 ir_variable *const var = ((ir_instruction *) node)->as_variable();
474
475 if ((var == NULL) || (var->mode != ir_var_in))
476 continue;
477
478 /* The location was explicitly assigned, nothing to do here.
479 */
480 if (var->location != -1)
481 continue;
482
483 /* Find an unused bit in used_locations and assign that as the
484 * attribute location.
485 */
486 for (unsigned i = 0; i < (8 * sizeof(used_locations)); i++) {
487 if ((used_locations & (1 << i)) == 0) {
488 var->location = VERT_ATTRIB_GENERIC0 + i;
489 used_locations |= (1 << i);
490 break;
491 }
492 }
493 }
494}
495
496
497void
Ian Romanick832dfa52010-06-17 15:04:20 -0700498link_shaders(struct glsl_program *prog)
499{
500 prog->LinkStatus = false;
501 prog->Validated = false;
502 prog->_Used = false;
503
504 /* Separate the shaders into groups based on their type.
505 */
506 struct glsl_shader **vert_shader_list;
507 unsigned num_vert_shaders = 0;
508 struct glsl_shader **frag_shader_list;
509 unsigned num_frag_shaders = 0;
510
511 vert_shader_list = (struct glsl_shader **)
Kenneth Graunkec186b3f2010-06-17 15:37:26 -0700512 calloc(2 * prog->NumShaders, sizeof(struct glsl_shader *));
Ian Romanick832dfa52010-06-17 15:04:20 -0700513 frag_shader_list = &vert_shader_list[prog->NumShaders];
514
515 for (unsigned i = 0; i < prog->NumShaders; i++) {
516 switch (prog->Shaders[i]->Type) {
517 case GL_VERTEX_SHADER:
518 vert_shader_list[num_vert_shaders] = prog->Shaders[i];
519 num_vert_shaders++;
520 break;
521 case GL_FRAGMENT_SHADER:
522 frag_shader_list[num_frag_shaders] = prog->Shaders[i];
523 num_frag_shaders++;
524 break;
525 case GL_GEOMETRY_SHADER:
526 /* FINISHME: Support geometry shaders. */
527 assert(prog->Shaders[i]->Type != GL_GEOMETRY_SHADER);
528 break;
529 }
530 }
531
532 /* FINISHME: Implement intra-stage linking. */
533 assert(num_vert_shaders <= 1);
534 assert(num_frag_shaders <= 1);
535
536 /* Verify that each of the per-target executables is valid.
537 */
538 if (!validate_vertex_shader_executable(vert_shader_list[0])
539 || !validate_fragment_shader_executable(frag_shader_list[0]))
540 goto done;
541
542
543 /* FINISHME: Perform inter-stage linking. */
Ian Romanickabee16e2010-06-21 16:16:05 -0700544 prog->_LinkedShaders = (struct glsl_shader **)
545 calloc(2, sizeof(struct glsl_shader *));
546 prog->_NumLinkedShaders = 0;
Ian Romanick832dfa52010-06-17 15:04:20 -0700547
Ian Romanickcc22c5a2010-06-18 17:13:42 -0700548 if (num_vert_shaders > 0) {
Ian Romanickabee16e2010-06-21 16:16:05 -0700549 prog->_LinkedShaders[prog->_NumLinkedShaders] = vert_shader_list[0];
550 prog->_NumLinkedShaders++;
Ian Romanickcc22c5a2010-06-18 17:13:42 -0700551 }
552
553 if (num_frag_shaders > 0) {
Ian Romanickabee16e2010-06-21 16:16:05 -0700554 prog->_LinkedShaders[prog->_NumLinkedShaders] = frag_shader_list[0];
555 prog->_NumLinkedShaders++;
Ian Romanickcc22c5a2010-06-18 17:13:42 -0700556 }
557
Ian Romanickabee16e2010-06-21 16:16:05 -0700558 if (cross_validate_uniforms(prog->_LinkedShaders, prog->_NumLinkedShaders)) {
Ian Romanick37101922010-06-18 19:02:10 -0700559 /* Validate the inputs of each stage with the output of the preceeding
560 * stage.
561 */
Ian Romanickabee16e2010-06-21 16:16:05 -0700562 for (unsigned i = 1; i < prog->_NumLinkedShaders; i++) {
563 if (!cross_validate_outputs_to_inputs(prog->_LinkedShaders[i - 1],
564 prog->_LinkedShaders[i]))
Ian Romanick37101922010-06-18 19:02:10 -0700565 goto done;
566 }
567
Ian Romanickcc22c5a2010-06-18 17:13:42 -0700568 prog->LinkStatus = true;
Ian Romanick37101922010-06-18 19:02:10 -0700569 }
Ian Romanick832dfa52010-06-17 15:04:20 -0700570
Ian Romanick13e10e42010-06-21 12:03:24 -0700571 /* FINISHME: Perform whole-program optimization here. */
572
Ian Romanickabee16e2010-06-21 16:16:05 -0700573 assign_uniform_locations(prog);
Ian Romanick13e10e42010-06-21 12:03:24 -0700574
Ian Romanick0ad22cd2010-06-21 17:18:31 -0700575 if (prog->_LinkedShaders[0]->Type == GL_VERTEX_SHADER)
576 assign_attribute_locations(prog->_LinkedShaders[0],
577 prog->Attributes);
Ian Romanick13e10e42010-06-21 12:03:24 -0700578
579 /* FINISHME: Assign vertex shader output / fragment shader input
580 * FINISHME: locations.
581 */
582
583 /* FINISHME: Assign fragment shader output locations. */
584
585 /* FINISHME: Generate code here. */
586
Ian Romanick832dfa52010-06-17 15:04:20 -0700587done:
588 free(vert_shader_list);
589}