2 * Mesa 3-D graphics library
5 * Copyright (C) 2006 Brian Paul All Rights Reserved.
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:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
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.
32 #include "slang_link.h"
33 #include "slang_analyse.h"
35 #define TABLE_GROW(PTR,TYPE,N) \
36 (PTR = (TYPE *) (slang_alloc_realloc (PTR, N * sizeof (TYPE), (N + 1) * sizeof (TYPE))))
39 * Check if a given name starts with "gl_". Globals with this prefix are
40 * treated differently, as they are built-in variables.
43 entry_has_gl_prefix (slang_atom name
, slang_atom_pool
*atoms
)
47 str
= slang_atom_pool_id (atoms
, name
);
48 return str
[0] == 'g' && str
[1] == 'l' && str
[2] == '_';
52 * slang_active_variables
56 slang_active_variables_ctr (slang_active_variables
*self
)
63 slang_active_variables_dtr (slang_active_variables
*self
)
67 for (i
= 0; i
< self
->count
; i
++)
68 slang_alloc_free (self
->table
[i
].name
);
69 slang_alloc_free (self
->table
);
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
79 add_simple_variable (slang_active_variables
*self
, slang_export_data_quant
*q
, const GLchar
*name
)
82 slang_active_variable
*var
;
85 if (!TABLE_GROW(self
->table
, slang_active_variable
, n
))
88 /* Initialize the new element. Increment table size only when it is fully initilized. */
89 var
= &self
->table
[n
];
91 var
->name
= slang_string_duplicate (name
);
92 if (var
->name
== NULL
)
100 add_complex_variable (slang_active_variables
*self
, slang_export_data_quant
*q
, GLchar
*name
,
101 slang_atom_pool
*atoms
)
103 slang_string_concat (name
, slang_atom_pool_id (atoms
, q
->name
));
105 /* If array, add only first element. */
106 if (slang_export_data_quant_array (q
))
107 slang_string_concat (name
, "[0]");
109 if (slang_export_data_quant_struct (q
)) {
110 GLuint field_pos
, fields
, i
;
112 slang_string_concat (name
, ".");
113 field_pos
= slang_string_length (name
);
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
))
120 name
[field_pos
] = '\0';
126 return add_simple_variable (self
, q
, name
);
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.
134 gather_active_variables (slang_active_variables
*self
, slang_export_data_table
*tbl
,
135 slang_export_data_access access
)
139 for (i
= 0; i
< tbl
->count
; i
++) {
140 if (tbl
->entries
[i
].access
== access
) {
141 GLchar name
[1024] = "";
143 if (!add_complex_variable (self
, &tbl
->entries
[i
].quant
, name
, tbl
->atoms
))
152 * slang_attrib_overrides
156 slang_attrib_overrides_ctr (slang_attrib_overrides
*self
)
163 slang_attrib_overrides_dtr (slang_attrib_overrides
*self
)
167 for (i
= 0; i
< self
->count
; i
++)
168 slang_alloc_free (self
->table
[i
].name
);
169 slang_alloc_free (self
->table
);
172 static slang_attrib_override
*
173 lookup_attrib_override (slang_attrib_overrides
*self
, const GLchar
*name
)
178 for (i
= 0; i
< n
; i
++) {
179 if (slang_string_compare (name
, self
->table
[i
].name
) == 0)
180 return &self
->table
[i
];
186 _slang_attrib_overrides_add (slang_attrib_overrides
*self
, GLuint index
, const GLchar
*name
)
188 slang_attrib_override
*ovr
;
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
);
200 if (!TABLE_GROW(self
->table
, slang_attrib_override
, n
))
203 /* Initialize the new element. Increment table size only when it is fully initilized. */
204 ovr
= &self
->table
[n
];
206 ovr
->name
= slang_string_duplicate (name
);
207 if (ovr
->name
== NULL
)
215 * slang_uniform_bindings
219 slang_uniform_bindings_ctr (slang_uniform_bindings
*self
)
226 slang_uniform_bindings_dtr (slang_uniform_bindings
*self
)
230 for (i
= 0; i
< self
->count
; i
++)
231 slang_alloc_free (self
->table
[i
].name
);
232 slang_alloc_free (self
->table
);
236 add_simple_uniform_binding (slang_uniform_bindings
*self
, slang_export_data_quant
*q
,
237 const GLchar
*name
, GLuint index
, GLuint addr
)
240 slang_uniform_binding
*bind
;
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
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
;
254 if (!TABLE_GROW(self
->table
, slang_uniform_binding
, n
))
257 /* Initialize the new element. Increment table size only when it is fully initilized. */
258 bind
= &self
->table
[n
];
260 bind
->name
= slang_string_duplicate (name
);
261 if (bind
->name
== NULL
)
263 for (i
= 0; i
< SLANG_SHADER_MAX
; i
++)
264 bind
->address
[i
] = ~0;
265 bind
->address
[index
] = addr
;
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
)
277 slang_string_concat (name
, slang_atom_pool_id (atoms
, q
->name
));
278 count
= slang_export_data_quant_elements (q
);
280 /* If array, add binding for every array element. */
281 for (i
= 0; i
< count
; i
++) {
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
);
288 if (slang_export_data_quant_struct (q
)) {
289 GLuint field_pos
, fields
, i
;
291 slang_string_concat (name
, ".");
292 field_pos
= slang_string_length (name
);
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
))
300 name
[field_pos
] = '\0';
301 addr
+= slang_export_data_quant_size (&q
->structure
[i
]);
305 if (!add_simple_uniform_binding (self
, q
, name
, index
, addr
))
308 addr
+= slang_export_data_quant_size (q
);
311 name
[bracket_pos
] = '\0';
318 gather_uniform_bindings (slang_uniform_bindings
*self
, slang_export_data_table
*tbl
, GLuint index
)
323 for (i
= 0; i
< n
; i
++) {
324 if (tbl
->entries
[i
].access
== slang_exp_uniform
) {
325 GLchar name
[1024] = "";
327 if (!add_complex_uniform_binding (self
, &tbl
->entries
[i
].quant
, name
, tbl
->atoms
, index
,
328 tbl
->entries
[i
].address
))
337 * slang_attrib_bindings
341 slang_attrib_bindings_ctr (slang_attrib_bindings
*self
)
345 self
->binding_count
= 0;
346 for (i
= 0; i
< MAX_VERTEX_ATTRIBS
; i
++)
347 self
->slots
[i
].addr
= ~0;
351 slang_attrib_bindings_dtr (slang_attrib_bindings
*self
)
355 for (i
= 0; i
< self
->binding_count
; i
++)
356 slang_alloc_free (self
->bindings
[i
].name
);
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.
366 can_allocate_attrib_slots (slang_attrib_bindings
*self
, GLuint index
, GLuint count
)
370 for (i
= 0; i
< count
; i
++) {
371 if (self
->slots
[index
+ i
].addr
!= ~0)
378 allocate_attrib_slots (slang_attrib_bindings
*self
, GLuint count
)
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
++) {
387 size
= can_allocate_attrib_slots (self
, i
, count
);
391 /* Speed-up the search a bit. */
395 return MAX_VERTEX_ATTRIBS
;
399 add_attrib_binding (slang_attrib_bindings
*self
, slang_export_data_quant
*q
, const GLchar
*name
,
400 GLuint addr
, GLuint index_override
)
402 GLuint slot_span
, slot_fill
, slot_index
, i
;
403 slang_attrib_binding
*bind
;
405 assert (slang_export_data_quant_simple (q
));
407 switch (slang_export_data_quant_type (q
)) {
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
;
445 slot_index
= MAX_VERTEX_ATTRIBS
;
447 if (slot_index
== MAX_VERTEX_ATTRIBS
) {
448 /* TODO: info log: error: MAX_VERTEX_ATTRIBS exceeded */
452 /* Initialize the new element. Increment table size only when it is fully initilized. */
453 bind
= &self
->bindings
[self
->binding_count
];
455 bind
->name
= slang_string_duplicate (name
);
456 if (bind
->name
== NULL
)
458 bind
->first_slot_index
= slot_index
;
459 self
->binding_count
++;
461 for (i
= 0; i
< slot_span
; i
++) {
462 slang_attrib_slot
*slot
;
464 slot
= &self
->slots
[bind
->first_slot_index
+ i
];
465 slot
->addr
= addr
+ i
* slot_fill
* 4;
466 slot
->fill
= slot_fill
;
473 gather_attrib_bindings (slang_attrib_bindings
*self
, slang_export_data_table
*tbl
,
474 slang_attrib_overrides
*ovr
)
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
;
484 slang_attrib_override
*ao
;
486 quant
= &tbl
->entries
[i
].quant
;
487 id
= slang_atom_pool_id (tbl
->atoms
, quant
->name
);
488 ao
= lookup_attrib_override (ovr
, id
);
490 if (!add_attrib_binding (self
, quant
, id
, tbl
->entries
[i
].address
, ao
->index
))
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
;
502 slang_attrib_override
*ao
;
504 quant
= &tbl
->entries
[i
].quant
;
505 id
= slang_atom_pool_id (tbl
->atoms
, quant
->name
);
506 ao
= lookup_attrib_override (ovr
, id
);
508 if (!add_attrib_binding (self
, quant
, id
, tbl
->entries
[i
].address
, ao
->index
))
518 * slang_varying_bindings
522 slang_varying_bindings_ctr (slang_varying_bindings
*self
)
524 self
->binding_count
= 0;
525 self
->slot_count
= 0;
529 slang_varying_bindings_dtr (slang_varying_bindings
*self
)
533 for (i
= 0; i
< self
->binding_count
; i
++)
534 slang_alloc_free (self
->bindings
[i
].name
);
538 update_varying_slots (slang_varying_slot
*slots
, GLuint count
, GLboolean is_vert
, GLuint addr
,
543 for (i
= 0; i
< count
; i
++) {
545 slots
[i
].vert_addr
= addr
+ i
* 4 * do_offset
;
547 slots
[i
].frag_addr
= addr
+ i
* 4 * do_offset
;
552 add_varying_binding (slang_varying_bindings
*self
, slang_export_data_quant
*q
, const GLchar
*name
,
553 GLboolean is_vert
, GLuint addr
)
555 GLuint n
, slot_span
, i
;
556 slang_varying_binding
*bind
;
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
,
569 if (self
->slot_count
+ slot_span
> MAX_VARYING_FLOATS
) {
570 /* TODO: info log: error: MAX_VARYING_FLOATS exceeded */
574 /* Initialize the new element. Increment table size only when it is fully initilized. */
575 bind
= &self
->bindings
[n
];
577 bind
->name
= slang_string_duplicate (name
);
578 if (bind
->name
== NULL
)
580 bind
->first_slot_index
= self
->slot_count
;
581 self
->binding_count
++;
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
;
591 gather_varying_bindings (slang_varying_bindings
*self
, slang_export_data_table
*tbl
,
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
))
610 * slang_texture_bindings
614 _slang_texture_usages_ctr (slang_texture_usages
*self
)
621 _slang_texture_usages_dtr (slang_texture_usages
*self
)
623 slang_alloc_free (self
->table
);
631 _slang_program_ctr (slang_program
*self
)
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
++) {
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
;
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;
659 _slang_program_dtr (slang_program
*self
)
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
);
671 _slang_program_rst (slang_program
*self
)
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
);
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
++) {
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;
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;
707 gd (slang_export_data_table
*tbl
, const GLchar
*name
)
712 atom
= slang_atom_pool_atom (tbl
->atoms
, name
);
713 if (atom
== SLANG_ATOM_NULL
)
716 for (i
= 0; i
< tbl
->count
; i
++) {
717 if (atom
== tbl
->entries
[i
].quant
.name
)
718 return tbl
->entries
[i
].address
;
724 resolve_common_fixed (GLuint e
[], slang_export_data_table
*tbl
)
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");
768 resolve_vertex_fixed (GLuint e
[], slang_export_data_table
*tbl
)
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");
795 resolve_fragment_fixed (GLuint e
[], slang_export_data_table
*tbl
)
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");
809 gc (slang_export_code_table
*tbl
, const GLchar
*name
)
814 atom
= slang_atom_pool_atom (tbl
->atoms
, name
);
815 if (atom
== SLANG_ATOM_NULL
)
818 for (i
= 0; i
< tbl
->count
; i
++) {
819 if (atom
== tbl
->entries
[i
].name
)
820 return tbl
->entries
[i
].address
;
826 resolve_common_code (GLuint code
[], slang_export_code_table
*tbl
)
828 code
[SLANG_COMMON_CODE_MAIN
] = gc (tbl
, "@main");
832 _slang_link (slang_program
*prog
, slang_code_object
**objects
, GLuint count
)
836 for (i
= 0; i
< count
; i
++) {
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
);
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
))
851 if (!gather_active_variables (&prog
->active_uniforms
, &objects
[i
]->expdata
, slang_exp_uniform
))
853 if (!gather_active_variables (&prog
->active_attribs
, &objects
[i
]->expdata
, slang_exp_attribute
))
855 if (!gather_uniform_bindings (&prog
->uniforms
, &objects
[i
]->expdata
, index
))
857 if (!gather_varying_bindings (&prog
->varyings
, &objects
[i
]->expdata
,
858 index
== SLANG_SHADER_VERTEX
))
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
;
866 /* TODO: all varyings read by fragment shader must be written by vertex shader */
868 if (!_slang_analyse_texture_usage (prog
))