Indent and cosmetic changes.
[mesa.git] / src / mesa / shader / slang / slang_link.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 6.6
4 *
5 * Copyright (C) 2006 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 /**
26 * \file slang_link.c
27 * slang linker
28 * \author Michal Krol
29 */
30
31 #include "imports.h"
32 #include "slang_link.h"
33 #include "slang_analyse.h"
34
35 #define TABLE_GROW(PTR,TYPE,N) \
36 (PTR = (TYPE *) (slang_alloc_realloc (PTR, N * sizeof (TYPE), (N + 1) * sizeof (TYPE))))
37
38 /*
39 * Check if a given name starts with "gl_". Globals with this prefix are
40 * treated differently, as they are built-in variables.
41 */
42 static GLboolean
43 entry_has_gl_prefix (slang_atom name, slang_atom_pool *atoms)
44 {
45 const GLchar *str;
46
47 str = slang_atom_pool_id (atoms, name);
48 return str[0] == 'g' && str[1] == 'l' && str[2] == '_';
49 }
50
51 /*
52 * slang_active_variables
53 */
54
55 static GLvoid
56 slang_active_variables_ctr (slang_active_variables *self)
57 {
58 self->table = NULL;
59 self->count = 0;
60 }
61
62 static GLvoid
63 slang_active_variables_dtr (slang_active_variables *self)
64 {
65 GLuint i;
66
67 for (i = 0; i < self->count; i++)
68 slang_alloc_free (self->table[i].name);
69 slang_alloc_free (self->table);
70 }
71
72 /*
73 * Active variable queried by the application cannot be a structure. Queriable globals
74 * (uniforms and attributes) are decomposited into "simple" variables if they are
75 * "complex".
76 */
77
78 static GLboolean
79 add_simple_variable (slang_active_variables *self, slang_export_data_quant *q, const GLchar *name)
80 {
81 GLuint n;
82 slang_active_variable *var;
83
84 n = self->count;
85 if (!TABLE_GROW(self->table, slang_active_variable, n))
86 return GL_FALSE;
87
88 /* Initialize the new element. Increment table size only when it is fully initilized. */
89 var = &self->table[n];
90 var->quant = q;
91 var->name = slang_string_duplicate (name);
92 if (var->name == NULL)
93 return GL_FALSE;
94 self->count++;
95
96 return GL_TRUE;
97 }
98
99 static GLboolean
100 add_complex_variable (slang_active_variables *self, slang_export_data_quant *q, GLchar *name,
101 slang_atom_pool *atoms)
102 {
103 slang_string_concat (name, slang_atom_pool_id (atoms, q->name));
104
105 /* If array, add only first element. */
106 if (slang_export_data_quant_array (q))
107 slang_string_concat (name, "[0]");
108
109 if (slang_export_data_quant_struct (q)) {
110 GLuint field_pos, fields, i;
111
112 slang_string_concat (name, ".");
113 field_pos = slang_string_length (name);
114
115 /* Break it down into individual fields. */
116 fields = slang_export_data_quant_fields (q);
117 for (i = 0; i < fields; i++) {
118 if (!add_complex_variable (self, &q->structure[i], name, atoms))
119 return GL_FALSE;
120 name[field_pos] = '\0';
121 }
122
123 return GL_TRUE;
124 }
125
126 return add_simple_variable (self, q, name);
127 }
128
129 /*
130 * Search a list of global variables with a given access (either attribute or uniform)
131 * and add it to the list of active variables.
132 */
133 static GLboolean
134 gather_active_variables (slang_active_variables *self, slang_export_data_table *tbl,
135 slang_export_data_access access)
136 {
137 GLuint i;
138
139 for (i = 0; i < tbl->count; i++) {
140 if (tbl->entries[i].access == access) {
141 GLchar name[1024] = "";
142
143 if (!add_complex_variable (self, &tbl->entries[i].quant, name, tbl->atoms))
144 return GL_FALSE;
145 }
146 }
147
148 return GL_TRUE;
149 }
150
151 /*
152 * slang_attrib_overrides
153 */
154
155 static GLvoid
156 slang_attrib_overrides_ctr (slang_attrib_overrides *self)
157 {
158 self->table = NULL;
159 self->count = 0;
160 }
161
162 static GLvoid
163 slang_attrib_overrides_dtr (slang_attrib_overrides *self)
164 {
165 GLuint i;
166
167 for (i = 0; i < self->count; i++)
168 slang_alloc_free (self->table[i].name);
169 slang_alloc_free (self->table);
170 }
171
172 static slang_attrib_override *
173 lookup_attrib_override (slang_attrib_overrides *self, const GLchar *name)
174 {
175 GLuint n, i;
176
177 n = self->count;
178 for (i = 0; i < n; i++) {
179 if (slang_string_compare (name, self->table[i].name) == 0)
180 return &self->table[i];
181 }
182 return NULL;
183 }
184
185 GLboolean
186 _slang_attrib_overrides_add (slang_attrib_overrides *self, GLuint index, const GLchar *name)
187 {
188 slang_attrib_override *ovr;
189 GLuint n;
190
191 /* Attribs can be overriden multiple times. Look-up the table and replace
192 * its index if it is found. */
193 ovr = lookup_attrib_override (self, name);
194 if (ovr != NULL) {
195 ovr->index = index;
196 return GL_TRUE;
197 }
198
199 n = self->count;
200 if (!TABLE_GROW(self->table, slang_attrib_override, n))
201 return GL_FALSE;
202
203 /* Initialize the new element. Increment table size only when it is fully initilized. */
204 ovr = &self->table[n];
205 ovr->index = index;
206 ovr->name = slang_string_duplicate (name);
207 if (ovr->name == NULL)
208 return GL_FALSE;
209 self->count++;
210
211 return GL_TRUE;
212 }
213
214 /*
215 * slang_uniform_bindings
216 */
217
218 static GLvoid
219 slang_uniform_bindings_ctr (slang_uniform_bindings *self)
220 {
221 self->table = NULL;
222 self->count = 0;
223 }
224
225 static GLvoid
226 slang_uniform_bindings_dtr (slang_uniform_bindings *self)
227 {
228 GLuint i;
229
230 for (i = 0; i < self->count; i++)
231 slang_alloc_free (self->table[i].name);
232 slang_alloc_free (self->table);
233 }
234
235 static GLboolean
236 add_simple_uniform_binding (slang_uniform_bindings *self, slang_export_data_quant *q,
237 const GLchar *name, GLuint index, GLuint addr)
238 {
239 GLuint n, i;
240 slang_uniform_binding *bind;
241
242 /* Uniform binding table is shared between vertex and fragment shaders. If the same uniform
243 * is declared both in a vertex and fragment shader, only one uniform entry is maintained.
244 * When add a uniform binding there can be an entry already allocated for it by the other
245 * shader. */
246 n = self->count;
247 for (i = 0; i < n; i++) {
248 if (slang_string_compare (self->table[i].name, name) == 0) {
249 self->table[i].address[index] = addr;
250 return GL_TRUE;
251 }
252 }
253
254 if (!TABLE_GROW(self->table, slang_uniform_binding, n))
255 return GL_FALSE;
256
257 /* Initialize the new element. Increment table size only when it is fully initilized. */
258 bind = &self->table[n];
259 bind->quant = q;
260 bind->name = slang_string_duplicate (name);
261 if (bind->name == NULL)
262 return GL_FALSE;
263 for (i = 0; i < SLANG_SHADER_MAX; i++)
264 bind->address[i] = ~0;
265 bind->address[index] = addr;
266 self->count++;
267
268 return GL_TRUE;
269 }
270
271 static GLboolean
272 add_complex_uniform_binding (slang_uniform_bindings *self, slang_export_data_quant *q,
273 GLchar *name, slang_atom_pool *atoms, GLuint index, GLuint addr)
274 {
275 GLuint count, i;
276
277 slang_string_concat (name, slang_atom_pool_id (atoms, q->name));
278 count = slang_export_data_quant_elements (q);
279
280 /* If array, add binding for every array element. */
281 for (i = 0; i < count; i++) {
282 GLuint bracket_pos;
283
284 bracket_pos = slang_string_length (name);
285 if (slang_export_data_quant_array (q))
286 _mesa_sprintf (&name[slang_string_length (name)], "[%d]", i);
287
288 if (slang_export_data_quant_struct (q)) {
289 GLuint field_pos, fields, i;
290
291 slang_string_concat (name, ".");
292 field_pos = slang_string_length (name);
293
294 /* Break it down into individual fields. */
295 fields = slang_export_data_quant_fields (q);
296 for (i = 0; i < fields; i++) {
297 if (!add_complex_uniform_binding (self, &q->structure[i], name, atoms, index, addr))
298 return GL_FALSE;
299
300 name[field_pos] = '\0';
301 addr += slang_export_data_quant_size (&q->structure[i]);
302 }
303 }
304 else {
305 if (!add_simple_uniform_binding (self, q, name, index, addr))
306 return GL_FALSE;
307
308 addr += slang_export_data_quant_size (q);
309 }
310
311 name[bracket_pos] = '\0';
312 }
313
314 return GL_TRUE;
315 }
316
317 static GLboolean
318 gather_uniform_bindings (slang_uniform_bindings *self, slang_export_data_table *tbl, GLuint index)
319 {
320 GLuint n, i;
321
322 n = tbl->count;
323 for (i = 0; i < n; i++) {
324 if (tbl->entries[i].access == slang_exp_uniform) {
325 GLchar name[1024] = "";
326
327 if (!add_complex_uniform_binding (self, &tbl->entries[i].quant, name, tbl->atoms, index,
328 tbl->entries[i].address))
329 return GL_FALSE;
330 }
331 }
332
333 return GL_TRUE;
334 }
335
336 /*
337 * slang_attrib_bindings
338 */
339
340 static GLvoid
341 slang_attrib_bindings_ctr (slang_attrib_bindings *self)
342 {
343 GLuint i;
344
345 self->binding_count = 0;
346 for (i = 0; i < MAX_VERTEX_ATTRIBS; i++)
347 self->slots[i].addr = ~0;
348 }
349
350 static GLvoid
351 slang_attrib_bindings_dtr (slang_attrib_bindings *self)
352 {
353 GLuint i;
354
355 for (i = 0; i < self->binding_count; i++)
356 slang_alloc_free (self->bindings[i].name);
357 }
358
359 /*
360 * NOTE: If conventional vertex attribute gl_Vertex is used, application cannot use
361 * vertex attrib index 0 for binding override. Currently this is not checked.
362 * Anyways, attrib index 0 is not used when not explicitly asked.
363 */
364
365 static GLuint
366 can_allocate_attrib_slots (slang_attrib_bindings *self, GLuint index, GLuint count)
367 {
368 GLuint i;
369
370 for (i = 0; i < count; i++) {
371 if (self->slots[index + i].addr != ~0)
372 break;
373 }
374 return i;
375 }
376
377 static GLuint
378 allocate_attrib_slots (slang_attrib_bindings *self, GLuint count)
379 {
380 GLuint i;
381
382 /* Start with attrib index 1. Index 0 will be used when explicitly
383 * asked by application binding. */
384 for (i = 1; i <= MAX_VERTEX_ATTRIBS - count; i++) {
385 GLuint size;
386
387 size = can_allocate_attrib_slots (self, i, count);
388 if (size == count)
389 return i;
390
391 /* Speed-up the search a bit. */
392 i += size;
393 }
394
395 return MAX_VERTEX_ATTRIBS;
396 }
397
398 static GLboolean
399 add_attrib_binding (slang_attrib_bindings *self, slang_export_data_quant *q, const GLchar *name,
400 GLuint addr, GLuint index_override)
401 {
402 GLuint slot_span, slot_fill, slot_index, i;
403 slang_attrib_binding *bind;
404
405 assert (slang_export_data_quant_simple (q));
406
407 switch (slang_export_data_quant_type (q)) {
408 case GL_FLOAT:
409 slot_span = 1;
410 slot_fill = 1;
411 break;
412 case GL_FLOAT_VEC2:
413 slot_span = 1;
414 slot_fill = 2;
415 break;
416 case GL_FLOAT_VEC3:
417 slot_span = 1;
418 slot_fill = 3;
419 break;
420 case GL_FLOAT_VEC4:
421 slot_span = 1;
422 slot_fill = 4;
423 break;
424 case GL_FLOAT_MAT2:
425 slot_span = 2;
426 slot_fill = 2;
427 break;
428 case GL_FLOAT_MAT3:
429 slot_span = 3;
430 slot_fill = 3;
431 break;
432 case GL_FLOAT_MAT4:
433 slot_span = 4;
434 slot_fill = 4;
435 break;
436 default:
437 assert (0);
438 }
439
440 if (index_override == MAX_VERTEX_ATTRIBS)
441 slot_index = allocate_attrib_slots (self, slot_span);
442 else if (can_allocate_attrib_slots (self, index_override, slot_span) == slot_span)
443 slot_index = index_override;
444 else
445 slot_index = MAX_VERTEX_ATTRIBS;
446
447 if (slot_index == MAX_VERTEX_ATTRIBS) {
448 /* TODO: info log: error: MAX_VERTEX_ATTRIBS exceeded */
449 return GL_FALSE;
450 }
451
452 /* Initialize the new element. Increment table size only when it is fully initilized. */
453 bind = &self->bindings[self->binding_count];
454 bind->quant = q;
455 bind->name = slang_string_duplicate (name);
456 if (bind->name == NULL)
457 return GL_FALSE;
458 bind->first_slot_index = slot_index;
459 self->binding_count++;
460
461 for (i = 0; i < slot_span; i++) {
462 slang_attrib_slot *slot;
463
464 slot = &self->slots[bind->first_slot_index + i];
465 slot->addr = addr + i * slot_fill * 4;
466 slot->fill = slot_fill;
467 }
468
469 return GL_TRUE;
470 }
471
472 static GLboolean
473 gather_attrib_bindings (slang_attrib_bindings *self, slang_export_data_table *tbl,
474 slang_attrib_overrides *ovr)
475 {
476 GLuint i;
477
478 /* First pass. Gather attribs that have overriden index slots. */
479 for (i = 0; i < tbl->count; i++) {
480 if (tbl->entries[i].access == slang_exp_attribute &&
481 !entry_has_gl_prefix (tbl->entries[i].quant.name, tbl->atoms)) {
482 slang_export_data_quant *quant;
483 const GLchar *id;
484 slang_attrib_override *ao;
485
486 quant = &tbl->entries[i].quant;
487 id = slang_atom_pool_id (tbl->atoms, quant->name);
488 ao = lookup_attrib_override (ovr, id);
489 if (ao != NULL) {
490 if (!add_attrib_binding (self, quant, id, tbl->entries[i].address, ao->index))
491 return GL_FALSE;
492 }
493 }
494 }
495
496 /* Second pass. Gather attribs that have not overriden index slots. */
497 for (i = 0; i < tbl->count; i++) {
498 if (tbl->entries[i].access == slang_exp_attribute &&
499 !entry_has_gl_prefix (tbl->entries[i].quant.name, tbl->atoms)) {
500 slang_export_data_quant *quant;
501 const GLchar *id;
502 slang_attrib_override *ao;
503
504 quant = &tbl->entries[i].quant;
505 id = slang_atom_pool_id (tbl->atoms, quant->name);
506 ao = lookup_attrib_override (ovr, id);
507 if (ao == NULL) {
508 if (!add_attrib_binding (self, quant, id, tbl->entries[i].address, ao->index))
509 return GL_FALSE;
510 }
511 }
512 }
513
514 return GL_TRUE;
515 }
516
517 /*
518 * slang_varying_bindings
519 */
520
521 static GLvoid
522 slang_varying_bindings_ctr (slang_varying_bindings *self)
523 {
524 self->binding_count = 0;
525 self->slot_count = 0;
526 }
527
528 static GLvoid
529 slang_varying_bindings_dtr (slang_varying_bindings *self)
530 {
531 GLuint i;
532
533 for (i = 0; i < self->binding_count; i++)
534 slang_alloc_free (self->bindings[i].name);
535 }
536
537 static GLvoid
538 update_varying_slots (slang_varying_slot *slots, GLuint count, GLboolean is_vert, GLuint addr,
539 GLuint do_offset)
540 {
541 GLuint i;
542
543 for (i = 0; i < count; i++) {
544 if (is_vert)
545 slots[i].vert_addr = addr + i * 4 * do_offset;
546 else
547 slots[i].frag_addr = addr + i * 4 * do_offset;
548 }
549 }
550
551 static GLboolean
552 add_varying_binding (slang_varying_bindings *self, slang_export_data_quant *q, const GLchar *name,
553 GLboolean is_vert, GLuint addr)
554 {
555 GLuint n, slot_span, i;
556 slang_varying_binding *bind;
557
558 n = self->binding_count;
559 slot_span = slang_export_data_quant_components (q) * slang_export_data_quant_elements (q);
560 for (i = 0; i < n; i++) {
561 if (slang_string_compare (self->bindings[i].name, name) == 0) {
562 /* TODO: data quantities must match, or else link fails */
563 update_varying_slots (&self->slots[self->bindings[i].first_slot_index], slot_span,
564 is_vert, addr, 1);
565 return GL_TRUE;
566 }
567 }
568
569 if (self->slot_count + slot_span > MAX_VARYING_FLOATS) {
570 /* TODO: info log: error: MAX_VARYING_FLOATS exceeded */
571 return GL_FALSE;
572 }
573
574 /* Initialize the new element. Increment table size only when it is fully initilized. */
575 bind = &self->bindings[n];
576 bind->quant = q;
577 bind->name = slang_string_duplicate (name);
578 if (bind->name == NULL)
579 return GL_FALSE;
580 bind->first_slot_index = self->slot_count;
581 self->binding_count++;
582
583 update_varying_slots (&self->slots[bind->first_slot_index], slot_span, is_vert, addr, 1);
584 update_varying_slots (&self->slots[bind->first_slot_index], slot_span, !is_vert, ~0, 0);
585 self->slot_count += slot_span;
586
587 return GL_TRUE;
588 }
589
590 static GLboolean
591 gather_varying_bindings (slang_varying_bindings *self, slang_export_data_table *tbl,
592 GLboolean is_vert)
593 {
594 GLuint i;
595
596 for (i = 0; i < tbl->count; i++) {
597 if (tbl->entries[i].access == slang_exp_varying &&
598 !entry_has_gl_prefix (tbl->entries[i].quant.name, tbl->atoms)) {
599 if (!add_varying_binding (self, &tbl->entries[i].quant,
600 slang_atom_pool_id (tbl->atoms, tbl->entries[i].quant.name),
601 is_vert, tbl->entries[i].address))
602 return GL_FALSE;
603 }
604 }
605
606 return GL_TRUE;
607 }
608
609 /*
610 * slang_texture_bindings
611 */
612
613 GLvoid
614 _slang_texture_usages_ctr (slang_texture_usages *self)
615 {
616 self->table = NULL;
617 self->count = 0;
618 }
619
620 GLvoid
621 _slang_texture_usages_dtr (slang_texture_usages *self)
622 {
623 slang_alloc_free (self->table);
624 }
625
626 /*
627 * slang_program
628 */
629
630 GLvoid
631 _slang_program_ctr (slang_program *self)
632 {
633 GLuint i;
634
635 slang_active_variables_ctr (&self->active_uniforms);
636 slang_active_variables_ctr (&self->active_attribs);
637 slang_attrib_overrides_ctr (&self->attrib_overrides);
638 slang_uniform_bindings_ctr (&self->uniforms);
639 slang_attrib_bindings_ctr (&self->attribs);
640 slang_varying_bindings_ctr (&self->varyings);
641 _slang_texture_usages_ctr (&self->texture_usage);
642 for (i = 0; i < SLANG_SHADER_MAX; i++) {
643 GLuint j;
644
645 for (j = 0; j < SLANG_COMMON_FIXED_MAX; j++)
646 self->common_fixed_entries[i][j] = ~0;
647 for (j = 0; j < SLANG_COMMON_CODE_MAX; j++)
648 self->code[i][j] = ~0;
649 self->machines[i] = NULL;
650 self->assemblies[i] = NULL;
651 }
652 for (i = 0; i < SLANG_VERTEX_FIXED_MAX; i++)
653 self->vertex_fixed_entries[i] = ~0;
654 for (i = 0; i < SLANG_FRAGMENT_FIXED_MAX; i++)
655 self->fragment_fixed_entries[i] = ~0;
656 }
657
658 GLvoid
659 _slang_program_dtr (slang_program *self)
660 {
661 slang_active_variables_dtr (&self->active_uniforms);
662 slang_active_variables_dtr (&self->active_attribs);
663 slang_attrib_overrides_dtr (&self->attrib_overrides);
664 slang_uniform_bindings_dtr (&self->uniforms);
665 slang_attrib_bindings_dtr (&self->attribs);
666 slang_varying_bindings_dtr (&self->varyings);
667 _slang_texture_usages_dtr (&self->texture_usage);
668 }
669
670 GLvoid
671 _slang_program_rst (slang_program *self)
672 {
673 GLuint i;
674
675 slang_active_variables_dtr (&self->active_uniforms);
676 slang_active_variables_dtr (&self->active_attribs);
677 slang_uniform_bindings_dtr (&self->uniforms);
678 slang_attrib_bindings_dtr (&self->attribs);
679 slang_varying_bindings_dtr (&self->varyings);
680 _slang_texture_usages_dtr (&self->texture_usage);
681
682 slang_active_variables_ctr (&self->active_uniforms);
683 slang_active_variables_ctr (&self->active_attribs);
684 slang_uniform_bindings_ctr (&self->uniforms);
685 slang_attrib_bindings_ctr (&self->attribs);
686 slang_varying_bindings_ctr (&self->varyings);
687 _slang_texture_usages_ctr (&self->texture_usage);
688 for (i = 0; i < SLANG_SHADER_MAX; i++) {
689 GLuint j;
690
691 for (j = 0; j < SLANG_COMMON_FIXED_MAX; j++)
692 self->common_fixed_entries[i][j] = ~0;
693 for (j = 0; j < SLANG_COMMON_CODE_MAX; j++)
694 self->code[i][j] = ~0;
695 }
696 for (i = 0; i < SLANG_VERTEX_FIXED_MAX; i++)
697 self->vertex_fixed_entries[i] = ~0;
698 for (i = 0; i < SLANG_FRAGMENT_FIXED_MAX; i++)
699 self->fragment_fixed_entries[i] = ~0;
700 }
701
702 /*
703 * _slang_link()
704 */
705
706 static GLuint
707 gd (slang_export_data_table *tbl, const GLchar *name)
708 {
709 slang_atom atom;
710 GLuint i;
711
712 atom = slang_atom_pool_atom (tbl->atoms, name);
713 if (atom == SLANG_ATOM_NULL)
714 return ~0;
715
716 for (i = 0; i < tbl->count; i++) {
717 if (atom == tbl->entries[i].quant.name)
718 return tbl->entries[i].address;
719 }
720 return ~0;
721 }
722
723 static GLvoid
724 resolve_common_fixed (GLuint e[], slang_export_data_table *tbl)
725 {
726 e[SLANG_COMMON_FIXED_MODELVIEWMATRIX] = gd (tbl, "gl_ModelViewMatrix");
727 e[SLANG_COMMON_FIXED_PROJECTIONMATRIX] = gd (tbl, "gl_ProjectionMatrix");
728 e[SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIX] = gd (tbl, "gl_ModelViewProjectionMatrix");
729 e[SLANG_COMMON_FIXED_TEXTUREMATRIX] = gd (tbl, "gl_TextureMatrix");
730 e[SLANG_COMMON_FIXED_NORMALMATRIX] = gd (tbl, "gl_NormalMatrix");
731 e[SLANG_COMMON_FIXED_MODELVIEWMATRIXINVERSE] = gd (tbl, "gl_ModelViewMatrixInverse");
732 e[SLANG_COMMON_FIXED_PROJECTIONMATRIXINVERSE] = gd (tbl, "gl_ProjectionMatrixInverse");
733 e[SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXINVERSE] = gd (tbl, "gl_ModelViewProjectionMatrixInverse");
734 e[SLANG_COMMON_FIXED_TEXTUREMATRIXINVERSE] = gd (tbl, "gl_TextureMatrixInverse");
735 e[SLANG_COMMON_FIXED_MODELVIEWMATRIXTRANSPOSE] = gd (tbl, "gl_ModelViewMatrixTranspose");
736 e[SLANG_COMMON_FIXED_PROJECTIONMATRIXTRANSPOSE] = gd (tbl, "gl_ProjectionMatrixTranspose");
737 e[SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXTRANSPOSE] = gd (tbl, "gl_ModelViewProjectionMatrixTranspose");
738 e[SLANG_COMMON_FIXED_TEXTUREMATRIXTRANSPOSE] = gd (tbl, "gl_TextureMatrixTranspose");
739 e[SLANG_COMMON_FIXED_MODELVIEWMATRIXINVERSETRANSPOSE] = gd (tbl, "gl_ModelViewMatrixInverseTranspose");
740 e[SLANG_COMMON_FIXED_PROJECTIONMATRIXINVERSETRANSPOSE] = gd (tbl, "gl_ProjectionMatrixInverseTranspose");
741 e[SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXINVERSETRANSPOSE] = gd (tbl, "gl_ModelViewProjectionMatrixInverseTranspose");
742 e[SLANG_COMMON_FIXED_TEXTUREMATRIXINVERSETRANSPOSE] = gd (tbl, "gl_TextureMatrixInverseTranspose");
743 e[SLANG_COMMON_FIXED_NORMALSCALE] = gd (tbl, "gl_NormalScale");
744 e[SLANG_COMMON_FIXED_DEPTHRANGE] = gd (tbl, "gl_DepthRange");
745 e[SLANG_COMMON_FIXED_CLIPPLANE] = gd (tbl, "gl_ClipPlane");
746 e[SLANG_COMMON_FIXED_POINT] = gd (tbl, "gl_Point");
747 e[SLANG_COMMON_FIXED_FRONTMATERIAL] = gd (tbl, "gl_FrontMaterial");
748 e[SLANG_COMMON_FIXED_BACKMATERIAL] = gd (tbl, "gl_BackMaterial");
749 e[SLANG_COMMON_FIXED_LIGHTSOURCE] = gd (tbl, "gl_LightSource");
750 e[SLANG_COMMON_FIXED_LIGHTMODEL] = gd (tbl, "gl_LightModel");
751 e[SLANG_COMMON_FIXED_FRONTLIGHTMODELPRODUCT] = gd (tbl, "gl_FrontLightModelProduct");
752 e[SLANG_COMMON_FIXED_BACKLIGHTMODELPRODUCT] = gd (tbl, "gl_BackLightModelProduct");
753 e[SLANG_COMMON_FIXED_FRONTLIGHTPRODUCT] = gd (tbl, "gl_FrontLightProduct");
754 e[SLANG_COMMON_FIXED_BACKLIGHTPRODUCT] = gd (tbl, "gl_BackLightProduct");
755 e[SLANG_COMMON_FIXED_TEXTUREENVCOLOR] = gd (tbl, "gl_TextureEnvColor");
756 e[SLANG_COMMON_FIXED_EYEPLANES] = gd (tbl, "gl_EyePlaneS");
757 e[SLANG_COMMON_FIXED_EYEPLANET] = gd (tbl, "gl_EyePlaneT");
758 e[SLANG_COMMON_FIXED_EYEPLANER] = gd (tbl, "gl_EyePlaneR");
759 e[SLANG_COMMON_FIXED_EYEPLANEQ] = gd (tbl, "gl_EyePlaneQ");
760 e[SLANG_COMMON_FIXED_OBJECTPLANES] = gd (tbl, "gl_ObjectPlaneS");
761 e[SLANG_COMMON_FIXED_OBJECTPLANET] = gd (tbl, "gl_ObjectPlaneT");
762 e[SLANG_COMMON_FIXED_OBJECTPLANER] = gd (tbl, "gl_ObjectPlaneR");
763 e[SLANG_COMMON_FIXED_OBJECTPLANEQ] = gd (tbl, "gl_ObjectPlaneQ");
764 e[SLANG_COMMON_FIXED_FOG] = gd (tbl, "gl_Fog");
765 }
766
767 static GLvoid
768 resolve_vertex_fixed (GLuint e[], slang_export_data_table *tbl)
769 {
770 e[SLANG_VERTEX_FIXED_POSITION] = gd (tbl, "gl_Position");
771 e[SLANG_VERTEX_FIXED_POINTSIZE] = gd (tbl, "gl_PointSize");
772 e[SLANG_VERTEX_FIXED_CLIPVERTEX] = gd (tbl, "gl_ClipVertex");
773 e[SLANG_VERTEX_FIXED_COLOR] = gd (tbl, "gl_Color");
774 e[SLANG_VERTEX_FIXED_SECONDARYCOLOR] = gd (tbl, "gl_SecondaryColor");
775 e[SLANG_VERTEX_FIXED_NORMAL] = gd (tbl, "gl_Normal");
776 e[SLANG_VERTEX_FIXED_VERTEX] = gd (tbl, "gl_Vertex");
777 e[SLANG_VERTEX_FIXED_MULTITEXCOORD0] = gd (tbl, "gl_MultiTexCoord0");
778 e[SLANG_VERTEX_FIXED_MULTITEXCOORD1] = gd (tbl, "gl_MultiTexCoord1");
779 e[SLANG_VERTEX_FIXED_MULTITEXCOORD2] = gd (tbl, "gl_MultiTexCoord2");
780 e[SLANG_VERTEX_FIXED_MULTITEXCOORD3] = gd (tbl, "gl_MultiTexCoord3");
781 e[SLANG_VERTEX_FIXED_MULTITEXCOORD4] = gd (tbl, "gl_MultiTexCoord4");
782 e[SLANG_VERTEX_FIXED_MULTITEXCOORD5] = gd (tbl, "gl_MultiTexCoord5");
783 e[SLANG_VERTEX_FIXED_MULTITEXCOORD6] = gd (tbl, "gl_MultiTexCoord6");
784 e[SLANG_VERTEX_FIXED_MULTITEXCOORD7] = gd (tbl, "gl_MultiTexCoord7");
785 e[SLANG_VERTEX_FIXED_FOGCOORD] = gd (tbl, "gl_FogCoord");
786 e[SLANG_VERTEX_FIXED_FRONTCOLOR] = gd (tbl, "gl_FrontColor");
787 e[SLANG_VERTEX_FIXED_BACKCOLOR] = gd (tbl, "gl_BackColor");
788 e[SLANG_VERTEX_FIXED_FRONTSECONDARYCOLOR] = gd (tbl, "gl_FrontSecondaryColor");
789 e[SLANG_VERTEX_FIXED_BACKSECONDARYCOLOR] = gd (tbl, "gl_BackSecondaryColor");
790 e[SLANG_VERTEX_FIXED_TEXCOORD] = gd (tbl, "gl_TexCoord");
791 e[SLANG_VERTEX_FIXED_FOGFRAGCOORD] = gd (tbl, "gl_FogFragCoord");
792 }
793
794 static GLvoid
795 resolve_fragment_fixed (GLuint e[], slang_export_data_table *tbl)
796 {
797 e[SLANG_FRAGMENT_FIXED_FRAGCOORD] = gd (tbl, "gl_FragCoord");
798 e[SLANG_FRAGMENT_FIXED_FRONTFACING] = gd (tbl, "gl_FrontFacing");
799 e[SLANG_FRAGMENT_FIXED_FRAGCOLOR] = gd (tbl, "gl_FragColor");
800 e[SLANG_FRAGMENT_FIXED_FRAGDATA] = gd (tbl, "gl_FragData");
801 e[SLANG_FRAGMENT_FIXED_FRAGDEPTH] = gd (tbl, "gl_FragDepth");
802 e[SLANG_FRAGMENT_FIXED_COLOR] = gd (tbl, "gl_Color");
803 e[SLANG_FRAGMENT_FIXED_SECONDARYCOLOR] = gd (tbl, "gl_SecondaryColor");
804 e[SLANG_FRAGMENT_FIXED_TEXCOORD] = gd (tbl, "gl_TexCoord");
805 e[SLANG_FRAGMENT_FIXED_FOGFRAGCOORD] = gd (tbl, "gl_FogFragCoord");
806 }
807
808 static GLuint
809 gc (slang_export_code_table *tbl, const GLchar *name)
810 {
811 slang_atom atom;
812 GLuint i;
813
814 atom = slang_atom_pool_atom (tbl->atoms, name);
815 if (atom == SLANG_ATOM_NULL)
816 return ~0;
817
818 for (i = 0; i < tbl->count; i++) {
819 if (atom == tbl->entries[i].name)
820 return tbl->entries[i].address;
821 }
822 return ~0;
823 }
824
825 static GLvoid
826 resolve_common_code (GLuint code[], slang_export_code_table *tbl)
827 {
828 code[SLANG_COMMON_CODE_MAIN] = gc (tbl, "@main");
829 }
830
831 GLboolean
832 _slang_link (slang_program *prog, slang_code_object **objects, GLuint count)
833 {
834 GLuint i;
835
836 for (i = 0; i < count; i++) {
837 GLuint index;
838
839 if (objects[i]->unit.type == slang_unit_fragment_shader) {
840 index = SLANG_SHADER_FRAGMENT;
841 resolve_fragment_fixed (prog->fragment_fixed_entries, &objects[i]->expdata);
842 }
843 else {
844 index = SLANG_SHADER_VERTEX;
845 resolve_vertex_fixed (prog->vertex_fixed_entries, &objects[i]->expdata);
846 if (!gather_attrib_bindings (&prog->attribs, &objects[i]->expdata,
847 &prog->attrib_overrides))
848 return GL_FALSE;
849 }
850
851 if (!gather_active_variables (&prog->active_uniforms, &objects[i]->expdata, slang_exp_uniform))
852 return GL_FALSE;
853 if (!gather_active_variables (&prog->active_attribs, &objects[i]->expdata, slang_exp_attribute))
854 return GL_FALSE;
855 if (!gather_uniform_bindings (&prog->uniforms, &objects[i]->expdata, index))
856 return GL_FALSE;
857 if (!gather_varying_bindings (&prog->varyings, &objects[i]->expdata,
858 index == SLANG_SHADER_VERTEX))
859 return GL_FALSE;
860 resolve_common_fixed (prog->common_fixed_entries[index], &objects[i]->expdata);
861 resolve_common_code (prog->code[index], &objects[i]->expcode);
862 prog->machines[index] = &objects[i]->machine;
863 prog->assemblies[index] = &objects[i]->assembly;
864 }
865
866 /* TODO: all varyings read by fragment shader must be written by vertex shader */
867
868 if (!_slang_analyse_texture_usage (prog))
869 return GL_FALSE;
870
871 return GL_TRUE;
872 }
873