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 */ 664f054616c70eb5bb1eb711d5bdf6f4c71ac3b877Conley Owens#include <cstddef> 671591693c7b415e9869157c711fe11263c95d74eDavid Li#include <cstdlib> 681591693c7b415e9869157c711fe11263c95d74eDavid Li#include <cstdio> 691591693c7b415e9869157c711fe11263c95d74eDavid Li#include <cstdarg> 701591693c7b415e9869157c711fe11263c95d74eDavid Li#include <climits> 711591693c7b415e9869157c711fe11263c95d74eDavid Li 72c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li#include <pixelflinger2/pixelflinger2_interface.h> 73c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li 741591693c7b415e9869157c711fe11263c95d74eDavid Liextern "C" { 75d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li#include <hieralloc.h> 761591693c7b415e9869157c711fe11263c95d74eDavid Li} 771591693c7b415e9869157c711fe11263c95d74eDavid Li 781591693c7b415e9869157c711fe11263c95d74eDavid Li#include "main/core.h" 791591693c7b415e9869157c711fe11263c95d74eDavid Li#include "glsl_symbol_table.h" 801591693c7b415e9869157c711fe11263c95d74eDavid Li#include "ir.h" 811591693c7b415e9869157c711fe11263c95d74eDavid Li#include "program.h" 821591693c7b415e9869157c711fe11263c95d74eDavid Li#include "program/hash_table.h" 831591693c7b415e9869157c711fe11263c95d74eDavid Li#include "linker.h" 841591693c7b415e9869157c711fe11263c95d74eDavid Li#include "ir_optimization.h" 851591693c7b415e9869157c711fe11263c95d74eDavid Li 861591693c7b415e9869157c711fe11263c95d74eDavid Li#include "main/shaderobj.h" 872ac1cf8a62bcf080b70eaa7c0e4f57d4e8001685David Li 881591693c7b415e9869157c711fe11263c95d74eDavid Li/** 891591693c7b415e9869157c711fe11263c95d74eDavid Li * Visitor that determines whether or not a variable is ever written. 901591693c7b415e9869157c711fe11263c95d74eDavid Li */ 911591693c7b415e9869157c711fe11263c95d74eDavid Liclass find_assignment_visitor : public ir_hierarchical_visitor { 921591693c7b415e9869157c711fe11263c95d74eDavid Lipublic: 931591693c7b415e9869157c711fe11263c95d74eDavid Li find_assignment_visitor(const char *name) 941591693c7b415e9869157c711fe11263c95d74eDavid Li : name(name), found(false) 951591693c7b415e9869157c711fe11263c95d74eDavid Li { 961591693c7b415e9869157c711fe11263c95d74eDavid Li /* empty */ 971591693c7b415e9869157c711fe11263c95d74eDavid Li } 981591693c7b415e9869157c711fe11263c95d74eDavid Li 991591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit_enter(ir_assignment *ir) 1001591693c7b415e9869157c711fe11263c95d74eDavid Li { 1011591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *const var = ir->lhs->variable_referenced(); 1021591693c7b415e9869157c711fe11263c95d74eDavid Li 1031591693c7b415e9869157c711fe11263c95d74eDavid Li if (strcmp(name, var->name) == 0) { 1041591693c7b415e9869157c711fe11263c95d74eDavid Li found = true; 1051591693c7b415e9869157c711fe11263c95d74eDavid Li return visit_stop; 1061591693c7b415e9869157c711fe11263c95d74eDavid Li } 1071591693c7b415e9869157c711fe11263c95d74eDavid Li 1081591693c7b415e9869157c711fe11263c95d74eDavid Li return visit_continue_with_parent; 1091591693c7b415e9869157c711fe11263c95d74eDavid Li } 1101591693c7b415e9869157c711fe11263c95d74eDavid Li 1114f054616c70eb5bb1eb711d5bdf6f4c71ac3b877Conley Owens using ir_hierarchical_visitor::visit_enter; 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 1554f054616c70eb5bb1eb711d5bdf6f4c71ac3b877Conley Owens using ir_hierarchical_visitor::visit; 1561591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit(ir_dereference_variable *ir) 1571591693c7b415e9869157c711fe11263c95d74eDavid Li { 1581591693c7b415e9869157c711fe11263c95d74eDavid Li if (strcmp(this->name, ir->var->name) == 0) { 1591591693c7b415e9869157c711fe11263c95d74eDavid Li this->found = true; 1601591693c7b415e9869157c711fe11263c95d74eDavid Li return visit_stop; 1611591693c7b415e9869157c711fe11263c95d74eDavid Li } 1621591693c7b415e9869157c711fe11263c95d74eDavid Li 1631591693c7b415e9869157c711fe11263c95d74eDavid Li return visit_continue; 1641591693c7b415e9869157c711fe11263c95d74eDavid Li } 1651591693c7b415e9869157c711fe11263c95d74eDavid Li 1661591693c7b415e9869157c711fe11263c95d74eDavid Li bool variable_found() const 1671591693c7b415e9869157c711fe11263c95d74eDavid Li { 1681591693c7b415e9869157c711fe11263c95d74eDavid Li return this->found; 1691591693c7b415e9869157c711fe11263c95d74eDavid Li } 1701591693c7b415e9869157c711fe11263c95d74eDavid Li 1711591693c7b415e9869157c711fe11263c95d74eDavid Liprivate: 1721591693c7b415e9869157c711fe11263c95d74eDavid Li const char *name; /**< Find writes to a variable with this name. */ 1731591693c7b415e9869157c711fe11263c95d74eDavid Li bool found; /**< Was a write to the variable found? */ 1741591693c7b415e9869157c711fe11263c95d74eDavid Li}; 1751591693c7b415e9869157c711fe11263c95d74eDavid Li 1761591693c7b415e9869157c711fe11263c95d74eDavid Li 1771591693c7b415e9869157c711fe11263c95d74eDavid Livoid 1781591693c7b415e9869157c711fe11263c95d74eDavid Lilinker_error_printf(gl_shader_program *prog, const char *fmt, ...) 1791591693c7b415e9869157c711fe11263c95d74eDavid Li{ 1801591693c7b415e9869157c711fe11263c95d74eDavid Li va_list ap; 1811591693c7b415e9869157c711fe11263c95d74eDavid Li 182d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li prog->InfoLog = hieralloc_strdup_append(prog->InfoLog, "error: "); 1831591693c7b415e9869157c711fe11263c95d74eDavid Li va_start(ap, fmt); 184d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li prog->InfoLog = hieralloc_vasprintf_append(prog->InfoLog, fmt, ap); 1851591693c7b415e9869157c711fe11263c95d74eDavid Li va_end(ap); 1861591693c7b415e9869157c711fe11263c95d74eDavid Li} 1871591693c7b415e9869157c711fe11263c95d74eDavid Li 1881591693c7b415e9869157c711fe11263c95d74eDavid Li 1891591693c7b415e9869157c711fe11263c95d74eDavid Livoid 1901591693c7b415e9869157c711fe11263c95d74eDavid Liinvalidate_variable_locations(gl_shader *sh, enum ir_variable_mode mode, 1911591693c7b415e9869157c711fe11263c95d74eDavid Li int generic_base) 1921591693c7b415e9869157c711fe11263c95d74eDavid Li{ 1931591693c7b415e9869157c711fe11263c95d74eDavid Li foreach_list(node, sh->ir) { 1941591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *const var = ((ir_instruction *) node)->as_variable(); 1951591693c7b415e9869157c711fe11263c95d74eDavid Li 1961591693c7b415e9869157c711fe11263c95d74eDavid Li if ((var == NULL) || (var->mode != (unsigned) mode)) 1971591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 1981591693c7b415e9869157c711fe11263c95d74eDavid Li 1991591693c7b415e9869157c711fe11263c95d74eDavid Li /* Only assign locations for generic attributes / varyings / etc. 2001591693c7b415e9869157c711fe11263c95d74eDavid Li */ 2011591693c7b415e9869157c711fe11263c95d74eDavid Li if ((var->location >= generic_base) && !var->explicit_location) 2021591693c7b415e9869157c711fe11263c95d74eDavid Li var->location = -1; 2031591693c7b415e9869157c711fe11263c95d74eDavid Li } 2041591693c7b415e9869157c711fe11263c95d74eDavid Li} 2051591693c7b415e9869157c711fe11263c95d74eDavid Li 2061591693c7b415e9869157c711fe11263c95d74eDavid Li 2071591693c7b415e9869157c711fe11263c95d74eDavid Li/** 2081591693c7b415e9869157c711fe11263c95d74eDavid Li * Determine the number of attribute slots required for a particular type 2091591693c7b415e9869157c711fe11263c95d74eDavid Li * 2101591693c7b415e9869157c711fe11263c95d74eDavid Li * This code is here because it implements the language rules of a specific 2111591693c7b415e9869157c711fe11263c95d74eDavid Li * GLSL version. Since it's a property of the language and not a property of 2121591693c7b415e9869157c711fe11263c95d74eDavid Li * types in general, it doesn't really belong in glsl_type. 2131591693c7b415e9869157c711fe11263c95d74eDavid Li */ 2141591693c7b415e9869157c711fe11263c95d74eDavid Liunsigned 2151591693c7b415e9869157c711fe11263c95d74eDavid Licount_attribute_slots(const glsl_type *t) 2161591693c7b415e9869157c711fe11263c95d74eDavid Li{ 2171591693c7b415e9869157c711fe11263c95d74eDavid Li /* From page 31 (page 37 of the PDF) of the GLSL 1.50 spec: 2181591693c7b415e9869157c711fe11263c95d74eDavid Li * 2191591693c7b415e9869157c711fe11263c95d74eDavid Li * "A scalar input counts the same amount against this limit as a vec4, 2201591693c7b415e9869157c711fe11263c95d74eDavid Li * so applications may want to consider packing groups of four 2211591693c7b415e9869157c711fe11263c95d74eDavid Li * unrelated float inputs together into a vector to better utilize the 2221591693c7b415e9869157c711fe11263c95d74eDavid Li * capabilities of the underlying hardware. A matrix input will use up 2231591693c7b415e9869157c711fe11263c95d74eDavid Li * multiple locations. The number of locations used will equal the 2241591693c7b415e9869157c711fe11263c95d74eDavid Li * number of columns in the matrix." 2251591693c7b415e9869157c711fe11263c95d74eDavid Li * 2261591693c7b415e9869157c711fe11263c95d74eDavid Li * The spec does not explicitly say how arrays are counted. However, it 2271591693c7b415e9869157c711fe11263c95d74eDavid Li * should be safe to assume the total number of slots consumed by an array 2281591693c7b415e9869157c711fe11263c95d74eDavid Li * is the number of entries in the array multiplied by the number of slots 2291591693c7b415e9869157c711fe11263c95d74eDavid Li * consumed by a single element of the array. 2301591693c7b415e9869157c711fe11263c95d74eDavid Li */ 2311591693c7b415e9869157c711fe11263c95d74eDavid Li 2321591693c7b415e9869157c711fe11263c95d74eDavid Li if (t->is_array()) 2331591693c7b415e9869157c711fe11263c95d74eDavid Li return t->array_size() * count_attribute_slots(t->element_type()); 2341591693c7b415e9869157c711fe11263c95d74eDavid Li 2351591693c7b415e9869157c711fe11263c95d74eDavid Li if (t->is_matrix()) 2361591693c7b415e9869157c711fe11263c95d74eDavid Li return t->matrix_columns; 2371591693c7b415e9869157c711fe11263c95d74eDavid Li 2381591693c7b415e9869157c711fe11263c95d74eDavid Li return 1; 2391591693c7b415e9869157c711fe11263c95d74eDavid Li} 2401591693c7b415e9869157c711fe11263c95d74eDavid Li 2411591693c7b415e9869157c711fe11263c95d74eDavid Li 2421591693c7b415e9869157c711fe11263c95d74eDavid Li/** 2431591693c7b415e9869157c711fe11263c95d74eDavid Li * Verify that a vertex shader executable meets all semantic requirements 2441591693c7b415e9869157c711fe11263c95d74eDavid Li * 2451591693c7b415e9869157c711fe11263c95d74eDavid Li * \param shader Vertex shader executable to be verified 2461591693c7b415e9869157c711fe11263c95d74eDavid Li */ 2471591693c7b415e9869157c711fe11263c95d74eDavid Libool 2481591693c7b415e9869157c711fe11263c95d74eDavid Livalidate_vertex_shader_executable(struct gl_shader_program *prog, 2491591693c7b415e9869157c711fe11263c95d74eDavid Li struct gl_shader *shader) 2501591693c7b415e9869157c711fe11263c95d74eDavid Li{ 2511591693c7b415e9869157c711fe11263c95d74eDavid Li if (shader == NULL) 2521591693c7b415e9869157c711fe11263c95d74eDavid Li return true; 2531591693c7b415e9869157c711fe11263c95d74eDavid Li 2541591693c7b415e9869157c711fe11263c95d74eDavid Li find_assignment_visitor find("gl_Position"); 2551591693c7b415e9869157c711fe11263c95d74eDavid Li find.run(shader->ir); 2561591693c7b415e9869157c711fe11263c95d74eDavid Li if (!find.variable_found()) { 2571591693c7b415e9869157c711fe11263c95d74eDavid Li linker_error_printf(prog, 2581591693c7b415e9869157c711fe11263c95d74eDavid Li "vertex shader does not write to `gl_Position'\n"); 2591591693c7b415e9869157c711fe11263c95d74eDavid Li return false; 2601591693c7b415e9869157c711fe11263c95d74eDavid Li } 2611591693c7b415e9869157c711fe11263c95d74eDavid Li 2621591693c7b415e9869157c711fe11263c95d74eDavid Li return true; 2631591693c7b415e9869157c711fe11263c95d74eDavid Li} 2641591693c7b415e9869157c711fe11263c95d74eDavid Li 2651591693c7b415e9869157c711fe11263c95d74eDavid Li 2661591693c7b415e9869157c711fe11263c95d74eDavid Li/** 2671591693c7b415e9869157c711fe11263c95d74eDavid Li * Verify that a fragment shader executable meets all semantic requirements 2681591693c7b415e9869157c711fe11263c95d74eDavid Li * 2691591693c7b415e9869157c711fe11263c95d74eDavid Li * \param shader Fragment shader executable to be verified 2701591693c7b415e9869157c711fe11263c95d74eDavid Li */ 2711591693c7b415e9869157c711fe11263c95d74eDavid Libool 2721591693c7b415e9869157c711fe11263c95d74eDavid Livalidate_fragment_shader_executable(struct gl_shader_program *prog, 2731591693c7b415e9869157c711fe11263c95d74eDavid Li struct gl_shader *shader) 2741591693c7b415e9869157c711fe11263c95d74eDavid Li{ 2751591693c7b415e9869157c711fe11263c95d74eDavid Li if (shader == NULL) 2761591693c7b415e9869157c711fe11263c95d74eDavid Li return true; 2771591693c7b415e9869157c711fe11263c95d74eDavid Li 2781591693c7b415e9869157c711fe11263c95d74eDavid Li find_assignment_visitor frag_color("gl_FragColor"); 2791591693c7b415e9869157c711fe11263c95d74eDavid Li find_assignment_visitor frag_data("gl_FragData"); 2801591693c7b415e9869157c711fe11263c95d74eDavid Li 2811591693c7b415e9869157c711fe11263c95d74eDavid Li frag_color.run(shader->ir); 2821591693c7b415e9869157c711fe11263c95d74eDavid Li frag_data.run(shader->ir); 2831591693c7b415e9869157c711fe11263c95d74eDavid Li 2841591693c7b415e9869157c711fe11263c95d74eDavid Li if (frag_color.variable_found() && frag_data.variable_found()) { 2851591693c7b415e9869157c711fe11263c95d74eDavid Li linker_error_printf(prog, "fragment shader writes to both " 2861591693c7b415e9869157c711fe11263c95d74eDavid Li "`gl_FragColor' and `gl_FragData'\n"); 2871591693c7b415e9869157c711fe11263c95d74eDavid Li return false; 2881591693c7b415e9869157c711fe11263c95d74eDavid Li } 2891591693c7b415e9869157c711fe11263c95d74eDavid Li 2901591693c7b415e9869157c711fe11263c95d74eDavid Li return true; 2911591693c7b415e9869157c711fe11263c95d74eDavid Li} 2921591693c7b415e9869157c711fe11263c95d74eDavid Li 2931591693c7b415e9869157c711fe11263c95d74eDavid Li 2941591693c7b415e9869157c711fe11263c95d74eDavid Li/** 2951591693c7b415e9869157c711fe11263c95d74eDavid Li * Generate a string describing the mode of a variable 2961591693c7b415e9869157c711fe11263c95d74eDavid Li */ 2971591693c7b415e9869157c711fe11263c95d74eDavid Listatic const char * 2981591693c7b415e9869157c711fe11263c95d74eDavid Limode_string(const ir_variable *var) 2991591693c7b415e9869157c711fe11263c95d74eDavid Li{ 3001591693c7b415e9869157c711fe11263c95d74eDavid Li switch (var->mode) { 3011591693c7b415e9869157c711fe11263c95d74eDavid Li case ir_var_auto: 3021591693c7b415e9869157c711fe11263c95d74eDavid Li return (var->read_only) ? "global constant" : "global variable"; 3031591693c7b415e9869157c711fe11263c95d74eDavid Li 3041591693c7b415e9869157c711fe11263c95d74eDavid Li case ir_var_uniform: return "uniform"; 3051591693c7b415e9869157c711fe11263c95d74eDavid Li case ir_var_in: return "shader input"; 3061591693c7b415e9869157c711fe11263c95d74eDavid Li case ir_var_out: return "shader output"; 3071591693c7b415e9869157c711fe11263c95d74eDavid Li case ir_var_inout: return "shader inout"; 3081591693c7b415e9869157c711fe11263c95d74eDavid Li 3091591693c7b415e9869157c711fe11263c95d74eDavid Li case ir_var_temporary: 3101591693c7b415e9869157c711fe11263c95d74eDavid Li default: 3111591693c7b415e9869157c711fe11263c95d74eDavid Li assert(!"Should not get here."); 3121591693c7b415e9869157c711fe11263c95d74eDavid Li return "invalid variable"; 3131591693c7b415e9869157c711fe11263c95d74eDavid Li } 3141591693c7b415e9869157c711fe11263c95d74eDavid Li} 3151591693c7b415e9869157c711fe11263c95d74eDavid Li 3161591693c7b415e9869157c711fe11263c95d74eDavid Li 3171591693c7b415e9869157c711fe11263c95d74eDavid Li/** 3181591693c7b415e9869157c711fe11263c95d74eDavid Li * Perform validation of global variables used across multiple shaders 3191591693c7b415e9869157c711fe11263c95d74eDavid Li */ 3201591693c7b415e9869157c711fe11263c95d74eDavid Libool 3211591693c7b415e9869157c711fe11263c95d74eDavid Licross_validate_globals(struct gl_shader_program *prog, 3221591693c7b415e9869157c711fe11263c95d74eDavid Li struct gl_shader **shader_list, 3231591693c7b415e9869157c711fe11263c95d74eDavid Li unsigned num_shaders, 3241591693c7b415e9869157c711fe11263c95d74eDavid Li bool uniforms_only) 3251591693c7b415e9869157c711fe11263c95d74eDavid Li{ 3261591693c7b415e9869157c711fe11263c95d74eDavid Li /* Examine all of the uniforms in all of the shaders and cross validate 3271591693c7b415e9869157c711fe11263c95d74eDavid Li * them. 3281591693c7b415e9869157c711fe11263c95d74eDavid Li */ 3293b02c91d7b1fcc777dbdafeb044e0df61e1ff0d8David Li glsl_symbol_table variables(prog); 3301591693c7b415e9869157c711fe11263c95d74eDavid Li for (unsigned i = 0; i < num_shaders; i++) { 3311591693c7b415e9869157c711fe11263c95d74eDavid Li if (shader_list[i] == NULL) 3321591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 3331591693c7b415e9869157c711fe11263c95d74eDavid Li 3341591693c7b415e9869157c711fe11263c95d74eDavid Li foreach_list(node, shader_list[i]->ir) { 3351591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *const var = ((ir_instruction *) node)->as_variable(); 3361591693c7b415e9869157c711fe11263c95d74eDavid Li 3371591693c7b415e9869157c711fe11263c95d74eDavid Li if (var == NULL) 3381591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 3391591693c7b415e9869157c711fe11263c95d74eDavid Li 3401591693c7b415e9869157c711fe11263c95d74eDavid Li if (uniforms_only && (var->mode != ir_var_uniform)) 3411591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 3421591693c7b415e9869157c711fe11263c95d74eDavid Li 3431591693c7b415e9869157c711fe11263c95d74eDavid Li /* Don't cross validate temporaries that are at global scope. These 3441591693c7b415e9869157c711fe11263c95d74eDavid Li * will eventually get pulled into the shaders 'main'. 3451591693c7b415e9869157c711fe11263c95d74eDavid Li */ 3461591693c7b415e9869157c711fe11263c95d74eDavid Li if (var->mode == ir_var_temporary) 3471591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 3481591693c7b415e9869157c711fe11263c95d74eDavid Li 3491591693c7b415e9869157c711fe11263c95d74eDavid Li /* If a global with this name has already been seen, verify that the 3501591693c7b415e9869157c711fe11263c95d74eDavid Li * new instance has the same type. In addition, if the globals have 3511591693c7b415e9869157c711fe11263c95d74eDavid Li * initializers, the values of the initializers must be the same. 3521591693c7b415e9869157c711fe11263c95d74eDavid Li */ 3531591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *const existing = variables.get_variable(var->name); 3541591693c7b415e9869157c711fe11263c95d74eDavid Li if (existing != NULL) { 3551591693c7b415e9869157c711fe11263c95d74eDavid Li if (var->type != existing->type) { 3561591693c7b415e9869157c711fe11263c95d74eDavid Li /* Consider the types to be "the same" if both types are arrays 3571591693c7b415e9869157c711fe11263c95d74eDavid Li * of the same type and one of the arrays is implicitly sized. 3581591693c7b415e9869157c711fe11263c95d74eDavid Li * In addition, set the type of the linked variable to the 3591591693c7b415e9869157c711fe11263c95d74eDavid Li * explicitly sized array. 3601591693c7b415e9869157c711fe11263c95d74eDavid Li */ 3611591693c7b415e9869157c711fe11263c95d74eDavid Li if (var->type->is_array() 3621591693c7b415e9869157c711fe11263c95d74eDavid Li && existing->type->is_array() 3631591693c7b415e9869157c711fe11263c95d74eDavid Li && (var->type->fields.array == existing->type->fields.array) 3641591693c7b415e9869157c711fe11263c95d74eDavid Li && ((var->type->length == 0) 3651591693c7b415e9869157c711fe11263c95d74eDavid Li || (existing->type->length == 0))) { 3661591693c7b415e9869157c711fe11263c95d74eDavid Li if (existing->type->length == 0) { 3671591693c7b415e9869157c711fe11263c95d74eDavid Li existing->type = var->type; 3681591693c7b415e9869157c711fe11263c95d74eDavid Li existing->max_array_access = 3691591693c7b415e9869157c711fe11263c95d74eDavid Li MAX2(existing->max_array_access, 3701591693c7b415e9869157c711fe11263c95d74eDavid Li var->max_array_access); 3711591693c7b415e9869157c711fe11263c95d74eDavid Li } 3721591693c7b415e9869157c711fe11263c95d74eDavid Li } else { 3731591693c7b415e9869157c711fe11263c95d74eDavid Li linker_error_printf(prog, "%s `%s' declared as type " 3741591693c7b415e9869157c711fe11263c95d74eDavid Li "`%s' and type `%s'\n", 3751591693c7b415e9869157c711fe11263c95d74eDavid Li mode_string(var), 3761591693c7b415e9869157c711fe11263c95d74eDavid Li var->name, var->type->name, 3771591693c7b415e9869157c711fe11263c95d74eDavid Li existing->type->name); 3781591693c7b415e9869157c711fe11263c95d74eDavid Li return false; 3791591693c7b415e9869157c711fe11263c95d74eDavid Li } 3801591693c7b415e9869157c711fe11263c95d74eDavid Li } 3811591693c7b415e9869157c711fe11263c95d74eDavid Li 3821591693c7b415e9869157c711fe11263c95d74eDavid Li if (var->explicit_location) { 3831591693c7b415e9869157c711fe11263c95d74eDavid Li if (existing->explicit_location 3841591693c7b415e9869157c711fe11263c95d74eDavid Li && (var->location != existing->location)) { 3851591693c7b415e9869157c711fe11263c95d74eDavid Li linker_error_printf(prog, "explicit locations for %s " 3861591693c7b415e9869157c711fe11263c95d74eDavid Li "`%s' have differing values\n", 3871591693c7b415e9869157c711fe11263c95d74eDavid Li mode_string(var), var->name); 3881591693c7b415e9869157c711fe11263c95d74eDavid Li return false; 3891591693c7b415e9869157c711fe11263c95d74eDavid Li } 3901591693c7b415e9869157c711fe11263c95d74eDavid Li 3911591693c7b415e9869157c711fe11263c95d74eDavid Li existing->location = var->location; 3921591693c7b415e9869157c711fe11263c95d74eDavid Li existing->explicit_location = true; 3931591693c7b415e9869157c711fe11263c95d74eDavid Li } 3941591693c7b415e9869157c711fe11263c95d74eDavid Li 3951591693c7b415e9869157c711fe11263c95d74eDavid Li /* FINISHME: Handle non-constant initializers. 3961591693c7b415e9869157c711fe11263c95d74eDavid Li */ 3971591693c7b415e9869157c711fe11263c95d74eDavid Li if (var->constant_value != NULL) { 3981591693c7b415e9869157c711fe11263c95d74eDavid Li if (existing->constant_value != NULL) { 3991591693c7b415e9869157c711fe11263c95d74eDavid Li if (!var->constant_value->has_value(existing->constant_value)) { 4001591693c7b415e9869157c711fe11263c95d74eDavid Li linker_error_printf(prog, "initializers for %s " 4011591693c7b415e9869157c711fe11263c95d74eDavid Li "`%s' have differing values\n", 4021591693c7b415e9869157c711fe11263c95d74eDavid Li mode_string(var), var->name); 4031591693c7b415e9869157c711fe11263c95d74eDavid Li return false; 4041591693c7b415e9869157c711fe11263c95d74eDavid Li } 4051591693c7b415e9869157c711fe11263c95d74eDavid Li } else 4061591693c7b415e9869157c711fe11263c95d74eDavid Li /* If the first-seen instance of a particular uniform did not 4071591693c7b415e9869157c711fe11263c95d74eDavid Li * have an initializer but a later instance does, copy the 4081591693c7b415e9869157c711fe11263c95d74eDavid Li * initializer to the version stored in the symbol table. 4091591693c7b415e9869157c711fe11263c95d74eDavid Li */ 4101591693c7b415e9869157c711fe11263c95d74eDavid Li /* FINISHME: This is wrong. The constant_value field should 4111591693c7b415e9869157c711fe11263c95d74eDavid Li * FINISHME: not be modified! Imagine a case where a shader 4121591693c7b415e9869157c711fe11263c95d74eDavid Li * FINISHME: without an initializer is linked in two different 4131591693c7b415e9869157c711fe11263c95d74eDavid Li * FINISHME: programs with shaders that have differing 4141591693c7b415e9869157c711fe11263c95d74eDavid Li * FINISHME: initializers. Linking with the first will 4151591693c7b415e9869157c711fe11263c95d74eDavid Li * FINISHME: modify the shader, and linking with the second 4161591693c7b415e9869157c711fe11263c95d74eDavid Li * FINISHME: will fail. 4171591693c7b415e9869157c711fe11263c95d74eDavid Li */ 4181591693c7b415e9869157c711fe11263c95d74eDavid Li existing->constant_value = 419d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li var->constant_value->clone(hieralloc_parent(existing), NULL); 4201591693c7b415e9869157c711fe11263c95d74eDavid Li } 4211591693c7b415e9869157c711fe11263c95d74eDavid Li 4221591693c7b415e9869157c711fe11263c95d74eDavid Li if (existing->invariant != var->invariant) { 4231591693c7b415e9869157c711fe11263c95d74eDavid Li linker_error_printf(prog, "declarations for %s `%s' have " 4241591693c7b415e9869157c711fe11263c95d74eDavid Li "mismatching invariant qualifiers\n", 4251591693c7b415e9869157c711fe11263c95d74eDavid Li mode_string(var), var->name); 4261591693c7b415e9869157c711fe11263c95d74eDavid Li return false; 4271591693c7b415e9869157c711fe11263c95d74eDavid Li } 4281591693c7b415e9869157c711fe11263c95d74eDavid Li } else 4291591693c7b415e9869157c711fe11263c95d74eDavid Li variables.add_variable(var); 4301591693c7b415e9869157c711fe11263c95d74eDavid Li } 4311591693c7b415e9869157c711fe11263c95d74eDavid Li } 4321591693c7b415e9869157c711fe11263c95d74eDavid Li 4331591693c7b415e9869157c711fe11263c95d74eDavid Li return true; 4341591693c7b415e9869157c711fe11263c95d74eDavid Li} 4351591693c7b415e9869157c711fe11263c95d74eDavid Li 4361591693c7b415e9869157c711fe11263c95d74eDavid Li 4371591693c7b415e9869157c711fe11263c95d74eDavid Li/** 4381591693c7b415e9869157c711fe11263c95d74eDavid Li * Perform validation of uniforms used across multiple shader stages 4391591693c7b415e9869157c711fe11263c95d74eDavid Li */ 4401591693c7b415e9869157c711fe11263c95d74eDavid Libool 4411591693c7b415e9869157c711fe11263c95d74eDavid Licross_validate_uniforms(struct gl_shader_program *prog) 4421591693c7b415e9869157c711fe11263c95d74eDavid Li{ 4431591693c7b415e9869157c711fe11263c95d74eDavid Li return cross_validate_globals(prog, prog->_LinkedShaders, 4441591693c7b415e9869157c711fe11263c95d74eDavid Li MESA_SHADER_TYPES, true); 4451591693c7b415e9869157c711fe11263c95d74eDavid Li} 4461591693c7b415e9869157c711fe11263c95d74eDavid Li 4471591693c7b415e9869157c711fe11263c95d74eDavid Li 4481591693c7b415e9869157c711fe11263c95d74eDavid Li/** 4491591693c7b415e9869157c711fe11263c95d74eDavid Li * Validate that outputs from one stage match inputs of another 4501591693c7b415e9869157c711fe11263c95d74eDavid Li */ 4511591693c7b415e9869157c711fe11263c95d74eDavid Libool 4521591693c7b415e9869157c711fe11263c95d74eDavid Licross_validate_outputs_to_inputs(struct gl_shader_program *prog, 4531591693c7b415e9869157c711fe11263c95d74eDavid Li gl_shader *producer, gl_shader *consumer) 4541591693c7b415e9869157c711fe11263c95d74eDavid Li{ 4553b02c91d7b1fcc777dbdafeb044e0df61e1ff0d8David Li glsl_symbol_table parameters(prog); 4561591693c7b415e9869157c711fe11263c95d74eDavid Li /* FINISHME: Figure these out dynamically. */ 4571591693c7b415e9869157c711fe11263c95d74eDavid Li const char *const producer_stage = "vertex"; 4581591693c7b415e9869157c711fe11263c95d74eDavid Li const char *const consumer_stage = "fragment"; 4591591693c7b415e9869157c711fe11263c95d74eDavid Li 4601591693c7b415e9869157c711fe11263c95d74eDavid Li /* Find all shader outputs in the "producer" stage. 4611591693c7b415e9869157c711fe11263c95d74eDavid Li */ 4621591693c7b415e9869157c711fe11263c95d74eDavid Li foreach_list(node, producer->ir) { 4631591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *const var = ((ir_instruction *) node)->as_variable(); 4641591693c7b415e9869157c711fe11263c95d74eDavid Li 4651591693c7b415e9869157c711fe11263c95d74eDavid Li /* FINISHME: For geometry shaders, this should also look for inout 4661591693c7b415e9869157c711fe11263c95d74eDavid Li * FINISHME: variables. 4671591693c7b415e9869157c711fe11263c95d74eDavid Li */ 4681591693c7b415e9869157c711fe11263c95d74eDavid Li if ((var == NULL) || (var->mode != ir_var_out)) 4691591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 4701591693c7b415e9869157c711fe11263c95d74eDavid Li 4711591693c7b415e9869157c711fe11263c95d74eDavid Li parameters.add_variable(var); 4721591693c7b415e9869157c711fe11263c95d74eDavid Li } 4731591693c7b415e9869157c711fe11263c95d74eDavid Li 4741591693c7b415e9869157c711fe11263c95d74eDavid Li 4751591693c7b415e9869157c711fe11263c95d74eDavid Li /* Find all shader inputs in the "consumer" stage. Any variables that have 4761591693c7b415e9869157c711fe11263c95d74eDavid Li * matching outputs already in the symbol table must have the same type and 4771591693c7b415e9869157c711fe11263c95d74eDavid Li * qualifiers. 4781591693c7b415e9869157c711fe11263c95d74eDavid Li */ 4791591693c7b415e9869157c711fe11263c95d74eDavid Li foreach_list(node, consumer->ir) { 4801591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *const input = ((ir_instruction *) node)->as_variable(); 4811591693c7b415e9869157c711fe11263c95d74eDavid Li 4821591693c7b415e9869157c711fe11263c95d74eDavid Li /* FINISHME: For geometry shaders, this should also look for inout 4831591693c7b415e9869157c711fe11263c95d74eDavid Li * FINISHME: variables. 4841591693c7b415e9869157c711fe11263c95d74eDavid Li */ 4851591693c7b415e9869157c711fe11263c95d74eDavid Li if ((input == NULL) || (input->mode != ir_var_in)) 4861591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 4871591693c7b415e9869157c711fe11263c95d74eDavid Li 4881591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *const output = parameters.get_variable(input->name); 4891591693c7b415e9869157c711fe11263c95d74eDavid Li if (output != NULL) { 4901591693c7b415e9869157c711fe11263c95d74eDavid Li /* Check that the types match between stages. 4911591693c7b415e9869157c711fe11263c95d74eDavid Li */ 4921591693c7b415e9869157c711fe11263c95d74eDavid Li if (input->type != output->type) { 4931591693c7b415e9869157c711fe11263c95d74eDavid Li /* There is a bit of a special case for gl_TexCoord. This 4941591693c7b415e9869157c711fe11263c95d74eDavid Li * built-in is unsized by default. Appliations that variable 4951591693c7b415e9869157c711fe11263c95d74eDavid Li * access it must redeclare it with a size. There is some 4961591693c7b415e9869157c711fe11263c95d74eDavid Li * language in the GLSL spec that implies the fragment shader 4971591693c7b415e9869157c711fe11263c95d74eDavid Li * and vertex shader do not have to agree on this size. Other 4981591693c7b415e9869157c711fe11263c95d74eDavid Li * driver behave this way, and one or two applications seem to 4991591693c7b415e9869157c711fe11263c95d74eDavid Li * rely on it. 5001591693c7b415e9869157c711fe11263c95d74eDavid Li * 5011591693c7b415e9869157c711fe11263c95d74eDavid Li * Neither declaration needs to be modified here because the array 5021591693c7b415e9869157c711fe11263c95d74eDavid Li * sizes are fixed later when update_array_sizes is called. 5031591693c7b415e9869157c711fe11263c95d74eDavid Li * 5041591693c7b415e9869157c711fe11263c95d74eDavid Li * From page 48 (page 54 of the PDF) of the GLSL 1.10 spec: 5051591693c7b415e9869157c711fe11263c95d74eDavid Li * 5061591693c7b415e9869157c711fe11263c95d74eDavid Li * "Unlike user-defined varying variables, the built-in 5071591693c7b415e9869157c711fe11263c95d74eDavid Li * varying variables don't have a strict one-to-one 5081591693c7b415e9869157c711fe11263c95d74eDavid Li * correspondence between the vertex language and the 5091591693c7b415e9869157c711fe11263c95d74eDavid Li * fragment language." 5101591693c7b415e9869157c711fe11263c95d74eDavid Li */ 5111591693c7b415e9869157c711fe11263c95d74eDavid Li if (!output->type->is_array() 5121591693c7b415e9869157c711fe11263c95d74eDavid Li || (strncmp("gl_", output->name, 3) != 0)) { 5131591693c7b415e9869157c711fe11263c95d74eDavid Li linker_error_printf(prog, 5141591693c7b415e9869157c711fe11263c95d74eDavid Li "%s shader output `%s' declared as " 5151591693c7b415e9869157c711fe11263c95d74eDavid Li "type `%s', but %s shader input declared " 5161591693c7b415e9869157c711fe11263c95d74eDavid Li "as type `%s'\n", 5171591693c7b415e9869157c711fe11263c95d74eDavid Li producer_stage, output->name, 5181591693c7b415e9869157c711fe11263c95d74eDavid Li output->type->name, 5191591693c7b415e9869157c711fe11263c95d74eDavid Li consumer_stage, input->type->name); 5201591693c7b415e9869157c711fe11263c95d74eDavid Li return false; 5211591693c7b415e9869157c711fe11263c95d74eDavid Li } 5221591693c7b415e9869157c711fe11263c95d74eDavid Li } 5231591693c7b415e9869157c711fe11263c95d74eDavid Li 5241591693c7b415e9869157c711fe11263c95d74eDavid Li /* Check that all of the qualifiers match between stages. 5251591693c7b415e9869157c711fe11263c95d74eDavid Li */ 5261591693c7b415e9869157c711fe11263c95d74eDavid Li if (input->centroid != output->centroid) { 5271591693c7b415e9869157c711fe11263c95d74eDavid Li linker_error_printf(prog, 5281591693c7b415e9869157c711fe11263c95d74eDavid Li "%s shader output `%s' %s centroid qualifier, " 5291591693c7b415e9869157c711fe11263c95d74eDavid Li "but %s shader input %s centroid qualifier\n", 5301591693c7b415e9869157c711fe11263c95d74eDavid Li producer_stage, 5311591693c7b415e9869157c711fe11263c95d74eDavid Li output->name, 5321591693c7b415e9869157c711fe11263c95d74eDavid Li (output->centroid) ? "has" : "lacks", 5331591693c7b415e9869157c711fe11263c95d74eDavid Li consumer_stage, 5341591693c7b415e9869157c711fe11263c95d74eDavid Li (input->centroid) ? "has" : "lacks"); 5351591693c7b415e9869157c711fe11263c95d74eDavid Li return false; 5361591693c7b415e9869157c711fe11263c95d74eDavid Li } 5371591693c7b415e9869157c711fe11263c95d74eDavid Li 5381591693c7b415e9869157c711fe11263c95d74eDavid Li if (input->invariant != output->invariant) { 5391591693c7b415e9869157c711fe11263c95d74eDavid Li linker_error_printf(prog, 5401591693c7b415e9869157c711fe11263c95d74eDavid Li "%s shader output `%s' %s invariant qualifier, " 5411591693c7b415e9869157c711fe11263c95d74eDavid Li "but %s shader input %s invariant qualifier\n", 5421591693c7b415e9869157c711fe11263c95d74eDavid Li producer_stage, 5431591693c7b415e9869157c711fe11263c95d74eDavid Li output->name, 5441591693c7b415e9869157c711fe11263c95d74eDavid Li (output->invariant) ? "has" : "lacks", 5451591693c7b415e9869157c711fe11263c95d74eDavid Li consumer_stage, 5461591693c7b415e9869157c711fe11263c95d74eDavid Li (input->invariant) ? "has" : "lacks"); 5471591693c7b415e9869157c711fe11263c95d74eDavid Li return false; 5481591693c7b415e9869157c711fe11263c95d74eDavid Li } 5491591693c7b415e9869157c711fe11263c95d74eDavid Li 5501591693c7b415e9869157c711fe11263c95d74eDavid Li if (input->interpolation != output->interpolation) { 5511591693c7b415e9869157c711fe11263c95d74eDavid Li linker_error_printf(prog, 5521591693c7b415e9869157c711fe11263c95d74eDavid Li "%s shader output `%s' specifies %s " 5531591693c7b415e9869157c711fe11263c95d74eDavid Li "interpolation qualifier, " 5541591693c7b415e9869157c711fe11263c95d74eDavid Li "but %s shader input specifies %s " 5551591693c7b415e9869157c711fe11263c95d74eDavid Li "interpolation qualifier\n", 5561591693c7b415e9869157c711fe11263c95d74eDavid Li producer_stage, 5571591693c7b415e9869157c711fe11263c95d74eDavid Li output->name, 5581591693c7b415e9869157c711fe11263c95d74eDavid Li output->interpolation_string(), 5591591693c7b415e9869157c711fe11263c95d74eDavid Li consumer_stage, 5601591693c7b415e9869157c711fe11263c95d74eDavid Li input->interpolation_string()); 5611591693c7b415e9869157c711fe11263c95d74eDavid Li return false; 5621591693c7b415e9869157c711fe11263c95d74eDavid Li } 5631591693c7b415e9869157c711fe11263c95d74eDavid Li } 5641591693c7b415e9869157c711fe11263c95d74eDavid Li } 5651591693c7b415e9869157c711fe11263c95d74eDavid Li 5661591693c7b415e9869157c711fe11263c95d74eDavid Li return true; 5671591693c7b415e9869157c711fe11263c95d74eDavid Li} 5681591693c7b415e9869157c711fe11263c95d74eDavid Li 5691591693c7b415e9869157c711fe11263c95d74eDavid Li 5701591693c7b415e9869157c711fe11263c95d74eDavid Li/** 5711591693c7b415e9869157c711fe11263c95d74eDavid Li * Populates a shaders symbol table with all global declarations 5721591693c7b415e9869157c711fe11263c95d74eDavid Li */ 5731591693c7b415e9869157c711fe11263c95d74eDavid Listatic void 5741591693c7b415e9869157c711fe11263c95d74eDavid Lipopulate_symbol_table(gl_shader *sh) 5751591693c7b415e9869157c711fe11263c95d74eDavid Li{ 5763b02c91d7b1fcc777dbdafeb044e0df61e1ff0d8David Li sh->symbols = new(sh) glsl_symbol_table(sh); 5771591693c7b415e9869157c711fe11263c95d74eDavid Li 5781591693c7b415e9869157c711fe11263c95d74eDavid Li foreach_list(node, sh->ir) { 5791591693c7b415e9869157c711fe11263c95d74eDavid Li ir_instruction *const inst = (ir_instruction *) node; 5801591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *var; 5811591693c7b415e9869157c711fe11263c95d74eDavid Li ir_function *func; 5821591693c7b415e9869157c711fe11263c95d74eDavid Li 5831591693c7b415e9869157c711fe11263c95d74eDavid Li if ((func = inst->as_function()) != NULL) { 5841591693c7b415e9869157c711fe11263c95d74eDavid Li sh->symbols->add_function(func); 5851591693c7b415e9869157c711fe11263c95d74eDavid Li } else if ((var = inst->as_variable()) != NULL) { 5861591693c7b415e9869157c711fe11263c95d74eDavid Li sh->symbols->add_variable(var); 5871591693c7b415e9869157c711fe11263c95d74eDavid Li } 5881591693c7b415e9869157c711fe11263c95d74eDavid Li } 5891591693c7b415e9869157c711fe11263c95d74eDavid Li} 5901591693c7b415e9869157c711fe11263c95d74eDavid Li 5911591693c7b415e9869157c711fe11263c95d74eDavid Li 5921591693c7b415e9869157c711fe11263c95d74eDavid Li/** 5931591693c7b415e9869157c711fe11263c95d74eDavid Li * Remap variables referenced in an instruction tree 5941591693c7b415e9869157c711fe11263c95d74eDavid Li * 5951591693c7b415e9869157c711fe11263c95d74eDavid Li * This is used when instruction trees are cloned from one shader and placed in 5961591693c7b415e9869157c711fe11263c95d74eDavid Li * another. These trees will contain references to \c ir_variable nodes that 5971591693c7b415e9869157c711fe11263c95d74eDavid Li * do not exist in the target shader. This function finds these \c ir_variable 5981591693c7b415e9869157c711fe11263c95d74eDavid Li * references and replaces the references with matching variables in the target 5991591693c7b415e9869157c711fe11263c95d74eDavid Li * shader. 6001591693c7b415e9869157c711fe11263c95d74eDavid Li * 6011591693c7b415e9869157c711fe11263c95d74eDavid Li * If there is no matching variable in the target shader, a clone of the 6021591693c7b415e9869157c711fe11263c95d74eDavid Li * \c ir_variable is made and added to the target shader. The new variable is 6031591693c7b415e9869157c711fe11263c95d74eDavid Li * added to \b both the instruction stream and the symbol table. 6041591693c7b415e9869157c711fe11263c95d74eDavid Li * 6051591693c7b415e9869157c711fe11263c95d74eDavid Li * \param inst IR tree that is to be processed. 6061591693c7b415e9869157c711fe11263c95d74eDavid Li * \param symbols Symbol table containing global scope symbols in the 6071591693c7b415e9869157c711fe11263c95d74eDavid Li * linked shader. 6081591693c7b415e9869157c711fe11263c95d74eDavid Li * \param instructions Instruction stream where new variable declarations 6091591693c7b415e9869157c711fe11263c95d74eDavid Li * should be added. 6101591693c7b415e9869157c711fe11263c95d74eDavid Li */ 6111591693c7b415e9869157c711fe11263c95d74eDavid Livoid 6121591693c7b415e9869157c711fe11263c95d74eDavid Liremap_variables(ir_instruction *inst, struct gl_shader *target, 6131591693c7b415e9869157c711fe11263c95d74eDavid Li hash_table *temps) 6141591693c7b415e9869157c711fe11263c95d74eDavid Li{ 6151591693c7b415e9869157c711fe11263c95d74eDavid Li class remap_visitor : public ir_hierarchical_visitor { 6161591693c7b415e9869157c711fe11263c95d74eDavid Li public: 6171591693c7b415e9869157c711fe11263c95d74eDavid Li remap_visitor(struct gl_shader *target, 6181591693c7b415e9869157c711fe11263c95d74eDavid Li hash_table *temps) 6191591693c7b415e9869157c711fe11263c95d74eDavid Li { 6201591693c7b415e9869157c711fe11263c95d74eDavid Li this->target = target; 6211591693c7b415e9869157c711fe11263c95d74eDavid Li this->symbols = target->symbols; 6221591693c7b415e9869157c711fe11263c95d74eDavid Li this->instructions = target->ir; 6231591693c7b415e9869157c711fe11263c95d74eDavid Li this->temps = temps; 6241591693c7b415e9869157c711fe11263c95d74eDavid Li } 6251591693c7b415e9869157c711fe11263c95d74eDavid Li 6264f054616c70eb5bb1eb711d5bdf6f4c71ac3b877Conley Owens using ir_hierarchical_visitor::visit; 6271591693c7b415e9869157c711fe11263c95d74eDavid Li virtual ir_visitor_status visit(ir_dereference_variable *ir) 6281591693c7b415e9869157c711fe11263c95d74eDavid Li { 6291591693c7b415e9869157c711fe11263c95d74eDavid Li if (ir->var->mode == ir_var_temporary) { 6301591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *var = (ir_variable *) hash_table_find(temps, ir->var); 6311591693c7b415e9869157c711fe11263c95d74eDavid Li 6321591693c7b415e9869157c711fe11263c95d74eDavid Li assert(var != NULL); 6331591693c7b415e9869157c711fe11263c95d74eDavid Li ir->var = var; 6341591693c7b415e9869157c711fe11263c95d74eDavid Li return visit_continue; 6351591693c7b415e9869157c711fe11263c95d74eDavid Li } 6361591693c7b415e9869157c711fe11263c95d74eDavid Li 6371591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *const existing = 6381591693c7b415e9869157c711fe11263c95d74eDavid Li this->symbols->get_variable(ir->var->name); 6391591693c7b415e9869157c711fe11263c95d74eDavid Li if (existing != NULL) 6401591693c7b415e9869157c711fe11263c95d74eDavid Li ir->var = existing; 6411591693c7b415e9869157c711fe11263c95d74eDavid Li else { 6421591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *copy = ir->var->clone(this->target, NULL); 6431591693c7b415e9869157c711fe11263c95d74eDavid Li 6441591693c7b415e9869157c711fe11263c95d74eDavid Li this->symbols->add_variable(copy); 6451591693c7b415e9869157c711fe11263c95d74eDavid Li this->instructions->push_head(copy); 6461591693c7b415e9869157c711fe11263c95d74eDavid Li ir->var = copy; 6471591693c7b415e9869157c711fe11263c95d74eDavid Li } 6481591693c7b415e9869157c711fe11263c95d74eDavid Li 6491591693c7b415e9869157c711fe11263c95d74eDavid Li return visit_continue; 6501591693c7b415e9869157c711fe11263c95d74eDavid Li } 6511591693c7b415e9869157c711fe11263c95d74eDavid Li 6521591693c7b415e9869157c711fe11263c95d74eDavid Li private: 6531591693c7b415e9869157c711fe11263c95d74eDavid Li struct gl_shader *target; 6541591693c7b415e9869157c711fe11263c95d74eDavid Li glsl_symbol_table *symbols; 6551591693c7b415e9869157c711fe11263c95d74eDavid Li exec_list *instructions; 6561591693c7b415e9869157c711fe11263c95d74eDavid Li hash_table *temps; 6571591693c7b415e9869157c711fe11263c95d74eDavid Li }; 6581591693c7b415e9869157c711fe11263c95d74eDavid Li 6591591693c7b415e9869157c711fe11263c95d74eDavid Li remap_visitor v(target, temps); 6601591693c7b415e9869157c711fe11263c95d74eDavid Li 6611591693c7b415e9869157c711fe11263c95d74eDavid Li inst->accept(&v); 6621591693c7b415e9869157c711fe11263c95d74eDavid Li} 6631591693c7b415e9869157c711fe11263c95d74eDavid Li 6641591693c7b415e9869157c711fe11263c95d74eDavid Li 6651591693c7b415e9869157c711fe11263c95d74eDavid Li/** 6661591693c7b415e9869157c711fe11263c95d74eDavid Li * Move non-declarations from one instruction stream to another 6671591693c7b415e9869157c711fe11263c95d74eDavid Li * 6681591693c7b415e9869157c711fe11263c95d74eDavid Li * The intended usage pattern of this function is to pass the pointer to the 6691591693c7b415e9869157c711fe11263c95d74eDavid Li * head sentinel of a list (i.e., a pointer to the list cast to an \c exec_node 6701591693c7b415e9869157c711fe11263c95d74eDavid Li * pointer) for \c last and \c false for \c make_copies on the first 6711591693c7b415e9869157c711fe11263c95d74eDavid Li * call. Successive calls pass the return value of the previous call for 6721591693c7b415e9869157c711fe11263c95d74eDavid Li * \c last and \c true for \c make_copies. 6731591693c7b415e9869157c711fe11263c95d74eDavid Li * 6741591693c7b415e9869157c711fe11263c95d74eDavid Li * \param instructions Source instruction stream 6751591693c7b415e9869157c711fe11263c95d74eDavid Li * \param last Instruction after which new instructions should be 6761591693c7b415e9869157c711fe11263c95d74eDavid Li * inserted in the target instruction stream 6771591693c7b415e9869157c711fe11263c95d74eDavid Li * \param make_copies Flag selecting whether instructions in \c instructions 6781591693c7b415e9869157c711fe11263c95d74eDavid Li * should be copied (via \c ir_instruction::clone) into the 6791591693c7b415e9869157c711fe11263c95d74eDavid Li * target list or moved. 6801591693c7b415e9869157c711fe11263c95d74eDavid Li * 6811591693c7b415e9869157c711fe11263c95d74eDavid Li * \return 6821591693c7b415e9869157c711fe11263c95d74eDavid Li * The new "last" instruction in the target instruction stream. This pointer 6831591693c7b415e9869157c711fe11263c95d74eDavid Li * is suitable for use as the \c last parameter of a later call to this 6841591693c7b415e9869157c711fe11263c95d74eDavid Li * function. 6851591693c7b415e9869157c711fe11263c95d74eDavid Li */ 6861591693c7b415e9869157c711fe11263c95d74eDavid Liexec_node * 6871591693c7b415e9869157c711fe11263c95d74eDavid Limove_non_declarations(exec_list *instructions, exec_node *last, 6881591693c7b415e9869157c711fe11263c95d74eDavid Li bool make_copies, gl_shader *target) 6891591693c7b415e9869157c711fe11263c95d74eDavid Li{ 6901591693c7b415e9869157c711fe11263c95d74eDavid Li hash_table *temps = NULL; 6911591693c7b415e9869157c711fe11263c95d74eDavid Li 6921591693c7b415e9869157c711fe11263c95d74eDavid Li if (make_copies) 6931591693c7b415e9869157c711fe11263c95d74eDavid Li temps = hash_table_ctor(0, hash_table_pointer_hash, 6941591693c7b415e9869157c711fe11263c95d74eDavid Li hash_table_pointer_compare); 6951591693c7b415e9869157c711fe11263c95d74eDavid Li 6961591693c7b415e9869157c711fe11263c95d74eDavid Li foreach_list_safe(node, instructions) { 6971591693c7b415e9869157c711fe11263c95d74eDavid Li ir_instruction *inst = (ir_instruction *) node; 6981591693c7b415e9869157c711fe11263c95d74eDavid Li 6991591693c7b415e9869157c711fe11263c95d74eDavid Li if (inst->as_function()) 7001591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 7011591693c7b415e9869157c711fe11263c95d74eDavid Li 7021591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *var = inst->as_variable(); 7031591693c7b415e9869157c711fe11263c95d74eDavid Li if ((var != NULL) && (var->mode != ir_var_temporary)) 7041591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 7051591693c7b415e9869157c711fe11263c95d74eDavid Li 7061591693c7b415e9869157c711fe11263c95d74eDavid Li assert(inst->as_assignment() 7071591693c7b415e9869157c711fe11263c95d74eDavid Li || ((var != NULL) && (var->mode == ir_var_temporary))); 7081591693c7b415e9869157c711fe11263c95d74eDavid Li 7091591693c7b415e9869157c711fe11263c95d74eDavid Li if (make_copies) { 7101591693c7b415e9869157c711fe11263c95d74eDavid Li inst = inst->clone(target, NULL); 7111591693c7b415e9869157c711fe11263c95d74eDavid Li 7121591693c7b415e9869157c711fe11263c95d74eDavid Li if (var != NULL) 7131591693c7b415e9869157c711fe11263c95d74eDavid Li hash_table_insert(temps, inst, var); 7141591693c7b415e9869157c711fe11263c95d74eDavid Li else 7151591693c7b415e9869157c711fe11263c95d74eDavid Li remap_variables(inst, target, temps); 7161591693c7b415e9869157c711fe11263c95d74eDavid Li } else { 7171591693c7b415e9869157c711fe11263c95d74eDavid Li inst->remove(); 7181591693c7b415e9869157c711fe11263c95d74eDavid Li } 7191591693c7b415e9869157c711fe11263c95d74eDavid Li 7201591693c7b415e9869157c711fe11263c95d74eDavid Li last->insert_after(inst); 7211591693c7b415e9869157c711fe11263c95d74eDavid Li last = inst; 7221591693c7b415e9869157c711fe11263c95d74eDavid Li } 7231591693c7b415e9869157c711fe11263c95d74eDavid Li 7241591693c7b415e9869157c711fe11263c95d74eDavid Li if (make_copies) 7251591693c7b415e9869157c711fe11263c95d74eDavid Li hash_table_dtor(temps); 7261591693c7b415e9869157c711fe11263c95d74eDavid Li 7271591693c7b415e9869157c711fe11263c95d74eDavid Li return last; 7281591693c7b415e9869157c711fe11263c95d74eDavid Li} 7291591693c7b415e9869157c711fe11263c95d74eDavid Li 7301591693c7b415e9869157c711fe11263c95d74eDavid Li/** 7311591693c7b415e9869157c711fe11263c95d74eDavid Li * Get the function signature for main from a shader 7321591693c7b415e9869157c711fe11263c95d74eDavid Li */ 7331591693c7b415e9869157c711fe11263c95d74eDavid Listatic ir_function_signature * 7341591693c7b415e9869157c711fe11263c95d74eDavid Liget_main_function_signature(gl_shader *sh) 7351591693c7b415e9869157c711fe11263c95d74eDavid Li{ 7361591693c7b415e9869157c711fe11263c95d74eDavid Li ir_function *const f = sh->symbols->get_function("main"); 7371591693c7b415e9869157c711fe11263c95d74eDavid Li if (f != NULL) { 7381591693c7b415e9869157c711fe11263c95d74eDavid Li exec_list void_parameters; 7391591693c7b415e9869157c711fe11263c95d74eDavid Li 7401591693c7b415e9869157c711fe11263c95d74eDavid Li /* Look for the 'void main()' signature and ensure that it's defined. 7411591693c7b415e9869157c711fe11263c95d74eDavid Li * This keeps the linker from accidentally pick a shader that just 7421591693c7b415e9869157c711fe11263c95d74eDavid Li * contains a prototype for main. 7431591693c7b415e9869157c711fe11263c95d74eDavid Li * 7441591693c7b415e9869157c711fe11263c95d74eDavid Li * We don't have to check for multiple definitions of main (in multiple 7451591693c7b415e9869157c711fe11263c95d74eDavid Li * shaders) because that would have already been caught above. 7461591693c7b415e9869157c711fe11263c95d74eDavid Li */ 7471591693c7b415e9869157c711fe11263c95d74eDavid Li ir_function_signature *sig = f->matching_signature(&void_parameters); 7481591693c7b415e9869157c711fe11263c95d74eDavid Li if ((sig != NULL) && sig->is_defined) { 7491591693c7b415e9869157c711fe11263c95d74eDavid Li return sig; 7501591693c7b415e9869157c711fe11263c95d74eDavid Li } 7511591693c7b415e9869157c711fe11263c95d74eDavid Li } 7521591693c7b415e9869157c711fe11263c95d74eDavid Li 7531591693c7b415e9869157c711fe11263c95d74eDavid Li return NULL; 7541591693c7b415e9869157c711fe11263c95d74eDavid Li} 7551591693c7b415e9869157c711fe11263c95d74eDavid Li 7561591693c7b415e9869157c711fe11263c95d74eDavid Li 7571591693c7b415e9869157c711fe11263c95d74eDavid Li/** 7581591693c7b415e9869157c711fe11263c95d74eDavid Li * Combine a group of shaders for a single stage to generate a linked shader 7591591693c7b415e9869157c711fe11263c95d74eDavid Li * 7601591693c7b415e9869157c711fe11263c95d74eDavid Li * \note 7611591693c7b415e9869157c711fe11263c95d74eDavid Li * If this function is supplied a single shader, it is cloned, and the new 7621591693c7b415e9869157c711fe11263c95d74eDavid Li * shader is returned. 7631591693c7b415e9869157c711fe11263c95d74eDavid Li */ 7641591693c7b415e9869157c711fe11263c95d74eDavid Listatic struct gl_shader * 7651591693c7b415e9869157c711fe11263c95d74eDavid Lilink_intrastage_shaders(void *mem_ctx, 766b341bc8271147be311b77937347f0f3f54aab749David Li const struct gl_context *ctx, 7671591693c7b415e9869157c711fe11263c95d74eDavid Li struct gl_shader_program *prog, 7681591693c7b415e9869157c711fe11263c95d74eDavid Li struct gl_shader **shader_list, 7691591693c7b415e9869157c711fe11263c95d74eDavid Li unsigned num_shaders) 7701591693c7b415e9869157c711fe11263c95d74eDavid Li{ 7711591693c7b415e9869157c711fe11263c95d74eDavid Li /* Check that global variables defined in multiple shaders are consistent. 7721591693c7b415e9869157c711fe11263c95d74eDavid Li */ 7731591693c7b415e9869157c711fe11263c95d74eDavid Li if (!cross_validate_globals(prog, shader_list, num_shaders, false)) 7741591693c7b415e9869157c711fe11263c95d74eDavid Li return NULL; 7751591693c7b415e9869157c711fe11263c95d74eDavid Li 7761591693c7b415e9869157c711fe11263c95d74eDavid Li /* Check that there is only a single definition of each function signature 7771591693c7b415e9869157c711fe11263c95d74eDavid Li * across all shaders. 7781591693c7b415e9869157c711fe11263c95d74eDavid Li */ 7791591693c7b415e9869157c711fe11263c95d74eDavid Li for (unsigned i = 0; i < (num_shaders - 1); i++) { 7801591693c7b415e9869157c711fe11263c95d74eDavid Li foreach_list(node, shader_list[i]->ir) { 7811591693c7b415e9869157c711fe11263c95d74eDavid Li ir_function *const f = ((ir_instruction *) node)->as_function(); 7821591693c7b415e9869157c711fe11263c95d74eDavid Li 7831591693c7b415e9869157c711fe11263c95d74eDavid Li if (f == NULL) 7841591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 7851591693c7b415e9869157c711fe11263c95d74eDavid Li 7861591693c7b415e9869157c711fe11263c95d74eDavid Li for (unsigned j = i + 1; j < num_shaders; j++) { 7871591693c7b415e9869157c711fe11263c95d74eDavid Li ir_function *const other = 7881591693c7b415e9869157c711fe11263c95d74eDavid Li shader_list[j]->symbols->get_function(f->name); 7891591693c7b415e9869157c711fe11263c95d74eDavid Li 7901591693c7b415e9869157c711fe11263c95d74eDavid Li /* If the other shader has no function (and therefore no function 7911591693c7b415e9869157c711fe11263c95d74eDavid Li * signatures) with the same name, skip to the next shader. 7921591693c7b415e9869157c711fe11263c95d74eDavid Li */ 7931591693c7b415e9869157c711fe11263c95d74eDavid Li if (other == NULL) 7941591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 7951591693c7b415e9869157c711fe11263c95d74eDavid Li 7961591693c7b415e9869157c711fe11263c95d74eDavid Li foreach_iter (exec_list_iterator, iter, *f) { 7971591693c7b415e9869157c711fe11263c95d74eDavid Li ir_function_signature *sig = 7981591693c7b415e9869157c711fe11263c95d74eDavid Li (ir_function_signature *) iter.get(); 7991591693c7b415e9869157c711fe11263c95d74eDavid Li 8001591693c7b415e9869157c711fe11263c95d74eDavid Li if (!sig->is_defined || sig->is_builtin) 8011591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 8021591693c7b415e9869157c711fe11263c95d74eDavid Li 8031591693c7b415e9869157c711fe11263c95d74eDavid Li ir_function_signature *other_sig = 8041591693c7b415e9869157c711fe11263c95d74eDavid Li other->exact_matching_signature(& sig->parameters); 8051591693c7b415e9869157c711fe11263c95d74eDavid Li 8061591693c7b415e9869157c711fe11263c95d74eDavid Li if ((other_sig != NULL) && other_sig->is_defined 8071591693c7b415e9869157c711fe11263c95d74eDavid Li && !other_sig->is_builtin) { 8081591693c7b415e9869157c711fe11263c95d74eDavid Li linker_error_printf(prog, 8091591693c7b415e9869157c711fe11263c95d74eDavid Li "function `%s' is multiply defined", 8101591693c7b415e9869157c711fe11263c95d74eDavid Li f->name); 8111591693c7b415e9869157c711fe11263c95d74eDavid Li return NULL; 8121591693c7b415e9869157c711fe11263c95d74eDavid Li } 8131591693c7b415e9869157c711fe11263c95d74eDavid Li } 8141591693c7b415e9869157c711fe11263c95d74eDavid Li } 8151591693c7b415e9869157c711fe11263c95d74eDavid Li } 8161591693c7b415e9869157c711fe11263c95d74eDavid Li } 8171591693c7b415e9869157c711fe11263c95d74eDavid Li 8181591693c7b415e9869157c711fe11263c95d74eDavid Li /* Find the shader that defines main, and make a clone of it. 8191591693c7b415e9869157c711fe11263c95d74eDavid Li * 8201591693c7b415e9869157c711fe11263c95d74eDavid Li * Starting with the clone, search for undefined references. If one is 8211591693c7b415e9869157c711fe11263c95d74eDavid Li * found, find the shader that defines it. Clone the reference and add 8221591693c7b415e9869157c711fe11263c95d74eDavid Li * it to the shader. Repeat until there are no undefined references or 8231591693c7b415e9869157c711fe11263c95d74eDavid Li * until a reference cannot be resolved. 8241591693c7b415e9869157c711fe11263c95d74eDavid Li */ 8251591693c7b415e9869157c711fe11263c95d74eDavid Li gl_shader *main = NULL; 8261591693c7b415e9869157c711fe11263c95d74eDavid Li for (unsigned i = 0; i < num_shaders; i++) { 8271591693c7b415e9869157c711fe11263c95d74eDavid Li if (get_main_function_signature(shader_list[i]) != NULL) { 8281591693c7b415e9869157c711fe11263c95d74eDavid Li main = shader_list[i]; 8291591693c7b415e9869157c711fe11263c95d74eDavid Li break; 8301591693c7b415e9869157c711fe11263c95d74eDavid Li } 8311591693c7b415e9869157c711fe11263c95d74eDavid Li } 8321591693c7b415e9869157c711fe11263c95d74eDavid Li 8331591693c7b415e9869157c711fe11263c95d74eDavid Li if (main == NULL) { 8341591693c7b415e9869157c711fe11263c95d74eDavid Li linker_error_printf(prog, "%s shader lacks `main'\n", 8351591693c7b415e9869157c711fe11263c95d74eDavid Li (shader_list[0]->Type == GL_VERTEX_SHADER) 8361591693c7b415e9869157c711fe11263c95d74eDavid Li ? "vertex" : "fragment"); 8371591693c7b415e9869157c711fe11263c95d74eDavid Li return NULL; 8381591693c7b415e9869157c711fe11263c95d74eDavid Li } 8391591693c7b415e9869157c711fe11263c95d74eDavid Li 840b341bc8271147be311b77937347f0f3f54aab749David Li gl_shader *linked = _mesa_new_shader(prog, 0, main->Type); 8411591693c7b415e9869157c711fe11263c95d74eDavid Li linked->ir = new(linked) exec_list; 8421591693c7b415e9869157c711fe11263c95d74eDavid Li clone_ir_list(mem_ctx, linked->ir, main->ir); 8431591693c7b415e9869157c711fe11263c95d74eDavid Li 8441591693c7b415e9869157c711fe11263c95d74eDavid Li populate_symbol_table(linked); 8451591693c7b415e9869157c711fe11263c95d74eDavid Li 8461591693c7b415e9869157c711fe11263c95d74eDavid Li /* The a pointer to the main function in the final linked shader (i.e., the 8471591693c7b415e9869157c711fe11263c95d74eDavid Li * copy of the original shader that contained the main function). 8481591693c7b415e9869157c711fe11263c95d74eDavid Li */ 8491591693c7b415e9869157c711fe11263c95d74eDavid Li ir_function_signature *const main_sig = get_main_function_signature(linked); 8501591693c7b415e9869157c711fe11263c95d74eDavid Li 8511591693c7b415e9869157c711fe11263c95d74eDavid Li /* Move any instructions other than variable declarations or function 8521591693c7b415e9869157c711fe11263c95d74eDavid Li * declarations into main. 8531591693c7b415e9869157c711fe11263c95d74eDavid Li */ 8541591693c7b415e9869157c711fe11263c95d74eDavid Li exec_node *insertion_point = 8551591693c7b415e9869157c711fe11263c95d74eDavid Li move_non_declarations(linked->ir, (exec_node *) &main_sig->body, false, 8561591693c7b415e9869157c711fe11263c95d74eDavid Li linked); 8571591693c7b415e9869157c711fe11263c95d74eDavid Li 8581591693c7b415e9869157c711fe11263c95d74eDavid Li for (unsigned i = 0; i < num_shaders; i++) { 8591591693c7b415e9869157c711fe11263c95d74eDavid Li if (shader_list[i] == main) 8601591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 8611591693c7b415e9869157c711fe11263c95d74eDavid Li 8621591693c7b415e9869157c711fe11263c95d74eDavid Li insertion_point = move_non_declarations(shader_list[i]->ir, 8631591693c7b415e9869157c711fe11263c95d74eDavid Li insertion_point, true, linked); 8641591693c7b415e9869157c711fe11263c95d74eDavid Li } 8651591693c7b415e9869157c711fe11263c95d74eDavid Li 8661591693c7b415e9869157c711fe11263c95d74eDavid Li /* Resolve initializers for global variables in the linked shader. 8671591693c7b415e9869157c711fe11263c95d74eDavid Li */ 8681591693c7b415e9869157c711fe11263c95d74eDavid Li unsigned num_linking_shaders = num_shaders; 8691591693c7b415e9869157c711fe11263c95d74eDavid Li for (unsigned i = 0; i < num_shaders; i++) 8701591693c7b415e9869157c711fe11263c95d74eDavid Li num_linking_shaders += shader_list[i]->num_builtins_to_link; 8711591693c7b415e9869157c711fe11263c95d74eDavid Li 8721591693c7b415e9869157c711fe11263c95d74eDavid Li gl_shader **linking_shaders = 8731591693c7b415e9869157c711fe11263c95d74eDavid Li (gl_shader **) calloc(num_linking_shaders, sizeof(gl_shader *)); 8741591693c7b415e9869157c711fe11263c95d74eDavid Li 8751591693c7b415e9869157c711fe11263c95d74eDavid Li memcpy(linking_shaders, shader_list, 8761591693c7b415e9869157c711fe11263c95d74eDavid Li sizeof(linking_shaders[0]) * num_shaders); 8771591693c7b415e9869157c711fe11263c95d74eDavid Li 8781591693c7b415e9869157c711fe11263c95d74eDavid Li unsigned idx = num_shaders; 8791591693c7b415e9869157c711fe11263c95d74eDavid Li for (unsigned i = 0; i < num_shaders; i++) { 8801591693c7b415e9869157c711fe11263c95d74eDavid Li memcpy(&linking_shaders[idx], shader_list[i]->builtins_to_link, 8811591693c7b415e9869157c711fe11263c95d74eDavid Li sizeof(linking_shaders[0]) * shader_list[i]->num_builtins_to_link); 8821591693c7b415e9869157c711fe11263c95d74eDavid Li idx += shader_list[i]->num_builtins_to_link; 8831591693c7b415e9869157c711fe11263c95d74eDavid Li } 8841591693c7b415e9869157c711fe11263c95d74eDavid Li 8851591693c7b415e9869157c711fe11263c95d74eDavid Li assert(idx == num_linking_shaders); 8861591693c7b415e9869157c711fe11263c95d74eDavid Li 8871591693c7b415e9869157c711fe11263c95d74eDavid Li if (!link_function_calls(prog, linked, linking_shaders, 8881591693c7b415e9869157c711fe11263c95d74eDavid Li num_linking_shaders)) { 8892ac1cf8a62bcf080b70eaa7c0e4f57d4e8001685David Li _mesa_delete_shader(ctx, linked); 8901591693c7b415e9869157c711fe11263c95d74eDavid Li linked = NULL; 8911591693c7b415e9869157c711fe11263c95d74eDavid Li } 8921591693c7b415e9869157c711fe11263c95d74eDavid Li 8931591693c7b415e9869157c711fe11263c95d74eDavid Li free(linking_shaders); 8941591693c7b415e9869157c711fe11263c95d74eDavid Li 8951591693c7b415e9869157c711fe11263c95d74eDavid Li /* Make a pass over all global variables to ensure that arrays with 8961591693c7b415e9869157c711fe11263c95d74eDavid Li * unspecified sizes have a size specified. The size is inferred from the 8971591693c7b415e9869157c711fe11263c95d74eDavid Li * max_array_access field. 8981591693c7b415e9869157c711fe11263c95d74eDavid Li */ 8991591693c7b415e9869157c711fe11263c95d74eDavid Li if (linked != NULL) { 9001591693c7b415e9869157c711fe11263c95d74eDavid Li foreach_list(node, linked->ir) { 9011591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *const var = ((ir_instruction *) node)->as_variable(); 9021591693c7b415e9869157c711fe11263c95d74eDavid Li 9031591693c7b415e9869157c711fe11263c95d74eDavid Li if (var == NULL) 9041591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 9051591693c7b415e9869157c711fe11263c95d74eDavid Li 9061591693c7b415e9869157c711fe11263c95d74eDavid Li if ((var->mode != ir_var_auto) && (var->mode != ir_var_temporary)) 9071591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 9081591693c7b415e9869157c711fe11263c95d74eDavid Li 9091591693c7b415e9869157c711fe11263c95d74eDavid Li if (!var->type->is_array() || (var->type->length != 0)) 9101591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 9111591693c7b415e9869157c711fe11263c95d74eDavid Li 9121591693c7b415e9869157c711fe11263c95d74eDavid Li const glsl_type *type = 9131591693c7b415e9869157c711fe11263c95d74eDavid Li glsl_type::get_array_instance(var->type->fields.array, 9141591693c7b415e9869157c711fe11263c95d74eDavid Li var->max_array_access); 9151591693c7b415e9869157c711fe11263c95d74eDavid Li 9161591693c7b415e9869157c711fe11263c95d74eDavid Li assert(type != NULL); 9171591693c7b415e9869157c711fe11263c95d74eDavid Li var->type = type; 9181591693c7b415e9869157c711fe11263c95d74eDavid Li } 9191591693c7b415e9869157c711fe11263c95d74eDavid Li } 9201591693c7b415e9869157c711fe11263c95d74eDavid Li 9211591693c7b415e9869157c711fe11263c95d74eDavid Li return linked; 9221591693c7b415e9869157c711fe11263c95d74eDavid Li} 9231591693c7b415e9869157c711fe11263c95d74eDavid Li 9241591693c7b415e9869157c711fe11263c95d74eDavid Li 9251591693c7b415e9869157c711fe11263c95d74eDavid Listruct uniform_node { 9261591693c7b415e9869157c711fe11263c95d74eDavid Li exec_node link; 9271591693c7b415e9869157c711fe11263c95d74eDavid Li struct gl_uniform *u; 9281591693c7b415e9869157c711fe11263c95d74eDavid Li unsigned slots; 9291591693c7b415e9869157c711fe11263c95d74eDavid Li}; 9301591693c7b415e9869157c711fe11263c95d74eDavid Li 9311591693c7b415e9869157c711fe11263c95d74eDavid Li/** 9321591693c7b415e9869157c711fe11263c95d74eDavid Li * Update the sizes of linked shader uniform arrays to the maximum 9331591693c7b415e9869157c711fe11263c95d74eDavid Li * array index used. 9341591693c7b415e9869157c711fe11263c95d74eDavid Li * 9351591693c7b415e9869157c711fe11263c95d74eDavid Li * From page 81 (page 95 of the PDF) of the OpenGL 2.1 spec: 9361591693c7b415e9869157c711fe11263c95d74eDavid Li * 9371591693c7b415e9869157c711fe11263c95d74eDavid Li * If one or more elements of an array are active, 9381591693c7b415e9869157c711fe11263c95d74eDavid Li * GetActiveUniform will return the name of the array in name, 9391591693c7b415e9869157c711fe11263c95d74eDavid Li * subject to the restrictions listed above. The type of the array 9401591693c7b415e9869157c711fe11263c95d74eDavid Li * is returned in type. The size parameter contains the highest 9411591693c7b415e9869157c711fe11263c95d74eDavid Li * array element index used, plus one. The compiler or linker 9421591693c7b415e9869157c711fe11263c95d74eDavid Li * determines the highest index used. There will be only one 9431591693c7b415e9869157c711fe11263c95d74eDavid Li * active uniform reported by the GL per uniform array. 9441591693c7b415e9869157c711fe11263c95d74eDavid Li 9451591693c7b415e9869157c711fe11263c95d74eDavid Li */ 9461591693c7b415e9869157c711fe11263c95d74eDavid Listatic void 9471591693c7b415e9869157c711fe11263c95d74eDavid Liupdate_array_sizes(struct gl_shader_program *prog) 9481591693c7b415e9869157c711fe11263c95d74eDavid Li{ 9491591693c7b415e9869157c711fe11263c95d74eDavid Li for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { 9501591693c7b415e9869157c711fe11263c95d74eDavid Li if (prog->_LinkedShaders[i] == NULL) 9511591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 9521591693c7b415e9869157c711fe11263c95d74eDavid Li 9531591693c7b415e9869157c711fe11263c95d74eDavid Li foreach_list(node, prog->_LinkedShaders[i]->ir) { 9541591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *const var = ((ir_instruction *) node)->as_variable(); 9551591693c7b415e9869157c711fe11263c95d74eDavid Li 9561591693c7b415e9869157c711fe11263c95d74eDavid Li if ((var == NULL) || (var->mode != ir_var_uniform && 9571591693c7b415e9869157c711fe11263c95d74eDavid Li var->mode != ir_var_in && 9581591693c7b415e9869157c711fe11263c95d74eDavid Li var->mode != ir_var_out) || 9591591693c7b415e9869157c711fe11263c95d74eDavid Li !var->type->is_array()) 9601591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 9611591693c7b415e9869157c711fe11263c95d74eDavid Li 9621591693c7b415e9869157c711fe11263c95d74eDavid Li unsigned int size = var->max_array_access; 9631591693c7b415e9869157c711fe11263c95d74eDavid Li for (unsigned j = 0; j < MESA_SHADER_TYPES; j++) { 9641591693c7b415e9869157c711fe11263c95d74eDavid Li if (prog->_LinkedShaders[j] == NULL) 9651591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 9661591693c7b415e9869157c711fe11263c95d74eDavid Li 9671591693c7b415e9869157c711fe11263c95d74eDavid Li foreach_list(node2, prog->_LinkedShaders[j]->ir) { 9681591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *other_var = ((ir_instruction *) node2)->as_variable(); 9691591693c7b415e9869157c711fe11263c95d74eDavid Li if (!other_var) 9701591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 9711591693c7b415e9869157c711fe11263c95d74eDavid Li 9721591693c7b415e9869157c711fe11263c95d74eDavid Li if (strcmp(var->name, other_var->name) == 0 && 9731591693c7b415e9869157c711fe11263c95d74eDavid Li other_var->max_array_access > size) { 9741591693c7b415e9869157c711fe11263c95d74eDavid Li size = other_var->max_array_access; 9751591693c7b415e9869157c711fe11263c95d74eDavid Li } 9761591693c7b415e9869157c711fe11263c95d74eDavid Li } 9771591693c7b415e9869157c711fe11263c95d74eDavid Li } 9781591693c7b415e9869157c711fe11263c95d74eDavid Li 9791591693c7b415e9869157c711fe11263c95d74eDavid Li if (size + 1 != var->type->fields.array->length) { 9801591693c7b415e9869157c711fe11263c95d74eDavid Li var->type = glsl_type::get_array_instance(var->type->fields.array, 9811591693c7b415e9869157c711fe11263c95d74eDavid Li size + 1); 9821591693c7b415e9869157c711fe11263c95d74eDavid Li /* FINISHME: We should update the types of array 9831591693c7b415e9869157c711fe11263c95d74eDavid Li * dereferences of this variable now. 9841591693c7b415e9869157c711fe11263c95d74eDavid Li */ 9851591693c7b415e9869157c711fe11263c95d74eDavid Li } 9861591693c7b415e9869157c711fe11263c95d74eDavid Li } 9871591693c7b415e9869157c711fe11263c95d74eDavid Li } 9881591693c7b415e9869157c711fe11263c95d74eDavid Li} 9891591693c7b415e9869157c711fe11263c95d74eDavid Li 990c0025eb1a3d421c0355a21db9d8ea2bd81278460David Listatic int // returns location assigned 9911591693c7b415e9869157c711fe11263c95d74eDavid Liadd_uniform(void *mem_ctx, exec_list *uniforms, struct hash_table *ht, 9921591693c7b415e9869157c711fe11263c95d74eDavid Li const char *name, const glsl_type *type, GLenum shader_type, 993e82376d380005c21cb70637d42104fcd4d652843David Li unsigned *next_shader_pos, unsigned *total_uniforms, unsigned *next_sampler_pos, unsigned * samplers_used) 9941591693c7b415e9869157c711fe11263c95d74eDavid Li{ 995c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li int index = -1; 9961591693c7b415e9869157c711fe11263c95d74eDavid Li if (type->is_record()) { 9971591693c7b415e9869157c711fe11263c95d74eDavid Li for (unsigned int i = 0; i < type->length; i++) { 998c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li const glsl_type *field_type = type->fields.structure[i].type; 999c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li char *field_name = hieralloc_asprintf(mem_ctx, "%s.%s", name, 10001591693c7b415e9869157c711fe11263c95d74eDavid Li type->fields.structure[i].name); 10011591693c7b415e9869157c711fe11263c95d74eDavid Li 1002c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li int firstIndex = add_uniform(mem_ctx, uniforms, ht, field_name, field_type, 1003e82376d380005c21cb70637d42104fcd4d652843David Li shader_type, next_shader_pos, total_uniforms, next_sampler_pos, samplers_used); 1004c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li if (i == 0) 1005c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li index = firstIndex; 10061591693c7b415e9869157c711fe11263c95d74eDavid Li } 10071591693c7b415e9869157c711fe11263c95d74eDavid Li } else { 10081591693c7b415e9869157c711fe11263c95d74eDavid Li uniform_node *n = (uniform_node *) hash_table_find(ht, name); 10091591693c7b415e9869157c711fe11263c95d74eDavid Li unsigned int vec4_slots; 10101591693c7b415e9869157c711fe11263c95d74eDavid Li const glsl_type *array_elem_type = NULL; 10111591693c7b415e9869157c711fe11263c95d74eDavid Li 10121591693c7b415e9869157c711fe11263c95d74eDavid Li if (type->is_array()) { 1013c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li array_elem_type = type->fields.array; 1014c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li /* Array of structures. */ 1015c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li if (array_elem_type->is_record()) { 1016c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li for (unsigned int i = 0; i < type->length; i++) { 1017c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li char *elem_name = hieralloc_asprintf(mem_ctx, "%s[%d]", name, i); 1018c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li int firstIndex = add_uniform(mem_ctx, uniforms, ht, elem_name, array_elem_type, 1019e82376d380005c21cb70637d42104fcd4d652843David Li shader_type, next_shader_pos, total_uniforms, next_sampler_pos, samplers_used); 1020c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li if (i == 0) 1021c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li index = firstIndex; 1022c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li } 1023c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li return index; 1024c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li } 10251591693c7b415e9869157c711fe11263c95d74eDavid Li } 10261591693c7b415e9869157c711fe11263c95d74eDavid Li 10271591693c7b415e9869157c711fe11263c95d74eDavid Li /* Fix the storage size of samplers at 1 vec4 each. Be sure to pad out 10281591693c7b415e9869157c711fe11263c95d74eDavid Li * vectors to vec4 slots. 10291591693c7b415e9869157c711fe11263c95d74eDavid Li */ 10301591693c7b415e9869157c711fe11263c95d74eDavid Li if (type->is_array()) { 1031c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li if (array_elem_type->is_sampler()) 1032c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li vec4_slots = type->length; 1033c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li else 1034c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li vec4_slots = type->length * array_elem_type->matrix_columns; 1035c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li } else if (type->is_sampler()) 1036c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li vec4_slots = 1; 1037c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li else 1038c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li vec4_slots = type->matrix_columns; 10391591693c7b415e9869157c711fe11263c95d74eDavid Li 10401591693c7b415e9869157c711fe11263c95d74eDavid Li if (n == NULL) { 1041c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li n = (uniform_node *) calloc(1, sizeof(struct uniform_node)); 1042c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li n->u = (gl_uniform *) calloc(1, sizeof(struct gl_uniform)); 1043c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li n->slots = vec4_slots; 1044c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li 1045c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li n->u->Name = strdup(name); 1046c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li n->u->Type = type; 1047c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li n->u->Pos = *next_shader_pos; 1048c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li (*total_uniforms)++; 104936ffccf19c02a54a6dc9952dc9c181d4fda2a020David Li 1050c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li if (type->is_sampler() || (array_elem_type && array_elem_type->is_sampler())) 1051c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li { 1052c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li n->u->Pos = *next_sampler_pos; 1053c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li *next_sampler_pos += vec4_slots; 1054c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li } 1055c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li else 1056c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li (*next_shader_pos) += vec4_slots; 1057c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li hash_table_insert(ht, n, name); 1058c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li uniforms->push_tail(&n->link); 105936ffccf19c02a54a6dc9952dc9c181d4fda2a020David Li } 1060e82376d380005c21cb70637d42104fcd4d652843David Li 1061e82376d380005c21cb70637d42104fcd4d652843David Li if (type->is_sampler() || (array_elem_type && array_elem_type->is_sampler())) 1062e82376d380005c21cb70637d42104fcd4d652843David Li (*samplers_used) |= 1 << n->u->Pos; 1063c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li index = n->u->Pos; 10641591693c7b415e9869157c711fe11263c95d74eDavid Li } 1065c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li return index; 10661591693c7b415e9869157c711fe11263c95d74eDavid Li} 10671591693c7b415e9869157c711fe11263c95d74eDavid Li 10681591693c7b415e9869157c711fe11263c95d74eDavid Livoid 10691591693c7b415e9869157c711fe11263c95d74eDavid Liassign_uniform_locations(struct gl_shader_program *prog) 10701591693c7b415e9869157c711fe11263c95d74eDavid Li{ 10711591693c7b415e9869157c711fe11263c95d74eDavid Li /* */ 10721591693c7b415e9869157c711fe11263c95d74eDavid Li exec_list uniforms; 10731591693c7b415e9869157c711fe11263c95d74eDavid Li unsigned total_uniforms = 0; 107436ffccf19c02a54a6dc9952dc9c181d4fda2a020David Li unsigned next_sampler_pos = 0; // all shaders in prog share same sampler location 10751591693c7b415e9869157c711fe11263c95d74eDavid Li hash_table *ht = hash_table_ctor(32, hash_table_string_hash, 10761591693c7b415e9869157c711fe11263c95d74eDavid Li hash_table_string_compare); 1077c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li void *mem_ctx = hieralloc_new(prog); 1078c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li 1079c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li unsigned next_position = 0; // also number of slots for uniforms 10801591693c7b415e9869157c711fe11263c95d74eDavid Li 10811591693c7b415e9869157c711fe11263c95d74eDavid Li for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { 10821591693c7b415e9869157c711fe11263c95d74eDavid Li if (prog->_LinkedShaders[i] == NULL) 10831591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 10841591693c7b415e9869157c711fe11263c95d74eDavid Li 1085e82376d380005c21cb70637d42104fcd4d652843David Li prog->_LinkedShaders[i]->SamplersUsed = 0; 10861591693c7b415e9869157c711fe11263c95d74eDavid Li foreach_list(node, prog->_LinkedShaders[i]->ir) { 10871591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *const var = ((ir_instruction *) node)->as_variable(); 10881591693c7b415e9869157c711fe11263c95d74eDavid Li 10891591693c7b415e9869157c711fe11263c95d74eDavid Li if ((var == NULL) || (var->mode != ir_var_uniform)) 10901591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 10911591693c7b415e9869157c711fe11263c95d74eDavid Li 10921591693c7b415e9869157c711fe11263c95d74eDavid Li if (strncmp(var->name, "gl_", 3) == 0) { 10931591693c7b415e9869157c711fe11263c95d74eDavid Li /* At the moment, we don't allocate uniform locations for 10941591693c7b415e9869157c711fe11263c95d74eDavid Li * builtin uniforms. It's permitted by spec, and we'll 10951591693c7b415e9869157c711fe11263c95d74eDavid Li * likely switch to doing that at some point, but not yet. 10961591693c7b415e9869157c711fe11263c95d74eDavid Li */ 10971591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 10981591693c7b415e9869157c711fe11263c95d74eDavid Li } 10991591693c7b415e9869157c711fe11263c95d74eDavid Li 1100c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li var->location = add_uniform(mem_ctx, &uniforms, ht, var->name, var->type, 11011591693c7b415e9869157c711fe11263c95d74eDavid Li prog->_LinkedShaders[i]->Type, 1102e82376d380005c21cb70637d42104fcd4d652843David Li &next_position, &total_uniforms, &next_sampler_pos, &prog->_LinkedShaders[i]->SamplersUsed); 11031591693c7b415e9869157c711fe11263c95d74eDavid Li } 11041591693c7b415e9869157c711fe11263c95d74eDavid Li } 11051591693c7b415e9869157c711fe11263c95d74eDavid Li 1106c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li gl_uniform_list *ul = hieralloc_zero(prog, gl_uniform_list); 11071591693c7b415e9869157c711fe11263c95d74eDavid Li 11081591693c7b415e9869157c711fe11263c95d74eDavid Li ul->Size = total_uniforms; 11091591693c7b415e9869157c711fe11263c95d74eDavid Li ul->NumUniforms = total_uniforms; 1110c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li ul->Uniforms = (gl_uniform *)hieralloc_zero_size(ul, total_uniforms * sizeof(gl_uniform)); 11111591693c7b415e9869157c711fe11263c95d74eDavid Li 11121591693c7b415e9869157c711fe11263c95d74eDavid Li unsigned idx = 0; 11131591693c7b415e9869157c711fe11263c95d74eDavid Li uniform_node *next; 11141591693c7b415e9869157c711fe11263c95d74eDavid Li for (uniform_node *node = (uniform_node *) uniforms.head 11151591693c7b415e9869157c711fe11263c95d74eDavid Li ; node->link.next != NULL 11161591693c7b415e9869157c711fe11263c95d74eDavid Li ; node = next) { 11171591693c7b415e9869157c711fe11263c95d74eDavid Li next = (uniform_node *) node->link.next; 11181591693c7b415e9869157c711fe11263c95d74eDavid Li 11191591693c7b415e9869157c711fe11263c95d74eDavid Li node->link.remove(); 11201591693c7b415e9869157c711fe11263c95d74eDavid Li memcpy(&ul->Uniforms[idx], node->u, sizeof(gl_uniform)); 11211591693c7b415e9869157c711fe11263c95d74eDavid Li idx++; 11221591693c7b415e9869157c711fe11263c95d74eDavid Li 11231591693c7b415e9869157c711fe11263c95d74eDavid Li free(node->u); 11241591693c7b415e9869157c711fe11263c95d74eDavid Li free(node); 11251591693c7b415e9869157c711fe11263c95d74eDavid Li } 11261591693c7b415e9869157c711fe11263c95d74eDavid Li 11271591693c7b415e9869157c711fe11263c95d74eDavid Li hash_table_dtor(ht); 11281591693c7b415e9869157c711fe11263c95d74eDavid Li 11291591693c7b415e9869157c711fe11263c95d74eDavid Li prog->Uniforms = ul; 1130c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li prog->Uniforms->Slots = next_position; 113101e6ff90560d588418e706ce4d2a16d5a15520e5David Li prog->Uniforms->SamplerSlots = next_sampler_pos; 1132c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li 1133c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li hieralloc_free(mem_ctx); 11341591693c7b415e9869157c711fe11263c95d74eDavid Li} 11351591693c7b415e9869157c711fe11263c95d74eDavid Li 11361591693c7b415e9869157c711fe11263c95d74eDavid Li 11371591693c7b415e9869157c711fe11263c95d74eDavid Li/** 11381591693c7b415e9869157c711fe11263c95d74eDavid Li * Find a contiguous set of available bits in a bitmask 11391591693c7b415e9869157c711fe11263c95d74eDavid Li * 11401591693c7b415e9869157c711fe11263c95d74eDavid Li * \param used_mask Bits representing used (1) and unused (0) locations 11411591693c7b415e9869157c711fe11263c95d74eDavid Li * \param needed_count Number of contiguous bits needed. 11421591693c7b415e9869157c711fe11263c95d74eDavid Li * 11431591693c7b415e9869157c711fe11263c95d74eDavid Li * \return 11441591693c7b415e9869157c711fe11263c95d74eDavid Li * Base location of the available bits on success or -1 on failure. 11451591693c7b415e9869157c711fe11263c95d74eDavid Li */ 11461591693c7b415e9869157c711fe11263c95d74eDavid Liint 11471591693c7b415e9869157c711fe11263c95d74eDavid Lifind_available_slots(unsigned used_mask, unsigned needed_count) 11481591693c7b415e9869157c711fe11263c95d74eDavid Li{ 11491591693c7b415e9869157c711fe11263c95d74eDavid Li unsigned needed_mask = (1 << needed_count) - 1; 11501591693c7b415e9869157c711fe11263c95d74eDavid Li const int max_bit_to_test = (8 * sizeof(used_mask)) - needed_count; 11511591693c7b415e9869157c711fe11263c95d74eDavid Li 11521591693c7b415e9869157c711fe11263c95d74eDavid Li /* The comparison to 32 is redundant, but without it GCC emits "warning: 11531591693c7b415e9869157c711fe11263c95d74eDavid Li * cannot optimize possibly infinite loops" for the loop below. 11541591693c7b415e9869157c711fe11263c95d74eDavid Li */ 11551591693c7b415e9869157c711fe11263c95d74eDavid Li if ((needed_count == 0) || (max_bit_to_test < 0) || (max_bit_to_test > 32)) 11561591693c7b415e9869157c711fe11263c95d74eDavid Li return -1; 11571591693c7b415e9869157c711fe11263c95d74eDavid Li 11581591693c7b415e9869157c711fe11263c95d74eDavid Li for (int i = 0; i <= max_bit_to_test; i++) { 11591591693c7b415e9869157c711fe11263c95d74eDavid Li if ((needed_mask & ~used_mask) == needed_mask) 11601591693c7b415e9869157c711fe11263c95d74eDavid Li return i; 11611591693c7b415e9869157c711fe11263c95d74eDavid Li 11621591693c7b415e9869157c711fe11263c95d74eDavid Li needed_mask <<= 1; 11631591693c7b415e9869157c711fe11263c95d74eDavid Li } 11641591693c7b415e9869157c711fe11263c95d74eDavid Li 11651591693c7b415e9869157c711fe11263c95d74eDavid Li return -1; 11661591693c7b415e9869157c711fe11263c95d74eDavid Li} 11671591693c7b415e9869157c711fe11263c95d74eDavid Li 11681591693c7b415e9869157c711fe11263c95d74eDavid Li 11691591693c7b415e9869157c711fe11263c95d74eDavid Libool 11701591693c7b415e9869157c711fe11263c95d74eDavid Liassign_attribute_locations(gl_shader_program *prog, unsigned max_attribute_index) 11711591693c7b415e9869157c711fe11263c95d74eDavid Li{ 11721591693c7b415e9869157c711fe11263c95d74eDavid Li /* Mark invalid attribute locations as being used. 11731591693c7b415e9869157c711fe11263c95d74eDavid Li */ 11741591693c7b415e9869157c711fe11263c95d74eDavid Li unsigned used_locations = (max_attribute_index >= 32) 11751591693c7b415e9869157c711fe11263c95d74eDavid Li ? ~0 : ~((1 << max_attribute_index) - 1); 11761591693c7b415e9869157c711fe11263c95d74eDavid Li 11771591693c7b415e9869157c711fe11263c95d74eDavid Li gl_shader *const sh = prog->_LinkedShaders[0]; 11781591693c7b415e9869157c711fe11263c95d74eDavid Li assert(sh->Type == GL_VERTEX_SHADER); 11793225321119408735f16b72b539c9fb7d80683552David Li prog->VaryingSlots = 0; 11801591693c7b415e9869157c711fe11263c95d74eDavid Li /* Operate in a total of four passes. 11811591693c7b415e9869157c711fe11263c95d74eDavid Li * 1182c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li * 1. Invalidate the location assignments for all vertex shader inputs, 1183c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li * except for explicit_location and glBindAttribLocation 11841591693c7b415e9869157c711fe11263c95d74eDavid Li * 11851591693c7b415e9869157c711fe11263c95d74eDavid Li * 2. Assign locations for inputs that have user-defined (via 11861591693c7b415e9869157c711fe11263c95d74eDavid Li * glBindVertexAttribLocation) locatoins. 11871591693c7b415e9869157c711fe11263c95d74eDavid Li * 11881591693c7b415e9869157c711fe11263c95d74eDavid Li * 3. Sort the attributes without assigned locations by number of slots 11891591693c7b415e9869157c711fe11263c95d74eDavid Li * required in decreasing order. Fragmentation caused by attribute 11901591693c7b415e9869157c711fe11263c95d74eDavid Li * locations assigned by the application may prevent large attributes 11911591693c7b415e9869157c711fe11263c95d74eDavid Li * from having enough contiguous space. 11921591693c7b415e9869157c711fe11263c95d74eDavid Li * 11931591693c7b415e9869157c711fe11263c95d74eDavid Li * 4. Assign locations to any inputs without assigned locations. 11941591693c7b415e9869157c711fe11263c95d74eDavid Li */ 11951591693c7b415e9869157c711fe11263c95d74eDavid Li if (prog->Attributes != NULL) { 1196c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li // declare attributes if they haven't been already by BindAttribLocation 1197c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li gl_program_parameter_list * attributes = prog->Attributes; 1198c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li foreach_list(node, sh->ir) { 1199c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li ir_variable *const var = ((ir_instruction *) node)->as_variable(); 1200c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li if ((var == NULL) || (var->mode != ir_var_in)) 1201c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li continue; 1202c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li if (_mesa_get_parameter(attributes, var->name) < 0) 1203c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li _mesa_add_parameter(attributes, var->name); 1204c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li } 1205c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li 1206c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li for (unsigned i = 0; i < attributes->NumParameters; i++) { 1207c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li gl_program_parameter * param = attributes->Parameters + i; 1208c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li ir_variable * const var = sh->symbols->get_variable(param->Name); 1209c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li if (!var || ir_var_in != var->mode) 1210c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li continue; 1211c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li 1212c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li if (param->BindLocation >= 0 && !var->explicit_location) 1213c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li var->location = param->Location = param->BindLocation; 1214c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li else if (var->explicit_location) 1215c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li param->Location = var->location; 1216c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li else 1217c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li var->location = -1; 1218c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li const unsigned slots = count_attribute_slots(var->type); 1219c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li param->Slots = slots; 1220c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li if (0 > var->location) 1221c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li continue; 1222c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li /* From page 61 of the OpenGL 4.0 spec: 12231591693c7b415e9869157c711fe11263c95d74eDavid Li * 12241591693c7b415e9869157c711fe11263c95d74eDavid Li * "LinkProgram will fail if the attribute bindings assigned by 12251591693c7b415e9869157c711fe11263c95d74eDavid Li * BindAttribLocation do not leave not enough space to assign a 12261591693c7b415e9869157c711fe11263c95d74eDavid Li * location for an active matrix attribute or an active attribute 12271591693c7b415e9869157c711fe11263c95d74eDavid Li * array, both of which require multiple contiguous generic 12281591693c7b415e9869157c711fe11263c95d74eDavid Li * attributes." 12291591693c7b415e9869157c711fe11263c95d74eDavid Li * 12301591693c7b415e9869157c711fe11263c95d74eDavid Li * Previous versions of the spec contain similar language but omit the 12311591693c7b415e9869157c711fe11263c95d74eDavid Li * bit about attribute arrays. 12321591693c7b415e9869157c711fe11263c95d74eDavid Li * 12331591693c7b415e9869157c711fe11263c95d74eDavid Li * Page 61 of the OpenGL 4.0 spec also says: 12341591693c7b415e9869157c711fe11263c95d74eDavid Li * 12351591693c7b415e9869157c711fe11263c95d74eDavid Li * "It is possible for an application to bind more than one 12361591693c7b415e9869157c711fe11263c95d74eDavid Li * attribute name to the same location. This is referred to as 12371591693c7b415e9869157c711fe11263c95d74eDavid Li * aliasing. This will only work if only one of the aliased 12381591693c7b415e9869157c711fe11263c95d74eDavid Li * attributes is active in the executable program, or if no path 12391591693c7b415e9869157c711fe11263c95d74eDavid Li * through the shader consumes more than one attribute of a set 12401591693c7b415e9869157c711fe11263c95d74eDavid Li * of attributes aliased to the same location. A link error can 12411591693c7b415e9869157c711fe11263c95d74eDavid Li * occur if the linker determines that every path through the 12421591693c7b415e9869157c711fe11263c95d74eDavid Li * shader consumes multiple aliased attributes, but 12431591693c7b415e9869157c711fe11263c95d74eDavid Li * implementations are not required to generate an error in this 12441591693c7b415e9869157c711fe11263c95d74eDavid Li * case." 12451591693c7b415e9869157c711fe11263c95d74eDavid Li * 12461591693c7b415e9869157c711fe11263c95d74eDavid Li * These two paragraphs are either somewhat contradictory, or I don't 12471591693c7b415e9869157c711fe11263c95d74eDavid Li * fully understand one or both of them. 12481591693c7b415e9869157c711fe11263c95d74eDavid Li */ 12491591693c7b415e9869157c711fe11263c95d74eDavid Li /* FINISHME: The code as currently written does not support attribute 12501591693c7b415e9869157c711fe11263c95d74eDavid Li * FINISHME: location aliasing (see comment above). 12511591693c7b415e9869157c711fe11263c95d74eDavid Li */ 1252c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li const int attr = param->Location; 12531591693c7b415e9869157c711fe11263c95d74eDavid Li /* Mask representing the contiguous slots that will be used by this 12541591693c7b415e9869157c711fe11263c95d74eDavid Li * attribute. 12551591693c7b415e9869157c711fe11263c95d74eDavid Li */ 12561591693c7b415e9869157c711fe11263c95d74eDavid Li const unsigned use_mask = (1 << slots) - 1; 12571591693c7b415e9869157c711fe11263c95d74eDavid Li /* Generate a link error if the set of bits requested for this 12581591693c7b415e9869157c711fe11263c95d74eDavid Li * attribute overlaps any previously allocated bits. 12591591693c7b415e9869157c711fe11263c95d74eDavid Li */ 1260c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li if ((use_mask << attr) & used_locations) { 12611591693c7b415e9869157c711fe11263c95d74eDavid Li linker_error_printf(prog, 12621591693c7b415e9869157c711fe11263c95d74eDavid Li "insufficient contiguous attribute locations " 12631591693c7b415e9869157c711fe11263c95d74eDavid Li "available for vertex shader input `%s'", 12641591693c7b415e9869157c711fe11263c95d74eDavid Li var->name); 12651591693c7b415e9869157c711fe11263c95d74eDavid Li return false; 12661591693c7b415e9869157c711fe11263c95d74eDavid Li } 1267c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li 12681591693c7b415e9869157c711fe11263c95d74eDavid Li used_locations |= (use_mask << attr); 12691591693c7b415e9869157c711fe11263c95d74eDavid Li } 12701591693c7b415e9869157c711fe11263c95d74eDavid Li } 12711591693c7b415e9869157c711fe11263c95d74eDavid Li 12721591693c7b415e9869157c711fe11263c95d74eDavid Li /* Temporary storage for the set of attributes that need locations assigned. 12731591693c7b415e9869157c711fe11263c95d74eDavid Li */ 12741591693c7b415e9869157c711fe11263c95d74eDavid Li struct temp_attr { 12751591693c7b415e9869157c711fe11263c95d74eDavid Li unsigned slots; 12761591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *var; 12771591693c7b415e9869157c711fe11263c95d74eDavid Li 12781591693c7b415e9869157c711fe11263c95d74eDavid Li /* Used below in the call to qsort. */ 12791591693c7b415e9869157c711fe11263c95d74eDavid Li static int compare(const void *a, const void *b) 12801591693c7b415e9869157c711fe11263c95d74eDavid Li { 12811591693c7b415e9869157c711fe11263c95d74eDavid Li const temp_attr *const l = (const temp_attr *) a; 12821591693c7b415e9869157c711fe11263c95d74eDavid Li const temp_attr *const r = (const temp_attr *) b; 12831591693c7b415e9869157c711fe11263c95d74eDavid Li 12841591693c7b415e9869157c711fe11263c95d74eDavid Li /* Reversed because we want a descending order sort below. */ 12851591693c7b415e9869157c711fe11263c95d74eDavid Li return r->slots - l->slots; 12861591693c7b415e9869157c711fe11263c95d74eDavid Li } 12871591693c7b415e9869157c711fe11263c95d74eDavid Li } to_assign[16]; 12881591693c7b415e9869157c711fe11263c95d74eDavid Li 12891591693c7b415e9869157c711fe11263c95d74eDavid Li unsigned num_attr = 0; 12901591693c7b415e9869157c711fe11263c95d74eDavid Li 12911591693c7b415e9869157c711fe11263c95d74eDavid Li foreach_list(node, sh->ir) { 12921591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *const var = ((ir_instruction *) node)->as_variable(); 12931591693c7b415e9869157c711fe11263c95d74eDavid Li if ((var == NULL) || (var->mode != ir_var_in)) 1294c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li continue; 12951591693c7b415e9869157c711fe11263c95d74eDavid Li if (var->explicit_location) { 12961591693c7b415e9869157c711fe11263c95d74eDavid Li const unsigned slots = count_attribute_slots(var->type); 12971591693c7b415e9869157c711fe11263c95d74eDavid Li const unsigned use_mask = (1 << slots) - 1; 1298c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li const int attr = var->location/* - VERT_ATTRIB_GENERIC0*/; 12991591693c7b415e9869157c711fe11263c95d74eDavid Li 1300c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li if ((var->location >= (int)(max_attribute_index/* + VERT_ATTRIB_GENERIC0*/)) 13011591693c7b415e9869157c711fe11263c95d74eDavid Li || (var->location < 0)) { 13021591693c7b415e9869157c711fe11263c95d74eDavid Li linker_error_printf(prog, 13031591693c7b415e9869157c711fe11263c95d74eDavid Li "invalid explicit location %d specified for " 13041591693c7b415e9869157c711fe11263c95d74eDavid Li "`%s'\n", 13051591693c7b415e9869157c711fe11263c95d74eDavid Li (var->location < 0) ? var->location : attr, 13061591693c7b415e9869157c711fe11263c95d74eDavid Li var->name); 13071591693c7b415e9869157c711fe11263c95d74eDavid Li return false; 1308c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li } else if (var->location >= 0/*VERT_ATTRIB_GENERIC0*/) { 13091591693c7b415e9869157c711fe11263c95d74eDavid Li used_locations |= (use_mask << attr); 13101591693c7b415e9869157c711fe11263c95d74eDavid Li } 13111591693c7b415e9869157c711fe11263c95d74eDavid Li } 13121591693c7b415e9869157c711fe11263c95d74eDavid Li 13131591693c7b415e9869157c711fe11263c95d74eDavid Li /* The location was explicitly assigned, nothing to do here. 13141591693c7b415e9869157c711fe11263c95d74eDavid Li */ 13151591693c7b415e9869157c711fe11263c95d74eDavid Li if (var->location != -1) 13161591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 13171591693c7b415e9869157c711fe11263c95d74eDavid Li 13181591693c7b415e9869157c711fe11263c95d74eDavid Li to_assign[num_attr].slots = count_attribute_slots(var->type); 13191591693c7b415e9869157c711fe11263c95d74eDavid Li to_assign[num_attr].var = var; 13201591693c7b415e9869157c711fe11263c95d74eDavid Li num_attr++; 13211591693c7b415e9869157c711fe11263c95d74eDavid Li } 13221591693c7b415e9869157c711fe11263c95d74eDavid Li 13231591693c7b415e9869157c711fe11263c95d74eDavid Li /* If all of the attributes were assigned locations by the application (or 13241591693c7b415e9869157c711fe11263c95d74eDavid Li * are built-in attributes with fixed locations), return early. This should 13251591693c7b415e9869157c711fe11263c95d74eDavid Li * be the common case. 13261591693c7b415e9869157c711fe11263c95d74eDavid Li */ 13271591693c7b415e9869157c711fe11263c95d74eDavid Li if (num_attr == 0) 13281591693c7b415e9869157c711fe11263c95d74eDavid Li return true; 13291591693c7b415e9869157c711fe11263c95d74eDavid Li 13301591693c7b415e9869157c711fe11263c95d74eDavid Li qsort(to_assign, num_attr, sizeof(to_assign[0]), temp_attr::compare); 13311591693c7b415e9869157c711fe11263c95d74eDavid Li 13321591693c7b415e9869157c711fe11263c95d74eDavid Li /* VERT_ATTRIB_GENERIC0 is a psdueo-alias for VERT_ATTRIB_POS. It can only 13331591693c7b415e9869157c711fe11263c95d74eDavid Li * be explicitly assigned by via glBindAttribLocation. Mark it as reserved 13341591693c7b415e9869157c711fe11263c95d74eDavid Li * to prevent it from being automatically allocated below. 13351591693c7b415e9869157c711fe11263c95d74eDavid Li */ 13361591693c7b415e9869157c711fe11263c95d74eDavid Li find_deref_visitor find("gl_Vertex"); 13371591693c7b415e9869157c711fe11263c95d74eDavid Li find.run(sh->ir); 13381591693c7b415e9869157c711fe11263c95d74eDavid Li if (find.variable_found()) 13391591693c7b415e9869157c711fe11263c95d74eDavid Li used_locations |= (1 << 0); 13401591693c7b415e9869157c711fe11263c95d74eDavid Li 13411591693c7b415e9869157c711fe11263c95d74eDavid Li for (unsigned i = 0; i < num_attr; i++) { 13421591693c7b415e9869157c711fe11263c95d74eDavid Li /* Mask representing the contiguous slots that will be used by this 13431591693c7b415e9869157c711fe11263c95d74eDavid Li * attribute. 13441591693c7b415e9869157c711fe11263c95d74eDavid Li */ 13451591693c7b415e9869157c711fe11263c95d74eDavid Li const unsigned use_mask = (1 << to_assign[i].slots) - 1; 13461591693c7b415e9869157c711fe11263c95d74eDavid Li 13471591693c7b415e9869157c711fe11263c95d74eDavid Li int location = find_available_slots(used_locations, to_assign[i].slots); 13481591693c7b415e9869157c711fe11263c95d74eDavid Li 13491591693c7b415e9869157c711fe11263c95d74eDavid Li if (location < 0) { 13501591693c7b415e9869157c711fe11263c95d74eDavid Li linker_error_printf(prog, 13511591693c7b415e9869157c711fe11263c95d74eDavid Li "insufficient contiguous attribute locations " 13521591693c7b415e9869157c711fe11263c95d74eDavid Li "available for vertex shader input `%s'", 13531591693c7b415e9869157c711fe11263c95d74eDavid Li to_assign[i].var->name); 13541591693c7b415e9869157c711fe11263c95d74eDavid Li return false; 13551591693c7b415e9869157c711fe11263c95d74eDavid Li } 13561591693c7b415e9869157c711fe11263c95d74eDavid Li 1357c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li to_assign[i].var->location = /*VERT_ATTRIB_GENERIC0 +*/ location; 13581591693c7b415e9869157c711fe11263c95d74eDavid Li used_locations |= (use_mask << location); 1359c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li int paramIndex = _mesa_get_parameter(prog->Attributes, to_assign[i].var->name); 1360c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li if (0 <= paramIndex) 1361c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li prog->Attributes->Parameters[paramIndex].Location = location; 13621591693c7b415e9869157c711fe11263c95d74eDavid Li } 13631591693c7b415e9869157c711fe11263c95d74eDavid Li 13641591693c7b415e9869157c711fe11263c95d74eDavid Li return true; 13651591693c7b415e9869157c711fe11263c95d74eDavid Li} 13661591693c7b415e9869157c711fe11263c95d74eDavid Li 13671591693c7b415e9869157c711fe11263c95d74eDavid Li 13681591693c7b415e9869157c711fe11263c95d74eDavid Li/** 13691591693c7b415e9869157c711fe11263c95d74eDavid Li * Demote shader inputs and outputs that are not used in other stages 13701591693c7b415e9869157c711fe11263c95d74eDavid Li */ 13711591693c7b415e9869157c711fe11263c95d74eDavid Livoid 13721591693c7b415e9869157c711fe11263c95d74eDavid Lidemote_shader_inputs_and_outputs(gl_shader *sh, enum ir_variable_mode mode) 13731591693c7b415e9869157c711fe11263c95d74eDavid Li{ 13741591693c7b415e9869157c711fe11263c95d74eDavid Li foreach_list(node, sh->ir) { 13751591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *const var = ((ir_instruction *) node)->as_variable(); 13761591693c7b415e9869157c711fe11263c95d74eDavid Li 13771591693c7b415e9869157c711fe11263c95d74eDavid Li if ((var == NULL) || (var->mode != int(mode))) 13781591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 13791591693c7b415e9869157c711fe11263c95d74eDavid Li 13801591693c7b415e9869157c711fe11263c95d74eDavid Li /* A shader 'in' or 'out' variable is only really an input or output if 13811591693c7b415e9869157c711fe11263c95d74eDavid Li * its value is used by other shader stages. This will cause the variable 13821591693c7b415e9869157c711fe11263c95d74eDavid Li * to have a location assigned. 13831591693c7b415e9869157c711fe11263c95d74eDavid Li */ 13841591693c7b415e9869157c711fe11263c95d74eDavid Li if (var->location == -1) { 13851591693c7b415e9869157c711fe11263c95d74eDavid Li var->mode = ir_var_auto; 13861591693c7b415e9869157c711fe11263c95d74eDavid Li } 13871591693c7b415e9869157c711fe11263c95d74eDavid Li } 13881591693c7b415e9869157c711fe11263c95d74eDavid Li} 13891591693c7b415e9869157c711fe11263c95d74eDavid Li 13901591693c7b415e9869157c711fe11263c95d74eDavid Livoid 13911591693c7b415e9869157c711fe11263c95d74eDavid Liassign_varying_locations(struct gl_shader_program *prog, 13921591693c7b415e9869157c711fe11263c95d74eDavid Li gl_shader *producer, gl_shader *consumer) 13931591693c7b415e9869157c711fe11263c95d74eDavid Li{ 13943225321119408735f16b72b539c9fb7d80683552David Li prog->VaryingSlots = 0; 13953225321119408735f16b72b539c9fb7d80683552David Li prog->UsesFragCoord = false; 13963225321119408735f16b72b539c9fb7d80683552David Li prog->UsesPointCoord = false; 13971591693c7b415e9869157c711fe11263c95d74eDavid Li /* FINISHME: Set dynamically when geometry shader support is added. */ 13983225321119408735f16b72b539c9fb7d80683552David Li unsigned output_index = offsetof(VertexOutput,varyings) / sizeof(Vector4); /*VERT_RESULT_VAR0*/; 13993225321119408735f16b72b539c9fb7d80683552David Li unsigned input_index = offsetof(VertexOutput,varyings) / sizeof(Vector4); 14001591693c7b415e9869157c711fe11263c95d74eDavid Li 14011591693c7b415e9869157c711fe11263c95d74eDavid Li /* Operate in a total of three passes. 14021591693c7b415e9869157c711fe11263c95d74eDavid Li * 14031591693c7b415e9869157c711fe11263c95d74eDavid Li * 1. Assign locations for any matching inputs and outputs. 14041591693c7b415e9869157c711fe11263c95d74eDavid Li * 14051591693c7b415e9869157c711fe11263c95d74eDavid Li * 2. Mark output variables in the producer that do not have locations as 14061591693c7b415e9869157c711fe11263c95d74eDavid Li * not being outputs. This lets the optimizer eliminate them. 14071591693c7b415e9869157c711fe11263c95d74eDavid Li * 14081591693c7b415e9869157c711fe11263c95d74eDavid Li * 3. Mark input variables in the consumer that do not have locations as 14091591693c7b415e9869157c711fe11263c95d74eDavid Li * not being inputs. This lets the optimizer eliminate them. 14101591693c7b415e9869157c711fe11263c95d74eDavid Li */ 1411c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li foreach_list(node, producer->ir) { 1412c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li ir_variable *const var = ((ir_instruction *) node)->as_variable(); 1413c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li if (!var || ir_var_out != var->mode) 1414c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li continue; 1415c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li if (!strcmp("gl_Position", var->name)) 14163225321119408735f16b72b539c9fb7d80683552David Li var->location = offsetof(VertexOutput,position) / sizeof(Vector4); 1417c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li else if (!strcmp("gl_PointSize", var->name)) 14183225321119408735f16b72b539c9fb7d80683552David Li var->location = offsetof(VertexOutput,pointSize) / sizeof(Vector4); 1419c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li else 1420c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li var->location = -1; 1421c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li } 1422c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li foreach_list(node, consumer->ir) { 1423c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li ir_variable *const var = ((ir_instruction *) node)->as_variable(); 1424c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li if (!var || ir_var_in != var->mode) 1425c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li continue; 1426c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li if (!strcmp("gl_FragCoord", var->name)) 14273225321119408735f16b72b539c9fb7d80683552David Li { 14283225321119408735f16b72b539c9fb7d80683552David Li var->location = offsetof(VertexOutput,position)/sizeof(Vector4); 14293225321119408735f16b72b539c9fb7d80683552David Li prog->UsesFragCoord = true; 14303225321119408735f16b72b539c9fb7d80683552David Li } 1431c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li else if (!strcmp("gl_FrontFacing", var->name)) 14323225321119408735f16b72b539c9fb7d80683552David Li var->location = offsetof(VertexOutput,frontFacingPointCoord)/sizeof(Vector4); 1433c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li else if (!strcmp("gl_PointCoord", var->name)) 14343225321119408735f16b72b539c9fb7d80683552David Li { 14353225321119408735f16b72b539c9fb7d80683552David Li var->location = offsetof(VertexOutput,frontFacingPointCoord)/sizeof(Vector4); 14363225321119408735f16b72b539c9fb7d80683552David Li prog->UsesPointCoord = true; 14373225321119408735f16b72b539c9fb7d80683552David Li } 1438c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li else 1439c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li var->location = -1; 1440c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li } 14411591693c7b415e9869157c711fe11263c95d74eDavid Li 14421591693c7b415e9869157c711fe11263c95d74eDavid Li foreach_list(node, producer->ir) { 14431591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *const output_var = ((ir_instruction *) node)->as_variable(); 14441591693c7b415e9869157c711fe11263c95d74eDavid Li 1445c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li if ((output_var == NULL) || (output_var->mode != ir_var_out)) 1446c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li continue; 1447c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li int paramIndex = _mesa_get_parameter(prog->Varying, output_var->name); 1448c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li if (paramIndex < 0) 1449c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li paramIndex = _mesa_add_parameter(prog->Varying, output_var->name); 1450c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li gl_program_parameter * param = prog->Varying->Parameters + paramIndex; 1451c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li if (output_var->location != -1) 1452c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li { 1453c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li param->BindLocation = output_var->location; 1454c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li continue; 1455c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li } 14561591693c7b415e9869157c711fe11263c95d74eDavid Li 14571591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *const input_var = 14581591693c7b415e9869157c711fe11263c95d74eDavid Li consumer->symbols->get_variable(output_var->name); 14591591693c7b415e9869157c711fe11263c95d74eDavid Li 14601591693c7b415e9869157c711fe11263c95d74eDavid Li if ((input_var == NULL) || (input_var->mode != ir_var_in)) 14611591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 14621591693c7b415e9869157c711fe11263c95d74eDavid Li 14631591693c7b415e9869157c711fe11263c95d74eDavid Li assert(input_var->location == -1); 14641591693c7b415e9869157c711fe11263c95d74eDavid Li 1465c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li param->BindLocation = output_var->location = output_index; 1466c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li param->Location = input_var->location = input_index; 14671591693c7b415e9869157c711fe11263c95d74eDavid Li 14681591693c7b415e9869157c711fe11263c95d74eDavid Li /* FINISHME: Support for "varying" records in GLSL 1.50. */ 14691591693c7b415e9869157c711fe11263c95d74eDavid Li assert(!output_var->type->is_record()); 14701591693c7b415e9869157c711fe11263c95d74eDavid Li 14711591693c7b415e9869157c711fe11263c95d74eDavid Li if (output_var->type->is_array()) { 14721591693c7b415e9869157c711fe11263c95d74eDavid Li const unsigned slots = output_var->type->length 14731591693c7b415e9869157c711fe11263c95d74eDavid Li * output_var->type->fields.array->matrix_columns; 14741591693c7b415e9869157c711fe11263c95d74eDavid Li 14751591693c7b415e9869157c711fe11263c95d74eDavid Li output_index += slots; 14761591693c7b415e9869157c711fe11263c95d74eDavid Li input_index += slots; 14773225321119408735f16b72b539c9fb7d80683552David Li prog->VaryingSlots += slots; 14781591693c7b415e9869157c711fe11263c95d74eDavid Li } else { 14791591693c7b415e9869157c711fe11263c95d74eDavid Li const unsigned slots = output_var->type->matrix_columns; 14801591693c7b415e9869157c711fe11263c95d74eDavid Li 14811591693c7b415e9869157c711fe11263c95d74eDavid Li output_index += slots; 14821591693c7b415e9869157c711fe11263c95d74eDavid Li input_index += slots; 14833225321119408735f16b72b539c9fb7d80683552David Li prog->VaryingSlots += slots; 14841591693c7b415e9869157c711fe11263c95d74eDavid Li } 14851591693c7b415e9869157c711fe11263c95d74eDavid Li } 14861591693c7b415e9869157c711fe11263c95d74eDavid Li 14871591693c7b415e9869157c711fe11263c95d74eDavid Li foreach_list(node, consumer->ir) { 14881591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *const var = ((ir_instruction *) node)->as_variable(); 14891591693c7b415e9869157c711fe11263c95d74eDavid Li 14901591693c7b415e9869157c711fe11263c95d74eDavid Li if ((var == NULL) || (var->mode != ir_var_in)) 14911591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 1492c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li int paramIndex = _mesa_get_parameter(prog->Varying, var->name); 1493c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li if (paramIndex < 0) 1494c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li paramIndex = _mesa_add_parameter(prog->Varying, var->name); 1495c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li gl_program_parameter * param = prog->Varying->Parameters + paramIndex; 1496c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li 14971591693c7b415e9869157c711fe11263c95d74eDavid Li if (var->location == -1) { 1498c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li if (prog->Version <= 120) { 14991591693c7b415e9869157c711fe11263c95d74eDavid Li /* On page 25 (page 31 of the PDF) of the GLSL 1.20 spec: 15001591693c7b415e9869157c711fe11263c95d74eDavid Li * 15011591693c7b415e9869157c711fe11263c95d74eDavid Li * Only those varying variables used (i.e. read) in 15021591693c7b415e9869157c711fe11263c95d74eDavid Li * the fragment shader executable must be written to 15031591693c7b415e9869157c711fe11263c95d74eDavid Li * by the vertex shader executable; declaring 15041591693c7b415e9869157c711fe11263c95d74eDavid Li * superfluous varying variables in a vertex shader is 15051591693c7b415e9869157c711fe11263c95d74eDavid Li * permissible. 15061591693c7b415e9869157c711fe11263c95d74eDavid Li * 15071591693c7b415e9869157c711fe11263c95d74eDavid Li * We interpret this text as meaning that the VS must 15081591693c7b415e9869157c711fe11263c95d74eDavid Li * write the variable for the FS to read it. See 15091591693c7b415e9869157c711fe11263c95d74eDavid Li * "glsl1-varying read but not written" in piglit. 15101591693c7b415e9869157c711fe11263c95d74eDavid Li */ 15111591693c7b415e9869157c711fe11263c95d74eDavid Li 1512c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li linker_error_printf(prog, "fragment shader varying %s not written " 1513c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li "by vertex shader\n.", var->name); 1514c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li prog->LinkStatus = false; 1515c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li } 15161591693c7b415e9869157c711fe11263c95d74eDavid Li 15171591693c7b415e9869157c711fe11263c95d74eDavid Li /* An 'in' variable is only really a shader input if its 15181591693c7b415e9869157c711fe11263c95d74eDavid Li * value is written by the previous stage. 15191591693c7b415e9869157c711fe11263c95d74eDavid Li */ 1520c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li var->mode = ir_var_auto; 15211591693c7b415e9869157c711fe11263c95d74eDavid Li } 1522c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li else 1523c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li param->Location = var->location; 15241591693c7b415e9869157c711fe11263c95d74eDavid Li } 15251591693c7b415e9869157c711fe11263c95d74eDavid Li} 15261591693c7b415e9869157c711fe11263c95d74eDavid Li 15271591693c7b415e9869157c711fe11263c95d74eDavid Li 15281591693c7b415e9869157c711fe11263c95d74eDavid Livoid 1529b341bc8271147be311b77937347f0f3f54aab749David Lilink_shaders(const struct gl_context *ctx, struct gl_shader_program *prog) 15301591693c7b415e9869157c711fe11263c95d74eDavid Li{ 153113fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li //void *mem_ctx = hieralloc_init("temporary linker context"); 153213fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li void * mem_ctx = prog; // need linked & cloned ir to persist 15331591693c7b415e9869157c711fe11263c95d74eDavid Li 15341591693c7b415e9869157c711fe11263c95d74eDavid Li prog->LinkStatus = false; 15351591693c7b415e9869157c711fe11263c95d74eDavid Li prog->Validated = false; 15361591693c7b415e9869157c711fe11263c95d74eDavid Li prog->_Used = false; 15371591693c7b415e9869157c711fe11263c95d74eDavid Li 15381591693c7b415e9869157c711fe11263c95d74eDavid Li if (prog->InfoLog != NULL) 1539d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li hieralloc_free(prog->InfoLog); 15401591693c7b415e9869157c711fe11263c95d74eDavid Li 15413b02c91d7b1fcc777dbdafeb044e0df61e1ff0d8David Li prog->InfoLog = hieralloc_strdup(prog, ""); 15421591693c7b415e9869157c711fe11263c95d74eDavid Li 15431591693c7b415e9869157c711fe11263c95d74eDavid Li /* Separate the shaders into groups based on their type. 15441591693c7b415e9869157c711fe11263c95d74eDavid Li */ 15451591693c7b415e9869157c711fe11263c95d74eDavid Li struct gl_shader **vert_shader_list; 15461591693c7b415e9869157c711fe11263c95d74eDavid Li unsigned num_vert_shaders = 0; 15471591693c7b415e9869157c711fe11263c95d74eDavid Li struct gl_shader **frag_shader_list; 15481591693c7b415e9869157c711fe11263c95d74eDavid Li unsigned num_frag_shaders = 0; 15491591693c7b415e9869157c711fe11263c95d74eDavid Li 15501591693c7b415e9869157c711fe11263c95d74eDavid Li vert_shader_list = (struct gl_shader **) 15511591693c7b415e9869157c711fe11263c95d74eDavid Li calloc(2 * prog->NumShaders, sizeof(struct gl_shader *)); 15521591693c7b415e9869157c711fe11263c95d74eDavid Li frag_shader_list = &vert_shader_list[prog->NumShaders]; 15531591693c7b415e9869157c711fe11263c95d74eDavid Li 15541591693c7b415e9869157c711fe11263c95d74eDavid Li unsigned min_version = UINT_MAX; 15551591693c7b415e9869157c711fe11263c95d74eDavid Li unsigned max_version = 0; 15561591693c7b415e9869157c711fe11263c95d74eDavid Li for (unsigned i = 0; i < prog->NumShaders; i++) { 15571591693c7b415e9869157c711fe11263c95d74eDavid Li min_version = MIN2(min_version, prog->Shaders[i]->Version); 15581591693c7b415e9869157c711fe11263c95d74eDavid Li max_version = MAX2(max_version, prog->Shaders[i]->Version); 15591591693c7b415e9869157c711fe11263c95d74eDavid Li 15601591693c7b415e9869157c711fe11263c95d74eDavid Li switch (prog->Shaders[i]->Type) { 15611591693c7b415e9869157c711fe11263c95d74eDavid Li case GL_VERTEX_SHADER: 15621591693c7b415e9869157c711fe11263c95d74eDavid Li vert_shader_list[num_vert_shaders] = prog->Shaders[i]; 15631591693c7b415e9869157c711fe11263c95d74eDavid Li num_vert_shaders++; 15641591693c7b415e9869157c711fe11263c95d74eDavid Li break; 15651591693c7b415e9869157c711fe11263c95d74eDavid Li case GL_FRAGMENT_SHADER: 15661591693c7b415e9869157c711fe11263c95d74eDavid Li frag_shader_list[num_frag_shaders] = prog->Shaders[i]; 15671591693c7b415e9869157c711fe11263c95d74eDavid Li num_frag_shaders++; 15681591693c7b415e9869157c711fe11263c95d74eDavid Li break; 15691591693c7b415e9869157c711fe11263c95d74eDavid Li case GL_GEOMETRY_SHADER: 15701591693c7b415e9869157c711fe11263c95d74eDavid Li /* FINISHME: Support geometry shaders. */ 15711591693c7b415e9869157c711fe11263c95d74eDavid Li assert(prog->Shaders[i]->Type != GL_GEOMETRY_SHADER); 15721591693c7b415e9869157c711fe11263c95d74eDavid Li break; 15731591693c7b415e9869157c711fe11263c95d74eDavid Li } 15741591693c7b415e9869157c711fe11263c95d74eDavid Li } 15751591693c7b415e9869157c711fe11263c95d74eDavid Li 15761591693c7b415e9869157c711fe11263c95d74eDavid Li /* Previous to GLSL version 1.30, different compilation units could mix and 15771591693c7b415e9869157c711fe11263c95d74eDavid Li * match shading language versions. With GLSL 1.30 and later, the versions 15781591693c7b415e9869157c711fe11263c95d74eDavid Li * of all shaders must match. 15791591693c7b415e9869157c711fe11263c95d74eDavid Li */ 15801591693c7b415e9869157c711fe11263c95d74eDavid Li assert(min_version >= 100); 15811591693c7b415e9869157c711fe11263c95d74eDavid Li assert(max_version <= 130); 15821591693c7b415e9869157c711fe11263c95d74eDavid Li if ((max_version >= 130 || min_version == 100) 15831591693c7b415e9869157c711fe11263c95d74eDavid Li && min_version != max_version) { 15841591693c7b415e9869157c711fe11263c95d74eDavid Li linker_error_printf(prog, "all shaders must use same shading " 15851591693c7b415e9869157c711fe11263c95d74eDavid Li "language version\n"); 15861591693c7b415e9869157c711fe11263c95d74eDavid Li goto done; 15871591693c7b415e9869157c711fe11263c95d74eDavid Li } 15881591693c7b415e9869157c711fe11263c95d74eDavid Li 15891591693c7b415e9869157c711fe11263c95d74eDavid Li prog->Version = max_version; 15901591693c7b415e9869157c711fe11263c95d74eDavid Li 15911591693c7b415e9869157c711fe11263c95d74eDavid Li for (unsigned int i = 0; i < MESA_SHADER_TYPES; i++) { 15921591693c7b415e9869157c711fe11263c95d74eDavid Li if (prog->_LinkedShaders[i] != NULL) 15932ac1cf8a62bcf080b70eaa7c0e4f57d4e8001685David Li _mesa_delete_shader(ctx, prog->_LinkedShaders[i]); 15941591693c7b415e9869157c711fe11263c95d74eDavid Li 15951591693c7b415e9869157c711fe11263c95d74eDavid Li prog->_LinkedShaders[i] = NULL; 15961591693c7b415e9869157c711fe11263c95d74eDavid Li } 15971591693c7b415e9869157c711fe11263c95d74eDavid Li 15981591693c7b415e9869157c711fe11263c95d74eDavid Li /* Link all shaders for a particular stage and validate the result. 15991591693c7b415e9869157c711fe11263c95d74eDavid Li */ 16001591693c7b415e9869157c711fe11263c95d74eDavid Li if (num_vert_shaders > 0) { 16011591693c7b415e9869157c711fe11263c95d74eDavid Li gl_shader *const sh = 16021591693c7b415e9869157c711fe11263c95d74eDavid Li link_intrastage_shaders(mem_ctx, ctx, prog, vert_shader_list, 16031591693c7b415e9869157c711fe11263c95d74eDavid Li num_vert_shaders); 16041591693c7b415e9869157c711fe11263c95d74eDavid Li 16051591693c7b415e9869157c711fe11263c95d74eDavid Li if (sh == NULL) 16061591693c7b415e9869157c711fe11263c95d74eDavid Li goto done; 16071591693c7b415e9869157c711fe11263c95d74eDavid Li 16081591693c7b415e9869157c711fe11263c95d74eDavid Li if (!validate_vertex_shader_executable(prog, sh)) 16091591693c7b415e9869157c711fe11263c95d74eDavid Li goto done; 16101591693c7b415e9869157c711fe11263c95d74eDavid Li 16111591693c7b415e9869157c711fe11263c95d74eDavid Li _mesa_reference_shader(ctx, &prog->_LinkedShaders[MESA_SHADER_VERTEX], 16121591693c7b415e9869157c711fe11263c95d74eDavid Li sh); 16131591693c7b415e9869157c711fe11263c95d74eDavid Li } 16141591693c7b415e9869157c711fe11263c95d74eDavid Li 16151591693c7b415e9869157c711fe11263c95d74eDavid Li if (num_frag_shaders > 0) { 16161591693c7b415e9869157c711fe11263c95d74eDavid Li gl_shader *const sh = 16171591693c7b415e9869157c711fe11263c95d74eDavid Li link_intrastage_shaders(mem_ctx, ctx, prog, frag_shader_list, 16181591693c7b415e9869157c711fe11263c95d74eDavid Li num_frag_shaders); 16191591693c7b415e9869157c711fe11263c95d74eDavid Li 16201591693c7b415e9869157c711fe11263c95d74eDavid Li if (sh == NULL) 16211591693c7b415e9869157c711fe11263c95d74eDavid Li goto done; 16221591693c7b415e9869157c711fe11263c95d74eDavid Li 16231591693c7b415e9869157c711fe11263c95d74eDavid Li if (!validate_fragment_shader_executable(prog, sh)) 16241591693c7b415e9869157c711fe11263c95d74eDavid Li goto done; 16251591693c7b415e9869157c711fe11263c95d74eDavid Li 16261591693c7b415e9869157c711fe11263c95d74eDavid Li _mesa_reference_shader(ctx, &prog->_LinkedShaders[MESA_SHADER_FRAGMENT], 16271591693c7b415e9869157c711fe11263c95d74eDavid Li sh); 16281591693c7b415e9869157c711fe11263c95d74eDavid Li } 16291591693c7b415e9869157c711fe11263c95d74eDavid Li 16301591693c7b415e9869157c711fe11263c95d74eDavid Li /* Here begins the inter-stage linking phase. Some initial validation is 16311591693c7b415e9869157c711fe11263c95d74eDavid Li * performed, then locations are assigned for uniforms, attributes, and 16321591693c7b415e9869157c711fe11263c95d74eDavid Li * varyings. 16331591693c7b415e9869157c711fe11263c95d74eDavid Li */ 16341591693c7b415e9869157c711fe11263c95d74eDavid Li if (cross_validate_uniforms(prog)) { 16351591693c7b415e9869157c711fe11263c95d74eDavid Li unsigned prev; 16361591693c7b415e9869157c711fe11263c95d74eDavid Li 16371591693c7b415e9869157c711fe11263c95d74eDavid Li for (prev = 0; prev < MESA_SHADER_TYPES; prev++) { 16381591693c7b415e9869157c711fe11263c95d74eDavid Li if (prog->_LinkedShaders[prev] != NULL) 16391591693c7b415e9869157c711fe11263c95d74eDavid Li break; 16401591693c7b415e9869157c711fe11263c95d74eDavid Li } 16411591693c7b415e9869157c711fe11263c95d74eDavid Li 16421591693c7b415e9869157c711fe11263c95d74eDavid Li /* Validate the inputs of each stage with the output of the preceeding 16431591693c7b415e9869157c711fe11263c95d74eDavid Li * stage. 16441591693c7b415e9869157c711fe11263c95d74eDavid Li */ 16451591693c7b415e9869157c711fe11263c95d74eDavid Li for (unsigned i = prev + 1; i < MESA_SHADER_TYPES; i++) { 16461591693c7b415e9869157c711fe11263c95d74eDavid Li if (prog->_LinkedShaders[i] == NULL) 16471591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 16481591693c7b415e9869157c711fe11263c95d74eDavid Li 16491591693c7b415e9869157c711fe11263c95d74eDavid Li if (!cross_validate_outputs_to_inputs(prog, 16501591693c7b415e9869157c711fe11263c95d74eDavid Li prog->_LinkedShaders[prev], 16511591693c7b415e9869157c711fe11263c95d74eDavid Li prog->_LinkedShaders[i])) 16521591693c7b415e9869157c711fe11263c95d74eDavid Li goto done; 16531591693c7b415e9869157c711fe11263c95d74eDavid Li 16541591693c7b415e9869157c711fe11263c95d74eDavid Li prev = i; 16551591693c7b415e9869157c711fe11263c95d74eDavid Li } 16561591693c7b415e9869157c711fe11263c95d74eDavid Li 16571591693c7b415e9869157c711fe11263c95d74eDavid Li prog->LinkStatus = true; 16581591693c7b415e9869157c711fe11263c95d74eDavid Li } 16591591693c7b415e9869157c711fe11263c95d74eDavid Li 16601591693c7b415e9869157c711fe11263c95d74eDavid Li /* Do common optimization before assigning storage for attributes, 16611591693c7b415e9869157c711fe11263c95d74eDavid Li * uniforms, and varyings. Later optimization could possibly make 16621591693c7b415e9869157c711fe11263c95d74eDavid Li * some of that unused. 16631591693c7b415e9869157c711fe11263c95d74eDavid Li */ 16641591693c7b415e9869157c711fe11263c95d74eDavid Li for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { 16651591693c7b415e9869157c711fe11263c95d74eDavid Li if (prog->_LinkedShaders[i] == NULL) 16661591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 16671591693c7b415e9869157c711fe11263c95d74eDavid Li 16681591693c7b415e9869157c711fe11263c95d74eDavid Li while (do_common_optimization(prog->_LinkedShaders[i]->ir, true, 32)) 16691591693c7b415e9869157c711fe11263c95d74eDavid Li ; 16701591693c7b415e9869157c711fe11263c95d74eDavid Li } 16711591693c7b415e9869157c711fe11263c95d74eDavid Li 16721591693c7b415e9869157c711fe11263c95d74eDavid Li update_array_sizes(prog); 16731591693c7b415e9869157c711fe11263c95d74eDavid Li 16741591693c7b415e9869157c711fe11263c95d74eDavid Li assign_uniform_locations(prog); 16751591693c7b415e9869157c711fe11263c95d74eDavid Li 16761591693c7b415e9869157c711fe11263c95d74eDavid Li if (prog->_LinkedShaders[MESA_SHADER_VERTEX] != NULL) { 16771591693c7b415e9869157c711fe11263c95d74eDavid Li /* FINISHME: The value of the max_attribute_index parameter is 16781591693c7b415e9869157c711fe11263c95d74eDavid Li * FINISHME: implementation dependent based on the value of 16791591693c7b415e9869157c711fe11263c95d74eDavid Li * FINISHME: GL_MAX_VERTEX_ATTRIBS. GL_MAX_VERTEX_ATTRIBS must be 16801591693c7b415e9869157c711fe11263c95d74eDavid Li * FINISHME: at least 16, so hardcode 16 for now. 16811591693c7b415e9869157c711fe11263c95d74eDavid Li */ 16821591693c7b415e9869157c711fe11263c95d74eDavid Li if (!assign_attribute_locations(prog, 16)) { 16831591693c7b415e9869157c711fe11263c95d74eDavid Li prog->LinkStatus = false; 16841591693c7b415e9869157c711fe11263c95d74eDavid Li goto done; 16851591693c7b415e9869157c711fe11263c95d74eDavid Li } 16868e399777f3d6c0e02a31af9e231e7547d3fdbb7dDavid Li prog->AttributeSlots = 0; 16878e399777f3d6c0e02a31af9e231e7547d3fdbb7dDavid Li for (unsigned i = 0; i < prog->Attributes->NumParameters; i++) 16888e399777f3d6c0e02a31af9e231e7547d3fdbb7dDavid Li { 16898e399777f3d6c0e02a31af9e231e7547d3fdbb7dDavid Li const gl_program_parameter & param = prog->Attributes->Parameters[i]; 16908e399777f3d6c0e02a31af9e231e7547d3fdbb7dDavid Li if (param.Location + param.Slots > prog->AttributeSlots) 16918e399777f3d6c0e02a31af9e231e7547d3fdbb7dDavid Li prog->AttributeSlots = param.Location + param.Slots; 16928e399777f3d6c0e02a31af9e231e7547d3fdbb7dDavid Li } 16931591693c7b415e9869157c711fe11263c95d74eDavid Li } 16941591693c7b415e9869157c711fe11263c95d74eDavid Li 16951591693c7b415e9869157c711fe11263c95d74eDavid Li unsigned prev; 16961591693c7b415e9869157c711fe11263c95d74eDavid Li for (prev = 0; prev < MESA_SHADER_TYPES; prev++) { 16971591693c7b415e9869157c711fe11263c95d74eDavid Li if (prog->_LinkedShaders[prev] != NULL) 16981591693c7b415e9869157c711fe11263c95d74eDavid Li break; 16991591693c7b415e9869157c711fe11263c95d74eDavid Li } 17001591693c7b415e9869157c711fe11263c95d74eDavid Li 17011591693c7b415e9869157c711fe11263c95d74eDavid Li for (unsigned i = prev + 1; i < MESA_SHADER_TYPES; i++) { 17021591693c7b415e9869157c711fe11263c95d74eDavid Li if (prog->_LinkedShaders[i] == NULL) 17031591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 17041591693c7b415e9869157c711fe11263c95d74eDavid Li 17051591693c7b415e9869157c711fe11263c95d74eDavid Li assign_varying_locations(prog, 17061591693c7b415e9869157c711fe11263c95d74eDavid Li prog->_LinkedShaders[prev], 1707c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li prog->_LinkedShaders[i]); 17081591693c7b415e9869157c711fe11263c95d74eDavid Li prev = i; 17091591693c7b415e9869157c711fe11263c95d74eDavid Li } 17101591693c7b415e9869157c711fe11263c95d74eDavid Li 17111591693c7b415e9869157c711fe11263c95d74eDavid Li if (prog->_LinkedShaders[MESA_SHADER_VERTEX] != NULL) { 1712f9ad8a790398513a845d486f58566854f7eceee4David Li demote_shader_inputs_and_outputs(prog->_LinkedShaders[MESA_SHADER_VERTEX], 1713f9ad8a790398513a845d486f58566854f7eceee4David Li ir_var_out); 17141591693c7b415e9869157c711fe11263c95d74eDavid Li } 17151591693c7b415e9869157c711fe11263c95d74eDavid Li 17161591693c7b415e9869157c711fe11263c95d74eDavid Li if (prog->_LinkedShaders[MESA_SHADER_GEOMETRY] != NULL) { 17171591693c7b415e9869157c711fe11263c95d74eDavid Li gl_shader *const sh = prog->_LinkedShaders[MESA_SHADER_GEOMETRY]; 17181591693c7b415e9869157c711fe11263c95d74eDavid Li 17191591693c7b415e9869157c711fe11263c95d74eDavid Li demote_shader_inputs_and_outputs(sh, ir_var_in); 17201591693c7b415e9869157c711fe11263c95d74eDavid Li demote_shader_inputs_and_outputs(sh, ir_var_inout); 17211591693c7b415e9869157c711fe11263c95d74eDavid Li demote_shader_inputs_and_outputs(sh, ir_var_out); 17221591693c7b415e9869157c711fe11263c95d74eDavid Li } 17231591693c7b415e9869157c711fe11263c95d74eDavid Li 17241591693c7b415e9869157c711fe11263c95d74eDavid Li if (prog->_LinkedShaders[MESA_SHADER_FRAGMENT] != NULL) { 17251591693c7b415e9869157c711fe11263c95d74eDavid Li gl_shader *const sh = prog->_LinkedShaders[MESA_SHADER_FRAGMENT]; 17261591693c7b415e9869157c711fe11263c95d74eDavid Li 1727f9ad8a790398513a845d486f58566854f7eceee4David Li demote_shader_inputs_and_outputs(sh, ir_var_in); 1728c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li 1729c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li foreach_list(node, sh->ir) { 1730c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li ir_variable *const var = ((ir_instruction *) node)->as_variable(); 1731c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li if (!var || ir_var_out != var->mode) 1732c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li continue; 1733c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li if (!strcmp("gl_FragColor", var->name) || !strcmp("gl_FragData", var->name)) 1734c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li { 1735c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li int paramIndex = _mesa_get_parameter(prog->Varying, var->name); 1736c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li if (0 > paramIndex) 1737c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li paramIndex = _mesa_add_parameter(prog->Varying, var->name); 17383225321119408735f16b72b539c9fb7d80683552David Li var->location= offsetof(VertexOutput,fragColor)/sizeof(Vector4); 1739c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li prog->Varying->Parameters[paramIndex].Location = var->location; 1740c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li } 1741c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li else 1742c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li assert(0); 1743c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li } 17441591693c7b415e9869157c711fe11263c95d74eDavid Li } 1745d274f94df69a016386195efcf0640802c7d7d2dcDavid Li 1746c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li //prog->InputOuputBase = malloc(1024 * 8); 1747c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li //memset(prog->InputOuputBase, 0xdd, 1024 * 8); 1748c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li prog->InputOuputBase = hieralloc_realloc(prog, prog->InputOuputBase, char, 174901e6ff90560d588418e706ce4d2a16d5a15520e5David Li (prog->Uniforms->Slots + prog->Uniforms->SamplerSlots) * sizeof(float) * 4 + sizeof(VertexInput) + sizeof(VertexOutput) + 16); 175001e6ff90560d588418e706ce4d2a16d5a15520e5David Li prog->ValuesVertexInput = (float (*)[4])((((unsigned long)prog->InputOuputBase) + 15L) & (~15L)); 1751c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li prog->ValuesVertexOutput = (float (*)[4])((unsigned long)prog->ValuesVertexInput + sizeof(VertexInput)); 1752c0025eb1a3d421c0355a21db9d8ea2bd81278460David Li prog->ValuesUniform = (float (*)[4])((unsigned long)prog->ValuesVertexOutput + sizeof(VertexOutput)); 17531591693c7b415e9869157c711fe11263c95d74eDavid Li 175401e6ff90560d588418e706ce4d2a16d5a15520e5David Li // initialize uniforms to zero after link 175501e6ff90560d588418e706ce4d2a16d5a15520e5David Li memset(prog->ValuesUniform, 0, sizeof(float) * 4 * (prog->Uniforms->Slots + prog->Uniforms->SamplerSlots)); 17568e399777f3d6c0e02a31af9e231e7547d3fdbb7dDavid Li 17571591693c7b415e9869157c711fe11263c95d74eDavid Lidone: 17581591693c7b415e9869157c711fe11263c95d74eDavid Li free(vert_shader_list); 17591591693c7b415e9869157c711fe11263c95d74eDavid Li 17601591693c7b415e9869157c711fe11263c95d74eDavid Li for (unsigned i = 0; i < MESA_SHADER_TYPES; i++) { 17611591693c7b415e9869157c711fe11263c95d74eDavid Li if (prog->_LinkedShaders[i] == NULL) 17621591693c7b415e9869157c711fe11263c95d74eDavid Li continue; 17631591693c7b415e9869157c711fe11263c95d74eDavid Li 17641591693c7b415e9869157c711fe11263c95d74eDavid Li /* Retain any live IR, but trash the rest. */ 17651591693c7b415e9869157c711fe11263c95d74eDavid Li reparent_ir(prog->_LinkedShaders[i]->ir, prog->_LinkedShaders[i]->ir); 17661591693c7b415e9869157c711fe11263c95d74eDavid Li } 17671591693c7b415e9869157c711fe11263c95d74eDavid Li 176813fea0fc797fa0d4c236db5aa2e6a23fc0e450dbDavid Li //hieralloc_free(mem_ctx); 17694f054616c70eb5bb1eb711d5bdf6f4c71ac3b877Conley Owens} 1770