linker.cpp revision 13fea0fc797fa0d4c236db5aa2e6a23fc0e450db
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 711591693c7b415e9869157c711fe11263c95d74eDavid Liextern "C" { 72d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li#include <hieralloc.h> 731591693c7b415e9869157c711fe11263c95d74eDavid Li} 741591693c7b415e9869157c711fe11263c95d74eDavid Li 751591693c7b415e9869157c711fe11263c95d74eDavid Li#include "main/core.h" 761591693c7b415e9869157c711fe11263c95d74eDavid Li#include "glsl_symbol_table.h" 771591693c7b415e9869157c711fe11263c95d74eDavid Li#include "ir.h" 781591693c7b415e9869157c711fe11263c95d74eDavid Li#include "program.h" 791591693c7b415e9869157c711fe11263c95d74eDavid Li#include "program/hash_table.h" 801591693c7b415e9869157c711fe11263c95d74eDavid Li#include "linker.h" 811591693c7b415e9869157c711fe11263c95d74eDavid Li#include "ir_optimization.h" 821591693c7b415e9869157c711fe11263c95d74eDavid Li 831591693c7b415e9869157c711fe11263c95d74eDavid Liextern "C" { 841591693c7b415e9869157c711fe11263c95d74eDavid Li#include "main/shaderobj.h" 851591693c7b415e9869157c711fe11263c95d74eDavid Li} 861591693c7b415e9869157c711fe11263c95d74eDavid Li 871591693c7b415e9869157c711fe11263c95d74eDavid Li/** 881591693c7b415e9869157c711fe11263c95d74eDavid Li * Visitor that determines whether or not a variable is ever written. 891591693c7b415e9869157c711fe11263c95d74eDavid Li */ 901591693c7b415e9869157c711fe11263c95d74eDavid Liclass find_assignment_visitor : public ir_hierarchical_visitor { 911591693c7b415e9869157c711fe11263c95d74eDavid Lipublic: 921591693c7b415e9869157c711fe11263c95d74eDavid Li find_assignment_visitor(const char *name) 931591693c7b415e9869157c711fe11263c95d74eDavid Li : name(name), found(false) 941591693c7b415e9869157c711fe11263c95d74eDavid Li { 951591693c7b415e9869157c711fe11263c95d74eDavid Li /* empty */ 961591693c7b415e9869157c711fe11263c95d74eDavid Li } 971591693c7b415e9869157c711fe11263c95d74eDavid Li 981591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_enter(ir_assignment *ir) 991591693c7b415e9869157c711fe11263c95d74eDavid Li { 1001591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *const var = ir->lhs->variable_referenced(); 1011591693c7b415e9869157c711fe11263c95d74eDavid Li 1021591693c7b415e9869157c711fe11263c95d74eDavid Li if (strcmp(name, var->name) == 0) { 1031591693c7b415e9869157c711fe11263c95d74eDavid Li found = true; 1041591693c7b415e9869157c711fe11263c95d74eDavid Li return visit_stop; 1051591693c7b415e9869157c711fe11263c95d74eDavid Li } 1061591693c7b415e9869157c711fe11263c95d74eDavid Li 1071591693c7b415e9869157c711fe11263c95d74eDavid Li return visit_continue_with_parent; 1081591693c7b415e9869157c711fe11263c95d74eDavid Li } 1091591693c7b415e9869157c711fe11263c95d74eDavid Li 1101591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_enter(ir_call *ir) 1111591693c7b415e9869157c711fe11263c95d74eDavid Li { 1121591693c7b415e9869157c711fe11263c95d74eDavid Li exec_list_iterator sig_iter = ir->get_callee()->parameters.iterator(); 1131591693c7b415e9869157c711fe11263c95d74eDavid Li foreach_iter(exec_list_iterator, iter, *ir) { 1141591693c7b415e9869157c711fe11263c95d74eDavid Li ir_rvalue *param_rval = (ir_rvalue *)iter.get(); 1151591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *sig_param = (ir_variable *)sig_iter.get(); 1161591693c7b415e9869157c711fe11263c95d74eDavid Li 1171591693c7b415e9869157c711fe11263c95d74eDavid Li if (sig_param->mode == ir_var_out || 1181591693c7b415e9869157c711fe11263c95d74eDavid Li sig_param->mode == ir_var_inout) { 1191591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *var = param_rval->variable_referenced(); 1201591693c7b415e9869157c711fe11263c95d74eDavid Li if (var && strcmp(name, var->name) == 0) { 1211591693c7b415e9869157c711fe11263c95d74eDavid Li found = true; 1221591693c7b415e9869157c711fe11263c95d74eDavid Li return visit_stop; 1231591693c7b415e9869157c711fe11263c95d74eDavid Li } 1241591693c7b415e9869157c711fe11263c95d74eDavid Li } 1251591693c7b415e9869157c711fe11263c95d74eDavid Li sig_iter.next(); 1261591693c7b415e9869157c711fe11263c95d74eDavid Li } 1271591693c7b415e9869157c711fe11263c95d74eDavid Li 1281591693c7b415e9869157c711fe11263c95d74eDavid Li return visit_continue_with_parent; 1291591693c7b415e9869157c711fe11263c95d74eDavid Li } 1301591693c7b415e9869157c711fe11263c95d74eDavid Li 1311591693c7b415e9869157c711fe11263c95d74eDavid Li bool variable_found() 1321591693c7b415e9869157c711fe11263c95d74eDavid Li { 1331591693c7b415e9869157c711fe11263c95d74eDavid Li return found; 1341591693c7b415e9869157c711fe11263c95d74eDavid Li } 1351591693c7b415e9869157c711fe11263c95d74eDavid Li 1361591693c7b415e9869157c711fe11263c95d74eDavid Liprivate: 1371591693c7b415e9869157c711fe11263c95d74eDavid Li const char *name; /**< Find writes to a variable with this name. */ 1381591693c7b415e9869157c711fe11263c95d74eDavid Li bool found; /**< Was a write to the variable found? */ 1391591693c7b415e9869157c711fe11263c95d74eDavid Li}; 1401591693c7b415e9869157c711fe11263c95d74eDavid Li 1411591693c7b415e9869157c711fe11263c95d74eDavid Li 1421591693c7b415e9869157c711fe11263c95d74eDavid Li/** 1431591693c7b415e9869157c711fe11263c95d74eDavid Li * Visitor that determines whether or not a variable is ever read. 1441591693c7b415e9869157c711fe11263c95d74eDavid Li */ 1451591693c7b415e9869157c711fe11263c95d74eDavid Liclass find_deref_visitor : public ir_hierarchical_visitor { 1461591693c7b415e9869157c711fe11263c95d74eDavid Lipublic: 1471591693c7b415e9869157c711fe11263c95d74eDavid Li find_deref_visitor(const char *name) 1481591693c7b415e9869157c711fe11263c95d74eDavid Li : name(name), found(false) 1491591693c7b415e9869157c711fe11263c95d74eDavid Li { 1501591693c7b415e9869157c711fe11263c95d74eDavid Li /* empty */ 1511591693c7b415e9869157c711fe11263c95d74eDavid Li } 1521591693c7b415e9869157c711fe11263c95d74eDavid Li 1531591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit(ir_dereference_variable *ir) 1541591693c7b415e9869157c711fe11263c95d74eDavid Li { 1551591693c7b415e9869157c711fe11263c95d74eDavid Li if (strcmp(this->name, ir->var->name) == 0) { 1561591693c7b415e9869157c711fe11263c95d74eDavid Li this->found = true; 1571591693c7b415e9869157c711fe11263c95d74eDavid Li return visit_stop; 1581591693c7b415e9869157c711fe11263c95d74eDavid Li } 1591591693c7b415e9869157c711fe11263c95d74eDavid Li 1601591693c7b415e9869157c711fe11263c95d74eDavid Li return visit_continue; 1611591693c7b415e9869157c711fe11263c95d74eDavid Li } 1621591693c7b415e9869157c711fe11263c95d74eDavid Li 1631591693c7b415e9869157c711fe11263c95d74eDavid Li bool variable_found() const 1641591693c7b415e9869157c711fe11263c95d74eDavid Li { 1651591693c7b415e9869157c711fe11263c95d74eDavid Li return this->found; 1661591693c7b415e9869157c711fe11263c95d74eDavid Li } 1671591693c7b415e9869157c711fe11263c95d74eDavid Li 1681591693c7b415e9869157c711fe11263c95d74eDavid Liprivate: 1691591693c7b415e9869157c711fe11263c95d74eDavid Li const char *name; /**< Find writes to a variable with this name. */ 1701591693c7b415e9869157c711fe11263c95d74eDavid Li bool found; /**< Was a write to the variable found? */ 1711591693c7b415e9869157c711fe11263c95d74eDavid Li}; 1721591693c7b415e9869157c711fe11263c95d74eDavid Li 1731591693c7b415e9869157c711fe11263c95d74eDavid Li 1741591693c7b415e9869157c711fe11263c95d74eDavid Livoid 1751591693c7b415e9869157c711fe11263c95d74eDavid Lilinker_error_printf(gl_shader_program *prog, const char *fmt, ...) 1761591693c7b415e9869157c711fe11263c95d74eDavid Li{ 1771591693c7b415e9869157c711fe11263c95d74eDavid Li va_list ap; 1781591693c7b415e9869157c711fe11263c95d74eDavid Li 179d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li prog->InfoLog = hieralloc_strdup_append(prog->InfoLog, "error: "); 1801591693c7b415e9869157c711fe11263c95d74eDavid Li va_start(ap, fmt); 181d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li prog->InfoLog = hieralloc_vasprintf_append(prog->InfoLog, fmt, ap); 1821591693c7b415e9869157c711fe11263c95d74eDavid Li va_end(ap); 1831591693c7b415e9869157c711fe11263c95d74eDavid Li} 1841591693c7b415e9869157c711fe11263c95d74eDavid Li 1851591693c7b415e9869157c711fe11263c95d74eDavid Li 1861591693c7b415e9869157c711fe11263c95d74eDavid Livoid 1871591693c7b415e9869157c711fe11263c95d74eDavid Liinvalidate_variable_locations(gl_shader *sh, enum ir_variable_mode mode, 1881591693c7b415e9869157c711fe11263c95d74eDavid Li int generic_base) 1891591693c7b415e9869157c711fe11263c95d74eDavid Li{ 1901591693c7b415e9869157c711fe11263c95d74eDavid Li foreach_list(node, sh->ir) { 1911591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *const var = ((ir_instruction *) node)->as_variable(); 1921591693c7b415e9869157c711fe11263c95d74eDavid Li 1931591693c7b415e9869157c711fe11263c95d74eDavid Li if ((var == NULL) || (var->mode != (unsigned) mode)) 1941591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 1951591693c7b415e9869157c711fe11263c95d74eDavid Li 1961591693c7b415e9869157c711fe11263c95d74eDavid Li /* Only assign locations for generic attributes / varyings / etc. 1971591693c7b415e9869157c711fe11263c95d74eDavid Li */ 1981591693c7b415e9869157c711fe11263c95d74eDavid Li if ((var->location >= generic_base) && !var->explicit_location) 1991591693c7b415e9869157c711fe11263c95d74eDavid Li var->location = -1; 2001591693c7b415e9869157c711fe11263c95d74eDavid Li } 2011591693c7b415e9869157c711fe11263c95d74eDavid Li} 2021591693c7b415e9869157c711fe11263c95d74eDavid Li 2031591693c7b415e9869157c711fe11263c95d74eDavid Li 2041591693c7b415e9869157c711fe11263c95d74eDavid Li/** 2051591693c7b415e9869157c711fe11263c95d74eDavid Li * Determine the number of attribute slots required for a particular type 2061591693c7b415e9869157c711fe11263c95d74eDavid Li * 2071591693c7b415e9869157c711fe11263c95d74eDavid Li * This code is here because it implements the language rules of a specific 2081591693c7b415e9869157c711fe11263c95d74eDavid Li * GLSL version. Since it's a property of the language and not a property of 2091591693c7b415e9869157c711fe11263c95d74eDavid Li * types in general, it doesn't really belong in glsl_type. 2101591693c7b415e9869157c711fe11263c95d74eDavid Li */ 2111591693c7b415e9869157c711fe11263c95d74eDavid Liunsigned 2121591693c7b415e9869157c711fe11263c95d74eDavid Licount_attribute_slots(const glsl_type *t) 2131591693c7b415e9869157c711fe11263c95d74eDavid Li{ 2141591693c7b415e9869157c711fe11263c95d74eDavid Li /* From page 31 (page 37 of the PDF) of the GLSL 1.50 spec: 2151591693c7b415e9869157c711fe11263c95d74eDavid Li * 2161591693c7b415e9869157c711fe11263c95d74eDavid Li * "A scalar input counts the same amount against this limit as a vec4, 2171591693c7b415e9869157c711fe11263c95d74eDavid Li * so applications may want to consider packing groups of four 2181591693c7b415e9869157c711fe11263c95d74eDavid Li * unrelated float inputs together into a vector to better utilize the 2191591693c7b415e9869157c711fe11263c95d74eDavid Li * capabilities of the underlying hardware. A matrix input will use up 2201591693c7b415e9869157c711fe11263c95d74eDavid Li * multiple locations. The number of locations used will equal the 2211591693c7b415e9869157c711fe11263c95d74eDavid Li * number of columns in the matrix." 2221591693c7b415e9869157c711fe11263c95d74eDavid Li * 2231591693c7b415e9869157c711fe11263c95d74eDavid Li * The spec does not explicitly say how arrays are counted. However, it 2241591693c7b415e9869157c711fe11263c95d74eDavid Li * should be safe to assume the total number of slots consumed by an array 2251591693c7b415e9869157c711fe11263c95d74eDavid Li * is the number of entries in the array multiplied by the number of slots 2261591693c7b415e9869157c711fe11263c95d74eDavid Li * consumed by a single element of the array. 2271591693c7b415e9869157c711fe11263c95d74eDavid Li */ 2281591693c7b415e9869157c711fe11263c95d74eDavid Li 2291591693c7b415e9869157c711fe11263c95d74eDavid Li if (t->is_array()) 2301591693c7b415e9869157c711fe11263c95d74eDavid Li return t->array_size() * count_attribute_slots(t->element_type()); 2311591693c7b415e9869157c711fe11263c95d74eDavid Li 2321591693c7b415e9869157c711fe11263c95d74eDavid Li if (t->is_matrix()) 2331591693c7b415e9869157c711fe11263c95d74eDavid Li return t->matrix_columns; 2341591693c7b415e9869157c711fe11263c95d74eDavid Li 2351591693c7b415e9869157c711fe11263c95d74eDavid Li return 1; 2361591693c7b415e9869157c711fe11263c95d74eDavid Li} 2371591693c7b415e9869157c711fe11263c95d74eDavid Li 2381591693c7b415e9869157c711fe11263c95d74eDavid Li 2391591693c7b415e9869157c711fe11263c95d74eDavid Li/** 2401591693c7b415e9869157c711fe11263c95d74eDavid Li * Verify that a vertex shader executable meets all semantic requirements 2411591693c7b415e9869157c711fe11263c95d74eDavid Li * 2421591693c7b415e9869157c711fe11263c95d74eDavid Li * \param shader Vertex shader executable to be verified 2431591693c7b415e9869157c711fe11263c95d74eDavid Li */ 2441591693c7b415e9869157c711fe11263c95d74eDavid Libool 2451591693c7b415e9869157c711fe11263c95d74eDavid Livalidate_vertex_shader_executable(struct gl_shader_program *prog, 2461591693c7b415e9869157c711fe11263c95d74eDavid Li struct gl_shader *shader) 2471591693c7b415e9869157c711fe11263c95d74eDavid Li{ 2481591693c7b415e9869157c711fe11263c95d74eDavid Li if (shader == NULL) 2491591693c7b415e9869157c711fe11263c95d74eDavid Li return true; 2501591693c7b415e9869157c711fe11263c95d74eDavid Li 2511591693c7b415e9869157c711fe11263c95d74eDavid Li find_assignment_visitor find("gl_Position"); 2521591693c7b415e9869157c711fe11263c95d74eDavid Li find.run(shader->ir); 2531591693c7b415e9869157c711fe11263c95d74eDavid Li if (!find.variable_found()) { 2541591693c7b415e9869157c711fe11263c95d74eDavid Li linker_error_printf(prog, 2551591693c7b415e9869157c711fe11263c95d74eDavid Li "vertex shader does not write to `gl_Position'\n"); 2561591693c7b415e9869157c711fe11263c95d74eDavid Li return false; 2571591693c7b415e9869157c711fe11263c95d74eDavid Li } 2581591693c7b415e9869157c711fe11263c95d74eDavid Li 2591591693c7b415e9869157c711fe11263c95d74eDavid Li return true; 2601591693c7b415e9869157c711fe11263c95d74eDavid Li} 2611591693c7b415e9869157c711fe11263c95d74eDavid Li 2621591693c7b415e9869157c711fe11263c95d74eDavid Li 2631591693c7b415e9869157c711fe11263c95d74eDavid Li/** 2641591693c7b415e9869157c711fe11263c95d74eDavid Li * Verify that a fragment shader executable meets all semantic requirements 2651591693c7b415e9869157c711fe11263c95d74eDavid Li * 2661591693c7b415e9869157c711fe11263c95d74eDavid Li * \param shader Fragment shader executable to be verified 2671591693c7b415e9869157c711fe11263c95d74eDavid Li */ 2681591693c7b415e9869157c711fe11263c95d74eDavid Libool 2691591693c7b415e9869157c711fe11263c95d74eDavid Livalidate_fragment_shader_executable(struct gl_shader_program *prog, 2701591693c7b415e9869157c711fe11263c95d74eDavid Li struct gl_shader *shader) 2711591693c7b415e9869157c711fe11263c95d74eDavid Li{ 2721591693c7b415e9869157c711fe11263c95d74eDavid Li if (shader == NULL) 2731591693c7b415e9869157c711fe11263c95d74eDavid Li return true; 2741591693c7b415e9869157c711fe11263c95d74eDavid Li 2751591693c7b415e9869157c711fe11263c95d74eDavid Li find_assignment_visitor frag_color("gl_FragColor"); 2761591693c7b415e9869157c711fe11263c95d74eDavid Li find_assignment_visitor frag_data("gl_FragData"); 2771591693c7b415e9869157c711fe11263c95d74eDavid Li 2781591693c7b415e9869157c711fe11263c95d74eDavid Li frag_color.run(shader->ir); 2791591693c7b415e9869157c711fe11263c95d74eDavid Li frag_data.run(shader->ir); 2801591693c7b415e9869157c711fe11263c95d74eDavid Li 2811591693c7b415e9869157c711fe11263c95d74eDavid Li if (frag_color.variable_found() && frag_data.variable_found()) { 2821591693c7b415e9869157c711fe11263c95d74eDavid Li linker_error_printf(prog, "fragment shader writes to both " 2831591693c7b415e9869157c711fe11263c95d74eDavid Li "`gl_FragColor' and `gl_FragData'\n"); 2841591693c7b415e9869157c711fe11263c95d74eDavid Li return false; 2851591693c7b415e9869157c711fe11263c95d74eDavid Li } 2861591693c7b415e9869157c711fe11263c95d74eDavid Li 2871591693c7b415e9869157c711fe11263c95d74eDavid Li return true; 2881591693c7b415e9869157c711fe11263c95d74eDavid Li} 2891591693c7b415e9869157c711fe11263c95d74eDavid Li 2901591693c7b415e9869157c711fe11263c95d74eDavid Li 2911591693c7b415e9869157c711fe11263c95d74eDavid Li/** 2921591693c7b415e9869157c711fe11263c95d74eDavid Li * Generate a string describing the mode of a variable 2931591693c7b415e9869157c711fe11263c95d74eDavid Li */ 2941591693c7b415e9869157c711fe11263c95d74eDavid Listatic const char * 2951591693c7b415e9869157c711fe11263c95d74eDavid Limode_string(const ir_variable *var) 2961591693c7b415e9869157c711fe11263c95d74eDavid Li{ 2971591693c7b415e9869157c711fe11263c95d74eDavid Li switch (var->mode) { 2981591693c7b415e9869157c711fe11263c95d74eDavid Li case ir_var_auto: 2991591693c7b415e9869157c711fe11263c95d74eDavid Li return (var->read_only) ? "global constant" : "global variable"; 3001591693c7b415e9869157c711fe11263c95d74eDavid Li 3011591693c7b415e9869157c711fe11263c95d74eDavid Li case ir_var_uniform: return "uniform"; 3021591693c7b415e9869157c711fe11263c95d74eDavid Li case ir_var_in: return "shader input"; 3031591693c7b415e9869157c711fe11263c95d74eDavid Li case ir_var_out: return "shader output"; 3041591693c7b415e9869157c711fe11263c95d74eDavid Li case ir_var_inout: return "shader inout"; 3051591693c7b415e9869157c711fe11263c95d74eDavid Li 3061591693c7b415e9869157c711fe11263c95d74eDavid Li case ir_var_temporary: 3071591693c7b415e9869157c711fe11263c95d74eDavid Li default: 3081591693c7b415e9869157c711fe11263c95d74eDavid Li assert(!"Should not get here."); 3091591693c7b415e9869157c711fe11263c95d74eDavid Li return "invalid variable"; 3101591693c7b415e9869157c711fe11263c95d74eDavid Li } 3111591693c7b415e9869157c711fe11263c95d74eDavid Li} 3121591693c7b415e9869157c711fe11263c95d74eDavid Li 3131591693c7b415e9869157c711fe11263c95d74eDavid Li 3141591693c7b415e9869157c711fe11263c95d74eDavid Li/** 3151591693c7b415e9869157c711fe11263c95d74eDavid Li * Perform validation of global variables used across multiple shaders 3161591693c7b415e9869157c711fe11263c95d74eDavid Li */ 3171591693c7b415e9869157c711fe11263c95d74eDavid Libool 3181591693c7b415e9869157c711fe11263c95d74eDavid Licross_validate_globals(struct gl_shader_program *prog, 3191591693c7b415e9869157c711fe11263c95d74eDavid Li struct gl_shader **shader_list, 3201591693c7b415e9869157c711fe11263c95d74eDavid Li unsigned num_shaders, 3211591693c7b415e9869157c711fe11263c95d74eDavid Li bool uniforms_only) 3221591693c7b415e9869157c711fe11263c95d74eDavid Li{ 3231591693c7b415e9869157c711fe11263c95d74eDavid Li /* Examine all of the uniforms in all of the shaders and cross validate 3241591693c7b415e9869157c711fe11263c95d74eDavid Li * them. 3251591693c7b415e9869157c711fe11263c95d74eDavid Li */ 3261591693c7b415e9869157c711fe11263c95d74eDavid Li glsl_symbol_table variables; 3271591693c7b415e9869157c711fe11263c95d74eDavid Li for (unsigned i = 0; i < num_shaders; i++) { 3281591693c7b415e9869157c711fe11263c95d74eDavid Li if (shader_list[i] == NULL) 3291591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 3301591693c7b415e9869157c711fe11263c95d74eDavid Li 3311591693c7b415e9869157c711fe11263c95d74eDavid Li foreach_list(node, shader_list[i]->ir) { 3321591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *const var = ((ir_instruction *) node)->as_variable(); 3331591693c7b415e9869157c711fe11263c95d74eDavid Li 3341591693c7b415e9869157c711fe11263c95d74eDavid Li if (var == NULL) 3351591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 3361591693c7b415e9869157c711fe11263c95d74eDavid Li 3371591693c7b415e9869157c711fe11263c95d74eDavid Li if (uniforms_only && (var->mode != ir_var_uniform)) 3381591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 3391591693c7b415e9869157c711fe11263c95d74eDavid Li 3401591693c7b415e9869157c711fe11263c95d74eDavid Li /* Don't cross validate temporaries that are at global scope. These 3411591693c7b415e9869157c711fe11263c95d74eDavid Li * will eventually get pulled into the shaders 'main'. 3421591693c7b415e9869157c711fe11263c95d74eDavid Li */ 3431591693c7b415e9869157c711fe11263c95d74eDavid Li if (var->mode == ir_var_temporary) 3441591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 3451591693c7b415e9869157c711fe11263c95d74eDavid Li 3461591693c7b415e9869157c711fe11263c95d74eDavid Li /* If a global with this name has already been seen, verify that the 3471591693c7b415e9869157c711fe11263c95d74eDavid Li * new instance has the same type. In addition, if the globals have 3481591693c7b415e9869157c711fe11263c95d74eDavid Li * initializers, the values of the initializers must be the same. 3491591693c7b415e9869157c711fe11263c95d74eDavid Li */ 3501591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *const existing = variables.get_variable(var->name); 3511591693c7b415e9869157c711fe11263c95d74eDavid Li if (existing != NULL) { 3521591693c7b415e9869157c711fe11263c95d74eDavid Li if (var->type != existing->type) { 3531591693c7b415e9869157c711fe11263c95d74eDavid Li /* Consider the types to be "the same" if both types are arrays 3541591693c7b415e9869157c711fe11263c95d74eDavid Li * of the same type and one of the arrays is implicitly sized. 3551591693c7b415e9869157c711fe11263c95d74eDavid Li * In addition, set the type of the linked variable to the 3561591693c7b415e9869157c711fe11263c95d74eDavid Li * explicitly sized array. 3571591693c7b415e9869157c711fe11263c95d74eDavid Li */ 3581591693c7b415e9869157c711fe11263c95d74eDavid Li if (var->type->is_array() 3591591693c7b415e9869157c711fe11263c95d74eDavid Li && existing->type->is_array() 3601591693c7b415e9869157c711fe11263c95d74eDavid Li && (var->type->fields.array == existing->type->fields.array) 3611591693c7b415e9869157c711fe11263c95d74eDavid Li && ((var->type->length == 0) 3621591693c7b415e9869157c711fe11263c95d74eDavid Li || (existing->type->length == 0))) { 3631591693c7b415e9869157c711fe11263c95d74eDavid Li if (existing->type->length == 0) { 3641591693c7b415e9869157c711fe11263c95d74eDavid Li existing->type = var->type; 3651591693c7b415e9869157c711fe11263c95d74eDavid Li existing->max_array_access = 3661591693c7b415e9869157c711fe11263c95d74eDavid Li MAX2(existing->max_array_access, 3671591693c7b415e9869157c711fe11263c95d74eDavid Li var->max_array_access); 3681591693c7b415e9869157c711fe11263c95d74eDavid Li } 3691591693c7b415e9869157c711fe11263c95d74eDavid Li } else { 3701591693c7b415e9869157c711fe11263c95d74eDavid Li linker_error_printf(prog, "%s `%s' declared as type " 3711591693c7b415e9869157c711fe11263c95d74eDavid Li "`%s' and type `%s'\n", 3721591693c7b415e9869157c711fe11263c95d74eDavid Li mode_string(var), 3731591693c7b415e9869157c711fe11263c95d74eDavid Li var->name, var->type->name, 3741591693c7b415e9869157c711fe11263c95d74eDavid Li existing->type->name); 3751591693c7b415e9869157c711fe11263c95d74eDavid Li return false; 3761591693c7b415e9869157c711fe11263c95d74eDavid Li } 3771591693c7b415e9869157c711fe11263c95d74eDavid Li } 3781591693c7b415e9869157c711fe11263c95d74eDavid Li 3791591693c7b415e9869157c711fe11263c95d74eDavid Li if (var->explicit_location) { 3801591693c7b415e9869157c711fe11263c95d74eDavid Li if (existing->explicit_location 3811591693c7b415e9869157c711fe11263c95d74eDavid Li && (var->location != existing->location)) { 3821591693c7b415e9869157c711fe11263c95d74eDavid Li linker_error_printf(prog, "explicit locations for %s " 3831591693c7b415e9869157c711fe11263c95d74eDavid Li "`%s' have differing values\n", 3841591693c7b415e9869157c711fe11263c95d74eDavid Li mode_string(var), var->name); 3851591693c7b415e9869157c711fe11263c95d74eDavid Li return false; 3861591693c7b415e9869157c711fe11263c95d74eDavid Li } 3871591693c7b415e9869157c711fe11263c95d74eDavid Li 3881591693c7b415e9869157c711fe11263c95d74eDavid Li existing->location = var->location; 3891591693c7b415e9869157c711fe11263c95d74eDavid Li existing->explicit_location = true; 3901591693c7b415e9869157c711fe11263c95d74eDavid Li } 3911591693c7b415e9869157c711fe11263c95d74eDavid Li 3921591693c7b415e9869157c711fe11263c95d74eDavid Li /* FINISHME: Handle non-constant initializers. 3931591693c7b415e9869157c711fe11263c95d74eDavid Li */ 3941591693c7b415e9869157c711fe11263c95d74eDavid Li if (var->constant_value != NULL) { 3951591693c7b415e9869157c711fe11263c95d74eDavid Li if (existing->constant_value != NULL) { 3961591693c7b415e9869157c711fe11263c95d74eDavid Li if (!var->constant_value->has_value(existing->constant_value)) { 3971591693c7b415e9869157c711fe11263c95d74eDavid Li linker_error_printf(prog, "initializers for %s " 3981591693c7b415e9869157c711fe11263c95d74eDavid Li "`%s' have differing values\n", 3991591693c7b415e9869157c711fe11263c95d74eDavid Li mode_string(var), var->name); 4001591693c7b415e9869157c711fe11263c95d74eDavid Li return false; 4011591693c7b415e9869157c711fe11263c95d74eDavid Li } 4021591693c7b415e9869157c711fe11263c95d74eDavid Li } else 4031591693c7b415e9869157c711fe11263c95d74eDavid Li /* If the first-seen instance of a particular uniform did not 4041591693c7b415e9869157c711fe11263c95d74eDavid Li * have an initializer but a later instance does, copy the 4051591693c7b415e9869157c711fe11263c95d74eDavid Li * initializer to the version stored in the symbol table. 4061591693c7b415e9869157c711fe11263c95d74eDavid Li */ 4071591693c7b415e9869157c711fe11263c95d74eDavid Li /* FINISHME: This is wrong. The constant_value field should 4081591693c7b415e9869157c711fe11263c95d74eDavid Li * FINISHME: not be modified! Imagine a case where a shader 4091591693c7b415e9869157c711fe11263c95d74eDavid Li * FINISHME: without an initializer is linked in two different 4101591693c7b415e9869157c711fe11263c95d74eDavid Li * FINISHME: programs with shaders that have differing 4111591693c7b415e9869157c711fe11263c95d74eDavid Li * FINISHME: initializers. Linking with the first will 4121591693c7b415e9869157c711fe11263c95d74eDavid Li * FINISHME: modify the shader, and linking with the second 4131591693c7b415e9869157c711fe11263c95d74eDavid Li * FINISHME: will fail. 4141591693c7b415e9869157c711fe11263c95d74eDavid Li */ 4151591693c7b415e9869157c711fe11263c95d74eDavid Li existing->constant_value = 416d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li var->constant_value->clone(hieralloc_parent(existing), NULL); 4171591693c7b415e9869157c711fe11263c95d74eDavid Li } 4181591693c7b415e9869157c711fe11263c95d74eDavid Li 4191591693c7b415e9869157c711fe11263c95d74eDavid Li if (existing->invariant != var->invariant) { 4201591693c7b415e9869157c711fe11263c95d74eDavid Li linker_error_printf(prog, "declarations for %s `%s' have " 4211591693c7b415e9869157c711fe11263c95d74eDavid Li "mismatching invariant qualifiers\n", 4221591693c7b415e9869157c711fe11263c95d74eDavid Li mode_string(var), var->name); 4231591693c7b415e9869157c711fe11263c95d74eDavid Li return false; 4241591693c7b415e9869157c711fe11263c95d74eDavid Li } 4251591693c7b415e9869157c711fe11263c95d74eDavid Li } else 4261591693c7b415e9869157c711fe11263c95d74eDavid Li variables.add_variable(var); 4271591693c7b415e9869157c711fe11263c95d74eDavid Li } 4281591693c7b415e9869157c711fe11263c95d74eDavid Li } 4291591693c7b415e9869157c711fe11263c95d74eDavid Li 4301591693c7b415e9869157c711fe11263c95d74eDavid Li return true; 4311591693c7b415e9869157c711fe11263c95d74eDavid Li} 4321591693c7b415e9869157c711fe11263c95d74eDavid Li 4331591693c7b415e9869157c711fe11263c95d74eDavid Li 4341591693c7b415e9869157c711fe11263c95d74eDavid Li/** 4351591693c7b415e9869157c711fe11263c95d74eDavid Li * Perform validation of uniforms used across multiple shader stages 4361591693c7b415e9869157c711fe11263c95d74eDavid Li */ 4371591693c7b415e9869157c711fe11263c95d74eDavid Libool 4381591693c7b415e9869157c711fe11263c95d74eDavid Licross_validate_uniforms(struct gl_shader_program *prog) 4391591693c7b415e9869157c711fe11263c95d74eDavid Li{ 4401591693c7b415e9869157c711fe11263c95d74eDavid Li return cross_validate_globals(prog, prog->_LinkedShaders, 4411591693c7b415e9869157c711fe11263c95d74eDavid Li MESA_SHADER_TYPES, true); 4421591693c7b415e9869157c711fe11263c95d74eDavid Li} 4431591693c7b415e9869157c711fe11263c95d74eDavid Li 4441591693c7b415e9869157c711fe11263c95d74eDavid Li 4451591693c7b415e9869157c711fe11263c95d74eDavid Li/** 4461591693c7b415e9869157c711fe11263c95d74eDavid Li * Validate that outputs from one stage match inputs of another 4471591693c7b415e9869157c711fe11263c95d74eDavid Li */ 4481591693c7b415e9869157c711fe11263c95d74eDavid Libool 4491591693c7b415e9869157c711fe11263c95d74eDavid Licross_validate_outputs_to_inputs(struct gl_shader_program *prog, 4501591693c7b415e9869157c711fe11263c95d74eDavid Li gl_shader *producer, gl_shader *consumer) 4511591693c7b415e9869157c711fe11263c95d74eDavid Li{ 4521591693c7b415e9869157c711fe11263c95d74eDavid Li glsl_symbol_table parameters; 4531591693c7b415e9869157c711fe11263c95d74eDavid Li /* FINISHME: Figure these out dynamically. */ 4541591693c7b415e9869157c711fe11263c95d74eDavid Li const char *const producer_stage = "vertex"; 4551591693c7b415e9869157c711fe11263c95d74eDavid Li const char *const consumer_stage = "fragment"; 4561591693c7b415e9869157c711fe11263c95d74eDavid Li 4571591693c7b415e9869157c711fe11263c95d74eDavid Li /* Find all shader outputs in the "producer" stage. 4581591693c7b415e9869157c711fe11263c95d74eDavid Li */ 4591591693c7b415e9869157c711fe11263c95d74eDavid Li foreach_list(node, producer->ir) { 4601591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *const var = ((ir_instruction *) node)->as_variable(); 4611591693c7b415e9869157c711fe11263c95d74eDavid Li 4621591693c7b415e9869157c711fe11263c95d74eDavid Li /* FINISHME: For geometry shaders, this should also look for inout 4631591693c7b415e9869157c711fe11263c95d74eDavid Li * FINISHME: variables. 4641591693c7b415e9869157c711fe11263c95d74eDavid Li */ 4651591693c7b415e9869157c711fe11263c95d74eDavid Li if ((var == NULL) || (var->mode != ir_var_out)) 4661591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 4671591693c7b415e9869157c711fe11263c95d74eDavid Li 4681591693c7b415e9869157c711fe11263c95d74eDavid Li parameters.add_variable(var); 4691591693c7b415e9869157c711fe11263c95d74eDavid Li } 4701591693c7b415e9869157c711fe11263c95d74eDavid Li 4711591693c7b415e9869157c711fe11263c95d74eDavid Li 4721591693c7b415e9869157c711fe11263c95d74eDavid Li /* Find all shader inputs in the "consumer" stage. Any variables that have 4731591693c7b415e9869157c711fe11263c95d74eDavid Li * matching outputs already in the symbol table must have the same type and 4741591693c7b415e9869157c711fe11263c95d74eDavid Li * qualifiers. 4751591693c7b415e9869157c711fe11263c95d74eDavid Li */ 4761591693c7b415e9869157c711fe11263c95d74eDavid Li foreach_list(node, consumer->ir) { 4771591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *const input = ((ir_instruction *) node)->as_variable(); 4781591693c7b415e9869157c711fe11263c95d74eDavid Li 4791591693c7b415e9869157c711fe11263c95d74eDavid Li /* FINISHME: For geometry shaders, this should also look for inout 4801591693c7b415e9869157c711fe11263c95d74eDavid Li * FINISHME: variables. 4811591693c7b415e9869157c711fe11263c95d74eDavid Li */ 4821591693c7b415e9869157c711fe11263c95d74eDavid Li if ((input == NULL) || (input->mode != ir_var_in)) 4831591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 4841591693c7b415e9869157c711fe11263c95d74eDavid Li 4851591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *const output = parameters.get_variable(input->name); 4861591693c7b415e9869157c711fe11263c95d74eDavid Li if (output != NULL) { 4871591693c7b415e9869157c711fe11263c95d74eDavid Li /* Check that the types match between stages. 4881591693c7b415e9869157c711fe11263c95d74eDavid Li */ 4891591693c7b415e9869157c711fe11263c95d74eDavid Li if (input->type != output->type) { 4901591693c7b415e9869157c711fe11263c95d74eDavid Li /* There is a bit of a special case for gl_TexCoord. This 4911591693c7b415e9869157c711fe11263c95d74eDavid Li * built-in is unsized by default. Appliations that variable 4921591693c7b415e9869157c711fe11263c95d74eDavid Li * access it must redeclare it with a size. There is some 4931591693c7b415e9869157c711fe11263c95d74eDavid Li * language in the GLSL spec that implies the fragment shader 4941591693c7b415e9869157c711fe11263c95d74eDavid Li * and vertex shader do not have to agree on this size. Other 4951591693c7b415e9869157c711fe11263c95d74eDavid Li * driver behave this way, and one or two applications seem to 4961591693c7b415e9869157c711fe11263c95d74eDavid Li * rely on it. 4971591693c7b415e9869157c711fe11263c95d74eDavid Li * 4981591693c7b415e9869157c711fe11263c95d74eDavid Li * Neither declaration needs to be modified here because the array 4991591693c7b415e9869157c711fe11263c95d74eDavid Li * sizes are fixed later when update_array_sizes is called. 5001591693c7b415e9869157c711fe11263c95d74eDavid Li * 5011591693c7b415e9869157c711fe11263c95d74eDavid Li * From page 48 (page 54 of the PDF) of the GLSL 1.10 spec: 5021591693c7b415e9869157c711fe11263c95d74eDavid Li * 5031591693c7b415e9869157c711fe11263c95d74eDavid Li * "Unlike user-defined varying variables, the built-in 5041591693c7b415e9869157c711fe11263c95d74eDavid Li * varying variables don't have a strict one-to-one 5051591693c7b415e9869157c711fe11263c95d74eDavid Li * correspondence between the vertex language and the 5061591693c7b415e9869157c711fe11263c95d74eDavid Li * fragment language." 5071591693c7b415e9869157c711fe11263c95d74eDavid Li */ 5081591693c7b415e9869157c711fe11263c95d74eDavid Li if (!output->type->is_array() 5091591693c7b415e9869157c711fe11263c95d74eDavid Li || (strncmp("gl_", output->name, 3) != 0)) { 5101591693c7b415e9869157c711fe11263c95d74eDavid Li linker_error_printf(prog, 5111591693c7b415e9869157c711fe11263c95d74eDavid Li "%s shader output `%s' declared as " 5121591693c7b415e9869157c711fe11263c95d74eDavid Li "type `%s', but %s shader input declared " 5131591693c7b415e9869157c711fe11263c95d74eDavid Li "as type `%s'\n", 5141591693c7b415e9869157c711fe11263c95d74eDavid Li producer_stage, output->name, 5151591693c7b415e9869157c711fe11263c95d74eDavid Li output->type->name, 5161591693c7b415e9869157c711fe11263c95d74eDavid Li consumer_stage, input->type->name); 5171591693c7b415e9869157c711fe11263c95d74eDavid Li return false; 5181591693c7b415e9869157c711fe11263c95d74eDavid Li } 5191591693c7b415e9869157c711fe11263c95d74eDavid Li } 5201591693c7b415e9869157c711fe11263c95d74eDavid Li 5211591693c7b415e9869157c711fe11263c95d74eDavid Li /* Check that all of the qualifiers match between stages. 5221591693c7b415e9869157c711fe11263c95d74eDavid Li */ 5231591693c7b415e9869157c711fe11263c95d74eDavid Li if (input->centroid != output->centroid) { 5241591693c7b415e9869157c711fe11263c95d74eDavid Li linker_error_printf(prog, 5251591693c7b415e9869157c711fe11263c95d74eDavid Li "%s shader output `%s' %s centroid qualifier, " 5261591693c7b415e9869157c711fe11263c95d74eDavid Li "but %s shader input %s centroid qualifier\n", 5271591693c7b415e9869157c711fe11263c95d74eDavid Li producer_stage, 5281591693c7b415e9869157c711fe11263c95d74eDavid Li output->name, 5291591693c7b415e9869157c711fe11263c95d74eDavid Li (output->centroid) ? "has" : "lacks", 5301591693c7b415e9869157c711fe11263c95d74eDavid Li consumer_stage, 5311591693c7b415e9869157c711fe11263c95d74eDavid Li (input->centroid) ? "has" : "lacks"); 5321591693c7b415e9869157c711fe11263c95d74eDavid Li return false; 5331591693c7b415e9869157c711fe11263c95d74eDavid Li } 5341591693c7b415e9869157c711fe11263c95d74eDavid Li 5351591693c7b415e9869157c711fe11263c95d74eDavid Li if (input->invariant != output->invariant) { 5361591693c7b415e9869157c711fe11263c95d74eDavid Li linker_error_printf(prog, 5371591693c7b415e9869157c711fe11263c95d74eDavid Li "%s shader output `%s' %s invariant qualifier, " 5381591693c7b415e9869157c711fe11263c95d74eDavid Li "but %s shader input %s invariant qualifier\n", 5391591693c7b415e9869157c711fe11263c95d74eDavid Li producer_stage, 5401591693c7b415e9869157c711fe11263c95d74eDavid Li output->name, 5411591693c7b415e9869157c711fe11263c95d74eDavid Li (output->invariant) ? "has" : "lacks", 5421591693c7b415e9869157c711fe11263c95d74eDavid Li consumer_stage, 5431591693c7b415e9869157c711fe11263c95d74eDavid Li (input->invariant) ? "has" : "lacks"); 5441591693c7b415e9869157c711fe11263c95d74eDavid Li return false; 5451591693c7b415e9869157c711fe11263c95d74eDavid Li } 5461591693c7b415e9869157c711fe11263c95d74eDavid Li 5471591693c7b415e9869157c711fe11263c95d74eDavid Li if (input->interpolation != output->interpolation) { 5481591693c7b415e9869157c711fe11263c95d74eDavid Li linker_error_printf(prog, 5491591693c7b415e9869157c711fe11263c95d74eDavid Li "%s shader output `%s' specifies %s " 5501591693c7b415e9869157c711fe11263c95d74eDavid Li "interpolation qualifier, " 5511591693c7b415e9869157c711fe11263c95d74eDavid Li "but %s shader input specifies %s " 5521591693c7b415e9869157c711fe11263c95d74eDavid Li "interpolation qualifier\n", 5531591693c7b415e9869157c711fe11263c95d74eDavid Li producer_stage, 5541591693c7b415e9869157c711fe11263c95d74eDavid Li output->name, 5551591693c7b415e9869157c711fe11263c95d74eDavid Li output->interpolation_string(), 5561591693c7b415e9869157c711fe11263c95d74eDavid Li consumer_stage, 5571591693c7b415e9869157c711fe11263c95d74eDavid Li input->interpolation_string()); 5581591693c7b415e9869157c711fe11263c95d74eDavid Li return false; 5591591693c7b415e9869157c711fe11263c95d74eDavid Li } 5601591693c7b415e9869157c711fe11263c95d74eDavid Li } 5611591693c7b415e9869157c711fe11263c95d74eDavid Li } 5621591693c7b415e9869157c711fe11263c95d74eDavid Li 5631591693c7b415e9869157c711fe11263c95d74eDavid Li return true; 5641591693c7b415e9869157c711fe11263c95d74eDavid Li} 5651591693c7b415e9869157c711fe11263c95d74eDavid Li 5661591693c7b415e9869157c711fe11263c95d74eDavid Li 5671591693c7b415e9869157c711fe11263c95d74eDavid Li/** 5681591693c7b415e9869157c711fe11263c95d74eDavid Li * Populates a shaders symbol table with all global declarations 5691591693c7b415e9869157c711fe11263c95d74eDavid Li */ 5701591693c7b415e9869157c711fe11263c95d74eDavid Listatic void 5711591693c7b415e9869157c711fe11263c95d74eDavid Lipopulate_symbol_table(gl_shader *sh) 5721591693c7b415e9869157c711fe11263c95d74eDavid Li{ 5731591693c7b415e9869157c711fe11263c95d74eDavid Li sh->symbols = new(sh) glsl_symbol_table; 5741591693c7b415e9869157c711fe11263c95d74eDavid Li 5751591693c7b415e9869157c711fe11263c95d74eDavid Li foreach_list(node, sh->ir) { 5761591693c7b415e9869157c711fe11263c95d74eDavid Li ir_instruction *const inst = (ir_instruction *) node; 5771591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *var; 5781591693c7b415e9869157c711fe11263c95d74eDavid Li ir_function *func; 5791591693c7b415e9869157c711fe11263c95d74eDavid Li 5801591693c7b415e9869157c711fe11263c95d74eDavid Li if ((func = inst->as_function()) != NULL) { 5811591693c7b415e9869157c711fe11263c95d74eDavid Li sh->symbols->add_function(func); 5821591693c7b415e9869157c711fe11263c95d74eDavid Li } else if ((var = inst->as_variable()) != NULL) { 5831591693c7b415e9869157c711fe11263c95d74eDavid Li sh->symbols->add_variable(var); 5841591693c7b415e9869157c711fe11263c95d74eDavid Li } 5851591693c7b415e9869157c711fe11263c95d74eDavid Li } 5861591693c7b415e9869157c711fe11263c95d74eDavid Li} 5871591693c7b415e9869157c711fe11263c95d74eDavid Li 5881591693c7b415e9869157c711fe11263c95d74eDavid Li 5891591693c7b415e9869157c711fe11263c95d74eDavid Li/** 5901591693c7b415e9869157c711fe11263c95d74eDavid Li * Remap variables referenced in an instruction tree 5911591693c7b415e9869157c711fe11263c95d74eDavid Li * 5921591693c7b415e9869157c711fe11263c95d74eDavid Li * This is used when instruction trees are cloned from one shader and placed in 5931591693c7b415e9869157c711fe11263c95d74eDavid Li * another. These trees will contain references to \c ir_variable nodes that 5941591693c7b415e9869157c711fe11263c95d74eDavid Li * do not exist in the target shader. This function finds these \c ir_variable 5951591693c7b415e9869157c711fe11263c95d74eDavid Li * references and replaces the references with matching variables in the target 5961591693c7b415e9869157c711fe11263c95d74eDavid Li * shader. 5971591693c7b415e9869157c711fe11263c95d74eDavid Li * 5981591693c7b415e9869157c711fe11263c95d74eDavid Li * If there is no matching variable in the target shader, a clone of the 5991591693c7b415e9869157c711fe11263c95d74eDavid Li * \c ir_variable is made and added to the target shader. The new variable is 6001591693c7b415e9869157c711fe11263c95d74eDavid Li * added to \b both the instruction stream and the symbol table. 6011591693c7b415e9869157c711fe11263c95d74eDavid Li * 6021591693c7b415e9869157c711fe11263c95d74eDavid Li * \param inst IR tree that is to be processed. 6031591693c7b415e9869157c711fe11263c95d74eDavid Li * \param symbols Symbol table containing global scope symbols in the 6041591693c7b415e9869157c711fe11263c95d74eDavid Li * linked shader. 6051591693c7b415e9869157c711fe11263c95d74eDavid Li * \param instructions Instruction stream where new variable declarations 6061591693c7b415e9869157c711fe11263c95d74eDavid Li * should be added. 6071591693c7b415e9869157c711fe11263c95d74eDavid Li */ 6081591693c7b415e9869157c711fe11263c95d74eDavid Livoid 6091591693c7b415e9869157c711fe11263c95d74eDavid Liremap_variables(ir_instruction *inst, struct gl_shader *target, 6101591693c7b415e9869157c711fe11263c95d74eDavid Li hash_table *temps) 6111591693c7b415e9869157c711fe11263c95d74eDavid Li{ 6121591693c7b415e9869157c711fe11263c95d74eDavid Li class remap_visitor : public ir_hierarchical_visitor { 6131591693c7b415e9869157c711fe11263c95d74eDavid Li public: 6141591693c7b415e9869157c711fe11263c95d74eDavid Li remap_visitor(struct gl_shader *target, 6151591693c7b415e9869157c711fe11263c95d74eDavid Li hash_table *temps) 6161591693c7b415e9869157c711fe11263c95d74eDavid Li { 6171591693c7b415e9869157c711fe11263c95d74eDavid Li this->target = target; 6181591693c7b415e9869157c711fe11263c95d74eDavid Li this->symbols = target->symbols; 6191591693c7b415e9869157c711fe11263c95d74eDavid Li this->instructions = target->ir; 6201591693c7b415e9869157c711fe11263c95d74eDavid Li this->temps = temps; 6211591693c7b415e9869157c711fe11263c95d74eDavid Li } 6221591693c7b415e9869157c711fe11263c95d74eDavid Li 6231591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit(ir_dereference_variable *ir) 6241591693c7b415e9869157c711fe11263c95d74eDavid Li { 6251591693c7b415e9869157c711fe11263c95d74eDavid Li if (ir->var->mode == ir_var_temporary) { 6261591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *var = (ir_variable *) hash_table_find(temps, ir->var); 6271591693c7b415e9869157c711fe11263c95d74eDavid Li 6281591693c7b415e9869157c711fe11263c95d74eDavid Li assert(var != NULL); 6291591693c7b415e9869157c711fe11263c95d74eDavid Li ir->var = var; 6301591693c7b415e9869157c711fe11263c95d74eDavid Li return visit_continue; 6311591693c7b415e9869157c711fe11263c95d74eDavid Li } 6321591693c7b415e9869157c711fe11263c95d74eDavid Li 6331591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *const existing = 6341591693c7b415e9869157c711fe11263c95d74eDavid Li this->symbols->get_variable(ir->var->name); 6351591693c7b415e9869157c711fe11263c95d74eDavid Li if (existing != NULL) 6361591693c7b415e9869157c711fe11263c95d74eDavid Li ir->var = existing; 6371591693c7b415e9869157c711fe11263c95d74eDavid Li else { 6381591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *copy = ir->var->clone(this->target, NULL); 6391591693c7b415e9869157c711fe11263c95d74eDavid Li 6401591693c7b415e9869157c711fe11263c95d74eDavid Li this->symbols->add_variable(copy); 6411591693c7b415e9869157c711fe11263c95d74eDavid Li this->instructions->push_head(copy); 6421591693c7b415e9869157c711fe11263c95d74eDavid Li ir->var = copy; 6431591693c7b415e9869157c711fe11263c95d74eDavid Li } 6441591693c7b415e9869157c711fe11263c95d74eDavid Li 6451591693c7b415e9869157c711fe11263c95d74eDavid Li return visit_continue; 6461591693c7b415e9869157c711fe11263c95d74eDavid Li } 6471591693c7b415e9869157c711fe11263c95d74eDavid Li 6481591693c7b415e9869157c711fe11263c95d74eDavid Li private: 6491591693c7b415e9869157c711fe11263c95d74eDavid Li struct gl_shader *target; 6501591693c7b415e9869157c711fe11263c95d74eDavid Li glsl_symbol_table *symbols; 6511591693c7b415e9869157c711fe11263c95d74eDavid Li exec_list *instructions; 6521591693c7b415e9869157c711fe11263c95d74eDavid Li hash_table *temps; 6531591693c7b415e9869157c711fe11263c95d74eDavid Li }; 6541591693c7b415e9869157c711fe11263c95d74eDavid Li 6551591693c7b415e9869157c711fe11263c95d74eDavid Li remap_visitor v(target, temps); 6561591693c7b415e9869157c711fe11263c95d74eDavid Li 6571591693c7b415e9869157c711fe11263c95d74eDavid Li inst->accept(&v); 6581591693c7b415e9869157c711fe11263c95d74eDavid Li} 6591591693c7b415e9869157c711fe11263c95d74eDavid Li 6601591693c7b415e9869157c711fe11263c95d74eDavid Li 6611591693c7b415e9869157c711fe11263c95d74eDavid Li/** 6621591693c7b415e9869157c711fe11263c95d74eDavid Li * Move non-declarations from one instruction stream to another 6631591693c7b415e9869157c711fe11263c95d74eDavid Li * 6641591693c7b415e9869157c711fe11263c95d74eDavid Li * The intended usage pattern of this function is to pass the pointer to the 6651591693c7b415e9869157c711fe11263c95d74eDavid Li * head sentinel of a list (i.e., a pointer to the list cast to an \c exec_node 6661591693c7b415e9869157c711fe11263c95d74eDavid Li * pointer) for \c last and \c false for \c make_copies on the first 6671591693c7b415e9869157c711fe11263c95d74eDavid Li * call. Successive calls pass the return value of the previous call for 6681591693c7b415e9869157c711fe11263c95d74eDavid Li * \c last and \c true for \c make_copies. 6691591693c7b415e9869157c711fe11263c95d74eDavid Li * 6701591693c7b415e9869157c711fe11263c95d74eDavid Li * \param instructions Source instruction stream 6711591693c7b415e9869157c711fe11263c95d74eDavid Li * \param last Instruction after which new instructions should be 6721591693c7b415e9869157c711fe11263c95d74eDavid Li * inserted in the target instruction stream 6731591693c7b415e9869157c711fe11263c95d74eDavid Li * \param make_copies Flag selecting whether instructions in \c instructions 6741591693c7b415e9869157c711fe11263c95d74eDavid Li * should be copied (via \c ir_instruction::clone) into the 6751591693c7b415e9869157c711fe11263c95d74eDavid Li * target list or moved. 6761591693c7b415e9869157c711fe11263c95d74eDavid Li * 6771591693c7b415e9869157c711fe11263c95d74eDavid Li * \return 6781591693c7b415e9869157c711fe11263c95d74eDavid Li * The new "last" instruction in the target instruction stream. This pointer 6791591693c7b415e9869157c711fe11263c95d74eDavid Li * is suitable for use as the \c last parameter of a later call to this 6801591693c7b415e9869157c711fe11263c95d74eDavid Li * function. 6811591693c7b415e9869157c711fe11263c95d74eDavid Li */ 6821591693c7b415e9869157c711fe11263c95d74eDavid Liexec_node * 6831591693c7b415e9869157c711fe11263c95d74eDavid Limove_non_declarations(exec_list *instructions, exec_node *last, 6841591693c7b415e9869157c711fe11263c95d74eDavid Li bool make_copies, gl_shader *target) 6851591693c7b415e9869157c711fe11263c95d74eDavid Li{ 6861591693c7b415e9869157c711fe11263c95d74eDavid Li hash_table *temps = NULL; 6871591693c7b415e9869157c711fe11263c95d74eDavid Li 6881591693c7b415e9869157c711fe11263c95d74eDavid Li if (make_copies) 6891591693c7b415e9869157c711fe11263c95d74eDavid Li temps = hash_table_ctor(0, hash_table_pointer_hash, 6901591693c7b415e9869157c711fe11263c95d74eDavid Li hash_table_pointer_compare); 6911591693c7b415e9869157c711fe11263c95d74eDavid Li 6921591693c7b415e9869157c711fe11263c95d74eDavid Li foreach_list_safe(node, instructions) { 6931591693c7b415e9869157c711fe11263c95d74eDavid Li ir_instruction *inst = (ir_instruction *) node; 6941591693c7b415e9869157c711fe11263c95d74eDavid Li 6951591693c7b415e9869157c711fe11263c95d74eDavid Li if (inst->as_function()) 6961591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 6971591693c7b415e9869157c711fe11263c95d74eDavid Li 6981591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *var = inst->as_variable(); 6991591693c7b415e9869157c711fe11263c95d74eDavid Li if ((var != NULL) && (var->mode != ir_var_temporary)) 7001591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 7011591693c7b415e9869157c711fe11263c95d74eDavid Li 7021591693c7b415e9869157c711fe11263c95d74eDavid Li assert(inst->as_assignment() 7031591693c7b415e9869157c711fe11263c95d74eDavid Li || ((var != NULL) && (var->mode == ir_var_temporary))); 7041591693c7b415e9869157c711fe11263c95d74eDavid Li 7051591693c7b415e9869157c711fe11263c95d74eDavid Li if (make_copies) { 7061591693c7b415e9869157c711fe11263c95d74eDavid Li inst = inst->clone(target, NULL); 7071591693c7b415e9869157c711fe11263c95d74eDavid Li 7081591693c7b415e9869157c711fe11263c95d74eDavid Li if (var != NULL) 7091591693c7b415e9869157c711fe11263c95d74eDavid Li hash_table_insert(temps, inst, var); 7101591693c7b415e9869157c711fe11263c95d74eDavid Li else 7111591693c7b415e9869157c711fe11263c95d74eDavid Li remap_variables(inst, target, temps); 7121591693c7b415e9869157c711fe11263c95d74eDavid Li } else { 7131591693c7b415e9869157c711fe11263c95d74eDavid Li inst->remove(); 7141591693c7b415e9869157c711fe11263c95d74eDavid Li } 7151591693c7b415e9869157c711fe11263c95d74eDavid Li 7161591693c7b415e9869157c711fe11263c95d74eDavid Li last->insert_after(inst); 7171591693c7b415e9869157c711fe11263c95d74eDavid Li last = inst; 7181591693c7b415e9869157c711fe11263c95d74eDavid Li } 7191591693c7b415e9869157c711fe11263c95d74eDavid Li 7201591693c7b415e9869157c711fe11263c95d74eDavid Li if (make_copies) 7211591693c7b415e9869157c711fe11263c95d74eDavid Li hash_table_dtor(temps); 7221591693c7b415e9869157c711fe11263c95d74eDavid Li 7231591693c7b415e9869157c711fe11263c95d74eDavid Li return last; 7241591693c7b415e9869157c711fe11263c95d74eDavid Li} 7251591693c7b415e9869157c711fe11263c95d74eDavid Li 7261591693c7b415e9869157c711fe11263c95d74eDavid Li/** 7271591693c7b415e9869157c711fe11263c95d74eDavid Li * Get the function signature for main from a shader 7281591693c7b415e9869157c711fe11263c95d74eDavid Li */ 7291591693c7b415e9869157c711fe11263c95d74eDavid Listatic ir_function_signature * 7301591693c7b415e9869157c711fe11263c95d74eDavid Liget_main_function_signature(gl_shader *sh) 7311591693c7b415e9869157c711fe11263c95d74eDavid Li{ 7321591693c7b415e9869157c711fe11263c95d74eDavid Li ir_function *const f = sh->symbols->get_function("main"); 7331591693c7b415e9869157c711fe11263c95d74eDavid Li if (f != NULL) { 7341591693c7b415e9869157c711fe11263c95d74eDavid Li exec_list void_parameters; 7351591693c7b415e9869157c711fe11263c95d74eDavid Li 7361591693c7b415e9869157c711fe11263c95d74eDavid Li /* Look for the 'void main()' signature and ensure that it's defined. 7371591693c7b415e9869157c711fe11263c95d74eDavid Li * This keeps the linker from accidentally pick a shader that just 7381591693c7b415e9869157c711fe11263c95d74eDavid Li * contains a prototype for main. 7391591693c7b415e9869157c711fe11263c95d74eDavid Li * 7401591693c7b415e9869157c711fe11263c95d74eDavid Li * We don't have to check for multiple definitions of main (in multiple 7411591693c7b415e9869157c711fe11263c95d74eDavid Li * shaders) because that would have already been caught above. 7421591693c7b415e9869157c711fe11263c95d74eDavid Li */ 7431591693c7b415e9869157c711fe11263c95d74eDavid Li ir_function_signature *sig = f->matching_signature(&void_parameters); 7441591693c7b415e9869157c711fe11263c95d74eDavid Li if ((sig != NULL) && sig->is_defined) { 7451591693c7b415e9869157c711fe11263c95d74eDavid Li return sig; 7461591693c7b415e9869157c711fe11263c95d74eDavid Li } 7471591693c7b415e9869157c711fe11263c95d74eDavid Li } 7481591693c7b415e9869157c711fe11263c95d74eDavid Li 7491591693c7b415e9869157c711fe11263c95d74eDavid Li return NULL; 7501591693c7b415e9869157c711fe11263c95d74eDavid Li} 7511591693c7b415e9869157c711fe11263c95d74eDavid Li 7521591693c7b415e9869157c711fe11263c95d74eDavid Li 7531591693c7b415e9869157c711fe11263c95d74eDavid Li/** 7541591693c7b415e9869157c711fe11263c95d74eDavid Li * Combine a group of shaders for a single stage to generate a linked shader 7551591693c7b415e9869157c711fe11263c95d74eDavid Li * 7561591693c7b415e9869157c711fe11263c95d74eDavid Li * \note 7571591693c7b415e9869157c711fe11263c95d74eDavid Li * If this function is supplied a single shader, it is cloned, and the new 7581591693c7b415e9869157c711fe11263c95d74eDavid Li * shader is returned. 7591591693c7b415e9869157c711fe11263c95d74eDavid Li */ 7601591693c7b415e9869157c711fe11263c95d74eDavid Listatic struct gl_shader * 7611591693c7b415e9869157c711fe11263c95d74eDavid Lilink_intrastage_shaders(void *mem_ctx, 7621591693c7b415e9869157c711fe11263c95d74eDavid Li struct gl_context *ctx, 7631591693c7b415e9869157c711fe11263c95d74eDavid Li struct gl_shader_program *prog, 7641591693c7b415e9869157c711fe11263c95d74eDavid Li struct gl_shader **shader_list, 7651591693c7b415e9869157c711fe11263c95d74eDavid Li unsigned num_shaders) 7661591693c7b415e9869157c711fe11263c95d74eDavid Li{ 7671591693c7b415e9869157c711fe11263c95d74eDavid Li /* Check that global variables defined in multiple shaders are consistent. 7681591693c7b415e9869157c711fe11263c95d74eDavid Li */ 7691591693c7b415e9869157c711fe11263c95d74eDavid Li if (!cross_validate_globals(prog, shader_list, num_shaders, false)) 7701591693c7b415e9869157c711fe11263c95d74eDavid Li return NULL; 7711591693c7b415e9869157c711fe11263c95d74eDavid Li 7721591693c7b415e9869157c711fe11263c95d74eDavid Li /* Check that there is only a single definition of each function signature 7731591693c7b415e9869157c711fe11263c95d74eDavid Li * across all shaders. 7741591693c7b415e9869157c711fe11263c95d74eDavid Li */ 7751591693c7b415e9869157c711fe11263c95d74eDavid Li for (unsigned i = 0; i < (num_shaders - 1); i++) { 7761591693c7b415e9869157c711fe11263c95d74eDavid Li foreach_list(node, shader_list[i]->ir) { 7771591693c7b415e9869157c711fe11263c95d74eDavid Li ir_function *const f = ((ir_instruction *) node)->as_function(); 7781591693c7b415e9869157c711fe11263c95d74eDavid Li 7791591693c7b415e9869157c711fe11263c95d74eDavid Li if (f == NULL) 7801591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 7811591693c7b415e9869157c711fe11263c95d74eDavid Li 7821591693c7b415e9869157c711fe11263c95d74eDavid Li for (unsigned j = i + 1; j < num_shaders; j++) { 7831591693c7b415e9869157c711fe11263c95d74eDavid Li ir_function *const other = 7841591693c7b415e9869157c711fe11263c95d74eDavid Li shader_list[j]->symbols->get_function(f->name); 7851591693c7b415e9869157c711fe11263c95d74eDavid Li 7861591693c7b415e9869157c711fe11263c95d74eDavid Li /* If the other shader has no function (and therefore no function 7871591693c7b415e9869157c711fe11263c95d74eDavid Li * signatures) with the same name, skip to the next shader. 7881591693c7b415e9869157c711fe11263c95d74eDavid Li */ 7891591693c7b415e9869157c711fe11263c95d74eDavid Li if (other == NULL) 7901591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 7911591693c7b415e9869157c711fe11263c95d74eDavid Li 7921591693c7b415e9869157c711fe11263c95d74eDavid Li foreach_iter (exec_list_iterator, iter, *f) { 7931591693c7b415e9869157c711fe11263c95d74eDavid Li ir_function_signature *sig = 7941591693c7b415e9869157c711fe11263c95d74eDavid Li (ir_function_signature *) iter.get(); 7951591693c7b415e9869157c711fe11263c95d74eDavid Li 7961591693c7b415e9869157c711fe11263c95d74eDavid Li if (!sig->is_defined || sig->is_builtin) 7971591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 7981591693c7b415e9869157c711fe11263c95d74eDavid Li 7991591693c7b415e9869157c711fe11263c95d74eDavid Li ir_function_signature *other_sig = 8001591693c7b415e9869157c711fe11263c95d74eDavid Li other->exact_matching_signature(& sig->parameters); 8011591693c7b415e9869157c711fe11263c95d74eDavid Li 8021591693c7b415e9869157c711fe11263c95d74eDavid Li if ((other_sig != NULL) && other_sig->is_defined 8031591693c7b415e9869157c711fe11263c95d74eDavid Li && !other_sig->is_builtin) { 8041591693c7b415e9869157c711fe11263c95d74eDavid Li linker_error_printf(prog, 8051591693c7b415e9869157c711fe11263c95d74eDavid Li "function `%s' is multiply defined", 8061591693c7b415e9869157c711fe11263c95d74eDavid Li f->name); 8071591693c7b415e9869157c711fe11263c95d74eDavid Li return NULL; 8081591693c7b415e9869157c711fe11263c95d74eDavid Li } 8091591693c7b415e9869157c711fe11263c95d74eDavid Li } 8101591693c7b415e9869157c711fe11263c95d74eDavid Li } 8111591693c7b415e9869157c711fe11263c95d74eDavid Li } 8121591693c7b415e9869157c711fe11263c95d74eDavid Li } 8131591693c7b415e9869157c711fe11263c95d74eDavid Li 8141591693c7b415e9869157c711fe11263c95d74eDavid Li /* Find the shader that defines main, and make a clone of it. 8151591693c7b415e9869157c711fe11263c95d74eDavid Li * 8161591693c7b415e9869157c711fe11263c95d74eDavid Li * Starting with the clone, search for undefined references. If one is 8171591693c7b415e9869157c711fe11263c95d74eDavid Li * found, find the shader that defines it. Clone the reference and add 8181591693c7b415e9869157c711fe11263c95d74eDavid Li * it to the shader. Repeat until there are no undefined references or 8191591693c7b415e9869157c711fe11263c95d74eDavid Li * until a reference cannot be resolved. 8201591693c7b415e9869157c711fe11263c95d74eDavid Li */ 8211591693c7b415e9869157c711fe11263c95d74eDavid Li gl_shader *main = NULL; 8221591693c7b415e9869157c711fe11263c95d74eDavid Li for (unsigned i = 0; i < num_shaders; i++) { 8231591693c7b415e9869157c711fe11263c95d74eDavid Li if (get_main_function_signature(shader_list[i]) != NULL) { 8241591693c7b415e9869157c711fe11263c95d74eDavid Li main = shader_list[i]; 8251591693c7b415e9869157c711fe11263c95d74eDavid Li break; 8261591693c7b415e9869157c711fe11263c95d74eDavid Li } 8271591693c7b415e9869157c711fe11263c95d74eDavid Li } 8281591693c7b415e9869157c711fe11263c95d74eDavid Li 8291591693c7b415e9869157c711fe11263c95d74eDavid Li if (main == NULL) { 8301591693c7b415e9869157c711fe11263c95d74eDavid Li linker_error_printf(prog, "%s shader lacks `main'\n", 8311591693c7b415e9869157c711fe11263c95d74eDavid Li (shader_list[0]->Type == GL_VERTEX_SHADER) 8321591693c7b415e9869157c711fe11263c95d74eDavid Li ? "vertex" : "fragment"); 8331591693c7b415e9869157c711fe11263c95d74eDavid Li return NULL; 8341591693c7b415e9869157c711fe11263c95d74eDavid Li } 8351591693c7b415e9869157c711fe11263c95d74eDavid Li 8361591693c7b415e9869157c711fe11263c95d74eDavid Li gl_shader *linked = ctx->Driver.NewShader(NULL, 0, main->Type); 8371591693c7b415e9869157c711fe11263c95d74eDavid Li linked->ir = new(linked) exec_list; 8381591693c7b415e9869157c711fe11263c95d74eDavid Li clone_ir_list(mem_ctx, linked->ir, main->ir); 8391591693c7b415e9869157c711fe11263c95d74eDavid Li 8401591693c7b415e9869157c711fe11263c95d74eDavid Li populate_symbol_table(linked); 8411591693c7b415e9869157c711fe11263c95d74eDavid Li 8421591693c7b415e9869157c711fe11263c95d74eDavid Li /* The a pointer to the main function in the final linked shader (i.e., the 8431591693c7b415e9869157c711fe11263c95d74eDavid Li * copy of the original shader that contained the main function). 8441591693c7b415e9869157c711fe11263c95d74eDavid Li */ 8451591693c7b415e9869157c711fe11263c95d74eDavid Li ir_function_signature *const main_sig = get_main_function_signature(linked); 8461591693c7b415e9869157c711fe11263c95d74eDavid Li 8471591693c7b415e9869157c711fe11263c95d74eDavid Li /* Move any instructions other than variable declarations or function 8481591693c7b415e9869157c711fe11263c95d74eDavid Li * declarations into main. 8491591693c7b415e9869157c711fe11263c95d74eDavid Li */ 8501591693c7b415e9869157c711fe11263c95d74eDavid Li exec_node *insertion_point = 8511591693c7b415e9869157c711fe11263c95d74eDavid Li move_non_declarations(linked->ir, (exec_node *) &main_sig->body, false, 8521591693c7b415e9869157c711fe11263c95d74eDavid Li linked); 8531591693c7b415e9869157c711fe11263c95d74eDavid Li 8541591693c7b415e9869157c711fe11263c95d74eDavid Li for (unsigned i = 0; i < num_shaders; i++) { 8551591693c7b415e9869157c711fe11263c95d74eDavid Li if (shader_list[i] == main) 8561591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 8571591693c7b415e9869157c711fe11263c95d74eDavid Li 8581591693c7b415e9869157c711fe11263c95d74eDavid Li insertion_point = move_non_declarations(shader_list[i]->ir, 8591591693c7b415e9869157c711fe11263c95d74eDavid Li insertion_point, true, linked); 8601591693c7b415e9869157c711fe11263c95d74eDavid Li } 8611591693c7b415e9869157c711fe11263c95d74eDavid Li 8621591693c7b415e9869157c711fe11263c95d74eDavid Li /* Resolve initializers for global variables in the linked shader. 8631591693c7b415e9869157c711fe11263c95d74eDavid Li */ 8641591693c7b415e9869157c711fe11263c95d74eDavid Li unsigned num_linking_shaders = num_shaders; 8651591693c7b415e9869157c711fe11263c95d74eDavid Li for (unsigned i = 0; i < num_shaders; i++) 8661591693c7b415e9869157c711fe11263c95d74eDavid Li num_linking_shaders += shader_list[i]->num_builtins_to_link; 8671591693c7b415e9869157c711fe11263c95d74eDavid Li 8681591693c7b415e9869157c711fe11263c95d74eDavid Li gl_shader **linking_shaders = 8691591693c7b415e9869157c711fe11263c95d74eDavid Li (gl_shader **) calloc(num_linking_shaders, sizeof(gl_shader *)); 8701591693c7b415e9869157c711fe11263c95d74eDavid Li 8711591693c7b415e9869157c711fe11263c95d74eDavid Li memcpy(linking_shaders, shader_list, 8721591693c7b415e9869157c711fe11263c95d74eDavid Li sizeof(linking_shaders[0]) * num_shaders); 8731591693c7b415e9869157c711fe11263c95d74eDavid Li 8741591693c7b415e9869157c711fe11263c95d74eDavid Li unsigned idx = num_shaders; 8751591693c7b415e9869157c711fe11263c95d74eDavid Li for (unsigned i = 0; i < num_shaders; i++) { 8761591693c7b415e9869157c711fe11263c95d74eDavid Li memcpy(&linking_shaders[idx], shader_list[i]->builtins_to_link, 8771591693c7b415e9869157c711fe11263c95d74eDavid Li sizeof(linking_shaders[0]) * shader_list[i]->num_builtins_to_link); 8781591693c7b415e9869157c711fe11263c95d74eDavid Li idx += shader_list[i]->num_builtins_to_link; 8791591693c7b415e9869157c711fe11263c95d74eDavid Li } 8801591693c7b415e9869157c711fe11263c95d74eDavid Li 8811591693c7b415e9869157c711fe11263c95d74eDavid Li assert(idx == num_linking_shaders); 8821591693c7b415e9869157c711fe11263c95d74eDavid Li 8831591693c7b415e9869157c711fe11263c95d74eDavid Li if (!link_function_calls(prog, linked, linking_shaders, 8841591693c7b415e9869157c711fe11263c95d74eDavid Li num_linking_shaders)) { 8851591693c7b415e9869157c711fe11263c95d74eDavid Li ctx->Driver.DeleteShader(ctx, linked); 8861591693c7b415e9869157c711fe11263c95d74eDavid Li linked = NULL; 8871591693c7b415e9869157c711fe11263c95d74eDavid Li } 8881591693c7b415e9869157c711fe11263c95d74eDavid Li 8891591693c7b415e9869157c711fe11263c95d74eDavid Li free(linking_shaders); 8901591693c7b415e9869157c711fe11263c95d74eDavid Li 8911591693c7b415e9869157c711fe11263c95d74eDavid Li /* Make a pass over all global variables to ensure that arrays with 8921591693c7b415e9869157c711fe11263c95d74eDavid Li * unspecified sizes have a size specified. The size is inferred from the 8931591693c7b415e9869157c711fe11263c95d74eDavid Li * max_array_access field. 8941591693c7b415e9869157c711fe11263c95d74eDavid Li */ 8951591693c7b415e9869157c711fe11263c95d74eDavid Li if (linked != NULL) { 8961591693c7b415e9869157c711fe11263c95d74eDavid Li foreach_list(node, linked->ir) { 8971591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *const var = ((ir_instruction *) node)->as_variable(); 8981591693c7b415e9869157c711fe11263c95d74eDavid Li 8991591693c7b415e9869157c711fe11263c95d74eDavid Li if (var == NULL) 9001591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 9011591693c7b415e9869157c711fe11263c95d74eDavid Li 9021591693c7b415e9869157c711fe11263c95d74eDavid Li if ((var->mode != ir_var_auto) && (var->mode != ir_var_temporary)) 9031591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 9041591693c7b415e9869157c711fe11263c95d74eDavid Li 9051591693c7b415e9869157c711fe11263c95d74eDavid Li if (!var->type->is_array() || (var->type->length != 0)) 9061591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 9071591693c7b415e9869157c711fe11263c95d74eDavid Li 9081591693c7b415e9869157c711fe11263c95d74eDavid Li const glsl_type *type = 9091591693c7b415e9869157c711fe11263c95d74eDavid Li glsl_type::get_array_instance(var->type->fields.array, 9101591693c7b415e9869157c711fe11263c95d74eDavid Li var->max_array_access); 9111591693c7b415e9869157c711fe11263c95d74eDavid Li 9121591693c7b415e9869157c711fe11263c95d74eDavid Li assert(type != NULL); 9131591693c7b415e9869157c711fe11263c95d74eDavid Li var->type = type; 9141591693c7b415e9869157c711fe11263c95d74eDavid Li } 9151591693c7b415e9869157c711fe11263c95d74eDavid Li } 9161591693c7b415e9869157c711fe11263c95d74eDavid Li 9171591693c7b415e9869157c711fe11263c95d74eDavid Li return linked; 9181591693c7b415e9869157c711fe11263c95d74eDavid Li} 9191591693c7b415e9869157c711fe11263c95d74eDavid Li 9201591693c7b415e9869157c711fe11263c95d74eDavid Li 9211591693c7b415e9869157c711fe11263c95d74eDavid Listruct uniform_node { 9221591693c7b415e9869157c711fe11263c95d74eDavid Li exec_node link; 9231591693c7b415e9869157c711fe11263c95d74eDavid Li struct gl_uniform *u; 9241591693c7b415e9869157c711fe11263c95d74eDavid Li unsigned slots; 9251591693c7b415e9869157c711fe11263c95d74eDavid Li}; 9261591693c7b415e9869157c711fe11263c95d74eDavid Li 9271591693c7b415e9869157c711fe11263c95d74eDavid Li/** 9281591693c7b415e9869157c711fe11263c95d74eDavid Li * Update the sizes of linked shader uniform arrays to the maximum 9291591693c7b415e9869157c711fe11263c95d74eDavid Li * array index used. 9301591693c7b415e9869157c711fe11263c95d74eDavid Li * 9311591693c7b415e9869157c711fe11263c95d74eDavid Li * From page 81 (page 95 of the PDF) of the OpenGL 2.1 spec: 9321591693c7b415e9869157c711fe11263c95d74eDavid Li * 9331591693c7b415e9869157c711fe11263c95d74eDavid Li * If one or more elements of an array are active, 9341591693c7b415e9869157c711fe11263c95d74eDavid Li * GetActiveUniform will return the name of the array in name, 9351591693c7b415e9869157c711fe11263c95d74eDavid Li * subject to the restrictions listed above. The type of the array 9361591693c7b415e9869157c711fe11263c95d74eDavid Li * is returned in type. The size parameter contains the highest 9371591693c7b415e9869157c711fe11263c95d74eDavid Li * array element index used, plus one. The compiler or linker 9381591693c7b415e9869157c711fe11263c95d74eDavid Li * determines the highest index used. There will be only one 9391591693c7b415e9869157c711fe11263c95d74eDavid Li * active uniform reported by the GL per uniform array. 9401591693c7b415e9869157c711fe11263c95d74eDavid Li 9411591693c7b415e9869157c711fe11263c95d74eDavid Li */ 9421591693c7b415e9869157c711fe11263c95d74eDavid Listatic void 9431591693c7b415e9869157c711fe11263c95d74eDavid Liupdate_array_sizes(struct gl_shader_program *prog) 9441591693c7b415e9869157c711fe11263c95d74eDavid Li{ 9451591693c7b415e9869157c711fe11263c95d74eDavid Li for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { 9461591693c7b415e9869157c711fe11263c95d74eDavid Li if (prog->_LinkedShaders[i] == NULL) 9471591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 9481591693c7b415e9869157c711fe11263c95d74eDavid Li 9491591693c7b415e9869157c711fe11263c95d74eDavid Li foreach_list(node, prog->_LinkedShaders[i]->ir) { 9501591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *const var = ((ir_instruction *) node)->as_variable(); 9511591693c7b415e9869157c711fe11263c95d74eDavid Li 9521591693c7b415e9869157c711fe11263c95d74eDavid Li if ((var == NULL) || (var->mode != ir_var_uniform && 9531591693c7b415e9869157c711fe11263c95d74eDavid Li var->mode != ir_var_in && 9541591693c7b415e9869157c711fe11263c95d74eDavid Li var->mode != ir_var_out) || 9551591693c7b415e9869157c711fe11263c95d74eDavid Li !var->type->is_array()) 9561591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 9571591693c7b415e9869157c711fe11263c95d74eDavid Li 9581591693c7b415e9869157c711fe11263c95d74eDavid Li unsigned int size = var->max_array_access; 9591591693c7b415e9869157c711fe11263c95d74eDavid Li for (unsigned j = 0; j < MESA_SHADER_TYPES; j++) { 9601591693c7b415e9869157c711fe11263c95d74eDavid Li if (prog->_LinkedShaders[j] == NULL) 9611591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 9621591693c7b415e9869157c711fe11263c95d74eDavid Li 9631591693c7b415e9869157c711fe11263c95d74eDavid Li foreach_list(node2, prog->_LinkedShaders[j]->ir) { 9641591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *other_var = ((ir_instruction *) node2)->as_variable(); 9651591693c7b415e9869157c711fe11263c95d74eDavid Li if (!other_var) 9661591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 9671591693c7b415e9869157c711fe11263c95d74eDavid Li 9681591693c7b415e9869157c711fe11263c95d74eDavid Li if (strcmp(var->name, other_var->name) == 0 && 9691591693c7b415e9869157c711fe11263c95d74eDavid Li other_var->max_array_access > size) { 9701591693c7b415e9869157c711fe11263c95d74eDavid Li size = other_var->max_array_access; 9711591693c7b415e9869157c711fe11263c95d74eDavid Li } 9721591693c7b415e9869157c711fe11263c95d74eDavid Li } 9731591693c7b415e9869157c711fe11263c95d74eDavid Li } 9741591693c7b415e9869157c711fe11263c95d74eDavid Li 9751591693c7b415e9869157c711fe11263c95d74eDavid Li if (size + 1 != var->type->fields.array->length) { 9761591693c7b415e9869157c711fe11263c95d74eDavid Li var->type = glsl_type::get_array_instance(var->type->fields.array, 9771591693c7b415e9869157c711fe11263c95d74eDavid Li size + 1); 9781591693c7b415e9869157c711fe11263c95d74eDavid Li /* FINISHME: We should update the types of array 9791591693c7b415e9869157c711fe11263c95d74eDavid Li * dereferences of this variable now. 9801591693c7b415e9869157c711fe11263c95d74eDavid Li */ 9811591693c7b415e9869157c711fe11263c95d74eDavid Li } 9821591693c7b415e9869157c711fe11263c95d74eDavid Li } 9831591693c7b415e9869157c711fe11263c95d74eDavid Li } 9841591693c7b415e9869157c711fe11263c95d74eDavid Li} 9851591693c7b415e9869157c711fe11263c95d74eDavid Li 9861591693c7b415e9869157c711fe11263c95d74eDavid Listatic void 9871591693c7b415e9869157c711fe11263c95d74eDavid Liadd_uniform(void *mem_ctx, exec_list *uniforms, struct hash_table *ht, 9881591693c7b415e9869157c711fe11263c95d74eDavid Li const char *name, const glsl_type *type, GLenum shader_type, 9891591693c7b415e9869157c711fe11263c95d74eDavid Li unsigned *next_shader_pos, unsigned *total_uniforms) 9901591693c7b415e9869157c711fe11263c95d74eDavid Li{ 9911591693c7b415e9869157c711fe11263c95d74eDavid Li if (type->is_record()) { 9921591693c7b415e9869157c711fe11263c95d74eDavid Li for (unsigned int i = 0; i < type->length; i++) { 9931591693c7b415e9869157c711fe11263c95d74eDavid Li const glsl_type *field_type = type->fields.structure[i].type; 994d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li char *field_name = hieralloc_asprintf(mem_ctx, "%s.%s", name, 9951591693c7b415e9869157c711fe11263c95d74eDavid Li type->fields.structure[i].name); 9961591693c7b415e9869157c711fe11263c95d74eDavid Li 9971591693c7b415e9869157c711fe11263c95d74eDavid Li add_uniform(mem_ctx, uniforms, ht, field_name, field_type, 9981591693c7b415e9869157c711fe11263c95d74eDavid Li shader_type, next_shader_pos, total_uniforms); 9991591693c7b415e9869157c711fe11263c95d74eDavid Li } 10001591693c7b415e9869157c711fe11263c95d74eDavid Li } else { 10011591693c7b415e9869157c711fe11263c95d74eDavid Li uniform_node *n = (uniform_node *) hash_table_find(ht, name); 10021591693c7b415e9869157c711fe11263c95d74eDavid Li unsigned int vec4_slots; 10031591693c7b415e9869157c711fe11263c95d74eDavid Li const glsl_type *array_elem_type = NULL; 10041591693c7b415e9869157c711fe11263c95d74eDavid Li 10051591693c7b415e9869157c711fe11263c95d74eDavid Li if (type->is_array()) { 10061591693c7b415e9869157c711fe11263c95d74eDavid Li array_elem_type = type->fields.array; 10071591693c7b415e9869157c711fe11263c95d74eDavid Li /* Array of structures. */ 10081591693c7b415e9869157c711fe11263c95d74eDavid Li if (array_elem_type->is_record()) { 10091591693c7b415e9869157c711fe11263c95d74eDavid Li for (unsigned int i = 0; i < type->length; i++) { 1010d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li char *elem_name = hieralloc_asprintf(mem_ctx, "%s[%d]", name, i); 10111591693c7b415e9869157c711fe11263c95d74eDavid Li add_uniform(mem_ctx, uniforms, ht, elem_name, array_elem_type, 10121591693c7b415e9869157c711fe11263c95d74eDavid Li shader_type, next_shader_pos, total_uniforms); 10131591693c7b415e9869157c711fe11263c95d74eDavid Li } 10141591693c7b415e9869157c711fe11263c95d74eDavid Li return; 10151591693c7b415e9869157c711fe11263c95d74eDavid Li } 10161591693c7b415e9869157c711fe11263c95d74eDavid Li } 10171591693c7b415e9869157c711fe11263c95d74eDavid Li 10181591693c7b415e9869157c711fe11263c95d74eDavid Li /* Fix the storage size of samplers at 1 vec4 each. Be sure to pad out 10191591693c7b415e9869157c711fe11263c95d74eDavid Li * vectors to vec4 slots. 10201591693c7b415e9869157c711fe11263c95d74eDavid Li */ 10211591693c7b415e9869157c711fe11263c95d74eDavid Li if (type->is_array()) { 10221591693c7b415e9869157c711fe11263c95d74eDavid Li if (array_elem_type->is_sampler()) 10231591693c7b415e9869157c711fe11263c95d74eDavid Li vec4_slots = type->length; 10241591693c7b415e9869157c711fe11263c95d74eDavid Li else 10251591693c7b415e9869157c711fe11263c95d74eDavid Li vec4_slots = type->length * array_elem_type->matrix_columns; 10261591693c7b415e9869157c711fe11263c95d74eDavid Li } else if (type->is_sampler()) { 10271591693c7b415e9869157c711fe11263c95d74eDavid Li vec4_slots = 1; 10281591693c7b415e9869157c711fe11263c95d74eDavid Li } else { 10291591693c7b415e9869157c711fe11263c95d74eDavid Li vec4_slots = type->matrix_columns; 10301591693c7b415e9869157c711fe11263c95d74eDavid Li } 10311591693c7b415e9869157c711fe11263c95d74eDavid Li 10321591693c7b415e9869157c711fe11263c95d74eDavid Li if (n == NULL) { 10331591693c7b415e9869157c711fe11263c95d74eDavid Li n = (uniform_node *) calloc(1, sizeof(struct uniform_node)); 10341591693c7b415e9869157c711fe11263c95d74eDavid Li n->u = (gl_uniform *) calloc(1, sizeof(struct gl_uniform)); 10351591693c7b415e9869157c711fe11263c95d74eDavid Li n->slots = vec4_slots; 10361591693c7b415e9869157c711fe11263c95d74eDavid Li 10371591693c7b415e9869157c711fe11263c95d74eDavid Li n->u->Name = strdup(name); 10381591693c7b415e9869157c711fe11263c95d74eDavid Li n->u->Type = type; 10391591693c7b415e9869157c711fe11263c95d74eDavid Li n->u->VertPos = -1; 10401591693c7b415e9869157c711fe11263c95d74eDavid Li n->u->FragPos = -1; 10411591693c7b415e9869157c711fe11263c95d74eDavid Li n->u->GeomPos = -1; 10421591693c7b415e9869157c711fe11263c95d74eDavid Li (*total_uniforms)++; 10431591693c7b415e9869157c711fe11263c95d74eDavid Li 10441591693c7b415e9869157c711fe11263c95d74eDavid Li hash_table_insert(ht, n, name); 10451591693c7b415e9869157c711fe11263c95d74eDavid Li uniforms->push_tail(& n->link); 10461591693c7b415e9869157c711fe11263c95d74eDavid Li } 10471591693c7b415e9869157c711fe11263c95d74eDavid Li 10481591693c7b415e9869157c711fe11263c95d74eDavid Li switch (shader_type) { 10491591693c7b415e9869157c711fe11263c95d74eDavid Li case GL_VERTEX_SHADER: 10501591693c7b415e9869157c711fe11263c95d74eDavid Li n->u->VertPos = *next_shader_pos; 10511591693c7b415e9869157c711fe11263c95d74eDavid Li break; 10521591693c7b415e9869157c711fe11263c95d74eDavid Li case GL_FRAGMENT_SHADER: 10531591693c7b415e9869157c711fe11263c95d74eDavid Li n->u->FragPos = *next_shader_pos; 10541591693c7b415e9869157c711fe11263c95d74eDavid Li break; 10551591693c7b415e9869157c711fe11263c95d74eDavid Li case GL_GEOMETRY_SHADER: 10561591693c7b415e9869157c711fe11263c95d74eDavid Li n->u->GeomPos = *next_shader_pos; 10571591693c7b415e9869157c711fe11263c95d74eDavid Li break; 10581591693c7b415e9869157c711fe11263c95d74eDavid Li } 10591591693c7b415e9869157c711fe11263c95d74eDavid Li 10601591693c7b415e9869157c711fe11263c95d74eDavid Li (*next_shader_pos) += vec4_slots; 10611591693c7b415e9869157c711fe11263c95d74eDavid Li } 10621591693c7b415e9869157c711fe11263c95d74eDavid Li} 10631591693c7b415e9869157c711fe11263c95d74eDavid Li 10641591693c7b415e9869157c711fe11263c95d74eDavid Livoid 10651591693c7b415e9869157c711fe11263c95d74eDavid Liassign_uniform_locations(struct gl_shader_program *prog) 10661591693c7b415e9869157c711fe11263c95d74eDavid Li{ 10671591693c7b415e9869157c711fe11263c95d74eDavid Li /* */ 10681591693c7b415e9869157c711fe11263c95d74eDavid Li exec_list uniforms; 10691591693c7b415e9869157c711fe11263c95d74eDavid Li unsigned total_uniforms = 0; 10701591693c7b415e9869157c711fe11263c95d74eDavid Li hash_table *ht = hash_table_ctor(32, hash_table_string_hash, 10711591693c7b415e9869157c711fe11263c95d74eDavid Li hash_table_string_compare); 1072d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li void *mem_ctx = hieralloc_new(NULL); 10731591693c7b415e9869157c711fe11263c95d74eDavid Li 10741591693c7b415e9869157c711fe11263c95d74eDavid Li for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { 10751591693c7b415e9869157c711fe11263c95d74eDavid Li if (prog->_LinkedShaders[i] == NULL) 10761591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 10771591693c7b415e9869157c711fe11263c95d74eDavid Li 10781591693c7b415e9869157c711fe11263c95d74eDavid Li unsigned next_position = 0; 10791591693c7b415e9869157c711fe11263c95d74eDavid Li 10801591693c7b415e9869157c711fe11263c95d74eDavid Li foreach_list(node, prog->_LinkedShaders[i]->ir) { 10811591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *const var = ((ir_instruction *) node)->as_variable(); 10821591693c7b415e9869157c711fe11263c95d74eDavid Li 10831591693c7b415e9869157c711fe11263c95d74eDavid Li if ((var == NULL) || (var->mode != ir_var_uniform)) 10841591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 10851591693c7b415e9869157c711fe11263c95d74eDavid Li 10861591693c7b415e9869157c711fe11263c95d74eDavid Li if (strncmp(var->name, "gl_", 3) == 0) { 10871591693c7b415e9869157c711fe11263c95d74eDavid Li /* At the moment, we don't allocate uniform locations for 10881591693c7b415e9869157c711fe11263c95d74eDavid Li * builtin uniforms. It's permitted by spec, and we'll 10891591693c7b415e9869157c711fe11263c95d74eDavid Li * likely switch to doing that at some point, but not yet. 10901591693c7b415e9869157c711fe11263c95d74eDavid Li */ 10911591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 10921591693c7b415e9869157c711fe11263c95d74eDavid Li } 10931591693c7b415e9869157c711fe11263c95d74eDavid Li 10941591693c7b415e9869157c711fe11263c95d74eDavid Li var->location = next_position; 10951591693c7b415e9869157c711fe11263c95d74eDavid Li add_uniform(mem_ctx, &uniforms, ht, var->name, var->type, 10961591693c7b415e9869157c711fe11263c95d74eDavid Li prog->_LinkedShaders[i]->Type, 10971591693c7b415e9869157c711fe11263c95d74eDavid Li &next_position, &total_uniforms); 10981591693c7b415e9869157c711fe11263c95d74eDavid Li } 10991591693c7b415e9869157c711fe11263c95d74eDavid Li } 11001591693c7b415e9869157c711fe11263c95d74eDavid Li 1101d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li hieralloc_free(mem_ctx); 11021591693c7b415e9869157c711fe11263c95d74eDavid Li 11031591693c7b415e9869157c711fe11263c95d74eDavid Li gl_uniform_list *ul = (gl_uniform_list *) 11041591693c7b415e9869157c711fe11263c95d74eDavid Li calloc(1, sizeof(gl_uniform_list)); 11051591693c7b415e9869157c711fe11263c95d74eDavid Li 11061591693c7b415e9869157c711fe11263c95d74eDavid Li ul->Size = total_uniforms; 11071591693c7b415e9869157c711fe11263c95d74eDavid Li ul->NumUniforms = total_uniforms; 11081591693c7b415e9869157c711fe11263c95d74eDavid Li ul->Uniforms = (gl_uniform *) calloc(total_uniforms, sizeof(gl_uniform)); 11091591693c7b415e9869157c711fe11263c95d74eDavid Li 11101591693c7b415e9869157c711fe11263c95d74eDavid Li unsigned idx = 0; 11111591693c7b415e9869157c711fe11263c95d74eDavid Li uniform_node *next; 11121591693c7b415e9869157c711fe11263c95d74eDavid Li for (uniform_node *node = (uniform_node *) uniforms.head 11131591693c7b415e9869157c711fe11263c95d74eDavid Li ; node->link.next != NULL 11141591693c7b415e9869157c711fe11263c95d74eDavid Li ; node = next) { 11151591693c7b415e9869157c711fe11263c95d74eDavid Li next = (uniform_node *) node->link.next; 11161591693c7b415e9869157c711fe11263c95d74eDavid Li 11171591693c7b415e9869157c711fe11263c95d74eDavid Li node->link.remove(); 11181591693c7b415e9869157c711fe11263c95d74eDavid Li memcpy(&ul->Uniforms[idx], node->u, sizeof(gl_uniform)); 11191591693c7b415e9869157c711fe11263c95d74eDavid Li idx++; 11201591693c7b415e9869157c711fe11263c95d74eDavid Li 11211591693c7b415e9869157c711fe11263c95d74eDavid Li free(node->u); 11221591693c7b415e9869157c711fe11263c95d74eDavid Li free(node); 11231591693c7b415e9869157c711fe11263c95d74eDavid Li } 11241591693c7b415e9869157c711fe11263c95d74eDavid Li 11251591693c7b415e9869157c711fe11263c95d74eDavid Li hash_table_dtor(ht); 11261591693c7b415e9869157c711fe11263c95d74eDavid Li 11271591693c7b415e9869157c711fe11263c95d74eDavid Li prog->Uniforms = ul; 11281591693c7b415e9869157c711fe11263c95d74eDavid Li} 11291591693c7b415e9869157c711fe11263c95d74eDavid Li 11301591693c7b415e9869157c711fe11263c95d74eDavid Li 11311591693c7b415e9869157c711fe11263c95d74eDavid Li/** 11321591693c7b415e9869157c711fe11263c95d74eDavid Li * Find a contiguous set of available bits in a bitmask 11331591693c7b415e9869157c711fe11263c95d74eDavid Li * 11341591693c7b415e9869157c711fe11263c95d74eDavid Li * \param used_mask Bits representing used (1) and unused (0) locations 11351591693c7b415e9869157c711fe11263c95d74eDavid Li * \param needed_count Number of contiguous bits needed. 11361591693c7b415e9869157c711fe11263c95d74eDavid Li * 11371591693c7b415e9869157c711fe11263c95d74eDavid Li * \return 11381591693c7b415e9869157c711fe11263c95d74eDavid Li * Base location of the available bits on success or -1 on failure. 11391591693c7b415e9869157c711fe11263c95d74eDavid Li */ 11401591693c7b415e9869157c711fe11263c95d74eDavid Liint 11411591693c7b415e9869157c711fe11263c95d74eDavid Lifind_available_slots(unsigned used_mask, unsigned needed_count) 11421591693c7b415e9869157c711fe11263c95d74eDavid Li{ 11431591693c7b415e9869157c711fe11263c95d74eDavid Li unsigned needed_mask = (1 << needed_count) - 1; 11441591693c7b415e9869157c711fe11263c95d74eDavid Li const int max_bit_to_test = (8 * sizeof(used_mask)) - needed_count; 11451591693c7b415e9869157c711fe11263c95d74eDavid Li 11461591693c7b415e9869157c711fe11263c95d74eDavid Li /* The comparison to 32 is redundant, but without it GCC emits "warning: 11471591693c7b415e9869157c711fe11263c95d74eDavid Li * cannot optimize possibly infinite loops" for the loop below. 11481591693c7b415e9869157c711fe11263c95d74eDavid Li */ 11491591693c7b415e9869157c711fe11263c95d74eDavid Li if ((needed_count == 0) || (max_bit_to_test < 0) || (max_bit_to_test > 32)) 11501591693c7b415e9869157c711fe11263c95d74eDavid Li return -1; 11511591693c7b415e9869157c711fe11263c95d74eDavid Li 11521591693c7b415e9869157c711fe11263c95d74eDavid Li for (int i = 0; i <= max_bit_to_test; i++) { 11531591693c7b415e9869157c711fe11263c95d74eDavid Li if ((needed_mask & ~used_mask) == needed_mask) 11541591693c7b415e9869157c711fe11263c95d74eDavid Li return i; 11551591693c7b415e9869157c711fe11263c95d74eDavid Li 11561591693c7b415e9869157c711fe11263c95d74eDavid Li needed_mask <<= 1; 11571591693c7b415e9869157c711fe11263c95d74eDavid Li } 11581591693c7b415e9869157c711fe11263c95d74eDavid Li 11591591693c7b415e9869157c711fe11263c95d74eDavid Li return -1; 11601591693c7b415e9869157c711fe11263c95d74eDavid Li} 11611591693c7b415e9869157c711fe11263c95d74eDavid Li 11621591693c7b415e9869157c711fe11263c95d74eDavid Li 11631591693c7b415e9869157c711fe11263c95d74eDavid Libool 11641591693c7b415e9869157c711fe11263c95d74eDavid Liassign_attribute_locations(gl_shader_program *prog, unsigned max_attribute_index) 11651591693c7b415e9869157c711fe11263c95d74eDavid Li{ 11661591693c7b415e9869157c711fe11263c95d74eDavid Li /* Mark invalid attribute locations as being used. 11671591693c7b415e9869157c711fe11263c95d74eDavid Li */ 11681591693c7b415e9869157c711fe11263c95d74eDavid Li unsigned used_locations = (max_attribute_index >= 32) 11691591693c7b415e9869157c711fe11263c95d74eDavid Li ? ~0 : ~((1 << max_attribute_index) - 1); 11701591693c7b415e9869157c711fe11263c95d74eDavid Li 11711591693c7b415e9869157c711fe11263c95d74eDavid Li gl_shader *const sh = prog->_LinkedShaders[0]; 11721591693c7b415e9869157c711fe11263c95d74eDavid Li assert(sh->Type == GL_VERTEX_SHADER); 11731591693c7b415e9869157c711fe11263c95d74eDavid Li 11741591693c7b415e9869157c711fe11263c95d74eDavid Li /* Operate in a total of four passes. 11751591693c7b415e9869157c711fe11263c95d74eDavid Li * 11761591693c7b415e9869157c711fe11263c95d74eDavid Li * 1. Invalidate the location assignments for all vertex shader inputs. 11771591693c7b415e9869157c711fe11263c95d74eDavid Li * 11781591693c7b415e9869157c711fe11263c95d74eDavid Li * 2. Assign locations for inputs that have user-defined (via 11791591693c7b415e9869157c711fe11263c95d74eDavid Li * glBindVertexAttribLocation) locatoins. 11801591693c7b415e9869157c711fe11263c95d74eDavid Li * 11811591693c7b415e9869157c711fe11263c95d74eDavid Li * 3. Sort the attributes without assigned locations by number of slots 11821591693c7b415e9869157c711fe11263c95d74eDavid Li * required in decreasing order. Fragmentation caused by attribute 11831591693c7b415e9869157c711fe11263c95d74eDavid Li * locations assigned by the application may prevent large attributes 11841591693c7b415e9869157c711fe11263c95d74eDavid Li * from having enough contiguous space. 11851591693c7b415e9869157c711fe11263c95d74eDavid Li * 11861591693c7b415e9869157c711fe11263c95d74eDavid Li * 4. Assign locations to any inputs without assigned locations. 11871591693c7b415e9869157c711fe11263c95d74eDavid Li */ 11881591693c7b415e9869157c711fe11263c95d74eDavid Li 11891591693c7b415e9869157c711fe11263c95d74eDavid Li invalidate_variable_locations(sh, ir_var_in, VERT_ATTRIB_GENERIC0); 11901591693c7b415e9869157c711fe11263c95d74eDavid Li 11911591693c7b415e9869157c711fe11263c95d74eDavid Li if (prog->Attributes != NULL) { 11921591693c7b415e9869157c711fe11263c95d74eDavid Li for (unsigned i = 0; i < prog->Attributes->NumParameters; i++) { 11931591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *const var = 11941591693c7b415e9869157c711fe11263c95d74eDavid Li sh->symbols->get_variable(prog->Attributes->Parameters[i].Name); 11951591693c7b415e9869157c711fe11263c95d74eDavid Li 11961591693c7b415e9869157c711fe11263c95d74eDavid Li /* Note: attributes that occupy multiple slots, such as arrays or 11971591693c7b415e9869157c711fe11263c95d74eDavid Li * matrices, may appear in the attrib array multiple times. 11981591693c7b415e9869157c711fe11263c95d74eDavid Li */ 11991591693c7b415e9869157c711fe11263c95d74eDavid Li if ((var == NULL) || (var->location != -1)) 12001591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 12011591693c7b415e9869157c711fe11263c95d74eDavid Li 12021591693c7b415e9869157c711fe11263c95d74eDavid Li /* From page 61 of the OpenGL 4.0 spec: 12031591693c7b415e9869157c711fe11263c95d74eDavid Li * 12041591693c7b415e9869157c711fe11263c95d74eDavid Li * "LinkProgram will fail if the attribute bindings assigned by 12051591693c7b415e9869157c711fe11263c95d74eDavid Li * BindAttribLocation do not leave not enough space to assign a 12061591693c7b415e9869157c711fe11263c95d74eDavid Li * location for an active matrix attribute or an active attribute 12071591693c7b415e9869157c711fe11263c95d74eDavid Li * array, both of which require multiple contiguous generic 12081591693c7b415e9869157c711fe11263c95d74eDavid Li * attributes." 12091591693c7b415e9869157c711fe11263c95d74eDavid Li * 12101591693c7b415e9869157c711fe11263c95d74eDavid Li * Previous versions of the spec contain similar language but omit the 12111591693c7b415e9869157c711fe11263c95d74eDavid Li * bit about attribute arrays. 12121591693c7b415e9869157c711fe11263c95d74eDavid Li * 12131591693c7b415e9869157c711fe11263c95d74eDavid Li * Page 61 of the OpenGL 4.0 spec also says: 12141591693c7b415e9869157c711fe11263c95d74eDavid Li * 12151591693c7b415e9869157c711fe11263c95d74eDavid Li * "It is possible for an application to bind more than one 12161591693c7b415e9869157c711fe11263c95d74eDavid Li * attribute name to the same location. This is referred to as 12171591693c7b415e9869157c711fe11263c95d74eDavid Li * aliasing. This will only work if only one of the aliased 12181591693c7b415e9869157c711fe11263c95d74eDavid Li * attributes is active in the executable program, or if no path 12191591693c7b415e9869157c711fe11263c95d74eDavid Li * through the shader consumes more than one attribute of a set 12201591693c7b415e9869157c711fe11263c95d74eDavid Li * of attributes aliased to the same location. A link error can 12211591693c7b415e9869157c711fe11263c95d74eDavid Li * occur if the linker determines that every path through the 12221591693c7b415e9869157c711fe11263c95d74eDavid Li * shader consumes multiple aliased attributes, but 12231591693c7b415e9869157c711fe11263c95d74eDavid Li * implementations are not required to generate an error in this 12241591693c7b415e9869157c711fe11263c95d74eDavid Li * case." 12251591693c7b415e9869157c711fe11263c95d74eDavid Li * 12261591693c7b415e9869157c711fe11263c95d74eDavid Li * These two paragraphs are either somewhat contradictory, or I don't 12271591693c7b415e9869157c711fe11263c95d74eDavid Li * fully understand one or both of them. 12281591693c7b415e9869157c711fe11263c95d74eDavid Li */ 12291591693c7b415e9869157c711fe11263c95d74eDavid Li /* FINISHME: The code as currently written does not support attribute 12301591693c7b415e9869157c711fe11263c95d74eDavid Li * FINISHME: location aliasing (see comment above). 12311591693c7b415e9869157c711fe11263c95d74eDavid Li */ 12321591693c7b415e9869157c711fe11263c95d74eDavid Li const int attr = prog->Attributes->Parameters[i].StateIndexes[0]; 12331591693c7b415e9869157c711fe11263c95d74eDavid Li const unsigned slots = count_attribute_slots(var->type); 12341591693c7b415e9869157c711fe11263c95d74eDavid Li 12351591693c7b415e9869157c711fe11263c95d74eDavid Li /* Mask representing the contiguous slots that will be used by this 12361591693c7b415e9869157c711fe11263c95d74eDavid Li * attribute. 12371591693c7b415e9869157c711fe11263c95d74eDavid Li */ 12381591693c7b415e9869157c711fe11263c95d74eDavid Li const unsigned use_mask = (1 << slots) - 1; 12391591693c7b415e9869157c711fe11263c95d74eDavid Li 12401591693c7b415e9869157c711fe11263c95d74eDavid Li /* Generate a link error if the set of bits requested for this 12411591693c7b415e9869157c711fe11263c95d74eDavid Li * attribute overlaps any previously allocated bits. 12421591693c7b415e9869157c711fe11263c95d74eDavid Li */ 12431591693c7b415e9869157c711fe11263c95d74eDavid Li if ((~(use_mask << attr) & used_locations) != used_locations) { 12441591693c7b415e9869157c711fe11263c95d74eDavid Li linker_error_printf(prog, 12451591693c7b415e9869157c711fe11263c95d74eDavid Li "insufficient contiguous attribute locations " 12461591693c7b415e9869157c711fe11263c95d74eDavid Li "available for vertex shader input `%s'", 12471591693c7b415e9869157c711fe11263c95d74eDavid Li var->name); 12481591693c7b415e9869157c711fe11263c95d74eDavid Li return false; 12491591693c7b415e9869157c711fe11263c95d74eDavid Li } 12501591693c7b415e9869157c711fe11263c95d74eDavid Li 12511591693c7b415e9869157c711fe11263c95d74eDavid Li var->location = VERT_ATTRIB_GENERIC0 + attr; 12521591693c7b415e9869157c711fe11263c95d74eDavid Li used_locations |= (use_mask << attr); 12531591693c7b415e9869157c711fe11263c95d74eDavid Li } 12541591693c7b415e9869157c711fe11263c95d74eDavid Li } 12551591693c7b415e9869157c711fe11263c95d74eDavid Li 12561591693c7b415e9869157c711fe11263c95d74eDavid Li /* Temporary storage for the set of attributes that need locations assigned. 12571591693c7b415e9869157c711fe11263c95d74eDavid Li */ 12581591693c7b415e9869157c711fe11263c95d74eDavid Li struct temp_attr { 12591591693c7b415e9869157c711fe11263c95d74eDavid Li unsigned slots; 12601591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *var; 12611591693c7b415e9869157c711fe11263c95d74eDavid Li 12621591693c7b415e9869157c711fe11263c95d74eDavid Li /* Used below in the call to qsort. */ 12631591693c7b415e9869157c711fe11263c95d74eDavid Li static int compare(const void *a, const void *b) 12641591693c7b415e9869157c711fe11263c95d74eDavid Li { 12651591693c7b415e9869157c711fe11263c95d74eDavid Li const temp_attr *const l = (const temp_attr *) a; 12661591693c7b415e9869157c711fe11263c95d74eDavid Li const temp_attr *const r = (const temp_attr *) b; 12671591693c7b415e9869157c711fe11263c95d74eDavid Li 12681591693c7b415e9869157c711fe11263c95d74eDavid Li /* Reversed because we want a descending order sort below. */ 12691591693c7b415e9869157c711fe11263c95d74eDavid Li return r->slots - l->slots; 12701591693c7b415e9869157c711fe11263c95d74eDavid Li } 12711591693c7b415e9869157c711fe11263c95d74eDavid Li } to_assign[16]; 12721591693c7b415e9869157c711fe11263c95d74eDavid Li 12731591693c7b415e9869157c711fe11263c95d74eDavid Li unsigned num_attr = 0; 12741591693c7b415e9869157c711fe11263c95d74eDavid Li 12751591693c7b415e9869157c711fe11263c95d74eDavid Li foreach_list(node, sh->ir) { 12761591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *const var = ((ir_instruction *) node)->as_variable(); 12771591693c7b415e9869157c711fe11263c95d74eDavid Li 12781591693c7b415e9869157c711fe11263c95d74eDavid Li if ((var == NULL) || (var->mode != ir_var_in)) 12791591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 12801591693c7b415e9869157c711fe11263c95d74eDavid Li 12811591693c7b415e9869157c711fe11263c95d74eDavid Li if (var->explicit_location) { 12821591693c7b415e9869157c711fe11263c95d74eDavid Li const unsigned slots = count_attribute_slots(var->type); 12831591693c7b415e9869157c711fe11263c95d74eDavid Li const unsigned use_mask = (1 << slots) - 1; 12841591693c7b415e9869157c711fe11263c95d74eDavid Li const int attr = var->location - VERT_ATTRIB_GENERIC0; 12851591693c7b415e9869157c711fe11263c95d74eDavid Li 12861591693c7b415e9869157c711fe11263c95d74eDavid Li if ((var->location >= (int)(max_attribute_index + VERT_ATTRIB_GENERIC0)) 12871591693c7b415e9869157c711fe11263c95d74eDavid Li || (var->location < 0)) { 12881591693c7b415e9869157c711fe11263c95d74eDavid Li linker_error_printf(prog, 12891591693c7b415e9869157c711fe11263c95d74eDavid Li "invalid explicit location %d specified for " 12901591693c7b415e9869157c711fe11263c95d74eDavid Li "`%s'\n", 12911591693c7b415e9869157c711fe11263c95d74eDavid Li (var->location < 0) ? var->location : attr, 12921591693c7b415e9869157c711fe11263c95d74eDavid Li var->name); 12931591693c7b415e9869157c711fe11263c95d74eDavid Li return false; 12941591693c7b415e9869157c711fe11263c95d74eDavid Li } else if (var->location >= VERT_ATTRIB_GENERIC0) { 12951591693c7b415e9869157c711fe11263c95d74eDavid Li used_locations |= (use_mask << attr); 12961591693c7b415e9869157c711fe11263c95d74eDavid Li } 12971591693c7b415e9869157c711fe11263c95d74eDavid Li } 12981591693c7b415e9869157c711fe11263c95d74eDavid Li 12991591693c7b415e9869157c711fe11263c95d74eDavid Li /* The location was explicitly assigned, nothing to do here. 13001591693c7b415e9869157c711fe11263c95d74eDavid Li */ 13011591693c7b415e9869157c711fe11263c95d74eDavid Li if (var->location != -1) 13021591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 13031591693c7b415e9869157c711fe11263c95d74eDavid Li 13041591693c7b415e9869157c711fe11263c95d74eDavid Li to_assign[num_attr].slots = count_attribute_slots(var->type); 13051591693c7b415e9869157c711fe11263c95d74eDavid Li to_assign[num_attr].var = var; 13061591693c7b415e9869157c711fe11263c95d74eDavid Li num_attr++; 13071591693c7b415e9869157c711fe11263c95d74eDavid Li } 13081591693c7b415e9869157c711fe11263c95d74eDavid Li 13091591693c7b415e9869157c711fe11263c95d74eDavid Li /* If all of the attributes were assigned locations by the application (or 13101591693c7b415e9869157c711fe11263c95d74eDavid Li * are built-in attributes with fixed locations), return early. This should 13111591693c7b415e9869157c711fe11263c95d74eDavid Li * be the common case. 13121591693c7b415e9869157c711fe11263c95d74eDavid Li */ 13131591693c7b415e9869157c711fe11263c95d74eDavid Li if (num_attr == 0) 13141591693c7b415e9869157c711fe11263c95d74eDavid Li return true; 13151591693c7b415e9869157c711fe11263c95d74eDavid Li 13161591693c7b415e9869157c711fe11263c95d74eDavid Li qsort(to_assign, num_attr, sizeof(to_assign[0]), temp_attr::compare); 13171591693c7b415e9869157c711fe11263c95d74eDavid Li 13181591693c7b415e9869157c711fe11263c95d74eDavid Li /* VERT_ATTRIB_GENERIC0 is a psdueo-alias for VERT_ATTRIB_POS. It can only 13191591693c7b415e9869157c711fe11263c95d74eDavid Li * be explicitly assigned by via glBindAttribLocation. Mark it as reserved 13201591693c7b415e9869157c711fe11263c95d74eDavid Li * to prevent it from being automatically allocated below. 13211591693c7b415e9869157c711fe11263c95d74eDavid Li */ 13221591693c7b415e9869157c711fe11263c95d74eDavid Li find_deref_visitor find("gl_Vertex"); 13231591693c7b415e9869157c711fe11263c95d74eDavid Li find.run(sh->ir); 13241591693c7b415e9869157c711fe11263c95d74eDavid Li if (find.variable_found()) 13251591693c7b415e9869157c711fe11263c95d74eDavid Li used_locations |= (1 << 0); 13261591693c7b415e9869157c711fe11263c95d74eDavid Li 13271591693c7b415e9869157c711fe11263c95d74eDavid Li for (unsigned i = 0; i < num_attr; i++) { 13281591693c7b415e9869157c711fe11263c95d74eDavid Li /* Mask representing the contiguous slots that will be used by this 13291591693c7b415e9869157c711fe11263c95d74eDavid Li * attribute. 13301591693c7b415e9869157c711fe11263c95d74eDavid Li */ 13311591693c7b415e9869157c711fe11263c95d74eDavid Li const unsigned use_mask = (1 << to_assign[i].slots) - 1; 13321591693c7b415e9869157c711fe11263c95d74eDavid Li 13331591693c7b415e9869157c711fe11263c95d74eDavid Li int location = find_available_slots(used_locations, to_assign[i].slots); 13341591693c7b415e9869157c711fe11263c95d74eDavid Li 13351591693c7b415e9869157c711fe11263c95d74eDavid Li if (location < 0) { 13361591693c7b415e9869157c711fe11263c95d74eDavid Li linker_error_printf(prog, 13371591693c7b415e9869157c711fe11263c95d74eDavid Li "insufficient contiguous attribute locations " 13381591693c7b415e9869157c711fe11263c95d74eDavid Li "available for vertex shader input `%s'", 13391591693c7b415e9869157c711fe11263c95d74eDavid Li to_assign[i].var->name); 13401591693c7b415e9869157c711fe11263c95d74eDavid Li return false; 13411591693c7b415e9869157c711fe11263c95d74eDavid Li } 13421591693c7b415e9869157c711fe11263c95d74eDavid Li 13431591693c7b415e9869157c711fe11263c95d74eDavid Li to_assign[i].var->location = VERT_ATTRIB_GENERIC0 + location; 13441591693c7b415e9869157c711fe11263c95d74eDavid Li used_locations |= (use_mask << location); 13451591693c7b415e9869157c711fe11263c95d74eDavid Li } 13461591693c7b415e9869157c711fe11263c95d74eDavid Li 13471591693c7b415e9869157c711fe11263c95d74eDavid Li return true; 13481591693c7b415e9869157c711fe11263c95d74eDavid Li} 13491591693c7b415e9869157c711fe11263c95d74eDavid Li 13501591693c7b415e9869157c711fe11263c95d74eDavid Li 13511591693c7b415e9869157c711fe11263c95d74eDavid Li/** 13521591693c7b415e9869157c711fe11263c95d74eDavid Li * Demote shader inputs and outputs that are not used in other stages 13531591693c7b415e9869157c711fe11263c95d74eDavid Li */ 13541591693c7b415e9869157c711fe11263c95d74eDavid Livoid 13551591693c7b415e9869157c711fe11263c95d74eDavid Lidemote_shader_inputs_and_outputs(gl_shader *sh, enum ir_variable_mode mode) 13561591693c7b415e9869157c711fe11263c95d74eDavid Li{ 13571591693c7b415e9869157c711fe11263c95d74eDavid Li foreach_list(node, sh->ir) { 13581591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *const var = ((ir_instruction *) node)->as_variable(); 13591591693c7b415e9869157c711fe11263c95d74eDavid Li 13601591693c7b415e9869157c711fe11263c95d74eDavid Li if ((var == NULL) || (var->mode != int(mode))) 13611591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 13621591693c7b415e9869157c711fe11263c95d74eDavid Li 13631591693c7b415e9869157c711fe11263c95d74eDavid Li /* A shader 'in' or 'out' variable is only really an input or output if 13641591693c7b415e9869157c711fe11263c95d74eDavid Li * its value is used by other shader stages. This will cause the variable 13651591693c7b415e9869157c711fe11263c95d74eDavid Li * to have a location assigned. 13661591693c7b415e9869157c711fe11263c95d74eDavid Li */ 13671591693c7b415e9869157c711fe11263c95d74eDavid Li if (var->location == -1) { 13681591693c7b415e9869157c711fe11263c95d74eDavid Li var->mode = ir_var_auto; 13691591693c7b415e9869157c711fe11263c95d74eDavid Li } 13701591693c7b415e9869157c711fe11263c95d74eDavid Li } 13711591693c7b415e9869157c711fe11263c95d74eDavid Li} 13721591693c7b415e9869157c711fe11263c95d74eDavid Li 13731591693c7b415e9869157c711fe11263c95d74eDavid Li 13741591693c7b415e9869157c711fe11263c95d74eDavid Livoid 13751591693c7b415e9869157c711fe11263c95d74eDavid Liassign_varying_locations(struct gl_shader_program *prog, 13761591693c7b415e9869157c711fe11263c95d74eDavid Li gl_shader *producer, gl_shader *consumer) 13771591693c7b415e9869157c711fe11263c95d74eDavid Li{ 13781591693c7b415e9869157c711fe11263c95d74eDavid Li /* FINISHME: Set dynamically when geometry shader support is added. */ 13791591693c7b415e9869157c711fe11263c95d74eDavid Li unsigned output_index = VERT_RESULT_VAR0; 13801591693c7b415e9869157c711fe11263c95d74eDavid Li unsigned input_index = FRAG_ATTRIB_VAR0; 13811591693c7b415e9869157c711fe11263c95d74eDavid Li 13821591693c7b415e9869157c711fe11263c95d74eDavid Li /* Operate in a total of three passes. 13831591693c7b415e9869157c711fe11263c95d74eDavid Li * 13841591693c7b415e9869157c711fe11263c95d74eDavid Li * 1. Assign locations for any matching inputs and outputs. 13851591693c7b415e9869157c711fe11263c95d74eDavid Li * 13861591693c7b415e9869157c711fe11263c95d74eDavid Li * 2. Mark output variables in the producer that do not have locations as 13871591693c7b415e9869157c711fe11263c95d74eDavid Li * not being outputs. This lets the optimizer eliminate them. 13881591693c7b415e9869157c711fe11263c95d74eDavid Li * 13891591693c7b415e9869157c711fe11263c95d74eDavid Li * 3. Mark input variables in the consumer that do not have locations as 13901591693c7b415e9869157c711fe11263c95d74eDavid Li * not being inputs. This lets the optimizer eliminate them. 13911591693c7b415e9869157c711fe11263c95d74eDavid Li */ 13921591693c7b415e9869157c711fe11263c95d74eDavid Li 13931591693c7b415e9869157c711fe11263c95d74eDavid Li invalidate_variable_locations(producer, ir_var_out, VERT_RESULT_VAR0); 13941591693c7b415e9869157c711fe11263c95d74eDavid Li invalidate_variable_locations(consumer, ir_var_in, FRAG_ATTRIB_VAR0); 13951591693c7b415e9869157c711fe11263c95d74eDavid Li 13961591693c7b415e9869157c711fe11263c95d74eDavid Li foreach_list(node, producer->ir) { 13971591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *const output_var = ((ir_instruction *) node)->as_variable(); 13981591693c7b415e9869157c711fe11263c95d74eDavid Li 13991591693c7b415e9869157c711fe11263c95d74eDavid Li if ((output_var == NULL) || (output_var->mode != ir_var_out) 14001591693c7b415e9869157c711fe11263c95d74eDavid Li || (output_var->location != -1)) 14011591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 14021591693c7b415e9869157c711fe11263c95d74eDavid Li 14031591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *const input_var = 14041591693c7b415e9869157c711fe11263c95d74eDavid Li consumer->symbols->get_variable(output_var->name); 14051591693c7b415e9869157c711fe11263c95d74eDavid Li 14061591693c7b415e9869157c711fe11263c95d74eDavid Li if ((input_var == NULL) || (input_var->mode != ir_var_in)) 14071591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 14081591693c7b415e9869157c711fe11263c95d74eDavid Li 14091591693c7b415e9869157c711fe11263c95d74eDavid Li assert(input_var->location == -1); 14101591693c7b415e9869157c711fe11263c95d74eDavid Li 14111591693c7b415e9869157c711fe11263c95d74eDavid Li output_var->location = output_index; 14121591693c7b415e9869157c711fe11263c95d74eDavid Li input_var->location = input_index; 14131591693c7b415e9869157c711fe11263c95d74eDavid Li 14141591693c7b415e9869157c711fe11263c95d74eDavid Li /* FINISHME: Support for "varying" records in GLSL 1.50. */ 14151591693c7b415e9869157c711fe11263c95d74eDavid Li assert(!output_var->type->is_record()); 14161591693c7b415e9869157c711fe11263c95d74eDavid Li 14171591693c7b415e9869157c711fe11263c95d74eDavid Li if (output_var->type->is_array()) { 14181591693c7b415e9869157c711fe11263c95d74eDavid Li const unsigned slots = output_var->type->length 14191591693c7b415e9869157c711fe11263c95d74eDavid Li * output_var->type->fields.array->matrix_columns; 14201591693c7b415e9869157c711fe11263c95d74eDavid Li 14211591693c7b415e9869157c711fe11263c95d74eDavid Li output_index += slots; 14221591693c7b415e9869157c711fe11263c95d74eDavid Li input_index += slots; 14231591693c7b415e9869157c711fe11263c95d74eDavid Li } else { 14241591693c7b415e9869157c711fe11263c95d74eDavid Li const unsigned slots = output_var->type->matrix_columns; 14251591693c7b415e9869157c711fe11263c95d74eDavid Li 14261591693c7b415e9869157c711fe11263c95d74eDavid Li output_index += slots; 14271591693c7b415e9869157c711fe11263c95d74eDavid Li input_index += slots; 14281591693c7b415e9869157c711fe11263c95d74eDavid Li } 14291591693c7b415e9869157c711fe11263c95d74eDavid Li } 14301591693c7b415e9869157c711fe11263c95d74eDavid Li 14311591693c7b415e9869157c711fe11263c95d74eDavid Li foreach_list(node, consumer->ir) { 14321591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *const var = ((ir_instruction *) node)->as_variable(); 14331591693c7b415e9869157c711fe11263c95d74eDavid Li 14341591693c7b415e9869157c711fe11263c95d74eDavid Li if ((var == NULL) || (var->mode != ir_var_in)) 14351591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 14361591693c7b415e9869157c711fe11263c95d74eDavid Li 14371591693c7b415e9869157c711fe11263c95d74eDavid Li if (var->location == -1) { 14381591693c7b415e9869157c711fe11263c95d74eDavid Li if (prog->Version <= 120) { 14391591693c7b415e9869157c711fe11263c95d74eDavid Li /* On page 25 (page 31 of the PDF) of the GLSL 1.20 spec: 14401591693c7b415e9869157c711fe11263c95d74eDavid Li * 14411591693c7b415e9869157c711fe11263c95d74eDavid Li * Only those varying variables used (i.e. read) in 14421591693c7b415e9869157c711fe11263c95d74eDavid Li * the fragment shader executable must be written to 14431591693c7b415e9869157c711fe11263c95d74eDavid Li * by the vertex shader executable; declaring 14441591693c7b415e9869157c711fe11263c95d74eDavid Li * superfluous varying variables in a vertex shader is 14451591693c7b415e9869157c711fe11263c95d74eDavid Li * permissible. 14461591693c7b415e9869157c711fe11263c95d74eDavid Li * 14471591693c7b415e9869157c711fe11263c95d74eDavid Li * We interpret this text as meaning that the VS must 14481591693c7b415e9869157c711fe11263c95d74eDavid Li * write the variable for the FS to read it. See 14491591693c7b415e9869157c711fe11263c95d74eDavid Li * "glsl1-varying read but not written" in piglit. 14501591693c7b415e9869157c711fe11263c95d74eDavid Li */ 14511591693c7b415e9869157c711fe11263c95d74eDavid Li 14521591693c7b415e9869157c711fe11263c95d74eDavid Li linker_error_printf(prog, "fragment shader varying %s not written " 14531591693c7b415e9869157c711fe11263c95d74eDavid Li "by vertex shader\n.", var->name); 14541591693c7b415e9869157c711fe11263c95d74eDavid Li prog->LinkStatus = false; 14551591693c7b415e9869157c711fe11263c95d74eDavid Li } 14561591693c7b415e9869157c711fe11263c95d74eDavid Li 14571591693c7b415e9869157c711fe11263c95d74eDavid Li /* An 'in' variable is only really a shader input if its 14581591693c7b415e9869157c711fe11263c95d74eDavid Li * value is written by the previous stage. 14591591693c7b415e9869157c711fe11263c95d74eDavid Li */ 14601591693c7b415e9869157c711fe11263c95d74eDavid Li var->mode = ir_var_auto; 14611591693c7b415e9869157c711fe11263c95d74eDavid Li } 14621591693c7b415e9869157c711fe11263c95d74eDavid Li } 14631591693c7b415e9869157c711fe11263c95d74eDavid Li} 14641591693c7b415e9869157c711fe11263c95d74eDavid Li 14651591693c7b415e9869157c711fe11263c95d74eDavid Li 14661591693c7b415e9869157c711fe11263c95d74eDavid Livoid 14671591693c7b415e9869157c711fe11263c95d74eDavid Lilink_shaders(struct gl_context *ctx, struct gl_shader_program *prog) 14681591693c7b415e9869157c711fe11263c95d74eDavid Li{ 146913fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li //void *mem_ctx = hieralloc_init("temporary linker context"); 147013fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li void * mem_ctx = prog; // need linked & cloned ir to persist 14711591693c7b415e9869157c711fe11263c95d74eDavid Li 14721591693c7b415e9869157c711fe11263c95d74eDavid Li prog->LinkStatus = false; 14731591693c7b415e9869157c711fe11263c95d74eDavid Li prog->Validated = false; 14741591693c7b415e9869157c711fe11263c95d74eDavid Li prog->_Used = false; 14751591693c7b415e9869157c711fe11263c95d74eDavid Li 14761591693c7b415e9869157c711fe11263c95d74eDavid Li if (prog->InfoLog != NULL) 1477d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li hieralloc_free(prog->InfoLog); 14781591693c7b415e9869157c711fe11263c95d74eDavid Li 1479d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li prog->InfoLog = hieralloc_strdup(NULL, ""); 14801591693c7b415e9869157c711fe11263c95d74eDavid Li 14811591693c7b415e9869157c711fe11263c95d74eDavid Li /* Separate the shaders into groups based on their type. 14821591693c7b415e9869157c711fe11263c95d74eDavid Li */ 14831591693c7b415e9869157c711fe11263c95d74eDavid Li struct gl_shader **vert_shader_list; 14841591693c7b415e9869157c711fe11263c95d74eDavid Li unsigned num_vert_shaders = 0; 14851591693c7b415e9869157c711fe11263c95d74eDavid Li struct gl_shader **frag_shader_list; 14861591693c7b415e9869157c711fe11263c95d74eDavid Li unsigned num_frag_shaders = 0; 14871591693c7b415e9869157c711fe11263c95d74eDavid Li 14881591693c7b415e9869157c711fe11263c95d74eDavid Li vert_shader_list = (struct gl_shader **) 14891591693c7b415e9869157c711fe11263c95d74eDavid Li calloc(2 * prog->NumShaders, sizeof(struct gl_shader *)); 14901591693c7b415e9869157c711fe11263c95d74eDavid Li frag_shader_list = &vert_shader_list[prog->NumShaders]; 14911591693c7b415e9869157c711fe11263c95d74eDavid Li 14921591693c7b415e9869157c711fe11263c95d74eDavid Li unsigned min_version = UINT_MAX; 14931591693c7b415e9869157c711fe11263c95d74eDavid Li unsigned max_version = 0; 14941591693c7b415e9869157c711fe11263c95d74eDavid Li for (unsigned i = 0; i < prog->NumShaders; i++) { 14951591693c7b415e9869157c711fe11263c95d74eDavid Li min_version = MIN2(min_version, prog->Shaders[i]->Version); 14961591693c7b415e9869157c711fe11263c95d74eDavid Li max_version = MAX2(max_version, prog->Shaders[i]->Version); 14971591693c7b415e9869157c711fe11263c95d74eDavid Li 14981591693c7b415e9869157c711fe11263c95d74eDavid Li switch (prog->Shaders[i]->Type) { 14991591693c7b415e9869157c711fe11263c95d74eDavid Li case GL_VERTEX_SHADER: 15001591693c7b415e9869157c711fe11263c95d74eDavid Li vert_shader_list[num_vert_shaders] = prog->Shaders[i]; 15011591693c7b415e9869157c711fe11263c95d74eDavid Li num_vert_shaders++; 15021591693c7b415e9869157c711fe11263c95d74eDavid Li break; 15031591693c7b415e9869157c711fe11263c95d74eDavid Li case GL_FRAGMENT_SHADER: 15041591693c7b415e9869157c711fe11263c95d74eDavid Li frag_shader_list[num_frag_shaders] = prog->Shaders[i]; 15051591693c7b415e9869157c711fe11263c95d74eDavid Li num_frag_shaders++; 15061591693c7b415e9869157c711fe11263c95d74eDavid Li break; 15071591693c7b415e9869157c711fe11263c95d74eDavid Li case GL_GEOMETRY_SHADER: 15081591693c7b415e9869157c711fe11263c95d74eDavid Li /* FINISHME: Support geometry shaders. */ 15091591693c7b415e9869157c711fe11263c95d74eDavid Li assert(prog->Shaders[i]->Type != GL_GEOMETRY_SHADER); 15101591693c7b415e9869157c711fe11263c95d74eDavid Li break; 15111591693c7b415e9869157c711fe11263c95d74eDavid Li } 15121591693c7b415e9869157c711fe11263c95d74eDavid Li } 15131591693c7b415e9869157c711fe11263c95d74eDavid Li 15141591693c7b415e9869157c711fe11263c95d74eDavid Li /* Previous to GLSL version 1.30, different compilation units could mix and 15151591693c7b415e9869157c711fe11263c95d74eDavid Li * match shading language versions. With GLSL 1.30 and later, the versions 15161591693c7b415e9869157c711fe11263c95d74eDavid Li * of all shaders must match. 15171591693c7b415e9869157c711fe11263c95d74eDavid Li */ 15181591693c7b415e9869157c711fe11263c95d74eDavid Li assert(min_version >= 100); 15191591693c7b415e9869157c711fe11263c95d74eDavid Li assert(max_version <= 130); 15201591693c7b415e9869157c711fe11263c95d74eDavid Li if ((max_version >= 130 || min_version == 100) 15211591693c7b415e9869157c711fe11263c95d74eDavid Li && min_version != max_version) { 15221591693c7b415e9869157c711fe11263c95d74eDavid Li linker_error_printf(prog, "all shaders must use same shading " 15231591693c7b415e9869157c711fe11263c95d74eDavid Li "language version\n"); 15241591693c7b415e9869157c711fe11263c95d74eDavid Li goto done; 15251591693c7b415e9869157c711fe11263c95d74eDavid Li } 15261591693c7b415e9869157c711fe11263c95d74eDavid Li 15271591693c7b415e9869157c711fe11263c95d74eDavid Li prog->Version = max_version; 15281591693c7b415e9869157c711fe11263c95d74eDavid Li 15291591693c7b415e9869157c711fe11263c95d74eDavid Li for (unsigned int i = 0; i < MESA_SHADER_TYPES; i++) { 15301591693c7b415e9869157c711fe11263c95d74eDavid Li if (prog->_LinkedShaders[i] != NULL) 15311591693c7b415e9869157c711fe11263c95d74eDavid Li ctx->Driver.DeleteShader(ctx, prog->_LinkedShaders[i]); 15321591693c7b415e9869157c711fe11263c95d74eDavid Li 15331591693c7b415e9869157c711fe11263c95d74eDavid Li prog->_LinkedShaders[i] = NULL; 15341591693c7b415e9869157c711fe11263c95d74eDavid Li } 15351591693c7b415e9869157c711fe11263c95d74eDavid Li 15361591693c7b415e9869157c711fe11263c95d74eDavid Li /* Link all shaders for a particular stage and validate the result. 15371591693c7b415e9869157c711fe11263c95d74eDavid Li */ 15381591693c7b415e9869157c711fe11263c95d74eDavid Li if (num_vert_shaders > 0) { 15391591693c7b415e9869157c711fe11263c95d74eDavid Li gl_shader *const sh = 15401591693c7b415e9869157c711fe11263c95d74eDavid Li link_intrastage_shaders(mem_ctx, ctx, prog, vert_shader_list, 15411591693c7b415e9869157c711fe11263c95d74eDavid Li num_vert_shaders); 15421591693c7b415e9869157c711fe11263c95d74eDavid Li 15431591693c7b415e9869157c711fe11263c95d74eDavid Li if (sh == NULL) 15441591693c7b415e9869157c711fe11263c95d74eDavid Li goto done; 15451591693c7b415e9869157c711fe11263c95d74eDavid Li 15461591693c7b415e9869157c711fe11263c95d74eDavid Li if (!validate_vertex_shader_executable(prog, sh)) 15471591693c7b415e9869157c711fe11263c95d74eDavid Li goto done; 15481591693c7b415e9869157c711fe11263c95d74eDavid Li 15491591693c7b415e9869157c711fe11263c95d74eDavid Li _mesa_reference_shader(ctx, &prog->_LinkedShaders[MESA_SHADER_VERTEX], 15501591693c7b415e9869157c711fe11263c95d74eDavid Li sh); 15511591693c7b415e9869157c711fe11263c95d74eDavid Li } 15521591693c7b415e9869157c711fe11263c95d74eDavid Li 15531591693c7b415e9869157c711fe11263c95d74eDavid Li if (num_frag_shaders > 0) { 15541591693c7b415e9869157c711fe11263c95d74eDavid Li gl_shader *const sh = 15551591693c7b415e9869157c711fe11263c95d74eDavid Li link_intrastage_shaders(mem_ctx, ctx, prog, frag_shader_list, 15561591693c7b415e9869157c711fe11263c95d74eDavid Li num_frag_shaders); 15571591693c7b415e9869157c711fe11263c95d74eDavid Li 15581591693c7b415e9869157c711fe11263c95d74eDavid Li if (sh == NULL) 15591591693c7b415e9869157c711fe11263c95d74eDavid Li goto done; 15601591693c7b415e9869157c711fe11263c95d74eDavid Li 15611591693c7b415e9869157c711fe11263c95d74eDavid Li if (!validate_fragment_shader_executable(prog, sh)) 15621591693c7b415e9869157c711fe11263c95d74eDavid Li goto done; 15631591693c7b415e9869157c711fe11263c95d74eDavid Li 15641591693c7b415e9869157c711fe11263c95d74eDavid Li _mesa_reference_shader(ctx, &prog->_LinkedShaders[MESA_SHADER_FRAGMENT], 15651591693c7b415e9869157c711fe11263c95d74eDavid Li sh); 15661591693c7b415e9869157c711fe11263c95d74eDavid Li } 15671591693c7b415e9869157c711fe11263c95d74eDavid Li 15681591693c7b415e9869157c711fe11263c95d74eDavid Li /* Here begins the inter-stage linking phase. Some initial validation is 15691591693c7b415e9869157c711fe11263c95d74eDavid Li * performed, then locations are assigned for uniforms, attributes, and 15701591693c7b415e9869157c711fe11263c95d74eDavid Li * varyings. 15711591693c7b415e9869157c711fe11263c95d74eDavid Li */ 15721591693c7b415e9869157c711fe11263c95d74eDavid Li if (cross_validate_uniforms(prog)) { 15731591693c7b415e9869157c711fe11263c95d74eDavid Li unsigned prev; 15741591693c7b415e9869157c711fe11263c95d74eDavid Li 15751591693c7b415e9869157c711fe11263c95d74eDavid Li for (prev = 0; prev < MESA_SHADER_TYPES; prev++) { 15761591693c7b415e9869157c711fe11263c95d74eDavid Li if (prog->_LinkedShaders[prev] != NULL) 15771591693c7b415e9869157c711fe11263c95d74eDavid Li break; 15781591693c7b415e9869157c711fe11263c95d74eDavid Li } 15791591693c7b415e9869157c711fe11263c95d74eDavid Li 15801591693c7b415e9869157c711fe11263c95d74eDavid Li /* Validate the inputs of each stage with the output of the preceeding 15811591693c7b415e9869157c711fe11263c95d74eDavid Li * stage. 15821591693c7b415e9869157c711fe11263c95d74eDavid Li */ 15831591693c7b415e9869157c711fe11263c95d74eDavid Li for (unsigned i = prev + 1; i < MESA_SHADER_TYPES; i++) { 15841591693c7b415e9869157c711fe11263c95d74eDavid Li if (prog->_LinkedShaders[i] == NULL) 15851591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 15861591693c7b415e9869157c711fe11263c95d74eDavid Li 15871591693c7b415e9869157c711fe11263c95d74eDavid Li if (!cross_validate_outputs_to_inputs(prog, 15881591693c7b415e9869157c711fe11263c95d74eDavid Li prog->_LinkedShaders[prev], 15891591693c7b415e9869157c711fe11263c95d74eDavid Li prog->_LinkedShaders[i])) 15901591693c7b415e9869157c711fe11263c95d74eDavid Li goto done; 15911591693c7b415e9869157c711fe11263c95d74eDavid Li 15921591693c7b415e9869157c711fe11263c95d74eDavid Li prev = i; 15931591693c7b415e9869157c711fe11263c95d74eDavid Li } 15941591693c7b415e9869157c711fe11263c95d74eDavid Li 15951591693c7b415e9869157c711fe11263c95d74eDavid Li prog->LinkStatus = true; 15961591693c7b415e9869157c711fe11263c95d74eDavid Li } 15971591693c7b415e9869157c711fe11263c95d74eDavid Li 15981591693c7b415e9869157c711fe11263c95d74eDavid Li /* Do common optimization before assigning storage for attributes, 15991591693c7b415e9869157c711fe11263c95d74eDavid Li * uniforms, and varyings. Later optimization could possibly make 16001591693c7b415e9869157c711fe11263c95d74eDavid Li * some of that unused. 16011591693c7b415e9869157c711fe11263c95d74eDavid Li */ 16021591693c7b415e9869157c711fe11263c95d74eDavid Li for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { 16031591693c7b415e9869157c711fe11263c95d74eDavid Li if (prog->_LinkedShaders[i] == NULL) 16041591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 16051591693c7b415e9869157c711fe11263c95d74eDavid Li 16061591693c7b415e9869157c711fe11263c95d74eDavid Li while (do_common_optimization(prog->_LinkedShaders[i]->ir, true, 32)) 16071591693c7b415e9869157c711fe11263c95d74eDavid Li ; 16081591693c7b415e9869157c711fe11263c95d74eDavid Li } 16091591693c7b415e9869157c711fe11263c95d74eDavid Li 16101591693c7b415e9869157c711fe11263c95d74eDavid Li update_array_sizes(prog); 16111591693c7b415e9869157c711fe11263c95d74eDavid Li 16121591693c7b415e9869157c711fe11263c95d74eDavid Li assign_uniform_locations(prog); 16131591693c7b415e9869157c711fe11263c95d74eDavid Li 16141591693c7b415e9869157c711fe11263c95d74eDavid Li if (prog->_LinkedShaders[MESA_SHADER_VERTEX] != NULL) { 16151591693c7b415e9869157c711fe11263c95d74eDavid Li /* FINISHME: The value of the max_attribute_index parameter is 16161591693c7b415e9869157c711fe11263c95d74eDavid Li * FINISHME: implementation dependent based on the value of 16171591693c7b415e9869157c711fe11263c95d74eDavid Li * FINISHME: GL_MAX_VERTEX_ATTRIBS. GL_MAX_VERTEX_ATTRIBS must be 16181591693c7b415e9869157c711fe11263c95d74eDavid Li * FINISHME: at least 16, so hardcode 16 for now. 16191591693c7b415e9869157c711fe11263c95d74eDavid Li */ 16201591693c7b415e9869157c711fe11263c95d74eDavid Li if (!assign_attribute_locations(prog, 16)) { 16211591693c7b415e9869157c711fe11263c95d74eDavid Li prog->LinkStatus = false; 16221591693c7b415e9869157c711fe11263c95d74eDavid Li goto done; 16231591693c7b415e9869157c711fe11263c95d74eDavid Li } 16241591693c7b415e9869157c711fe11263c95d74eDavid Li } 16251591693c7b415e9869157c711fe11263c95d74eDavid Li 16261591693c7b415e9869157c711fe11263c95d74eDavid Li unsigned prev; 16271591693c7b415e9869157c711fe11263c95d74eDavid Li for (prev = 0; prev < MESA_SHADER_TYPES; prev++) { 16281591693c7b415e9869157c711fe11263c95d74eDavid Li if (prog->_LinkedShaders[prev] != NULL) 16291591693c7b415e9869157c711fe11263c95d74eDavid Li break; 16301591693c7b415e9869157c711fe11263c95d74eDavid Li } 16311591693c7b415e9869157c711fe11263c95d74eDavid Li 16321591693c7b415e9869157c711fe11263c95d74eDavid Li for (unsigned i = prev + 1; i < MESA_SHADER_TYPES; i++) { 16331591693c7b415e9869157c711fe11263c95d74eDavid Li if (prog->_LinkedShaders[i] == NULL) 16341591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 16351591693c7b415e9869157c711fe11263c95d74eDavid Li 16361591693c7b415e9869157c711fe11263c95d74eDavid Li assign_varying_locations(prog, 16371591693c7b415e9869157c711fe11263c95d74eDavid Li prog->_LinkedShaders[prev], 16381591693c7b415e9869157c711fe11263c95d74eDavid Li prog->_LinkedShaders[i]); 16391591693c7b415e9869157c711fe11263c95d74eDavid Li prev = i; 16401591693c7b415e9869157c711fe11263c95d74eDavid Li } 16411591693c7b415e9869157c711fe11263c95d74eDavid Li 16421591693c7b415e9869157c711fe11263c95d74eDavid Li if (prog->_LinkedShaders[MESA_SHADER_VERTEX] != NULL) { 16431591693c7b415e9869157c711fe11263c95d74eDavid Li demote_shader_inputs_and_outputs(prog->_LinkedShaders[MESA_SHADER_VERTEX], 16441591693c7b415e9869157c711fe11263c95d74eDavid Li ir_var_out); 16451591693c7b415e9869157c711fe11263c95d74eDavid Li } 16461591693c7b415e9869157c711fe11263c95d74eDavid Li 16471591693c7b415e9869157c711fe11263c95d74eDavid Li if (prog->_LinkedShaders[MESA_SHADER_GEOMETRY] != NULL) { 16481591693c7b415e9869157c711fe11263c95d74eDavid Li gl_shader *const sh = prog->_LinkedShaders[MESA_SHADER_GEOMETRY]; 16491591693c7b415e9869157c711fe11263c95d74eDavid Li 16501591693c7b415e9869157c711fe11263c95d74eDavid Li demote_shader_inputs_and_outputs(sh, ir_var_in); 16511591693c7b415e9869157c711fe11263c95d74eDavid Li demote_shader_inputs_and_outputs(sh, ir_var_inout); 16521591693c7b415e9869157c711fe11263c95d74eDavid Li demote_shader_inputs_and_outputs(sh, ir_var_out); 16531591693c7b415e9869157c711fe11263c95d74eDavid Li } 16541591693c7b415e9869157c711fe11263c95d74eDavid Li 16551591693c7b415e9869157c711fe11263c95d74eDavid Li if (prog->_LinkedShaders[MESA_SHADER_FRAGMENT] != NULL) { 16561591693c7b415e9869157c711fe11263c95d74eDavid Li gl_shader *const sh = prog->_LinkedShaders[MESA_SHADER_FRAGMENT]; 16571591693c7b415e9869157c711fe11263c95d74eDavid Li 1658b286f63e168037c1dbf9a10614dd6a1cd6b9ef69David Li //demote_shader_inputs_and_outputs(sh, ir_var_in); for testing, don't demote 16591591693c7b415e9869157c711fe11263c95d74eDavid Li } 16601591693c7b415e9869157c711fe11263c95d74eDavid Li 16611591693c7b415e9869157c711fe11263c95d74eDavid Li /* FINISHME: Assign fragment shader output locations. */ 16621591693c7b415e9869157c711fe11263c95d74eDavid Li 16631591693c7b415e9869157c711fe11263c95d74eDavid Lidone: 16641591693c7b415e9869157c711fe11263c95d74eDavid Li free(vert_shader_list); 16651591693c7b415e9869157c711fe11263c95d74eDavid Li 16661591693c7b415e9869157c711fe11263c95d74eDavid Li for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { 16671591693c7b415e9869157c711fe11263c95d74eDavid Li if (prog->_LinkedShaders[i] == NULL) 16681591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 16691591693c7b415e9869157c711fe11263c95d74eDavid Li 16701591693c7b415e9869157c711fe11263c95d74eDavid Li /* Retain any live IR, but trash the rest. */ 16711591693c7b415e9869157c711fe11263c95d74eDavid Li reparent_ir(prog->_LinkedShaders[i]->ir, prog->_LinkedShaders[i]->ir); 16721591693c7b415e9869157c711fe11263c95d74eDavid Li } 16731591693c7b415e9869157c711fe11263c95d74eDavid Li 167413fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li //hieralloc_free(mem_ctx); 16751591693c7b415e9869157c711fe11263c95d74eDavid Li} 1676