2 * Copyright © 2010 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
26 * GLSL linker implementation
28 * Given a set of shaders that are to be linked to generate a final program,
29 * there are three distinct stages.
31 * In the first stage shaders are partitioned into groups based on the shader
32 * type. All shaders of a particular type (e.g., vertex shaders) are linked
35 * - Undefined references in each shader are resolve to definitions in
37 * - Types and qualifiers of uniforms, outputs, and global variables defined
38 * in multiple shaders with the same name are verified to be the same.
39 * - Initializers for uniforms and global variables defined
40 * in multiple shaders with the same name are verified to be the same.
42 * The result, in the terminology of the GLSL spec, is a set of shader
43 * executables for each processing unit.
45 * After the first stage is complete, a series of semantic checks are performed
46 * on each of the shader executables.
48 * - Each shader executable must define a \c main function.
49 * - Each vertex shader executable must write to \c gl_Position.
50 * - Each fragment shader executable must write to either \c gl_FragData or
53 * In the final stage individual shader executables are linked to create a
54 * complete exectuable.
56 * - Types of uniforms defined in multiple shader stages with the same name
57 * are verified to be the same.
58 * - Initializers for uniforms defined in multiple shader stages with the
59 * same name are verified to be the same.
60 * - Types and qualifiers of outputs defined in one stage are verified to
61 * be the same as the types and qualifiers of inputs defined with the same
62 * name in a later stage.
64 * \author Ian Romanick <ian.d.romanick@intel.com>
74 #include "main/mtypes.h"
75 #include "glsl_symbol_table.h"
76 #include "glsl_parser_extras.h"
78 #include "ir_optimization.h"
81 #include "hash_table.h"
85 * Visitor that determines whether or not a variable is ever written.
87 class find_assignment_visitor
: public ir_hierarchical_visitor
{
89 find_assignment_visitor(const char *name
)
90 : name(name
), found(false)
95 virtual ir_visitor_status
visit_enter(ir_assignment
*ir
)
97 ir_variable
*const var
= ir
->lhs
->variable_referenced();
99 if (strcmp(name
, var
->name
) == 0) {
104 return visit_continue_with_parent
;
107 bool variable_found()
113 const char *name
; /**< Find writes to a variable with this name. */
114 bool found
; /**< Was a write to the variable found? */
119 linker_error_printf(glsl_program
*prog
, const char *fmt
, ...)
123 prog
->InfoLog
= talloc_strdup_append(prog
->InfoLog
, "error: ");
125 prog
->InfoLog
= talloc_vasprintf_append(prog
->InfoLog
, fmt
, ap
);
131 invalidate_variable_locations(glsl_shader
*sh
, enum ir_variable_mode mode
,
134 foreach_list(node
, &sh
->ir
) {
135 ir_variable
*const var
= ((ir_instruction
*) node
)->as_variable();
137 if ((var
== NULL
) || (var
->mode
!= (unsigned) mode
))
140 /* Only assign locations for generic attributes / varyings / etc.
142 if (var
->location
>= generic_base
)
149 * Determine the number of attribute slots required for a particular type
151 * This code is here because it implements the language rules of a specific
152 * GLSL version. Since it's a property of the language and not a property of
153 * types in general, it doesn't really belong in glsl_type.
156 count_attribute_slots(const glsl_type
*t
)
158 /* From page 31 (page 37 of the PDF) of the GLSL 1.50 spec:
160 * "A scalar input counts the same amount against this limit as a vec4,
161 * so applications may want to consider packing groups of four
162 * unrelated float inputs together into a vector to better utilize the
163 * capabilities of the underlying hardware. A matrix input will use up
164 * multiple locations. The number of locations used will equal the
165 * number of columns in the matrix."
167 * The spec does not explicitly say how arrays are counted. However, it
168 * should be safe to assume the total number of slots consumed by an array
169 * is the number of entries in the array multiplied by the number of slots
170 * consumed by a single element of the array.
174 return t
->array_size() * count_attribute_slots(t
->element_type());
177 return t
->matrix_columns
;
184 * Verify that a vertex shader executable meets all semantic requirements
186 * \param shader Vertex shader executable to be verified
189 validate_vertex_shader_executable(struct glsl_program
*prog
,
190 struct glsl_shader
*shader
)
195 if (!shader
->symbols
->get_function("main")) {
196 linker_error_printf(prog
, "vertex shader lacks `main'\n");
200 find_assignment_visitor
find("gl_Position");
201 find
.run(&shader
->ir
);
202 if (!find
.variable_found()) {
203 linker_error_printf(prog
,
204 "vertex shader does not write to `gl_Position'\n");
213 * Verify that a fragment shader executable meets all semantic requirements
215 * \param shader Fragment shader executable to be verified
218 validate_fragment_shader_executable(struct glsl_program
*prog
,
219 struct glsl_shader
*shader
)
224 if (!shader
->symbols
->get_function("main")) {
225 linker_error_printf(prog
, "fragment shader lacks `main'\n");
229 find_assignment_visitor
frag_color("gl_FragColor");
230 find_assignment_visitor
frag_data("gl_FragData");
232 frag_color
.run(&shader
->ir
);
233 frag_data
.run(&shader
->ir
);
235 if (!frag_color
.variable_found() && !frag_data
.variable_found()) {
236 linker_error_printf(prog
, "fragment shader does not write to "
237 "`gl_FragColor' or `gl_FragData'\n");
241 if (frag_color
.variable_found() && frag_data
.variable_found()) {
242 linker_error_printf(prog
, "fragment shader writes to both "
243 "`gl_FragColor' and `gl_FragData'\n");
252 * Perform validation of uniforms used across multiple shader stages
255 cross_validate_uniforms(struct glsl_program
*prog
)
257 /* Examine all of the uniforms in all of the shaders and cross validate
260 glsl_symbol_table uniforms
;
261 for (unsigned i
= 0; i
< prog
->_NumLinkedShaders
; i
++) {
262 foreach_list(node
, &prog
->_LinkedShaders
[i
]->ir
) {
263 ir_variable
*const var
= ((ir_instruction
*) node
)->as_variable();
265 if ((var
== NULL
) || (var
->mode
!= ir_var_uniform
))
268 /* If a uniform with this name has already been seen, verify that the
269 * new instance has the same type. In addition, if the uniforms have
270 * initializers, the values of the initializers must be the same.
272 ir_variable
*const existing
= uniforms
.get_variable(var
->name
);
273 if (existing
!= NULL
) {
274 if (var
->type
!= existing
->type
) {
275 linker_error_printf(prog
, "uniform `%s' declared as type "
276 "`%s' and type `%s'\n",
277 var
->name
, var
->type
->name
,
278 existing
->type
->name
);
282 if (var
->constant_value
!= NULL
) {
283 if (existing
->constant_value
!= NULL
) {
284 if (!var
->constant_value
->has_value(existing
->constant_value
)) {
285 linker_error_printf(prog
, "initializers for uniform "
286 "`%s' have differing values\n",
291 /* If the first-seen instance of a particular uniform did not
292 * have an initializer but a later instance does, copy the
293 * initializer to the version stored in the symbol table.
295 existing
->constant_value
=
296 (ir_constant
*)var
->constant_value
->clone(NULL
);
299 uniforms
.add_variable(var
->name
, var
);
308 * Validate that outputs from one stage match inputs of another
311 cross_validate_outputs_to_inputs(struct glsl_program
*prog
,
312 glsl_shader
*producer
, glsl_shader
*consumer
)
314 glsl_symbol_table parameters
;
315 /* FINISHME: Figure these out dynamically. */
316 const char *const producer_stage
= "vertex";
317 const char *const consumer_stage
= "fragment";
319 /* Find all shader outputs in the "producer" stage.
321 foreach_list(node
, &producer
->ir
) {
322 ir_variable
*const var
= ((ir_instruction
*) node
)->as_variable();
324 /* FINISHME: For geometry shaders, this should also look for inout
325 * FINISHME: variables.
327 if ((var
== NULL
) || (var
->mode
!= ir_var_out
))
330 parameters
.add_variable(var
->name
, var
);
334 /* Find all shader inputs in the "consumer" stage. Any variables that have
335 * matching outputs already in the symbol table must have the same type and
338 foreach_list(node
, &consumer
->ir
) {
339 ir_variable
*const input
= ((ir_instruction
*) node
)->as_variable();
341 /* FINISHME: For geometry shaders, this should also look for inout
342 * FINISHME: variables.
344 if ((input
== NULL
) || (input
->mode
!= ir_var_in
))
347 ir_variable
*const output
= parameters
.get_variable(input
->name
);
348 if (output
!= NULL
) {
349 /* Check that the types match between stages.
351 if (input
->type
!= output
->type
) {
352 linker_error_printf(prog
,
353 "%s shader output `%s' delcared as "
354 "type `%s', but %s shader input declared "
356 producer_stage
, output
->name
,
358 consumer_stage
, input
->type
->name
);
362 /* Check that all of the qualifiers match between stages.
364 if (input
->centroid
!= output
->centroid
) {
365 linker_error_printf(prog
,
366 "%s shader output `%s' %s centroid qualifier, "
367 "but %s shader input %s centroid qualifier\n",
370 (output
->centroid
) ? "has" : "lacks",
372 (input
->centroid
) ? "has" : "lacks");
376 if (input
->invariant
!= output
->invariant
) {
377 linker_error_printf(prog
,
378 "%s shader output `%s' %s invariant qualifier, "
379 "but %s shader input %s invariant qualifier\n",
382 (output
->invariant
) ? "has" : "lacks",
384 (input
->invariant
) ? "has" : "lacks");
388 if (input
->interpolation
!= output
->interpolation
) {
389 linker_error_printf(prog
,
390 "%s shader output `%s' specifies %s "
391 "interpolation qualifier, "
392 "but %s shader input specifies %s "
393 "interpolation qualifier\n",
396 output
->interpolation_string(),
398 input
->interpolation_string());
408 struct uniform_node
{
410 struct gl_uniform
*u
;
415 assign_uniform_locations(struct glsl_program
*prog
)
419 unsigned total_uniforms
= 0;
420 hash_table
*ht
= hash_table_ctor(32, hash_table_string_hash
,
421 hash_table_string_compare
);
423 for (unsigned i
= 0; i
< prog
->_NumLinkedShaders
; i
++) {
424 unsigned next_position
= 0;
426 foreach_list(node
, &prog
->_LinkedShaders
[i
]->ir
) {
427 ir_variable
*const var
= ((ir_instruction
*) node
)->as_variable();
429 if ((var
== NULL
) || (var
->mode
!= ir_var_uniform
))
432 const unsigned vec4_slots
= (var
->component_slots() + 3) / 4;
433 assert(vec4_slots
!= 0);
435 uniform_node
*n
= (uniform_node
*) hash_table_find(ht
, var
->name
);
437 n
= (uniform_node
*) calloc(1, sizeof(struct uniform_node
));
438 n
->u
= (gl_uniform
*) calloc(vec4_slots
, sizeof(struct gl_uniform
));
439 n
->slots
= vec4_slots
;
441 n
->u
[0].Name
= strdup(var
->name
);
442 for (unsigned j
= 1; j
< vec4_slots
; j
++)
443 n
->u
[j
].Name
= n
->u
[0].Name
;
445 hash_table_insert(ht
, n
, n
->u
[0].Name
);
446 uniforms
.push_tail(& n
->link
);
447 total_uniforms
+= vec4_slots
;
450 if (var
->constant_value
!= NULL
)
451 for (unsigned j
= 0; j
< vec4_slots
; j
++)
452 n
->u
[j
].Initialized
= true;
454 var
->location
= next_position
;
456 for (unsigned j
= 0; j
< vec4_slots
; j
++) {
457 switch (prog
->_LinkedShaders
[i
]->Type
) {
458 case GL_VERTEX_SHADER
:
459 n
->u
[j
].VertPos
= next_position
;
461 case GL_FRAGMENT_SHADER
:
462 n
->u
[j
].FragPos
= next_position
;
464 case GL_GEOMETRY_SHADER
:
465 /* FINISHME: Support geometry shaders. */
466 assert(prog
->_LinkedShaders
[i
]->Type
!= GL_GEOMETRY_SHADER
);
475 gl_uniform_list
*ul
= (gl_uniform_list
*)
476 calloc(1, sizeof(gl_uniform_list
));
478 ul
->Size
= total_uniforms
;
479 ul
->NumUniforms
= total_uniforms
;
480 ul
->Uniforms
= (gl_uniform
*) calloc(total_uniforms
, sizeof(gl_uniform
));
484 for (uniform_node
*node
= (uniform_node
*) uniforms
.head
485 ; node
->link
.next
!= NULL
487 next
= (uniform_node
*) node
->link
.next
;
490 memcpy(&ul
->Uniforms
[idx
], node
->u
, sizeof(gl_uniform
) * node
->slots
);
504 * Find a contiguous set of available bits in a bitmask
506 * \param used_mask Bits representing used (1) and unused (0) locations
507 * \param needed_count Number of contiguous bits needed.
510 * Base location of the available bits on success or -1 on failure.
513 find_available_slots(unsigned used_mask
, unsigned needed_count
)
515 unsigned needed_mask
= (1 << needed_count
) - 1;
516 const int max_bit_to_test
= (8 * sizeof(used_mask
)) - needed_count
;
518 /* The comparison to 32 is redundant, but without it GCC emits "warning:
519 * cannot optimize possibly infinite loops" for the loop below.
521 if ((needed_count
== 0) || (max_bit_to_test
< 0) || (max_bit_to_test
> 32))
524 for (int i
= 0; i
<= max_bit_to_test
; i
++) {
525 if ((needed_mask
& ~used_mask
) == needed_mask
)
536 assign_attribute_locations(glsl_program
*prog
, unsigned max_attribute_index
)
538 /* Mark invalid attribute locations as being used.
540 unsigned used_locations
= (max_attribute_index
>= 32)
541 ? ~0 : ~((1 << max_attribute_index
) - 1);
543 glsl_shader
*const sh
= prog
->_LinkedShaders
[0];
544 assert(sh
->Type
== GL_VERTEX_SHADER
);
546 /* Operate in a total of four passes.
548 * 1. Invalidate the location assignments for all vertex shader inputs.
550 * 2. Assign locations for inputs that have user-defined (via
551 * glBindVertexAttribLocation) locatoins.
553 * 3. Sort the attributes without assigned locations by number of slots
554 * required in decreasing order. Fragmentation caused by attribute
555 * locations assigned by the application may prevent large attributes
556 * from having enough contiguous space.
558 * 4. Assign locations to any inputs without assigned locations.
561 invalidate_variable_locations(sh
, ir_var_in
, VERT_ATTRIB_GENERIC0
);
563 if (prog
->Attributes
!= NULL
) {
564 for (unsigned i
= 0; i
< prog
->Attributes
->NumParameters
; i
++) {
565 ir_variable
*const var
=
566 sh
->symbols
->get_variable(prog
->Attributes
->Parameters
[i
].Name
);
568 /* Note: attributes that occupy multiple slots, such as arrays or
569 * matrices, may appear in the attrib array multiple times.
571 if ((var
== NULL
) || (var
->location
!= -1))
574 /* From page 61 of the OpenGL 4.0 spec:
576 * "LinkProgram will fail if the attribute bindings assigned by
577 * BindAttribLocation do not leave not enough space to assign a
578 * location for an active matrix attribute or an active attribute
579 * array, both of which require multiple contiguous generic
582 * Previous versions of the spec contain similar language but omit the
583 * bit about attribute arrays.
585 * Page 61 of the OpenGL 4.0 spec also says:
587 * "It is possible for an application to bind more than one
588 * attribute name to the same location. This is referred to as
589 * aliasing. This will only work if only one of the aliased
590 * attributes is active in the executable program, or if no path
591 * through the shader consumes more than one attribute of a set
592 * of attributes aliased to the same location. A link error can
593 * occur if the linker determines that every path through the
594 * shader consumes multiple aliased attributes, but
595 * implementations are not required to generate an error in this
598 * These two paragraphs are either somewhat contradictory, or I don't
599 * fully understand one or both of them.
601 /* FINISHME: The code as currently written does not support attribute
602 * FINISHME: location aliasing (see comment above).
604 const int attr
= prog
->Attributes
->Parameters
[i
].StateIndexes
[0];
605 const unsigned slots
= count_attribute_slots(var
->type
);
607 /* Mask representing the contiguous slots that will be used by this
610 const unsigned use_mask
= (1 << slots
) - 1;
612 /* Generate a link error if the set of bits requested for this
613 * attribute overlaps any previously allocated bits.
615 if ((~(use_mask
<< attr
) & used_locations
) != used_locations
) {
616 linker_error_printf(prog
,
617 "insufficient contiguous attribute locations "
618 "available for vertex shader input `%s'",
623 var
->location
= VERT_ATTRIB_GENERIC0
+ attr
;
624 used_locations
|= (use_mask
<< attr
);
628 /* Temporary storage for the set of attributes that need locations assigned.
634 /* Used below in the call to qsort. */
635 static int compare(const void *a
, const void *b
)
637 const temp_attr
*const l
= (const temp_attr
*) a
;
638 const temp_attr
*const r
= (const temp_attr
*) b
;
640 /* Reversed because we want a descending order sort below. */
641 return r
->slots
- l
->slots
;
645 unsigned num_attr
= 0;
647 foreach_list(node
, &sh
->ir
) {
648 ir_variable
*const var
= ((ir_instruction
*) node
)->as_variable();
650 if ((var
== NULL
) || (var
->mode
!= ir_var_in
))
653 /* The location was explicitly assigned, nothing to do here.
655 if (var
->location
!= -1)
658 to_assign
[num_attr
].slots
= count_attribute_slots(var
->type
);
659 to_assign
[num_attr
].var
= var
;
663 /* If all of the attributes were assigned locations by the application (or
664 * are built-in attributes with fixed locations), return early. This should
665 * be the common case.
670 qsort(to_assign
, num_attr
, sizeof(to_assign
[0]), temp_attr::compare
);
672 for (unsigned i
= 0; i
< num_attr
; i
++) {
673 /* Mask representing the contiguous slots that will be used by this
676 const unsigned use_mask
= (1 << to_assign
[i
].slots
) - 1;
678 int location
= find_available_slots(used_locations
, to_assign
[i
].slots
);
681 linker_error_printf(prog
,
682 "insufficient contiguous attribute locations "
683 "available for vertex shader input `%s'",
684 to_assign
[i
].var
->name
);
688 to_assign
[i
].var
->location
= VERT_ATTRIB_GENERIC0
+ location
;
689 used_locations
|= (use_mask
<< location
);
697 assign_varying_locations(glsl_shader
*producer
, glsl_shader
*consumer
)
699 /* FINISHME: Set dynamically when geometry shader support is added. */
700 unsigned output_index
= VERT_RESULT_VAR0
;
701 unsigned input_index
= FRAG_ATTRIB_VAR0
;
703 /* Operate in a total of three passes.
705 * 1. Assign locations for any matching inputs and outputs.
707 * 2. Mark output variables in the producer that do not have locations as
708 * not being outputs. This lets the optimizer eliminate them.
710 * 3. Mark input variables in the consumer that do not have locations as
711 * not being inputs. This lets the optimizer eliminate them.
714 invalidate_variable_locations(producer
, ir_var_out
, VERT_RESULT_VAR0
);
715 invalidate_variable_locations(consumer
, ir_var_in
, FRAG_ATTRIB_VAR0
);
717 foreach_list(node
, &producer
->ir
) {
718 ir_variable
*const output_var
= ((ir_instruction
*) node
)->as_variable();
720 if ((output_var
== NULL
) || (output_var
->mode
!= ir_var_out
)
721 || (output_var
->location
!= -1))
724 ir_variable
*const input_var
=
725 consumer
->symbols
->get_variable(output_var
->name
);
727 if ((input_var
== NULL
) || (input_var
->mode
!= ir_var_in
))
730 assert(input_var
->location
== -1);
732 /* FINISHME: Location assignment will need some changes when arrays,
733 * FINISHME: matrices, and structures are allowed as shader inputs /
736 output_var
->location
= output_index
;
737 input_var
->location
= input_index
;
743 foreach_list(node
, &producer
->ir
) {
744 ir_variable
*const var
= ((ir_instruction
*) node
)->as_variable();
746 if ((var
== NULL
) || (var
->mode
!= ir_var_out
))
749 /* An 'out' variable is only really a shader output if its value is read
750 * by the following stage.
752 var
->shader_out
= (var
->location
!= -1);
755 foreach_list(node
, &consumer
->ir
) {
756 ir_variable
*const var
= ((ir_instruction
*) node
)->as_variable();
758 if ((var
== NULL
) || (var
->mode
!= ir_var_in
))
761 /* An 'in' variable is only really a shader input if its value is written
762 * by the previous stage.
764 var
->shader_in
= (var
->location
!= -1);
770 link_shaders(struct glsl_program
*prog
)
772 prog
->LinkStatus
= false;
773 prog
->Validated
= false;
776 if (prog
->InfoLog
!= NULL
)
777 talloc_free(prog
->InfoLog
);
779 prog
->InfoLog
= talloc_strdup(NULL
, "");
781 /* Separate the shaders into groups based on their type.
783 struct glsl_shader
**vert_shader_list
;
784 unsigned num_vert_shaders
= 0;
785 struct glsl_shader
**frag_shader_list
;
786 unsigned num_frag_shaders
= 0;
788 vert_shader_list
= (struct glsl_shader
**)
789 calloc(2 * prog
->NumShaders
, sizeof(struct glsl_shader
*));
790 frag_shader_list
= &vert_shader_list
[prog
->NumShaders
];
792 for (unsigned i
= 0; i
< prog
->NumShaders
; i
++) {
793 switch (prog
->Shaders
[i
]->Type
) {
794 case GL_VERTEX_SHADER
:
795 vert_shader_list
[num_vert_shaders
] = prog
->Shaders
[i
];
798 case GL_FRAGMENT_SHADER
:
799 frag_shader_list
[num_frag_shaders
] = prog
->Shaders
[i
];
802 case GL_GEOMETRY_SHADER
:
803 /* FINISHME: Support geometry shaders. */
804 assert(prog
->Shaders
[i
]->Type
!= GL_GEOMETRY_SHADER
);
809 /* FINISHME: Implement intra-stage linking. */
810 assert(num_vert_shaders
<= 1);
811 assert(num_frag_shaders
<= 1);
813 /* Verify that each of the per-target executables is valid.
815 if (!validate_vertex_shader_executable(prog
, vert_shader_list
[0])
816 || !validate_fragment_shader_executable(prog
, frag_shader_list
[0]))
820 prog
->_LinkedShaders
= (struct glsl_shader
**)
821 calloc(2, sizeof(struct glsl_shader
*));
822 prog
->_NumLinkedShaders
= 0;
824 if (num_vert_shaders
> 0) {
825 prog
->_LinkedShaders
[prog
->_NumLinkedShaders
] = vert_shader_list
[0];
826 prog
->_NumLinkedShaders
++;
829 if (num_frag_shaders
> 0) {
830 prog
->_LinkedShaders
[prog
->_NumLinkedShaders
] = frag_shader_list
[0];
831 prog
->_NumLinkedShaders
++;
834 /* Here begins the inter-stage linking phase. Some initial validation is
835 * performed, then locations are assigned for uniforms, attributes, and
838 if (cross_validate_uniforms(prog
)) {
839 /* Validate the inputs of each stage with the output of the preceeding
842 for (unsigned i
= 1; i
< prog
->_NumLinkedShaders
; i
++) {
843 if (!cross_validate_outputs_to_inputs(prog
,
844 prog
->_LinkedShaders
[i
- 1],
845 prog
->_LinkedShaders
[i
]))
849 prog
->LinkStatus
= true;
852 /* FINISHME: Perform whole-program optimization here. */
854 assign_uniform_locations(prog
);
856 if (prog
->_LinkedShaders
[0]->Type
== GL_VERTEX_SHADER
)
857 /* FINISHME: The value of the max_attribute_index parameter is
858 * FINISHME: implementation dependent based on the value of
859 * FINISHME: GL_MAX_VERTEX_ATTRIBS. GL_MAX_VERTEX_ATTRIBS must be
860 * FINISHME: at least 16, so hardcode 16 for now.
862 if (!assign_attribute_locations(prog
, 16))
865 for (unsigned i
= 1; i
< prog
->_NumLinkedShaders
; i
++)
866 assign_varying_locations(prog
->_LinkedShaders
[i
- 1],
867 prog
->_LinkedShaders
[i
]);
869 /* FINISHME: Assign fragment shader output locations. */
872 free(vert_shader_list
);