linker.cpp revision f9ad8a790398513a845d486f58566854f7eceee4
11591693c7b415e9869157c711fe11263c95d74eDavid Li/*
21591693c7b415e9869157c711fe11263c95d74eDavid Li * Copyright © 2010 Intel Corporation
31591693c7b415e9869157c711fe11263c95d74eDavid Li *
41591693c7b415e9869157c711fe11263c95d74eDavid Li * Permission is hereby granted, free of charge, to any person obtaining a
51591693c7b415e9869157c711fe11263c95d74eDavid Li * copy of this software and associated documentation files (the "Software"),
61591693c7b415e9869157c711fe11263c95d74eDavid Li * to deal in the Software without restriction, including without limitation
71591693c7b415e9869157c711fe11263c95d74eDavid Li * the rights to use, copy, modify, merge, publish, distribute, sublicense,
81591693c7b415e9869157c711fe11263c95d74eDavid Li * and/or sell copies of the Software, and to permit persons to whom the
91591693c7b415e9869157c711fe11263c95d74eDavid Li * Software is furnished to do so, subject to the following conditions:
101591693c7b415e9869157c711fe11263c95d74eDavid Li *
111591693c7b415e9869157c711fe11263c95d74eDavid Li * The above copyright notice and this permission notice (including the next
121591693c7b415e9869157c711fe11263c95d74eDavid Li * paragraph) shall be included in all copies or substantial portions of the
131591693c7b415e9869157c711fe11263c95d74eDavid Li * Software.
141591693c7b415e9869157c711fe11263c95d74eDavid Li *
151591693c7b415e9869157c711fe11263c95d74eDavid Li * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
161591693c7b415e9869157c711fe11263c95d74eDavid Li * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
171591693c7b415e9869157c711fe11263c95d74eDavid Li * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
181591693c7b415e9869157c711fe11263c95d74eDavid Li * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
191591693c7b415e9869157c711fe11263c95d74eDavid Li * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
201591693c7b415e9869157c711fe11263c95d74eDavid Li * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
211591693c7b415e9869157c711fe11263c95d74eDavid Li * DEALINGS IN THE SOFTWARE.
221591693c7b415e9869157c711fe11263c95d74eDavid Li */
231591693c7b415e9869157c711fe11263c95d74eDavid Li
241591693c7b415e9869157c711fe11263c95d74eDavid Li/**
251591693c7b415e9869157c711fe11263c95d74eDavid Li * \file linker.cpp
261591693c7b415e9869157c711fe11263c95d74eDavid Li * GLSL linker implementation
271591693c7b415e9869157c711fe11263c95d74eDavid Li *
281591693c7b415e9869157c711fe11263c95d74eDavid Li * Given a set of shaders that are to be linked to generate a final program,
291591693c7b415e9869157c711fe11263c95d74eDavid Li * there are three distinct stages.
301591693c7b415e9869157c711fe11263c95d74eDavid Li *
311591693c7b415e9869157c711fe11263c95d74eDavid Li * In the first stage shaders are partitioned into groups based on the shader
321591693c7b415e9869157c711fe11263c95d74eDavid Li * type.  All shaders of a particular type (e.g., vertex shaders) are linked
331591693c7b415e9869157c711fe11263c95d74eDavid Li * together.
341591693c7b415e9869157c711fe11263c95d74eDavid Li *
351591693c7b415e9869157c711fe11263c95d74eDavid Li *   - Undefined references in each shader are resolve to definitions in
361591693c7b415e9869157c711fe11263c95d74eDavid Li *     another shader.
371591693c7b415e9869157c711fe11263c95d74eDavid Li *   - Types and qualifiers of uniforms, outputs, and global variables defined
381591693c7b415e9869157c711fe11263c95d74eDavid Li *     in multiple shaders with the same name are verified to be the same.
391591693c7b415e9869157c711fe11263c95d74eDavid Li *   - Initializers for uniforms and global variables defined
401591693c7b415e9869157c711fe11263c95d74eDavid Li *     in multiple shaders with the same name are verified to be the same.
411591693c7b415e9869157c711fe11263c95d74eDavid Li *
421591693c7b415e9869157c711fe11263c95d74eDavid Li * The result, in the terminology of the GLSL spec, is a set of shader
431591693c7b415e9869157c711fe11263c95d74eDavid Li * executables for each processing unit.
441591693c7b415e9869157c711fe11263c95d74eDavid Li *
451591693c7b415e9869157c711fe11263c95d74eDavid Li * After the first stage is complete, a series of semantic checks are performed
461591693c7b415e9869157c711fe11263c95d74eDavid Li * on each of the shader executables.
471591693c7b415e9869157c711fe11263c95d74eDavid Li *
481591693c7b415e9869157c711fe11263c95d74eDavid Li *   - Each shader executable must define a \c main function.
491591693c7b415e9869157c711fe11263c95d74eDavid Li *   - Each vertex shader executable must write to \c gl_Position.
501591693c7b415e9869157c711fe11263c95d74eDavid Li *   - Each fragment shader executable must write to either \c gl_FragData or
511591693c7b415e9869157c711fe11263c95d74eDavid Li *     \c gl_FragColor.
521591693c7b415e9869157c711fe11263c95d74eDavid Li *
531591693c7b415e9869157c711fe11263c95d74eDavid Li * In the final stage individual shader executables are linked to create a
541591693c7b415e9869157c711fe11263c95d74eDavid Li * complete exectuable.
551591693c7b415e9869157c711fe11263c95d74eDavid Li *
561591693c7b415e9869157c711fe11263c95d74eDavid Li *   - Types of uniforms defined in multiple shader stages with the same name
571591693c7b415e9869157c711fe11263c95d74eDavid Li *     are verified to be the same.
581591693c7b415e9869157c711fe11263c95d74eDavid Li *   - Initializers for uniforms defined in multiple shader stages with the
591591693c7b415e9869157c711fe11263c95d74eDavid Li *     same name are verified to be the same.
601591693c7b415e9869157c711fe11263c95d74eDavid Li *   - Types and qualifiers of outputs defined in one stage are verified to
611591693c7b415e9869157c711fe11263c95d74eDavid Li *     be the same as the types and qualifiers of inputs defined with the same
621591693c7b415e9869157c711fe11263c95d74eDavid Li *     name in a later stage.
631591693c7b415e9869157c711fe11263c95d74eDavid Li *
641591693c7b415e9869157c711fe11263c95d74eDavid Li * \author Ian Romanick <ian.d.romanick@intel.com>
651591693c7b415e9869157c711fe11263c95d74eDavid Li */
661591693c7b415e9869157c711fe11263c95d74eDavid Li#include <cstdlib>
671591693c7b415e9869157c711fe11263c95d74eDavid Li#include <cstdio>
681591693c7b415e9869157c711fe11263c95d74eDavid Li#include <cstdarg>
691591693c7b415e9869157c711fe11263c95d74eDavid Li#include <climits>
701591693c7b415e9869157c711fe11263c95d74eDavid Li
71c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li#include <pixelflinger2/pixelflinger2_interface.h>
72c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li
731591693c7b415e9869157c711fe11263c95d74eDavid Liextern "C" {
74d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li#include <hieralloc.h>
751591693c7b415e9869157c711fe11263c95d74eDavid Li}
761591693c7b415e9869157c711fe11263c95d74eDavid Li
771591693c7b415e9869157c711fe11263c95d74eDavid Li#include "main/core.h"
781591693c7b415e9869157c711fe11263c95d74eDavid Li#include "glsl_symbol_table.h"
791591693c7b415e9869157c711fe11263c95d74eDavid Li#include "ir.h"
801591693c7b415e9869157c711fe11263c95d74eDavid Li#include "program.h"
811591693c7b415e9869157c711fe11263c95d74eDavid Li#include "program/hash_table.h"
821591693c7b415e9869157c711fe11263c95d74eDavid Li#include "linker.h"
831591693c7b415e9869157c711fe11263c95d74eDavid Li#include "ir_optimization.h"
841591693c7b415e9869157c711fe11263c95d74eDavid Li
851591693c7b415e9869157c711fe11263c95d74eDavid Liextern "C" {
861591693c7b415e9869157c711fe11263c95d74eDavid Li#include "main/shaderobj.h"
871591693c7b415e9869157c711fe11263c95d74eDavid Li}
881591693c7b415e9869157c711fe11263c95d74eDavid Li
891591693c7b415e9869157c711fe11263c95d74eDavid Li/**
901591693c7b415e9869157c711fe11263c95d74eDavid Li * Visitor that determines whether or not a variable is ever written.
911591693c7b415e9869157c711fe11263c95d74eDavid Li */
921591693c7b415e9869157c711fe11263c95d74eDavid Liclass find_assignment_visitor : public ir_hierarchical_visitor {
931591693c7b415e9869157c711fe11263c95d74eDavid Lipublic:
941591693c7b415e9869157c711fe11263c95d74eDavid Li   find_assignment_visitor(const char *name)
951591693c7b415e9869157c711fe11263c95d74eDavid Li      : name(name), found(false)
961591693c7b415e9869157c711fe11263c95d74eDavid Li   {
971591693c7b415e9869157c711fe11263c95d74eDavid Li      /* empty */
981591693c7b415e9869157c711fe11263c95d74eDavid Li   }
991591693c7b415e9869157c711fe11263c95d74eDavid Li
1001591693c7b415e9869157c711fe11263c95d74eDavid Li   virtual ir_visitor_status visit_enter(ir_assignment *ir)
1011591693c7b415e9869157c711fe11263c95d74eDavid Li   {
1021591693c7b415e9869157c711fe11263c95d74eDavid Li      ir_variable *const var = ir->lhs->variable_referenced();
1031591693c7b415e9869157c711fe11263c95d74eDavid Li
1041591693c7b415e9869157c711fe11263c95d74eDavid Li      if (strcmp(name, var->name) == 0) {
1051591693c7b415e9869157c711fe11263c95d74eDavid Li	 found = true;
1061591693c7b415e9869157c711fe11263c95d74eDavid Li	 return visit_stop;
1071591693c7b415e9869157c711fe11263c95d74eDavid Li      }
1081591693c7b415e9869157c711fe11263c95d74eDavid Li
1091591693c7b415e9869157c711fe11263c95d74eDavid Li      return visit_continue_with_parent;
1101591693c7b415e9869157c711fe11263c95d74eDavid Li   }
1111591693c7b415e9869157c711fe11263c95d74eDavid Li
1121591693c7b415e9869157c711fe11263c95d74eDavid Li   virtual ir_visitor_status visit_enter(ir_call *ir)
1131591693c7b415e9869157c711fe11263c95d74eDavid Li   {
1141591693c7b415e9869157c711fe11263c95d74eDavid Li      exec_list_iterator sig_iter = ir->get_callee()->parameters.iterator();
1151591693c7b415e9869157c711fe11263c95d74eDavid Li      foreach_iter(exec_list_iterator, iter, *ir) {
1161591693c7b415e9869157c711fe11263c95d74eDavid Li	 ir_rvalue *param_rval = (ir_rvalue *)iter.get();
1171591693c7b415e9869157c711fe11263c95d74eDavid Li	 ir_variable *sig_param = (ir_variable *)sig_iter.get();
1181591693c7b415e9869157c711fe11263c95d74eDavid Li
1191591693c7b415e9869157c711fe11263c95d74eDavid Li	 if (sig_param->mode == ir_var_out ||
1201591693c7b415e9869157c711fe11263c95d74eDavid Li	     sig_param->mode == ir_var_inout) {
1211591693c7b415e9869157c711fe11263c95d74eDavid Li	    ir_variable *var = param_rval->variable_referenced();
1221591693c7b415e9869157c711fe11263c95d74eDavid Li	    if (var && strcmp(name, var->name) == 0) {
1231591693c7b415e9869157c711fe11263c95d74eDavid Li	       found = true;
1241591693c7b415e9869157c711fe11263c95d74eDavid Li	       return visit_stop;
1251591693c7b415e9869157c711fe11263c95d74eDavid Li	    }
1261591693c7b415e9869157c711fe11263c95d74eDavid Li	 }
1271591693c7b415e9869157c711fe11263c95d74eDavid Li	 sig_iter.next();
1281591693c7b415e9869157c711fe11263c95d74eDavid Li      }
1291591693c7b415e9869157c711fe11263c95d74eDavid Li
1301591693c7b415e9869157c711fe11263c95d74eDavid Li      return visit_continue_with_parent;
1311591693c7b415e9869157c711fe11263c95d74eDavid Li   }
1321591693c7b415e9869157c711fe11263c95d74eDavid Li
1331591693c7b415e9869157c711fe11263c95d74eDavid Li   bool variable_found()
1341591693c7b415e9869157c711fe11263c95d74eDavid Li   {
1351591693c7b415e9869157c711fe11263c95d74eDavid Li      return found;
1361591693c7b415e9869157c711fe11263c95d74eDavid Li   }
1371591693c7b415e9869157c711fe11263c95d74eDavid Li
1381591693c7b415e9869157c711fe11263c95d74eDavid Liprivate:
1391591693c7b415e9869157c711fe11263c95d74eDavid Li   const char *name;       /**< Find writes to a variable with this name. */
1401591693c7b415e9869157c711fe11263c95d74eDavid Li   bool found;             /**< Was a write to the variable found? */
1411591693c7b415e9869157c711fe11263c95d74eDavid Li};
1421591693c7b415e9869157c711fe11263c95d74eDavid Li
1431591693c7b415e9869157c711fe11263c95d74eDavid Li
1441591693c7b415e9869157c711fe11263c95d74eDavid Li/**
1451591693c7b415e9869157c711fe11263c95d74eDavid Li * Visitor that determines whether or not a variable is ever read.
1461591693c7b415e9869157c711fe11263c95d74eDavid Li */
1471591693c7b415e9869157c711fe11263c95d74eDavid Liclass find_deref_visitor : public ir_hierarchical_visitor {
1481591693c7b415e9869157c711fe11263c95d74eDavid Lipublic:
1491591693c7b415e9869157c711fe11263c95d74eDavid Li   find_deref_visitor(const char *name)
1501591693c7b415e9869157c711fe11263c95d74eDavid Li      : name(name), found(false)
1511591693c7b415e9869157c711fe11263c95d74eDavid Li   {
1521591693c7b415e9869157c711fe11263c95d74eDavid Li      /* empty */
1531591693c7b415e9869157c711fe11263c95d74eDavid Li   }
1541591693c7b415e9869157c711fe11263c95d74eDavid Li
1551591693c7b415e9869157c711fe11263c95d74eDavid Li   virtual ir_visitor_status visit(ir_dereference_variable *ir)
1561591693c7b415e9869157c711fe11263c95d74eDavid Li   {
1571591693c7b415e9869157c711fe11263c95d74eDavid Li      if (strcmp(this->name, ir->var->name) == 0) {
1581591693c7b415e9869157c711fe11263c95d74eDavid Li	 this->found = true;
1591591693c7b415e9869157c711fe11263c95d74eDavid Li	 return visit_stop;
1601591693c7b415e9869157c711fe11263c95d74eDavid Li      }
1611591693c7b415e9869157c711fe11263c95d74eDavid Li
1621591693c7b415e9869157c711fe11263c95d74eDavid Li      return visit_continue;
1631591693c7b415e9869157c711fe11263c95d74eDavid Li   }
1641591693c7b415e9869157c711fe11263c95d74eDavid Li
1651591693c7b415e9869157c711fe11263c95d74eDavid Li   bool variable_found() const
1661591693c7b415e9869157c711fe11263c95d74eDavid Li   {
1671591693c7b415e9869157c711fe11263c95d74eDavid Li      return this->found;
1681591693c7b415e9869157c711fe11263c95d74eDavid Li   }
1691591693c7b415e9869157c711fe11263c95d74eDavid Li
1701591693c7b415e9869157c711fe11263c95d74eDavid Liprivate:
1711591693c7b415e9869157c711fe11263c95d74eDavid Li   const char *name;       /**< Find writes to a variable with this name. */
1721591693c7b415e9869157c711fe11263c95d74eDavid Li   bool found;             /**< Was a write to the variable found? */
1731591693c7b415e9869157c711fe11263c95d74eDavid Li};
1741591693c7b415e9869157c711fe11263c95d74eDavid Li
1751591693c7b415e9869157c711fe11263c95d74eDavid Li
1761591693c7b415e9869157c711fe11263c95d74eDavid Livoid
1771591693c7b415e9869157c711fe11263c95d74eDavid Lilinker_error_printf(gl_shader_program *prog, const char *fmt, ...)
1781591693c7b415e9869157c711fe11263c95d74eDavid Li{
1791591693c7b415e9869157c711fe11263c95d74eDavid Li   va_list ap;
1801591693c7b415e9869157c711fe11263c95d74eDavid Li
181d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li   prog->InfoLog = hieralloc_strdup_append(prog->InfoLog, "error: ");
1821591693c7b415e9869157c711fe11263c95d74eDavid Li   va_start(ap, fmt);
183d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li   prog->InfoLog = hieralloc_vasprintf_append(prog->InfoLog, fmt, ap);
1841591693c7b415e9869157c711fe11263c95d74eDavid Li   va_end(ap);
1851591693c7b415e9869157c711fe11263c95d74eDavid Li}
1861591693c7b415e9869157c711fe11263c95d74eDavid Li
1871591693c7b415e9869157c711fe11263c95d74eDavid Li
1881591693c7b415e9869157c711fe11263c95d74eDavid Livoid
1891591693c7b415e9869157c711fe11263c95d74eDavid Liinvalidate_variable_locations(gl_shader *sh, enum ir_variable_mode mode,
1901591693c7b415e9869157c711fe11263c95d74eDavid Li			      int generic_base)
1911591693c7b415e9869157c711fe11263c95d74eDavid Li{
1921591693c7b415e9869157c711fe11263c95d74eDavid Li   foreach_list(node, sh->ir) {
1931591693c7b415e9869157c711fe11263c95d74eDavid Li      ir_variable *const var = ((ir_instruction *) node)->as_variable();
1941591693c7b415e9869157c711fe11263c95d74eDavid Li
1951591693c7b415e9869157c711fe11263c95d74eDavid Li      if ((var == NULL) || (var->mode != (unsigned) mode))
1961591693c7b415e9869157c711fe11263c95d74eDavid Li	 continue;
1971591693c7b415e9869157c711fe11263c95d74eDavid Li
1981591693c7b415e9869157c711fe11263c95d74eDavid Li      /* Only assign locations for generic attributes / varyings / etc.
1991591693c7b415e9869157c711fe11263c95d74eDavid Li       */
2001591693c7b415e9869157c711fe11263c95d74eDavid Li      if ((var->location >= generic_base) && !var->explicit_location)
2011591693c7b415e9869157c711fe11263c95d74eDavid Li	  var->location = -1;
2021591693c7b415e9869157c711fe11263c95d74eDavid Li   }
2031591693c7b415e9869157c711fe11263c95d74eDavid Li}
2041591693c7b415e9869157c711fe11263c95d74eDavid Li
2051591693c7b415e9869157c711fe11263c95d74eDavid Li
2061591693c7b415e9869157c711fe11263c95d74eDavid Li/**
2071591693c7b415e9869157c711fe11263c95d74eDavid Li * Determine the number of attribute slots required for a particular type
2081591693c7b415e9869157c711fe11263c95d74eDavid Li *
2091591693c7b415e9869157c711fe11263c95d74eDavid Li * This code is here because it implements the language rules of a specific
2101591693c7b415e9869157c711fe11263c95d74eDavid Li * GLSL version.  Since it's a property of the language and not a property of
2111591693c7b415e9869157c711fe11263c95d74eDavid Li * types in general, it doesn't really belong in glsl_type.
2121591693c7b415e9869157c711fe11263c95d74eDavid Li */
2131591693c7b415e9869157c711fe11263c95d74eDavid Liunsigned
2141591693c7b415e9869157c711fe11263c95d74eDavid Licount_attribute_slots(const glsl_type *t)
2151591693c7b415e9869157c711fe11263c95d74eDavid Li{
2161591693c7b415e9869157c711fe11263c95d74eDavid Li   /* From page 31 (page 37 of the PDF) of the GLSL 1.50 spec:
2171591693c7b415e9869157c711fe11263c95d74eDavid Li    *
2181591693c7b415e9869157c711fe11263c95d74eDavid Li    *     "A scalar input counts the same amount against this limit as a vec4,
2191591693c7b415e9869157c711fe11263c95d74eDavid Li    *     so applications may want to consider packing groups of four
2201591693c7b415e9869157c711fe11263c95d74eDavid Li    *     unrelated float inputs together into a vector to better utilize the
2211591693c7b415e9869157c711fe11263c95d74eDavid Li    *     capabilities of the underlying hardware. A matrix input will use up
2221591693c7b415e9869157c711fe11263c95d74eDavid Li    *     multiple locations.  The number of locations used will equal the
2231591693c7b415e9869157c711fe11263c95d74eDavid Li    *     number of columns in the matrix."
2241591693c7b415e9869157c711fe11263c95d74eDavid Li    *
2251591693c7b415e9869157c711fe11263c95d74eDavid Li    * The spec does not explicitly say how arrays are counted.  However, it
2261591693c7b415e9869157c711fe11263c95d74eDavid Li    * should be safe to assume the total number of slots consumed by an array
2271591693c7b415e9869157c711fe11263c95d74eDavid Li    * is the number of entries in the array multiplied by the number of slots
2281591693c7b415e9869157c711fe11263c95d74eDavid Li    * consumed by a single element of the array.
2291591693c7b415e9869157c711fe11263c95d74eDavid Li    */
2301591693c7b415e9869157c711fe11263c95d74eDavid Li
2311591693c7b415e9869157c711fe11263c95d74eDavid Li   if (t->is_array())
2321591693c7b415e9869157c711fe11263c95d74eDavid Li      return t->array_size() * count_attribute_slots(t->element_type());
2331591693c7b415e9869157c711fe11263c95d74eDavid Li
2341591693c7b415e9869157c711fe11263c95d74eDavid Li   if (t->is_matrix())
2351591693c7b415e9869157c711fe11263c95d74eDavid Li      return t->matrix_columns;
2361591693c7b415e9869157c711fe11263c95d74eDavid Li
2371591693c7b415e9869157c711fe11263c95d74eDavid Li   return 1;
2381591693c7b415e9869157c711fe11263c95d74eDavid Li}
2391591693c7b415e9869157c711fe11263c95d74eDavid Li
2401591693c7b415e9869157c711fe11263c95d74eDavid Li
2411591693c7b415e9869157c711fe11263c95d74eDavid Li/**
2421591693c7b415e9869157c711fe11263c95d74eDavid Li * Verify that a vertex shader executable meets all semantic requirements
2431591693c7b415e9869157c711fe11263c95d74eDavid Li *
2441591693c7b415e9869157c711fe11263c95d74eDavid Li * \param shader  Vertex shader executable to be verified
2451591693c7b415e9869157c711fe11263c95d74eDavid Li */
2461591693c7b415e9869157c711fe11263c95d74eDavid Libool
2471591693c7b415e9869157c711fe11263c95d74eDavid Livalidate_vertex_shader_executable(struct gl_shader_program *prog,
2481591693c7b415e9869157c711fe11263c95d74eDavid Li				  struct gl_shader *shader)
2491591693c7b415e9869157c711fe11263c95d74eDavid Li{
2501591693c7b415e9869157c711fe11263c95d74eDavid Li   if (shader == NULL)
2511591693c7b415e9869157c711fe11263c95d74eDavid Li      return true;
2521591693c7b415e9869157c711fe11263c95d74eDavid Li
2531591693c7b415e9869157c711fe11263c95d74eDavid Li   find_assignment_visitor find("gl_Position");
2541591693c7b415e9869157c711fe11263c95d74eDavid Li   find.run(shader->ir);
2551591693c7b415e9869157c711fe11263c95d74eDavid Li   if (!find.variable_found()) {
2561591693c7b415e9869157c711fe11263c95d74eDavid Li      linker_error_printf(prog,
2571591693c7b415e9869157c711fe11263c95d74eDavid Li			  "vertex shader does not write to `gl_Position'\n");
2581591693c7b415e9869157c711fe11263c95d74eDavid Li      return false;
2591591693c7b415e9869157c711fe11263c95d74eDavid Li   }
2601591693c7b415e9869157c711fe11263c95d74eDavid Li
2611591693c7b415e9869157c711fe11263c95d74eDavid Li   return true;
2621591693c7b415e9869157c711fe11263c95d74eDavid Li}
2631591693c7b415e9869157c711fe11263c95d74eDavid Li
2641591693c7b415e9869157c711fe11263c95d74eDavid Li
2651591693c7b415e9869157c711fe11263c95d74eDavid Li/**
2661591693c7b415e9869157c711fe11263c95d74eDavid Li * Verify that a fragment shader executable meets all semantic requirements
2671591693c7b415e9869157c711fe11263c95d74eDavid Li *
2681591693c7b415e9869157c711fe11263c95d74eDavid Li * \param shader  Fragment shader executable to be verified
2691591693c7b415e9869157c711fe11263c95d74eDavid Li */
2701591693c7b415e9869157c711fe11263c95d74eDavid Libool
2711591693c7b415e9869157c711fe11263c95d74eDavid Livalidate_fragment_shader_executable(struct gl_shader_program *prog,
2721591693c7b415e9869157c711fe11263c95d74eDavid Li				    struct gl_shader *shader)
2731591693c7b415e9869157c711fe11263c95d74eDavid Li{
2741591693c7b415e9869157c711fe11263c95d74eDavid Li   if (shader == NULL)
2751591693c7b415e9869157c711fe11263c95d74eDavid Li      return true;
2761591693c7b415e9869157c711fe11263c95d74eDavid Li
2771591693c7b415e9869157c711fe11263c95d74eDavid Li   find_assignment_visitor frag_color("gl_FragColor");
2781591693c7b415e9869157c711fe11263c95d74eDavid Li   find_assignment_visitor frag_data("gl_FragData");
2791591693c7b415e9869157c711fe11263c95d74eDavid Li
2801591693c7b415e9869157c711fe11263c95d74eDavid Li   frag_color.run(shader->ir);
2811591693c7b415e9869157c711fe11263c95d74eDavid Li   frag_data.run(shader->ir);
2821591693c7b415e9869157c711fe11263c95d74eDavid Li
2831591693c7b415e9869157c711fe11263c95d74eDavid Li   if (frag_color.variable_found() && frag_data.variable_found()) {
2841591693c7b415e9869157c711fe11263c95d74eDavid Li      linker_error_printf(prog,  "fragment shader writes to both "
2851591693c7b415e9869157c711fe11263c95d74eDavid Li			  "`gl_FragColor' and `gl_FragData'\n");
2861591693c7b415e9869157c711fe11263c95d74eDavid Li      return false;
2871591693c7b415e9869157c711fe11263c95d74eDavid Li   }
2881591693c7b415e9869157c711fe11263c95d74eDavid Li
2891591693c7b415e9869157c711fe11263c95d74eDavid Li   return true;
2901591693c7b415e9869157c711fe11263c95d74eDavid Li}
2911591693c7b415e9869157c711fe11263c95d74eDavid Li
2921591693c7b415e9869157c711fe11263c95d74eDavid Li
2931591693c7b415e9869157c711fe11263c95d74eDavid Li/**
2941591693c7b415e9869157c711fe11263c95d74eDavid Li * Generate a string describing the mode of a variable
2951591693c7b415e9869157c711fe11263c95d74eDavid Li */
2961591693c7b415e9869157c711fe11263c95d74eDavid Listatic const char *
2971591693c7b415e9869157c711fe11263c95d74eDavid Limode_string(const ir_variable *var)
2981591693c7b415e9869157c711fe11263c95d74eDavid Li{
2991591693c7b415e9869157c711fe11263c95d74eDavid Li   switch (var->mode) {
3001591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_var_auto:
3011591693c7b415e9869157c711fe11263c95d74eDavid Li      return (var->read_only) ? "global constant" : "global variable";
3021591693c7b415e9869157c711fe11263c95d74eDavid Li
3031591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_var_uniform: return "uniform";
3041591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_var_in:      return "shader input";
3051591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_var_out:     return "shader output";
3061591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_var_inout:   return "shader inout";
3071591693c7b415e9869157c711fe11263c95d74eDavid Li
3081591693c7b415e9869157c711fe11263c95d74eDavid Li   case ir_var_temporary:
3091591693c7b415e9869157c711fe11263c95d74eDavid Li   default:
3101591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(!"Should not get here.");
3111591693c7b415e9869157c711fe11263c95d74eDavid Li      return "invalid variable";
3121591693c7b415e9869157c711fe11263c95d74eDavid Li   }
3131591693c7b415e9869157c711fe11263c95d74eDavid Li}
3141591693c7b415e9869157c711fe11263c95d74eDavid Li
3151591693c7b415e9869157c711fe11263c95d74eDavid Li
3161591693c7b415e9869157c711fe11263c95d74eDavid Li/**
3171591693c7b415e9869157c711fe11263c95d74eDavid Li * Perform validation of global variables used across multiple shaders
3181591693c7b415e9869157c711fe11263c95d74eDavid Li */
3191591693c7b415e9869157c711fe11263c95d74eDavid Libool
3201591693c7b415e9869157c711fe11263c95d74eDavid Licross_validate_globals(struct gl_shader_program *prog,
3211591693c7b415e9869157c711fe11263c95d74eDavid Li		       struct gl_shader **shader_list,
3221591693c7b415e9869157c711fe11263c95d74eDavid Li		       unsigned num_shaders,
3231591693c7b415e9869157c711fe11263c95d74eDavid Li		       bool uniforms_only)
3241591693c7b415e9869157c711fe11263c95d74eDavid Li{
3251591693c7b415e9869157c711fe11263c95d74eDavid Li   /* Examine all of the uniforms in all of the shaders and cross validate
3261591693c7b415e9869157c711fe11263c95d74eDavid Li    * them.
3271591693c7b415e9869157c711fe11263c95d74eDavid Li    */
3283b02c91d7b1fcc777dbdafeb044e0df61e1ff0d8David Li   glsl_symbol_table variables(prog);
3291591693c7b415e9869157c711fe11263c95d74eDavid Li   for (unsigned i = 0; i < num_shaders; i++) {
3301591693c7b415e9869157c711fe11263c95d74eDavid Li      if (shader_list[i] == NULL)
3311591693c7b415e9869157c711fe11263c95d74eDavid Li	 continue;
3321591693c7b415e9869157c711fe11263c95d74eDavid Li
3331591693c7b415e9869157c711fe11263c95d74eDavid Li      foreach_list(node, shader_list[i]->ir) {
3341591693c7b415e9869157c711fe11263c95d74eDavid Li	 ir_variable *const var = ((ir_instruction *) node)->as_variable();
3351591693c7b415e9869157c711fe11263c95d74eDavid Li
3361591693c7b415e9869157c711fe11263c95d74eDavid Li	 if (var == NULL)
3371591693c7b415e9869157c711fe11263c95d74eDavid Li	    continue;
3381591693c7b415e9869157c711fe11263c95d74eDavid Li
3391591693c7b415e9869157c711fe11263c95d74eDavid Li	 if (uniforms_only && (var->mode != ir_var_uniform))
3401591693c7b415e9869157c711fe11263c95d74eDavid Li	    continue;
3411591693c7b415e9869157c711fe11263c95d74eDavid Li
3421591693c7b415e9869157c711fe11263c95d74eDavid Li	 /* Don't cross validate temporaries that are at global scope.  These
3431591693c7b415e9869157c711fe11263c95d74eDavid Li	  * will eventually get pulled into the shaders 'main'.
3441591693c7b415e9869157c711fe11263c95d74eDavid Li	  */
3451591693c7b415e9869157c711fe11263c95d74eDavid Li	 if (var->mode == ir_var_temporary)
3461591693c7b415e9869157c711fe11263c95d74eDavid Li	    continue;
3471591693c7b415e9869157c711fe11263c95d74eDavid Li
3481591693c7b415e9869157c711fe11263c95d74eDavid Li	 /* If a global with this name has already been seen, verify that the
3491591693c7b415e9869157c711fe11263c95d74eDavid Li	  * new instance has the same type.  In addition, if the globals have
3501591693c7b415e9869157c711fe11263c95d74eDavid Li	  * initializers, the values of the initializers must be the same.
3511591693c7b415e9869157c711fe11263c95d74eDavid Li	  */
3521591693c7b415e9869157c711fe11263c95d74eDavid Li	 ir_variable *const existing = variables.get_variable(var->name);
3531591693c7b415e9869157c711fe11263c95d74eDavid Li	 if (existing != NULL) {
3541591693c7b415e9869157c711fe11263c95d74eDavid Li	    if (var->type != existing->type) {
3551591693c7b415e9869157c711fe11263c95d74eDavid Li	       /* Consider the types to be "the same" if both types are arrays
3561591693c7b415e9869157c711fe11263c95d74eDavid Li		* of the same type and one of the arrays is implicitly sized.
3571591693c7b415e9869157c711fe11263c95d74eDavid Li		* In addition, set the type of the linked variable to the
3581591693c7b415e9869157c711fe11263c95d74eDavid Li		* explicitly sized array.
3591591693c7b415e9869157c711fe11263c95d74eDavid Li		*/
3601591693c7b415e9869157c711fe11263c95d74eDavid Li	       if (var->type->is_array()
3611591693c7b415e9869157c711fe11263c95d74eDavid Li		   && existing->type->is_array()
3621591693c7b415e9869157c711fe11263c95d74eDavid Li		   && (var->type->fields.array == existing->type->fields.array)
3631591693c7b415e9869157c711fe11263c95d74eDavid Li		   && ((var->type->length == 0)
3641591693c7b415e9869157c711fe11263c95d74eDavid Li		       || (existing->type->length == 0))) {
3651591693c7b415e9869157c711fe11263c95d74eDavid Li		  if (existing->type->length == 0) {
3661591693c7b415e9869157c711fe11263c95d74eDavid Li		     existing->type = var->type;
3671591693c7b415e9869157c711fe11263c95d74eDavid Li		     existing->max_array_access =
3681591693c7b415e9869157c711fe11263c95d74eDavid Li			MAX2(existing->max_array_access,
3691591693c7b415e9869157c711fe11263c95d74eDavid Li			     var->max_array_access);
3701591693c7b415e9869157c711fe11263c95d74eDavid Li		  }
3711591693c7b415e9869157c711fe11263c95d74eDavid Li	       } else {
3721591693c7b415e9869157c711fe11263c95d74eDavid Li		  linker_error_printf(prog, "%s `%s' declared as type "
3731591693c7b415e9869157c711fe11263c95d74eDavid Li				      "`%s' and type `%s'\n",
3741591693c7b415e9869157c711fe11263c95d74eDavid Li				      mode_string(var),
3751591693c7b415e9869157c711fe11263c95d74eDavid Li				      var->name, var->type->name,
3761591693c7b415e9869157c711fe11263c95d74eDavid Li				      existing->type->name);
3771591693c7b415e9869157c711fe11263c95d74eDavid Li		  return false;
3781591693c7b415e9869157c711fe11263c95d74eDavid Li	       }
3791591693c7b415e9869157c711fe11263c95d74eDavid Li	    }
3801591693c7b415e9869157c711fe11263c95d74eDavid Li
3811591693c7b415e9869157c711fe11263c95d74eDavid Li	    if (var->explicit_location) {
3821591693c7b415e9869157c711fe11263c95d74eDavid Li	       if (existing->explicit_location
3831591693c7b415e9869157c711fe11263c95d74eDavid Li		   && (var->location != existing->location)) {
3841591693c7b415e9869157c711fe11263c95d74eDavid Li		     linker_error_printf(prog, "explicit locations for %s "
3851591693c7b415e9869157c711fe11263c95d74eDavid Li					 "`%s' have differing values\n",
3861591693c7b415e9869157c711fe11263c95d74eDavid Li					 mode_string(var), var->name);
3871591693c7b415e9869157c711fe11263c95d74eDavid Li		     return false;
3881591693c7b415e9869157c711fe11263c95d74eDavid Li	       }
3891591693c7b415e9869157c711fe11263c95d74eDavid Li
3901591693c7b415e9869157c711fe11263c95d74eDavid Li	       existing->location = var->location;
3911591693c7b415e9869157c711fe11263c95d74eDavid Li	       existing->explicit_location = true;
3921591693c7b415e9869157c711fe11263c95d74eDavid Li	    }
3931591693c7b415e9869157c711fe11263c95d74eDavid Li
3941591693c7b415e9869157c711fe11263c95d74eDavid Li	    /* FINISHME: Handle non-constant initializers.
3951591693c7b415e9869157c711fe11263c95d74eDavid Li	     */
3961591693c7b415e9869157c711fe11263c95d74eDavid Li	    if (var->constant_value != NULL) {
3971591693c7b415e9869157c711fe11263c95d74eDavid Li	       if (existing->constant_value != NULL) {
3981591693c7b415e9869157c711fe11263c95d74eDavid Li		  if (!var->constant_value->has_value(existing->constant_value)) {
3991591693c7b415e9869157c711fe11263c95d74eDavid Li		     linker_error_printf(prog, "initializers for %s "
4001591693c7b415e9869157c711fe11263c95d74eDavid Li					 "`%s' have differing values\n",
4011591693c7b415e9869157c711fe11263c95d74eDavid Li					 mode_string(var), var->name);
4021591693c7b415e9869157c711fe11263c95d74eDavid Li		     return false;
4031591693c7b415e9869157c711fe11263c95d74eDavid Li		  }
4041591693c7b415e9869157c711fe11263c95d74eDavid Li	       } else
4051591693c7b415e9869157c711fe11263c95d74eDavid Li		  /* If the first-seen instance of a particular uniform did not
4061591693c7b415e9869157c711fe11263c95d74eDavid Li		   * have an initializer but a later instance does, copy the
4071591693c7b415e9869157c711fe11263c95d74eDavid Li		   * initializer to the version stored in the symbol table.
4081591693c7b415e9869157c711fe11263c95d74eDavid Li		   */
4091591693c7b415e9869157c711fe11263c95d74eDavid Li		  /* FINISHME: This is wrong.  The constant_value field should
4101591693c7b415e9869157c711fe11263c95d74eDavid Li		   * FINISHME: not be modified!  Imagine a case where a shader
4111591693c7b415e9869157c711fe11263c95d74eDavid Li		   * FINISHME: without an initializer is linked in two different
4121591693c7b415e9869157c711fe11263c95d74eDavid Li		   * FINISHME: programs with shaders that have differing
4131591693c7b415e9869157c711fe11263c95d74eDavid Li		   * FINISHME: initializers.  Linking with the first will
4141591693c7b415e9869157c711fe11263c95d74eDavid Li		   * FINISHME: modify the shader, and linking with the second
4151591693c7b415e9869157c711fe11263c95d74eDavid Li		   * FINISHME: will fail.
4161591693c7b415e9869157c711fe11263c95d74eDavid Li		   */
4171591693c7b415e9869157c711fe11263c95d74eDavid Li		  existing->constant_value =
418d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li		     var->constant_value->clone(hieralloc_parent(existing), NULL);
4191591693c7b415e9869157c711fe11263c95d74eDavid Li	    }
4201591693c7b415e9869157c711fe11263c95d74eDavid Li
4211591693c7b415e9869157c711fe11263c95d74eDavid Li	    if (existing->invariant != var->invariant) {
4221591693c7b415e9869157c711fe11263c95d74eDavid Li	       linker_error_printf(prog, "declarations for %s `%s' have "
4231591693c7b415e9869157c711fe11263c95d74eDavid Li	                           "mismatching invariant qualifiers\n",
4241591693c7b415e9869157c711fe11263c95d74eDavid Li	                           mode_string(var), var->name);
4251591693c7b415e9869157c711fe11263c95d74eDavid Li	       return false;
4261591693c7b415e9869157c711fe11263c95d74eDavid Li	    }
4271591693c7b415e9869157c711fe11263c95d74eDavid Li	 } else
4281591693c7b415e9869157c711fe11263c95d74eDavid Li	    variables.add_variable(var);
4291591693c7b415e9869157c711fe11263c95d74eDavid Li      }
4301591693c7b415e9869157c711fe11263c95d74eDavid Li   }
4311591693c7b415e9869157c711fe11263c95d74eDavid Li
4321591693c7b415e9869157c711fe11263c95d74eDavid Li   return true;
4331591693c7b415e9869157c711fe11263c95d74eDavid Li}
4341591693c7b415e9869157c711fe11263c95d74eDavid Li
4351591693c7b415e9869157c711fe11263c95d74eDavid Li
4361591693c7b415e9869157c711fe11263c95d74eDavid Li/**
4371591693c7b415e9869157c711fe11263c95d74eDavid Li * Perform validation of uniforms used across multiple shader stages
4381591693c7b415e9869157c711fe11263c95d74eDavid Li */
4391591693c7b415e9869157c711fe11263c95d74eDavid Libool
4401591693c7b415e9869157c711fe11263c95d74eDavid Licross_validate_uniforms(struct gl_shader_program *prog)
4411591693c7b415e9869157c711fe11263c95d74eDavid Li{
4421591693c7b415e9869157c711fe11263c95d74eDavid Li   return cross_validate_globals(prog, prog->_LinkedShaders,
4431591693c7b415e9869157c711fe11263c95d74eDavid Li				 MESA_SHADER_TYPES, true);
4441591693c7b415e9869157c711fe11263c95d74eDavid Li}
4451591693c7b415e9869157c711fe11263c95d74eDavid Li
4461591693c7b415e9869157c711fe11263c95d74eDavid Li
4471591693c7b415e9869157c711fe11263c95d74eDavid Li/**
4481591693c7b415e9869157c711fe11263c95d74eDavid Li * Validate that outputs from one stage match inputs of another
4491591693c7b415e9869157c711fe11263c95d74eDavid Li */
4501591693c7b415e9869157c711fe11263c95d74eDavid Libool
4511591693c7b415e9869157c711fe11263c95d74eDavid Licross_validate_outputs_to_inputs(struct gl_shader_program *prog,
4521591693c7b415e9869157c711fe11263c95d74eDavid Li				 gl_shader *producer, gl_shader *consumer)
4531591693c7b415e9869157c711fe11263c95d74eDavid Li{
4543b02c91d7b1fcc777dbdafeb044e0df61e1ff0d8David Li   glsl_symbol_table parameters(prog);
4551591693c7b415e9869157c711fe11263c95d74eDavid Li   /* FINISHME: Figure these out dynamically. */
4561591693c7b415e9869157c711fe11263c95d74eDavid Li   const char *const producer_stage = "vertex";
4571591693c7b415e9869157c711fe11263c95d74eDavid Li   const char *const consumer_stage = "fragment";
4581591693c7b415e9869157c711fe11263c95d74eDavid Li
4591591693c7b415e9869157c711fe11263c95d74eDavid Li   /* Find all shader outputs in the "producer" stage.
4601591693c7b415e9869157c711fe11263c95d74eDavid Li    */
4611591693c7b415e9869157c711fe11263c95d74eDavid Li   foreach_list(node, producer->ir) {
4621591693c7b415e9869157c711fe11263c95d74eDavid Li      ir_variable *const var = ((ir_instruction *) node)->as_variable();
4631591693c7b415e9869157c711fe11263c95d74eDavid Li
4641591693c7b415e9869157c711fe11263c95d74eDavid Li      /* FINISHME: For geometry shaders, this should also look for inout
4651591693c7b415e9869157c711fe11263c95d74eDavid Li       * FINISHME: variables.
4661591693c7b415e9869157c711fe11263c95d74eDavid Li       */
4671591693c7b415e9869157c711fe11263c95d74eDavid Li      if ((var == NULL) || (var->mode != ir_var_out))
4681591693c7b415e9869157c711fe11263c95d74eDavid Li	 continue;
4691591693c7b415e9869157c711fe11263c95d74eDavid Li
4701591693c7b415e9869157c711fe11263c95d74eDavid Li      parameters.add_variable(var);
4711591693c7b415e9869157c711fe11263c95d74eDavid Li   }
4721591693c7b415e9869157c711fe11263c95d74eDavid Li
4731591693c7b415e9869157c711fe11263c95d74eDavid Li
4741591693c7b415e9869157c711fe11263c95d74eDavid Li   /* Find all shader inputs in the "consumer" stage.  Any variables that have
4751591693c7b415e9869157c711fe11263c95d74eDavid Li    * matching outputs already in the symbol table must have the same type and
4761591693c7b415e9869157c711fe11263c95d74eDavid Li    * qualifiers.
4771591693c7b415e9869157c711fe11263c95d74eDavid Li    */
4781591693c7b415e9869157c711fe11263c95d74eDavid Li   foreach_list(node, consumer->ir) {
4791591693c7b415e9869157c711fe11263c95d74eDavid Li      ir_variable *const input = ((ir_instruction *) node)->as_variable();
4801591693c7b415e9869157c711fe11263c95d74eDavid Li
4811591693c7b415e9869157c711fe11263c95d74eDavid Li      /* FINISHME: For geometry shaders, this should also look for inout
4821591693c7b415e9869157c711fe11263c95d74eDavid Li       * FINISHME: variables.
4831591693c7b415e9869157c711fe11263c95d74eDavid Li       */
4841591693c7b415e9869157c711fe11263c95d74eDavid Li      if ((input == NULL) || (input->mode != ir_var_in))
4851591693c7b415e9869157c711fe11263c95d74eDavid Li	 continue;
4861591693c7b415e9869157c711fe11263c95d74eDavid Li
4871591693c7b415e9869157c711fe11263c95d74eDavid Li      ir_variable *const output = parameters.get_variable(input->name);
4881591693c7b415e9869157c711fe11263c95d74eDavid Li      if (output != NULL) {
4891591693c7b415e9869157c711fe11263c95d74eDavid Li	 /* Check that the types match between stages.
4901591693c7b415e9869157c711fe11263c95d74eDavid Li	  */
4911591693c7b415e9869157c711fe11263c95d74eDavid Li	 if (input->type != output->type) {
4921591693c7b415e9869157c711fe11263c95d74eDavid Li	    /* There is a bit of a special case for gl_TexCoord.  This
4931591693c7b415e9869157c711fe11263c95d74eDavid Li	     * built-in is unsized by default.  Appliations that variable
4941591693c7b415e9869157c711fe11263c95d74eDavid Li	     * access it must redeclare it with a size.  There is some
4951591693c7b415e9869157c711fe11263c95d74eDavid Li	     * language in the GLSL spec that implies the fragment shader
4961591693c7b415e9869157c711fe11263c95d74eDavid Li	     * and vertex shader do not have to agree on this size.  Other
4971591693c7b415e9869157c711fe11263c95d74eDavid Li	     * driver behave this way, and one or two applications seem to
4981591693c7b415e9869157c711fe11263c95d74eDavid Li	     * rely on it.
4991591693c7b415e9869157c711fe11263c95d74eDavid Li	     *
5001591693c7b415e9869157c711fe11263c95d74eDavid Li	     * Neither declaration needs to be modified here because the array
5011591693c7b415e9869157c711fe11263c95d74eDavid Li	     * sizes are fixed later when update_array_sizes is called.
5021591693c7b415e9869157c711fe11263c95d74eDavid Li	     *
5031591693c7b415e9869157c711fe11263c95d74eDavid Li	     * From page 48 (page 54 of the PDF) of the GLSL 1.10 spec:
5041591693c7b415e9869157c711fe11263c95d74eDavid Li	     *
5051591693c7b415e9869157c711fe11263c95d74eDavid Li	     *     "Unlike user-defined varying variables, the built-in
5061591693c7b415e9869157c711fe11263c95d74eDavid Li	     *     varying variables don't have a strict one-to-one
5071591693c7b415e9869157c711fe11263c95d74eDavid Li	     *     correspondence between the vertex language and the
5081591693c7b415e9869157c711fe11263c95d74eDavid Li	     *     fragment language."
5091591693c7b415e9869157c711fe11263c95d74eDavid Li	     */
5101591693c7b415e9869157c711fe11263c95d74eDavid Li	    if (!output->type->is_array()
5111591693c7b415e9869157c711fe11263c95d74eDavid Li		|| (strncmp("gl_", output->name, 3) != 0)) {
5121591693c7b415e9869157c711fe11263c95d74eDavid Li	       linker_error_printf(prog,
5131591693c7b415e9869157c711fe11263c95d74eDavid Li				   "%s shader output `%s' declared as "
5141591693c7b415e9869157c711fe11263c95d74eDavid Li				   "type `%s', but %s shader input declared "
5151591693c7b415e9869157c711fe11263c95d74eDavid Li				   "as type `%s'\n",
5161591693c7b415e9869157c711fe11263c95d74eDavid Li				   producer_stage, output->name,
5171591693c7b415e9869157c711fe11263c95d74eDavid Li				   output->type->name,
5181591693c7b415e9869157c711fe11263c95d74eDavid Li				   consumer_stage, input->type->name);
5191591693c7b415e9869157c711fe11263c95d74eDavid Li	       return false;
5201591693c7b415e9869157c711fe11263c95d74eDavid Li	    }
5211591693c7b415e9869157c711fe11263c95d74eDavid Li	 }
5221591693c7b415e9869157c711fe11263c95d74eDavid Li
5231591693c7b415e9869157c711fe11263c95d74eDavid Li	 /* Check that all of the qualifiers match between stages.
5241591693c7b415e9869157c711fe11263c95d74eDavid Li	  */
5251591693c7b415e9869157c711fe11263c95d74eDavid Li	 if (input->centroid != output->centroid) {
5261591693c7b415e9869157c711fe11263c95d74eDavid Li	    linker_error_printf(prog,
5271591693c7b415e9869157c711fe11263c95d74eDavid Li				"%s shader output `%s' %s centroid qualifier, "
5281591693c7b415e9869157c711fe11263c95d74eDavid Li				"but %s shader input %s centroid qualifier\n",
5291591693c7b415e9869157c711fe11263c95d74eDavid Li				producer_stage,
5301591693c7b415e9869157c711fe11263c95d74eDavid Li				output->name,
5311591693c7b415e9869157c711fe11263c95d74eDavid Li				(output->centroid) ? "has" : "lacks",
5321591693c7b415e9869157c711fe11263c95d74eDavid Li				consumer_stage,
5331591693c7b415e9869157c711fe11263c95d74eDavid Li				(input->centroid) ? "has" : "lacks");
5341591693c7b415e9869157c711fe11263c95d74eDavid Li	    return false;
5351591693c7b415e9869157c711fe11263c95d74eDavid Li	 }
5361591693c7b415e9869157c711fe11263c95d74eDavid Li
5371591693c7b415e9869157c711fe11263c95d74eDavid Li	 if (input->invariant != output->invariant) {
5381591693c7b415e9869157c711fe11263c95d74eDavid Li	    linker_error_printf(prog,
5391591693c7b415e9869157c711fe11263c95d74eDavid Li				"%s shader output `%s' %s invariant qualifier, "
5401591693c7b415e9869157c711fe11263c95d74eDavid Li				"but %s shader input %s invariant qualifier\n",
5411591693c7b415e9869157c711fe11263c95d74eDavid Li				producer_stage,
5421591693c7b415e9869157c711fe11263c95d74eDavid Li				output->name,
5431591693c7b415e9869157c711fe11263c95d74eDavid Li				(output->invariant) ? "has" : "lacks",
5441591693c7b415e9869157c711fe11263c95d74eDavid Li				consumer_stage,
5451591693c7b415e9869157c711fe11263c95d74eDavid Li				(input->invariant) ? "has" : "lacks");
5461591693c7b415e9869157c711fe11263c95d74eDavid Li	    return false;
5471591693c7b415e9869157c711fe11263c95d74eDavid Li	 }
5481591693c7b415e9869157c711fe11263c95d74eDavid Li
5491591693c7b415e9869157c711fe11263c95d74eDavid Li	 if (input->interpolation != output->interpolation) {
5501591693c7b415e9869157c711fe11263c95d74eDavid Li	    linker_error_printf(prog,
5511591693c7b415e9869157c711fe11263c95d74eDavid Li				"%s shader output `%s' specifies %s "
5521591693c7b415e9869157c711fe11263c95d74eDavid Li				"interpolation qualifier, "
5531591693c7b415e9869157c711fe11263c95d74eDavid Li				"but %s shader input specifies %s "
5541591693c7b415e9869157c711fe11263c95d74eDavid Li				"interpolation qualifier\n",
5551591693c7b415e9869157c711fe11263c95d74eDavid Li				producer_stage,
5561591693c7b415e9869157c711fe11263c95d74eDavid Li				output->name,
5571591693c7b415e9869157c711fe11263c95d74eDavid Li				output->interpolation_string(),
5581591693c7b415e9869157c711fe11263c95d74eDavid Li				consumer_stage,
5591591693c7b415e9869157c711fe11263c95d74eDavid Li				input->interpolation_string());
5601591693c7b415e9869157c711fe11263c95d74eDavid Li	    return false;
5611591693c7b415e9869157c711fe11263c95d74eDavid Li	 }
5621591693c7b415e9869157c711fe11263c95d74eDavid Li      }
5631591693c7b415e9869157c711fe11263c95d74eDavid Li   }
5641591693c7b415e9869157c711fe11263c95d74eDavid Li
5651591693c7b415e9869157c711fe11263c95d74eDavid Li   return true;
5661591693c7b415e9869157c711fe11263c95d74eDavid Li}
5671591693c7b415e9869157c711fe11263c95d74eDavid Li
5681591693c7b415e9869157c711fe11263c95d74eDavid Li
5691591693c7b415e9869157c711fe11263c95d74eDavid Li/**
5701591693c7b415e9869157c711fe11263c95d74eDavid Li * Populates a shaders symbol table with all global declarations
5711591693c7b415e9869157c711fe11263c95d74eDavid Li */
5721591693c7b415e9869157c711fe11263c95d74eDavid Listatic void
5731591693c7b415e9869157c711fe11263c95d74eDavid Lipopulate_symbol_table(gl_shader *sh)
5741591693c7b415e9869157c711fe11263c95d74eDavid Li{
5753b02c91d7b1fcc777dbdafeb044e0df61e1ff0d8David Li   sh->symbols = new(sh) glsl_symbol_table(sh);
5761591693c7b415e9869157c711fe11263c95d74eDavid Li
5771591693c7b415e9869157c711fe11263c95d74eDavid Li   foreach_list(node, sh->ir) {
5781591693c7b415e9869157c711fe11263c95d74eDavid Li      ir_instruction *const inst = (ir_instruction *) node;
5791591693c7b415e9869157c711fe11263c95d74eDavid Li      ir_variable *var;
5801591693c7b415e9869157c711fe11263c95d74eDavid Li      ir_function *func;
5811591693c7b415e9869157c711fe11263c95d74eDavid Li
5821591693c7b415e9869157c711fe11263c95d74eDavid Li      if ((func = inst->as_function()) != NULL) {
5831591693c7b415e9869157c711fe11263c95d74eDavid Li	 sh->symbols->add_function(func);
5841591693c7b415e9869157c711fe11263c95d74eDavid Li      } else if ((var = inst->as_variable()) != NULL) {
5851591693c7b415e9869157c711fe11263c95d74eDavid Li	 sh->symbols->add_variable(var);
5861591693c7b415e9869157c711fe11263c95d74eDavid Li      }
5871591693c7b415e9869157c711fe11263c95d74eDavid Li   }
5881591693c7b415e9869157c711fe11263c95d74eDavid Li}
5891591693c7b415e9869157c711fe11263c95d74eDavid Li
5901591693c7b415e9869157c711fe11263c95d74eDavid Li
5911591693c7b415e9869157c711fe11263c95d74eDavid Li/**
5921591693c7b415e9869157c711fe11263c95d74eDavid Li * Remap variables referenced in an instruction tree
5931591693c7b415e9869157c711fe11263c95d74eDavid Li *
5941591693c7b415e9869157c711fe11263c95d74eDavid Li * This is used when instruction trees are cloned from one shader and placed in
5951591693c7b415e9869157c711fe11263c95d74eDavid Li * another.  These trees will contain references to \c ir_variable nodes that
5961591693c7b415e9869157c711fe11263c95d74eDavid Li * do not exist in the target shader.  This function finds these \c ir_variable
5971591693c7b415e9869157c711fe11263c95d74eDavid Li * references and replaces the references with matching variables in the target
5981591693c7b415e9869157c711fe11263c95d74eDavid Li * shader.
5991591693c7b415e9869157c711fe11263c95d74eDavid Li *
6001591693c7b415e9869157c711fe11263c95d74eDavid Li * If there is no matching variable in the target shader, a clone of the
6011591693c7b415e9869157c711fe11263c95d74eDavid Li * \c ir_variable is made and added to the target shader.  The new variable is
6021591693c7b415e9869157c711fe11263c95d74eDavid Li * added to \b both the instruction stream and the symbol table.
6031591693c7b415e9869157c711fe11263c95d74eDavid Li *
6041591693c7b415e9869157c711fe11263c95d74eDavid Li * \param inst         IR tree that is to be processed.
6051591693c7b415e9869157c711fe11263c95d74eDavid Li * \param symbols      Symbol table containing global scope symbols in the
6061591693c7b415e9869157c711fe11263c95d74eDavid Li *                     linked shader.
6071591693c7b415e9869157c711fe11263c95d74eDavid Li * \param instructions Instruction stream where new variable declarations
6081591693c7b415e9869157c711fe11263c95d74eDavid Li *                     should be added.
6091591693c7b415e9869157c711fe11263c95d74eDavid Li */
6101591693c7b415e9869157c711fe11263c95d74eDavid Livoid
6111591693c7b415e9869157c711fe11263c95d74eDavid Liremap_variables(ir_instruction *inst, struct gl_shader *target,
6121591693c7b415e9869157c711fe11263c95d74eDavid Li		hash_table *temps)
6131591693c7b415e9869157c711fe11263c95d74eDavid Li{
6141591693c7b415e9869157c711fe11263c95d74eDavid Li   class remap_visitor : public ir_hierarchical_visitor {
6151591693c7b415e9869157c711fe11263c95d74eDavid Li   public:
6161591693c7b415e9869157c711fe11263c95d74eDavid Li	 remap_visitor(struct gl_shader *target,
6171591693c7b415e9869157c711fe11263c95d74eDavid Li		    hash_table *temps)
6181591693c7b415e9869157c711fe11263c95d74eDavid Li      {
6191591693c7b415e9869157c711fe11263c95d74eDavid Li	 this->target = target;
6201591693c7b415e9869157c711fe11263c95d74eDavid Li	 this->symbols = target->symbols;
6211591693c7b415e9869157c711fe11263c95d74eDavid Li	 this->instructions = target->ir;
6221591693c7b415e9869157c711fe11263c95d74eDavid Li	 this->temps = temps;
6231591693c7b415e9869157c711fe11263c95d74eDavid Li      }
6241591693c7b415e9869157c711fe11263c95d74eDavid Li
6251591693c7b415e9869157c711fe11263c95d74eDavid Li      virtual ir_visitor_status visit(ir_dereference_variable *ir)
6261591693c7b415e9869157c711fe11263c95d74eDavid Li      {
6271591693c7b415e9869157c711fe11263c95d74eDavid Li	 if (ir->var->mode == ir_var_temporary) {
6281591693c7b415e9869157c711fe11263c95d74eDavid Li	    ir_variable *var = (ir_variable *) hash_table_find(temps, ir->var);
6291591693c7b415e9869157c711fe11263c95d74eDavid Li
6301591693c7b415e9869157c711fe11263c95d74eDavid Li	    assert(var != NULL);
6311591693c7b415e9869157c711fe11263c95d74eDavid Li	    ir->var = var;
6321591693c7b415e9869157c711fe11263c95d74eDavid Li	    return visit_continue;
6331591693c7b415e9869157c711fe11263c95d74eDavid Li	 }
6341591693c7b415e9869157c711fe11263c95d74eDavid Li
6351591693c7b415e9869157c711fe11263c95d74eDavid Li	 ir_variable *const existing =
6361591693c7b415e9869157c711fe11263c95d74eDavid Li	    this->symbols->get_variable(ir->var->name);
6371591693c7b415e9869157c711fe11263c95d74eDavid Li	 if (existing != NULL)
6381591693c7b415e9869157c711fe11263c95d74eDavid Li	    ir->var = existing;
6391591693c7b415e9869157c711fe11263c95d74eDavid Li	 else {
6401591693c7b415e9869157c711fe11263c95d74eDavid Li	    ir_variable *copy = ir->var->clone(this->target, NULL);
6411591693c7b415e9869157c711fe11263c95d74eDavid Li
6421591693c7b415e9869157c711fe11263c95d74eDavid Li	    this->symbols->add_variable(copy);
6431591693c7b415e9869157c711fe11263c95d74eDavid Li	    this->instructions->push_head(copy);
6441591693c7b415e9869157c711fe11263c95d74eDavid Li	    ir->var = copy;
6451591693c7b415e9869157c711fe11263c95d74eDavid Li	 }
6461591693c7b415e9869157c711fe11263c95d74eDavid Li
6471591693c7b415e9869157c711fe11263c95d74eDavid Li	 return visit_continue;
6481591693c7b415e9869157c711fe11263c95d74eDavid Li      }
6491591693c7b415e9869157c711fe11263c95d74eDavid Li
6501591693c7b415e9869157c711fe11263c95d74eDavid Li   private:
6511591693c7b415e9869157c711fe11263c95d74eDavid Li      struct gl_shader *target;
6521591693c7b415e9869157c711fe11263c95d74eDavid Li      glsl_symbol_table *symbols;
6531591693c7b415e9869157c711fe11263c95d74eDavid Li      exec_list *instructions;
6541591693c7b415e9869157c711fe11263c95d74eDavid Li      hash_table *temps;
6551591693c7b415e9869157c711fe11263c95d74eDavid Li   };
6561591693c7b415e9869157c711fe11263c95d74eDavid Li
6571591693c7b415e9869157c711fe11263c95d74eDavid Li   remap_visitor v(target, temps);
6581591693c7b415e9869157c711fe11263c95d74eDavid Li
6591591693c7b415e9869157c711fe11263c95d74eDavid Li   inst->accept(&v);
6601591693c7b415e9869157c711fe11263c95d74eDavid Li}
6611591693c7b415e9869157c711fe11263c95d74eDavid Li
6621591693c7b415e9869157c711fe11263c95d74eDavid Li
6631591693c7b415e9869157c711fe11263c95d74eDavid Li/**
6641591693c7b415e9869157c711fe11263c95d74eDavid Li * Move non-declarations from one instruction stream to another
6651591693c7b415e9869157c711fe11263c95d74eDavid Li *
6661591693c7b415e9869157c711fe11263c95d74eDavid Li * The intended usage pattern of this function is to pass the pointer to the
6671591693c7b415e9869157c711fe11263c95d74eDavid Li * head sentinel of a list (i.e., a pointer to the list cast to an \c exec_node
6681591693c7b415e9869157c711fe11263c95d74eDavid Li * pointer) for \c last and \c false for \c make_copies on the first
6691591693c7b415e9869157c711fe11263c95d74eDavid Li * call.  Successive calls pass the return value of the previous call for
6701591693c7b415e9869157c711fe11263c95d74eDavid Li * \c last and \c true for \c make_copies.
6711591693c7b415e9869157c711fe11263c95d74eDavid Li *
6721591693c7b415e9869157c711fe11263c95d74eDavid Li * \param instructions Source instruction stream
6731591693c7b415e9869157c711fe11263c95d74eDavid Li * \param last         Instruction after which new instructions should be
6741591693c7b415e9869157c711fe11263c95d74eDavid Li *                     inserted in the target instruction stream
6751591693c7b415e9869157c711fe11263c95d74eDavid Li * \param make_copies  Flag selecting whether instructions in \c instructions
6761591693c7b415e9869157c711fe11263c95d74eDavid Li *                     should be copied (via \c ir_instruction::clone) into the
6771591693c7b415e9869157c711fe11263c95d74eDavid Li *                     target list or moved.
6781591693c7b415e9869157c711fe11263c95d74eDavid Li *
6791591693c7b415e9869157c711fe11263c95d74eDavid Li * \return
6801591693c7b415e9869157c711fe11263c95d74eDavid Li * The new "last" instruction in the target instruction stream.  This pointer
6811591693c7b415e9869157c711fe11263c95d74eDavid Li * is suitable for use as the \c last parameter of a later call to this
6821591693c7b415e9869157c711fe11263c95d74eDavid Li * function.
6831591693c7b415e9869157c711fe11263c95d74eDavid Li */
6841591693c7b415e9869157c711fe11263c95d74eDavid Liexec_node *
6851591693c7b415e9869157c711fe11263c95d74eDavid Limove_non_declarations(exec_list *instructions, exec_node *last,
6861591693c7b415e9869157c711fe11263c95d74eDavid Li		      bool make_copies, gl_shader *target)
6871591693c7b415e9869157c711fe11263c95d74eDavid Li{
6881591693c7b415e9869157c711fe11263c95d74eDavid Li   hash_table *temps = NULL;
6891591693c7b415e9869157c711fe11263c95d74eDavid Li
6901591693c7b415e9869157c711fe11263c95d74eDavid Li   if (make_copies)
6911591693c7b415e9869157c711fe11263c95d74eDavid Li      temps = hash_table_ctor(0, hash_table_pointer_hash,
6921591693c7b415e9869157c711fe11263c95d74eDavid Li			      hash_table_pointer_compare);
6931591693c7b415e9869157c711fe11263c95d74eDavid Li
6941591693c7b415e9869157c711fe11263c95d74eDavid Li   foreach_list_safe(node, instructions) {
6951591693c7b415e9869157c711fe11263c95d74eDavid Li      ir_instruction *inst = (ir_instruction *) node;
6961591693c7b415e9869157c711fe11263c95d74eDavid Li
6971591693c7b415e9869157c711fe11263c95d74eDavid Li      if (inst->as_function())
6981591693c7b415e9869157c711fe11263c95d74eDavid Li	 continue;
6991591693c7b415e9869157c711fe11263c95d74eDavid Li
7001591693c7b415e9869157c711fe11263c95d74eDavid Li      ir_variable *var = inst->as_variable();
7011591693c7b415e9869157c711fe11263c95d74eDavid Li      if ((var != NULL) && (var->mode != ir_var_temporary))
7021591693c7b415e9869157c711fe11263c95d74eDavid Li	 continue;
7031591693c7b415e9869157c711fe11263c95d74eDavid Li
7041591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(inst->as_assignment()
7051591693c7b415e9869157c711fe11263c95d74eDavid Li	     || ((var != NULL) && (var->mode == ir_var_temporary)));
7061591693c7b415e9869157c711fe11263c95d74eDavid Li
7071591693c7b415e9869157c711fe11263c95d74eDavid Li      if (make_copies) {
7081591693c7b415e9869157c711fe11263c95d74eDavid Li	 inst = inst->clone(target, NULL);
7091591693c7b415e9869157c711fe11263c95d74eDavid Li
7101591693c7b415e9869157c711fe11263c95d74eDavid Li	 if (var != NULL)
7111591693c7b415e9869157c711fe11263c95d74eDavid Li	    hash_table_insert(temps, inst, var);
7121591693c7b415e9869157c711fe11263c95d74eDavid Li	 else
7131591693c7b415e9869157c711fe11263c95d74eDavid Li	    remap_variables(inst, target, temps);
7141591693c7b415e9869157c711fe11263c95d74eDavid Li      } else {
7151591693c7b415e9869157c711fe11263c95d74eDavid Li	 inst->remove();
7161591693c7b415e9869157c711fe11263c95d74eDavid Li      }
7171591693c7b415e9869157c711fe11263c95d74eDavid Li
7181591693c7b415e9869157c711fe11263c95d74eDavid Li      last->insert_after(inst);
7191591693c7b415e9869157c711fe11263c95d74eDavid Li      last = inst;
7201591693c7b415e9869157c711fe11263c95d74eDavid Li   }
7211591693c7b415e9869157c711fe11263c95d74eDavid Li
7221591693c7b415e9869157c711fe11263c95d74eDavid Li   if (make_copies)
7231591693c7b415e9869157c711fe11263c95d74eDavid Li      hash_table_dtor(temps);
7241591693c7b415e9869157c711fe11263c95d74eDavid Li
7251591693c7b415e9869157c711fe11263c95d74eDavid Li   return last;
7261591693c7b415e9869157c711fe11263c95d74eDavid Li}
7271591693c7b415e9869157c711fe11263c95d74eDavid Li
7281591693c7b415e9869157c711fe11263c95d74eDavid Li/**
7291591693c7b415e9869157c711fe11263c95d74eDavid Li * Get the function signature for main from a shader
7301591693c7b415e9869157c711fe11263c95d74eDavid Li */
7311591693c7b415e9869157c711fe11263c95d74eDavid Listatic ir_function_signature *
7321591693c7b415e9869157c711fe11263c95d74eDavid Liget_main_function_signature(gl_shader *sh)
7331591693c7b415e9869157c711fe11263c95d74eDavid Li{
7341591693c7b415e9869157c711fe11263c95d74eDavid Li   ir_function *const f = sh->symbols->get_function("main");
7351591693c7b415e9869157c711fe11263c95d74eDavid Li   if (f != NULL) {
7361591693c7b415e9869157c711fe11263c95d74eDavid Li      exec_list void_parameters;
7371591693c7b415e9869157c711fe11263c95d74eDavid Li
7381591693c7b415e9869157c711fe11263c95d74eDavid Li      /* Look for the 'void main()' signature and ensure that it's defined.
7391591693c7b415e9869157c711fe11263c95d74eDavid Li       * This keeps the linker from accidentally pick a shader that just
7401591693c7b415e9869157c711fe11263c95d74eDavid Li       * contains a prototype for main.
7411591693c7b415e9869157c711fe11263c95d74eDavid Li       *
7421591693c7b415e9869157c711fe11263c95d74eDavid Li       * We don't have to check for multiple definitions of main (in multiple
7431591693c7b415e9869157c711fe11263c95d74eDavid Li       * shaders) because that would have already been caught above.
7441591693c7b415e9869157c711fe11263c95d74eDavid Li       */
7451591693c7b415e9869157c711fe11263c95d74eDavid Li      ir_function_signature *sig = f->matching_signature(&void_parameters);
7461591693c7b415e9869157c711fe11263c95d74eDavid Li      if ((sig != NULL) && sig->is_defined) {
7471591693c7b415e9869157c711fe11263c95d74eDavid Li	 return sig;
7481591693c7b415e9869157c711fe11263c95d74eDavid Li      }
7491591693c7b415e9869157c711fe11263c95d74eDavid Li   }
7501591693c7b415e9869157c711fe11263c95d74eDavid Li
7511591693c7b415e9869157c711fe11263c95d74eDavid Li   return NULL;
7521591693c7b415e9869157c711fe11263c95d74eDavid Li}
7531591693c7b415e9869157c711fe11263c95d74eDavid Li
7541591693c7b415e9869157c711fe11263c95d74eDavid Li
7551591693c7b415e9869157c711fe11263c95d74eDavid Li/**
7561591693c7b415e9869157c711fe11263c95d74eDavid Li * Combine a group of shaders for a single stage to generate a linked shader
7571591693c7b415e9869157c711fe11263c95d74eDavid Li *
7581591693c7b415e9869157c711fe11263c95d74eDavid Li * \note
7591591693c7b415e9869157c711fe11263c95d74eDavid Li * If this function is supplied a single shader, it is cloned, and the new
7601591693c7b415e9869157c711fe11263c95d74eDavid Li * shader is returned.
7611591693c7b415e9869157c711fe11263c95d74eDavid Li */
7621591693c7b415e9869157c711fe11263c95d74eDavid Listatic struct gl_shader *
7631591693c7b415e9869157c711fe11263c95d74eDavid Lilink_intrastage_shaders(void *mem_ctx,
7641591693c7b415e9869157c711fe11263c95d74eDavid Li			struct gl_context *ctx,
7651591693c7b415e9869157c711fe11263c95d74eDavid Li			struct gl_shader_program *prog,
7661591693c7b415e9869157c711fe11263c95d74eDavid Li			struct gl_shader **shader_list,
7671591693c7b415e9869157c711fe11263c95d74eDavid Li			unsigned num_shaders)
7681591693c7b415e9869157c711fe11263c95d74eDavid Li{
7691591693c7b415e9869157c711fe11263c95d74eDavid Li   /* Check that global variables defined in multiple shaders are consistent.
7701591693c7b415e9869157c711fe11263c95d74eDavid Li    */
7711591693c7b415e9869157c711fe11263c95d74eDavid Li   if (!cross_validate_globals(prog, shader_list, num_shaders, false))
7721591693c7b415e9869157c711fe11263c95d74eDavid Li      return NULL;
7731591693c7b415e9869157c711fe11263c95d74eDavid Li
7741591693c7b415e9869157c711fe11263c95d74eDavid Li   /* Check that there is only a single definition of each function signature
7751591693c7b415e9869157c711fe11263c95d74eDavid Li    * across all shaders.
7761591693c7b415e9869157c711fe11263c95d74eDavid Li    */
7771591693c7b415e9869157c711fe11263c95d74eDavid Li   for (unsigned i = 0; i < (num_shaders - 1); i++) {
7781591693c7b415e9869157c711fe11263c95d74eDavid Li      foreach_list(node, shader_list[i]->ir) {
7791591693c7b415e9869157c711fe11263c95d74eDavid Li	 ir_function *const f = ((ir_instruction *) node)->as_function();
7801591693c7b415e9869157c711fe11263c95d74eDavid Li
7811591693c7b415e9869157c711fe11263c95d74eDavid Li	 if (f == NULL)
7821591693c7b415e9869157c711fe11263c95d74eDavid Li	    continue;
7831591693c7b415e9869157c711fe11263c95d74eDavid Li
7841591693c7b415e9869157c711fe11263c95d74eDavid Li	 for (unsigned j = i + 1; j < num_shaders; j++) {
7851591693c7b415e9869157c711fe11263c95d74eDavid Li	    ir_function *const other =
7861591693c7b415e9869157c711fe11263c95d74eDavid Li	       shader_list[j]->symbols->get_function(f->name);
7871591693c7b415e9869157c711fe11263c95d74eDavid Li
7881591693c7b415e9869157c711fe11263c95d74eDavid Li	    /* If the other shader has no function (and therefore no function
7891591693c7b415e9869157c711fe11263c95d74eDavid Li	     * signatures) with the same name, skip to the next shader.
7901591693c7b415e9869157c711fe11263c95d74eDavid Li	     */
7911591693c7b415e9869157c711fe11263c95d74eDavid Li	    if (other == NULL)
7921591693c7b415e9869157c711fe11263c95d74eDavid Li	       continue;
7931591693c7b415e9869157c711fe11263c95d74eDavid Li
7941591693c7b415e9869157c711fe11263c95d74eDavid Li	    foreach_iter (exec_list_iterator, iter, *f) {
7951591693c7b415e9869157c711fe11263c95d74eDavid Li	       ir_function_signature *sig =
7961591693c7b415e9869157c711fe11263c95d74eDavid Li		  (ir_function_signature *) iter.get();
7971591693c7b415e9869157c711fe11263c95d74eDavid Li
7981591693c7b415e9869157c711fe11263c95d74eDavid Li	       if (!sig->is_defined || sig->is_builtin)
7991591693c7b415e9869157c711fe11263c95d74eDavid Li		  continue;
8001591693c7b415e9869157c711fe11263c95d74eDavid Li
8011591693c7b415e9869157c711fe11263c95d74eDavid Li	       ir_function_signature *other_sig =
8021591693c7b415e9869157c711fe11263c95d74eDavid Li		  other->exact_matching_signature(& sig->parameters);
8031591693c7b415e9869157c711fe11263c95d74eDavid Li
8041591693c7b415e9869157c711fe11263c95d74eDavid Li	       if ((other_sig != NULL) && other_sig->is_defined
8051591693c7b415e9869157c711fe11263c95d74eDavid Li		   && !other_sig->is_builtin) {
8061591693c7b415e9869157c711fe11263c95d74eDavid Li		  linker_error_printf(prog,
8071591693c7b415e9869157c711fe11263c95d74eDavid Li				      "function `%s' is multiply defined",
8081591693c7b415e9869157c711fe11263c95d74eDavid Li				      f->name);
8091591693c7b415e9869157c711fe11263c95d74eDavid Li		  return NULL;
8101591693c7b415e9869157c711fe11263c95d74eDavid Li	       }
8111591693c7b415e9869157c711fe11263c95d74eDavid Li	    }
8121591693c7b415e9869157c711fe11263c95d74eDavid Li	 }
8131591693c7b415e9869157c711fe11263c95d74eDavid Li      }
8141591693c7b415e9869157c711fe11263c95d74eDavid Li   }
8151591693c7b415e9869157c711fe11263c95d74eDavid Li
8161591693c7b415e9869157c711fe11263c95d74eDavid Li   /* Find the shader that defines main, and make a clone of it.
8171591693c7b415e9869157c711fe11263c95d74eDavid Li    *
8181591693c7b415e9869157c711fe11263c95d74eDavid Li    * Starting with the clone, search for undefined references.  If one is
8191591693c7b415e9869157c711fe11263c95d74eDavid Li    * found, find the shader that defines it.  Clone the reference and add
8201591693c7b415e9869157c711fe11263c95d74eDavid Li    * it to the shader.  Repeat until there are no undefined references or
8211591693c7b415e9869157c711fe11263c95d74eDavid Li    * until a reference cannot be resolved.
8221591693c7b415e9869157c711fe11263c95d74eDavid Li    */
8231591693c7b415e9869157c711fe11263c95d74eDavid Li   gl_shader *main = NULL;
8241591693c7b415e9869157c711fe11263c95d74eDavid Li   for (unsigned i = 0; i < num_shaders; i++) {
8251591693c7b415e9869157c711fe11263c95d74eDavid Li      if (get_main_function_signature(shader_list[i]) != NULL) {
8261591693c7b415e9869157c711fe11263c95d74eDavid Li	 main = shader_list[i];
8271591693c7b415e9869157c711fe11263c95d74eDavid Li	 break;
8281591693c7b415e9869157c711fe11263c95d74eDavid Li      }
8291591693c7b415e9869157c711fe11263c95d74eDavid Li   }
8301591693c7b415e9869157c711fe11263c95d74eDavid Li
8311591693c7b415e9869157c711fe11263c95d74eDavid Li   if (main == NULL) {
8321591693c7b415e9869157c711fe11263c95d74eDavid Li      linker_error_printf(prog, "%s shader lacks `main'\n",
8331591693c7b415e9869157c711fe11263c95d74eDavid Li			  (shader_list[0]->Type == GL_VERTEX_SHADER)
8341591693c7b415e9869157c711fe11263c95d74eDavid Li			  ? "vertex" : "fragment");
8351591693c7b415e9869157c711fe11263c95d74eDavid Li      return NULL;
8361591693c7b415e9869157c711fe11263c95d74eDavid Li   }
8371591693c7b415e9869157c711fe11263c95d74eDavid Li
838d274f94df69a016386195efcf0640802c7d7d2dcDavid Li   gl_shader *linked = ctx->Driver.NewShader(ctx, 0, main->Type);
839d274f94df69a016386195efcf0640802c7d7d2dcDavid Li   hieralloc_steal(prog, linked);
8401591693c7b415e9869157c711fe11263c95d74eDavid Li   linked->ir = new(linked) exec_list;
8411591693c7b415e9869157c711fe11263c95d74eDavid Li   clone_ir_list(mem_ctx, linked->ir, main->ir);
8421591693c7b415e9869157c711fe11263c95d74eDavid Li
8431591693c7b415e9869157c711fe11263c95d74eDavid Li   populate_symbol_table(linked);
8441591693c7b415e9869157c711fe11263c95d74eDavid Li
8451591693c7b415e9869157c711fe11263c95d74eDavid Li   /* The a pointer to the main function in the final linked shader (i.e., the
8461591693c7b415e9869157c711fe11263c95d74eDavid Li    * copy of the original shader that contained the main function).
8471591693c7b415e9869157c711fe11263c95d74eDavid Li    */
8481591693c7b415e9869157c711fe11263c95d74eDavid Li   ir_function_signature *const main_sig = get_main_function_signature(linked);
8491591693c7b415e9869157c711fe11263c95d74eDavid Li
8501591693c7b415e9869157c711fe11263c95d74eDavid Li   /* Move any instructions other than variable declarations or function
8511591693c7b415e9869157c711fe11263c95d74eDavid Li    * declarations into main.
8521591693c7b415e9869157c711fe11263c95d74eDavid Li    */
8531591693c7b415e9869157c711fe11263c95d74eDavid Li   exec_node *insertion_point =
8541591693c7b415e9869157c711fe11263c95d74eDavid Li      move_non_declarations(linked->ir, (exec_node *) &main_sig->body, false,
8551591693c7b415e9869157c711fe11263c95d74eDavid Li			    linked);
8561591693c7b415e9869157c711fe11263c95d74eDavid Li
8571591693c7b415e9869157c711fe11263c95d74eDavid Li   for (unsigned i = 0; i < num_shaders; i++) {
8581591693c7b415e9869157c711fe11263c95d74eDavid Li      if (shader_list[i] == main)
8591591693c7b415e9869157c711fe11263c95d74eDavid Li	 continue;
8601591693c7b415e9869157c711fe11263c95d74eDavid Li
8611591693c7b415e9869157c711fe11263c95d74eDavid Li      insertion_point = move_non_declarations(shader_list[i]->ir,
8621591693c7b415e9869157c711fe11263c95d74eDavid Li					      insertion_point, true, linked);
8631591693c7b415e9869157c711fe11263c95d74eDavid Li   }
8641591693c7b415e9869157c711fe11263c95d74eDavid Li
8651591693c7b415e9869157c711fe11263c95d74eDavid Li   /* Resolve initializers for global variables in the linked shader.
8661591693c7b415e9869157c711fe11263c95d74eDavid Li    */
8671591693c7b415e9869157c711fe11263c95d74eDavid Li   unsigned num_linking_shaders = num_shaders;
8681591693c7b415e9869157c711fe11263c95d74eDavid Li   for (unsigned i = 0; i < num_shaders; i++)
8691591693c7b415e9869157c711fe11263c95d74eDavid Li      num_linking_shaders += shader_list[i]->num_builtins_to_link;
8701591693c7b415e9869157c711fe11263c95d74eDavid Li
8711591693c7b415e9869157c711fe11263c95d74eDavid Li   gl_shader **linking_shaders =
8721591693c7b415e9869157c711fe11263c95d74eDavid Li      (gl_shader **) calloc(num_linking_shaders, sizeof(gl_shader *));
8731591693c7b415e9869157c711fe11263c95d74eDavid Li
8741591693c7b415e9869157c711fe11263c95d74eDavid Li   memcpy(linking_shaders, shader_list,
8751591693c7b415e9869157c711fe11263c95d74eDavid Li	  sizeof(linking_shaders[0]) * num_shaders);
8761591693c7b415e9869157c711fe11263c95d74eDavid Li
8771591693c7b415e9869157c711fe11263c95d74eDavid Li   unsigned idx = num_shaders;
8781591693c7b415e9869157c711fe11263c95d74eDavid Li   for (unsigned i = 0; i < num_shaders; i++) {
8791591693c7b415e9869157c711fe11263c95d74eDavid Li      memcpy(&linking_shaders[idx], shader_list[i]->builtins_to_link,
8801591693c7b415e9869157c711fe11263c95d74eDavid Li	     sizeof(linking_shaders[0]) * shader_list[i]->num_builtins_to_link);
8811591693c7b415e9869157c711fe11263c95d74eDavid Li      idx += shader_list[i]->num_builtins_to_link;
8821591693c7b415e9869157c711fe11263c95d74eDavid Li   }
8831591693c7b415e9869157c711fe11263c95d74eDavid Li
8841591693c7b415e9869157c711fe11263c95d74eDavid Li   assert(idx == num_linking_shaders);
8851591693c7b415e9869157c711fe11263c95d74eDavid Li
8861591693c7b415e9869157c711fe11263c95d74eDavid Li   if (!link_function_calls(prog, linked, linking_shaders,
8871591693c7b415e9869157c711fe11263c95d74eDavid Li			    num_linking_shaders)) {
8881591693c7b415e9869157c711fe11263c95d74eDavid Li      ctx->Driver.DeleteShader(ctx, linked);
8891591693c7b415e9869157c711fe11263c95d74eDavid Li      linked = NULL;
8901591693c7b415e9869157c711fe11263c95d74eDavid Li   }
8911591693c7b415e9869157c711fe11263c95d74eDavid Li
8921591693c7b415e9869157c711fe11263c95d74eDavid Li   free(linking_shaders);
8931591693c7b415e9869157c711fe11263c95d74eDavid Li
8941591693c7b415e9869157c711fe11263c95d74eDavid Li   /* Make a pass over all global variables to ensure that arrays with
8951591693c7b415e9869157c711fe11263c95d74eDavid Li    * unspecified sizes have a size specified.  The size is inferred from the
8961591693c7b415e9869157c711fe11263c95d74eDavid Li    * max_array_access field.
8971591693c7b415e9869157c711fe11263c95d74eDavid Li    */
8981591693c7b415e9869157c711fe11263c95d74eDavid Li   if (linked != NULL) {
8991591693c7b415e9869157c711fe11263c95d74eDavid Li      foreach_list(node, linked->ir) {
9001591693c7b415e9869157c711fe11263c95d74eDavid Li	 ir_variable *const var = ((ir_instruction *) node)->as_variable();
9011591693c7b415e9869157c711fe11263c95d74eDavid Li
9021591693c7b415e9869157c711fe11263c95d74eDavid Li	 if (var == NULL)
9031591693c7b415e9869157c711fe11263c95d74eDavid Li	    continue;
9041591693c7b415e9869157c711fe11263c95d74eDavid Li
9051591693c7b415e9869157c711fe11263c95d74eDavid Li	 if ((var->mode != ir_var_auto) && (var->mode != ir_var_temporary))
9061591693c7b415e9869157c711fe11263c95d74eDavid Li	    continue;
9071591693c7b415e9869157c711fe11263c95d74eDavid Li
9081591693c7b415e9869157c711fe11263c95d74eDavid Li	 if (!var->type->is_array() || (var->type->length != 0))
9091591693c7b415e9869157c711fe11263c95d74eDavid Li	    continue;
9101591693c7b415e9869157c711fe11263c95d74eDavid Li
9111591693c7b415e9869157c711fe11263c95d74eDavid Li	 const glsl_type *type =
9121591693c7b415e9869157c711fe11263c95d74eDavid Li	    glsl_type::get_array_instance(var->type->fields.array,
9131591693c7b415e9869157c711fe11263c95d74eDavid Li					  var->max_array_access);
9141591693c7b415e9869157c711fe11263c95d74eDavid Li
9151591693c7b415e9869157c711fe11263c95d74eDavid Li	 assert(type != NULL);
9161591693c7b415e9869157c711fe11263c95d74eDavid Li	 var->type = type;
9171591693c7b415e9869157c711fe11263c95d74eDavid Li      }
9181591693c7b415e9869157c711fe11263c95d74eDavid Li   }
9191591693c7b415e9869157c711fe11263c95d74eDavid Li
9201591693c7b415e9869157c711fe11263c95d74eDavid Li   return linked;
9211591693c7b415e9869157c711fe11263c95d74eDavid Li}
9221591693c7b415e9869157c711fe11263c95d74eDavid Li
9231591693c7b415e9869157c711fe11263c95d74eDavid Li
9241591693c7b415e9869157c711fe11263c95d74eDavid Listruct uniform_node {
9251591693c7b415e9869157c711fe11263c95d74eDavid Li   exec_node link;
9261591693c7b415e9869157c711fe11263c95d74eDavid Li   struct gl_uniform *u;
9271591693c7b415e9869157c711fe11263c95d74eDavid Li   unsigned slots;
9281591693c7b415e9869157c711fe11263c95d74eDavid Li};
9291591693c7b415e9869157c711fe11263c95d74eDavid Li
9301591693c7b415e9869157c711fe11263c95d74eDavid Li/**
9311591693c7b415e9869157c711fe11263c95d74eDavid Li * Update the sizes of linked shader uniform arrays to the maximum
9321591693c7b415e9869157c711fe11263c95d74eDavid Li * array index used.
9331591693c7b415e9869157c711fe11263c95d74eDavid Li *
9341591693c7b415e9869157c711fe11263c95d74eDavid Li * From page 81 (page 95 of the PDF) of the OpenGL 2.1 spec:
9351591693c7b415e9869157c711fe11263c95d74eDavid Li *
9361591693c7b415e9869157c711fe11263c95d74eDavid Li *     If one or more elements of an array are active,
9371591693c7b415e9869157c711fe11263c95d74eDavid Li *     GetActiveUniform will return the name of the array in name,
9381591693c7b415e9869157c711fe11263c95d74eDavid Li *     subject to the restrictions listed above. The type of the array
9391591693c7b415e9869157c711fe11263c95d74eDavid Li *     is returned in type. The size parameter contains the highest
9401591693c7b415e9869157c711fe11263c95d74eDavid Li *     array element index used, plus one. The compiler or linker
9411591693c7b415e9869157c711fe11263c95d74eDavid Li *     determines the highest index used.  There will be only one
9421591693c7b415e9869157c711fe11263c95d74eDavid Li *     active uniform reported by the GL per uniform array.
9431591693c7b415e9869157c711fe11263c95d74eDavid Li
9441591693c7b415e9869157c711fe11263c95d74eDavid Li */
9451591693c7b415e9869157c711fe11263c95d74eDavid Listatic void
9461591693c7b415e9869157c711fe11263c95d74eDavid Liupdate_array_sizes(struct gl_shader_program *prog)
9471591693c7b415e9869157c711fe11263c95d74eDavid Li{
9481591693c7b415e9869157c711fe11263c95d74eDavid Li   for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) {
9491591693c7b415e9869157c711fe11263c95d74eDavid Li	 if (prog->_LinkedShaders[i] == NULL)
9501591693c7b415e9869157c711fe11263c95d74eDavid Li	    continue;
9511591693c7b415e9869157c711fe11263c95d74eDavid Li
9521591693c7b415e9869157c711fe11263c95d74eDavid Li      foreach_list(node, prog->_LinkedShaders[i]->ir) {
9531591693c7b415e9869157c711fe11263c95d74eDavid Li	 ir_variable *const var = ((ir_instruction *) node)->as_variable();
9541591693c7b415e9869157c711fe11263c95d74eDavid Li
9551591693c7b415e9869157c711fe11263c95d74eDavid Li	 if ((var == NULL) || (var->mode != ir_var_uniform &&
9561591693c7b415e9869157c711fe11263c95d74eDavid Li			       var->mode != ir_var_in &&
9571591693c7b415e9869157c711fe11263c95d74eDavid Li			       var->mode != ir_var_out) ||
9581591693c7b415e9869157c711fe11263c95d74eDavid Li	     !var->type->is_array())
9591591693c7b415e9869157c711fe11263c95d74eDavid Li	    continue;
9601591693c7b415e9869157c711fe11263c95d74eDavid Li
9611591693c7b415e9869157c711fe11263c95d74eDavid Li	 unsigned int size = var->max_array_access;
9621591693c7b415e9869157c711fe11263c95d74eDavid Li	 for (unsigned j = 0; j < MESA_SHADER_TYPES; j++) {
9631591693c7b415e9869157c711fe11263c95d74eDavid Li	       if (prog->_LinkedShaders[j] == NULL)
9641591693c7b415e9869157c711fe11263c95d74eDavid Li		  continue;
9651591693c7b415e9869157c711fe11263c95d74eDavid Li
9661591693c7b415e9869157c711fe11263c95d74eDavid Li	    foreach_list(node2, prog->_LinkedShaders[j]->ir) {
9671591693c7b415e9869157c711fe11263c95d74eDavid Li	       ir_variable *other_var = ((ir_instruction *) node2)->as_variable();
9681591693c7b415e9869157c711fe11263c95d74eDavid Li	       if (!other_var)
9691591693c7b415e9869157c711fe11263c95d74eDavid Li		  continue;
9701591693c7b415e9869157c711fe11263c95d74eDavid Li
9711591693c7b415e9869157c711fe11263c95d74eDavid Li	       if (strcmp(var->name, other_var->name) == 0 &&
9721591693c7b415e9869157c711fe11263c95d74eDavid Li		   other_var->max_array_access > size) {
9731591693c7b415e9869157c711fe11263c95d74eDavid Li		  size = other_var->max_array_access;
9741591693c7b415e9869157c711fe11263c95d74eDavid Li	       }
9751591693c7b415e9869157c711fe11263c95d74eDavid Li	    }
9761591693c7b415e9869157c711fe11263c95d74eDavid Li	 }
9771591693c7b415e9869157c711fe11263c95d74eDavid Li
9781591693c7b415e9869157c711fe11263c95d74eDavid Li	 if (size + 1 != var->type->fields.array->length) {
9791591693c7b415e9869157c711fe11263c95d74eDavid Li	    var->type = glsl_type::get_array_instance(var->type->fields.array,
9801591693c7b415e9869157c711fe11263c95d74eDavid Li						      size + 1);
9811591693c7b415e9869157c711fe11263c95d74eDavid Li	    /* FINISHME: We should update the types of array
9821591693c7b415e9869157c711fe11263c95d74eDavid Li	     * dereferences of this variable now.
9831591693c7b415e9869157c711fe11263c95d74eDavid Li	     */
9841591693c7b415e9869157c711fe11263c95d74eDavid Li	 }
9851591693c7b415e9869157c711fe11263c95d74eDavid Li      }
9861591693c7b415e9869157c711fe11263c95d74eDavid Li   }
9871591693c7b415e9869157c711fe11263c95d74eDavid Li}
9881591693c7b415e9869157c711fe11263c95d74eDavid Li
989c0025eb1a3d421c0355a21db9d8ea2bd81278460David Listatic int // returns location assigned
9901591693c7b415e9869157c711fe11263c95d74eDavid Liadd_uniform(void *mem_ctx, exec_list *uniforms, struct hash_table *ht,
9911591693c7b415e9869157c711fe11263c95d74eDavid Li	    const char *name, const glsl_type *type, GLenum shader_type,
992e82376d380005c21cb70637d42104fcd4d652843David Li	    unsigned *next_shader_pos, unsigned *total_uniforms, unsigned *next_sampler_pos, unsigned * samplers_used)
9931591693c7b415e9869157c711fe11263c95d74eDavid Li{
994c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li   int index = -1;
9951591693c7b415e9869157c711fe11263c95d74eDavid Li   if (type->is_record()) {
9961591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned int i = 0; i < type->length; i++) {
997c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         const glsl_type *field_type = type->fields.structure[i].type;
998c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         char *field_name = hieralloc_asprintf(mem_ctx, "%s.%s", name,
9991591693c7b415e9869157c711fe11263c95d74eDavid Li					    type->fields.structure[i].name);
10001591693c7b415e9869157c711fe11263c95d74eDavid Li
1001c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         int firstIndex = add_uniform(mem_ctx, uniforms, ht, field_name, field_type,
1002e82376d380005c21cb70637d42104fcd4d652843David Li            shader_type, next_shader_pos, total_uniforms, next_sampler_pos, samplers_used);
1003c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         if (i == 0)
1004c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li            index = firstIndex;
10051591693c7b415e9869157c711fe11263c95d74eDavid Li      }
10061591693c7b415e9869157c711fe11263c95d74eDavid Li   } else {
10071591693c7b415e9869157c711fe11263c95d74eDavid Li      uniform_node *n = (uniform_node *) hash_table_find(ht, name);
10081591693c7b415e9869157c711fe11263c95d74eDavid Li      unsigned int vec4_slots;
10091591693c7b415e9869157c711fe11263c95d74eDavid Li      const glsl_type *array_elem_type = NULL;
10101591693c7b415e9869157c711fe11263c95d74eDavid Li
10111591693c7b415e9869157c711fe11263c95d74eDavid Li      if (type->is_array()) {
1012c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         array_elem_type = type->fields.array;
1013c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         /* Array of structures. */
1014c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         if (array_elem_type->is_record()) {
1015c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li            for (unsigned int i = 0; i < type->length; i++) {
1016c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li               char *elem_name = hieralloc_asprintf(mem_ctx, "%s[%d]", name, i);
1017c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li               int firstIndex = add_uniform(mem_ctx, uniforms, ht, elem_name, array_elem_type,
1018e82376d380005c21cb70637d42104fcd4d652843David Li                  shader_type, next_shader_pos, total_uniforms, next_sampler_pos, samplers_used);
1019c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li               if (i == 0)
1020c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li                  index = firstIndex;
1021c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li            }
1022c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li            return index;
1023c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         }
10241591693c7b415e9869157c711fe11263c95d74eDavid Li      }
10251591693c7b415e9869157c711fe11263c95d74eDavid Li
10261591693c7b415e9869157c711fe11263c95d74eDavid Li      /* Fix the storage size of samplers at 1 vec4 each. Be sure to pad out
10271591693c7b415e9869157c711fe11263c95d74eDavid Li       * vectors to vec4 slots.
10281591693c7b415e9869157c711fe11263c95d74eDavid Li       */
10291591693c7b415e9869157c711fe11263c95d74eDavid Li      if (type->is_array()) {
1030c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         if (array_elem_type->is_sampler())
1031c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li            vec4_slots = type->length;
1032c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         else
1033c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li            vec4_slots = type->length * array_elem_type->matrix_columns;
1034c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li      } else if (type->is_sampler())
1035c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         vec4_slots = 1;
1036c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li      else
1037c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         vec4_slots = type->matrix_columns;
10381591693c7b415e9869157c711fe11263c95d74eDavid Li
10391591693c7b415e9869157c711fe11263c95d74eDavid Li      if (n == NULL) {
1040c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         n = (uniform_node *) calloc(1, sizeof(struct uniform_node));
1041c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         n->u = (gl_uniform *) calloc(1, sizeof(struct gl_uniform));
1042c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         n->slots = vec4_slots;
1043c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li
1044c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         n->u->Name = strdup(name);
1045c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         n->u->Type = type;
1046c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         n->u->Pos = *next_shader_pos;
1047c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         (*total_uniforms)++;
104836ffccf19c02a54a6dc9952dc9c181d4fda2a020David Li
1049c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         if (type->is_sampler() || (array_elem_type && array_elem_type->is_sampler()))
1050c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         {
1051c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li            n->u->Pos = *next_sampler_pos;
1052c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li            *next_sampler_pos += vec4_slots;
1053c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         }
1054c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         else
1055c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li            (*next_shader_pos) += vec4_slots;
1056c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         hash_table_insert(ht, n, name);
1057c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         uniforms->push_tail(&n->link);
105836ffccf19c02a54a6dc9952dc9c181d4fda2a020David Li      }
1059e82376d380005c21cb70637d42104fcd4d652843David Li
1060e82376d380005c21cb70637d42104fcd4d652843David Li      if (type->is_sampler() || (array_elem_type && array_elem_type->is_sampler()))
1061e82376d380005c21cb70637d42104fcd4d652843David Li         (*samplers_used) |= 1 << n->u->Pos;
1062c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li      index = n->u->Pos;
10631591693c7b415e9869157c711fe11263c95d74eDavid Li   }
1064c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li   return index;
10651591693c7b415e9869157c711fe11263c95d74eDavid Li}
10661591693c7b415e9869157c711fe11263c95d74eDavid Li
10671591693c7b415e9869157c711fe11263c95d74eDavid Livoid
10681591693c7b415e9869157c711fe11263c95d74eDavid Liassign_uniform_locations(struct gl_shader_program *prog)
10691591693c7b415e9869157c711fe11263c95d74eDavid Li{
10701591693c7b415e9869157c711fe11263c95d74eDavid Li   /* */
10711591693c7b415e9869157c711fe11263c95d74eDavid Li   exec_list uniforms;
10721591693c7b415e9869157c711fe11263c95d74eDavid Li   unsigned total_uniforms = 0;
107336ffccf19c02a54a6dc9952dc9c181d4fda2a020David Li   unsigned next_sampler_pos = 0; // all shaders in prog share same sampler location
10741591693c7b415e9869157c711fe11263c95d74eDavid Li   hash_table *ht = hash_table_ctor(32, hash_table_string_hash,
10751591693c7b415e9869157c711fe11263c95d74eDavid Li				    hash_table_string_compare);
1076c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li   void *mem_ctx = hieralloc_new(prog);
1077c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li
1078c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li   unsigned next_position = 0; // also number of slots for uniforms
10791591693c7b415e9869157c711fe11263c95d74eDavid Li
10801591693c7b415e9869157c711fe11263c95d74eDavid Li   for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) {
10811591693c7b415e9869157c711fe11263c95d74eDavid Li      if (prog->_LinkedShaders[i] == NULL)
10821591693c7b415e9869157c711fe11263c95d74eDavid Li	 continue;
10831591693c7b415e9869157c711fe11263c95d74eDavid Li
1084e82376d380005c21cb70637d42104fcd4d652843David Li      prog->_LinkedShaders[i]->SamplersUsed = 0;
10851591693c7b415e9869157c711fe11263c95d74eDavid Li      foreach_list(node, prog->_LinkedShaders[i]->ir) {
10861591693c7b415e9869157c711fe11263c95d74eDavid Li	 ir_variable *const var = ((ir_instruction *) node)->as_variable();
10871591693c7b415e9869157c711fe11263c95d74eDavid Li
10881591693c7b415e9869157c711fe11263c95d74eDavid Li	 if ((var == NULL) || (var->mode != ir_var_uniform))
10891591693c7b415e9869157c711fe11263c95d74eDavid Li	    continue;
10901591693c7b415e9869157c711fe11263c95d74eDavid Li
10911591693c7b415e9869157c711fe11263c95d74eDavid Li	 if (strncmp(var->name, "gl_", 3) == 0) {
10921591693c7b415e9869157c711fe11263c95d74eDavid Li	    /* At the moment, we don't allocate uniform locations for
10931591693c7b415e9869157c711fe11263c95d74eDavid Li	     * builtin uniforms.  It's permitted by spec, and we'll
10941591693c7b415e9869157c711fe11263c95d74eDavid Li	     * likely switch to doing that at some point, but not yet.
10951591693c7b415e9869157c711fe11263c95d74eDavid Li	     */
10961591693c7b415e9869157c711fe11263c95d74eDavid Li	    continue;
10971591693c7b415e9869157c711fe11263c95d74eDavid Li	 }
10981591693c7b415e9869157c711fe11263c95d74eDavid Li
1099c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li	 var->location = add_uniform(mem_ctx, &uniforms, ht, var->name, var->type,
11001591693c7b415e9869157c711fe11263c95d74eDavid Li		     prog->_LinkedShaders[i]->Type,
1101e82376d380005c21cb70637d42104fcd4d652843David Li		     &next_position, &total_uniforms, &next_sampler_pos, &prog->_LinkedShaders[i]->SamplersUsed);
11021591693c7b415e9869157c711fe11263c95d74eDavid Li      }
11031591693c7b415e9869157c711fe11263c95d74eDavid Li   }
11041591693c7b415e9869157c711fe11263c95d74eDavid Li
1105c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li   gl_uniform_list *ul = hieralloc_zero(prog, gl_uniform_list);
11061591693c7b415e9869157c711fe11263c95d74eDavid Li
11071591693c7b415e9869157c711fe11263c95d74eDavid Li   ul->Size = total_uniforms;
11081591693c7b415e9869157c711fe11263c95d74eDavid Li   ul->NumUniforms = total_uniforms;
1109c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li   ul->Uniforms = (gl_uniform *)hieralloc_zero_size(ul, total_uniforms * sizeof(gl_uniform));
11101591693c7b415e9869157c711fe11263c95d74eDavid Li
11111591693c7b415e9869157c711fe11263c95d74eDavid Li   unsigned idx = 0;
11121591693c7b415e9869157c711fe11263c95d74eDavid Li   uniform_node *next;
11131591693c7b415e9869157c711fe11263c95d74eDavid Li   for (uniform_node *node = (uniform_node *) uniforms.head
11141591693c7b415e9869157c711fe11263c95d74eDavid Li	   ; node->link.next != NULL
11151591693c7b415e9869157c711fe11263c95d74eDavid Li	   ; node = next) {
11161591693c7b415e9869157c711fe11263c95d74eDavid Li      next = (uniform_node *) node->link.next;
11171591693c7b415e9869157c711fe11263c95d74eDavid Li
11181591693c7b415e9869157c711fe11263c95d74eDavid Li      node->link.remove();
11191591693c7b415e9869157c711fe11263c95d74eDavid Li      memcpy(&ul->Uniforms[idx], node->u, sizeof(gl_uniform));
11201591693c7b415e9869157c711fe11263c95d74eDavid Li      idx++;
11211591693c7b415e9869157c711fe11263c95d74eDavid Li
11221591693c7b415e9869157c711fe11263c95d74eDavid Li      free(node->u);
11231591693c7b415e9869157c711fe11263c95d74eDavid Li      free(node);
11241591693c7b415e9869157c711fe11263c95d74eDavid Li   }
11251591693c7b415e9869157c711fe11263c95d74eDavid Li
11261591693c7b415e9869157c711fe11263c95d74eDavid Li   hash_table_dtor(ht);
11271591693c7b415e9869157c711fe11263c95d74eDavid Li
11281591693c7b415e9869157c711fe11263c95d74eDavid Li   prog->Uniforms = ul;
1129c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li   prog->Uniforms->Slots = next_position;
1130c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li
1131c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li   hieralloc_free(mem_ctx);
11321591693c7b415e9869157c711fe11263c95d74eDavid Li}
11331591693c7b415e9869157c711fe11263c95d74eDavid Li
11341591693c7b415e9869157c711fe11263c95d74eDavid Li
11351591693c7b415e9869157c711fe11263c95d74eDavid Li/**
11361591693c7b415e9869157c711fe11263c95d74eDavid Li * Find a contiguous set of available bits in a bitmask
11371591693c7b415e9869157c711fe11263c95d74eDavid Li *
11381591693c7b415e9869157c711fe11263c95d74eDavid Li * \param used_mask     Bits representing used (1) and unused (0) locations
11391591693c7b415e9869157c711fe11263c95d74eDavid Li * \param needed_count  Number of contiguous bits needed.
11401591693c7b415e9869157c711fe11263c95d74eDavid Li *
11411591693c7b415e9869157c711fe11263c95d74eDavid Li * \return
11421591693c7b415e9869157c711fe11263c95d74eDavid Li * Base location of the available bits on success or -1 on failure.
11431591693c7b415e9869157c711fe11263c95d74eDavid Li */
11441591693c7b415e9869157c711fe11263c95d74eDavid Liint
11451591693c7b415e9869157c711fe11263c95d74eDavid Lifind_available_slots(unsigned used_mask, unsigned needed_count)
11461591693c7b415e9869157c711fe11263c95d74eDavid Li{
11471591693c7b415e9869157c711fe11263c95d74eDavid Li   unsigned needed_mask = (1 << needed_count) - 1;
11481591693c7b415e9869157c711fe11263c95d74eDavid Li   const int max_bit_to_test = (8 * sizeof(used_mask)) - needed_count;
11491591693c7b415e9869157c711fe11263c95d74eDavid Li
11501591693c7b415e9869157c711fe11263c95d74eDavid Li   /* The comparison to 32 is redundant, but without it GCC emits "warning:
11511591693c7b415e9869157c711fe11263c95d74eDavid Li    * cannot optimize possibly infinite loops" for the loop below.
11521591693c7b415e9869157c711fe11263c95d74eDavid Li    */
11531591693c7b415e9869157c711fe11263c95d74eDavid Li   if ((needed_count == 0) || (max_bit_to_test < 0) || (max_bit_to_test > 32))
11541591693c7b415e9869157c711fe11263c95d74eDavid Li      return -1;
11551591693c7b415e9869157c711fe11263c95d74eDavid Li
11561591693c7b415e9869157c711fe11263c95d74eDavid Li   for (int i = 0; i <= max_bit_to_test; i++) {
11571591693c7b415e9869157c711fe11263c95d74eDavid Li      if ((needed_mask & ~used_mask) == needed_mask)
11581591693c7b415e9869157c711fe11263c95d74eDavid Li	 return i;
11591591693c7b415e9869157c711fe11263c95d74eDavid Li
11601591693c7b415e9869157c711fe11263c95d74eDavid Li      needed_mask <<= 1;
11611591693c7b415e9869157c711fe11263c95d74eDavid Li   }
11621591693c7b415e9869157c711fe11263c95d74eDavid Li
11631591693c7b415e9869157c711fe11263c95d74eDavid Li   return -1;
11641591693c7b415e9869157c711fe11263c95d74eDavid Li}
11651591693c7b415e9869157c711fe11263c95d74eDavid Li
11661591693c7b415e9869157c711fe11263c95d74eDavid Li
11671591693c7b415e9869157c711fe11263c95d74eDavid Libool
11681591693c7b415e9869157c711fe11263c95d74eDavid Liassign_attribute_locations(gl_shader_program *prog, unsigned max_attribute_index)
11691591693c7b415e9869157c711fe11263c95d74eDavid Li{
11701591693c7b415e9869157c711fe11263c95d74eDavid Li   /* Mark invalid attribute locations as being used.
11711591693c7b415e9869157c711fe11263c95d74eDavid Li    */
11721591693c7b415e9869157c711fe11263c95d74eDavid Li   unsigned used_locations = (max_attribute_index >= 32)
11731591693c7b415e9869157c711fe11263c95d74eDavid Li      ? ~0 : ~((1 << max_attribute_index) - 1);
11741591693c7b415e9869157c711fe11263c95d74eDavid Li
11751591693c7b415e9869157c711fe11263c95d74eDavid Li   gl_shader *const sh = prog->_LinkedShaders[0];
11761591693c7b415e9869157c711fe11263c95d74eDavid Li   assert(sh->Type == GL_VERTEX_SHADER);
11773225321119408735f16b72b539c9fb7d80683552David Li   prog->VaryingSlots = 0;
11781591693c7b415e9869157c711fe11263c95d74eDavid Li   /* Operate in a total of four passes.
11791591693c7b415e9869157c711fe11263c95d74eDavid Li    *
1180c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li    * 1. Invalidate the location assignments for all vertex shader inputs,
1181c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li    *    except for explicit_location and glBindAttribLocation
11821591693c7b415e9869157c711fe11263c95d74eDavid Li    *
11831591693c7b415e9869157c711fe11263c95d74eDavid Li    * 2. Assign locations for inputs that have user-defined (via
11841591693c7b415e9869157c711fe11263c95d74eDavid Li    *    glBindVertexAttribLocation) locatoins.
11851591693c7b415e9869157c711fe11263c95d74eDavid Li    *
11861591693c7b415e9869157c711fe11263c95d74eDavid Li    * 3. Sort the attributes without assigned locations by number of slots
11871591693c7b415e9869157c711fe11263c95d74eDavid Li    *    required in decreasing order.  Fragmentation caused by attribute
11881591693c7b415e9869157c711fe11263c95d74eDavid Li    *    locations assigned by the application may prevent large attributes
11891591693c7b415e9869157c711fe11263c95d74eDavid Li    *    from having enough contiguous space.
11901591693c7b415e9869157c711fe11263c95d74eDavid Li    *
11911591693c7b415e9869157c711fe11263c95d74eDavid Li    * 4. Assign locations to any inputs without assigned locations.
11921591693c7b415e9869157c711fe11263c95d74eDavid Li    */
11931591693c7b415e9869157c711fe11263c95d74eDavid Li   if (prog->Attributes != NULL) {
1194c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li      // declare attributes if they haven't been already by BindAttribLocation
1195c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li      gl_program_parameter_list * attributes = prog->Attributes;
1196c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         foreach_list(node, sh->ir) {
1197c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li            ir_variable *const var = ((ir_instruction *) node)->as_variable();
1198c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li            if ((var == NULL) || (var->mode != ir_var_in))
1199c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li               continue;
1200c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li            if (_mesa_get_parameter(attributes, var->name) < 0)
1201c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li                _mesa_add_parameter(attributes, var->name);
1202c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         }
1203c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li
1204c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li      for (unsigned i = 0; i < attributes->NumParameters; i++) {
1205c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         gl_program_parameter * param = attributes->Parameters + i;
1206c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         ir_variable * const var = sh->symbols->get_variable(param->Name);
1207c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         if (!var || ir_var_in != var->mode)
1208c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li            continue;
1209c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li
1210c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         if (param->BindLocation >= 0 && !var->explicit_location)
1211c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li            var->location = param->Location = param->BindLocation;
1212c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         else if (var->explicit_location)
1213c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li            param->Location = var->location;
1214c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         else
1215c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li            var->location = -1;
1216c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         const unsigned slots = count_attribute_slots(var->type);
1217c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         param->Slots = slots;
1218c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         if (0 > var->location)
1219c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li            continue;
1220c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li 	 /* From page 61 of the OpenGL 4.0 spec:
12211591693c7b415e9869157c711fe11263c95d74eDavid Li	  *
12221591693c7b415e9869157c711fe11263c95d74eDavid Li	  *     "LinkProgram will fail if the attribute bindings assigned by
12231591693c7b415e9869157c711fe11263c95d74eDavid Li	  *     BindAttribLocation do not leave not enough space to assign a
12241591693c7b415e9869157c711fe11263c95d74eDavid Li	  *     location for an active matrix attribute or an active attribute
12251591693c7b415e9869157c711fe11263c95d74eDavid Li	  *     array, both of which require multiple contiguous generic
12261591693c7b415e9869157c711fe11263c95d74eDavid Li	  *     attributes."
12271591693c7b415e9869157c711fe11263c95d74eDavid Li	  *
12281591693c7b415e9869157c711fe11263c95d74eDavid Li	  * Previous versions of the spec contain similar language but omit the
12291591693c7b415e9869157c711fe11263c95d74eDavid Li	  * bit about attribute arrays.
12301591693c7b415e9869157c711fe11263c95d74eDavid Li	  *
12311591693c7b415e9869157c711fe11263c95d74eDavid Li	  * Page 61 of the OpenGL 4.0 spec also says:
12321591693c7b415e9869157c711fe11263c95d74eDavid Li	  *
12331591693c7b415e9869157c711fe11263c95d74eDavid Li	  *     "It is possible for an application to bind more than one
12341591693c7b415e9869157c711fe11263c95d74eDavid Li	  *     attribute name to the same location. This is referred to as
12351591693c7b415e9869157c711fe11263c95d74eDavid Li	  *     aliasing. This will only work if only one of the aliased
12361591693c7b415e9869157c711fe11263c95d74eDavid Li	  *     attributes is active in the executable program, or if no path
12371591693c7b415e9869157c711fe11263c95d74eDavid Li	  *     through the shader consumes more than one attribute of a set
12381591693c7b415e9869157c711fe11263c95d74eDavid Li	  *     of attributes aliased to the same location. A link error can
12391591693c7b415e9869157c711fe11263c95d74eDavid Li	  *     occur if the linker determines that every path through the
12401591693c7b415e9869157c711fe11263c95d74eDavid Li	  *     shader consumes multiple aliased attributes, but
12411591693c7b415e9869157c711fe11263c95d74eDavid Li	  *     implementations are not required to generate an error in this
12421591693c7b415e9869157c711fe11263c95d74eDavid Li	  *     case."
12431591693c7b415e9869157c711fe11263c95d74eDavid Li	  *
12441591693c7b415e9869157c711fe11263c95d74eDavid Li	  * These two paragraphs are either somewhat contradictory, or I don't
12451591693c7b415e9869157c711fe11263c95d74eDavid Li	  * fully understand one or both of them.
12461591693c7b415e9869157c711fe11263c95d74eDavid Li	  */
12471591693c7b415e9869157c711fe11263c95d74eDavid Li	 /* FINISHME: The code as currently written does not support attribute
12481591693c7b415e9869157c711fe11263c95d74eDavid Li	  * FINISHME: location aliasing (see comment above).
12491591693c7b415e9869157c711fe11263c95d74eDavid Li	  */
1250c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         const int attr = param->Location;
12511591693c7b415e9869157c711fe11263c95d74eDavid Li	 /* Mask representing the contiguous slots that will be used by this
12521591693c7b415e9869157c711fe11263c95d74eDavid Li	  * attribute.
12531591693c7b415e9869157c711fe11263c95d74eDavid Li	  */
12541591693c7b415e9869157c711fe11263c95d74eDavid Li	 const unsigned use_mask = (1 << slots) - 1;
12551591693c7b415e9869157c711fe11263c95d74eDavid Li	 /* Generate a link error if the set of bits requested for this
12561591693c7b415e9869157c711fe11263c95d74eDavid Li	  * attribute overlaps any previously allocated bits.
12571591693c7b415e9869157c711fe11263c95d74eDavid Li	  */
1258c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li	 if ((use_mask << attr) & used_locations) {
12591591693c7b415e9869157c711fe11263c95d74eDavid Li	    linker_error_printf(prog,
12601591693c7b415e9869157c711fe11263c95d74eDavid Li				"insufficient contiguous attribute locations "
12611591693c7b415e9869157c711fe11263c95d74eDavid Li				"available for vertex shader input `%s'",
12621591693c7b415e9869157c711fe11263c95d74eDavid Li				var->name);
12631591693c7b415e9869157c711fe11263c95d74eDavid Li	    return false;
12641591693c7b415e9869157c711fe11263c95d74eDavid Li	 }
1265c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li
12661591693c7b415e9869157c711fe11263c95d74eDavid Li	 used_locations |= (use_mask << attr);
12671591693c7b415e9869157c711fe11263c95d74eDavid Li      }
12681591693c7b415e9869157c711fe11263c95d74eDavid Li   }
12691591693c7b415e9869157c711fe11263c95d74eDavid Li
12701591693c7b415e9869157c711fe11263c95d74eDavid Li   /* Temporary storage for the set of attributes that need locations assigned.
12711591693c7b415e9869157c711fe11263c95d74eDavid Li    */
12721591693c7b415e9869157c711fe11263c95d74eDavid Li   struct temp_attr {
12731591693c7b415e9869157c711fe11263c95d74eDavid Li      unsigned slots;
12741591693c7b415e9869157c711fe11263c95d74eDavid Li      ir_variable *var;
12751591693c7b415e9869157c711fe11263c95d74eDavid Li
12761591693c7b415e9869157c711fe11263c95d74eDavid Li      /* Used below in the call to qsort. */
12771591693c7b415e9869157c711fe11263c95d74eDavid Li      static int compare(const void *a, const void *b)
12781591693c7b415e9869157c711fe11263c95d74eDavid Li      {
12791591693c7b415e9869157c711fe11263c95d74eDavid Li	 const temp_attr *const l = (const temp_attr *) a;
12801591693c7b415e9869157c711fe11263c95d74eDavid Li	 const temp_attr *const r = (const temp_attr *) b;
12811591693c7b415e9869157c711fe11263c95d74eDavid Li
12821591693c7b415e9869157c711fe11263c95d74eDavid Li	 /* Reversed because we want a descending order sort below. */
12831591693c7b415e9869157c711fe11263c95d74eDavid Li	 return r->slots - l->slots;
12841591693c7b415e9869157c711fe11263c95d74eDavid Li      }
12851591693c7b415e9869157c711fe11263c95d74eDavid Li   } to_assign[16];
12861591693c7b415e9869157c711fe11263c95d74eDavid Li
12871591693c7b415e9869157c711fe11263c95d74eDavid Li   unsigned num_attr = 0;
12881591693c7b415e9869157c711fe11263c95d74eDavid Li
12891591693c7b415e9869157c711fe11263c95d74eDavid Li   foreach_list(node, sh->ir) {
12901591693c7b415e9869157c711fe11263c95d74eDavid Li      ir_variable *const var = ((ir_instruction *) node)->as_variable();
12911591693c7b415e9869157c711fe11263c95d74eDavid Li      if ((var == NULL) || (var->mode != ir_var_in))
1292c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         continue;
12931591693c7b415e9869157c711fe11263c95d74eDavid Li      if (var->explicit_location) {
12941591693c7b415e9869157c711fe11263c95d74eDavid Li	 const unsigned slots = count_attribute_slots(var->type);
12951591693c7b415e9869157c711fe11263c95d74eDavid Li	 const unsigned use_mask = (1 << slots) - 1;
1296c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li	 const int attr = var->location/* - VERT_ATTRIB_GENERIC0*/;
12971591693c7b415e9869157c711fe11263c95d74eDavid Li
1298c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li	 if ((var->location >= (int)(max_attribute_index/* + VERT_ATTRIB_GENERIC0*/))
12991591693c7b415e9869157c711fe11263c95d74eDavid Li	     || (var->location < 0)) {
13001591693c7b415e9869157c711fe11263c95d74eDavid Li	    linker_error_printf(prog,
13011591693c7b415e9869157c711fe11263c95d74eDavid Li				"invalid explicit location %d specified for "
13021591693c7b415e9869157c711fe11263c95d74eDavid Li				"`%s'\n",
13031591693c7b415e9869157c711fe11263c95d74eDavid Li				(var->location < 0) ? var->location : attr,
13041591693c7b415e9869157c711fe11263c95d74eDavid Li				var->name);
13051591693c7b415e9869157c711fe11263c95d74eDavid Li	    return false;
1306c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li	 } else if (var->location >= 0/*VERT_ATTRIB_GENERIC0*/) {
13071591693c7b415e9869157c711fe11263c95d74eDavid Li	    used_locations |= (use_mask << attr);
13081591693c7b415e9869157c711fe11263c95d74eDavid Li	 }
13091591693c7b415e9869157c711fe11263c95d74eDavid Li      }
13101591693c7b415e9869157c711fe11263c95d74eDavid Li
13111591693c7b415e9869157c711fe11263c95d74eDavid Li      /* The location was explicitly assigned, nothing to do here.
13121591693c7b415e9869157c711fe11263c95d74eDavid Li       */
13131591693c7b415e9869157c711fe11263c95d74eDavid Li      if (var->location != -1)
13141591693c7b415e9869157c711fe11263c95d74eDavid Li	 continue;
13151591693c7b415e9869157c711fe11263c95d74eDavid Li
13161591693c7b415e9869157c711fe11263c95d74eDavid Li      to_assign[num_attr].slots = count_attribute_slots(var->type);
13171591693c7b415e9869157c711fe11263c95d74eDavid Li      to_assign[num_attr].var = var;
13181591693c7b415e9869157c711fe11263c95d74eDavid Li      num_attr++;
13191591693c7b415e9869157c711fe11263c95d74eDavid Li   }
13201591693c7b415e9869157c711fe11263c95d74eDavid Li
13211591693c7b415e9869157c711fe11263c95d74eDavid Li   /* If all of the attributes were assigned locations by the application (or
13221591693c7b415e9869157c711fe11263c95d74eDavid Li    * are built-in attributes with fixed locations), return early.  This should
13231591693c7b415e9869157c711fe11263c95d74eDavid Li    * be the common case.
13241591693c7b415e9869157c711fe11263c95d74eDavid Li    */
13251591693c7b415e9869157c711fe11263c95d74eDavid Li   if (num_attr == 0)
13261591693c7b415e9869157c711fe11263c95d74eDavid Li      return true;
13271591693c7b415e9869157c711fe11263c95d74eDavid Li
13281591693c7b415e9869157c711fe11263c95d74eDavid Li   qsort(to_assign, num_attr, sizeof(to_assign[0]), temp_attr::compare);
13291591693c7b415e9869157c711fe11263c95d74eDavid Li
13301591693c7b415e9869157c711fe11263c95d74eDavid Li   /* VERT_ATTRIB_GENERIC0 is a psdueo-alias for VERT_ATTRIB_POS.  It can only
13311591693c7b415e9869157c711fe11263c95d74eDavid Li    * be explicitly assigned by via glBindAttribLocation.  Mark it as reserved
13321591693c7b415e9869157c711fe11263c95d74eDavid Li    * to prevent it from being automatically allocated below.
13331591693c7b415e9869157c711fe11263c95d74eDavid Li    */
13341591693c7b415e9869157c711fe11263c95d74eDavid Li   find_deref_visitor find("gl_Vertex");
13351591693c7b415e9869157c711fe11263c95d74eDavid Li   find.run(sh->ir);
13361591693c7b415e9869157c711fe11263c95d74eDavid Li   if (find.variable_found())
13371591693c7b415e9869157c711fe11263c95d74eDavid Li      used_locations |= (1 << 0);
13381591693c7b415e9869157c711fe11263c95d74eDavid Li
13391591693c7b415e9869157c711fe11263c95d74eDavid Li   for (unsigned i = 0; i < num_attr; i++) {
13401591693c7b415e9869157c711fe11263c95d74eDavid Li      /* Mask representing the contiguous slots that will be used by this
13411591693c7b415e9869157c711fe11263c95d74eDavid Li       * attribute.
13421591693c7b415e9869157c711fe11263c95d74eDavid Li       */
13431591693c7b415e9869157c711fe11263c95d74eDavid Li      const unsigned use_mask = (1 << to_assign[i].slots) - 1;
13441591693c7b415e9869157c711fe11263c95d74eDavid Li
13451591693c7b415e9869157c711fe11263c95d74eDavid Li      int location = find_available_slots(used_locations, to_assign[i].slots);
13461591693c7b415e9869157c711fe11263c95d74eDavid Li
13471591693c7b415e9869157c711fe11263c95d74eDavid Li      if (location < 0) {
13481591693c7b415e9869157c711fe11263c95d74eDavid Li	 linker_error_printf(prog,
13491591693c7b415e9869157c711fe11263c95d74eDavid Li			     "insufficient contiguous attribute locations "
13501591693c7b415e9869157c711fe11263c95d74eDavid Li			     "available for vertex shader input `%s'",
13511591693c7b415e9869157c711fe11263c95d74eDavid Li			     to_assign[i].var->name);
13521591693c7b415e9869157c711fe11263c95d74eDavid Li	 return false;
13531591693c7b415e9869157c711fe11263c95d74eDavid Li      }
13541591693c7b415e9869157c711fe11263c95d74eDavid Li
1355c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li      to_assign[i].var->location = /*VERT_ATTRIB_GENERIC0 +*/ location;
13561591693c7b415e9869157c711fe11263c95d74eDavid Li      used_locations |= (use_mask << location);
1357c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li      int paramIndex = _mesa_get_parameter(prog->Attributes, to_assign[i].var->name);
1358c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li      if (0 <= paramIndex)
1359c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         prog->Attributes->Parameters[paramIndex].Location = location;
13601591693c7b415e9869157c711fe11263c95d74eDavid Li   }
13613225321119408735f16b72b539c9fb7d80683552David Li
13623225321119408735f16b72b539c9fb7d80683552David Li   for (int i = sizeof(used_locations) * 8 - 1; i >= 0; i--)
13633225321119408735f16b72b539c9fb7d80683552David Li      if (used_locations & (1 << i))
13643225321119408735f16b72b539c9fb7d80683552David Li      {
13653225321119408735f16b72b539c9fb7d80683552David Li         prog->AttributeSlots = i + 1;
13663225321119408735f16b72b539c9fb7d80683552David Li         break;
13673225321119408735f16b72b539c9fb7d80683552David Li      }
13681591693c7b415e9869157c711fe11263c95d74eDavid Li
13691591693c7b415e9869157c711fe11263c95d74eDavid Li   return true;
13701591693c7b415e9869157c711fe11263c95d74eDavid Li}
13711591693c7b415e9869157c711fe11263c95d74eDavid Li
13721591693c7b415e9869157c711fe11263c95d74eDavid Li
13731591693c7b415e9869157c711fe11263c95d74eDavid Li/**
13741591693c7b415e9869157c711fe11263c95d74eDavid Li * Demote shader inputs and outputs that are not used in other stages
13751591693c7b415e9869157c711fe11263c95d74eDavid Li */
13761591693c7b415e9869157c711fe11263c95d74eDavid Livoid
13771591693c7b415e9869157c711fe11263c95d74eDavid Lidemote_shader_inputs_and_outputs(gl_shader *sh, enum ir_variable_mode mode)
13781591693c7b415e9869157c711fe11263c95d74eDavid Li{
13791591693c7b415e9869157c711fe11263c95d74eDavid Li   foreach_list(node, sh->ir) {
13801591693c7b415e9869157c711fe11263c95d74eDavid Li      ir_variable *const var = ((ir_instruction *) node)->as_variable();
13811591693c7b415e9869157c711fe11263c95d74eDavid Li
13821591693c7b415e9869157c711fe11263c95d74eDavid Li      if ((var == NULL) || (var->mode != int(mode)))
13831591693c7b415e9869157c711fe11263c95d74eDavid Li	 continue;
13841591693c7b415e9869157c711fe11263c95d74eDavid Li
13851591693c7b415e9869157c711fe11263c95d74eDavid Li      /* A shader 'in' or 'out' variable is only really an input or output if
13861591693c7b415e9869157c711fe11263c95d74eDavid Li       * its value is used by other shader stages.  This will cause the variable
13871591693c7b415e9869157c711fe11263c95d74eDavid Li       * to have a location assigned.
13881591693c7b415e9869157c711fe11263c95d74eDavid Li       */
13891591693c7b415e9869157c711fe11263c95d74eDavid Li      if (var->location == -1) {
13901591693c7b415e9869157c711fe11263c95d74eDavid Li	 var->mode = ir_var_auto;
13911591693c7b415e9869157c711fe11263c95d74eDavid Li      }
13921591693c7b415e9869157c711fe11263c95d74eDavid Li   }
13931591693c7b415e9869157c711fe11263c95d74eDavid Li}
13941591693c7b415e9869157c711fe11263c95d74eDavid Li
13951591693c7b415e9869157c711fe11263c95d74eDavid Livoid
13961591693c7b415e9869157c711fe11263c95d74eDavid Liassign_varying_locations(struct gl_shader_program *prog,
13971591693c7b415e9869157c711fe11263c95d74eDavid Li			 gl_shader *producer, gl_shader *consumer)
13981591693c7b415e9869157c711fe11263c95d74eDavid Li{
13993225321119408735f16b72b539c9fb7d80683552David Li   prog->VaryingSlots = 0;
14003225321119408735f16b72b539c9fb7d80683552David Li   prog->UsesFragCoord = false;
14013225321119408735f16b72b539c9fb7d80683552David Li   prog->UsesPointCoord = false;
14021591693c7b415e9869157c711fe11263c95d74eDavid Li   /* FINISHME: Set dynamically when geometry shader support is added. */
14033225321119408735f16b72b539c9fb7d80683552David Li   unsigned output_index = offsetof(VertexOutput,varyings) / sizeof(Vector4); /*VERT_RESULT_VAR0*/;
14043225321119408735f16b72b539c9fb7d80683552David Li   unsigned input_index = offsetof(VertexOutput,varyings) / sizeof(Vector4);
14051591693c7b415e9869157c711fe11263c95d74eDavid Li
14061591693c7b415e9869157c711fe11263c95d74eDavid Li   /* Operate in a total of three passes.
14071591693c7b415e9869157c711fe11263c95d74eDavid Li    *
14081591693c7b415e9869157c711fe11263c95d74eDavid Li    * 1. Assign locations for any matching inputs and outputs.
14091591693c7b415e9869157c711fe11263c95d74eDavid Li    *
14101591693c7b415e9869157c711fe11263c95d74eDavid Li    * 2. Mark output variables in the producer that do not have locations as
14111591693c7b415e9869157c711fe11263c95d74eDavid Li    *    not being outputs.  This lets the optimizer eliminate them.
14121591693c7b415e9869157c711fe11263c95d74eDavid Li    *
14131591693c7b415e9869157c711fe11263c95d74eDavid Li    * 3. Mark input variables in the consumer that do not have locations as
14141591693c7b415e9869157c711fe11263c95d74eDavid Li    *    not being inputs.  This lets the optimizer eliminate them.
14151591693c7b415e9869157c711fe11263c95d74eDavid Li    */
1416c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li   foreach_list(node, producer->ir) {
1417c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li      ir_variable *const var = ((ir_instruction *) node)->as_variable();
1418c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li      if (!var || ir_var_out != var->mode)
1419c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         continue;
1420c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li      if (!strcmp("gl_Position", var->name))
14213225321119408735f16b72b539c9fb7d80683552David Li         var->location = offsetof(VertexOutput,position) / sizeof(Vector4);
1422c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li      else if (!strcmp("gl_PointSize", var->name))
14233225321119408735f16b72b539c9fb7d80683552David Li         var->location = offsetof(VertexOutput,pointSize) / sizeof(Vector4);
1424c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li      else
1425c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         var->location = -1;
1426c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li   }
1427c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li   foreach_list(node, consumer->ir) {
1428c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li      ir_variable *const var = ((ir_instruction *) node)->as_variable();
1429c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li      if (!var || ir_var_in != var->mode)
1430c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         continue;
1431c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li      if (!strcmp("gl_FragCoord", var->name))
14323225321119408735f16b72b539c9fb7d80683552David Li      {
14333225321119408735f16b72b539c9fb7d80683552David Li         var->location = offsetof(VertexOutput,position)/sizeof(Vector4);
14343225321119408735f16b72b539c9fb7d80683552David Li         prog->UsesFragCoord = true;
14353225321119408735f16b72b539c9fb7d80683552David Li      }
1436c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li      else if (!strcmp("gl_FrontFacing", var->name))
14373225321119408735f16b72b539c9fb7d80683552David Li         var->location = offsetof(VertexOutput,frontFacingPointCoord)/sizeof(Vector4);
1438c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li      else if (!strcmp("gl_PointCoord", var->name))
14393225321119408735f16b72b539c9fb7d80683552David Li      {
14403225321119408735f16b72b539c9fb7d80683552David Li         var->location = offsetof(VertexOutput,frontFacingPointCoord)/sizeof(Vector4);
14413225321119408735f16b72b539c9fb7d80683552David Li         prog->UsesPointCoord = true;
14423225321119408735f16b72b539c9fb7d80683552David Li      }
1443c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li      else
1444c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         var->location = -1;
1445c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li   }
14461591693c7b415e9869157c711fe11263c95d74eDavid Li
14471591693c7b415e9869157c711fe11263c95d74eDavid Li   foreach_list(node, producer->ir) {
14481591693c7b415e9869157c711fe11263c95d74eDavid Li      ir_variable *const output_var = ((ir_instruction *) node)->as_variable();
14491591693c7b415e9869157c711fe11263c95d74eDavid Li
1450c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li      if ((output_var == NULL) || (output_var->mode != ir_var_out))
1451c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         continue;
1452c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li      int paramIndex = _mesa_get_parameter(prog->Varying, output_var->name);
1453c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li      if (paramIndex < 0)
1454c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         paramIndex = _mesa_add_parameter(prog->Varying, output_var->name);
1455c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li      gl_program_parameter * param = prog->Varying->Parameters + paramIndex;
1456c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li      if (output_var->location != -1)
1457c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li      {
1458c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         param->BindLocation = output_var->location;
1459c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         continue;
1460c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li      }
14611591693c7b415e9869157c711fe11263c95d74eDavid Li
14621591693c7b415e9869157c711fe11263c95d74eDavid Li      ir_variable *const input_var =
14631591693c7b415e9869157c711fe11263c95d74eDavid Li	 consumer->symbols->get_variable(output_var->name);
14641591693c7b415e9869157c711fe11263c95d74eDavid Li
14651591693c7b415e9869157c711fe11263c95d74eDavid Li      if ((input_var == NULL) || (input_var->mode != ir_var_in))
14661591693c7b415e9869157c711fe11263c95d74eDavid Li	 continue;
14671591693c7b415e9869157c711fe11263c95d74eDavid Li
14681591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(input_var->location == -1);
14691591693c7b415e9869157c711fe11263c95d74eDavid Li
1470c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li      param->BindLocation = output_var->location = output_index;
1471c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li      param->Location = input_var->location = input_index;
14721591693c7b415e9869157c711fe11263c95d74eDavid Li
14731591693c7b415e9869157c711fe11263c95d74eDavid Li      /* FINISHME: Support for "varying" records in GLSL 1.50. */
14741591693c7b415e9869157c711fe11263c95d74eDavid Li      assert(!output_var->type->is_record());
14751591693c7b415e9869157c711fe11263c95d74eDavid Li
14761591693c7b415e9869157c711fe11263c95d74eDavid Li      if (output_var->type->is_array()) {
14771591693c7b415e9869157c711fe11263c95d74eDavid Li	 const unsigned slots = output_var->type->length
14781591693c7b415e9869157c711fe11263c95d74eDavid Li	    * output_var->type->fields.array->matrix_columns;
14791591693c7b415e9869157c711fe11263c95d74eDavid Li
14801591693c7b415e9869157c711fe11263c95d74eDavid Li	 output_index += slots;
14811591693c7b415e9869157c711fe11263c95d74eDavid Li	 input_index += slots;
14823225321119408735f16b72b539c9fb7d80683552David Li    prog->VaryingSlots += slots;
14831591693c7b415e9869157c711fe11263c95d74eDavid Li      } else {
14841591693c7b415e9869157c711fe11263c95d74eDavid Li	 const unsigned slots = output_var->type->matrix_columns;
14851591693c7b415e9869157c711fe11263c95d74eDavid Li
14861591693c7b415e9869157c711fe11263c95d74eDavid Li	 output_index += slots;
14871591693c7b415e9869157c711fe11263c95d74eDavid Li	 input_index += slots;
14883225321119408735f16b72b539c9fb7d80683552David Li    prog->VaryingSlots += slots;
14891591693c7b415e9869157c711fe11263c95d74eDavid Li      }
14901591693c7b415e9869157c711fe11263c95d74eDavid Li   }
14911591693c7b415e9869157c711fe11263c95d74eDavid Li
14921591693c7b415e9869157c711fe11263c95d74eDavid Li   foreach_list(node, consumer->ir) {
14931591693c7b415e9869157c711fe11263c95d74eDavid Li      ir_variable *const var = ((ir_instruction *) node)->as_variable();
14941591693c7b415e9869157c711fe11263c95d74eDavid Li
14951591693c7b415e9869157c711fe11263c95d74eDavid Li      if ((var == NULL) || (var->mode != ir_var_in))
14961591693c7b415e9869157c711fe11263c95d74eDavid Li	 continue;
1497c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li      int paramIndex = _mesa_get_parameter(prog->Varying, var->name);
1498c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li      if (paramIndex < 0)
1499c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         paramIndex = _mesa_add_parameter(prog->Varying, var->name);
1500c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li      gl_program_parameter * param = prog->Varying->Parameters + paramIndex;
1501c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li
15021591693c7b415e9869157c711fe11263c95d74eDavid Li      if (var->location == -1) {
1503c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         if (prog->Version <= 120) {
15041591693c7b415e9869157c711fe11263c95d74eDavid Li	    /* On page 25 (page 31 of the PDF) of the GLSL 1.20 spec:
15051591693c7b415e9869157c711fe11263c95d74eDavid Li	     *
15061591693c7b415e9869157c711fe11263c95d74eDavid Li	     *     Only those varying variables used (i.e. read) in
15071591693c7b415e9869157c711fe11263c95d74eDavid Li	     *     the fragment shader executable must be written to
15081591693c7b415e9869157c711fe11263c95d74eDavid Li	     *     by the vertex shader executable; declaring
15091591693c7b415e9869157c711fe11263c95d74eDavid Li	     *     superfluous varying variables in a vertex shader is
15101591693c7b415e9869157c711fe11263c95d74eDavid Li	     *     permissible.
15111591693c7b415e9869157c711fe11263c95d74eDavid Li	     *
15121591693c7b415e9869157c711fe11263c95d74eDavid Li	     * We interpret this text as meaning that the VS must
15131591693c7b415e9869157c711fe11263c95d74eDavid Li	     * write the variable for the FS to read it.  See
15141591693c7b415e9869157c711fe11263c95d74eDavid Li	     * "glsl1-varying read but not written" in piglit.
15151591693c7b415e9869157c711fe11263c95d74eDavid Li	     */
15161591693c7b415e9869157c711fe11263c95d74eDavid Li
1517c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li            linker_error_printf(prog, "fragment shader varying %s not written "
1518c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li               "by vertex shader\n.", var->name);
1519c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li            prog->LinkStatus = false;
1520c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         }
15211591693c7b415e9869157c711fe11263c95d74eDavid Li
15221591693c7b415e9869157c711fe11263c95d74eDavid Li	 /* An 'in' variable is only really a shader input if its
15231591693c7b415e9869157c711fe11263c95d74eDavid Li	  * value is written by the previous stage.
15241591693c7b415e9869157c711fe11263c95d74eDavid Li	  */
1525c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         var->mode = ir_var_auto;
15261591693c7b415e9869157c711fe11263c95d74eDavid Li      }
1527c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li      else
1528c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         param->Location = var->location;
15291591693c7b415e9869157c711fe11263c95d74eDavid Li   }
15301591693c7b415e9869157c711fe11263c95d74eDavid Li}
15311591693c7b415e9869157c711fe11263c95d74eDavid Li
15321591693c7b415e9869157c711fe11263c95d74eDavid Li
15331591693c7b415e9869157c711fe11263c95d74eDavid Livoid
15341591693c7b415e9869157c711fe11263c95d74eDavid Lilink_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
15351591693c7b415e9869157c711fe11263c95d74eDavid Li{
153613fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li   //void *mem_ctx = hieralloc_init("temporary linker context");
153713fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li   void * mem_ctx = prog; // need linked & cloned ir to persist
15381591693c7b415e9869157c711fe11263c95d74eDavid Li
15391591693c7b415e9869157c711fe11263c95d74eDavid Li   prog->LinkStatus = false;
15401591693c7b415e9869157c711fe11263c95d74eDavid Li   prog->Validated = false;
15411591693c7b415e9869157c711fe11263c95d74eDavid Li   prog->_Used = false;
15421591693c7b415e9869157c711fe11263c95d74eDavid Li
15431591693c7b415e9869157c711fe11263c95d74eDavid Li   if (prog->InfoLog != NULL)
1544d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li      hieralloc_free(prog->InfoLog);
15451591693c7b415e9869157c711fe11263c95d74eDavid Li
15463b02c91d7b1fcc777dbdafeb044e0df61e1ff0d8David Li   prog->InfoLog = hieralloc_strdup(prog, "");
15471591693c7b415e9869157c711fe11263c95d74eDavid Li
15481591693c7b415e9869157c711fe11263c95d74eDavid Li   /* Separate the shaders into groups based on their type.
15491591693c7b415e9869157c711fe11263c95d74eDavid Li    */
15501591693c7b415e9869157c711fe11263c95d74eDavid Li   struct gl_shader **vert_shader_list;
15511591693c7b415e9869157c711fe11263c95d74eDavid Li   unsigned num_vert_shaders = 0;
15521591693c7b415e9869157c711fe11263c95d74eDavid Li   struct gl_shader **frag_shader_list;
15531591693c7b415e9869157c711fe11263c95d74eDavid Li   unsigned num_frag_shaders = 0;
15541591693c7b415e9869157c711fe11263c95d74eDavid Li
15551591693c7b415e9869157c711fe11263c95d74eDavid Li   vert_shader_list = (struct gl_shader **)
15561591693c7b415e9869157c711fe11263c95d74eDavid Li      calloc(2 * prog->NumShaders, sizeof(struct gl_shader *));
15571591693c7b415e9869157c711fe11263c95d74eDavid Li   frag_shader_list =  &vert_shader_list[prog->NumShaders];
15581591693c7b415e9869157c711fe11263c95d74eDavid Li
15591591693c7b415e9869157c711fe11263c95d74eDavid Li   unsigned min_version = UINT_MAX;
15601591693c7b415e9869157c711fe11263c95d74eDavid Li   unsigned max_version = 0;
15611591693c7b415e9869157c711fe11263c95d74eDavid Li   for (unsigned i = 0; i < prog->NumShaders; i++) {
15621591693c7b415e9869157c711fe11263c95d74eDavid Li      min_version = MIN2(min_version, prog->Shaders[i]->Version);
15631591693c7b415e9869157c711fe11263c95d74eDavid Li      max_version = MAX2(max_version, prog->Shaders[i]->Version);
15641591693c7b415e9869157c711fe11263c95d74eDavid Li
15651591693c7b415e9869157c711fe11263c95d74eDavid Li      switch (prog->Shaders[i]->Type) {
15661591693c7b415e9869157c711fe11263c95d74eDavid Li      case GL_VERTEX_SHADER:
15671591693c7b415e9869157c711fe11263c95d74eDavid Li	 vert_shader_list[num_vert_shaders] = prog->Shaders[i];
15681591693c7b415e9869157c711fe11263c95d74eDavid Li	 num_vert_shaders++;
15691591693c7b415e9869157c711fe11263c95d74eDavid Li	 break;
15701591693c7b415e9869157c711fe11263c95d74eDavid Li      case GL_FRAGMENT_SHADER:
15711591693c7b415e9869157c711fe11263c95d74eDavid Li	 frag_shader_list[num_frag_shaders] = prog->Shaders[i];
15721591693c7b415e9869157c711fe11263c95d74eDavid Li	 num_frag_shaders++;
15731591693c7b415e9869157c711fe11263c95d74eDavid Li	 break;
15741591693c7b415e9869157c711fe11263c95d74eDavid Li      case GL_GEOMETRY_SHADER:
15751591693c7b415e9869157c711fe11263c95d74eDavid Li	 /* FINISHME: Support geometry shaders. */
15761591693c7b415e9869157c711fe11263c95d74eDavid Li	 assert(prog->Shaders[i]->Type != GL_GEOMETRY_SHADER);
15771591693c7b415e9869157c711fe11263c95d74eDavid Li	 break;
15781591693c7b415e9869157c711fe11263c95d74eDavid Li      }
15791591693c7b415e9869157c711fe11263c95d74eDavid Li   }
15801591693c7b415e9869157c711fe11263c95d74eDavid Li
15811591693c7b415e9869157c711fe11263c95d74eDavid Li   /* Previous to GLSL version 1.30, different compilation units could mix and
15821591693c7b415e9869157c711fe11263c95d74eDavid Li    * match shading language versions.  With GLSL 1.30 and later, the versions
15831591693c7b415e9869157c711fe11263c95d74eDavid Li    * of all shaders must match.
15841591693c7b415e9869157c711fe11263c95d74eDavid Li    */
15851591693c7b415e9869157c711fe11263c95d74eDavid Li   assert(min_version >= 100);
15861591693c7b415e9869157c711fe11263c95d74eDavid Li   assert(max_version <= 130);
15871591693c7b415e9869157c711fe11263c95d74eDavid Li   if ((max_version >= 130 || min_version == 100)
15881591693c7b415e9869157c711fe11263c95d74eDavid Li       && min_version != max_version) {
15891591693c7b415e9869157c711fe11263c95d74eDavid Li      linker_error_printf(prog, "all shaders must use same shading "
15901591693c7b415e9869157c711fe11263c95d74eDavid Li			  "language version\n");
15911591693c7b415e9869157c711fe11263c95d74eDavid Li      goto done;
15921591693c7b415e9869157c711fe11263c95d74eDavid Li   }
15931591693c7b415e9869157c711fe11263c95d74eDavid Li
15941591693c7b415e9869157c711fe11263c95d74eDavid Li   prog->Version = max_version;
15951591693c7b415e9869157c711fe11263c95d74eDavid Li
15961591693c7b415e9869157c711fe11263c95d74eDavid Li   for (unsigned int i = 0; i < MESA_SHADER_TYPES; i++) {
15971591693c7b415e9869157c711fe11263c95d74eDavid Li      if (prog->_LinkedShaders[i] != NULL)
15981591693c7b415e9869157c711fe11263c95d74eDavid Li	 ctx->Driver.DeleteShader(ctx, prog->_LinkedShaders[i]);
15991591693c7b415e9869157c711fe11263c95d74eDavid Li
16001591693c7b415e9869157c711fe11263c95d74eDavid Li      prog->_LinkedShaders[i] = NULL;
16011591693c7b415e9869157c711fe11263c95d74eDavid Li   }
16021591693c7b415e9869157c711fe11263c95d74eDavid Li
16031591693c7b415e9869157c711fe11263c95d74eDavid Li   /* Link all shaders for a particular stage and validate the result.
16041591693c7b415e9869157c711fe11263c95d74eDavid Li    */
16051591693c7b415e9869157c711fe11263c95d74eDavid Li   if (num_vert_shaders > 0) {
16061591693c7b415e9869157c711fe11263c95d74eDavid Li      gl_shader *const sh =
16071591693c7b415e9869157c711fe11263c95d74eDavid Li	 link_intrastage_shaders(mem_ctx, ctx, prog, vert_shader_list,
16081591693c7b415e9869157c711fe11263c95d74eDavid Li				 num_vert_shaders);
16091591693c7b415e9869157c711fe11263c95d74eDavid Li
16101591693c7b415e9869157c711fe11263c95d74eDavid Li      if (sh == NULL)
16111591693c7b415e9869157c711fe11263c95d74eDavid Li	 goto done;
16121591693c7b415e9869157c711fe11263c95d74eDavid Li
16131591693c7b415e9869157c711fe11263c95d74eDavid Li      if (!validate_vertex_shader_executable(prog, sh))
16141591693c7b415e9869157c711fe11263c95d74eDavid Li	 goto done;
16151591693c7b415e9869157c711fe11263c95d74eDavid Li
16161591693c7b415e9869157c711fe11263c95d74eDavid Li      _mesa_reference_shader(ctx, &prog->_LinkedShaders[MESA_SHADER_VERTEX],
16171591693c7b415e9869157c711fe11263c95d74eDavid Li			     sh);
16181591693c7b415e9869157c711fe11263c95d74eDavid Li   }
16191591693c7b415e9869157c711fe11263c95d74eDavid Li
16201591693c7b415e9869157c711fe11263c95d74eDavid Li   if (num_frag_shaders > 0) {
16211591693c7b415e9869157c711fe11263c95d74eDavid Li      gl_shader *const sh =
16221591693c7b415e9869157c711fe11263c95d74eDavid Li	 link_intrastage_shaders(mem_ctx, ctx, prog, frag_shader_list,
16231591693c7b415e9869157c711fe11263c95d74eDavid Li				 num_frag_shaders);
16241591693c7b415e9869157c711fe11263c95d74eDavid Li
16251591693c7b415e9869157c711fe11263c95d74eDavid Li      if (sh == NULL)
16261591693c7b415e9869157c711fe11263c95d74eDavid Li	 goto done;
16271591693c7b415e9869157c711fe11263c95d74eDavid Li
16281591693c7b415e9869157c711fe11263c95d74eDavid Li      if (!validate_fragment_shader_executable(prog, sh))
16291591693c7b415e9869157c711fe11263c95d74eDavid Li	 goto done;
16301591693c7b415e9869157c711fe11263c95d74eDavid Li
16311591693c7b415e9869157c711fe11263c95d74eDavid Li      _mesa_reference_shader(ctx, &prog->_LinkedShaders[MESA_SHADER_FRAGMENT],
16321591693c7b415e9869157c711fe11263c95d74eDavid Li			     sh);
16331591693c7b415e9869157c711fe11263c95d74eDavid Li   }
16341591693c7b415e9869157c711fe11263c95d74eDavid Li
16351591693c7b415e9869157c711fe11263c95d74eDavid Li   /* Here begins the inter-stage linking phase.  Some initial validation is
16361591693c7b415e9869157c711fe11263c95d74eDavid Li    * performed, then locations are assigned for uniforms, attributes, and
16371591693c7b415e9869157c711fe11263c95d74eDavid Li    * varyings.
16381591693c7b415e9869157c711fe11263c95d74eDavid Li    */
16391591693c7b415e9869157c711fe11263c95d74eDavid Li   if (cross_validate_uniforms(prog)) {
16401591693c7b415e9869157c711fe11263c95d74eDavid Li      unsigned prev;
16411591693c7b415e9869157c711fe11263c95d74eDavid Li
16421591693c7b415e9869157c711fe11263c95d74eDavid Li      for (prev = 0; prev < MESA_SHADER_TYPES; prev++) {
16431591693c7b415e9869157c711fe11263c95d74eDavid Li	 if (prog->_LinkedShaders[prev] != NULL)
16441591693c7b415e9869157c711fe11263c95d74eDavid Li	    break;
16451591693c7b415e9869157c711fe11263c95d74eDavid Li      }
16461591693c7b415e9869157c711fe11263c95d74eDavid Li
16471591693c7b415e9869157c711fe11263c95d74eDavid Li      /* Validate the inputs of each stage with the output of the preceeding
16481591693c7b415e9869157c711fe11263c95d74eDavid Li       * stage.
16491591693c7b415e9869157c711fe11263c95d74eDavid Li       */
16501591693c7b415e9869157c711fe11263c95d74eDavid Li      for (unsigned i = prev + 1; i < MESA_SHADER_TYPES; i++) {
16511591693c7b415e9869157c711fe11263c95d74eDavid Li	 if (prog->_LinkedShaders[i] == NULL)
16521591693c7b415e9869157c711fe11263c95d74eDavid Li	    continue;
16531591693c7b415e9869157c711fe11263c95d74eDavid Li
16541591693c7b415e9869157c711fe11263c95d74eDavid Li	 if (!cross_validate_outputs_to_inputs(prog,
16551591693c7b415e9869157c711fe11263c95d74eDavid Li					       prog->_LinkedShaders[prev],
16561591693c7b415e9869157c711fe11263c95d74eDavid Li					       prog->_LinkedShaders[i]))
16571591693c7b415e9869157c711fe11263c95d74eDavid Li	    goto done;
16581591693c7b415e9869157c711fe11263c95d74eDavid Li
16591591693c7b415e9869157c711fe11263c95d74eDavid Li	 prev = i;
16601591693c7b415e9869157c711fe11263c95d74eDavid Li      }
16611591693c7b415e9869157c711fe11263c95d74eDavid Li
16621591693c7b415e9869157c711fe11263c95d74eDavid Li      prog->LinkStatus = true;
16631591693c7b415e9869157c711fe11263c95d74eDavid Li   }
16641591693c7b415e9869157c711fe11263c95d74eDavid Li
16651591693c7b415e9869157c711fe11263c95d74eDavid Li   /* Do common optimization before assigning storage for attributes,
16661591693c7b415e9869157c711fe11263c95d74eDavid Li    * uniforms, and varyings.  Later optimization could possibly make
16671591693c7b415e9869157c711fe11263c95d74eDavid Li    * some of that unused.
16681591693c7b415e9869157c711fe11263c95d74eDavid Li    */
16691591693c7b415e9869157c711fe11263c95d74eDavid Li   for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) {
16701591693c7b415e9869157c711fe11263c95d74eDavid Li      if (prog->_LinkedShaders[i] == NULL)
16711591693c7b415e9869157c711fe11263c95d74eDavid Li	 continue;
16721591693c7b415e9869157c711fe11263c95d74eDavid Li
16731591693c7b415e9869157c711fe11263c95d74eDavid Li      while (do_common_optimization(prog->_LinkedShaders[i]->ir, true, 32))
16741591693c7b415e9869157c711fe11263c95d74eDavid Li	 ;
16751591693c7b415e9869157c711fe11263c95d74eDavid Li   }
16761591693c7b415e9869157c711fe11263c95d74eDavid Li
16771591693c7b415e9869157c711fe11263c95d74eDavid Li   update_array_sizes(prog);
16781591693c7b415e9869157c711fe11263c95d74eDavid Li
16791591693c7b415e9869157c711fe11263c95d74eDavid Li   assign_uniform_locations(prog);
16801591693c7b415e9869157c711fe11263c95d74eDavid Li
16811591693c7b415e9869157c711fe11263c95d74eDavid Li   if (prog->_LinkedShaders[MESA_SHADER_VERTEX] != NULL) {
16821591693c7b415e9869157c711fe11263c95d74eDavid Li      /* FINISHME: The value of the max_attribute_index parameter is
16831591693c7b415e9869157c711fe11263c95d74eDavid Li       * FINISHME: implementation dependent based on the value of
16841591693c7b415e9869157c711fe11263c95d74eDavid Li       * FINISHME: GL_MAX_VERTEX_ATTRIBS.  GL_MAX_VERTEX_ATTRIBS must be
16851591693c7b415e9869157c711fe11263c95d74eDavid Li       * FINISHME: at least 16, so hardcode 16 for now.
16861591693c7b415e9869157c711fe11263c95d74eDavid Li       */
16871591693c7b415e9869157c711fe11263c95d74eDavid Li      if (!assign_attribute_locations(prog, 16)) {
16881591693c7b415e9869157c711fe11263c95d74eDavid Li	 prog->LinkStatus = false;
16891591693c7b415e9869157c711fe11263c95d74eDavid Li	 goto done;
16901591693c7b415e9869157c711fe11263c95d74eDavid Li      }
16911591693c7b415e9869157c711fe11263c95d74eDavid Li   }
16921591693c7b415e9869157c711fe11263c95d74eDavid Li
16931591693c7b415e9869157c711fe11263c95d74eDavid Li   unsigned prev;
16941591693c7b415e9869157c711fe11263c95d74eDavid Li   for (prev = 0; prev < MESA_SHADER_TYPES; prev++) {
16951591693c7b415e9869157c711fe11263c95d74eDavid Li      if (prog->_LinkedShaders[prev] != NULL)
16961591693c7b415e9869157c711fe11263c95d74eDavid Li	 break;
16971591693c7b415e9869157c711fe11263c95d74eDavid Li   }
16981591693c7b415e9869157c711fe11263c95d74eDavid Li
16991591693c7b415e9869157c711fe11263c95d74eDavid Li   for (unsigned i = prev + 1; i < MESA_SHADER_TYPES; i++) {
17001591693c7b415e9869157c711fe11263c95d74eDavid Li      if (prog->_LinkedShaders[i] == NULL)
17011591693c7b415e9869157c711fe11263c95d74eDavid Li	 continue;
17021591693c7b415e9869157c711fe11263c95d74eDavid Li
17031591693c7b415e9869157c711fe11263c95d74eDavid Li      assign_varying_locations(prog,
17041591693c7b415e9869157c711fe11263c95d74eDavid Li			       prog->_LinkedShaders[prev],
1705c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li			       prog->_LinkedShaders[i]);
17061591693c7b415e9869157c711fe11263c95d74eDavid Li      prev = i;
17071591693c7b415e9869157c711fe11263c95d74eDavid Li   }
17081591693c7b415e9869157c711fe11263c95d74eDavid Li
17091591693c7b415e9869157c711fe11263c95d74eDavid Li   if (prog->_LinkedShaders[MESA_SHADER_VERTEX] != NULL) {
1710f9ad8a790398513a845d486f58566854f7eceee4David Li      demote_shader_inputs_and_outputs(prog->_LinkedShaders[MESA_SHADER_VERTEX],
1711f9ad8a790398513a845d486f58566854f7eceee4David Li				       ir_var_out);
17121591693c7b415e9869157c711fe11263c95d74eDavid Li   }
17131591693c7b415e9869157c711fe11263c95d74eDavid Li
17141591693c7b415e9869157c711fe11263c95d74eDavid Li   if (prog->_LinkedShaders[MESA_SHADER_GEOMETRY] != NULL) {
17151591693c7b415e9869157c711fe11263c95d74eDavid Li      gl_shader *const sh = prog->_LinkedShaders[MESA_SHADER_GEOMETRY];
17161591693c7b415e9869157c711fe11263c95d74eDavid Li
17171591693c7b415e9869157c711fe11263c95d74eDavid Li      demote_shader_inputs_and_outputs(sh, ir_var_in);
17181591693c7b415e9869157c711fe11263c95d74eDavid Li      demote_shader_inputs_and_outputs(sh, ir_var_inout);
17191591693c7b415e9869157c711fe11263c95d74eDavid Li      demote_shader_inputs_and_outputs(sh, ir_var_out);
17201591693c7b415e9869157c711fe11263c95d74eDavid Li   }
17211591693c7b415e9869157c711fe11263c95d74eDavid Li
17221591693c7b415e9869157c711fe11263c95d74eDavid Li   if (prog->_LinkedShaders[MESA_SHADER_FRAGMENT] != NULL) {
17231591693c7b415e9869157c711fe11263c95d74eDavid Li      gl_shader *const sh = prog->_LinkedShaders[MESA_SHADER_FRAGMENT];
17241591693c7b415e9869157c711fe11263c95d74eDavid Li
1725f9ad8a790398513a845d486f58566854f7eceee4David Li      demote_shader_inputs_and_outputs(sh, ir_var_in);
1726c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li
1727c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li      foreach_list(node, sh->ir) {
1728c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         ir_variable *const var = ((ir_instruction *) node)->as_variable();
1729c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         if (!var || ir_var_out != var->mode)
1730c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li            continue;
1731c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         if (!strcmp("gl_FragColor", var->name) || !strcmp("gl_FragData", var->name))
1732c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         {
1733c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li            int paramIndex = _mesa_get_parameter(prog->Varying, var->name);
1734c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li            if (0 > paramIndex)
1735c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li               paramIndex = _mesa_add_parameter(prog->Varying, var->name);
17363225321119408735f16b72b539c9fb7d80683552David Li            var->location= offsetof(VertexOutput,fragColor)/sizeof(Vector4);
1737c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li            prog->Varying->Parameters[paramIndex].Location = var->location;
1738c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         }
1739c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li         else
1740c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li            assert(0);
1741c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li      }
17421591693c7b415e9869157c711fe11263c95d74eDavid Li   }
1743d274f94df69a016386195efcf0640802c7d7d2dcDavid Li
1744c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li   //prog->InputOuputBase = malloc(1024 * 8);
1745c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li   //memset(prog->InputOuputBase, 0xdd, 1024 * 8);
1746c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li   prog->InputOuputBase = hieralloc_realloc(prog, prog->InputOuputBase, char,
1747c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li      prog->Uniforms->Slots * 16 + sizeof(VertexInput) + sizeof(VertexOutput) + 16);
1748c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li   prog->ValuesVertexInput = (float (*)[4])((((unsigned long)prog->InputOuputBase) + 15) & (~15L));
1749c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li   prog->ValuesVertexOutput = (float (*)[4])((unsigned long)prog->ValuesVertexInput + sizeof(VertexInput));
1750c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li   prog->ValuesUniform = (float (*)[4])((unsigned long)prog->ValuesVertexOutput + sizeof(VertexOutput));
17511591693c7b415e9869157c711fe11263c95d74eDavid Li
17521591693c7b415e9869157c711fe11263c95d74eDavid Lidone:
17531591693c7b415e9869157c711fe11263c95d74eDavid Li   free(vert_shader_list);
17541591693c7b415e9869157c711fe11263c95d74eDavid Li
17551591693c7b415e9869157c711fe11263c95d74eDavid Li   for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) {
17561591693c7b415e9869157c711fe11263c95d74eDavid Li      if (prog->_LinkedShaders[i] == NULL)
17571591693c7b415e9869157c711fe11263c95d74eDavid Li	 continue;
17581591693c7b415e9869157c711fe11263c95d74eDavid Li
17591591693c7b415e9869157c711fe11263c95d74eDavid Li      /* Retain any live IR, but trash the rest. */
17601591693c7b415e9869157c711fe11263c95d74eDavid Li      reparent_ir(prog->_LinkedShaders[i]->ir, prog->_LinkedShaders[i]->ir);
17611591693c7b415e9869157c711fe11263c95d74eDavid Li   }
17621591693c7b415e9869157c711fe11263c95d74eDavid Li
176313fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li   //hieralloc_free(mem_ctx);
17643225321119408735f16b72b539c9fb7d80683552David Li}