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