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 static GLboolean
entry_has_gl_prefix (slang_atom name
, slang_atom_pool
*atoms
)
37 const char *str
= slang_atom_pool_id (atoms
, name
);
38 return str
[0] == 'g' && str
[1] == 'l' && str
[2] == '_';
42 * slang_active_variables
45 static GLvoid
slang_active_variables_ctr (slang_active_variables
*self
)
51 static GLvoid
slang_active_variables_dtr (slang_active_variables
*self
)
55 for (i
= 0; i
< self
->count
; i
++)
56 slang_alloc_free (self
->table
[i
].name
);
57 slang_alloc_free (self
->table
);
60 static GLboolean
add_simple_variable (slang_active_variables
*self
, slang_export_data_quant
*q
,
63 const GLuint n
= self
->count
;
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
)
70 self
->table
[n
].quant
= q
;
71 self
->table
[n
].name
= slang_string_duplicate (name
);
72 if (self
->table
[n
].name
== NULL
)
79 static GLboolean
add_complex_variable (slang_active_variables
*self
, slang_export_data_quant
*q
,
80 char *name
, slang_atom_pool
*atoms
)
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]");
86 if (slang_export_data_quant_struct (q
))
89 const GLuint fields
= slang_export_data_quant_fields (q
);
91 slang_string_concat (name
, ".");
92 dot_pos
= slang_string_length (name
);
94 for (i
= 0; i
< fields
; i
++)
96 if (!add_complex_variable (self
, &q
->structure
[i
], name
, atoms
))
105 return add_simple_variable (self
, q
, name
);
108 static GLboolean
gather_active_variables (slang_active_variables
*self
,
109 slang_export_data_table
*tbl
, slang_export_data_access access
)
113 for (i
= 0; i
< tbl
->count
; i
++)
114 if (tbl
->entries
[i
].access
== access
)
116 char name
[1024] = "";
118 if (!add_complex_variable (self
, &tbl
->entries
[i
].quant
, name
, tbl
->atoms
))
126 * slang_attrib_overrides
129 static GLvoid
slang_attrib_overrides_ctr (slang_attrib_overrides
*self
)
135 static GLvoid
slang_attrib_overrides_dtr (slang_attrib_overrides
*self
)
139 for (i
= 0; i
< self
->count
; i
++)
140 slang_alloc_free (self
->table
[i
].name
);
141 slang_alloc_free (self
->table
);
144 GLboolean
slang_attrib_overrides_add (slang_attrib_overrides
*self
, GLuint index
, const GLchar
*name
)
146 const GLuint n
= self
->count
;
149 for (i
= 0; i
< n
; i
++)
150 if (slang_string_compare (name
, self
->table
[i
].name
) == 0)
152 self
->table
[i
].index
= index
;
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
)
161 self
->table
[n
].index
= index
;
162 self
->table
[n
].name
= slang_string_duplicate (name
);
163 if (self
->table
[n
].name
== NULL
)
170 static GLuint
lookup_attrib_override (slang_attrib_overrides
*self
, const GLchar
*name
)
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
;
181 * slang_uniform_bindings
184 static GLvoid
slang_uniform_bindings_ctr (slang_uniform_bindings
*self
)
190 static GLvoid
slang_uniform_bindings_dtr (slang_uniform_bindings
*self
)
194 for (i
= 0; i
< self
->count
; i
++)
195 slang_alloc_free (self
->table
[i
].name
);
196 slang_alloc_free (self
->table
);
199 static GLboolean
add_simple_uniform_binding (slang_uniform_bindings
*self
,
200 slang_export_data_quant
*q
, const char *name
, GLuint index
, GLuint addr
)
202 const GLuint n
= self
->count
;
205 for (i
= 0; i
< n
; i
++)
206 if (slang_string_compare (self
->table
[i
].name
, name
) == 0)
208 self
->table
[i
].address
[index
] = addr
;
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
)
217 self
->table
[n
].quant
= q
;
218 self
->table
[n
].name
= slang_string_duplicate (name
);
219 if (self
->table
[n
].name
== NULL
)
221 for (i
= 0; i
< SLANG_SHADER_MAX
; i
++)
222 self
->table
[n
].address
[i
] = ~0;
223 self
->table
[n
].address
[index
] = addr
;
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
)
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
++)
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
);
244 if (slang_export_data_quant_struct (q
))
247 const GLuint fields
= slang_export_data_quant_fields (q
);
249 slang_string_concat (name
, ".");
250 dot_pos
= slang_string_length (name
);
252 for (i
= 0; i
< fields
; i
++)
254 if (!add_complex_uniform_binding (self
, &q
->structure
[i
], name
, atoms
, index
, addr
))
257 name
[dot_pos
] = '\0';
258 addr
+= slang_export_data_quant_size (&q
->structure
[i
]);
263 if (!add_simple_uniform_binding (self
, q
, name
, index
, addr
))
266 addr
+= slang_export_data_quant_size (q
);
269 name
[bracket_pos
] = '\0';
275 static GLboolean
gather_uniform_bindings (slang_uniform_bindings
*self
,
276 slang_export_data_table
*tbl
, GLuint index
)
280 for (i
= 0; i
< tbl
->count
; i
++)
281 if (tbl
->entries
[i
].access
== slang_exp_uniform
)
283 char name
[1024] = "";
285 if (!add_complex_uniform_binding (self
, &tbl
->entries
[i
].quant
, name
, tbl
->atoms
, index
,
286 tbl
->entries
[i
].address
))
294 * slang_attrib_bindings
297 static GLvoid
slang_attrib_bindings_ctr (slang_attrib_bindings
*self
)
301 self
->binding_count
= 0;
302 for (i
= 0; i
< MAX_VERTEX_ATTRIBS
; i
++)
303 self
->slots
[i
].addr
= ~0;
306 static GLvoid
slang_attrib_bindings_dtr (slang_attrib_bindings
*self
)
310 for (i
= 0; i
< self
->binding_count
; i
++)
311 slang_alloc_free (self
->bindings
[i
].name
);
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.
320 static GLuint
can_allocate_attrib_slots (slang_attrib_bindings
*self
, GLuint index
, GLuint count
)
324 for (i
= 0; i
< count
; i
++)
325 if (self
->slots
[index
+ i
].addr
!= ~0)
330 static GLuint
allocate_attrib_slots (slang_attrib_bindings
*self
, GLuint count
)
334 for (i
= 1; i
<= MAX_VERTEX_ATTRIBS
- count
; i
++)
338 size
= can_allocate_attrib_slots (self
, i
, count
);
342 /* speed-up the search a bit */
345 return MAX_VERTEX_ATTRIBS
;
349 add_attrib_binding (slang_attrib_bindings
*self
, slang_export_data_quant
*q
, const char *name
,
350 GLuint addr
, GLuint index_override
)
352 const GLuint n
= self
->binding_count
;
353 GLuint slot_span
, slot_fill
, slot_index
;
356 assert (slang_export_data_quant_simple (q
));
358 switch (slang_export_data_quant_type (q
))
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
;
397 slot_index
= MAX_VERTEX_ATTRIBS
;
399 if (slot_index
== MAX_VERTEX_ATTRIBS
)
401 /* TODO: info log: error: MAX_VERTEX_ATTRIBS exceeded */
405 self
->bindings
[n
].quant
= q
;
406 self
->bindings
[n
].name
= slang_string_duplicate (name
);
407 if (self
->bindings
[n
].name
== NULL
)
409 self
->bindings
[n
].first_slot_index
= slot_index
;
410 self
->binding_count
++;
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
;
421 static GLboolean
gather_attrib_bindings (slang_attrib_bindings
*self
, slang_export_data_table
*tbl
,
422 slang_attrib_overrides
*ovr
)
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
))
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
);
435 if (index
!= MAX_VERTEX_ATTRIBS
)
437 if (!add_attrib_binding (self
, quant
, id
, tbl
->entries
[i
].address
, index
))
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
))
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
);
451 if (index
== MAX_VERTEX_ATTRIBS
)
453 if (!add_attrib_binding (self
, quant
, id
, tbl
->entries
[i
].address
, index
))
462 * slang_varying_bindings
465 static GLvoid
slang_varying_bindings_ctr (slang_varying_bindings
*self
)
467 self
->binding_count
= 0;
468 self
->slot_count
= 0;
471 static GLvoid
slang_varying_bindings_dtr (slang_varying_bindings
*self
)
475 for (i
= 0; i
< self
->binding_count
; i
++)
476 slang_alloc_free (self
->bindings
[i
].name
);
479 static GLvoid
update_varying_slots (slang_varying_slot
*slots
, GLuint count
, GLboolean is_vert
,
480 GLuint addr
, GLuint do_offset
)
484 for (i
= 0; i
< count
; i
++)
485 *(is_vert
? &slots
[i
].vert_addr
: &slots
[i
].frag_addr
) = addr
+ i
* 4 * do_offset
;
488 static GLboolean
add_varying_binding (slang_varying_bindings
*self
,
489 slang_export_data_quant
*q
, const char *name
, GLboolean is_vert
, GLuint addr
)
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
);
496 for (i
= 0; i
< n
; i
++)
497 if (slang_string_compare (self
->bindings
[i
].name
, name
) == 0)
499 /* TODO: data quantities must match, or else link fails */
500 update_varying_slots (&self
->slots
[self
->bindings
[i
].first_slot_index
], slot_span
,
505 if (self
->slot_count
+ slot_span
> MAX_VARYING_FLOATS
)
507 /* TODO: info log: error: MAX_VARYING_FLOATS exceeded */
511 self
->bindings
[n
].quant
= q
;
512 self
->bindings
[n
].name
= slang_string_duplicate (name
);
513 if (self
->bindings
[n
].name
== NULL
)
515 self
->bindings
[n
].first_slot_index
= self
->slot_count
;
516 self
->binding_count
++;
518 update_varying_slots (&self
->slots
[self
->bindings
[n
].first_slot_index
], slot_span
, is_vert
,
520 update_varying_slots (&self
->slots
[self
->bindings
[n
].first_slot_index
], slot_span
, !is_vert
,
522 self
->slot_count
+= slot_span
;
527 static GLboolean
gather_varying_bindings (slang_varying_bindings
*self
,
528 slang_export_data_table
*tbl
, GLboolean is_vert
)
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
))
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
))
545 * slang_texture_bindings
548 GLvoid
slang_texture_usages_ctr (slang_texture_usages
*self
)
554 GLvoid
slang_texture_usages_dtr (slang_texture_usages
*self
)
556 slang_alloc_free (self
->table
);
563 GLvoid
slang_program_ctr (slang_program
*self
)
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
++)
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
;
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;
591 GLvoid
slang_program_dtr (slang_program
*self
)
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
);
602 GLvoid
slang_program_rst (slang_program
*self
)
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
);
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
++)
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;
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;
638 static GLuint
gd (slang_export_data_table
*tbl
, const char *name
)
643 atom
= slang_atom_pool_atom (tbl
->atoms
, name
);
644 if (atom
== SLANG_ATOM_NULL
)
647 for (i
= 0; i
< tbl
->count
; i
++)
648 if (atom
== tbl
->entries
[i
].quant
.name
)
649 return tbl
->entries
[i
].address
;
653 static GLvoid
resolve_common_fixed (GLuint e
[], slang_export_data_table
*tbl
)
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");
702 static GLvoid
resolve_vertex_fixed (GLuint e
[], slang_export_data_table
*tbl
)
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");
728 static GLvoid
resolve_fragment_fixed (GLuint e
[], slang_export_data_table
*tbl
)
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");
741 static GLuint
gc (slang_export_code_table
*tbl
, const char *name
)
746 atom
= slang_atom_pool_atom (tbl
->atoms
, name
);
747 if (atom
== SLANG_ATOM_NULL
)
750 for (i
= 0; i
< tbl
->count
; i
++)
751 if (atom
== tbl
->entries
[i
].name
)
752 return tbl
->entries
[i
].address
;
756 static GLvoid
resolve_common_code (GLuint code
[], slang_export_code_table
*tbl
)
758 code
[SLANG_COMMON_CODE_MAIN
] = gc (tbl
, "@main");
762 _slang_link (slang_program
*prog
, slang_code_object
**objects
, GLuint count
)
766 for (i
= 0; i
< count
; i
++)
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
);
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
))
783 if (!gather_active_variables (&prog
->active_uniforms
, &objects
[i
]->expdata
, slang_exp_uniform
))
785 if (!gather_active_variables (&prog
->active_attribs
, &objects
[i
]->expdata
, slang_exp_attribute
))
787 if (!gather_uniform_bindings (&prog
->uniforms
, &objects
[i
]->expdata
, index
))
789 if (!gather_varying_bindings (&prog
->varyings
, &objects
[i
]->expdata
,
790 index
== SLANG_SHADER_VERTEX
))
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
;
798 /* TODO: all varyings read by fragment shader must be written by vertex shader */
800 if (!_slang_analyse_texture_usage (prog
))