Fix Windows newlines.
[mesa.git] / src / mesa / shader / slang / slang_link.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 6.5
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 static GLboolean entry_has_gl_prefix (slang_atom name, slang_atom_pool *atoms)
36 {
37 const char *str = slang_atom_pool_id (atoms, name);
38 return str[0] == 'g' && str[1] == 'l' && str[2] == '_';
39 }
40
41 /*
42 * slang_active_variables
43 */
44
45 static GLvoid slang_active_variables_ctr (slang_active_variables *self)
46 {
47 self->table = NULL;
48 self->count = 0;
49 }
50
51 static GLvoid slang_active_variables_dtr (slang_active_variables *self)
52 {
53 GLuint i;
54
55 for (i = 0; i < self->count; i++)
56 slang_alloc_free (self->table[i].name);
57 slang_alloc_free (self->table);
58 }
59
60 static GLboolean add_simple_variable (slang_active_variables *self, slang_export_data_quant *q,
61 const char *name)
62 {
63 const GLuint n = self->count;
64
65 self->table = (slang_active_variable *) slang_alloc_realloc (self->table,
66 n * sizeof (slang_active_variable), (n + 1) * sizeof (slang_active_variable));
67 if (self->table == NULL)
68 return GL_FALSE;
69
70 self->table[n].quant = q;
71 self->table[n].name = slang_string_duplicate (name);
72 if (self->table[n].name == NULL)
73 return GL_FALSE;
74 self->count++;
75
76 return GL_TRUE;
77 }
78
79 static GLboolean add_complex_variable (slang_active_variables *self, slang_export_data_quant *q,
80 char *name, slang_atom_pool *atoms)
81 {
82 slang_string_concat (name, slang_atom_pool_id (atoms, q->name));
83 if (slang_export_data_quant_array (q))
84 slang_string_concat (name, "[0]");
85
86 if (slang_export_data_quant_struct (q))
87 {
88 GLuint dot_pos, i;
89 const GLuint fields = slang_export_data_quant_fields (q);
90
91 slang_string_concat (name, ".");
92 dot_pos = slang_string_length (name);
93
94 for (i = 0; i < fields; i++)
95 {
96 if (!add_complex_variable (self, &q->structure[i], name, atoms))
97 return GL_FALSE;
98
99 name[dot_pos] = '\0';
100 }
101
102 return GL_TRUE;
103 }
104
105 return add_simple_variable (self, q, name);
106 }
107
108 static GLboolean gather_active_variables (slang_active_variables *self,
109 slang_export_data_table *tbl, slang_export_data_access access)
110 {
111 GLuint i;
112
113 for (i = 0; i < tbl->count; i++)
114 if (tbl->entries[i].access == access)
115 {
116 char name[1024] = "";
117
118 if (!add_complex_variable (self, &tbl->entries[i].quant, name, tbl->atoms))
119 return GL_FALSE;
120 }
121
122 return GL_TRUE;
123 }
124
125 /*
126 * slang_attrib_overrides
127 */
128
129 static GLvoid slang_attrib_overrides_ctr (slang_attrib_overrides *self)
130 {
131 self->table = NULL;
132 self->count = 0;
133 }
134
135 static GLvoid slang_attrib_overrides_dtr (slang_attrib_overrides *self)
136 {
137 GLuint i;
138
139 for (i = 0; i < self->count; i++)
140 slang_alloc_free (self->table[i].name);
141 slang_alloc_free (self->table);
142 }
143
144 GLboolean slang_attrib_overrides_add (slang_attrib_overrides *self, GLuint index, const GLchar *name)
145 {
146 const GLuint n = self->count;
147 GLuint i;
148
149 for (i = 0; i < n; i++)
150 if (slang_string_compare (name, self->table[i].name) == 0)
151 {
152 self->table[i].index = index;
153 return GL_TRUE;
154 }
155
156 self->table = (slang_attrib_override *) slang_alloc_realloc (self->table,
157 n * sizeof (slang_attrib_override), (n + 1) * sizeof (slang_attrib_override));
158 if (self->table == NULL)
159 return GL_FALSE;
160
161 self->table[n].index = index;
162 self->table[n].name = slang_string_duplicate (name);
163 if (self->table[n].name == NULL)
164 return GL_FALSE;
165 self->count++;
166
167 return GL_TRUE;
168 }
169
170 static GLuint lookup_attrib_override (slang_attrib_overrides *self, const GLchar *name)
171 {
172 GLuint i;
173
174 for (i = 0; i < self->count; i++)
175 if (slang_string_compare (name, self->table[i].name) == 0)
176 return self->table[i].index;
177 return MAX_VERTEX_ATTRIBS;
178 }
179
180 /*
181 * slang_uniform_bindings
182 */
183
184 static GLvoid slang_uniform_bindings_ctr (slang_uniform_bindings *self)
185 {
186 self->table = NULL;
187 self->count = 0;
188 }
189
190 static GLvoid slang_uniform_bindings_dtr (slang_uniform_bindings *self)
191 {
192 GLuint i;
193
194 for (i = 0; i < self->count; i++)
195 slang_alloc_free (self->table[i].name);
196 slang_alloc_free (self->table);
197 }
198
199 static GLboolean add_simple_uniform_binding (slang_uniform_bindings *self,
200 slang_export_data_quant *q, const char *name, GLuint index, GLuint addr)
201 {
202 const GLuint n = self->count;
203 GLuint i;
204
205 for (i = 0; i < n; i++)
206 if (slang_string_compare (self->table[i].name, name) == 0)
207 {
208 self->table[i].address[index] = addr;
209 return GL_TRUE;
210 }
211
212 self->table = (slang_uniform_binding *) slang_alloc_realloc (self->table,
213 n * sizeof (slang_uniform_binding), (n + 1) * sizeof (slang_uniform_binding));
214 if (self->table == NULL)
215 return GL_FALSE;
216
217 self->table[n].quant = q;
218 self->table[n].name = slang_string_duplicate (name);
219 if (self->table[n].name == NULL)
220 return GL_FALSE;
221 for (i = 0; i < SLANG_SHADER_MAX; i++)
222 self->table[n].address[i] = ~0;
223 self->table[n].address[index] = addr;
224 self->count++;
225
226 return GL_TRUE;
227 }
228
229 static GLboolean add_complex_uniform_binding (slang_uniform_bindings *self,
230 slang_export_data_quant *q, char *name, slang_atom_pool *atoms, GLuint index, GLuint addr)
231 {
232 GLuint count, i;
233
234 slang_string_concat (name, slang_atom_pool_id (atoms, q->name));
235 count = slang_export_data_quant_elements (q);
236 for (i = 0; i < count; i++)
237 {
238 GLuint bracket_pos;
239
240 bracket_pos = slang_string_length (name);
241 if (slang_export_data_quant_array (q))
242 _mesa_sprintf (name + slang_string_length (name), "[%d]", i);
243
244 if (slang_export_data_quant_struct (q))
245 {
246 GLuint dot_pos, i;
247 const GLuint fields = slang_export_data_quant_fields (q);
248
249 slang_string_concat (name, ".");
250 dot_pos = slang_string_length (name);
251
252 for (i = 0; i < fields; i++)
253 {
254 if (!add_complex_uniform_binding (self, &q->structure[i], name, atoms, index, addr))
255 return GL_FALSE;
256
257 name[dot_pos] = '\0';
258 addr += slang_export_data_quant_size (&q->structure[i]);
259 }
260 }
261 else
262 {
263 if (!add_simple_uniform_binding (self, q, name, index, addr))
264 return GL_FALSE;
265
266 addr += slang_export_data_quant_size (q);
267 }
268
269 name[bracket_pos] = '\0';
270 }
271
272 return GL_TRUE;
273 }
274
275 static GLboolean gather_uniform_bindings (slang_uniform_bindings *self,
276 slang_export_data_table *tbl, GLuint index)
277 {
278 GLuint i;
279
280 for (i = 0; i < tbl->count; i++)
281 if (tbl->entries[i].access == slang_exp_uniform)
282 {
283 char name[1024] = "";
284
285 if (!add_complex_uniform_binding (self, &tbl->entries[i].quant, name, tbl->atoms, index,
286 tbl->entries[i].address))
287 return GL_FALSE;
288 }
289
290 return GL_TRUE;
291 }
292
293 /*
294 * slang_attrib_bindings
295 */
296
297 static GLvoid slang_attrib_bindings_ctr (slang_attrib_bindings *self)
298 {
299 GLuint i;
300
301 self->binding_count = 0;
302 for (i = 0; i < MAX_VERTEX_ATTRIBS; i++)
303 self->slots[i].addr = ~0;
304 }
305
306 static GLvoid slang_attrib_bindings_dtr (slang_attrib_bindings *self)
307 {
308 GLuint i;
309
310 for (i = 0; i < self->binding_count; i++)
311 slang_alloc_free (self->bindings[i].name);
312 }
313
314 /*
315 * NOTE: If conventional vertex attribute gl_Vertex is used, application cannot use
316 * vertex attrib index 0 for binding override. Currently this is not checked.
317 * Although attrib index 0 is not used when not explicitly asked.
318 */
319
320 static GLuint can_allocate_attrib_slots (slang_attrib_bindings *self, GLuint index, GLuint count)
321 {
322 GLuint i;
323
324 for (i = 0; i < count; i++)
325 if (self->slots[index + i].addr != ~0)
326 break;
327 return i;
328 }
329
330 static GLuint allocate_attrib_slots (slang_attrib_bindings *self, GLuint count)
331 {
332 GLuint i;
333
334 for (i = 1; i <= MAX_VERTEX_ATTRIBS - count; i++)
335 {
336 GLuint size;
337
338 size = can_allocate_attrib_slots (self, i, count);
339 if (size == count)
340 return i;
341
342 /* speed-up the search a bit */
343 i += size;
344 }
345 return MAX_VERTEX_ATTRIBS;
346 }
347
348 static GLboolean
349 add_attrib_binding (slang_attrib_bindings *self, slang_export_data_quant *q, const char *name,
350 GLuint addr, GLuint index_override)
351 {
352 const GLuint n = self->binding_count;
353 GLuint slot_span, slot_fill, slot_index;
354 GLuint i;
355
356 assert (slang_export_data_quant_simple (q));
357
358 switch (slang_export_data_quant_type (q))
359 {
360 case GL_FLOAT:
361 slot_span = 1;
362 slot_fill = 1;
363 break;
364 case GL_FLOAT_VEC2:
365 slot_span = 1;
366 slot_fill = 2;
367 break;
368 case GL_FLOAT_VEC3:
369 slot_span = 1;
370 slot_fill = 3;
371 break;
372 case GL_FLOAT_VEC4:
373 slot_span = 1;
374 slot_fill = 4;
375 break;
376 case GL_FLOAT_MAT2:
377 slot_span = 2;
378 slot_fill = 2;
379 break;
380 case GL_FLOAT_MAT3:
381 slot_span = 3;
382 slot_fill = 3;
383 break;
384 case GL_FLOAT_MAT4:
385 slot_span = 4;
386 slot_fill = 4;
387 break;
388 default:
389 assert (0);
390 }
391
392 if (index_override == MAX_VERTEX_ATTRIBS)
393 slot_index = allocate_attrib_slots (self, slot_span);
394 else if (can_allocate_attrib_slots (self, index_override, slot_span) == slot_span)
395 slot_index = index_override;
396 else
397 slot_index = MAX_VERTEX_ATTRIBS;
398
399 if (slot_index == MAX_VERTEX_ATTRIBS)
400 {
401 /* TODO: info log: error: MAX_VERTEX_ATTRIBS exceeded */
402 return GL_FALSE;
403 }
404
405 self->bindings[n].quant = q;
406 self->bindings[n].name = slang_string_duplicate (name);
407 if (self->bindings[n].name == NULL)
408 return GL_FALSE;
409 self->bindings[n].first_slot_index = slot_index;
410 self->binding_count++;
411
412 for (i = 0; i < slot_span; i++) {
413 slang_attrib_slot *slot = &self->slots[self->bindings[n].first_slot_index + i];
414 slot->addr = addr + i * slot_fill * 4;
415 slot->fill = slot_fill;
416 }
417
418 return GL_TRUE;
419 }
420
421 static GLboolean gather_attrib_bindings (slang_attrib_bindings *self, slang_export_data_table *tbl,
422 slang_attrib_overrides *ovr)
423 {
424 GLuint i;
425
426 /* First pass. Gather attribs that have overriden index slots. */
427 for (i = 0; i < tbl->count; i++)
428 if (tbl->entries[i].access == slang_exp_attribute &&
429 !entry_has_gl_prefix (tbl->entries[i].quant.name, tbl->atoms))
430 {
431 slang_export_data_quant *quant = &tbl->entries[i].quant;
432 const GLchar *id = slang_atom_pool_id (tbl->atoms, quant->name);
433 GLuint index = lookup_attrib_override (ovr, id);
434
435 if (index != MAX_VERTEX_ATTRIBS)
436 {
437 if (!add_attrib_binding (self, quant, id, tbl->entries[i].address, index))
438 return GL_FALSE;
439 }
440 }
441
442 /* Second pass. Gather attribs that have *NOT* overriden index slots. */
443 for (i = 0; i < tbl->count; i++)
444 if (tbl->entries[i].access == slang_exp_attribute &&
445 !entry_has_gl_prefix (tbl->entries[i].quant.name, tbl->atoms))
446 {
447 slang_export_data_quant *quant = &tbl->entries[i].quant;
448 const GLchar *id = slang_atom_pool_id (tbl->atoms, quant->name);
449 GLuint index = lookup_attrib_override (ovr, id);
450
451 if (index == MAX_VERTEX_ATTRIBS)
452 {
453 if (!add_attrib_binding (self, quant, id, tbl->entries[i].address, index))
454 return GL_FALSE;
455 }
456 }
457
458 return GL_TRUE;
459 }
460
461 /*
462 * slang_varying_bindings
463 */
464
465 static GLvoid slang_varying_bindings_ctr (slang_varying_bindings *self)
466 {
467 self->binding_count = 0;
468 self->slot_count = 0;
469 }
470
471 static GLvoid slang_varying_bindings_dtr (slang_varying_bindings *self)
472 {
473 GLuint i;
474
475 for (i = 0; i < self->binding_count; i++)
476 slang_alloc_free (self->bindings[i].name);
477 }
478
479 static GLvoid update_varying_slots (slang_varying_slot *slots, GLuint count, GLboolean is_vert,
480 GLuint addr, GLuint do_offset)
481 {
482 GLuint i;
483
484 for (i = 0; i < count; i++)
485 *(is_vert ? &slots[i].vert_addr : &slots[i].frag_addr) = addr + i * 4 * do_offset;
486 }
487
488 static GLboolean add_varying_binding (slang_varying_bindings *self,
489 slang_export_data_quant *q, const char *name, GLboolean is_vert, GLuint addr)
490 {
491 const GLuint n = self->binding_count;
492 const GLuint slot_span =
493 slang_export_data_quant_components (q) * slang_export_data_quant_elements (q);
494 GLuint i;
495
496 for (i = 0; i < n; i++)
497 if (slang_string_compare (self->bindings[i].name, name) == 0)
498 {
499 /* TODO: data quantities must match, or else link fails */
500 update_varying_slots (&self->slots[self->bindings[i].first_slot_index], slot_span,
501 is_vert, addr, 1);
502 return GL_TRUE;
503 }
504
505 if (self->slot_count + slot_span > MAX_VARYING_FLOATS)
506 {
507 /* TODO: info log: error: MAX_VARYING_FLOATS exceeded */
508 return GL_FALSE;
509 }
510
511 self->bindings[n].quant = q;
512 self->bindings[n].name = slang_string_duplicate (name);
513 if (self->bindings[n].name == NULL)
514 return GL_FALSE;
515 self->bindings[n].first_slot_index = self->slot_count;
516 self->binding_count++;
517
518 update_varying_slots (&self->slots[self->bindings[n].first_slot_index], slot_span, is_vert,
519 addr, 1);
520 update_varying_slots (&self->slots[self->bindings[n].first_slot_index], slot_span, !is_vert,
521 ~0, 0);
522 self->slot_count += slot_span;
523
524 return GL_TRUE;
525 }
526
527 static GLboolean gather_varying_bindings (slang_varying_bindings *self,
528 slang_export_data_table *tbl, GLboolean is_vert)
529 {
530 GLuint i;
531
532 for (i = 0; i < tbl->count; i++)
533 if (tbl->entries[i].access == slang_exp_varying &&
534 !entry_has_gl_prefix (tbl->entries[i].quant.name, tbl->atoms))
535 {
536 if (!add_varying_binding (self, &tbl->entries[i].quant, slang_atom_pool_id (tbl->atoms,
537 tbl->entries[i].quant.name), is_vert, tbl->entries[i].address))
538 return GL_FALSE;
539 }
540
541 return GL_TRUE;
542 }
543
544 /*
545 * slang_texture_bindings
546 */
547
548 GLvoid slang_texture_usages_ctr (slang_texture_usages *self)
549 {
550 self->table = NULL;
551 self->count = 0;
552 }
553
554 GLvoid slang_texture_usages_dtr (slang_texture_usages *self)
555 {
556 slang_alloc_free (self->table);
557 }
558
559 /*
560 * slang_program
561 */
562
563 GLvoid slang_program_ctr (slang_program *self)
564 {
565 GLuint i;
566
567 slang_active_variables_ctr (&self->active_uniforms);
568 slang_active_variables_ctr (&self->active_attribs);
569 slang_attrib_overrides_ctr (&self->attrib_overrides);
570 slang_uniform_bindings_ctr (&self->uniforms);
571 slang_attrib_bindings_ctr (&self->attribs);
572 slang_varying_bindings_ctr (&self->varyings);
573 slang_texture_usages_ctr (&self->texture_usage);
574 for (i = 0; i < SLANG_SHADER_MAX; i++)
575 {
576 GLuint j;
577
578 for (j = 0; j < SLANG_COMMON_FIXED_MAX; j++)
579 self->common_fixed_entries[i][j] = ~0;
580 for (j = 0; j < SLANG_COMMON_CODE_MAX; j++)
581 self->code[i][j] = ~0;
582 self->machines[i] = NULL;
583 self->assemblies[i] = NULL;
584 }
585 for (i = 0; i < SLANG_VERTEX_FIXED_MAX; i++)
586 self->vertex_fixed_entries[i] = ~0;
587 for (i = 0; i < SLANG_FRAGMENT_FIXED_MAX; i++)
588 self->fragment_fixed_entries[i] = ~0;
589 }
590
591 GLvoid slang_program_dtr (slang_program *self)
592 {
593 slang_active_variables_dtr (&self->active_uniforms);
594 slang_active_variables_dtr (&self->active_attribs);
595 slang_attrib_overrides_dtr (&self->attrib_overrides);
596 slang_uniform_bindings_dtr (&self->uniforms);
597 slang_attrib_bindings_dtr (&self->attribs);
598 slang_varying_bindings_dtr (&self->varyings);
599 slang_texture_usages_dtr (&self->texture_usage);
600 }
601
602 GLvoid slang_program_rst (slang_program *self)
603 {
604 GLuint i;
605
606 slang_active_variables_dtr (&self->active_uniforms);
607 slang_active_variables_dtr (&self->active_attribs);
608 slang_uniform_bindings_dtr (&self->uniforms);
609 slang_attrib_bindings_dtr (&self->attribs);
610 slang_varying_bindings_dtr (&self->varyings);
611 slang_texture_usages_dtr (&self->texture_usage);
612
613 slang_active_variables_ctr (&self->active_uniforms);
614 slang_active_variables_ctr (&self->active_attribs);
615 slang_uniform_bindings_ctr (&self->uniforms);
616 slang_attrib_bindings_ctr (&self->attribs);
617 slang_varying_bindings_ctr (&self->varyings);
618 slang_texture_usages_ctr (&self->texture_usage);
619 for (i = 0; i < SLANG_SHADER_MAX; i++)
620 {
621 GLuint j;
622
623 for (j = 0; j < SLANG_COMMON_FIXED_MAX; j++)
624 self->common_fixed_entries[i][j] = ~0;
625 for (j = 0; j < SLANG_COMMON_CODE_MAX; j++)
626 self->code[i][j] = ~0;
627 }
628 for (i = 0; i < SLANG_VERTEX_FIXED_MAX; i++)
629 self->vertex_fixed_entries[i] = ~0;
630 for (i = 0; i < SLANG_FRAGMENT_FIXED_MAX; i++)
631 self->fragment_fixed_entries[i] = ~0;
632 }
633
634 /*
635 * _slang_link()
636 */
637
638 static GLuint gd (slang_export_data_table *tbl, const char *name)
639 {
640 slang_atom atom;
641 GLuint i;
642
643 atom = slang_atom_pool_atom (tbl->atoms, name);
644 if (atom == SLANG_ATOM_NULL)
645 return ~0;
646
647 for (i = 0; i < tbl->count; i++)
648 if (atom == tbl->entries[i].quant.name)
649 return tbl->entries[i].address;
650 return ~0;
651 }
652
653 static GLvoid resolve_common_fixed (GLuint e[], slang_export_data_table *tbl)
654 {
655 e[SLANG_COMMON_FIXED_MODELVIEWMATRIX] = gd (tbl, "gl_ModelViewMatrix");
656 e[SLANG_COMMON_FIXED_PROJECTIONMATRIX] = gd (tbl, "gl_ProjectionMatrix");
657 e[SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIX] = gd (tbl, "gl_ModelViewProjectionMatrix");
658 e[SLANG_COMMON_FIXED_TEXTUREMATRIX] = gd (tbl, "gl_TextureMatrix");
659 e[SLANG_COMMON_FIXED_NORMALMATRIX] = gd (tbl, "gl_NormalMatrix");
660 e[SLANG_COMMON_FIXED_MODELVIEWMATRIXINVERSE] = gd (tbl, "gl_ModelViewMatrixInverse");
661 e[SLANG_COMMON_FIXED_PROJECTIONMATRIXINVERSE] = gd (tbl, "gl_ProjectionMatrixInverse");
662 e[SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXINVERSE] =
663 gd (tbl, "gl_ModelViewProjectionMatrixInverse");
664 e[SLANG_COMMON_FIXED_TEXTUREMATRIXINVERSE] = gd (tbl, "gl_TextureMatrixInverse");
665 e[SLANG_COMMON_FIXED_MODELVIEWMATRIXTRANSPOSE] = gd (tbl, "gl_ModelViewMatrixTranspose");
666 e[SLANG_COMMON_FIXED_PROJECTIONMATRIXTRANSPOSE] = gd (tbl, "gl_ProjectionMatrixTranspose");
667 e[SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXTRANSPOSE] =
668 gd (tbl, "gl_ModelViewProjectionMatrixTranspose");
669 e[SLANG_COMMON_FIXED_TEXTUREMATRIXTRANSPOSE] = gd (tbl, "gl_TextureMatrixTranspose");
670 e[SLANG_COMMON_FIXED_MODELVIEWMATRIXINVERSETRANSPOSE] =
671 gd (tbl, "gl_ModelViewMatrixInverseTranspose");
672 e[SLANG_COMMON_FIXED_PROJECTIONMATRIXINVERSETRANSPOSE] =
673 gd (tbl, "gl_ProjectionMatrixInverseTranspose");
674 e[SLANG_COMMON_FIXED_MODELVIEWPROJECTIONMATRIXINVERSETRANSPOSE] =
675 gd (tbl, "gl_ModelViewProjectionMatrixInverseTranspose");
676 e[SLANG_COMMON_FIXED_TEXTUREMATRIXINVERSETRANSPOSE] =
677 gd (tbl, "gl_TextureMatrixInverseTranspose");
678 e[SLANG_COMMON_FIXED_NORMALSCALE] = gd (tbl, "gl_NormalScale");
679 e[SLANG_COMMON_FIXED_DEPTHRANGE] = gd (tbl, "gl_DepthRange");
680 e[SLANG_COMMON_FIXED_CLIPPLANE] = gd (tbl, "gl_ClipPlane");
681 e[SLANG_COMMON_FIXED_POINT] = gd (tbl, "gl_Point");
682 e[SLANG_COMMON_FIXED_FRONTMATERIAL] = gd (tbl, "gl_FrontMaterial");
683 e[SLANG_COMMON_FIXED_BACKMATERIAL] = gd (tbl, "gl_BackMaterial");
684 e[SLANG_COMMON_FIXED_LIGHTSOURCE] = gd (tbl, "gl_LightSource");
685 e[SLANG_COMMON_FIXED_LIGHTMODEL] = gd (tbl, "gl_LightModel");
686 e[SLANG_COMMON_FIXED_FRONTLIGHTMODELPRODUCT] = gd (tbl, "gl_FrontLightModelProduct");
687 e[SLANG_COMMON_FIXED_BACKLIGHTMODELPRODUCT] = gd (tbl, "gl_BackLightModelProduct");
688 e[SLANG_COMMON_FIXED_FRONTLIGHTPRODUCT] = gd (tbl, "gl_FrontLightProduct");
689 e[SLANG_COMMON_FIXED_BACKLIGHTPRODUCT] = gd (tbl, "gl_BackLightProduct");
690 e[SLANG_COMMON_FIXED_TEXTUREENVCOLOR] = gd (tbl, "gl_TextureEnvColor");
691 e[SLANG_COMMON_FIXED_EYEPLANES] = gd (tbl, "gl_EyePlaneS");
692 e[SLANG_COMMON_FIXED_EYEPLANET] = gd (tbl, "gl_EyePlaneT");
693 e[SLANG_COMMON_FIXED_EYEPLANER] = gd (tbl, "gl_EyePlaneR");
694 e[SLANG_COMMON_FIXED_EYEPLANEQ] = gd (tbl, "gl_EyePlaneQ");
695 e[SLANG_COMMON_FIXED_OBJECTPLANES] = gd (tbl, "gl_ObjectPlaneS");
696 e[SLANG_COMMON_FIXED_OBJECTPLANET] = gd (tbl, "gl_ObjectPlaneT");
697 e[SLANG_COMMON_FIXED_OBJECTPLANER] = gd (tbl, "gl_ObjectPlaneR");
698 e[SLANG_COMMON_FIXED_OBJECTPLANEQ] = gd (tbl, "gl_ObjectPlaneQ");
699 e[SLANG_COMMON_FIXED_FOG] = gd (tbl, "gl_Fog");
700 }
701
702 static GLvoid resolve_vertex_fixed (GLuint e[], slang_export_data_table *tbl)
703 {
704 e[SLANG_VERTEX_FIXED_POSITION] = gd (tbl, "gl_Position");
705 e[SLANG_VERTEX_FIXED_POINTSIZE] = gd (tbl, "gl_PointSize");
706 e[SLANG_VERTEX_FIXED_CLIPVERTEX] = gd (tbl, "gl_ClipVertex");
707 e[SLANG_VERTEX_FIXED_COLOR] = gd (tbl, "gl_Color");
708 e[SLANG_VERTEX_FIXED_SECONDARYCOLOR] = gd (tbl, "gl_SecondaryColor");
709 e[SLANG_VERTEX_FIXED_NORMAL] = gd (tbl, "gl_Normal");
710 e[SLANG_VERTEX_FIXED_VERTEX] = gd (tbl, "gl_Vertex");
711 e[SLANG_VERTEX_FIXED_MULTITEXCOORD0] = gd (tbl, "gl_MultiTexCoord0");
712 e[SLANG_VERTEX_FIXED_MULTITEXCOORD1] = gd (tbl, "gl_MultiTexCoord1");
713 e[SLANG_VERTEX_FIXED_MULTITEXCOORD2] = gd (tbl, "gl_MultiTexCoord2");
714 e[SLANG_VERTEX_FIXED_MULTITEXCOORD3] = gd (tbl, "gl_MultiTexCoord3");
715 e[SLANG_VERTEX_FIXED_MULTITEXCOORD4] = gd (tbl, "gl_MultiTexCoord4");
716 e[SLANG_VERTEX_FIXED_MULTITEXCOORD5] = gd (tbl, "gl_MultiTexCoord5");
717 e[SLANG_VERTEX_FIXED_MULTITEXCOORD6] = gd (tbl, "gl_MultiTexCoord6");
718 e[SLANG_VERTEX_FIXED_MULTITEXCOORD7] = gd (tbl, "gl_MultiTexCoord7");
719 e[SLANG_VERTEX_FIXED_FOGCOORD] = gd (tbl, "gl_FogCoord");
720 e[SLANG_VERTEX_FIXED_FRONTCOLOR] = gd (tbl, "gl_FrontColor");
721 e[SLANG_VERTEX_FIXED_BACKCOLOR] = gd (tbl, "gl_BackColor");
722 e[SLANG_VERTEX_FIXED_FRONTSECONDARYCOLOR] = gd (tbl, "gl_FrontSecondaryColor");
723 e[SLANG_VERTEX_FIXED_BACKSECONDARYCOLOR] = gd (tbl, "gl_BackSecondaryColor");
724 e[SLANG_VERTEX_FIXED_TEXCOORD] = gd (tbl, "gl_TexCoord");
725 e[SLANG_VERTEX_FIXED_FOGFRAGCOORD] = gd (tbl, "gl_FogFragCoord");
726 }
727
728 static GLvoid resolve_fragment_fixed (GLuint e[], slang_export_data_table *tbl)
729 {
730 e[SLANG_FRAGMENT_FIXED_FRAGCOORD] = gd (tbl, "gl_FragCoord");
731 e[SLANG_FRAGMENT_FIXED_FRONTFACING] = gd (tbl, "gl_FrontFacing");
732 e[SLANG_FRAGMENT_FIXED_FRAGCOLOR] = gd (tbl, "gl_FragColor");
733 e[SLANG_FRAGMENT_FIXED_FRAGDATA] = gd (tbl, "gl_FragData");
734 e[SLANG_FRAGMENT_FIXED_FRAGDEPTH] = gd (tbl, "gl_FragDepth");
735 e[SLANG_FRAGMENT_FIXED_COLOR] = gd (tbl, "gl_Color");
736 e[SLANG_FRAGMENT_FIXED_SECONDARYCOLOR] = gd (tbl, "gl_SecondaryColor");
737 e[SLANG_FRAGMENT_FIXED_TEXCOORD] = gd (tbl, "gl_TexCoord");
738 e[SLANG_FRAGMENT_FIXED_FOGFRAGCOORD] = gd (tbl, "gl_FogFragCoord");
739 }
740
741 static GLuint gc (slang_export_code_table *tbl, const char *name)
742 {
743 slang_atom atom;
744 GLuint i;
745
746 atom = slang_atom_pool_atom (tbl->atoms, name);
747 if (atom == SLANG_ATOM_NULL)
748 return ~0;
749
750 for (i = 0; i < tbl->count; i++)
751 if (atom == tbl->entries[i].name)
752 return tbl->entries[i].address;
753 return ~0;
754 }
755
756 static GLvoid resolve_common_code (GLuint code[], slang_export_code_table *tbl)
757 {
758 code[SLANG_COMMON_CODE_MAIN] = gc (tbl, "@main");
759 }
760
761 GLboolean
762 _slang_link (slang_program *prog, slang_code_object **objects, GLuint count)
763 {
764 GLuint i;
765
766 for (i = 0; i < count; i++)
767 {
768 GLuint index;
769
770 if (objects[i]->unit.type == slang_unit_fragment_shader) {
771 index = SLANG_SHADER_FRAGMENT;
772 resolve_fragment_fixed (prog->fragment_fixed_entries, &objects[i]->expdata);
773 }
774 else
775 {
776 index = SLANG_SHADER_VERTEX;
777 resolve_vertex_fixed (prog->vertex_fixed_entries, &objects[i]->expdata);
778 if (!gather_attrib_bindings (&prog->attribs, &objects[i]->expdata,
779 &prog->attrib_overrides))
780 return GL_FALSE;
781 }
782
783 if (!gather_active_variables (&prog->active_uniforms, &objects[i]->expdata, slang_exp_uniform))
784 return GL_FALSE;
785 if (!gather_active_variables (&prog->active_attribs, &objects[i]->expdata, slang_exp_attribute))
786 return GL_FALSE;
787 if (!gather_uniform_bindings (&prog->uniforms, &objects[i]->expdata, index))
788 return GL_FALSE;
789 if (!gather_varying_bindings (&prog->varyings, &objects[i]->expdata,
790 index == SLANG_SHADER_VERTEX))
791 return GL_FALSE;
792 resolve_common_fixed (prog->common_fixed_entries[index], &objects[i]->expdata);
793 resolve_common_code (prog->code[index], &objects[i]->expcode);
794 prog->machines[index] = &objects[i]->machine;
795 prog->assemblies[index] = &objects[i]->assembly;
796 }
797
798 /* TODO: all varyings read by fragment shader must be written by vertex shader */
799
800 if (!_slang_analyse_texture_usage (prog))
801 return GL_FALSE;
802
803 return GL_TRUE;
804 }
805