1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © 2010 Intel Corporation 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 10bf215546Sopenharmony_ci * 11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 13bf215546Sopenharmony_ci * Software. 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21bf215546Sopenharmony_ci * DEALINGS IN THE SOFTWARE. 22bf215546Sopenharmony_ci */ 23bf215546Sopenharmony_ci 24bf215546Sopenharmony_ci/** 25bf215546Sopenharmony_ci * \file linker.cpp 26bf215546Sopenharmony_ci * GLSL linker implementation 27bf215546Sopenharmony_ci * 28bf215546Sopenharmony_ci * Given a set of shaders that are to be linked to generate a final program, 29bf215546Sopenharmony_ci * there are three distinct stages. 30bf215546Sopenharmony_ci * 31bf215546Sopenharmony_ci * In the first stage shaders are partitioned into groups based on the shader 32bf215546Sopenharmony_ci * type. All shaders of a particular type (e.g., vertex shaders) are linked 33bf215546Sopenharmony_ci * together. 34bf215546Sopenharmony_ci * 35bf215546Sopenharmony_ci * - Undefined references in each shader are resolve to definitions in 36bf215546Sopenharmony_ci * another shader. 37bf215546Sopenharmony_ci * - Types and qualifiers of uniforms, outputs, and global variables defined 38bf215546Sopenharmony_ci * in multiple shaders with the same name are verified to be the same. 39bf215546Sopenharmony_ci * - Initializers for uniforms and global variables defined 40bf215546Sopenharmony_ci * in multiple shaders with the same name are verified to be the same. 41bf215546Sopenharmony_ci * 42bf215546Sopenharmony_ci * The result, in the terminology of the GLSL spec, is a set of shader 43bf215546Sopenharmony_ci * executables for each processing unit. 44bf215546Sopenharmony_ci * 45bf215546Sopenharmony_ci * After the first stage is complete, a series of semantic checks are performed 46bf215546Sopenharmony_ci * on each of the shader executables. 47bf215546Sopenharmony_ci * 48bf215546Sopenharmony_ci * - Each shader executable must define a \c main function. 49bf215546Sopenharmony_ci * - Each vertex shader executable must write to \c gl_Position. 50bf215546Sopenharmony_ci * - Each fragment shader executable must write to either \c gl_FragData or 51bf215546Sopenharmony_ci * \c gl_FragColor. 52bf215546Sopenharmony_ci * 53bf215546Sopenharmony_ci * In the final stage individual shader executables are linked to create a 54bf215546Sopenharmony_ci * complete exectuable. 55bf215546Sopenharmony_ci * 56bf215546Sopenharmony_ci * - Types of uniforms defined in multiple shader stages with the same name 57bf215546Sopenharmony_ci * are verified to be the same. 58bf215546Sopenharmony_ci * - Initializers for uniforms defined in multiple shader stages with the 59bf215546Sopenharmony_ci * same name are verified to be the same. 60bf215546Sopenharmony_ci * - Types and qualifiers of outputs defined in one stage are verified to 61bf215546Sopenharmony_ci * be the same as the types and qualifiers of inputs defined with the same 62bf215546Sopenharmony_ci * name in a later stage. 63bf215546Sopenharmony_ci * 64bf215546Sopenharmony_ci * \author Ian Romanick <ian.d.romanick@intel.com> 65bf215546Sopenharmony_ci */ 66bf215546Sopenharmony_ci 67bf215546Sopenharmony_ci#include <ctype.h> 68bf215546Sopenharmony_ci#include "util/strndup.h" 69bf215546Sopenharmony_ci#include "glsl_symbol_table.h" 70bf215546Sopenharmony_ci#include "glsl_parser_extras.h" 71bf215546Sopenharmony_ci#include "ir.h" 72bf215546Sopenharmony_ci#include "nir.h" 73bf215546Sopenharmony_ci#include "program.h" 74bf215546Sopenharmony_ci#include "program/prog_instruction.h" 75bf215546Sopenharmony_ci#include "program/program.h" 76bf215546Sopenharmony_ci#include "util/mesa-sha1.h" 77bf215546Sopenharmony_ci#include "util/set.h" 78bf215546Sopenharmony_ci#include "string_to_uint_map.h" 79bf215546Sopenharmony_ci#include "linker.h" 80bf215546Sopenharmony_ci#include "linker_util.h" 81bf215546Sopenharmony_ci#include "link_varyings.h" 82bf215546Sopenharmony_ci#include "ir_optimization.h" 83bf215546Sopenharmony_ci#include "ir_rvalue_visitor.h" 84bf215546Sopenharmony_ci#include "ir_uniform.h" 85bf215546Sopenharmony_ci#include "builtin_functions.h" 86bf215546Sopenharmony_ci#include "shader_cache.h" 87bf215546Sopenharmony_ci#include "util/u_string.h" 88bf215546Sopenharmony_ci#include "util/u_math.h" 89bf215546Sopenharmony_ci 90bf215546Sopenharmony_ci 91bf215546Sopenharmony_ci#include "main/shaderobj.h" 92bf215546Sopenharmony_ci#include "main/enums.h" 93bf215546Sopenharmony_ci#include "main/mtypes.h" 94bf215546Sopenharmony_ci 95bf215546Sopenharmony_ci 96bf215546Sopenharmony_cinamespace { 97bf215546Sopenharmony_ci 98bf215546Sopenharmony_cistruct find_variable { 99bf215546Sopenharmony_ci const char *name; 100bf215546Sopenharmony_ci bool found; 101bf215546Sopenharmony_ci 102bf215546Sopenharmony_ci find_variable(const char *name) : name(name), found(false) {} 103bf215546Sopenharmony_ci}; 104bf215546Sopenharmony_ci 105bf215546Sopenharmony_ci/** 106bf215546Sopenharmony_ci * Visitor that determines whether or not a variable is ever written. 107bf215546Sopenharmony_ci * Note: this is only considering if the variable is statically written 108bf215546Sopenharmony_ci * (= regardless of the runtime flow of control) 109bf215546Sopenharmony_ci * 110bf215546Sopenharmony_ci * Use \ref find_assignments for convenience. 111bf215546Sopenharmony_ci */ 112bf215546Sopenharmony_ciclass find_assignment_visitor : public ir_hierarchical_visitor { 113bf215546Sopenharmony_cipublic: 114bf215546Sopenharmony_ci find_assignment_visitor(unsigned num_vars, 115bf215546Sopenharmony_ci find_variable * const *vars) 116bf215546Sopenharmony_ci : num_variables(num_vars), num_found(0), variables(vars) 117bf215546Sopenharmony_ci { 118bf215546Sopenharmony_ci } 119bf215546Sopenharmony_ci 120bf215546Sopenharmony_ci virtual ir_visitor_status visit_enter(ir_assignment *ir) 121bf215546Sopenharmony_ci { 122bf215546Sopenharmony_ci ir_variable *const var = ir->lhs->variable_referenced(); 123bf215546Sopenharmony_ci 124bf215546Sopenharmony_ci return check_variable_name(var->name); 125bf215546Sopenharmony_ci } 126bf215546Sopenharmony_ci 127bf215546Sopenharmony_ci virtual ir_visitor_status visit_enter(ir_call *ir) 128bf215546Sopenharmony_ci { 129bf215546Sopenharmony_ci foreach_two_lists(formal_node, &ir->callee->parameters, 130bf215546Sopenharmony_ci actual_node, &ir->actual_parameters) { 131bf215546Sopenharmony_ci ir_rvalue *param_rval = (ir_rvalue *) actual_node; 132bf215546Sopenharmony_ci ir_variable *sig_param = (ir_variable *) formal_node; 133bf215546Sopenharmony_ci 134bf215546Sopenharmony_ci if (sig_param->data.mode == ir_var_function_out || 135bf215546Sopenharmony_ci sig_param->data.mode == ir_var_function_inout) { 136bf215546Sopenharmony_ci ir_variable *var = param_rval->variable_referenced(); 137bf215546Sopenharmony_ci if (var && check_variable_name(var->name) == visit_stop) 138bf215546Sopenharmony_ci return visit_stop; 139bf215546Sopenharmony_ci } 140bf215546Sopenharmony_ci } 141bf215546Sopenharmony_ci 142bf215546Sopenharmony_ci if (ir->return_deref != NULL) { 143bf215546Sopenharmony_ci ir_variable *const var = ir->return_deref->variable_referenced(); 144bf215546Sopenharmony_ci 145bf215546Sopenharmony_ci if (check_variable_name(var->name) == visit_stop) 146bf215546Sopenharmony_ci return visit_stop; 147bf215546Sopenharmony_ci } 148bf215546Sopenharmony_ci 149bf215546Sopenharmony_ci return visit_continue_with_parent; 150bf215546Sopenharmony_ci } 151bf215546Sopenharmony_ci 152bf215546Sopenharmony_ciprivate: 153bf215546Sopenharmony_ci ir_visitor_status check_variable_name(const char *name) 154bf215546Sopenharmony_ci { 155bf215546Sopenharmony_ci for (unsigned i = 0; i < num_variables; ++i) { 156bf215546Sopenharmony_ci if (strcmp(variables[i]->name, name) == 0) { 157bf215546Sopenharmony_ci if (!variables[i]->found) { 158bf215546Sopenharmony_ci variables[i]->found = true; 159bf215546Sopenharmony_ci 160bf215546Sopenharmony_ci assert(num_found < num_variables); 161bf215546Sopenharmony_ci if (++num_found == num_variables) 162bf215546Sopenharmony_ci return visit_stop; 163bf215546Sopenharmony_ci } 164bf215546Sopenharmony_ci break; 165bf215546Sopenharmony_ci } 166bf215546Sopenharmony_ci } 167bf215546Sopenharmony_ci 168bf215546Sopenharmony_ci return visit_continue_with_parent; 169bf215546Sopenharmony_ci } 170bf215546Sopenharmony_ci 171bf215546Sopenharmony_ciprivate: 172bf215546Sopenharmony_ci unsigned num_variables; /**< Number of variables to find */ 173bf215546Sopenharmony_ci unsigned num_found; /**< Number of variables already found */ 174bf215546Sopenharmony_ci find_variable * const *variables; /**< Variables to find */ 175bf215546Sopenharmony_ci}; 176bf215546Sopenharmony_ci 177bf215546Sopenharmony_ci/** 178bf215546Sopenharmony_ci * Determine whether or not any of NULL-terminated list of variables is ever 179bf215546Sopenharmony_ci * written to. 180bf215546Sopenharmony_ci */ 181bf215546Sopenharmony_cistatic void 182bf215546Sopenharmony_cifind_assignments(exec_list *ir, find_variable * const *vars) 183bf215546Sopenharmony_ci{ 184bf215546Sopenharmony_ci unsigned num_variables = 0; 185bf215546Sopenharmony_ci 186bf215546Sopenharmony_ci for (find_variable * const *v = vars; *v; ++v) 187bf215546Sopenharmony_ci num_variables++; 188bf215546Sopenharmony_ci 189bf215546Sopenharmony_ci find_assignment_visitor visitor(num_variables, vars); 190bf215546Sopenharmony_ci visitor.run(ir); 191bf215546Sopenharmony_ci} 192bf215546Sopenharmony_ci 193bf215546Sopenharmony_ci/** 194bf215546Sopenharmony_ci * Determine whether or not the given variable is ever written to. 195bf215546Sopenharmony_ci */ 196bf215546Sopenharmony_cistatic void 197bf215546Sopenharmony_cifind_assignments(exec_list *ir, find_variable *var) 198bf215546Sopenharmony_ci{ 199bf215546Sopenharmony_ci find_assignment_visitor visitor(1, &var); 200bf215546Sopenharmony_ci visitor.run(ir); 201bf215546Sopenharmony_ci} 202bf215546Sopenharmony_ci 203bf215546Sopenharmony_ci/** 204bf215546Sopenharmony_ci * Visitor that determines whether or not a variable is ever read. 205bf215546Sopenharmony_ci */ 206bf215546Sopenharmony_ciclass find_deref_visitor : public ir_hierarchical_visitor { 207bf215546Sopenharmony_cipublic: 208bf215546Sopenharmony_ci find_deref_visitor(const char *name) 209bf215546Sopenharmony_ci : name(name), found(false) 210bf215546Sopenharmony_ci { 211bf215546Sopenharmony_ci /* empty */ 212bf215546Sopenharmony_ci } 213bf215546Sopenharmony_ci 214bf215546Sopenharmony_ci virtual ir_visitor_status visit(ir_dereference_variable *ir) 215bf215546Sopenharmony_ci { 216bf215546Sopenharmony_ci if (strcmp(this->name, ir->var->name) == 0) { 217bf215546Sopenharmony_ci this->found = true; 218bf215546Sopenharmony_ci return visit_stop; 219bf215546Sopenharmony_ci } 220bf215546Sopenharmony_ci 221bf215546Sopenharmony_ci return visit_continue; 222bf215546Sopenharmony_ci } 223bf215546Sopenharmony_ci 224bf215546Sopenharmony_ci bool variable_found() const 225bf215546Sopenharmony_ci { 226bf215546Sopenharmony_ci return this->found; 227bf215546Sopenharmony_ci } 228bf215546Sopenharmony_ci 229bf215546Sopenharmony_ciprivate: 230bf215546Sopenharmony_ci const char *name; /**< Find writes to a variable with this name. */ 231bf215546Sopenharmony_ci bool found; /**< Was a write to the variable found? */ 232bf215546Sopenharmony_ci}; 233bf215546Sopenharmony_ci 234bf215546Sopenharmony_ci 235bf215546Sopenharmony_ci/** 236bf215546Sopenharmony_ci * A visitor helper that provides methods for updating the types of 237bf215546Sopenharmony_ci * ir_dereferences. Classes that update variable types (say, updating 238bf215546Sopenharmony_ci * array sizes) will want to use this so that dereference types stay in sync. 239bf215546Sopenharmony_ci */ 240bf215546Sopenharmony_ciclass deref_type_updater : public ir_hierarchical_visitor { 241bf215546Sopenharmony_cipublic: 242bf215546Sopenharmony_ci virtual ir_visitor_status visit(ir_dereference_variable *ir) 243bf215546Sopenharmony_ci { 244bf215546Sopenharmony_ci ir->type = ir->var->type; 245bf215546Sopenharmony_ci return visit_continue; 246bf215546Sopenharmony_ci } 247bf215546Sopenharmony_ci 248bf215546Sopenharmony_ci virtual ir_visitor_status visit_leave(ir_dereference_array *ir) 249bf215546Sopenharmony_ci { 250bf215546Sopenharmony_ci const glsl_type *const vt = ir->array->type; 251bf215546Sopenharmony_ci if (vt->is_array()) 252bf215546Sopenharmony_ci ir->type = vt->fields.array; 253bf215546Sopenharmony_ci return visit_continue; 254bf215546Sopenharmony_ci } 255bf215546Sopenharmony_ci 256bf215546Sopenharmony_ci virtual ir_visitor_status visit_leave(ir_dereference_record *ir) 257bf215546Sopenharmony_ci { 258bf215546Sopenharmony_ci ir->type = ir->record->type->fields.structure[ir->field_idx].type; 259bf215546Sopenharmony_ci return visit_continue; 260bf215546Sopenharmony_ci } 261bf215546Sopenharmony_ci}; 262bf215546Sopenharmony_ci 263bf215546Sopenharmony_ci 264bf215546Sopenharmony_ciclass array_resize_visitor : public deref_type_updater { 265bf215546Sopenharmony_cipublic: 266bf215546Sopenharmony_ci using deref_type_updater::visit; 267bf215546Sopenharmony_ci 268bf215546Sopenharmony_ci unsigned num_vertices; 269bf215546Sopenharmony_ci gl_shader_program *prog; 270bf215546Sopenharmony_ci gl_shader_stage stage; 271bf215546Sopenharmony_ci 272bf215546Sopenharmony_ci array_resize_visitor(unsigned num_vertices, 273bf215546Sopenharmony_ci gl_shader_program *prog, 274bf215546Sopenharmony_ci gl_shader_stage stage) 275bf215546Sopenharmony_ci { 276bf215546Sopenharmony_ci this->num_vertices = num_vertices; 277bf215546Sopenharmony_ci this->prog = prog; 278bf215546Sopenharmony_ci this->stage = stage; 279bf215546Sopenharmony_ci } 280bf215546Sopenharmony_ci 281bf215546Sopenharmony_ci virtual ~array_resize_visitor() 282bf215546Sopenharmony_ci { 283bf215546Sopenharmony_ci /* empty */ 284bf215546Sopenharmony_ci } 285bf215546Sopenharmony_ci 286bf215546Sopenharmony_ci virtual ir_visitor_status visit(ir_variable *var) 287bf215546Sopenharmony_ci { 288bf215546Sopenharmony_ci if (!var->type->is_array() || var->data.mode != ir_var_shader_in || 289bf215546Sopenharmony_ci var->data.patch) 290bf215546Sopenharmony_ci return visit_continue; 291bf215546Sopenharmony_ci 292bf215546Sopenharmony_ci unsigned size = var->type->length; 293bf215546Sopenharmony_ci 294bf215546Sopenharmony_ci if (stage == MESA_SHADER_GEOMETRY) { 295bf215546Sopenharmony_ci /* Generate a link error if the shader has declared this array with 296bf215546Sopenharmony_ci * an incorrect size. 297bf215546Sopenharmony_ci */ 298bf215546Sopenharmony_ci if (!var->data.implicit_sized_array && 299bf215546Sopenharmony_ci size && size != this->num_vertices) { 300bf215546Sopenharmony_ci linker_error(this->prog, "size of array %s declared as %u, " 301bf215546Sopenharmony_ci "but number of input vertices is %u\n", 302bf215546Sopenharmony_ci var->name, size, this->num_vertices); 303bf215546Sopenharmony_ci return visit_continue; 304bf215546Sopenharmony_ci } 305bf215546Sopenharmony_ci 306bf215546Sopenharmony_ci /* Generate a link error if the shader attempts to access an input 307bf215546Sopenharmony_ci * array using an index too large for its actual size assigned at 308bf215546Sopenharmony_ci * link time. 309bf215546Sopenharmony_ci */ 310bf215546Sopenharmony_ci if (var->data.max_array_access >= (int)this->num_vertices) { 311bf215546Sopenharmony_ci linker_error(this->prog, "%s shader accesses element %i of " 312bf215546Sopenharmony_ci "%s, but only %i input vertices\n", 313bf215546Sopenharmony_ci _mesa_shader_stage_to_string(this->stage), 314bf215546Sopenharmony_ci var->data.max_array_access, var->name, this->num_vertices); 315bf215546Sopenharmony_ci return visit_continue; 316bf215546Sopenharmony_ci } 317bf215546Sopenharmony_ci } 318bf215546Sopenharmony_ci 319bf215546Sopenharmony_ci var->type = glsl_type::get_array_instance(var->type->fields.array, 320bf215546Sopenharmony_ci this->num_vertices); 321bf215546Sopenharmony_ci var->data.max_array_access = this->num_vertices - 1; 322bf215546Sopenharmony_ci 323bf215546Sopenharmony_ci return visit_continue; 324bf215546Sopenharmony_ci } 325bf215546Sopenharmony_ci}; 326bf215546Sopenharmony_ci 327bf215546Sopenharmony_ciclass array_length_to_const_visitor : public ir_rvalue_visitor { 328bf215546Sopenharmony_cipublic: 329bf215546Sopenharmony_ci array_length_to_const_visitor() 330bf215546Sopenharmony_ci { 331bf215546Sopenharmony_ci this->progress = false; 332bf215546Sopenharmony_ci } 333bf215546Sopenharmony_ci 334bf215546Sopenharmony_ci virtual ~array_length_to_const_visitor() 335bf215546Sopenharmony_ci { 336bf215546Sopenharmony_ci /* empty */ 337bf215546Sopenharmony_ci } 338bf215546Sopenharmony_ci 339bf215546Sopenharmony_ci bool progress; 340bf215546Sopenharmony_ci 341bf215546Sopenharmony_ci virtual void handle_rvalue(ir_rvalue **rvalue) 342bf215546Sopenharmony_ci { 343bf215546Sopenharmony_ci if (*rvalue == NULL || (*rvalue)->ir_type != ir_type_expression) 344bf215546Sopenharmony_ci return; 345bf215546Sopenharmony_ci 346bf215546Sopenharmony_ci ir_expression *expr = (*rvalue)->as_expression(); 347bf215546Sopenharmony_ci if (expr) { 348bf215546Sopenharmony_ci if (expr->operation == ir_unop_implicitly_sized_array_length) { 349bf215546Sopenharmony_ci assert(!expr->operands[0]->type->is_unsized_array()); 350bf215546Sopenharmony_ci ir_constant *constant = new(expr) 351bf215546Sopenharmony_ci ir_constant(expr->operands[0]->type->array_size()); 352bf215546Sopenharmony_ci if (constant) { 353bf215546Sopenharmony_ci *rvalue = constant; 354bf215546Sopenharmony_ci } 355bf215546Sopenharmony_ci } 356bf215546Sopenharmony_ci } 357bf215546Sopenharmony_ci } 358bf215546Sopenharmony_ci}; 359bf215546Sopenharmony_ci 360bf215546Sopenharmony_ci/** 361bf215546Sopenharmony_ci * Visitor that determines the highest stream id to which a (geometry) shader 362bf215546Sopenharmony_ci * emits vertices. It also checks whether End{Stream}Primitive is ever called. 363bf215546Sopenharmony_ci */ 364bf215546Sopenharmony_ciclass find_emit_vertex_visitor : public ir_hierarchical_visitor { 365bf215546Sopenharmony_cipublic: 366bf215546Sopenharmony_ci find_emit_vertex_visitor(int max_allowed) 367bf215546Sopenharmony_ci : max_stream_allowed(max_allowed), 368bf215546Sopenharmony_ci invalid_stream_id(0), 369bf215546Sopenharmony_ci invalid_stream_id_from_emit_vertex(false), 370bf215546Sopenharmony_ci end_primitive_found(false), 371bf215546Sopenharmony_ci used_streams(0) 372bf215546Sopenharmony_ci { 373bf215546Sopenharmony_ci /* empty */ 374bf215546Sopenharmony_ci } 375bf215546Sopenharmony_ci 376bf215546Sopenharmony_ci virtual ir_visitor_status visit_leave(ir_emit_vertex *ir) 377bf215546Sopenharmony_ci { 378bf215546Sopenharmony_ci int stream_id = ir->stream_id(); 379bf215546Sopenharmony_ci 380bf215546Sopenharmony_ci if (stream_id < 0) { 381bf215546Sopenharmony_ci invalid_stream_id = stream_id; 382bf215546Sopenharmony_ci invalid_stream_id_from_emit_vertex = true; 383bf215546Sopenharmony_ci return visit_stop; 384bf215546Sopenharmony_ci } 385bf215546Sopenharmony_ci 386bf215546Sopenharmony_ci if (stream_id > max_stream_allowed) { 387bf215546Sopenharmony_ci invalid_stream_id = stream_id; 388bf215546Sopenharmony_ci invalid_stream_id_from_emit_vertex = true; 389bf215546Sopenharmony_ci return visit_stop; 390bf215546Sopenharmony_ci } 391bf215546Sopenharmony_ci 392bf215546Sopenharmony_ci used_streams |= 1 << stream_id; 393bf215546Sopenharmony_ci 394bf215546Sopenharmony_ci return visit_continue; 395bf215546Sopenharmony_ci } 396bf215546Sopenharmony_ci 397bf215546Sopenharmony_ci virtual ir_visitor_status visit_leave(ir_end_primitive *ir) 398bf215546Sopenharmony_ci { 399bf215546Sopenharmony_ci end_primitive_found = true; 400bf215546Sopenharmony_ci 401bf215546Sopenharmony_ci int stream_id = ir->stream_id(); 402bf215546Sopenharmony_ci 403bf215546Sopenharmony_ci if (stream_id < 0) { 404bf215546Sopenharmony_ci invalid_stream_id = stream_id; 405bf215546Sopenharmony_ci invalid_stream_id_from_emit_vertex = false; 406bf215546Sopenharmony_ci return visit_stop; 407bf215546Sopenharmony_ci } 408bf215546Sopenharmony_ci 409bf215546Sopenharmony_ci if (stream_id > max_stream_allowed) { 410bf215546Sopenharmony_ci invalid_stream_id = stream_id; 411bf215546Sopenharmony_ci invalid_stream_id_from_emit_vertex = false; 412bf215546Sopenharmony_ci return visit_stop; 413bf215546Sopenharmony_ci } 414bf215546Sopenharmony_ci 415bf215546Sopenharmony_ci used_streams |= 1 << stream_id; 416bf215546Sopenharmony_ci 417bf215546Sopenharmony_ci return visit_continue; 418bf215546Sopenharmony_ci } 419bf215546Sopenharmony_ci 420bf215546Sopenharmony_ci bool error() 421bf215546Sopenharmony_ci { 422bf215546Sopenharmony_ci return invalid_stream_id != 0; 423bf215546Sopenharmony_ci } 424bf215546Sopenharmony_ci 425bf215546Sopenharmony_ci const char *error_func() 426bf215546Sopenharmony_ci { 427bf215546Sopenharmony_ci return invalid_stream_id_from_emit_vertex ? 428bf215546Sopenharmony_ci "EmitStreamVertex" : "EndStreamPrimitive"; 429bf215546Sopenharmony_ci } 430bf215546Sopenharmony_ci 431bf215546Sopenharmony_ci int error_stream() 432bf215546Sopenharmony_ci { 433bf215546Sopenharmony_ci return invalid_stream_id; 434bf215546Sopenharmony_ci } 435bf215546Sopenharmony_ci 436bf215546Sopenharmony_ci unsigned active_stream_mask() 437bf215546Sopenharmony_ci { 438bf215546Sopenharmony_ci return used_streams; 439bf215546Sopenharmony_ci } 440bf215546Sopenharmony_ci 441bf215546Sopenharmony_ci bool uses_end_primitive() 442bf215546Sopenharmony_ci { 443bf215546Sopenharmony_ci return end_primitive_found; 444bf215546Sopenharmony_ci } 445bf215546Sopenharmony_ci 446bf215546Sopenharmony_ciprivate: 447bf215546Sopenharmony_ci int max_stream_allowed; 448bf215546Sopenharmony_ci int invalid_stream_id; 449bf215546Sopenharmony_ci bool invalid_stream_id_from_emit_vertex; 450bf215546Sopenharmony_ci bool end_primitive_found; 451bf215546Sopenharmony_ci unsigned used_streams; 452bf215546Sopenharmony_ci}; 453bf215546Sopenharmony_ci 454bf215546Sopenharmony_ci} /* anonymous namespace */ 455bf215546Sopenharmony_ci 456bf215546Sopenharmony_civoid 457bf215546Sopenharmony_cilinker_error(gl_shader_program *prog, const char *fmt, ...) 458bf215546Sopenharmony_ci{ 459bf215546Sopenharmony_ci va_list ap; 460bf215546Sopenharmony_ci 461bf215546Sopenharmony_ci ralloc_strcat(&prog->data->InfoLog, "error: "); 462bf215546Sopenharmony_ci va_start(ap, fmt); 463bf215546Sopenharmony_ci ralloc_vasprintf_append(&prog->data->InfoLog, fmt, ap); 464bf215546Sopenharmony_ci va_end(ap); 465bf215546Sopenharmony_ci 466bf215546Sopenharmony_ci prog->data->LinkStatus = LINKING_FAILURE; 467bf215546Sopenharmony_ci} 468bf215546Sopenharmony_ci 469bf215546Sopenharmony_ci 470bf215546Sopenharmony_civoid 471bf215546Sopenharmony_cilinker_warning(gl_shader_program *prog, const char *fmt, ...) 472bf215546Sopenharmony_ci{ 473bf215546Sopenharmony_ci va_list ap; 474bf215546Sopenharmony_ci 475bf215546Sopenharmony_ci ralloc_strcat(&prog->data->InfoLog, "warning: "); 476bf215546Sopenharmony_ci va_start(ap, fmt); 477bf215546Sopenharmony_ci ralloc_vasprintf_append(&prog->data->InfoLog, fmt, ap); 478bf215546Sopenharmony_ci va_end(ap); 479bf215546Sopenharmony_ci 480bf215546Sopenharmony_ci} 481bf215546Sopenharmony_ci 482bf215546Sopenharmony_ci 483bf215546Sopenharmony_civoid 484bf215546Sopenharmony_cilink_invalidate_variable_locations(exec_list *ir) 485bf215546Sopenharmony_ci{ 486bf215546Sopenharmony_ci foreach_in_list(ir_instruction, node, ir) { 487bf215546Sopenharmony_ci ir_variable *const var = node->as_variable(); 488bf215546Sopenharmony_ci 489bf215546Sopenharmony_ci if (var == NULL) 490bf215546Sopenharmony_ci continue; 491bf215546Sopenharmony_ci 492bf215546Sopenharmony_ci /* Only assign locations for variables that lack an explicit location. 493bf215546Sopenharmony_ci * Explicit locations are set for all built-in variables, generic vertex 494bf215546Sopenharmony_ci * shader inputs (via layout(location=...)), and generic fragment shader 495bf215546Sopenharmony_ci * outputs (also via layout(location=...)). 496bf215546Sopenharmony_ci */ 497bf215546Sopenharmony_ci if (!var->data.explicit_location) { 498bf215546Sopenharmony_ci var->data.location = -1; 499bf215546Sopenharmony_ci var->data.location_frac = 0; 500bf215546Sopenharmony_ci } 501bf215546Sopenharmony_ci } 502bf215546Sopenharmony_ci} 503bf215546Sopenharmony_ci 504bf215546Sopenharmony_ci 505bf215546Sopenharmony_ci/** 506bf215546Sopenharmony_ci * Set clip_distance_array_size based and cull_distance_array_size on the given 507bf215546Sopenharmony_ci * shader. 508bf215546Sopenharmony_ci * 509bf215546Sopenharmony_ci * Also check for errors based on incorrect usage of gl_ClipVertex and 510bf215546Sopenharmony_ci * gl_ClipDistance and gl_CullDistance. 511bf215546Sopenharmony_ci * Additionally test whether the arrays gl_ClipDistance and gl_CullDistance 512bf215546Sopenharmony_ci * exceed the maximum size defined by gl_MaxCombinedClipAndCullDistances. 513bf215546Sopenharmony_ci * 514bf215546Sopenharmony_ci * Return false if an error was reported. 515bf215546Sopenharmony_ci */ 516bf215546Sopenharmony_cistatic void 517bf215546Sopenharmony_cianalyze_clip_cull_usage(struct gl_shader_program *prog, 518bf215546Sopenharmony_ci struct gl_linked_shader *shader, 519bf215546Sopenharmony_ci const struct gl_constants *consts, 520bf215546Sopenharmony_ci struct shader_info *info) 521bf215546Sopenharmony_ci{ 522bf215546Sopenharmony_ci if (consts->DoDCEBeforeClipCullAnalysis) { 523bf215546Sopenharmony_ci /* Remove dead functions to avoid raising an error (eg: dead function 524bf215546Sopenharmony_ci * writes to gl_ClipVertex, and main() writes to gl_ClipDistance). 525bf215546Sopenharmony_ci */ 526bf215546Sopenharmony_ci do_dead_functions(shader->ir); 527bf215546Sopenharmony_ci } 528bf215546Sopenharmony_ci 529bf215546Sopenharmony_ci info->clip_distance_array_size = 0; 530bf215546Sopenharmony_ci info->cull_distance_array_size = 0; 531bf215546Sopenharmony_ci 532bf215546Sopenharmony_ci if (prog->data->Version >= (prog->IsES ? 300 : 130)) { 533bf215546Sopenharmony_ci /* From section 7.1 (Vertex Shader Special Variables) of the 534bf215546Sopenharmony_ci * GLSL 1.30 spec: 535bf215546Sopenharmony_ci * 536bf215546Sopenharmony_ci * "It is an error for a shader to statically write both 537bf215546Sopenharmony_ci * gl_ClipVertex and gl_ClipDistance." 538bf215546Sopenharmony_ci * 539bf215546Sopenharmony_ci * This does not apply to GLSL ES shaders, since GLSL ES defines neither 540bf215546Sopenharmony_ci * gl_ClipVertex nor gl_ClipDistance. However with 541bf215546Sopenharmony_ci * GL_EXT_clip_cull_distance, this functionality is exposed in ES 3.0. 542bf215546Sopenharmony_ci */ 543bf215546Sopenharmony_ci find_variable gl_ClipDistance("gl_ClipDistance"); 544bf215546Sopenharmony_ci find_variable gl_CullDistance("gl_CullDistance"); 545bf215546Sopenharmony_ci find_variable gl_ClipVertex("gl_ClipVertex"); 546bf215546Sopenharmony_ci find_variable * const variables[] = { 547bf215546Sopenharmony_ci &gl_ClipDistance, 548bf215546Sopenharmony_ci &gl_CullDistance, 549bf215546Sopenharmony_ci !prog->IsES ? &gl_ClipVertex : NULL, 550bf215546Sopenharmony_ci NULL 551bf215546Sopenharmony_ci }; 552bf215546Sopenharmony_ci find_assignments(shader->ir, variables); 553bf215546Sopenharmony_ci 554bf215546Sopenharmony_ci /* From the ARB_cull_distance spec: 555bf215546Sopenharmony_ci * 556bf215546Sopenharmony_ci * It is a compile-time or link-time error for the set of shaders forming 557bf215546Sopenharmony_ci * a program to statically read or write both gl_ClipVertex and either 558bf215546Sopenharmony_ci * gl_ClipDistance or gl_CullDistance. 559bf215546Sopenharmony_ci * 560bf215546Sopenharmony_ci * This does not apply to GLSL ES shaders, since GLSL ES doesn't define 561bf215546Sopenharmony_ci * gl_ClipVertex. 562bf215546Sopenharmony_ci */ 563bf215546Sopenharmony_ci if (!prog->IsES) { 564bf215546Sopenharmony_ci if (gl_ClipVertex.found && gl_ClipDistance.found) { 565bf215546Sopenharmony_ci linker_error(prog, "%s shader writes to both `gl_ClipVertex' " 566bf215546Sopenharmony_ci "and `gl_ClipDistance'\n", 567bf215546Sopenharmony_ci _mesa_shader_stage_to_string(shader->Stage)); 568bf215546Sopenharmony_ci return; 569bf215546Sopenharmony_ci } 570bf215546Sopenharmony_ci if (gl_ClipVertex.found && gl_CullDistance.found) { 571bf215546Sopenharmony_ci linker_error(prog, "%s shader writes to both `gl_ClipVertex' " 572bf215546Sopenharmony_ci "and `gl_CullDistance'\n", 573bf215546Sopenharmony_ci _mesa_shader_stage_to_string(shader->Stage)); 574bf215546Sopenharmony_ci return; 575bf215546Sopenharmony_ci } 576bf215546Sopenharmony_ci } 577bf215546Sopenharmony_ci 578bf215546Sopenharmony_ci if (gl_ClipDistance.found) { 579bf215546Sopenharmony_ci ir_variable *clip_distance_var = 580bf215546Sopenharmony_ci shader->symbols->get_variable("gl_ClipDistance"); 581bf215546Sopenharmony_ci assert(clip_distance_var); 582bf215546Sopenharmony_ci info->clip_distance_array_size = clip_distance_var->type->length; 583bf215546Sopenharmony_ci } 584bf215546Sopenharmony_ci if (gl_CullDistance.found) { 585bf215546Sopenharmony_ci ir_variable *cull_distance_var = 586bf215546Sopenharmony_ci shader->symbols->get_variable("gl_CullDistance"); 587bf215546Sopenharmony_ci assert(cull_distance_var); 588bf215546Sopenharmony_ci info->cull_distance_array_size = cull_distance_var->type->length; 589bf215546Sopenharmony_ci } 590bf215546Sopenharmony_ci /* From the ARB_cull_distance spec: 591bf215546Sopenharmony_ci * 592bf215546Sopenharmony_ci * It is a compile-time or link-time error for the set of shaders forming 593bf215546Sopenharmony_ci * a program to have the sum of the sizes of the gl_ClipDistance and 594bf215546Sopenharmony_ci * gl_CullDistance arrays to be larger than 595bf215546Sopenharmony_ci * gl_MaxCombinedClipAndCullDistances. 596bf215546Sopenharmony_ci */ 597bf215546Sopenharmony_ci if ((uint32_t)(info->clip_distance_array_size + info->cull_distance_array_size) > 598bf215546Sopenharmony_ci consts->MaxClipPlanes) { 599bf215546Sopenharmony_ci linker_error(prog, "%s shader: the combined size of " 600bf215546Sopenharmony_ci "'gl_ClipDistance' and 'gl_CullDistance' size cannot " 601bf215546Sopenharmony_ci "be larger than " 602bf215546Sopenharmony_ci "gl_MaxCombinedClipAndCullDistances (%u)", 603bf215546Sopenharmony_ci _mesa_shader_stage_to_string(shader->Stage), 604bf215546Sopenharmony_ci consts->MaxClipPlanes); 605bf215546Sopenharmony_ci } 606bf215546Sopenharmony_ci } 607bf215546Sopenharmony_ci} 608bf215546Sopenharmony_ci 609bf215546Sopenharmony_ci 610bf215546Sopenharmony_ci/** 611bf215546Sopenharmony_ci * Verify that a vertex shader executable meets all semantic requirements. 612bf215546Sopenharmony_ci * 613bf215546Sopenharmony_ci * Also sets info.clip_distance_array_size and 614bf215546Sopenharmony_ci * info.cull_distance_array_size as a side effect. 615bf215546Sopenharmony_ci * 616bf215546Sopenharmony_ci * \param shader Vertex shader executable to be verified 617bf215546Sopenharmony_ci */ 618bf215546Sopenharmony_cistatic void 619bf215546Sopenharmony_civalidate_vertex_shader_executable(struct gl_shader_program *prog, 620bf215546Sopenharmony_ci struct gl_linked_shader *shader, 621bf215546Sopenharmony_ci const struct gl_constants *consts) 622bf215546Sopenharmony_ci{ 623bf215546Sopenharmony_ci if (shader == NULL) 624bf215546Sopenharmony_ci return; 625bf215546Sopenharmony_ci 626bf215546Sopenharmony_ci /* From the GLSL 1.10 spec, page 48: 627bf215546Sopenharmony_ci * 628bf215546Sopenharmony_ci * "The variable gl_Position is available only in the vertex 629bf215546Sopenharmony_ci * language and is intended for writing the homogeneous vertex 630bf215546Sopenharmony_ci * position. All executions of a well-formed vertex shader 631bf215546Sopenharmony_ci * executable must write a value into this variable. [...] The 632bf215546Sopenharmony_ci * variable gl_Position is available only in the vertex 633bf215546Sopenharmony_ci * language and is intended for writing the homogeneous vertex 634bf215546Sopenharmony_ci * position. All executions of a well-formed vertex shader 635bf215546Sopenharmony_ci * executable must write a value into this variable." 636bf215546Sopenharmony_ci * 637bf215546Sopenharmony_ci * while in GLSL 1.40 this text is changed to: 638bf215546Sopenharmony_ci * 639bf215546Sopenharmony_ci * "The variable gl_Position is available only in the vertex 640bf215546Sopenharmony_ci * language and is intended for writing the homogeneous vertex 641bf215546Sopenharmony_ci * position. It can be written at any time during shader 642bf215546Sopenharmony_ci * execution. It may also be read back by a vertex shader 643bf215546Sopenharmony_ci * after being written. This value will be used by primitive 644bf215546Sopenharmony_ci * assembly, clipping, culling, and other fixed functionality 645bf215546Sopenharmony_ci * operations, if present, that operate on primitives after 646bf215546Sopenharmony_ci * vertex processing has occurred. Its value is undefined if 647bf215546Sopenharmony_ci * the vertex shader executable does not write gl_Position." 648bf215546Sopenharmony_ci * 649bf215546Sopenharmony_ci * All GLSL ES Versions are similar to GLSL 1.40--failing to write to 650bf215546Sopenharmony_ci * gl_Position is not an error. 651bf215546Sopenharmony_ci */ 652bf215546Sopenharmony_ci if (prog->data->Version < (prog->IsES ? 300 : 140)) { 653bf215546Sopenharmony_ci find_variable gl_Position("gl_Position"); 654bf215546Sopenharmony_ci find_assignments(shader->ir, &gl_Position); 655bf215546Sopenharmony_ci if (!gl_Position.found) { 656bf215546Sopenharmony_ci if (prog->IsES) { 657bf215546Sopenharmony_ci linker_warning(prog, 658bf215546Sopenharmony_ci "vertex shader does not write to `gl_Position'. " 659bf215546Sopenharmony_ci "Its value is undefined. \n"); 660bf215546Sopenharmony_ci } else { 661bf215546Sopenharmony_ci linker_error(prog, 662bf215546Sopenharmony_ci "vertex shader does not write to `gl_Position'. \n"); 663bf215546Sopenharmony_ci } 664bf215546Sopenharmony_ci return; 665bf215546Sopenharmony_ci } 666bf215546Sopenharmony_ci } 667bf215546Sopenharmony_ci 668bf215546Sopenharmony_ci analyze_clip_cull_usage(prog, shader, consts, &shader->Program->info); 669bf215546Sopenharmony_ci} 670bf215546Sopenharmony_ci 671bf215546Sopenharmony_cistatic void 672bf215546Sopenharmony_civalidate_tess_eval_shader_executable(struct gl_shader_program *prog, 673bf215546Sopenharmony_ci struct gl_linked_shader *shader, 674bf215546Sopenharmony_ci const struct gl_constants *consts) 675bf215546Sopenharmony_ci{ 676bf215546Sopenharmony_ci if (shader == NULL) 677bf215546Sopenharmony_ci return; 678bf215546Sopenharmony_ci 679bf215546Sopenharmony_ci analyze_clip_cull_usage(prog, shader, consts, &shader->Program->info); 680bf215546Sopenharmony_ci} 681bf215546Sopenharmony_ci 682bf215546Sopenharmony_ci 683bf215546Sopenharmony_ci/** 684bf215546Sopenharmony_ci * Verify that a fragment shader executable meets all semantic requirements 685bf215546Sopenharmony_ci * 686bf215546Sopenharmony_ci * \param shader Fragment shader executable to be verified 687bf215546Sopenharmony_ci */ 688bf215546Sopenharmony_cistatic void 689bf215546Sopenharmony_civalidate_fragment_shader_executable(struct gl_shader_program *prog, 690bf215546Sopenharmony_ci struct gl_linked_shader *shader) 691bf215546Sopenharmony_ci{ 692bf215546Sopenharmony_ci if (shader == NULL) 693bf215546Sopenharmony_ci return; 694bf215546Sopenharmony_ci 695bf215546Sopenharmony_ci find_variable gl_FragColor("gl_FragColor"); 696bf215546Sopenharmony_ci find_variable gl_FragData("gl_FragData"); 697bf215546Sopenharmony_ci find_variable * const variables[] = { &gl_FragColor, &gl_FragData, NULL }; 698bf215546Sopenharmony_ci find_assignments(shader->ir, variables); 699bf215546Sopenharmony_ci 700bf215546Sopenharmony_ci if (gl_FragColor.found && gl_FragData.found) { 701bf215546Sopenharmony_ci linker_error(prog, "fragment shader writes to both " 702bf215546Sopenharmony_ci "`gl_FragColor' and `gl_FragData'\n"); 703bf215546Sopenharmony_ci } 704bf215546Sopenharmony_ci} 705bf215546Sopenharmony_ci 706bf215546Sopenharmony_ci/** 707bf215546Sopenharmony_ci * Verify that a geometry shader executable meets all semantic requirements 708bf215546Sopenharmony_ci * 709bf215546Sopenharmony_ci * Also sets prog->Geom.VerticesIn, and info.clip_distance_array_sizeand 710bf215546Sopenharmony_ci * info.cull_distance_array_size as a side effect. 711bf215546Sopenharmony_ci * 712bf215546Sopenharmony_ci * \param shader Geometry shader executable to be verified 713bf215546Sopenharmony_ci */ 714bf215546Sopenharmony_cistatic void 715bf215546Sopenharmony_civalidate_geometry_shader_executable(struct gl_shader_program *prog, 716bf215546Sopenharmony_ci struct gl_linked_shader *shader, 717bf215546Sopenharmony_ci const struct gl_constants *consts) 718bf215546Sopenharmony_ci{ 719bf215546Sopenharmony_ci if (shader == NULL) 720bf215546Sopenharmony_ci return; 721bf215546Sopenharmony_ci 722bf215546Sopenharmony_ci unsigned num_vertices = 723bf215546Sopenharmony_ci vertices_per_prim(shader->Program->info.gs.input_primitive); 724bf215546Sopenharmony_ci prog->Geom.VerticesIn = num_vertices; 725bf215546Sopenharmony_ci 726bf215546Sopenharmony_ci analyze_clip_cull_usage(prog, shader, consts, &shader->Program->info); 727bf215546Sopenharmony_ci} 728bf215546Sopenharmony_ci 729bf215546Sopenharmony_ci/** 730bf215546Sopenharmony_ci * Check if geometry shaders emit to non-zero streams and do corresponding 731bf215546Sopenharmony_ci * validations. 732bf215546Sopenharmony_ci */ 733bf215546Sopenharmony_cistatic void 734bf215546Sopenharmony_civalidate_geometry_shader_emissions(const struct gl_constants *consts, 735bf215546Sopenharmony_ci struct gl_shader_program *prog) 736bf215546Sopenharmony_ci{ 737bf215546Sopenharmony_ci struct gl_linked_shader *sh = prog->_LinkedShaders[MESA_SHADER_GEOMETRY]; 738bf215546Sopenharmony_ci 739bf215546Sopenharmony_ci if (sh != NULL) { 740bf215546Sopenharmony_ci find_emit_vertex_visitor emit_vertex(consts->MaxVertexStreams - 1); 741bf215546Sopenharmony_ci emit_vertex.run(sh->ir); 742bf215546Sopenharmony_ci if (emit_vertex.error()) { 743bf215546Sopenharmony_ci linker_error(prog, "Invalid call %s(%d). Accepted values for the " 744bf215546Sopenharmony_ci "stream parameter are in the range [0, %d].\n", 745bf215546Sopenharmony_ci emit_vertex.error_func(), 746bf215546Sopenharmony_ci emit_vertex.error_stream(), 747bf215546Sopenharmony_ci consts->MaxVertexStreams - 1); 748bf215546Sopenharmony_ci } 749bf215546Sopenharmony_ci prog->Geom.ActiveStreamMask = emit_vertex.active_stream_mask(); 750bf215546Sopenharmony_ci prog->Geom.UsesEndPrimitive = emit_vertex.uses_end_primitive(); 751bf215546Sopenharmony_ci 752bf215546Sopenharmony_ci /* From the ARB_gpu_shader5 spec: 753bf215546Sopenharmony_ci * 754bf215546Sopenharmony_ci * "Multiple vertex streams are supported only if the output primitive 755bf215546Sopenharmony_ci * type is declared to be "points". A program will fail to link if it 756bf215546Sopenharmony_ci * contains a geometry shader calling EmitStreamVertex() or 757bf215546Sopenharmony_ci * EndStreamPrimitive() if its output primitive type is not "points". 758bf215546Sopenharmony_ci * 759bf215546Sopenharmony_ci * However, in the same spec: 760bf215546Sopenharmony_ci * 761bf215546Sopenharmony_ci * "The function EmitVertex() is equivalent to calling EmitStreamVertex() 762bf215546Sopenharmony_ci * with <stream> set to zero." 763bf215546Sopenharmony_ci * 764bf215546Sopenharmony_ci * And: 765bf215546Sopenharmony_ci * 766bf215546Sopenharmony_ci * "The function EndPrimitive() is equivalent to calling 767bf215546Sopenharmony_ci * EndStreamPrimitive() with <stream> set to zero." 768bf215546Sopenharmony_ci * 769bf215546Sopenharmony_ci * Since we can call EmitVertex() and EndPrimitive() when we output 770bf215546Sopenharmony_ci * primitives other than points, calling EmitStreamVertex(0) or 771bf215546Sopenharmony_ci * EmitEndPrimitive(0) should not produce errors. This it also what Nvidia 772bf215546Sopenharmony_ci * does. We can use prog->Geom.ActiveStreamMask to check whether only the 773bf215546Sopenharmony_ci * first (zero) stream is active. 774bf215546Sopenharmony_ci * stream. 775bf215546Sopenharmony_ci */ 776bf215546Sopenharmony_ci if (prog->Geom.ActiveStreamMask & ~(1 << 0) && 777bf215546Sopenharmony_ci sh->Program->info.gs.output_primitive != GL_POINTS) { 778bf215546Sopenharmony_ci linker_error(prog, "EmitStreamVertex(n) and EndStreamPrimitive(n) " 779bf215546Sopenharmony_ci "with n>0 requires point output\n"); 780bf215546Sopenharmony_ci } 781bf215546Sopenharmony_ci } 782bf215546Sopenharmony_ci} 783bf215546Sopenharmony_ci 784bf215546Sopenharmony_cibool 785bf215546Sopenharmony_civalidate_intrastage_arrays(struct gl_shader_program *prog, 786bf215546Sopenharmony_ci ir_variable *const var, 787bf215546Sopenharmony_ci ir_variable *const existing, 788bf215546Sopenharmony_ci bool match_precision) 789bf215546Sopenharmony_ci{ 790bf215546Sopenharmony_ci /* Consider the types to be "the same" if both types are arrays 791bf215546Sopenharmony_ci * of the same type and one of the arrays is implicitly sized. 792bf215546Sopenharmony_ci * In addition, set the type of the linked variable to the 793bf215546Sopenharmony_ci * explicitly sized array. 794bf215546Sopenharmony_ci */ 795bf215546Sopenharmony_ci if (var->type->is_array() && existing->type->is_array()) { 796bf215546Sopenharmony_ci const glsl_type *no_array_var = var->type->fields.array; 797bf215546Sopenharmony_ci const glsl_type *no_array_existing = existing->type->fields.array; 798bf215546Sopenharmony_ci bool type_matches; 799bf215546Sopenharmony_ci 800bf215546Sopenharmony_ci type_matches = (match_precision ? 801bf215546Sopenharmony_ci no_array_var == no_array_existing : 802bf215546Sopenharmony_ci no_array_var->compare_no_precision(no_array_existing)); 803bf215546Sopenharmony_ci 804bf215546Sopenharmony_ci if (type_matches && 805bf215546Sopenharmony_ci ((var->type->length == 0)|| (existing->type->length == 0))) { 806bf215546Sopenharmony_ci if (var->type->length != 0) { 807bf215546Sopenharmony_ci if ((int)var->type->length <= existing->data.max_array_access) { 808bf215546Sopenharmony_ci linker_error(prog, "%s `%s' declared as type " 809bf215546Sopenharmony_ci "`%s' but outermost dimension has an index" 810bf215546Sopenharmony_ci " of `%i'\n", 811bf215546Sopenharmony_ci mode_string(var), 812bf215546Sopenharmony_ci var->name, var->type->name, 813bf215546Sopenharmony_ci existing->data.max_array_access); 814bf215546Sopenharmony_ci } 815bf215546Sopenharmony_ci existing->type = var->type; 816bf215546Sopenharmony_ci return true; 817bf215546Sopenharmony_ci } else if (existing->type->length != 0) { 818bf215546Sopenharmony_ci if((int)existing->type->length <= var->data.max_array_access && 819bf215546Sopenharmony_ci !existing->data.from_ssbo_unsized_array) { 820bf215546Sopenharmony_ci linker_error(prog, "%s `%s' declared as type " 821bf215546Sopenharmony_ci "`%s' but outermost dimension has an index" 822bf215546Sopenharmony_ci " of `%i'\n", 823bf215546Sopenharmony_ci mode_string(var), 824bf215546Sopenharmony_ci var->name, existing->type->name, 825bf215546Sopenharmony_ci var->data.max_array_access); 826bf215546Sopenharmony_ci } 827bf215546Sopenharmony_ci return true; 828bf215546Sopenharmony_ci } 829bf215546Sopenharmony_ci } 830bf215546Sopenharmony_ci } 831bf215546Sopenharmony_ci return false; 832bf215546Sopenharmony_ci} 833bf215546Sopenharmony_ci 834bf215546Sopenharmony_ci 835bf215546Sopenharmony_ci/** 836bf215546Sopenharmony_ci * Perform validation of global variables used across multiple shaders 837bf215546Sopenharmony_ci */ 838bf215546Sopenharmony_cistatic void 839bf215546Sopenharmony_cicross_validate_globals(const struct gl_constants *consts, 840bf215546Sopenharmony_ci struct gl_shader_program *prog, 841bf215546Sopenharmony_ci struct exec_list *ir, glsl_symbol_table *variables, 842bf215546Sopenharmony_ci bool uniforms_only) 843bf215546Sopenharmony_ci{ 844bf215546Sopenharmony_ci foreach_in_list(ir_instruction, node, ir) { 845bf215546Sopenharmony_ci ir_variable *const var = node->as_variable(); 846bf215546Sopenharmony_ci 847bf215546Sopenharmony_ci if (var == NULL) 848bf215546Sopenharmony_ci continue; 849bf215546Sopenharmony_ci 850bf215546Sopenharmony_ci if (uniforms_only && (var->data.mode != ir_var_uniform && var->data.mode != ir_var_shader_storage)) 851bf215546Sopenharmony_ci continue; 852bf215546Sopenharmony_ci 853bf215546Sopenharmony_ci /* don't cross validate subroutine uniforms */ 854bf215546Sopenharmony_ci if (var->type->contains_subroutine()) 855bf215546Sopenharmony_ci continue; 856bf215546Sopenharmony_ci 857bf215546Sopenharmony_ci /* Don't cross validate interface instances. These are only relevant 858bf215546Sopenharmony_ci * inside a shader. The cross validation is done at the Interface Block 859bf215546Sopenharmony_ci * name level. 860bf215546Sopenharmony_ci */ 861bf215546Sopenharmony_ci if (var->is_interface_instance()) 862bf215546Sopenharmony_ci continue; 863bf215546Sopenharmony_ci 864bf215546Sopenharmony_ci /* Don't cross validate temporaries that are at global scope. These 865bf215546Sopenharmony_ci * will eventually get pulled into the shaders 'main'. 866bf215546Sopenharmony_ci */ 867bf215546Sopenharmony_ci if (var->data.mode == ir_var_temporary) 868bf215546Sopenharmony_ci continue; 869bf215546Sopenharmony_ci 870bf215546Sopenharmony_ci /* If a global with this name has already been seen, verify that the 871bf215546Sopenharmony_ci * new instance has the same type. In addition, if the globals have 872bf215546Sopenharmony_ci * initializers, the values of the initializers must be the same. 873bf215546Sopenharmony_ci */ 874bf215546Sopenharmony_ci ir_variable *const existing = variables->get_variable(var->name); 875bf215546Sopenharmony_ci if (existing != NULL) { 876bf215546Sopenharmony_ci /* Check if types match. */ 877bf215546Sopenharmony_ci if (var->type != existing->type) { 878bf215546Sopenharmony_ci if (!validate_intrastage_arrays(prog, var, existing)) { 879bf215546Sopenharmony_ci /* If it is an unsized array in a Shader Storage Block, 880bf215546Sopenharmony_ci * two different shaders can access to different elements. 881bf215546Sopenharmony_ci * Because of that, they might be converted to different 882bf215546Sopenharmony_ci * sized arrays, then check that they are compatible but 883bf215546Sopenharmony_ci * ignore the array size. 884bf215546Sopenharmony_ci */ 885bf215546Sopenharmony_ci if (!(var->data.mode == ir_var_shader_storage && 886bf215546Sopenharmony_ci var->data.from_ssbo_unsized_array && 887bf215546Sopenharmony_ci existing->data.mode == ir_var_shader_storage && 888bf215546Sopenharmony_ci existing->data.from_ssbo_unsized_array && 889bf215546Sopenharmony_ci var->type->gl_type == existing->type->gl_type)) { 890bf215546Sopenharmony_ci linker_error(prog, "%s `%s' declared as type " 891bf215546Sopenharmony_ci "`%s' and type `%s'\n", 892bf215546Sopenharmony_ci mode_string(var), 893bf215546Sopenharmony_ci var->name, var->type->name, 894bf215546Sopenharmony_ci existing->type->name); 895bf215546Sopenharmony_ci return; 896bf215546Sopenharmony_ci } 897bf215546Sopenharmony_ci } 898bf215546Sopenharmony_ci } 899bf215546Sopenharmony_ci 900bf215546Sopenharmony_ci if (var->data.explicit_location) { 901bf215546Sopenharmony_ci if (existing->data.explicit_location 902bf215546Sopenharmony_ci && (var->data.location != existing->data.location)) { 903bf215546Sopenharmony_ci linker_error(prog, "explicit locations for %s " 904bf215546Sopenharmony_ci "`%s' have differing values\n", 905bf215546Sopenharmony_ci mode_string(var), var->name); 906bf215546Sopenharmony_ci return; 907bf215546Sopenharmony_ci } 908bf215546Sopenharmony_ci 909bf215546Sopenharmony_ci if (var->data.location_frac != existing->data.location_frac) { 910bf215546Sopenharmony_ci linker_error(prog, "explicit components for %s `%s' have " 911bf215546Sopenharmony_ci "differing values\n", mode_string(var), var->name); 912bf215546Sopenharmony_ci return; 913bf215546Sopenharmony_ci } 914bf215546Sopenharmony_ci 915bf215546Sopenharmony_ci existing->data.location = var->data.location; 916bf215546Sopenharmony_ci existing->data.explicit_location = true; 917bf215546Sopenharmony_ci } else { 918bf215546Sopenharmony_ci /* Check if uniform with implicit location was marked explicit 919bf215546Sopenharmony_ci * by earlier shader stage. If so, mark it explicit in this stage 920bf215546Sopenharmony_ci * too to make sure later processing does not treat it as 921bf215546Sopenharmony_ci * implicit one. 922bf215546Sopenharmony_ci */ 923bf215546Sopenharmony_ci if (existing->data.explicit_location) { 924bf215546Sopenharmony_ci var->data.location = existing->data.location; 925bf215546Sopenharmony_ci var->data.explicit_location = true; 926bf215546Sopenharmony_ci } 927bf215546Sopenharmony_ci } 928bf215546Sopenharmony_ci 929bf215546Sopenharmony_ci /* From the GLSL 4.20 specification: 930bf215546Sopenharmony_ci * "A link error will result if two compilation units in a program 931bf215546Sopenharmony_ci * specify different integer-constant bindings for the same 932bf215546Sopenharmony_ci * opaque-uniform name. However, it is not an error to specify a 933bf215546Sopenharmony_ci * binding on some but not all declarations for the same name" 934bf215546Sopenharmony_ci */ 935bf215546Sopenharmony_ci if (var->data.explicit_binding) { 936bf215546Sopenharmony_ci if (existing->data.explicit_binding && 937bf215546Sopenharmony_ci var->data.binding != existing->data.binding) { 938bf215546Sopenharmony_ci linker_error(prog, "explicit bindings for %s " 939bf215546Sopenharmony_ci "`%s' have differing values\n", 940bf215546Sopenharmony_ci mode_string(var), var->name); 941bf215546Sopenharmony_ci return; 942bf215546Sopenharmony_ci } 943bf215546Sopenharmony_ci 944bf215546Sopenharmony_ci existing->data.binding = var->data.binding; 945bf215546Sopenharmony_ci existing->data.explicit_binding = true; 946bf215546Sopenharmony_ci } 947bf215546Sopenharmony_ci 948bf215546Sopenharmony_ci if (var->type->contains_atomic() && 949bf215546Sopenharmony_ci var->data.offset != existing->data.offset) { 950bf215546Sopenharmony_ci linker_error(prog, "offset specifications for %s " 951bf215546Sopenharmony_ci "`%s' have differing values\n", 952bf215546Sopenharmony_ci mode_string(var), var->name); 953bf215546Sopenharmony_ci return; 954bf215546Sopenharmony_ci } 955bf215546Sopenharmony_ci 956bf215546Sopenharmony_ci /* Validate layout qualifiers for gl_FragDepth. 957bf215546Sopenharmony_ci * 958bf215546Sopenharmony_ci * From the AMD/ARB_conservative_depth specs: 959bf215546Sopenharmony_ci * 960bf215546Sopenharmony_ci * "If gl_FragDepth is redeclared in any fragment shader in a 961bf215546Sopenharmony_ci * program, it must be redeclared in all fragment shaders in 962bf215546Sopenharmony_ci * that program that have static assignments to 963bf215546Sopenharmony_ci * gl_FragDepth. All redeclarations of gl_FragDepth in all 964bf215546Sopenharmony_ci * fragment shaders in a single program must have the same set 965bf215546Sopenharmony_ci * of qualifiers." 966bf215546Sopenharmony_ci */ 967bf215546Sopenharmony_ci if (strcmp(var->name, "gl_FragDepth") == 0) { 968bf215546Sopenharmony_ci bool layout_declared = var->data.depth_layout != ir_depth_layout_none; 969bf215546Sopenharmony_ci bool layout_differs = 970bf215546Sopenharmony_ci var->data.depth_layout != existing->data.depth_layout; 971bf215546Sopenharmony_ci 972bf215546Sopenharmony_ci if (layout_declared && layout_differs) { 973bf215546Sopenharmony_ci linker_error(prog, 974bf215546Sopenharmony_ci "All redeclarations of gl_FragDepth in all " 975bf215546Sopenharmony_ci "fragment shaders in a single program must have " 976bf215546Sopenharmony_ci "the same set of qualifiers.\n"); 977bf215546Sopenharmony_ci } 978bf215546Sopenharmony_ci 979bf215546Sopenharmony_ci if (var->data.used && layout_differs) { 980bf215546Sopenharmony_ci linker_error(prog, 981bf215546Sopenharmony_ci "If gl_FragDepth is redeclared with a layout " 982bf215546Sopenharmony_ci "qualifier in any fragment shader, it must be " 983bf215546Sopenharmony_ci "redeclared with the same layout qualifier in " 984bf215546Sopenharmony_ci "all fragment shaders that have assignments to " 985bf215546Sopenharmony_ci "gl_FragDepth\n"); 986bf215546Sopenharmony_ci } 987bf215546Sopenharmony_ci } 988bf215546Sopenharmony_ci 989bf215546Sopenharmony_ci /* Page 35 (page 41 of the PDF) of the GLSL 4.20 spec says: 990bf215546Sopenharmony_ci * 991bf215546Sopenharmony_ci * "If a shared global has multiple initializers, the 992bf215546Sopenharmony_ci * initializers must all be constant expressions, and they 993bf215546Sopenharmony_ci * must all have the same value. Otherwise, a link error will 994bf215546Sopenharmony_ci * result. (A shared global having only one initializer does 995bf215546Sopenharmony_ci * not require that initializer to be a constant expression.)" 996bf215546Sopenharmony_ci * 997bf215546Sopenharmony_ci * Previous to 4.20 the GLSL spec simply said that initializers 998bf215546Sopenharmony_ci * must have the same value. In this case of non-constant 999bf215546Sopenharmony_ci * initializers, this was impossible to determine. As a result, 1000bf215546Sopenharmony_ci * no vendor actually implemented that behavior. The 4.20 1001bf215546Sopenharmony_ci * behavior matches the implemented behavior of at least one other 1002bf215546Sopenharmony_ci * vendor, so we'll implement that for all GLSL versions. 1003bf215546Sopenharmony_ci * If (at least) one of these constant expressions is implicit, 1004bf215546Sopenharmony_ci * because it was added by glsl_zero_init, we skip the verification. 1005bf215546Sopenharmony_ci */ 1006bf215546Sopenharmony_ci if (var->constant_initializer != NULL) { 1007bf215546Sopenharmony_ci if (existing->constant_initializer != NULL && 1008bf215546Sopenharmony_ci !existing->data.is_implicit_initializer && 1009bf215546Sopenharmony_ci !var->data.is_implicit_initializer) { 1010bf215546Sopenharmony_ci if (!var->constant_initializer->has_value(existing->constant_initializer)) { 1011bf215546Sopenharmony_ci linker_error(prog, "initializers for %s " 1012bf215546Sopenharmony_ci "`%s' have differing values\n", 1013bf215546Sopenharmony_ci mode_string(var), var->name); 1014bf215546Sopenharmony_ci return; 1015bf215546Sopenharmony_ci } 1016bf215546Sopenharmony_ci } else { 1017bf215546Sopenharmony_ci /* If the first-seen instance of a particular uniform did 1018bf215546Sopenharmony_ci * not have an initializer but a later instance does, 1019bf215546Sopenharmony_ci * replace the former with the later. 1020bf215546Sopenharmony_ci */ 1021bf215546Sopenharmony_ci if (!var->data.is_implicit_initializer) 1022bf215546Sopenharmony_ci variables->replace_variable(existing->name, var); 1023bf215546Sopenharmony_ci } 1024bf215546Sopenharmony_ci } 1025bf215546Sopenharmony_ci 1026bf215546Sopenharmony_ci if (var->data.has_initializer) { 1027bf215546Sopenharmony_ci if (existing->data.has_initializer 1028bf215546Sopenharmony_ci && (var->constant_initializer == NULL 1029bf215546Sopenharmony_ci || existing->constant_initializer == NULL)) { 1030bf215546Sopenharmony_ci linker_error(prog, 1031bf215546Sopenharmony_ci "shared global variable `%s' has multiple " 1032bf215546Sopenharmony_ci "non-constant initializers.\n", 1033bf215546Sopenharmony_ci var->name); 1034bf215546Sopenharmony_ci return; 1035bf215546Sopenharmony_ci } 1036bf215546Sopenharmony_ci } 1037bf215546Sopenharmony_ci 1038bf215546Sopenharmony_ci if (existing->data.explicit_invariant != var->data.explicit_invariant) { 1039bf215546Sopenharmony_ci linker_error(prog, "declarations for %s `%s' have " 1040bf215546Sopenharmony_ci "mismatching invariant qualifiers\n", 1041bf215546Sopenharmony_ci mode_string(var), var->name); 1042bf215546Sopenharmony_ci return; 1043bf215546Sopenharmony_ci } 1044bf215546Sopenharmony_ci if (existing->data.centroid != var->data.centroid) { 1045bf215546Sopenharmony_ci linker_error(prog, "declarations for %s `%s' have " 1046bf215546Sopenharmony_ci "mismatching centroid qualifiers\n", 1047bf215546Sopenharmony_ci mode_string(var), var->name); 1048bf215546Sopenharmony_ci return; 1049bf215546Sopenharmony_ci } 1050bf215546Sopenharmony_ci if (existing->data.sample != var->data.sample) { 1051bf215546Sopenharmony_ci linker_error(prog, "declarations for %s `%s` have " 1052bf215546Sopenharmony_ci "mismatching sample qualifiers\n", 1053bf215546Sopenharmony_ci mode_string(var), var->name); 1054bf215546Sopenharmony_ci return; 1055bf215546Sopenharmony_ci } 1056bf215546Sopenharmony_ci if (existing->data.image_format != var->data.image_format) { 1057bf215546Sopenharmony_ci linker_error(prog, "declarations for %s `%s` have " 1058bf215546Sopenharmony_ci "mismatching image format qualifiers\n", 1059bf215546Sopenharmony_ci mode_string(var), var->name); 1060bf215546Sopenharmony_ci return; 1061bf215546Sopenharmony_ci } 1062bf215546Sopenharmony_ci 1063bf215546Sopenharmony_ci /* Check the precision qualifier matches for uniform variables on 1064bf215546Sopenharmony_ci * GLSL ES. 1065bf215546Sopenharmony_ci */ 1066bf215546Sopenharmony_ci if (!consts->AllowGLSLRelaxedES && 1067bf215546Sopenharmony_ci prog->IsES && !var->get_interface_type() && 1068bf215546Sopenharmony_ci existing->data.precision != var->data.precision) { 1069bf215546Sopenharmony_ci if ((existing->data.used && var->data.used) || prog->data->Version >= 300) { 1070bf215546Sopenharmony_ci linker_error(prog, "declarations for %s `%s` have " 1071bf215546Sopenharmony_ci "mismatching precision qualifiers\n", 1072bf215546Sopenharmony_ci mode_string(var), var->name); 1073bf215546Sopenharmony_ci return; 1074bf215546Sopenharmony_ci } else { 1075bf215546Sopenharmony_ci linker_warning(prog, "declarations for %s `%s` have " 1076bf215546Sopenharmony_ci "mismatching precision qualifiers\n", 1077bf215546Sopenharmony_ci mode_string(var), var->name); 1078bf215546Sopenharmony_ci } 1079bf215546Sopenharmony_ci } 1080bf215546Sopenharmony_ci 1081bf215546Sopenharmony_ci /* In OpenGL GLSL 3.20 spec, section 4.3.9: 1082bf215546Sopenharmony_ci * 1083bf215546Sopenharmony_ci * "It is a link-time error if any particular shader interface 1084bf215546Sopenharmony_ci * contains: 1085bf215546Sopenharmony_ci * 1086bf215546Sopenharmony_ci * - two different blocks, each having no instance name, and each 1087bf215546Sopenharmony_ci * having a member of the same name, or 1088bf215546Sopenharmony_ci * 1089bf215546Sopenharmony_ci * - a variable outside a block, and a block with no instance name, 1090bf215546Sopenharmony_ci * where the variable has the same name as a member in the block." 1091bf215546Sopenharmony_ci */ 1092bf215546Sopenharmony_ci const glsl_type *var_itype = var->get_interface_type(); 1093bf215546Sopenharmony_ci const glsl_type *existing_itype = existing->get_interface_type(); 1094bf215546Sopenharmony_ci if (var_itype != existing_itype) { 1095bf215546Sopenharmony_ci if (!var_itype || !existing_itype) { 1096bf215546Sopenharmony_ci linker_error(prog, "declarations for %s `%s` are inside block " 1097bf215546Sopenharmony_ci "`%s` and outside a block", 1098bf215546Sopenharmony_ci mode_string(var), var->name, 1099bf215546Sopenharmony_ci var_itype ? var_itype->name : existing_itype->name); 1100bf215546Sopenharmony_ci return; 1101bf215546Sopenharmony_ci } else if (strcmp(var_itype->name, existing_itype->name) != 0) { 1102bf215546Sopenharmony_ci linker_error(prog, "declarations for %s `%s` are inside blocks " 1103bf215546Sopenharmony_ci "`%s` and `%s`", 1104bf215546Sopenharmony_ci mode_string(var), var->name, 1105bf215546Sopenharmony_ci existing_itype->name, 1106bf215546Sopenharmony_ci var_itype->name); 1107bf215546Sopenharmony_ci return; 1108bf215546Sopenharmony_ci } 1109bf215546Sopenharmony_ci } 1110bf215546Sopenharmony_ci } else 1111bf215546Sopenharmony_ci variables->add_variable(var); 1112bf215546Sopenharmony_ci } 1113bf215546Sopenharmony_ci} 1114bf215546Sopenharmony_ci 1115bf215546Sopenharmony_ci 1116bf215546Sopenharmony_ci/** 1117bf215546Sopenharmony_ci * Perform validation of uniforms used across multiple shader stages 1118bf215546Sopenharmony_ci */ 1119bf215546Sopenharmony_cistatic void 1120bf215546Sopenharmony_cicross_validate_uniforms(const struct gl_constants *consts, 1121bf215546Sopenharmony_ci struct gl_shader_program *prog) 1122bf215546Sopenharmony_ci{ 1123bf215546Sopenharmony_ci glsl_symbol_table variables; 1124bf215546Sopenharmony_ci for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 1125bf215546Sopenharmony_ci if (prog->_LinkedShaders[i] == NULL) 1126bf215546Sopenharmony_ci continue; 1127bf215546Sopenharmony_ci 1128bf215546Sopenharmony_ci cross_validate_globals(consts, prog, prog->_LinkedShaders[i]->ir, 1129bf215546Sopenharmony_ci &variables, true); 1130bf215546Sopenharmony_ci } 1131bf215546Sopenharmony_ci} 1132bf215546Sopenharmony_ci 1133bf215546Sopenharmony_ci/** 1134bf215546Sopenharmony_ci * Accumulates the array of buffer blocks and checks that all definitions of 1135bf215546Sopenharmony_ci * blocks agree on their contents. 1136bf215546Sopenharmony_ci */ 1137bf215546Sopenharmony_cistatic bool 1138bf215546Sopenharmony_ciinterstage_cross_validate_uniform_blocks(struct gl_shader_program *prog, 1139bf215546Sopenharmony_ci bool validate_ssbo) 1140bf215546Sopenharmony_ci{ 1141bf215546Sopenharmony_ci int *ifc_blk_stage_idx[MESA_SHADER_STAGES]; 1142bf215546Sopenharmony_ci struct gl_uniform_block *blks = NULL; 1143bf215546Sopenharmony_ci unsigned *num_blks = validate_ssbo ? &prog->data->NumShaderStorageBlocks : 1144bf215546Sopenharmony_ci &prog->data->NumUniformBlocks; 1145bf215546Sopenharmony_ci 1146bf215546Sopenharmony_ci unsigned max_num_buffer_blocks = 0; 1147bf215546Sopenharmony_ci for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 1148bf215546Sopenharmony_ci if (prog->_LinkedShaders[i]) { 1149bf215546Sopenharmony_ci if (validate_ssbo) { 1150bf215546Sopenharmony_ci max_num_buffer_blocks += 1151bf215546Sopenharmony_ci prog->_LinkedShaders[i]->Program->info.num_ssbos; 1152bf215546Sopenharmony_ci } else { 1153bf215546Sopenharmony_ci max_num_buffer_blocks += 1154bf215546Sopenharmony_ci prog->_LinkedShaders[i]->Program->info.num_ubos; 1155bf215546Sopenharmony_ci } 1156bf215546Sopenharmony_ci } 1157bf215546Sopenharmony_ci } 1158bf215546Sopenharmony_ci 1159bf215546Sopenharmony_ci for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 1160bf215546Sopenharmony_ci struct gl_linked_shader *sh = prog->_LinkedShaders[i]; 1161bf215546Sopenharmony_ci 1162bf215546Sopenharmony_ci ifc_blk_stage_idx[i] = 1163bf215546Sopenharmony_ci (int *) malloc(sizeof(int) * max_num_buffer_blocks); 1164bf215546Sopenharmony_ci for (unsigned int j = 0; j < max_num_buffer_blocks; j++) 1165bf215546Sopenharmony_ci ifc_blk_stage_idx[i][j] = -1; 1166bf215546Sopenharmony_ci 1167bf215546Sopenharmony_ci if (sh == NULL) 1168bf215546Sopenharmony_ci continue; 1169bf215546Sopenharmony_ci 1170bf215546Sopenharmony_ci unsigned sh_num_blocks; 1171bf215546Sopenharmony_ci struct gl_uniform_block **sh_blks; 1172bf215546Sopenharmony_ci if (validate_ssbo) { 1173bf215546Sopenharmony_ci sh_num_blocks = prog->_LinkedShaders[i]->Program->info.num_ssbos; 1174bf215546Sopenharmony_ci sh_blks = sh->Program->sh.ShaderStorageBlocks; 1175bf215546Sopenharmony_ci } else { 1176bf215546Sopenharmony_ci sh_num_blocks = prog->_LinkedShaders[i]->Program->info.num_ubos; 1177bf215546Sopenharmony_ci sh_blks = sh->Program->sh.UniformBlocks; 1178bf215546Sopenharmony_ci } 1179bf215546Sopenharmony_ci 1180bf215546Sopenharmony_ci for (unsigned int j = 0; j < sh_num_blocks; j++) { 1181bf215546Sopenharmony_ci int index = link_cross_validate_uniform_block(prog->data, &blks, 1182bf215546Sopenharmony_ci num_blks, sh_blks[j]); 1183bf215546Sopenharmony_ci 1184bf215546Sopenharmony_ci if (index == -1) { 1185bf215546Sopenharmony_ci linker_error(prog, "buffer block `%s' has mismatching " 1186bf215546Sopenharmony_ci "definitions\n", sh_blks[j]->name.string); 1187bf215546Sopenharmony_ci 1188bf215546Sopenharmony_ci for (unsigned k = 0; k <= i; k++) { 1189bf215546Sopenharmony_ci free(ifc_blk_stage_idx[k]); 1190bf215546Sopenharmony_ci } 1191bf215546Sopenharmony_ci 1192bf215546Sopenharmony_ci /* Reset the block count. This will help avoid various segfaults 1193bf215546Sopenharmony_ci * from api calls that assume the array exists due to the count 1194bf215546Sopenharmony_ci * being non-zero. 1195bf215546Sopenharmony_ci */ 1196bf215546Sopenharmony_ci *num_blks = 0; 1197bf215546Sopenharmony_ci return false; 1198bf215546Sopenharmony_ci } 1199bf215546Sopenharmony_ci 1200bf215546Sopenharmony_ci ifc_blk_stage_idx[i][index] = j; 1201bf215546Sopenharmony_ci } 1202bf215546Sopenharmony_ci } 1203bf215546Sopenharmony_ci 1204bf215546Sopenharmony_ci /* Update per stage block pointers to point to the program list. 1205bf215546Sopenharmony_ci * FIXME: We should be able to free the per stage blocks here. 1206bf215546Sopenharmony_ci */ 1207bf215546Sopenharmony_ci for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 1208bf215546Sopenharmony_ci for (unsigned j = 0; j < *num_blks; j++) { 1209bf215546Sopenharmony_ci int stage_index = ifc_blk_stage_idx[i][j]; 1210bf215546Sopenharmony_ci 1211bf215546Sopenharmony_ci if (stage_index != -1) { 1212bf215546Sopenharmony_ci struct gl_linked_shader *sh = prog->_LinkedShaders[i]; 1213bf215546Sopenharmony_ci 1214bf215546Sopenharmony_ci struct gl_uniform_block **sh_blks = validate_ssbo ? 1215bf215546Sopenharmony_ci sh->Program->sh.ShaderStorageBlocks : 1216bf215546Sopenharmony_ci sh->Program->sh.UniformBlocks; 1217bf215546Sopenharmony_ci 1218bf215546Sopenharmony_ci blks[j].stageref |= sh_blks[stage_index]->stageref; 1219bf215546Sopenharmony_ci sh_blks[stage_index] = &blks[j]; 1220bf215546Sopenharmony_ci } 1221bf215546Sopenharmony_ci } 1222bf215546Sopenharmony_ci } 1223bf215546Sopenharmony_ci 1224bf215546Sopenharmony_ci for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 1225bf215546Sopenharmony_ci free(ifc_blk_stage_idx[i]); 1226bf215546Sopenharmony_ci } 1227bf215546Sopenharmony_ci 1228bf215546Sopenharmony_ci if (validate_ssbo) 1229bf215546Sopenharmony_ci prog->data->ShaderStorageBlocks = blks; 1230bf215546Sopenharmony_ci else 1231bf215546Sopenharmony_ci prog->data->UniformBlocks = blks; 1232bf215546Sopenharmony_ci 1233bf215546Sopenharmony_ci return true; 1234bf215546Sopenharmony_ci} 1235bf215546Sopenharmony_ci 1236bf215546Sopenharmony_ci/** 1237bf215546Sopenharmony_ci * Verifies the invariance of built-in special variables. 1238bf215546Sopenharmony_ci */ 1239bf215546Sopenharmony_cistatic bool 1240bf215546Sopenharmony_civalidate_invariant_builtins(struct gl_shader_program *prog, 1241bf215546Sopenharmony_ci const gl_linked_shader *vert, 1242bf215546Sopenharmony_ci const gl_linked_shader *frag) 1243bf215546Sopenharmony_ci{ 1244bf215546Sopenharmony_ci const ir_variable *var_vert; 1245bf215546Sopenharmony_ci const ir_variable *var_frag; 1246bf215546Sopenharmony_ci 1247bf215546Sopenharmony_ci if (!vert || !frag) 1248bf215546Sopenharmony_ci return true; 1249bf215546Sopenharmony_ci 1250bf215546Sopenharmony_ci /* 1251bf215546Sopenharmony_ci * From OpenGL ES Shading Language 1.0 specification 1252bf215546Sopenharmony_ci * (4.6.4 Invariance and Linkage): 1253bf215546Sopenharmony_ci * "The invariance of varyings that are declared in both the vertex and 1254bf215546Sopenharmony_ci * fragment shaders must match. For the built-in special variables, 1255bf215546Sopenharmony_ci * gl_FragCoord can only be declared invariant if and only if 1256bf215546Sopenharmony_ci * gl_Position is declared invariant. Similarly gl_PointCoord can only 1257bf215546Sopenharmony_ci * be declared invariant if and only if gl_PointSize is declared 1258bf215546Sopenharmony_ci * invariant. It is an error to declare gl_FrontFacing as invariant. 1259bf215546Sopenharmony_ci * The invariance of gl_FrontFacing is the same as the invariance of 1260bf215546Sopenharmony_ci * gl_Position." 1261bf215546Sopenharmony_ci */ 1262bf215546Sopenharmony_ci var_frag = frag->symbols->get_variable("gl_FragCoord"); 1263bf215546Sopenharmony_ci if (var_frag && var_frag->data.invariant) { 1264bf215546Sopenharmony_ci var_vert = vert->symbols->get_variable("gl_Position"); 1265bf215546Sopenharmony_ci if (var_vert && !var_vert->data.invariant) { 1266bf215546Sopenharmony_ci linker_error(prog, 1267bf215546Sopenharmony_ci "fragment shader built-in `%s' has invariant qualifier, " 1268bf215546Sopenharmony_ci "but vertex shader built-in `%s' lacks invariant qualifier\n", 1269bf215546Sopenharmony_ci var_frag->name, var_vert->name); 1270bf215546Sopenharmony_ci return false; 1271bf215546Sopenharmony_ci } 1272bf215546Sopenharmony_ci } 1273bf215546Sopenharmony_ci 1274bf215546Sopenharmony_ci var_frag = frag->symbols->get_variable("gl_PointCoord"); 1275bf215546Sopenharmony_ci if (var_frag && var_frag->data.invariant) { 1276bf215546Sopenharmony_ci var_vert = vert->symbols->get_variable("gl_PointSize"); 1277bf215546Sopenharmony_ci if (var_vert && !var_vert->data.invariant) { 1278bf215546Sopenharmony_ci linker_error(prog, 1279bf215546Sopenharmony_ci "fragment shader built-in `%s' has invariant qualifier, " 1280bf215546Sopenharmony_ci "but vertex shader built-in `%s' lacks invariant qualifier\n", 1281bf215546Sopenharmony_ci var_frag->name, var_vert->name); 1282bf215546Sopenharmony_ci return false; 1283bf215546Sopenharmony_ci } 1284bf215546Sopenharmony_ci } 1285bf215546Sopenharmony_ci 1286bf215546Sopenharmony_ci var_frag = frag->symbols->get_variable("gl_FrontFacing"); 1287bf215546Sopenharmony_ci if (var_frag && var_frag->data.invariant) { 1288bf215546Sopenharmony_ci linker_error(prog, 1289bf215546Sopenharmony_ci "fragment shader built-in `%s' can not be declared as invariant\n", 1290bf215546Sopenharmony_ci var_frag->name); 1291bf215546Sopenharmony_ci return false; 1292bf215546Sopenharmony_ci } 1293bf215546Sopenharmony_ci 1294bf215546Sopenharmony_ci return true; 1295bf215546Sopenharmony_ci} 1296bf215546Sopenharmony_ci 1297bf215546Sopenharmony_ci/** 1298bf215546Sopenharmony_ci * Populates a shaders symbol table with all global declarations 1299bf215546Sopenharmony_ci */ 1300bf215546Sopenharmony_cistatic void 1301bf215546Sopenharmony_cipopulate_symbol_table(gl_linked_shader *sh, glsl_symbol_table *symbols) 1302bf215546Sopenharmony_ci{ 1303bf215546Sopenharmony_ci sh->symbols = new(sh) glsl_symbol_table; 1304bf215546Sopenharmony_ci 1305bf215546Sopenharmony_ci _mesa_glsl_copy_symbols_from_table(sh->ir, symbols, sh->symbols); 1306bf215546Sopenharmony_ci} 1307bf215546Sopenharmony_ci 1308bf215546Sopenharmony_ci 1309bf215546Sopenharmony_ci/** 1310bf215546Sopenharmony_ci * Remap variables referenced in an instruction tree 1311bf215546Sopenharmony_ci * 1312bf215546Sopenharmony_ci * This is used when instruction trees are cloned from one shader and placed in 1313bf215546Sopenharmony_ci * another. These trees will contain references to \c ir_variable nodes that 1314bf215546Sopenharmony_ci * do not exist in the target shader. This function finds these \c ir_variable 1315bf215546Sopenharmony_ci * references and replaces the references with matching variables in the target 1316bf215546Sopenharmony_ci * shader. 1317bf215546Sopenharmony_ci * 1318bf215546Sopenharmony_ci * If there is no matching variable in the target shader, a clone of the 1319bf215546Sopenharmony_ci * \c ir_variable is made and added to the target shader. The new variable is 1320bf215546Sopenharmony_ci * added to \b both the instruction stream and the symbol table. 1321bf215546Sopenharmony_ci * 1322bf215546Sopenharmony_ci * \param inst IR tree that is to be processed. 1323bf215546Sopenharmony_ci * \param symbols Symbol table containing global scope symbols in the 1324bf215546Sopenharmony_ci * linked shader. 1325bf215546Sopenharmony_ci * \param instructions Instruction stream where new variable declarations 1326bf215546Sopenharmony_ci * should be added. 1327bf215546Sopenharmony_ci */ 1328bf215546Sopenharmony_cistatic void 1329bf215546Sopenharmony_ciremap_variables(ir_instruction *inst, struct gl_linked_shader *target, 1330bf215546Sopenharmony_ci hash_table *temps) 1331bf215546Sopenharmony_ci{ 1332bf215546Sopenharmony_ci class remap_visitor : public ir_hierarchical_visitor { 1333bf215546Sopenharmony_ci public: 1334bf215546Sopenharmony_ci remap_visitor(struct gl_linked_shader *target, hash_table *temps) 1335bf215546Sopenharmony_ci { 1336bf215546Sopenharmony_ci this->target = target; 1337bf215546Sopenharmony_ci this->symbols = target->symbols; 1338bf215546Sopenharmony_ci this->instructions = target->ir; 1339bf215546Sopenharmony_ci this->temps = temps; 1340bf215546Sopenharmony_ci } 1341bf215546Sopenharmony_ci 1342bf215546Sopenharmony_ci virtual ir_visitor_status visit(ir_dereference_variable *ir) 1343bf215546Sopenharmony_ci { 1344bf215546Sopenharmony_ci if (ir->var->data.mode == ir_var_temporary) { 1345bf215546Sopenharmony_ci hash_entry *entry = _mesa_hash_table_search(temps, ir->var); 1346bf215546Sopenharmony_ci ir_variable *var = entry ? (ir_variable *) entry->data : NULL; 1347bf215546Sopenharmony_ci 1348bf215546Sopenharmony_ci assert(var != NULL); 1349bf215546Sopenharmony_ci ir->var = var; 1350bf215546Sopenharmony_ci return visit_continue; 1351bf215546Sopenharmony_ci } 1352bf215546Sopenharmony_ci 1353bf215546Sopenharmony_ci ir_variable *const existing = 1354bf215546Sopenharmony_ci this->symbols->get_variable(ir->var->name); 1355bf215546Sopenharmony_ci if (existing != NULL) 1356bf215546Sopenharmony_ci ir->var = existing; 1357bf215546Sopenharmony_ci else { 1358bf215546Sopenharmony_ci ir_variable *copy = ir->var->clone(this->target, NULL); 1359bf215546Sopenharmony_ci 1360bf215546Sopenharmony_ci this->symbols->add_variable(copy); 1361bf215546Sopenharmony_ci this->instructions->push_head(copy); 1362bf215546Sopenharmony_ci ir->var = copy; 1363bf215546Sopenharmony_ci } 1364bf215546Sopenharmony_ci 1365bf215546Sopenharmony_ci return visit_continue; 1366bf215546Sopenharmony_ci } 1367bf215546Sopenharmony_ci 1368bf215546Sopenharmony_ci private: 1369bf215546Sopenharmony_ci struct gl_linked_shader *target; 1370bf215546Sopenharmony_ci glsl_symbol_table *symbols; 1371bf215546Sopenharmony_ci exec_list *instructions; 1372bf215546Sopenharmony_ci hash_table *temps; 1373bf215546Sopenharmony_ci }; 1374bf215546Sopenharmony_ci 1375bf215546Sopenharmony_ci remap_visitor v(target, temps); 1376bf215546Sopenharmony_ci 1377bf215546Sopenharmony_ci inst->accept(&v); 1378bf215546Sopenharmony_ci} 1379bf215546Sopenharmony_ci 1380bf215546Sopenharmony_ci 1381bf215546Sopenharmony_ci/** 1382bf215546Sopenharmony_ci * Move non-declarations from one instruction stream to another 1383bf215546Sopenharmony_ci * 1384bf215546Sopenharmony_ci * The intended usage pattern of this function is to pass the pointer to the 1385bf215546Sopenharmony_ci * head sentinel of a list (i.e., a pointer to the list cast to an \c exec_node 1386bf215546Sopenharmony_ci * pointer) for \c last and \c false for \c make_copies on the first 1387bf215546Sopenharmony_ci * call. Successive calls pass the return value of the previous call for 1388bf215546Sopenharmony_ci * \c last and \c true for \c make_copies. 1389bf215546Sopenharmony_ci * 1390bf215546Sopenharmony_ci * \param instructions Source instruction stream 1391bf215546Sopenharmony_ci * \param last Instruction after which new instructions should be 1392bf215546Sopenharmony_ci * inserted in the target instruction stream 1393bf215546Sopenharmony_ci * \param make_copies Flag selecting whether instructions in \c instructions 1394bf215546Sopenharmony_ci * should be copied (via \c ir_instruction::clone) into the 1395bf215546Sopenharmony_ci * target list or moved. 1396bf215546Sopenharmony_ci * 1397bf215546Sopenharmony_ci * \return 1398bf215546Sopenharmony_ci * The new "last" instruction in the target instruction stream. This pointer 1399bf215546Sopenharmony_ci * is suitable for use as the \c last parameter of a later call to this 1400bf215546Sopenharmony_ci * function. 1401bf215546Sopenharmony_ci */ 1402bf215546Sopenharmony_cistatic exec_node * 1403bf215546Sopenharmony_cimove_non_declarations(exec_list *instructions, exec_node *last, 1404bf215546Sopenharmony_ci bool make_copies, gl_linked_shader *target) 1405bf215546Sopenharmony_ci{ 1406bf215546Sopenharmony_ci hash_table *temps = NULL; 1407bf215546Sopenharmony_ci 1408bf215546Sopenharmony_ci if (make_copies) 1409bf215546Sopenharmony_ci temps = _mesa_pointer_hash_table_create(NULL); 1410bf215546Sopenharmony_ci 1411bf215546Sopenharmony_ci foreach_in_list_safe(ir_instruction, inst, instructions) { 1412bf215546Sopenharmony_ci if (inst->as_function()) 1413bf215546Sopenharmony_ci continue; 1414bf215546Sopenharmony_ci 1415bf215546Sopenharmony_ci ir_variable *var = inst->as_variable(); 1416bf215546Sopenharmony_ci if ((var != NULL) && (var->data.mode != ir_var_temporary)) 1417bf215546Sopenharmony_ci continue; 1418bf215546Sopenharmony_ci 1419bf215546Sopenharmony_ci assert(inst->as_assignment() 1420bf215546Sopenharmony_ci || inst->as_call() 1421bf215546Sopenharmony_ci || inst->as_if() /* for initializers with the ?: operator */ 1422bf215546Sopenharmony_ci || ((var != NULL) && (var->data.mode == ir_var_temporary))); 1423bf215546Sopenharmony_ci 1424bf215546Sopenharmony_ci if (make_copies) { 1425bf215546Sopenharmony_ci inst = inst->clone(target, NULL); 1426bf215546Sopenharmony_ci 1427bf215546Sopenharmony_ci if (var != NULL) 1428bf215546Sopenharmony_ci _mesa_hash_table_insert(temps, var, inst); 1429bf215546Sopenharmony_ci else 1430bf215546Sopenharmony_ci remap_variables(inst, target, temps); 1431bf215546Sopenharmony_ci } else { 1432bf215546Sopenharmony_ci inst->remove(); 1433bf215546Sopenharmony_ci } 1434bf215546Sopenharmony_ci 1435bf215546Sopenharmony_ci last->insert_after(inst); 1436bf215546Sopenharmony_ci last = inst; 1437bf215546Sopenharmony_ci } 1438bf215546Sopenharmony_ci 1439bf215546Sopenharmony_ci if (make_copies) 1440bf215546Sopenharmony_ci _mesa_hash_table_destroy(temps, NULL); 1441bf215546Sopenharmony_ci 1442bf215546Sopenharmony_ci return last; 1443bf215546Sopenharmony_ci} 1444bf215546Sopenharmony_ci 1445bf215546Sopenharmony_ci 1446bf215546Sopenharmony_ci/** 1447bf215546Sopenharmony_ci * This class is only used in link_intrastage_shaders() below but declaring 1448bf215546Sopenharmony_ci * it inside that function leads to compiler warnings with some versions of 1449bf215546Sopenharmony_ci * gcc. 1450bf215546Sopenharmony_ci */ 1451bf215546Sopenharmony_ciclass array_sizing_visitor : public deref_type_updater { 1452bf215546Sopenharmony_cipublic: 1453bf215546Sopenharmony_ci using deref_type_updater::visit; 1454bf215546Sopenharmony_ci 1455bf215546Sopenharmony_ci array_sizing_visitor() 1456bf215546Sopenharmony_ci : mem_ctx(ralloc_context(NULL)), 1457bf215546Sopenharmony_ci unnamed_interfaces(_mesa_pointer_hash_table_create(NULL)) 1458bf215546Sopenharmony_ci { 1459bf215546Sopenharmony_ci } 1460bf215546Sopenharmony_ci 1461bf215546Sopenharmony_ci ~array_sizing_visitor() 1462bf215546Sopenharmony_ci { 1463bf215546Sopenharmony_ci _mesa_hash_table_destroy(this->unnamed_interfaces, NULL); 1464bf215546Sopenharmony_ci ralloc_free(this->mem_ctx); 1465bf215546Sopenharmony_ci } 1466bf215546Sopenharmony_ci 1467bf215546Sopenharmony_ci virtual ir_visitor_status visit(ir_variable *var) 1468bf215546Sopenharmony_ci { 1469bf215546Sopenharmony_ci const glsl_type *type_without_array; 1470bf215546Sopenharmony_ci bool implicit_sized_array = var->data.implicit_sized_array; 1471bf215546Sopenharmony_ci fixup_type(&var->type, var->data.max_array_access, 1472bf215546Sopenharmony_ci var->data.from_ssbo_unsized_array, 1473bf215546Sopenharmony_ci &implicit_sized_array); 1474bf215546Sopenharmony_ci var->data.implicit_sized_array = implicit_sized_array; 1475bf215546Sopenharmony_ci type_without_array = var->type->without_array(); 1476bf215546Sopenharmony_ci if (var->type->is_interface()) { 1477bf215546Sopenharmony_ci if (interface_contains_unsized_arrays(var->type)) { 1478bf215546Sopenharmony_ci const glsl_type *new_type = 1479bf215546Sopenharmony_ci resize_interface_members(var->type, 1480bf215546Sopenharmony_ci var->get_max_ifc_array_access(), 1481bf215546Sopenharmony_ci var->is_in_shader_storage_block()); 1482bf215546Sopenharmony_ci var->type = new_type; 1483bf215546Sopenharmony_ci var->change_interface_type(new_type); 1484bf215546Sopenharmony_ci } 1485bf215546Sopenharmony_ci } else if (type_without_array->is_interface()) { 1486bf215546Sopenharmony_ci if (interface_contains_unsized_arrays(type_without_array)) { 1487bf215546Sopenharmony_ci const glsl_type *new_type = 1488bf215546Sopenharmony_ci resize_interface_members(type_without_array, 1489bf215546Sopenharmony_ci var->get_max_ifc_array_access(), 1490bf215546Sopenharmony_ci var->is_in_shader_storage_block()); 1491bf215546Sopenharmony_ci var->change_interface_type(new_type); 1492bf215546Sopenharmony_ci var->type = update_interface_members_array(var->type, new_type); 1493bf215546Sopenharmony_ci } 1494bf215546Sopenharmony_ci } else if (const glsl_type *ifc_type = var->get_interface_type()) { 1495bf215546Sopenharmony_ci /* Store a pointer to the variable in the unnamed_interfaces 1496bf215546Sopenharmony_ci * hashtable. 1497bf215546Sopenharmony_ci */ 1498bf215546Sopenharmony_ci hash_entry *entry = 1499bf215546Sopenharmony_ci _mesa_hash_table_search(this->unnamed_interfaces, 1500bf215546Sopenharmony_ci ifc_type); 1501bf215546Sopenharmony_ci 1502bf215546Sopenharmony_ci ir_variable **interface_vars = entry ? (ir_variable **) entry->data : NULL; 1503bf215546Sopenharmony_ci 1504bf215546Sopenharmony_ci if (interface_vars == NULL) { 1505bf215546Sopenharmony_ci interface_vars = rzalloc_array(mem_ctx, ir_variable *, 1506bf215546Sopenharmony_ci ifc_type->length); 1507bf215546Sopenharmony_ci _mesa_hash_table_insert(this->unnamed_interfaces, ifc_type, 1508bf215546Sopenharmony_ci interface_vars); 1509bf215546Sopenharmony_ci } 1510bf215546Sopenharmony_ci unsigned index = ifc_type->field_index(var->name); 1511bf215546Sopenharmony_ci assert(index < ifc_type->length); 1512bf215546Sopenharmony_ci assert(interface_vars[index] == NULL); 1513bf215546Sopenharmony_ci interface_vars[index] = var; 1514bf215546Sopenharmony_ci } 1515bf215546Sopenharmony_ci return visit_continue; 1516bf215546Sopenharmony_ci } 1517bf215546Sopenharmony_ci 1518bf215546Sopenharmony_ci /** 1519bf215546Sopenharmony_ci * For each unnamed interface block that was discovered while running the 1520bf215546Sopenharmony_ci * visitor, adjust the interface type to reflect the newly assigned array 1521bf215546Sopenharmony_ci * sizes, and fix up the ir_variable nodes to point to the new interface 1522bf215546Sopenharmony_ci * type. 1523bf215546Sopenharmony_ci */ 1524bf215546Sopenharmony_ci void fixup_unnamed_interface_types() 1525bf215546Sopenharmony_ci { 1526bf215546Sopenharmony_ci hash_table_call_foreach(this->unnamed_interfaces, 1527bf215546Sopenharmony_ci fixup_unnamed_interface_type, NULL); 1528bf215546Sopenharmony_ci } 1529bf215546Sopenharmony_ci 1530bf215546Sopenharmony_ciprivate: 1531bf215546Sopenharmony_ci /** 1532bf215546Sopenharmony_ci * If the type pointed to by \c type represents an unsized array, replace 1533bf215546Sopenharmony_ci * it with a sized array whose size is determined by max_array_access. 1534bf215546Sopenharmony_ci */ 1535bf215546Sopenharmony_ci static void fixup_type(const glsl_type **type, unsigned max_array_access, 1536bf215546Sopenharmony_ci bool from_ssbo_unsized_array, bool *implicit_sized) 1537bf215546Sopenharmony_ci { 1538bf215546Sopenharmony_ci if (!from_ssbo_unsized_array && (*type)->is_unsized_array()) { 1539bf215546Sopenharmony_ci *type = glsl_type::get_array_instance((*type)->fields.array, 1540bf215546Sopenharmony_ci max_array_access + 1); 1541bf215546Sopenharmony_ci *implicit_sized = true; 1542bf215546Sopenharmony_ci assert(*type != NULL); 1543bf215546Sopenharmony_ci } 1544bf215546Sopenharmony_ci } 1545bf215546Sopenharmony_ci 1546bf215546Sopenharmony_ci static const glsl_type * 1547bf215546Sopenharmony_ci update_interface_members_array(const glsl_type *type, 1548bf215546Sopenharmony_ci const glsl_type *new_interface_type) 1549bf215546Sopenharmony_ci { 1550bf215546Sopenharmony_ci const glsl_type *element_type = type->fields.array; 1551bf215546Sopenharmony_ci if (element_type->is_array()) { 1552bf215546Sopenharmony_ci const glsl_type *new_array_type = 1553bf215546Sopenharmony_ci update_interface_members_array(element_type, new_interface_type); 1554bf215546Sopenharmony_ci return glsl_type::get_array_instance(new_array_type, type->length); 1555bf215546Sopenharmony_ci } else { 1556bf215546Sopenharmony_ci return glsl_type::get_array_instance(new_interface_type, 1557bf215546Sopenharmony_ci type->length); 1558bf215546Sopenharmony_ci } 1559bf215546Sopenharmony_ci } 1560bf215546Sopenharmony_ci 1561bf215546Sopenharmony_ci /** 1562bf215546Sopenharmony_ci * Determine whether the given interface type contains unsized arrays (if 1563bf215546Sopenharmony_ci * it doesn't, array_sizing_visitor doesn't need to process it). 1564bf215546Sopenharmony_ci */ 1565bf215546Sopenharmony_ci static bool interface_contains_unsized_arrays(const glsl_type *type) 1566bf215546Sopenharmony_ci { 1567bf215546Sopenharmony_ci for (unsigned i = 0; i < type->length; i++) { 1568bf215546Sopenharmony_ci const glsl_type *elem_type = type->fields.structure[i].type; 1569bf215546Sopenharmony_ci if (elem_type->is_unsized_array()) 1570bf215546Sopenharmony_ci return true; 1571bf215546Sopenharmony_ci } 1572bf215546Sopenharmony_ci return false; 1573bf215546Sopenharmony_ci } 1574bf215546Sopenharmony_ci 1575bf215546Sopenharmony_ci /** 1576bf215546Sopenharmony_ci * Create a new interface type based on the given type, with unsized arrays 1577bf215546Sopenharmony_ci * replaced by sized arrays whose size is determined by 1578bf215546Sopenharmony_ci * max_ifc_array_access. 1579bf215546Sopenharmony_ci */ 1580bf215546Sopenharmony_ci static const glsl_type * 1581bf215546Sopenharmony_ci resize_interface_members(const glsl_type *type, 1582bf215546Sopenharmony_ci const int *max_ifc_array_access, 1583bf215546Sopenharmony_ci bool is_ssbo) 1584bf215546Sopenharmony_ci { 1585bf215546Sopenharmony_ci unsigned num_fields = type->length; 1586bf215546Sopenharmony_ci glsl_struct_field *fields = new glsl_struct_field[num_fields]; 1587bf215546Sopenharmony_ci memcpy(fields, type->fields.structure, 1588bf215546Sopenharmony_ci num_fields * sizeof(*fields)); 1589bf215546Sopenharmony_ci for (unsigned i = 0; i < num_fields; i++) { 1590bf215546Sopenharmony_ci bool implicit_sized_array = fields[i].implicit_sized_array; 1591bf215546Sopenharmony_ci /* If SSBO last member is unsized array, we don't replace it by a sized 1592bf215546Sopenharmony_ci * array. 1593bf215546Sopenharmony_ci */ 1594bf215546Sopenharmony_ci if (is_ssbo && i == (num_fields - 1)) 1595bf215546Sopenharmony_ci fixup_type(&fields[i].type, max_ifc_array_access[i], 1596bf215546Sopenharmony_ci true, &implicit_sized_array); 1597bf215546Sopenharmony_ci else 1598bf215546Sopenharmony_ci fixup_type(&fields[i].type, max_ifc_array_access[i], 1599bf215546Sopenharmony_ci false, &implicit_sized_array); 1600bf215546Sopenharmony_ci fields[i].implicit_sized_array = implicit_sized_array; 1601bf215546Sopenharmony_ci } 1602bf215546Sopenharmony_ci glsl_interface_packing packing = 1603bf215546Sopenharmony_ci (glsl_interface_packing) type->interface_packing; 1604bf215546Sopenharmony_ci bool row_major = (bool) type->interface_row_major; 1605bf215546Sopenharmony_ci const glsl_type *new_ifc_type = 1606bf215546Sopenharmony_ci glsl_type::get_interface_instance(fields, num_fields, 1607bf215546Sopenharmony_ci packing, row_major, type->name); 1608bf215546Sopenharmony_ci delete [] fields; 1609bf215546Sopenharmony_ci return new_ifc_type; 1610bf215546Sopenharmony_ci } 1611bf215546Sopenharmony_ci 1612bf215546Sopenharmony_ci static void fixup_unnamed_interface_type(const void *key, void *data, 1613bf215546Sopenharmony_ci void *) 1614bf215546Sopenharmony_ci { 1615bf215546Sopenharmony_ci const glsl_type *ifc_type = (const glsl_type *) key; 1616bf215546Sopenharmony_ci ir_variable **interface_vars = (ir_variable **) data; 1617bf215546Sopenharmony_ci unsigned num_fields = ifc_type->length; 1618bf215546Sopenharmony_ci glsl_struct_field *fields = new glsl_struct_field[num_fields]; 1619bf215546Sopenharmony_ci memcpy(fields, ifc_type->fields.structure, 1620bf215546Sopenharmony_ci num_fields * sizeof(*fields)); 1621bf215546Sopenharmony_ci bool interface_type_changed = false; 1622bf215546Sopenharmony_ci for (unsigned i = 0; i < num_fields; i++) { 1623bf215546Sopenharmony_ci if (interface_vars[i] != NULL && 1624bf215546Sopenharmony_ci fields[i].type != interface_vars[i]->type) { 1625bf215546Sopenharmony_ci fields[i].type = interface_vars[i]->type; 1626bf215546Sopenharmony_ci interface_type_changed = true; 1627bf215546Sopenharmony_ci } 1628bf215546Sopenharmony_ci } 1629bf215546Sopenharmony_ci if (!interface_type_changed) { 1630bf215546Sopenharmony_ci delete [] fields; 1631bf215546Sopenharmony_ci return; 1632bf215546Sopenharmony_ci } 1633bf215546Sopenharmony_ci glsl_interface_packing packing = 1634bf215546Sopenharmony_ci (glsl_interface_packing) ifc_type->interface_packing; 1635bf215546Sopenharmony_ci bool row_major = (bool) ifc_type->interface_row_major; 1636bf215546Sopenharmony_ci const glsl_type *new_ifc_type = 1637bf215546Sopenharmony_ci glsl_type::get_interface_instance(fields, num_fields, packing, 1638bf215546Sopenharmony_ci row_major, ifc_type->name); 1639bf215546Sopenharmony_ci delete [] fields; 1640bf215546Sopenharmony_ci for (unsigned i = 0; i < num_fields; i++) { 1641bf215546Sopenharmony_ci if (interface_vars[i] != NULL) 1642bf215546Sopenharmony_ci interface_vars[i]->change_interface_type(new_ifc_type); 1643bf215546Sopenharmony_ci } 1644bf215546Sopenharmony_ci } 1645bf215546Sopenharmony_ci 1646bf215546Sopenharmony_ci /** 1647bf215546Sopenharmony_ci * Memory context used to allocate the data in \c unnamed_interfaces. 1648bf215546Sopenharmony_ci */ 1649bf215546Sopenharmony_ci void *mem_ctx; 1650bf215546Sopenharmony_ci 1651bf215546Sopenharmony_ci /** 1652bf215546Sopenharmony_ci * Hash table from const glsl_type * to an array of ir_variable *'s 1653bf215546Sopenharmony_ci * pointing to the ir_variables constituting each unnamed interface block. 1654bf215546Sopenharmony_ci */ 1655bf215546Sopenharmony_ci hash_table *unnamed_interfaces; 1656bf215546Sopenharmony_ci}; 1657bf215546Sopenharmony_ci 1658bf215546Sopenharmony_cistatic bool 1659bf215546Sopenharmony_civalidate_xfb_buffer_stride(const struct gl_constants *consts, unsigned idx, 1660bf215546Sopenharmony_ci struct gl_shader_program *prog) 1661bf215546Sopenharmony_ci{ 1662bf215546Sopenharmony_ci /* We will validate doubles at a later stage */ 1663bf215546Sopenharmony_ci if (prog->TransformFeedback.BufferStride[idx] % 4) { 1664bf215546Sopenharmony_ci linker_error(prog, "invalid qualifier xfb_stride=%d must be a " 1665bf215546Sopenharmony_ci "multiple of 4 or if its applied to a type that is " 1666bf215546Sopenharmony_ci "or contains a double a multiple of 8.", 1667bf215546Sopenharmony_ci prog->TransformFeedback.BufferStride[idx]); 1668bf215546Sopenharmony_ci return false; 1669bf215546Sopenharmony_ci } 1670bf215546Sopenharmony_ci 1671bf215546Sopenharmony_ci if (prog->TransformFeedback.BufferStride[idx] / 4 > 1672bf215546Sopenharmony_ci consts->MaxTransformFeedbackInterleavedComponents) { 1673bf215546Sopenharmony_ci linker_error(prog, "The MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS " 1674bf215546Sopenharmony_ci "limit has been exceeded."); 1675bf215546Sopenharmony_ci return false; 1676bf215546Sopenharmony_ci } 1677bf215546Sopenharmony_ci 1678bf215546Sopenharmony_ci return true; 1679bf215546Sopenharmony_ci} 1680bf215546Sopenharmony_ci 1681bf215546Sopenharmony_ci/** 1682bf215546Sopenharmony_ci * Check for conflicting xfb_stride default qualifiers and store buffer stride 1683bf215546Sopenharmony_ci * for later use. 1684bf215546Sopenharmony_ci */ 1685bf215546Sopenharmony_cistatic void 1686bf215546Sopenharmony_cilink_xfb_stride_layout_qualifiers(const struct gl_constants *consts, 1687bf215546Sopenharmony_ci struct gl_shader_program *prog, 1688bf215546Sopenharmony_ci struct gl_shader **shader_list, 1689bf215546Sopenharmony_ci unsigned num_shaders) 1690bf215546Sopenharmony_ci{ 1691bf215546Sopenharmony_ci for (unsigned i = 0; i < MAX_FEEDBACK_BUFFERS; i++) { 1692bf215546Sopenharmony_ci prog->TransformFeedback.BufferStride[i] = 0; 1693bf215546Sopenharmony_ci } 1694bf215546Sopenharmony_ci 1695bf215546Sopenharmony_ci for (unsigned i = 0; i < num_shaders; i++) { 1696bf215546Sopenharmony_ci struct gl_shader *shader = shader_list[i]; 1697bf215546Sopenharmony_ci 1698bf215546Sopenharmony_ci for (unsigned j = 0; j < MAX_FEEDBACK_BUFFERS; j++) { 1699bf215546Sopenharmony_ci if (shader->TransformFeedbackBufferStride[j]) { 1700bf215546Sopenharmony_ci if (prog->TransformFeedback.BufferStride[j] == 0) { 1701bf215546Sopenharmony_ci prog->TransformFeedback.BufferStride[j] = 1702bf215546Sopenharmony_ci shader->TransformFeedbackBufferStride[j]; 1703bf215546Sopenharmony_ci if (!validate_xfb_buffer_stride(consts, j, prog)) 1704bf215546Sopenharmony_ci return; 1705bf215546Sopenharmony_ci } else if (prog->TransformFeedback.BufferStride[j] != 1706bf215546Sopenharmony_ci shader->TransformFeedbackBufferStride[j]){ 1707bf215546Sopenharmony_ci linker_error(prog, 1708bf215546Sopenharmony_ci "intrastage shaders defined with conflicting " 1709bf215546Sopenharmony_ci "xfb_stride for buffer %d (%d and %d)\n", j, 1710bf215546Sopenharmony_ci prog->TransformFeedback.BufferStride[j], 1711bf215546Sopenharmony_ci shader->TransformFeedbackBufferStride[j]); 1712bf215546Sopenharmony_ci return; 1713bf215546Sopenharmony_ci } 1714bf215546Sopenharmony_ci } 1715bf215546Sopenharmony_ci } 1716bf215546Sopenharmony_ci } 1717bf215546Sopenharmony_ci} 1718bf215546Sopenharmony_ci 1719bf215546Sopenharmony_ci/** 1720bf215546Sopenharmony_ci * Check for conflicting bindless/bound sampler/image layout qualifiers at 1721bf215546Sopenharmony_ci * global scope. 1722bf215546Sopenharmony_ci */ 1723bf215546Sopenharmony_cistatic void 1724bf215546Sopenharmony_cilink_bindless_layout_qualifiers(struct gl_shader_program *prog, 1725bf215546Sopenharmony_ci struct gl_shader **shader_list, 1726bf215546Sopenharmony_ci unsigned num_shaders) 1727bf215546Sopenharmony_ci{ 1728bf215546Sopenharmony_ci bool bindless_sampler, bindless_image; 1729bf215546Sopenharmony_ci bool bound_sampler, bound_image; 1730bf215546Sopenharmony_ci 1731bf215546Sopenharmony_ci bindless_sampler = bindless_image = false; 1732bf215546Sopenharmony_ci bound_sampler = bound_image = false; 1733bf215546Sopenharmony_ci 1734bf215546Sopenharmony_ci for (unsigned i = 0; i < num_shaders; i++) { 1735bf215546Sopenharmony_ci struct gl_shader *shader = shader_list[i]; 1736bf215546Sopenharmony_ci 1737bf215546Sopenharmony_ci if (shader->bindless_sampler) 1738bf215546Sopenharmony_ci bindless_sampler = true; 1739bf215546Sopenharmony_ci if (shader->bindless_image) 1740bf215546Sopenharmony_ci bindless_image = true; 1741bf215546Sopenharmony_ci if (shader->bound_sampler) 1742bf215546Sopenharmony_ci bound_sampler = true; 1743bf215546Sopenharmony_ci if (shader->bound_image) 1744bf215546Sopenharmony_ci bound_image = true; 1745bf215546Sopenharmony_ci 1746bf215546Sopenharmony_ci if ((bindless_sampler && bound_sampler) || 1747bf215546Sopenharmony_ci (bindless_image && bound_image)) { 1748bf215546Sopenharmony_ci /* From section 4.4.6 of the ARB_bindless_texture spec: 1749bf215546Sopenharmony_ci * 1750bf215546Sopenharmony_ci * "If both bindless_sampler and bound_sampler, or bindless_image 1751bf215546Sopenharmony_ci * and bound_image, are declared at global scope in any 1752bf215546Sopenharmony_ci * compilation unit, a link- time error will be generated." 1753bf215546Sopenharmony_ci */ 1754bf215546Sopenharmony_ci linker_error(prog, "both bindless_sampler and bound_sampler, or " 1755bf215546Sopenharmony_ci "bindless_image and bound_image, can't be declared at " 1756bf215546Sopenharmony_ci "global scope"); 1757bf215546Sopenharmony_ci } 1758bf215546Sopenharmony_ci } 1759bf215546Sopenharmony_ci} 1760bf215546Sopenharmony_ci 1761bf215546Sopenharmony_ci/** 1762bf215546Sopenharmony_ci * Check for conflicting viewport_relative settings across shaders, and sets 1763bf215546Sopenharmony_ci * the value for the linked shader. 1764bf215546Sopenharmony_ci */ 1765bf215546Sopenharmony_cistatic void 1766bf215546Sopenharmony_cilink_layer_viewport_relative_qualifier(struct gl_shader_program *prog, 1767bf215546Sopenharmony_ci struct gl_program *gl_prog, 1768bf215546Sopenharmony_ci struct gl_shader **shader_list, 1769bf215546Sopenharmony_ci unsigned num_shaders) 1770bf215546Sopenharmony_ci{ 1771bf215546Sopenharmony_ci unsigned i; 1772bf215546Sopenharmony_ci 1773bf215546Sopenharmony_ci /* Find first shader with explicit layer declaration */ 1774bf215546Sopenharmony_ci for (i = 0; i < num_shaders; i++) { 1775bf215546Sopenharmony_ci if (shader_list[i]->redeclares_gl_layer) { 1776bf215546Sopenharmony_ci gl_prog->info.layer_viewport_relative = 1777bf215546Sopenharmony_ci shader_list[i]->layer_viewport_relative; 1778bf215546Sopenharmony_ci break; 1779bf215546Sopenharmony_ci } 1780bf215546Sopenharmony_ci } 1781bf215546Sopenharmony_ci 1782bf215546Sopenharmony_ci /* Now make sure that each subsequent shader's explicit layer declaration 1783bf215546Sopenharmony_ci * matches the first one's. 1784bf215546Sopenharmony_ci */ 1785bf215546Sopenharmony_ci for (; i < num_shaders; i++) { 1786bf215546Sopenharmony_ci if (shader_list[i]->redeclares_gl_layer && 1787bf215546Sopenharmony_ci shader_list[i]->layer_viewport_relative != 1788bf215546Sopenharmony_ci gl_prog->info.layer_viewport_relative) { 1789bf215546Sopenharmony_ci linker_error(prog, "all gl_Layer redeclarations must have identical " 1790bf215546Sopenharmony_ci "viewport_relative settings"); 1791bf215546Sopenharmony_ci } 1792bf215546Sopenharmony_ci } 1793bf215546Sopenharmony_ci} 1794bf215546Sopenharmony_ci 1795bf215546Sopenharmony_ci/** 1796bf215546Sopenharmony_ci * Performs the cross-validation of tessellation control shader vertices and 1797bf215546Sopenharmony_ci * layout qualifiers for the attached tessellation control shaders, 1798bf215546Sopenharmony_ci * and propagates them to the linked TCS and linked shader program. 1799bf215546Sopenharmony_ci */ 1800bf215546Sopenharmony_cistatic void 1801bf215546Sopenharmony_cilink_tcs_out_layout_qualifiers(struct gl_shader_program *prog, 1802bf215546Sopenharmony_ci struct gl_program *gl_prog, 1803bf215546Sopenharmony_ci struct gl_shader **shader_list, 1804bf215546Sopenharmony_ci unsigned num_shaders) 1805bf215546Sopenharmony_ci{ 1806bf215546Sopenharmony_ci if (gl_prog->info.stage != MESA_SHADER_TESS_CTRL) 1807bf215546Sopenharmony_ci return; 1808bf215546Sopenharmony_ci 1809bf215546Sopenharmony_ci gl_prog->info.tess.tcs_vertices_out = 0; 1810bf215546Sopenharmony_ci 1811bf215546Sopenharmony_ci /* From the GLSL 4.0 spec (chapter 4.3.8.2): 1812bf215546Sopenharmony_ci * 1813bf215546Sopenharmony_ci * "All tessellation control shader layout declarations in a program 1814bf215546Sopenharmony_ci * must specify the same output patch vertex count. There must be at 1815bf215546Sopenharmony_ci * least one layout qualifier specifying an output patch vertex count 1816bf215546Sopenharmony_ci * in any program containing tessellation control shaders; however, 1817bf215546Sopenharmony_ci * such a declaration is not required in all tessellation control 1818bf215546Sopenharmony_ci * shaders." 1819bf215546Sopenharmony_ci */ 1820bf215546Sopenharmony_ci 1821bf215546Sopenharmony_ci for (unsigned i = 0; i < num_shaders; i++) { 1822bf215546Sopenharmony_ci struct gl_shader *shader = shader_list[i]; 1823bf215546Sopenharmony_ci 1824bf215546Sopenharmony_ci if (shader->info.TessCtrl.VerticesOut != 0) { 1825bf215546Sopenharmony_ci if (gl_prog->info.tess.tcs_vertices_out != 0 && 1826bf215546Sopenharmony_ci gl_prog->info.tess.tcs_vertices_out != 1827bf215546Sopenharmony_ci (unsigned) shader->info.TessCtrl.VerticesOut) { 1828bf215546Sopenharmony_ci linker_error(prog, "tessellation control shader defined with " 1829bf215546Sopenharmony_ci "conflicting output vertex count (%d and %d)\n", 1830bf215546Sopenharmony_ci gl_prog->info.tess.tcs_vertices_out, 1831bf215546Sopenharmony_ci shader->info.TessCtrl.VerticesOut); 1832bf215546Sopenharmony_ci return; 1833bf215546Sopenharmony_ci } 1834bf215546Sopenharmony_ci gl_prog->info.tess.tcs_vertices_out = 1835bf215546Sopenharmony_ci shader->info.TessCtrl.VerticesOut; 1836bf215546Sopenharmony_ci } 1837bf215546Sopenharmony_ci } 1838bf215546Sopenharmony_ci 1839bf215546Sopenharmony_ci /* Just do the intrastage -> interstage propagation right now, 1840bf215546Sopenharmony_ci * since we already know we're in the right type of shader program 1841bf215546Sopenharmony_ci * for doing it. 1842bf215546Sopenharmony_ci */ 1843bf215546Sopenharmony_ci if (gl_prog->info.tess.tcs_vertices_out == 0) { 1844bf215546Sopenharmony_ci linker_error(prog, "tessellation control shader didn't declare " 1845bf215546Sopenharmony_ci "vertices out layout qualifier\n"); 1846bf215546Sopenharmony_ci return; 1847bf215546Sopenharmony_ci } 1848bf215546Sopenharmony_ci} 1849bf215546Sopenharmony_ci 1850bf215546Sopenharmony_ci 1851bf215546Sopenharmony_ci/** 1852bf215546Sopenharmony_ci * Performs the cross-validation of tessellation evaluation shader 1853bf215546Sopenharmony_ci * primitive type, vertex spacing, ordering and point_mode layout qualifiers 1854bf215546Sopenharmony_ci * for the attached tessellation evaluation shaders, and propagates them 1855bf215546Sopenharmony_ci * to the linked TES and linked shader program. 1856bf215546Sopenharmony_ci */ 1857bf215546Sopenharmony_cistatic void 1858bf215546Sopenharmony_cilink_tes_in_layout_qualifiers(struct gl_shader_program *prog, 1859bf215546Sopenharmony_ci struct gl_program *gl_prog, 1860bf215546Sopenharmony_ci struct gl_shader **shader_list, 1861bf215546Sopenharmony_ci unsigned num_shaders) 1862bf215546Sopenharmony_ci{ 1863bf215546Sopenharmony_ci if (gl_prog->info.stage != MESA_SHADER_TESS_EVAL) 1864bf215546Sopenharmony_ci return; 1865bf215546Sopenharmony_ci 1866bf215546Sopenharmony_ci int point_mode = -1; 1867bf215546Sopenharmony_ci unsigned vertex_order = 0; 1868bf215546Sopenharmony_ci 1869bf215546Sopenharmony_ci gl_prog->info.tess._primitive_mode = TESS_PRIMITIVE_UNSPECIFIED; 1870bf215546Sopenharmony_ci gl_prog->info.tess.spacing = TESS_SPACING_UNSPECIFIED; 1871bf215546Sopenharmony_ci 1872bf215546Sopenharmony_ci /* From the GLSL 4.0 spec (chapter 4.3.8.1): 1873bf215546Sopenharmony_ci * 1874bf215546Sopenharmony_ci * "At least one tessellation evaluation shader (compilation unit) in 1875bf215546Sopenharmony_ci * a program must declare a primitive mode in its input layout. 1876bf215546Sopenharmony_ci * Declaration vertex spacing, ordering, and point mode identifiers is 1877bf215546Sopenharmony_ci * optional. It is not required that all tessellation evaluation 1878bf215546Sopenharmony_ci * shaders in a program declare a primitive mode. If spacing or 1879bf215546Sopenharmony_ci * vertex ordering declarations are omitted, the tessellation 1880bf215546Sopenharmony_ci * primitive generator will use equal spacing or counter-clockwise 1881bf215546Sopenharmony_ci * vertex ordering, respectively. If a point mode declaration is 1882bf215546Sopenharmony_ci * omitted, the tessellation primitive generator will produce lines or 1883bf215546Sopenharmony_ci * triangles according to the primitive mode." 1884bf215546Sopenharmony_ci */ 1885bf215546Sopenharmony_ci 1886bf215546Sopenharmony_ci for (unsigned i = 0; i < num_shaders; i++) { 1887bf215546Sopenharmony_ci struct gl_shader *shader = shader_list[i]; 1888bf215546Sopenharmony_ci 1889bf215546Sopenharmony_ci if (shader->info.TessEval._PrimitiveMode != TESS_PRIMITIVE_UNSPECIFIED) { 1890bf215546Sopenharmony_ci if (gl_prog->info.tess._primitive_mode != TESS_PRIMITIVE_UNSPECIFIED && 1891bf215546Sopenharmony_ci gl_prog->info.tess._primitive_mode != 1892bf215546Sopenharmony_ci shader->info.TessEval._PrimitiveMode) { 1893bf215546Sopenharmony_ci linker_error(prog, "tessellation evaluation shader defined with " 1894bf215546Sopenharmony_ci "conflicting input primitive modes.\n"); 1895bf215546Sopenharmony_ci return; 1896bf215546Sopenharmony_ci } 1897bf215546Sopenharmony_ci gl_prog->info.tess._primitive_mode = 1898bf215546Sopenharmony_ci shader->info.TessEval._PrimitiveMode; 1899bf215546Sopenharmony_ci } 1900bf215546Sopenharmony_ci 1901bf215546Sopenharmony_ci if (shader->info.TessEval.Spacing != 0) { 1902bf215546Sopenharmony_ci if (gl_prog->info.tess.spacing != 0 && gl_prog->info.tess.spacing != 1903bf215546Sopenharmony_ci shader->info.TessEval.Spacing) { 1904bf215546Sopenharmony_ci linker_error(prog, "tessellation evaluation shader defined with " 1905bf215546Sopenharmony_ci "conflicting vertex spacing.\n"); 1906bf215546Sopenharmony_ci return; 1907bf215546Sopenharmony_ci } 1908bf215546Sopenharmony_ci gl_prog->info.tess.spacing = shader->info.TessEval.Spacing; 1909bf215546Sopenharmony_ci } 1910bf215546Sopenharmony_ci 1911bf215546Sopenharmony_ci if (shader->info.TessEval.VertexOrder != 0) { 1912bf215546Sopenharmony_ci if (vertex_order != 0 && 1913bf215546Sopenharmony_ci vertex_order != shader->info.TessEval.VertexOrder) { 1914bf215546Sopenharmony_ci linker_error(prog, "tessellation evaluation shader defined with " 1915bf215546Sopenharmony_ci "conflicting ordering.\n"); 1916bf215546Sopenharmony_ci return; 1917bf215546Sopenharmony_ci } 1918bf215546Sopenharmony_ci vertex_order = shader->info.TessEval.VertexOrder; 1919bf215546Sopenharmony_ci } 1920bf215546Sopenharmony_ci 1921bf215546Sopenharmony_ci if (shader->info.TessEval.PointMode != -1) { 1922bf215546Sopenharmony_ci if (point_mode != -1 && 1923bf215546Sopenharmony_ci point_mode != shader->info.TessEval.PointMode) { 1924bf215546Sopenharmony_ci linker_error(prog, "tessellation evaluation shader defined with " 1925bf215546Sopenharmony_ci "conflicting point modes.\n"); 1926bf215546Sopenharmony_ci return; 1927bf215546Sopenharmony_ci } 1928bf215546Sopenharmony_ci point_mode = shader->info.TessEval.PointMode; 1929bf215546Sopenharmony_ci } 1930bf215546Sopenharmony_ci 1931bf215546Sopenharmony_ci } 1932bf215546Sopenharmony_ci 1933bf215546Sopenharmony_ci /* Just do the intrastage -> interstage propagation right now, 1934bf215546Sopenharmony_ci * since we already know we're in the right type of shader program 1935bf215546Sopenharmony_ci * for doing it. 1936bf215546Sopenharmony_ci */ 1937bf215546Sopenharmony_ci if (gl_prog->info.tess._primitive_mode == TESS_PRIMITIVE_UNSPECIFIED) { 1938bf215546Sopenharmony_ci linker_error(prog, 1939bf215546Sopenharmony_ci "tessellation evaluation shader didn't declare input " 1940bf215546Sopenharmony_ci "primitive modes.\n"); 1941bf215546Sopenharmony_ci return; 1942bf215546Sopenharmony_ci } 1943bf215546Sopenharmony_ci 1944bf215546Sopenharmony_ci if (gl_prog->info.tess.spacing == TESS_SPACING_UNSPECIFIED) 1945bf215546Sopenharmony_ci gl_prog->info.tess.spacing = TESS_SPACING_EQUAL; 1946bf215546Sopenharmony_ci 1947bf215546Sopenharmony_ci if (vertex_order == 0 || vertex_order == GL_CCW) 1948bf215546Sopenharmony_ci gl_prog->info.tess.ccw = true; 1949bf215546Sopenharmony_ci else 1950bf215546Sopenharmony_ci gl_prog->info.tess.ccw = false; 1951bf215546Sopenharmony_ci 1952bf215546Sopenharmony_ci 1953bf215546Sopenharmony_ci if (point_mode == -1 || point_mode == GL_FALSE) 1954bf215546Sopenharmony_ci gl_prog->info.tess.point_mode = false; 1955bf215546Sopenharmony_ci else 1956bf215546Sopenharmony_ci gl_prog->info.tess.point_mode = true; 1957bf215546Sopenharmony_ci} 1958bf215546Sopenharmony_ci 1959bf215546Sopenharmony_ci 1960bf215546Sopenharmony_ci/** 1961bf215546Sopenharmony_ci * Performs the cross-validation of layout qualifiers specified in 1962bf215546Sopenharmony_ci * redeclaration of gl_FragCoord for the attached fragment shaders, 1963bf215546Sopenharmony_ci * and propagates them to the linked FS and linked shader program. 1964bf215546Sopenharmony_ci */ 1965bf215546Sopenharmony_cistatic void 1966bf215546Sopenharmony_cilink_fs_inout_layout_qualifiers(struct gl_shader_program *prog, 1967bf215546Sopenharmony_ci struct gl_linked_shader *linked_shader, 1968bf215546Sopenharmony_ci struct gl_shader **shader_list, 1969bf215546Sopenharmony_ci unsigned num_shaders) 1970bf215546Sopenharmony_ci{ 1971bf215546Sopenharmony_ci bool redeclares_gl_fragcoord = false; 1972bf215546Sopenharmony_ci bool uses_gl_fragcoord = false; 1973bf215546Sopenharmony_ci bool origin_upper_left = false; 1974bf215546Sopenharmony_ci bool pixel_center_integer = false; 1975bf215546Sopenharmony_ci 1976bf215546Sopenharmony_ci if (linked_shader->Stage != MESA_SHADER_FRAGMENT || 1977bf215546Sopenharmony_ci (prog->data->Version < 150 && 1978bf215546Sopenharmony_ci !prog->ARB_fragment_coord_conventions_enable)) 1979bf215546Sopenharmony_ci return; 1980bf215546Sopenharmony_ci 1981bf215546Sopenharmony_ci for (unsigned i = 0; i < num_shaders; i++) { 1982bf215546Sopenharmony_ci struct gl_shader *shader = shader_list[i]; 1983bf215546Sopenharmony_ci /* From the GLSL 1.50 spec, page 39: 1984bf215546Sopenharmony_ci * 1985bf215546Sopenharmony_ci * "If gl_FragCoord is redeclared in any fragment shader in a program, 1986bf215546Sopenharmony_ci * it must be redeclared in all the fragment shaders in that program 1987bf215546Sopenharmony_ci * that have a static use gl_FragCoord." 1988bf215546Sopenharmony_ci */ 1989bf215546Sopenharmony_ci if ((redeclares_gl_fragcoord && !shader->redeclares_gl_fragcoord && 1990bf215546Sopenharmony_ci shader->uses_gl_fragcoord) 1991bf215546Sopenharmony_ci || (shader->redeclares_gl_fragcoord && !redeclares_gl_fragcoord && 1992bf215546Sopenharmony_ci uses_gl_fragcoord)) { 1993bf215546Sopenharmony_ci linker_error(prog, "fragment shader defined with conflicting " 1994bf215546Sopenharmony_ci "layout qualifiers for gl_FragCoord\n"); 1995bf215546Sopenharmony_ci } 1996bf215546Sopenharmony_ci 1997bf215546Sopenharmony_ci /* From the GLSL 1.50 spec, page 39: 1998bf215546Sopenharmony_ci * 1999bf215546Sopenharmony_ci * "All redeclarations of gl_FragCoord in all fragment shaders in a 2000bf215546Sopenharmony_ci * single program must have the same set of qualifiers." 2001bf215546Sopenharmony_ci */ 2002bf215546Sopenharmony_ci if (redeclares_gl_fragcoord && shader->redeclares_gl_fragcoord && 2003bf215546Sopenharmony_ci (shader->origin_upper_left != origin_upper_left || 2004bf215546Sopenharmony_ci shader->pixel_center_integer != pixel_center_integer)) { 2005bf215546Sopenharmony_ci linker_error(prog, "fragment shader defined with conflicting " 2006bf215546Sopenharmony_ci "layout qualifiers for gl_FragCoord\n"); 2007bf215546Sopenharmony_ci } 2008bf215546Sopenharmony_ci 2009bf215546Sopenharmony_ci /* Update the linked shader state. Note that uses_gl_fragcoord should 2010bf215546Sopenharmony_ci * accumulate the results. The other values should replace. If there 2011bf215546Sopenharmony_ci * are multiple redeclarations, all the fields except uses_gl_fragcoord 2012bf215546Sopenharmony_ci * are already known to be the same. 2013bf215546Sopenharmony_ci */ 2014bf215546Sopenharmony_ci if (shader->redeclares_gl_fragcoord || shader->uses_gl_fragcoord) { 2015bf215546Sopenharmony_ci redeclares_gl_fragcoord = shader->redeclares_gl_fragcoord; 2016bf215546Sopenharmony_ci uses_gl_fragcoord |= shader->uses_gl_fragcoord; 2017bf215546Sopenharmony_ci origin_upper_left = shader->origin_upper_left; 2018bf215546Sopenharmony_ci pixel_center_integer = shader->pixel_center_integer; 2019bf215546Sopenharmony_ci } 2020bf215546Sopenharmony_ci 2021bf215546Sopenharmony_ci linked_shader->Program->info.fs.early_fragment_tests |= 2022bf215546Sopenharmony_ci shader->EarlyFragmentTests || shader->PostDepthCoverage; 2023bf215546Sopenharmony_ci linked_shader->Program->info.fs.inner_coverage |= shader->InnerCoverage; 2024bf215546Sopenharmony_ci linked_shader->Program->info.fs.post_depth_coverage |= 2025bf215546Sopenharmony_ci shader->PostDepthCoverage; 2026bf215546Sopenharmony_ci linked_shader->Program->info.fs.pixel_interlock_ordered |= 2027bf215546Sopenharmony_ci shader->PixelInterlockOrdered; 2028bf215546Sopenharmony_ci linked_shader->Program->info.fs.pixel_interlock_unordered |= 2029bf215546Sopenharmony_ci shader->PixelInterlockUnordered; 2030bf215546Sopenharmony_ci linked_shader->Program->info.fs.sample_interlock_ordered |= 2031bf215546Sopenharmony_ci shader->SampleInterlockOrdered; 2032bf215546Sopenharmony_ci linked_shader->Program->info.fs.sample_interlock_unordered |= 2033bf215546Sopenharmony_ci shader->SampleInterlockUnordered; 2034bf215546Sopenharmony_ci linked_shader->Program->info.fs.advanced_blend_modes |= shader->BlendSupport; 2035bf215546Sopenharmony_ci } 2036bf215546Sopenharmony_ci 2037bf215546Sopenharmony_ci linked_shader->Program->info.fs.pixel_center_integer = pixel_center_integer; 2038bf215546Sopenharmony_ci linked_shader->Program->info.fs.origin_upper_left = origin_upper_left; 2039bf215546Sopenharmony_ci} 2040bf215546Sopenharmony_ci 2041bf215546Sopenharmony_ci/** 2042bf215546Sopenharmony_ci * Performs the cross-validation of geometry shader max_vertices and 2043bf215546Sopenharmony_ci * primitive type layout qualifiers for the attached geometry shaders, 2044bf215546Sopenharmony_ci * and propagates them to the linked GS and linked shader program. 2045bf215546Sopenharmony_ci */ 2046bf215546Sopenharmony_cistatic void 2047bf215546Sopenharmony_cilink_gs_inout_layout_qualifiers(struct gl_shader_program *prog, 2048bf215546Sopenharmony_ci struct gl_program *gl_prog, 2049bf215546Sopenharmony_ci struct gl_shader **shader_list, 2050bf215546Sopenharmony_ci unsigned num_shaders) 2051bf215546Sopenharmony_ci{ 2052bf215546Sopenharmony_ci /* No in/out qualifiers defined for anything but GLSL 1.50+ 2053bf215546Sopenharmony_ci * geometry shaders so far. 2054bf215546Sopenharmony_ci */ 2055bf215546Sopenharmony_ci if (gl_prog->info.stage != MESA_SHADER_GEOMETRY || 2056bf215546Sopenharmony_ci prog->data->Version < 150) 2057bf215546Sopenharmony_ci return; 2058bf215546Sopenharmony_ci 2059bf215546Sopenharmony_ci int vertices_out = -1; 2060bf215546Sopenharmony_ci 2061bf215546Sopenharmony_ci gl_prog->info.gs.invocations = 0; 2062bf215546Sopenharmony_ci gl_prog->info.gs.input_primitive = SHADER_PRIM_UNKNOWN; 2063bf215546Sopenharmony_ci gl_prog->info.gs.output_primitive = SHADER_PRIM_UNKNOWN; 2064bf215546Sopenharmony_ci 2065bf215546Sopenharmony_ci /* From the GLSL 1.50 spec, page 46: 2066bf215546Sopenharmony_ci * 2067bf215546Sopenharmony_ci * "All geometry shader output layout declarations in a program 2068bf215546Sopenharmony_ci * must declare the same layout and same value for 2069bf215546Sopenharmony_ci * max_vertices. There must be at least one geometry output 2070bf215546Sopenharmony_ci * layout declaration somewhere in a program, but not all 2071bf215546Sopenharmony_ci * geometry shaders (compilation units) are required to 2072bf215546Sopenharmony_ci * declare it." 2073bf215546Sopenharmony_ci */ 2074bf215546Sopenharmony_ci 2075bf215546Sopenharmony_ci for (unsigned i = 0; i < num_shaders; i++) { 2076bf215546Sopenharmony_ci struct gl_shader *shader = shader_list[i]; 2077bf215546Sopenharmony_ci 2078bf215546Sopenharmony_ci if (shader->info.Geom.InputType != SHADER_PRIM_UNKNOWN) { 2079bf215546Sopenharmony_ci if (gl_prog->info.gs.input_primitive != SHADER_PRIM_UNKNOWN && 2080bf215546Sopenharmony_ci gl_prog->info.gs.input_primitive != 2081bf215546Sopenharmony_ci shader->info.Geom.InputType) { 2082bf215546Sopenharmony_ci linker_error(prog, "geometry shader defined with conflicting " 2083bf215546Sopenharmony_ci "input types\n"); 2084bf215546Sopenharmony_ci return; 2085bf215546Sopenharmony_ci } 2086bf215546Sopenharmony_ci gl_prog->info.gs.input_primitive = (enum shader_prim)shader->info.Geom.InputType; 2087bf215546Sopenharmony_ci } 2088bf215546Sopenharmony_ci 2089bf215546Sopenharmony_ci if (shader->info.Geom.OutputType != SHADER_PRIM_UNKNOWN) { 2090bf215546Sopenharmony_ci if (gl_prog->info.gs.output_primitive != SHADER_PRIM_UNKNOWN && 2091bf215546Sopenharmony_ci gl_prog->info.gs.output_primitive != 2092bf215546Sopenharmony_ci shader->info.Geom.OutputType) { 2093bf215546Sopenharmony_ci linker_error(prog, "geometry shader defined with conflicting " 2094bf215546Sopenharmony_ci "output types\n"); 2095bf215546Sopenharmony_ci return; 2096bf215546Sopenharmony_ci } 2097bf215546Sopenharmony_ci gl_prog->info.gs.output_primitive = (enum shader_prim)shader->info.Geom.OutputType; 2098bf215546Sopenharmony_ci } 2099bf215546Sopenharmony_ci 2100bf215546Sopenharmony_ci if (shader->info.Geom.VerticesOut != -1) { 2101bf215546Sopenharmony_ci if (vertices_out != -1 && 2102bf215546Sopenharmony_ci vertices_out != shader->info.Geom.VerticesOut) { 2103bf215546Sopenharmony_ci linker_error(prog, "geometry shader defined with conflicting " 2104bf215546Sopenharmony_ci "output vertex count (%d and %d)\n", 2105bf215546Sopenharmony_ci vertices_out, shader->info.Geom.VerticesOut); 2106bf215546Sopenharmony_ci return; 2107bf215546Sopenharmony_ci } 2108bf215546Sopenharmony_ci vertices_out = shader->info.Geom.VerticesOut; 2109bf215546Sopenharmony_ci } 2110bf215546Sopenharmony_ci 2111bf215546Sopenharmony_ci if (shader->info.Geom.Invocations != 0) { 2112bf215546Sopenharmony_ci if (gl_prog->info.gs.invocations != 0 && 2113bf215546Sopenharmony_ci gl_prog->info.gs.invocations != 2114bf215546Sopenharmony_ci (unsigned) shader->info.Geom.Invocations) { 2115bf215546Sopenharmony_ci linker_error(prog, "geometry shader defined with conflicting " 2116bf215546Sopenharmony_ci "invocation count (%d and %d)\n", 2117bf215546Sopenharmony_ci gl_prog->info.gs.invocations, 2118bf215546Sopenharmony_ci shader->info.Geom.Invocations); 2119bf215546Sopenharmony_ci return; 2120bf215546Sopenharmony_ci } 2121bf215546Sopenharmony_ci gl_prog->info.gs.invocations = shader->info.Geom.Invocations; 2122bf215546Sopenharmony_ci } 2123bf215546Sopenharmony_ci } 2124bf215546Sopenharmony_ci 2125bf215546Sopenharmony_ci /* Just do the intrastage -> interstage propagation right now, 2126bf215546Sopenharmony_ci * since we already know we're in the right type of shader program 2127bf215546Sopenharmony_ci * for doing it. 2128bf215546Sopenharmony_ci */ 2129bf215546Sopenharmony_ci if (gl_prog->info.gs.input_primitive == SHADER_PRIM_UNKNOWN) { 2130bf215546Sopenharmony_ci linker_error(prog, 2131bf215546Sopenharmony_ci "geometry shader didn't declare primitive input type\n"); 2132bf215546Sopenharmony_ci return; 2133bf215546Sopenharmony_ci } 2134bf215546Sopenharmony_ci 2135bf215546Sopenharmony_ci if (gl_prog->info.gs.output_primitive == SHADER_PRIM_UNKNOWN) { 2136bf215546Sopenharmony_ci linker_error(prog, 2137bf215546Sopenharmony_ci "geometry shader didn't declare primitive output type\n"); 2138bf215546Sopenharmony_ci return; 2139bf215546Sopenharmony_ci } 2140bf215546Sopenharmony_ci 2141bf215546Sopenharmony_ci if (vertices_out == -1) { 2142bf215546Sopenharmony_ci linker_error(prog, 2143bf215546Sopenharmony_ci "geometry shader didn't declare max_vertices\n"); 2144bf215546Sopenharmony_ci return; 2145bf215546Sopenharmony_ci } else { 2146bf215546Sopenharmony_ci gl_prog->info.gs.vertices_out = vertices_out; 2147bf215546Sopenharmony_ci } 2148bf215546Sopenharmony_ci 2149bf215546Sopenharmony_ci if (gl_prog->info.gs.invocations == 0) 2150bf215546Sopenharmony_ci gl_prog->info.gs.invocations = 1; 2151bf215546Sopenharmony_ci} 2152bf215546Sopenharmony_ci 2153bf215546Sopenharmony_ci 2154bf215546Sopenharmony_ci/** 2155bf215546Sopenharmony_ci * Perform cross-validation of compute shader local_size_{x,y,z} layout and 2156bf215546Sopenharmony_ci * derivative arrangement qualifiers for the attached compute shaders, and 2157bf215546Sopenharmony_ci * propagate them to the linked CS and linked shader program. 2158bf215546Sopenharmony_ci */ 2159bf215546Sopenharmony_cistatic void 2160bf215546Sopenharmony_cilink_cs_input_layout_qualifiers(struct gl_shader_program *prog, 2161bf215546Sopenharmony_ci struct gl_program *gl_prog, 2162bf215546Sopenharmony_ci struct gl_shader **shader_list, 2163bf215546Sopenharmony_ci unsigned num_shaders) 2164bf215546Sopenharmony_ci{ 2165bf215546Sopenharmony_ci /* This function is called for all shader stages, but it only has an effect 2166bf215546Sopenharmony_ci * for compute shaders. 2167bf215546Sopenharmony_ci */ 2168bf215546Sopenharmony_ci if (gl_prog->info.stage != MESA_SHADER_COMPUTE) 2169bf215546Sopenharmony_ci return; 2170bf215546Sopenharmony_ci 2171bf215546Sopenharmony_ci for (int i = 0; i < 3; i++) 2172bf215546Sopenharmony_ci gl_prog->info.workgroup_size[i] = 0; 2173bf215546Sopenharmony_ci 2174bf215546Sopenharmony_ci gl_prog->info.workgroup_size_variable = false; 2175bf215546Sopenharmony_ci 2176bf215546Sopenharmony_ci gl_prog->info.cs.derivative_group = DERIVATIVE_GROUP_NONE; 2177bf215546Sopenharmony_ci 2178bf215546Sopenharmony_ci /* From the ARB_compute_shader spec, in the section describing local size 2179bf215546Sopenharmony_ci * declarations: 2180bf215546Sopenharmony_ci * 2181bf215546Sopenharmony_ci * If multiple compute shaders attached to a single program object 2182bf215546Sopenharmony_ci * declare local work-group size, the declarations must be identical; 2183bf215546Sopenharmony_ci * otherwise a link-time error results. Furthermore, if a program 2184bf215546Sopenharmony_ci * object contains any compute shaders, at least one must contain an 2185bf215546Sopenharmony_ci * input layout qualifier specifying the local work sizes of the 2186bf215546Sopenharmony_ci * program, or a link-time error will occur. 2187bf215546Sopenharmony_ci */ 2188bf215546Sopenharmony_ci for (unsigned sh = 0; sh < num_shaders; sh++) { 2189bf215546Sopenharmony_ci struct gl_shader *shader = shader_list[sh]; 2190bf215546Sopenharmony_ci 2191bf215546Sopenharmony_ci if (shader->info.Comp.LocalSize[0] != 0) { 2192bf215546Sopenharmony_ci if (gl_prog->info.workgroup_size[0] != 0) { 2193bf215546Sopenharmony_ci for (int i = 0; i < 3; i++) { 2194bf215546Sopenharmony_ci if (gl_prog->info.workgroup_size[i] != 2195bf215546Sopenharmony_ci shader->info.Comp.LocalSize[i]) { 2196bf215546Sopenharmony_ci linker_error(prog, "compute shader defined with conflicting " 2197bf215546Sopenharmony_ci "local sizes\n"); 2198bf215546Sopenharmony_ci return; 2199bf215546Sopenharmony_ci } 2200bf215546Sopenharmony_ci } 2201bf215546Sopenharmony_ci } 2202bf215546Sopenharmony_ci for (int i = 0; i < 3; i++) { 2203bf215546Sopenharmony_ci gl_prog->info.workgroup_size[i] = 2204bf215546Sopenharmony_ci shader->info.Comp.LocalSize[i]; 2205bf215546Sopenharmony_ci } 2206bf215546Sopenharmony_ci } else if (shader->info.Comp.LocalSizeVariable) { 2207bf215546Sopenharmony_ci if (gl_prog->info.workgroup_size[0] != 0) { 2208bf215546Sopenharmony_ci /* The ARB_compute_variable_group_size spec says: 2209bf215546Sopenharmony_ci * 2210bf215546Sopenharmony_ci * If one compute shader attached to a program declares a 2211bf215546Sopenharmony_ci * variable local group size and a second compute shader 2212bf215546Sopenharmony_ci * attached to the same program declares a fixed local group 2213bf215546Sopenharmony_ci * size, a link-time error results. 2214bf215546Sopenharmony_ci */ 2215bf215546Sopenharmony_ci linker_error(prog, "compute shader defined with both fixed and " 2216bf215546Sopenharmony_ci "variable local group size\n"); 2217bf215546Sopenharmony_ci return; 2218bf215546Sopenharmony_ci } 2219bf215546Sopenharmony_ci gl_prog->info.workgroup_size_variable = true; 2220bf215546Sopenharmony_ci } 2221bf215546Sopenharmony_ci 2222bf215546Sopenharmony_ci enum gl_derivative_group group = shader->info.Comp.DerivativeGroup; 2223bf215546Sopenharmony_ci if (group != DERIVATIVE_GROUP_NONE) { 2224bf215546Sopenharmony_ci if (gl_prog->info.cs.derivative_group != DERIVATIVE_GROUP_NONE && 2225bf215546Sopenharmony_ci gl_prog->info.cs.derivative_group != group) { 2226bf215546Sopenharmony_ci linker_error(prog, "compute shader defined with conflicting " 2227bf215546Sopenharmony_ci "derivative groups\n"); 2228bf215546Sopenharmony_ci return; 2229bf215546Sopenharmony_ci } 2230bf215546Sopenharmony_ci gl_prog->info.cs.derivative_group = group; 2231bf215546Sopenharmony_ci } 2232bf215546Sopenharmony_ci } 2233bf215546Sopenharmony_ci 2234bf215546Sopenharmony_ci /* Just do the intrastage -> interstage propagation right now, 2235bf215546Sopenharmony_ci * since we already know we're in the right type of shader program 2236bf215546Sopenharmony_ci * for doing it. 2237bf215546Sopenharmony_ci */ 2238bf215546Sopenharmony_ci if (gl_prog->info.workgroup_size[0] == 0 && 2239bf215546Sopenharmony_ci !gl_prog->info.workgroup_size_variable) { 2240bf215546Sopenharmony_ci linker_error(prog, "compute shader must contain a fixed or a variable " 2241bf215546Sopenharmony_ci "local group size\n"); 2242bf215546Sopenharmony_ci return; 2243bf215546Sopenharmony_ci } 2244bf215546Sopenharmony_ci 2245bf215546Sopenharmony_ci if (gl_prog->info.cs.derivative_group == DERIVATIVE_GROUP_QUADS) { 2246bf215546Sopenharmony_ci if (gl_prog->info.workgroup_size[0] % 2 != 0) { 2247bf215546Sopenharmony_ci linker_error(prog, "derivative_group_quadsNV must be used with a " 2248bf215546Sopenharmony_ci "local group size whose first dimension " 2249bf215546Sopenharmony_ci "is a multiple of 2\n"); 2250bf215546Sopenharmony_ci return; 2251bf215546Sopenharmony_ci } 2252bf215546Sopenharmony_ci if (gl_prog->info.workgroup_size[1] % 2 != 0) { 2253bf215546Sopenharmony_ci linker_error(prog, "derivative_group_quadsNV must be used with a local" 2254bf215546Sopenharmony_ci "group size whose second dimension " 2255bf215546Sopenharmony_ci "is a multiple of 2\n"); 2256bf215546Sopenharmony_ci return; 2257bf215546Sopenharmony_ci } 2258bf215546Sopenharmony_ci } else if (gl_prog->info.cs.derivative_group == DERIVATIVE_GROUP_LINEAR) { 2259bf215546Sopenharmony_ci if ((gl_prog->info.workgroup_size[0] * 2260bf215546Sopenharmony_ci gl_prog->info.workgroup_size[1] * 2261bf215546Sopenharmony_ci gl_prog->info.workgroup_size[2]) % 4 != 0) { 2262bf215546Sopenharmony_ci linker_error(prog, "derivative_group_linearNV must be used with a " 2263bf215546Sopenharmony_ci "local group size whose total number of invocations " 2264bf215546Sopenharmony_ci "is a multiple of 4\n"); 2265bf215546Sopenharmony_ci return; 2266bf215546Sopenharmony_ci } 2267bf215546Sopenharmony_ci } 2268bf215546Sopenharmony_ci} 2269bf215546Sopenharmony_ci 2270bf215546Sopenharmony_ci/** 2271bf215546Sopenharmony_ci * Link all out variables on a single stage which are not 2272bf215546Sopenharmony_ci * directly used in a shader with the main function. 2273bf215546Sopenharmony_ci */ 2274bf215546Sopenharmony_cistatic void 2275bf215546Sopenharmony_cilink_output_variables(struct gl_linked_shader *linked_shader, 2276bf215546Sopenharmony_ci struct gl_shader **shader_list, 2277bf215546Sopenharmony_ci unsigned num_shaders) 2278bf215546Sopenharmony_ci{ 2279bf215546Sopenharmony_ci struct glsl_symbol_table *symbols = linked_shader->symbols; 2280bf215546Sopenharmony_ci 2281bf215546Sopenharmony_ci for (unsigned i = 0; i < num_shaders; i++) { 2282bf215546Sopenharmony_ci 2283bf215546Sopenharmony_ci /* Skip shader object with main function */ 2284bf215546Sopenharmony_ci if (shader_list[i]->symbols->get_function("main")) 2285bf215546Sopenharmony_ci continue; 2286bf215546Sopenharmony_ci 2287bf215546Sopenharmony_ci foreach_in_list(ir_instruction, ir, shader_list[i]->ir) { 2288bf215546Sopenharmony_ci if (ir->ir_type != ir_type_variable) 2289bf215546Sopenharmony_ci continue; 2290bf215546Sopenharmony_ci 2291bf215546Sopenharmony_ci ir_variable *var = (ir_variable *) ir; 2292bf215546Sopenharmony_ci 2293bf215546Sopenharmony_ci if (var->data.mode == ir_var_shader_out && 2294bf215546Sopenharmony_ci !symbols->get_variable(var->name)) { 2295bf215546Sopenharmony_ci var = var->clone(linked_shader, NULL); 2296bf215546Sopenharmony_ci symbols->add_variable(var); 2297bf215546Sopenharmony_ci linked_shader->ir->push_head(var); 2298bf215546Sopenharmony_ci } 2299bf215546Sopenharmony_ci } 2300bf215546Sopenharmony_ci } 2301bf215546Sopenharmony_ci 2302bf215546Sopenharmony_ci return; 2303bf215546Sopenharmony_ci} 2304bf215546Sopenharmony_ci 2305bf215546Sopenharmony_ci 2306bf215546Sopenharmony_ci/** 2307bf215546Sopenharmony_ci * Combine a group of shaders for a single stage to generate a linked shader 2308bf215546Sopenharmony_ci * 2309bf215546Sopenharmony_ci * \note 2310bf215546Sopenharmony_ci * If this function is supplied a single shader, it is cloned, and the new 2311bf215546Sopenharmony_ci * shader is returned. 2312bf215546Sopenharmony_ci */ 2313bf215546Sopenharmony_cistruct gl_linked_shader * 2314bf215546Sopenharmony_cilink_intrastage_shaders(void *mem_ctx, 2315bf215546Sopenharmony_ci struct gl_context *ctx, 2316bf215546Sopenharmony_ci struct gl_shader_program *prog, 2317bf215546Sopenharmony_ci struct gl_shader **shader_list, 2318bf215546Sopenharmony_ci unsigned num_shaders, 2319bf215546Sopenharmony_ci bool allow_missing_main) 2320bf215546Sopenharmony_ci{ 2321bf215546Sopenharmony_ci struct gl_uniform_block *ubo_blocks = NULL; 2322bf215546Sopenharmony_ci struct gl_uniform_block *ssbo_blocks = NULL; 2323bf215546Sopenharmony_ci unsigned num_ubo_blocks = 0; 2324bf215546Sopenharmony_ci unsigned num_ssbo_blocks = 0; 2325bf215546Sopenharmony_ci 2326bf215546Sopenharmony_ci /* Check that global variables defined in multiple shaders are consistent. 2327bf215546Sopenharmony_ci */ 2328bf215546Sopenharmony_ci glsl_symbol_table variables; 2329bf215546Sopenharmony_ci for (unsigned i = 0; i < num_shaders; i++) { 2330bf215546Sopenharmony_ci if (shader_list[i] == NULL) 2331bf215546Sopenharmony_ci continue; 2332bf215546Sopenharmony_ci cross_validate_globals(&ctx->Const, prog, shader_list[i]->ir, &variables, 2333bf215546Sopenharmony_ci false); 2334bf215546Sopenharmony_ci } 2335bf215546Sopenharmony_ci 2336bf215546Sopenharmony_ci if (!prog->data->LinkStatus) 2337bf215546Sopenharmony_ci return NULL; 2338bf215546Sopenharmony_ci 2339bf215546Sopenharmony_ci /* Check that interface blocks defined in multiple shaders are consistent. 2340bf215546Sopenharmony_ci */ 2341bf215546Sopenharmony_ci validate_intrastage_interface_blocks(prog, (const gl_shader **)shader_list, 2342bf215546Sopenharmony_ci num_shaders); 2343bf215546Sopenharmony_ci if (!prog->data->LinkStatus) 2344bf215546Sopenharmony_ci return NULL; 2345bf215546Sopenharmony_ci 2346bf215546Sopenharmony_ci /* Check that there is only a single definition of each function signature 2347bf215546Sopenharmony_ci * across all shaders. 2348bf215546Sopenharmony_ci */ 2349bf215546Sopenharmony_ci for (unsigned i = 0; i < (num_shaders - 1); i++) { 2350bf215546Sopenharmony_ci foreach_in_list(ir_instruction, node, shader_list[i]->ir) { 2351bf215546Sopenharmony_ci ir_function *const f = node->as_function(); 2352bf215546Sopenharmony_ci 2353bf215546Sopenharmony_ci if (f == NULL) 2354bf215546Sopenharmony_ci continue; 2355bf215546Sopenharmony_ci 2356bf215546Sopenharmony_ci for (unsigned j = i + 1; j < num_shaders; j++) { 2357bf215546Sopenharmony_ci ir_function *const other = 2358bf215546Sopenharmony_ci shader_list[j]->symbols->get_function(f->name); 2359bf215546Sopenharmony_ci 2360bf215546Sopenharmony_ci /* If the other shader has no function (and therefore no function 2361bf215546Sopenharmony_ci * signatures) with the same name, skip to the next shader. 2362bf215546Sopenharmony_ci */ 2363bf215546Sopenharmony_ci if (other == NULL) 2364bf215546Sopenharmony_ci continue; 2365bf215546Sopenharmony_ci 2366bf215546Sopenharmony_ci foreach_in_list(ir_function_signature, sig, &f->signatures) { 2367bf215546Sopenharmony_ci if (!sig->is_defined) 2368bf215546Sopenharmony_ci continue; 2369bf215546Sopenharmony_ci 2370bf215546Sopenharmony_ci ir_function_signature *other_sig = 2371bf215546Sopenharmony_ci other->exact_matching_signature(NULL, &sig->parameters); 2372bf215546Sopenharmony_ci 2373bf215546Sopenharmony_ci if (other_sig != NULL && other_sig->is_defined) { 2374bf215546Sopenharmony_ci linker_error(prog, "function `%s' is multiply defined\n", 2375bf215546Sopenharmony_ci f->name); 2376bf215546Sopenharmony_ci return NULL; 2377bf215546Sopenharmony_ci } 2378bf215546Sopenharmony_ci } 2379bf215546Sopenharmony_ci } 2380bf215546Sopenharmony_ci } 2381bf215546Sopenharmony_ci } 2382bf215546Sopenharmony_ci 2383bf215546Sopenharmony_ci /* Find the shader that defines main, and make a clone of it. 2384bf215546Sopenharmony_ci * 2385bf215546Sopenharmony_ci * Starting with the clone, search for undefined references. If one is 2386bf215546Sopenharmony_ci * found, find the shader that defines it. Clone the reference and add 2387bf215546Sopenharmony_ci * it to the shader. Repeat until there are no undefined references or 2388bf215546Sopenharmony_ci * until a reference cannot be resolved. 2389bf215546Sopenharmony_ci */ 2390bf215546Sopenharmony_ci gl_shader *main = NULL; 2391bf215546Sopenharmony_ci for (unsigned i = 0; i < num_shaders; i++) { 2392bf215546Sopenharmony_ci if (_mesa_get_main_function_signature(shader_list[i]->symbols)) { 2393bf215546Sopenharmony_ci main = shader_list[i]; 2394bf215546Sopenharmony_ci break; 2395bf215546Sopenharmony_ci } 2396bf215546Sopenharmony_ci } 2397bf215546Sopenharmony_ci 2398bf215546Sopenharmony_ci if (main == NULL && allow_missing_main) 2399bf215546Sopenharmony_ci main = shader_list[0]; 2400bf215546Sopenharmony_ci 2401bf215546Sopenharmony_ci if (main == NULL) { 2402bf215546Sopenharmony_ci linker_error(prog, "%s shader lacks `main'\n", 2403bf215546Sopenharmony_ci _mesa_shader_stage_to_string(shader_list[0]->Stage)); 2404bf215546Sopenharmony_ci return NULL; 2405bf215546Sopenharmony_ci } 2406bf215546Sopenharmony_ci 2407bf215546Sopenharmony_ci gl_linked_shader *linked = rzalloc(NULL, struct gl_linked_shader); 2408bf215546Sopenharmony_ci linked->Stage = shader_list[0]->Stage; 2409bf215546Sopenharmony_ci 2410bf215546Sopenharmony_ci /* Create program and attach it to the linked shader */ 2411bf215546Sopenharmony_ci struct gl_program *gl_prog = 2412bf215546Sopenharmony_ci ctx->Driver.NewProgram(ctx, shader_list[0]->Stage, prog->Name, false); 2413bf215546Sopenharmony_ci if (!gl_prog) { 2414bf215546Sopenharmony_ci prog->data->LinkStatus = LINKING_FAILURE; 2415bf215546Sopenharmony_ci _mesa_delete_linked_shader(ctx, linked); 2416bf215546Sopenharmony_ci return NULL; 2417bf215546Sopenharmony_ci } 2418bf215546Sopenharmony_ci 2419bf215546Sopenharmony_ci _mesa_reference_shader_program_data(&gl_prog->sh.data, prog->data); 2420bf215546Sopenharmony_ci 2421bf215546Sopenharmony_ci /* Don't use _mesa_reference_program() just take ownership */ 2422bf215546Sopenharmony_ci linked->Program = gl_prog; 2423bf215546Sopenharmony_ci 2424bf215546Sopenharmony_ci linked->ir = new(linked) exec_list; 2425bf215546Sopenharmony_ci clone_ir_list(mem_ctx, linked->ir, main->ir); 2426bf215546Sopenharmony_ci 2427bf215546Sopenharmony_ci link_fs_inout_layout_qualifiers(prog, linked, shader_list, num_shaders); 2428bf215546Sopenharmony_ci link_tcs_out_layout_qualifiers(prog, gl_prog, shader_list, num_shaders); 2429bf215546Sopenharmony_ci link_tes_in_layout_qualifiers(prog, gl_prog, shader_list, num_shaders); 2430bf215546Sopenharmony_ci link_gs_inout_layout_qualifiers(prog, gl_prog, shader_list, num_shaders); 2431bf215546Sopenharmony_ci link_cs_input_layout_qualifiers(prog, gl_prog, shader_list, num_shaders); 2432bf215546Sopenharmony_ci 2433bf215546Sopenharmony_ci if (linked->Stage != MESA_SHADER_FRAGMENT) 2434bf215546Sopenharmony_ci link_xfb_stride_layout_qualifiers(&ctx->Const, prog, shader_list, num_shaders); 2435bf215546Sopenharmony_ci 2436bf215546Sopenharmony_ci link_bindless_layout_qualifiers(prog, shader_list, num_shaders); 2437bf215546Sopenharmony_ci 2438bf215546Sopenharmony_ci link_layer_viewport_relative_qualifier(prog, gl_prog, shader_list, num_shaders); 2439bf215546Sopenharmony_ci 2440bf215546Sopenharmony_ci populate_symbol_table(linked, shader_list[0]->symbols); 2441bf215546Sopenharmony_ci 2442bf215546Sopenharmony_ci /* The pointer to the main function in the final linked shader (i.e., the 2443bf215546Sopenharmony_ci * copy of the original shader that contained the main function). 2444bf215546Sopenharmony_ci */ 2445bf215546Sopenharmony_ci ir_function_signature *const main_sig = 2446bf215546Sopenharmony_ci _mesa_get_main_function_signature(linked->symbols); 2447bf215546Sopenharmony_ci 2448bf215546Sopenharmony_ci /* Move any instructions other than variable declarations or function 2449bf215546Sopenharmony_ci * declarations into main. 2450bf215546Sopenharmony_ci */ 2451bf215546Sopenharmony_ci if (main_sig != NULL) { 2452bf215546Sopenharmony_ci exec_node *insertion_point = 2453bf215546Sopenharmony_ci move_non_declarations(linked->ir, &main_sig->body.head_sentinel, false, 2454bf215546Sopenharmony_ci linked); 2455bf215546Sopenharmony_ci 2456bf215546Sopenharmony_ci for (unsigned i = 0; i < num_shaders; i++) { 2457bf215546Sopenharmony_ci if (shader_list[i] == main) 2458bf215546Sopenharmony_ci continue; 2459bf215546Sopenharmony_ci 2460bf215546Sopenharmony_ci insertion_point = move_non_declarations(shader_list[i]->ir, 2461bf215546Sopenharmony_ci insertion_point, true, linked); 2462bf215546Sopenharmony_ci } 2463bf215546Sopenharmony_ci } 2464bf215546Sopenharmony_ci 2465bf215546Sopenharmony_ci if (!link_function_calls(prog, linked, shader_list, num_shaders)) { 2466bf215546Sopenharmony_ci _mesa_delete_linked_shader(ctx, linked); 2467bf215546Sopenharmony_ci return NULL; 2468bf215546Sopenharmony_ci } 2469bf215546Sopenharmony_ci 2470bf215546Sopenharmony_ci if (linked->Stage != MESA_SHADER_FRAGMENT) 2471bf215546Sopenharmony_ci link_output_variables(linked, shader_list, num_shaders); 2472bf215546Sopenharmony_ci 2473bf215546Sopenharmony_ci /* Make a pass over all variable declarations to ensure that arrays with 2474bf215546Sopenharmony_ci * unspecified sizes have a size specified. The size is inferred from the 2475bf215546Sopenharmony_ci * max_array_access field. 2476bf215546Sopenharmony_ci */ 2477bf215546Sopenharmony_ci array_sizing_visitor v; 2478bf215546Sopenharmony_ci v.run(linked->ir); 2479bf215546Sopenharmony_ci v.fixup_unnamed_interface_types(); 2480bf215546Sopenharmony_ci 2481bf215546Sopenharmony_ci /* Now that we know the sizes of all the arrays, we can replace .length() 2482bf215546Sopenharmony_ci * calls with a constant expression. 2483bf215546Sopenharmony_ci */ 2484bf215546Sopenharmony_ci array_length_to_const_visitor len_v; 2485bf215546Sopenharmony_ci len_v.run(linked->ir); 2486bf215546Sopenharmony_ci 2487bf215546Sopenharmony_ci /* Link up uniform blocks defined within this stage. */ 2488bf215546Sopenharmony_ci link_uniform_blocks(mem_ctx, &ctx->Const, prog, linked, &ubo_blocks, 2489bf215546Sopenharmony_ci &num_ubo_blocks, &ssbo_blocks, &num_ssbo_blocks); 2490bf215546Sopenharmony_ci 2491bf215546Sopenharmony_ci const unsigned max_uniform_blocks = 2492bf215546Sopenharmony_ci ctx->Const.Program[linked->Stage].MaxUniformBlocks; 2493bf215546Sopenharmony_ci if (num_ubo_blocks > max_uniform_blocks) { 2494bf215546Sopenharmony_ci linker_error(prog, "Too many %s uniform blocks (%d/%d)\n", 2495bf215546Sopenharmony_ci _mesa_shader_stage_to_string(linked->Stage), 2496bf215546Sopenharmony_ci num_ubo_blocks, max_uniform_blocks); 2497bf215546Sopenharmony_ci } 2498bf215546Sopenharmony_ci 2499bf215546Sopenharmony_ci const unsigned max_shader_storage_blocks = 2500bf215546Sopenharmony_ci ctx->Const.Program[linked->Stage].MaxShaderStorageBlocks; 2501bf215546Sopenharmony_ci if (num_ssbo_blocks > max_shader_storage_blocks) { 2502bf215546Sopenharmony_ci linker_error(prog, "Too many %s shader storage blocks (%d/%d)\n", 2503bf215546Sopenharmony_ci _mesa_shader_stage_to_string(linked->Stage), 2504bf215546Sopenharmony_ci num_ssbo_blocks, max_shader_storage_blocks); 2505bf215546Sopenharmony_ci } 2506bf215546Sopenharmony_ci 2507bf215546Sopenharmony_ci if (!prog->data->LinkStatus) { 2508bf215546Sopenharmony_ci _mesa_delete_linked_shader(ctx, linked); 2509bf215546Sopenharmony_ci return NULL; 2510bf215546Sopenharmony_ci } 2511bf215546Sopenharmony_ci 2512bf215546Sopenharmony_ci /* Copy ubo blocks to linked shader list */ 2513bf215546Sopenharmony_ci linked->Program->sh.UniformBlocks = 2514bf215546Sopenharmony_ci ralloc_array(linked, gl_uniform_block *, num_ubo_blocks); 2515bf215546Sopenharmony_ci ralloc_steal(linked, ubo_blocks); 2516bf215546Sopenharmony_ci for (unsigned i = 0; i < num_ubo_blocks; i++) { 2517bf215546Sopenharmony_ci linked->Program->sh.UniformBlocks[i] = &ubo_blocks[i]; 2518bf215546Sopenharmony_ci } 2519bf215546Sopenharmony_ci linked->Program->sh.NumUniformBlocks = num_ubo_blocks; 2520bf215546Sopenharmony_ci linked->Program->info.num_ubos = num_ubo_blocks; 2521bf215546Sopenharmony_ci 2522bf215546Sopenharmony_ci /* Copy ssbo blocks to linked shader list */ 2523bf215546Sopenharmony_ci linked->Program->sh.ShaderStorageBlocks = 2524bf215546Sopenharmony_ci ralloc_array(linked, gl_uniform_block *, num_ssbo_blocks); 2525bf215546Sopenharmony_ci ralloc_steal(linked, ssbo_blocks); 2526bf215546Sopenharmony_ci for (unsigned i = 0; i < num_ssbo_blocks; i++) { 2527bf215546Sopenharmony_ci linked->Program->sh.ShaderStorageBlocks[i] = &ssbo_blocks[i]; 2528bf215546Sopenharmony_ci } 2529bf215546Sopenharmony_ci linked->Program->info.num_ssbos = num_ssbo_blocks; 2530bf215546Sopenharmony_ci 2531bf215546Sopenharmony_ci /* At this point linked should contain all of the linked IR, so 2532bf215546Sopenharmony_ci * validate it to make sure nothing went wrong. 2533bf215546Sopenharmony_ci */ 2534bf215546Sopenharmony_ci validate_ir_tree(linked->ir); 2535bf215546Sopenharmony_ci 2536bf215546Sopenharmony_ci /* Set the size of geometry shader input arrays */ 2537bf215546Sopenharmony_ci if (linked->Stage == MESA_SHADER_GEOMETRY) { 2538bf215546Sopenharmony_ci unsigned num_vertices = 2539bf215546Sopenharmony_ci vertices_per_prim(gl_prog->info.gs.input_primitive); 2540bf215546Sopenharmony_ci array_resize_visitor input_resize_visitor(num_vertices, prog, 2541bf215546Sopenharmony_ci MESA_SHADER_GEOMETRY); 2542bf215546Sopenharmony_ci foreach_in_list(ir_instruction, ir, linked->ir) { 2543bf215546Sopenharmony_ci ir->accept(&input_resize_visitor); 2544bf215546Sopenharmony_ci } 2545bf215546Sopenharmony_ci } 2546bf215546Sopenharmony_ci 2547bf215546Sopenharmony_ci if (ctx->Const.VertexID_is_zero_based) 2548bf215546Sopenharmony_ci lower_vertex_id(linked); 2549bf215546Sopenharmony_ci 2550bf215546Sopenharmony_ci if (ctx->Const.LowerCsDerivedVariables) 2551bf215546Sopenharmony_ci lower_cs_derived(linked); 2552bf215546Sopenharmony_ci 2553bf215546Sopenharmony_ci /* Set the linked source SHA1. */ 2554bf215546Sopenharmony_ci if (num_shaders == 1) { 2555bf215546Sopenharmony_ci memcpy(linked->linked_source_sha1, shader_list[0]->compiled_source_sha1, 2556bf215546Sopenharmony_ci SHA1_DIGEST_LENGTH); 2557bf215546Sopenharmony_ci } else { 2558bf215546Sopenharmony_ci struct mesa_sha1 sha1_ctx; 2559bf215546Sopenharmony_ci _mesa_sha1_init(&sha1_ctx); 2560bf215546Sopenharmony_ci 2561bf215546Sopenharmony_ci for (unsigned i = 0; i < num_shaders; i++) { 2562bf215546Sopenharmony_ci if (shader_list[i] == NULL) 2563bf215546Sopenharmony_ci continue; 2564bf215546Sopenharmony_ci 2565bf215546Sopenharmony_ci _mesa_sha1_update(&sha1_ctx, shader_list[i]->compiled_source_sha1, 2566bf215546Sopenharmony_ci SHA1_DIGEST_LENGTH); 2567bf215546Sopenharmony_ci } 2568bf215546Sopenharmony_ci _mesa_sha1_final(&sha1_ctx, linked->linked_source_sha1); 2569bf215546Sopenharmony_ci } 2570bf215546Sopenharmony_ci 2571bf215546Sopenharmony_ci return linked; 2572bf215546Sopenharmony_ci} 2573bf215546Sopenharmony_ci 2574bf215546Sopenharmony_ci/** 2575bf215546Sopenharmony_ci * Resize tessellation evaluation per-vertex inputs to the size of 2576bf215546Sopenharmony_ci * tessellation control per-vertex outputs. 2577bf215546Sopenharmony_ci */ 2578bf215546Sopenharmony_cistatic void 2579bf215546Sopenharmony_ciresize_tes_inputs(const struct gl_constants *consts, 2580bf215546Sopenharmony_ci struct gl_shader_program *prog) 2581bf215546Sopenharmony_ci{ 2582bf215546Sopenharmony_ci if (prog->_LinkedShaders[MESA_SHADER_TESS_EVAL] == NULL) 2583bf215546Sopenharmony_ci return; 2584bf215546Sopenharmony_ci 2585bf215546Sopenharmony_ci gl_linked_shader *const tcs = prog->_LinkedShaders[MESA_SHADER_TESS_CTRL]; 2586bf215546Sopenharmony_ci gl_linked_shader *const tes = prog->_LinkedShaders[MESA_SHADER_TESS_EVAL]; 2587bf215546Sopenharmony_ci 2588bf215546Sopenharmony_ci /* If no control shader is present, then the TES inputs are statically 2589bf215546Sopenharmony_ci * sized to MaxPatchVertices; the actual size of the arrays won't be 2590bf215546Sopenharmony_ci * known until draw time. 2591bf215546Sopenharmony_ci */ 2592bf215546Sopenharmony_ci const int num_vertices = tcs 2593bf215546Sopenharmony_ci ? tcs->Program->info.tess.tcs_vertices_out 2594bf215546Sopenharmony_ci : consts->MaxPatchVertices; 2595bf215546Sopenharmony_ci 2596bf215546Sopenharmony_ci array_resize_visitor input_resize_visitor(num_vertices, prog, 2597bf215546Sopenharmony_ci MESA_SHADER_TESS_EVAL); 2598bf215546Sopenharmony_ci foreach_in_list(ir_instruction, ir, tes->ir) { 2599bf215546Sopenharmony_ci ir->accept(&input_resize_visitor); 2600bf215546Sopenharmony_ci } 2601bf215546Sopenharmony_ci 2602bf215546Sopenharmony_ci if (tcs) { 2603bf215546Sopenharmony_ci /* Convert the gl_PatchVerticesIn system value into a constant, since 2604bf215546Sopenharmony_ci * the value is known at this point. 2605bf215546Sopenharmony_ci */ 2606bf215546Sopenharmony_ci foreach_in_list(ir_instruction, ir, tes->ir) { 2607bf215546Sopenharmony_ci ir_variable *var = ir->as_variable(); 2608bf215546Sopenharmony_ci if (var && var->data.mode == ir_var_system_value && 2609bf215546Sopenharmony_ci var->data.location == SYSTEM_VALUE_VERTICES_IN) { 2610bf215546Sopenharmony_ci void *mem_ctx = ralloc_parent(var); 2611bf215546Sopenharmony_ci var->data.location = 0; 2612bf215546Sopenharmony_ci var->data.explicit_location = false; 2613bf215546Sopenharmony_ci var->data.mode = ir_var_auto; 2614bf215546Sopenharmony_ci var->constant_value = new(mem_ctx) ir_constant(num_vertices); 2615bf215546Sopenharmony_ci } 2616bf215546Sopenharmony_ci } 2617bf215546Sopenharmony_ci } 2618bf215546Sopenharmony_ci} 2619bf215546Sopenharmony_ci 2620bf215546Sopenharmony_ci/** 2621bf215546Sopenharmony_ci * Find a contiguous set of available bits in a bitmask. 2622bf215546Sopenharmony_ci * 2623bf215546Sopenharmony_ci * \param used_mask Bits representing used (1) and unused (0) locations 2624bf215546Sopenharmony_ci * \param needed_count Number of contiguous bits needed. 2625bf215546Sopenharmony_ci * 2626bf215546Sopenharmony_ci * \return 2627bf215546Sopenharmony_ci * Base location of the available bits on success or -1 on failure. 2628bf215546Sopenharmony_ci */ 2629bf215546Sopenharmony_cistatic int 2630bf215546Sopenharmony_cifind_available_slots(unsigned used_mask, unsigned needed_count) 2631bf215546Sopenharmony_ci{ 2632bf215546Sopenharmony_ci unsigned needed_mask = (1 << needed_count) - 1; 2633bf215546Sopenharmony_ci const int max_bit_to_test = (8 * sizeof(used_mask)) - needed_count; 2634bf215546Sopenharmony_ci 2635bf215546Sopenharmony_ci /* The comparison to 32 is redundant, but without it GCC emits "warning: 2636bf215546Sopenharmony_ci * cannot optimize possibly infinite loops" for the loop below. 2637bf215546Sopenharmony_ci */ 2638bf215546Sopenharmony_ci if ((needed_count == 0) || (max_bit_to_test < 0) || (max_bit_to_test > 32)) 2639bf215546Sopenharmony_ci return -1; 2640bf215546Sopenharmony_ci 2641bf215546Sopenharmony_ci for (int i = 0; i <= max_bit_to_test; i++) { 2642bf215546Sopenharmony_ci if ((needed_mask & ~used_mask) == needed_mask) 2643bf215546Sopenharmony_ci return i; 2644bf215546Sopenharmony_ci 2645bf215546Sopenharmony_ci needed_mask <<= 1; 2646bf215546Sopenharmony_ci } 2647bf215546Sopenharmony_ci 2648bf215546Sopenharmony_ci return -1; 2649bf215546Sopenharmony_ci} 2650bf215546Sopenharmony_ci 2651bf215546Sopenharmony_ci 2652bf215546Sopenharmony_ci#define SAFE_MASK_FROM_INDEX(i) (((i) >= 32) ? ~0 : ((1 << (i)) - 1)) 2653bf215546Sopenharmony_ci 2654bf215546Sopenharmony_ci/** 2655bf215546Sopenharmony_ci * Assign locations for either VS inputs or FS outputs. 2656bf215546Sopenharmony_ci * 2657bf215546Sopenharmony_ci * \param mem_ctx Temporary ralloc context used for linking. 2658bf215546Sopenharmony_ci * \param prog Shader program whose variables need locations 2659bf215546Sopenharmony_ci * assigned. 2660bf215546Sopenharmony_ci * \param constants Driver specific constant values for the program. 2661bf215546Sopenharmony_ci * \param target_index Selector for the program target to receive location 2662bf215546Sopenharmony_ci * assignmnets. Must be either \c MESA_SHADER_VERTEX or 2663bf215546Sopenharmony_ci * \c MESA_SHADER_FRAGMENT. 2664bf215546Sopenharmony_ci * \param do_assignment Whether we are actually marking the assignment or we 2665bf215546Sopenharmony_ci * are just doing a dry-run checking. 2666bf215546Sopenharmony_ci * 2667bf215546Sopenharmony_ci * \return 2668bf215546Sopenharmony_ci * If locations are (or can be, in case of dry-running) successfully assigned, 2669bf215546Sopenharmony_ci * true is returned. Otherwise an error is emitted to the shader link log and 2670bf215546Sopenharmony_ci * false is returned. 2671bf215546Sopenharmony_ci */ 2672bf215546Sopenharmony_cistatic bool 2673bf215546Sopenharmony_ciassign_attribute_or_color_locations(void *mem_ctx, 2674bf215546Sopenharmony_ci gl_shader_program *prog, 2675bf215546Sopenharmony_ci const struct gl_constants *constants, 2676bf215546Sopenharmony_ci unsigned target_index, 2677bf215546Sopenharmony_ci bool do_assignment) 2678bf215546Sopenharmony_ci{ 2679bf215546Sopenharmony_ci /* Maximum number of generic locations. This corresponds to either the 2680bf215546Sopenharmony_ci * maximum number of draw buffers or the maximum number of generic 2681bf215546Sopenharmony_ci * attributes. 2682bf215546Sopenharmony_ci */ 2683bf215546Sopenharmony_ci unsigned max_index = (target_index == MESA_SHADER_VERTEX) ? 2684bf215546Sopenharmony_ci constants->Program[target_index].MaxAttribs : 2685bf215546Sopenharmony_ci MAX2(constants->MaxDrawBuffers, constants->MaxDualSourceDrawBuffers); 2686bf215546Sopenharmony_ci 2687bf215546Sopenharmony_ci /* Mark invalid locations as being used. 2688bf215546Sopenharmony_ci */ 2689bf215546Sopenharmony_ci unsigned used_locations = ~SAFE_MASK_FROM_INDEX(max_index); 2690bf215546Sopenharmony_ci unsigned double_storage_locations = 0; 2691bf215546Sopenharmony_ci 2692bf215546Sopenharmony_ci assert((target_index == MESA_SHADER_VERTEX) 2693bf215546Sopenharmony_ci || (target_index == MESA_SHADER_FRAGMENT)); 2694bf215546Sopenharmony_ci 2695bf215546Sopenharmony_ci gl_linked_shader *const sh = prog->_LinkedShaders[target_index]; 2696bf215546Sopenharmony_ci if (sh == NULL) 2697bf215546Sopenharmony_ci return true; 2698bf215546Sopenharmony_ci 2699bf215546Sopenharmony_ci /* Operate in a total of four passes. 2700bf215546Sopenharmony_ci * 2701bf215546Sopenharmony_ci * 1. Invalidate the location assignments for all vertex shader inputs. 2702bf215546Sopenharmony_ci * 2703bf215546Sopenharmony_ci * 2. Assign locations for inputs that have user-defined (via 2704bf215546Sopenharmony_ci * glBindVertexAttribLocation) locations and outputs that have 2705bf215546Sopenharmony_ci * user-defined locations (via glBindFragDataLocation). 2706bf215546Sopenharmony_ci * 2707bf215546Sopenharmony_ci * 3. Sort the attributes without assigned locations by number of slots 2708bf215546Sopenharmony_ci * required in decreasing order. Fragmentation caused by attribute 2709bf215546Sopenharmony_ci * locations assigned by the application may prevent large attributes 2710bf215546Sopenharmony_ci * from having enough contiguous space. 2711bf215546Sopenharmony_ci * 2712bf215546Sopenharmony_ci * 4. Assign locations to any inputs without assigned locations. 2713bf215546Sopenharmony_ci */ 2714bf215546Sopenharmony_ci 2715bf215546Sopenharmony_ci const int generic_base = (target_index == MESA_SHADER_VERTEX) 2716bf215546Sopenharmony_ci ? (int) VERT_ATTRIB_GENERIC0 : (int) FRAG_RESULT_DATA0; 2717bf215546Sopenharmony_ci 2718bf215546Sopenharmony_ci const enum ir_variable_mode direction = 2719bf215546Sopenharmony_ci (target_index == MESA_SHADER_VERTEX) 2720bf215546Sopenharmony_ci ? ir_var_shader_in : ir_var_shader_out; 2721bf215546Sopenharmony_ci 2722bf215546Sopenharmony_ci 2723bf215546Sopenharmony_ci /* Temporary storage for the set of attributes that need locations assigned. 2724bf215546Sopenharmony_ci */ 2725bf215546Sopenharmony_ci struct temp_attr { 2726bf215546Sopenharmony_ci unsigned slots; 2727bf215546Sopenharmony_ci ir_variable *var; 2728bf215546Sopenharmony_ci 2729bf215546Sopenharmony_ci /* Used below in the call to qsort. */ 2730bf215546Sopenharmony_ci static int compare(const void *a, const void *b) 2731bf215546Sopenharmony_ci { 2732bf215546Sopenharmony_ci const temp_attr *const l = (const temp_attr *) a; 2733bf215546Sopenharmony_ci const temp_attr *const r = (const temp_attr *) b; 2734bf215546Sopenharmony_ci 2735bf215546Sopenharmony_ci /* Reversed because we want a descending order sort below. */ 2736bf215546Sopenharmony_ci return r->slots - l->slots; 2737bf215546Sopenharmony_ci } 2738bf215546Sopenharmony_ci } to_assign[32]; 2739bf215546Sopenharmony_ci assert(max_index <= 32); 2740bf215546Sopenharmony_ci 2741bf215546Sopenharmony_ci /* Temporary array for the set of attributes that have locations assigned, 2742bf215546Sopenharmony_ci * for the purpose of checking overlapping slots/components of (non-ES) 2743bf215546Sopenharmony_ci * fragment shader outputs. 2744bf215546Sopenharmony_ci */ 2745bf215546Sopenharmony_ci ir_variable *assigned[12 * 4]; /* (max # of FS outputs) * # components */ 2746bf215546Sopenharmony_ci unsigned assigned_attr = 0; 2747bf215546Sopenharmony_ci 2748bf215546Sopenharmony_ci unsigned num_attr = 0; 2749bf215546Sopenharmony_ci 2750bf215546Sopenharmony_ci foreach_in_list(ir_instruction, node, sh->ir) { 2751bf215546Sopenharmony_ci ir_variable *const var = node->as_variable(); 2752bf215546Sopenharmony_ci 2753bf215546Sopenharmony_ci if ((var == NULL) || (var->data.mode != (unsigned) direction)) 2754bf215546Sopenharmony_ci continue; 2755bf215546Sopenharmony_ci 2756bf215546Sopenharmony_ci if (var->data.explicit_location) { 2757bf215546Sopenharmony_ci if ((var->data.location >= (int)(max_index + generic_base)) 2758bf215546Sopenharmony_ci || (var->data.location < 0)) { 2759bf215546Sopenharmony_ci linker_error(prog, 2760bf215546Sopenharmony_ci "invalid explicit location %d specified for `%s'\n", 2761bf215546Sopenharmony_ci (var->data.location < 0) 2762bf215546Sopenharmony_ci ? var->data.location 2763bf215546Sopenharmony_ci : var->data.location - generic_base, 2764bf215546Sopenharmony_ci var->name); 2765bf215546Sopenharmony_ci return false; 2766bf215546Sopenharmony_ci } 2767bf215546Sopenharmony_ci } else if (target_index == MESA_SHADER_VERTEX) { 2768bf215546Sopenharmony_ci unsigned binding; 2769bf215546Sopenharmony_ci 2770bf215546Sopenharmony_ci if (prog->AttributeBindings->get(binding, var->name)) { 2771bf215546Sopenharmony_ci assert(binding >= VERT_ATTRIB_GENERIC0); 2772bf215546Sopenharmony_ci var->data.location = binding; 2773bf215546Sopenharmony_ci } 2774bf215546Sopenharmony_ci } else if (target_index == MESA_SHADER_FRAGMENT) { 2775bf215546Sopenharmony_ci unsigned binding; 2776bf215546Sopenharmony_ci unsigned index; 2777bf215546Sopenharmony_ci const char *name = var->name; 2778bf215546Sopenharmony_ci const glsl_type *type = var->type; 2779bf215546Sopenharmony_ci 2780bf215546Sopenharmony_ci while (type) { 2781bf215546Sopenharmony_ci /* Check if there's a binding for the variable name */ 2782bf215546Sopenharmony_ci if (prog->FragDataBindings->get(binding, name)) { 2783bf215546Sopenharmony_ci assert(binding >= FRAG_RESULT_DATA0); 2784bf215546Sopenharmony_ci var->data.location = binding; 2785bf215546Sopenharmony_ci 2786bf215546Sopenharmony_ci if (prog->FragDataIndexBindings->get(index, name)) { 2787bf215546Sopenharmony_ci var->data.index = index; 2788bf215546Sopenharmony_ci } 2789bf215546Sopenharmony_ci break; 2790bf215546Sopenharmony_ci } 2791bf215546Sopenharmony_ci 2792bf215546Sopenharmony_ci /* If not, but it's an array type, look for name[0] */ 2793bf215546Sopenharmony_ci if (type->is_array()) { 2794bf215546Sopenharmony_ci name = ralloc_asprintf(mem_ctx, "%s[0]", name); 2795bf215546Sopenharmony_ci type = type->fields.array; 2796bf215546Sopenharmony_ci continue; 2797bf215546Sopenharmony_ci } 2798bf215546Sopenharmony_ci 2799bf215546Sopenharmony_ci break; 2800bf215546Sopenharmony_ci } 2801bf215546Sopenharmony_ci } 2802bf215546Sopenharmony_ci 2803bf215546Sopenharmony_ci if (strcmp(var->name, "gl_LastFragData") == 0) 2804bf215546Sopenharmony_ci continue; 2805bf215546Sopenharmony_ci 2806bf215546Sopenharmony_ci /* From GL4.5 core spec, section 15.2 (Shader Execution): 2807bf215546Sopenharmony_ci * 2808bf215546Sopenharmony_ci * "Output binding assignments will cause LinkProgram to fail: 2809bf215546Sopenharmony_ci * ... 2810bf215546Sopenharmony_ci * If the program has an active output assigned to a location greater 2811bf215546Sopenharmony_ci * than or equal to the value of MAX_DUAL_SOURCE_DRAW_BUFFERS and has 2812bf215546Sopenharmony_ci * an active output assigned an index greater than or equal to one;" 2813bf215546Sopenharmony_ci */ 2814bf215546Sopenharmony_ci if (target_index == MESA_SHADER_FRAGMENT && var->data.index >= 1 && 2815bf215546Sopenharmony_ci var->data.location - generic_base >= 2816bf215546Sopenharmony_ci (int) constants->MaxDualSourceDrawBuffers) { 2817bf215546Sopenharmony_ci linker_error(prog, 2818bf215546Sopenharmony_ci "output location %d >= GL_MAX_DUAL_SOURCE_DRAW_BUFFERS " 2819bf215546Sopenharmony_ci "with index %u for %s\n", 2820bf215546Sopenharmony_ci var->data.location - generic_base, var->data.index, 2821bf215546Sopenharmony_ci var->name); 2822bf215546Sopenharmony_ci return false; 2823bf215546Sopenharmony_ci } 2824bf215546Sopenharmony_ci 2825bf215546Sopenharmony_ci const unsigned slots = var->type->count_attribute_slots(target_index == MESA_SHADER_VERTEX); 2826bf215546Sopenharmony_ci 2827bf215546Sopenharmony_ci /* If the variable is not a built-in and has a location statically 2828bf215546Sopenharmony_ci * assigned in the shader (presumably via a layout qualifier), make sure 2829bf215546Sopenharmony_ci * that it doesn't collide with other assigned locations. Otherwise, 2830bf215546Sopenharmony_ci * add it to the list of variables that need linker-assigned locations. 2831bf215546Sopenharmony_ci */ 2832bf215546Sopenharmony_ci if (var->data.location != -1) { 2833bf215546Sopenharmony_ci if (var->data.location >= generic_base && var->data.index < 1) { 2834bf215546Sopenharmony_ci /* From page 61 of the OpenGL 4.0 spec: 2835bf215546Sopenharmony_ci * 2836bf215546Sopenharmony_ci * "LinkProgram will fail if the attribute bindings assigned 2837bf215546Sopenharmony_ci * by BindAttribLocation do not leave not enough space to 2838bf215546Sopenharmony_ci * assign a location for an active matrix attribute or an 2839bf215546Sopenharmony_ci * active attribute array, both of which require multiple 2840bf215546Sopenharmony_ci * contiguous generic attributes." 2841bf215546Sopenharmony_ci * 2842bf215546Sopenharmony_ci * I think above text prohibits the aliasing of explicit and 2843bf215546Sopenharmony_ci * automatic assignments. But, aliasing is allowed in manual 2844bf215546Sopenharmony_ci * assignments of attribute locations. See below comments for 2845bf215546Sopenharmony_ci * the details. 2846bf215546Sopenharmony_ci * 2847bf215546Sopenharmony_ci * From OpenGL 4.0 spec, page 61: 2848bf215546Sopenharmony_ci * 2849bf215546Sopenharmony_ci * "It is possible for an application to bind more than one 2850bf215546Sopenharmony_ci * attribute name to the same location. This is referred to as 2851bf215546Sopenharmony_ci * aliasing. This will only work if only one of the aliased 2852bf215546Sopenharmony_ci * attributes is active in the executable program, or if no 2853bf215546Sopenharmony_ci * path through the shader consumes more than one attribute of 2854bf215546Sopenharmony_ci * a set of attributes aliased to the same location. A link 2855bf215546Sopenharmony_ci * error can occur if the linker determines that every path 2856bf215546Sopenharmony_ci * through the shader consumes multiple aliased attributes, 2857bf215546Sopenharmony_ci * but implementations are not required to generate an error 2858bf215546Sopenharmony_ci * in this case." 2859bf215546Sopenharmony_ci * 2860bf215546Sopenharmony_ci * From GLSL 4.30 spec, page 54: 2861bf215546Sopenharmony_ci * 2862bf215546Sopenharmony_ci * "A program will fail to link if any two non-vertex shader 2863bf215546Sopenharmony_ci * input variables are assigned to the same location. For 2864bf215546Sopenharmony_ci * vertex shaders, multiple input variables may be assigned 2865bf215546Sopenharmony_ci * to the same location using either layout qualifiers or via 2866bf215546Sopenharmony_ci * the OpenGL API. However, such aliasing is intended only to 2867bf215546Sopenharmony_ci * support vertex shaders where each execution path accesses 2868bf215546Sopenharmony_ci * at most one input per each location. Implementations are 2869bf215546Sopenharmony_ci * permitted, but not required, to generate link-time errors 2870bf215546Sopenharmony_ci * if they detect that every path through the vertex shader 2871bf215546Sopenharmony_ci * executable accesses multiple inputs assigned to any single 2872bf215546Sopenharmony_ci * location. For all shader types, a program will fail to link 2873bf215546Sopenharmony_ci * if explicit location assignments leave the linker unable 2874bf215546Sopenharmony_ci * to find space for other variables without explicit 2875bf215546Sopenharmony_ci * assignments." 2876bf215546Sopenharmony_ci * 2877bf215546Sopenharmony_ci * From OpenGL ES 3.0 spec, page 56: 2878bf215546Sopenharmony_ci * 2879bf215546Sopenharmony_ci * "Binding more than one attribute name to the same location 2880bf215546Sopenharmony_ci * is referred to as aliasing, and is not permitted in OpenGL 2881bf215546Sopenharmony_ci * ES Shading Language 3.00 vertex shaders. LinkProgram will 2882bf215546Sopenharmony_ci * fail when this condition exists. However, aliasing is 2883bf215546Sopenharmony_ci * possible in OpenGL ES Shading Language 1.00 vertex shaders. 2884bf215546Sopenharmony_ci * This will only work if only one of the aliased attributes 2885bf215546Sopenharmony_ci * is active in the executable program, or if no path through 2886bf215546Sopenharmony_ci * the shader consumes more than one attribute of a set of 2887bf215546Sopenharmony_ci * attributes aliased to the same location. A link error can 2888bf215546Sopenharmony_ci * occur if the linker determines that every path through the 2889bf215546Sopenharmony_ci * shader consumes multiple aliased attributes, but implemen- 2890bf215546Sopenharmony_ci * tations are not required to generate an error in this case." 2891bf215546Sopenharmony_ci * 2892bf215546Sopenharmony_ci * After looking at above references from OpenGL, OpenGL ES and 2893bf215546Sopenharmony_ci * GLSL specifications, we allow aliasing of vertex input variables 2894bf215546Sopenharmony_ci * in: OpenGL 2.0 (and above) and OpenGL ES 2.0. 2895bf215546Sopenharmony_ci * 2896bf215546Sopenharmony_ci * NOTE: This is not required by the spec but its worth mentioning 2897bf215546Sopenharmony_ci * here that we're not doing anything to make sure that no path 2898bf215546Sopenharmony_ci * through the vertex shader executable accesses multiple inputs 2899bf215546Sopenharmony_ci * assigned to any single location. 2900bf215546Sopenharmony_ci */ 2901bf215546Sopenharmony_ci 2902bf215546Sopenharmony_ci /* Mask representing the contiguous slots that will be used by 2903bf215546Sopenharmony_ci * this attribute. 2904bf215546Sopenharmony_ci */ 2905bf215546Sopenharmony_ci const unsigned attr = var->data.location - generic_base; 2906bf215546Sopenharmony_ci const unsigned use_mask = (1 << slots) - 1; 2907bf215546Sopenharmony_ci const char *const string = (target_index == MESA_SHADER_VERTEX) 2908bf215546Sopenharmony_ci ? "vertex shader input" : "fragment shader output"; 2909bf215546Sopenharmony_ci 2910bf215546Sopenharmony_ci /* Generate a link error if the requested locations for this 2911bf215546Sopenharmony_ci * attribute exceed the maximum allowed attribute location. 2912bf215546Sopenharmony_ci */ 2913bf215546Sopenharmony_ci if (attr + slots > max_index) { 2914bf215546Sopenharmony_ci linker_error(prog, 2915bf215546Sopenharmony_ci "insufficient contiguous locations " 2916bf215546Sopenharmony_ci "available for %s `%s' %d %d %d\n", string, 2917bf215546Sopenharmony_ci var->name, used_locations, use_mask, attr); 2918bf215546Sopenharmony_ci return false; 2919bf215546Sopenharmony_ci } 2920bf215546Sopenharmony_ci 2921bf215546Sopenharmony_ci /* Generate a link error if the set of bits requested for this 2922bf215546Sopenharmony_ci * attribute overlaps any previously allocated bits. 2923bf215546Sopenharmony_ci */ 2924bf215546Sopenharmony_ci if ((~(use_mask << attr) & used_locations) != used_locations) { 2925bf215546Sopenharmony_ci if (target_index == MESA_SHADER_FRAGMENT && !prog->IsES) { 2926bf215546Sopenharmony_ci /* From section 4.4.2 (Output Layout Qualifiers) of the GLSL 2927bf215546Sopenharmony_ci * 4.40 spec: 2928bf215546Sopenharmony_ci * 2929bf215546Sopenharmony_ci * "Additionally, for fragment shader outputs, if two 2930bf215546Sopenharmony_ci * variables are placed within the same location, they 2931bf215546Sopenharmony_ci * must have the same underlying type (floating-point or 2932bf215546Sopenharmony_ci * integer). No component aliasing of output variables or 2933bf215546Sopenharmony_ci * members is allowed. 2934bf215546Sopenharmony_ci */ 2935bf215546Sopenharmony_ci for (unsigned i = 0; i < assigned_attr; i++) { 2936bf215546Sopenharmony_ci unsigned assigned_slots = 2937bf215546Sopenharmony_ci assigned[i]->type->count_attribute_slots(false); 2938bf215546Sopenharmony_ci unsigned assig_attr = 2939bf215546Sopenharmony_ci assigned[i]->data.location - generic_base; 2940bf215546Sopenharmony_ci unsigned assigned_use_mask = (1 << assigned_slots) - 1; 2941bf215546Sopenharmony_ci 2942bf215546Sopenharmony_ci if ((assigned_use_mask << assig_attr) & 2943bf215546Sopenharmony_ci (use_mask << attr)) { 2944bf215546Sopenharmony_ci 2945bf215546Sopenharmony_ci const glsl_type *assigned_type = 2946bf215546Sopenharmony_ci assigned[i]->type->without_array(); 2947bf215546Sopenharmony_ci const glsl_type *type = var->type->without_array(); 2948bf215546Sopenharmony_ci if (assigned_type->base_type != type->base_type) { 2949bf215546Sopenharmony_ci linker_error(prog, "types do not match for aliased" 2950bf215546Sopenharmony_ci " %ss %s and %s\n", string, 2951bf215546Sopenharmony_ci assigned[i]->name, var->name); 2952bf215546Sopenharmony_ci return false; 2953bf215546Sopenharmony_ci } 2954bf215546Sopenharmony_ci 2955bf215546Sopenharmony_ci unsigned assigned_component_mask = 2956bf215546Sopenharmony_ci ((1 << assigned_type->vector_elements) - 1) << 2957bf215546Sopenharmony_ci assigned[i]->data.location_frac; 2958bf215546Sopenharmony_ci unsigned component_mask = 2959bf215546Sopenharmony_ci ((1 << type->vector_elements) - 1) << 2960bf215546Sopenharmony_ci var->data.location_frac; 2961bf215546Sopenharmony_ci if (assigned_component_mask & component_mask) { 2962bf215546Sopenharmony_ci linker_error(prog, "overlapping component is " 2963bf215546Sopenharmony_ci "assigned to %ss %s and %s " 2964bf215546Sopenharmony_ci "(component=%d)\n", 2965bf215546Sopenharmony_ci string, assigned[i]->name, var->name, 2966bf215546Sopenharmony_ci var->data.location_frac); 2967bf215546Sopenharmony_ci return false; 2968bf215546Sopenharmony_ci } 2969bf215546Sopenharmony_ci } 2970bf215546Sopenharmony_ci } 2971bf215546Sopenharmony_ci } else if (target_index == MESA_SHADER_FRAGMENT || 2972bf215546Sopenharmony_ci (prog->IsES && prog->data->Version >= 300)) { 2973bf215546Sopenharmony_ci linker_error(prog, "overlapping location is assigned " 2974bf215546Sopenharmony_ci "to %s `%s' %d %d %d\n", string, var->name, 2975bf215546Sopenharmony_ci used_locations, use_mask, attr); 2976bf215546Sopenharmony_ci return false; 2977bf215546Sopenharmony_ci } else { 2978bf215546Sopenharmony_ci linker_warning(prog, "overlapping location is assigned " 2979bf215546Sopenharmony_ci "to %s `%s' %d %d %d\n", string, var->name, 2980bf215546Sopenharmony_ci used_locations, use_mask, attr); 2981bf215546Sopenharmony_ci } 2982bf215546Sopenharmony_ci } 2983bf215546Sopenharmony_ci 2984bf215546Sopenharmony_ci if (target_index == MESA_SHADER_FRAGMENT && !prog->IsES) { 2985bf215546Sopenharmony_ci /* Only track assigned variables for non-ES fragment shaders 2986bf215546Sopenharmony_ci * to avoid overflowing the array. 2987bf215546Sopenharmony_ci * 2988bf215546Sopenharmony_ci * At most one variable per fragment output component should 2989bf215546Sopenharmony_ci * reach this. 2990bf215546Sopenharmony_ci */ 2991bf215546Sopenharmony_ci assert(assigned_attr < ARRAY_SIZE(assigned)); 2992bf215546Sopenharmony_ci assigned[assigned_attr] = var; 2993bf215546Sopenharmony_ci assigned_attr++; 2994bf215546Sopenharmony_ci } 2995bf215546Sopenharmony_ci 2996bf215546Sopenharmony_ci used_locations |= (use_mask << attr); 2997bf215546Sopenharmony_ci 2998bf215546Sopenharmony_ci /* From the GL 4.5 core spec, section 11.1.1 (Vertex Attributes): 2999bf215546Sopenharmony_ci * 3000bf215546Sopenharmony_ci * "A program with more than the value of MAX_VERTEX_ATTRIBS 3001bf215546Sopenharmony_ci * active attribute variables may fail to link, unless 3002bf215546Sopenharmony_ci * device-dependent optimizations are able to make the program 3003bf215546Sopenharmony_ci * fit within available hardware resources. For the purposes 3004bf215546Sopenharmony_ci * of this test, attribute variables of the type dvec3, dvec4, 3005bf215546Sopenharmony_ci * dmat2x3, dmat2x4, dmat3, dmat3x4, dmat4x3, and dmat4 may 3006bf215546Sopenharmony_ci * count as consuming twice as many attributes as equivalent 3007bf215546Sopenharmony_ci * single-precision types. While these types use the same number 3008bf215546Sopenharmony_ci * of generic attributes as their single-precision equivalents, 3009bf215546Sopenharmony_ci * implementations are permitted to consume two single-precision 3010bf215546Sopenharmony_ci * vectors of internal storage for each three- or four-component 3011bf215546Sopenharmony_ci * double-precision vector." 3012bf215546Sopenharmony_ci * 3013bf215546Sopenharmony_ci * Mark this attribute slot as taking up twice as much space 3014bf215546Sopenharmony_ci * so we can count it properly against limits. According to 3015bf215546Sopenharmony_ci * issue (3) of the GL_ARB_vertex_attrib_64bit behavior, this 3016bf215546Sopenharmony_ci * is optional behavior, but it seems preferable. 3017bf215546Sopenharmony_ci */ 3018bf215546Sopenharmony_ci if (var->type->without_array()->is_dual_slot()) 3019bf215546Sopenharmony_ci double_storage_locations |= (use_mask << attr); 3020bf215546Sopenharmony_ci } 3021bf215546Sopenharmony_ci 3022bf215546Sopenharmony_ci continue; 3023bf215546Sopenharmony_ci } 3024bf215546Sopenharmony_ci 3025bf215546Sopenharmony_ci if (num_attr >= max_index) { 3026bf215546Sopenharmony_ci linker_error(prog, "too many %s (max %u)", 3027bf215546Sopenharmony_ci target_index == MESA_SHADER_VERTEX ? 3028bf215546Sopenharmony_ci "vertex shader inputs" : "fragment shader outputs", 3029bf215546Sopenharmony_ci max_index); 3030bf215546Sopenharmony_ci return false; 3031bf215546Sopenharmony_ci } 3032bf215546Sopenharmony_ci to_assign[num_attr].slots = slots; 3033bf215546Sopenharmony_ci to_assign[num_attr].var = var; 3034bf215546Sopenharmony_ci num_attr++; 3035bf215546Sopenharmony_ci } 3036bf215546Sopenharmony_ci 3037bf215546Sopenharmony_ci if (!do_assignment) 3038bf215546Sopenharmony_ci return true; 3039bf215546Sopenharmony_ci 3040bf215546Sopenharmony_ci if (target_index == MESA_SHADER_VERTEX) { 3041bf215546Sopenharmony_ci unsigned total_attribs_size = 3042bf215546Sopenharmony_ci util_bitcount(used_locations & SAFE_MASK_FROM_INDEX(max_index)) + 3043bf215546Sopenharmony_ci util_bitcount(double_storage_locations); 3044bf215546Sopenharmony_ci if (total_attribs_size > max_index) { 3045bf215546Sopenharmony_ci linker_error(prog, 3046bf215546Sopenharmony_ci "attempt to use %d vertex attribute slots only %d available ", 3047bf215546Sopenharmony_ci total_attribs_size, max_index); 3048bf215546Sopenharmony_ci return false; 3049bf215546Sopenharmony_ci } 3050bf215546Sopenharmony_ci } 3051bf215546Sopenharmony_ci 3052bf215546Sopenharmony_ci /* If all of the attributes were assigned locations by the application (or 3053bf215546Sopenharmony_ci * are built-in attributes with fixed locations), return early. This should 3054bf215546Sopenharmony_ci * be the common case. 3055bf215546Sopenharmony_ci */ 3056bf215546Sopenharmony_ci if (num_attr == 0) 3057bf215546Sopenharmony_ci return true; 3058bf215546Sopenharmony_ci 3059bf215546Sopenharmony_ci qsort(to_assign, num_attr, sizeof(to_assign[0]), temp_attr::compare); 3060bf215546Sopenharmony_ci 3061bf215546Sopenharmony_ci if (target_index == MESA_SHADER_VERTEX) { 3062bf215546Sopenharmony_ci /* VERT_ATTRIB_GENERIC0 is a pseudo-alias for VERT_ATTRIB_POS. It can 3063bf215546Sopenharmony_ci * only be explicitly assigned by via glBindAttribLocation. Mark it as 3064bf215546Sopenharmony_ci * reserved to prevent it from being automatically allocated below. 3065bf215546Sopenharmony_ci */ 3066bf215546Sopenharmony_ci find_deref_visitor find("gl_Vertex"); 3067bf215546Sopenharmony_ci find.run(sh->ir); 3068bf215546Sopenharmony_ci if (find.variable_found()) 3069bf215546Sopenharmony_ci used_locations |= (1 << 0); 3070bf215546Sopenharmony_ci } 3071bf215546Sopenharmony_ci 3072bf215546Sopenharmony_ci for (unsigned i = 0; i < num_attr; i++) { 3073bf215546Sopenharmony_ci /* Mask representing the contiguous slots that will be used by this 3074bf215546Sopenharmony_ci * attribute. 3075bf215546Sopenharmony_ci */ 3076bf215546Sopenharmony_ci const unsigned use_mask = (1 << to_assign[i].slots) - 1; 3077bf215546Sopenharmony_ci 3078bf215546Sopenharmony_ci int location = find_available_slots(used_locations, to_assign[i].slots); 3079bf215546Sopenharmony_ci 3080bf215546Sopenharmony_ci if (location < 0) { 3081bf215546Sopenharmony_ci const char *const string = (target_index == MESA_SHADER_VERTEX) 3082bf215546Sopenharmony_ci ? "vertex shader input" : "fragment shader output"; 3083bf215546Sopenharmony_ci 3084bf215546Sopenharmony_ci linker_error(prog, 3085bf215546Sopenharmony_ci "insufficient contiguous locations " 3086bf215546Sopenharmony_ci "available for %s `%s'\n", 3087bf215546Sopenharmony_ci string, to_assign[i].var->name); 3088bf215546Sopenharmony_ci return false; 3089bf215546Sopenharmony_ci } 3090bf215546Sopenharmony_ci 3091bf215546Sopenharmony_ci to_assign[i].var->data.location = generic_base + location; 3092bf215546Sopenharmony_ci used_locations |= (use_mask << location); 3093bf215546Sopenharmony_ci 3094bf215546Sopenharmony_ci if (to_assign[i].var->type->without_array()->is_dual_slot()) 3095bf215546Sopenharmony_ci double_storage_locations |= (use_mask << location); 3096bf215546Sopenharmony_ci } 3097bf215546Sopenharmony_ci 3098bf215546Sopenharmony_ci /* Now that we have all the locations, from the GL 4.5 core spec, section 3099bf215546Sopenharmony_ci * 11.1.1 (Vertex Attributes), dvec3, dvec4, dmat2x3, dmat2x4, dmat3, 3100bf215546Sopenharmony_ci * dmat3x4, dmat4x3, and dmat4 count as consuming twice as many attributes 3101bf215546Sopenharmony_ci * as equivalent single-precision types. 3102bf215546Sopenharmony_ci */ 3103bf215546Sopenharmony_ci if (target_index == MESA_SHADER_VERTEX) { 3104bf215546Sopenharmony_ci unsigned total_attribs_size = 3105bf215546Sopenharmony_ci util_bitcount(used_locations & SAFE_MASK_FROM_INDEX(max_index)) + 3106bf215546Sopenharmony_ci util_bitcount(double_storage_locations); 3107bf215546Sopenharmony_ci if (total_attribs_size > max_index) { 3108bf215546Sopenharmony_ci linker_error(prog, 3109bf215546Sopenharmony_ci "attempt to use %d vertex attribute slots only %d available ", 3110bf215546Sopenharmony_ci total_attribs_size, max_index); 3111bf215546Sopenharmony_ci return false; 3112bf215546Sopenharmony_ci } 3113bf215546Sopenharmony_ci } 3114bf215546Sopenharmony_ci 3115bf215546Sopenharmony_ci return true; 3116bf215546Sopenharmony_ci} 3117bf215546Sopenharmony_ci 3118bf215546Sopenharmony_ci/** 3119bf215546Sopenharmony_ci * Store the gl_FragDepth layout in the gl_shader_program struct. 3120bf215546Sopenharmony_ci */ 3121bf215546Sopenharmony_cistatic void 3122bf215546Sopenharmony_cistore_fragdepth_layout(struct gl_shader_program *prog) 3123bf215546Sopenharmony_ci{ 3124bf215546Sopenharmony_ci if (prog->_LinkedShaders[MESA_SHADER_FRAGMENT] == NULL) { 3125bf215546Sopenharmony_ci return; 3126bf215546Sopenharmony_ci } 3127bf215546Sopenharmony_ci 3128bf215546Sopenharmony_ci struct exec_list *ir = prog->_LinkedShaders[MESA_SHADER_FRAGMENT]->ir; 3129bf215546Sopenharmony_ci 3130bf215546Sopenharmony_ci /* We don't look up the gl_FragDepth symbol directly because if 3131bf215546Sopenharmony_ci * gl_FragDepth is not used in the shader, it's removed from the IR. 3132bf215546Sopenharmony_ci * However, the symbol won't be removed from the symbol table. 3133bf215546Sopenharmony_ci * 3134bf215546Sopenharmony_ci * We're only interested in the cases where the variable is NOT removed 3135bf215546Sopenharmony_ci * from the IR. 3136bf215546Sopenharmony_ci */ 3137bf215546Sopenharmony_ci foreach_in_list(ir_instruction, node, ir) { 3138bf215546Sopenharmony_ci ir_variable *const var = node->as_variable(); 3139bf215546Sopenharmony_ci 3140bf215546Sopenharmony_ci if (var == NULL || var->data.mode != ir_var_shader_out) { 3141bf215546Sopenharmony_ci continue; 3142bf215546Sopenharmony_ci } 3143bf215546Sopenharmony_ci 3144bf215546Sopenharmony_ci if (strcmp(var->name, "gl_FragDepth") == 0) { 3145bf215546Sopenharmony_ci switch (var->data.depth_layout) { 3146bf215546Sopenharmony_ci case ir_depth_layout_none: 3147bf215546Sopenharmony_ci prog->FragDepthLayout = FRAG_DEPTH_LAYOUT_NONE; 3148bf215546Sopenharmony_ci return; 3149bf215546Sopenharmony_ci case ir_depth_layout_any: 3150bf215546Sopenharmony_ci prog->FragDepthLayout = FRAG_DEPTH_LAYOUT_ANY; 3151bf215546Sopenharmony_ci return; 3152bf215546Sopenharmony_ci case ir_depth_layout_greater: 3153bf215546Sopenharmony_ci prog->FragDepthLayout = FRAG_DEPTH_LAYOUT_GREATER; 3154bf215546Sopenharmony_ci return; 3155bf215546Sopenharmony_ci case ir_depth_layout_less: 3156bf215546Sopenharmony_ci prog->FragDepthLayout = FRAG_DEPTH_LAYOUT_LESS; 3157bf215546Sopenharmony_ci return; 3158bf215546Sopenharmony_ci case ir_depth_layout_unchanged: 3159bf215546Sopenharmony_ci prog->FragDepthLayout = FRAG_DEPTH_LAYOUT_UNCHANGED; 3160bf215546Sopenharmony_ci return; 3161bf215546Sopenharmony_ci default: 3162bf215546Sopenharmony_ci assert(0); 3163bf215546Sopenharmony_ci return; 3164bf215546Sopenharmony_ci } 3165bf215546Sopenharmony_ci } 3166bf215546Sopenharmony_ci } 3167bf215546Sopenharmony_ci} 3168bf215546Sopenharmony_ci 3169bf215546Sopenharmony_ci 3170bf215546Sopenharmony_ci/** 3171bf215546Sopenharmony_ci * Initializes explicit location slots to INACTIVE_UNIFORM_EXPLICIT_LOCATION 3172bf215546Sopenharmony_ci * for a variable, checks for overlaps between other uniforms using explicit 3173bf215546Sopenharmony_ci * locations. 3174bf215546Sopenharmony_ci */ 3175bf215546Sopenharmony_cistatic int 3176bf215546Sopenharmony_cireserve_explicit_locations(struct gl_shader_program *prog, 3177bf215546Sopenharmony_ci string_to_uint_map *map, ir_variable *var) 3178bf215546Sopenharmony_ci{ 3179bf215546Sopenharmony_ci unsigned slots = var->type->uniform_locations(); 3180bf215546Sopenharmony_ci unsigned max_loc = var->data.location + slots - 1; 3181bf215546Sopenharmony_ci unsigned return_value = slots; 3182bf215546Sopenharmony_ci 3183bf215546Sopenharmony_ci /* Resize remap table if locations do not fit in the current one. */ 3184bf215546Sopenharmony_ci if (max_loc + 1 > prog->NumUniformRemapTable) { 3185bf215546Sopenharmony_ci prog->UniformRemapTable = 3186bf215546Sopenharmony_ci reralloc(prog, prog->UniformRemapTable, 3187bf215546Sopenharmony_ci gl_uniform_storage *, 3188bf215546Sopenharmony_ci max_loc + 1); 3189bf215546Sopenharmony_ci 3190bf215546Sopenharmony_ci if (!prog->UniformRemapTable) { 3191bf215546Sopenharmony_ci linker_error(prog, "Out of memory during linking.\n"); 3192bf215546Sopenharmony_ci return -1; 3193bf215546Sopenharmony_ci } 3194bf215546Sopenharmony_ci 3195bf215546Sopenharmony_ci /* Initialize allocated space. */ 3196bf215546Sopenharmony_ci for (unsigned i = prog->NumUniformRemapTable; i < max_loc + 1; i++) 3197bf215546Sopenharmony_ci prog->UniformRemapTable[i] = NULL; 3198bf215546Sopenharmony_ci 3199bf215546Sopenharmony_ci prog->NumUniformRemapTable = max_loc + 1; 3200bf215546Sopenharmony_ci } 3201bf215546Sopenharmony_ci 3202bf215546Sopenharmony_ci for (unsigned i = 0; i < slots; i++) { 3203bf215546Sopenharmony_ci unsigned loc = var->data.location + i; 3204bf215546Sopenharmony_ci 3205bf215546Sopenharmony_ci /* Check if location is already used. */ 3206bf215546Sopenharmony_ci if (prog->UniformRemapTable[loc] == INACTIVE_UNIFORM_EXPLICIT_LOCATION) { 3207bf215546Sopenharmony_ci 3208bf215546Sopenharmony_ci /* Possibly same uniform from a different stage, this is ok. */ 3209bf215546Sopenharmony_ci unsigned hash_loc; 3210bf215546Sopenharmony_ci if (map->get(hash_loc, var->name) && hash_loc == loc - i) { 3211bf215546Sopenharmony_ci return_value = 0; 3212bf215546Sopenharmony_ci continue; 3213bf215546Sopenharmony_ci } 3214bf215546Sopenharmony_ci 3215bf215546Sopenharmony_ci /* ARB_explicit_uniform_location specification states: 3216bf215546Sopenharmony_ci * 3217bf215546Sopenharmony_ci * "No two default-block uniform variables in the program can have 3218bf215546Sopenharmony_ci * the same location, even if they are unused, otherwise a compiler 3219bf215546Sopenharmony_ci * or linker error will be generated." 3220bf215546Sopenharmony_ci */ 3221bf215546Sopenharmony_ci linker_error(prog, 3222bf215546Sopenharmony_ci "location qualifier for uniform %s overlaps " 3223bf215546Sopenharmony_ci "previously used location\n", 3224bf215546Sopenharmony_ci var->name); 3225bf215546Sopenharmony_ci return -1; 3226bf215546Sopenharmony_ci } 3227bf215546Sopenharmony_ci 3228bf215546Sopenharmony_ci /* Initialize location as inactive before optimization 3229bf215546Sopenharmony_ci * rounds and location assignment. 3230bf215546Sopenharmony_ci */ 3231bf215546Sopenharmony_ci prog->UniformRemapTable[loc] = INACTIVE_UNIFORM_EXPLICIT_LOCATION; 3232bf215546Sopenharmony_ci } 3233bf215546Sopenharmony_ci 3234bf215546Sopenharmony_ci /* Note, base location used for arrays. */ 3235bf215546Sopenharmony_ci map->put(var->data.location, var->name); 3236bf215546Sopenharmony_ci 3237bf215546Sopenharmony_ci return return_value; 3238bf215546Sopenharmony_ci} 3239bf215546Sopenharmony_ci 3240bf215546Sopenharmony_cistatic bool 3241bf215546Sopenharmony_cireserve_subroutine_explicit_locations(struct gl_shader_program *prog, 3242bf215546Sopenharmony_ci struct gl_program *p, 3243bf215546Sopenharmony_ci ir_variable *var) 3244bf215546Sopenharmony_ci{ 3245bf215546Sopenharmony_ci unsigned slots = var->type->uniform_locations(); 3246bf215546Sopenharmony_ci unsigned max_loc = var->data.location + slots - 1; 3247bf215546Sopenharmony_ci 3248bf215546Sopenharmony_ci /* Resize remap table if locations do not fit in the current one. */ 3249bf215546Sopenharmony_ci if (max_loc + 1 > p->sh.NumSubroutineUniformRemapTable) { 3250bf215546Sopenharmony_ci p->sh.SubroutineUniformRemapTable = 3251bf215546Sopenharmony_ci reralloc(p, p->sh.SubroutineUniformRemapTable, 3252bf215546Sopenharmony_ci gl_uniform_storage *, 3253bf215546Sopenharmony_ci max_loc + 1); 3254bf215546Sopenharmony_ci 3255bf215546Sopenharmony_ci if (!p->sh.SubroutineUniformRemapTable) { 3256bf215546Sopenharmony_ci linker_error(prog, "Out of memory during linking.\n"); 3257bf215546Sopenharmony_ci return false; 3258bf215546Sopenharmony_ci } 3259bf215546Sopenharmony_ci 3260bf215546Sopenharmony_ci /* Initialize allocated space. */ 3261bf215546Sopenharmony_ci for (unsigned i = p->sh.NumSubroutineUniformRemapTable; i < max_loc + 1; i++) 3262bf215546Sopenharmony_ci p->sh.SubroutineUniformRemapTable[i] = NULL; 3263bf215546Sopenharmony_ci 3264bf215546Sopenharmony_ci p->sh.NumSubroutineUniformRemapTable = max_loc + 1; 3265bf215546Sopenharmony_ci } 3266bf215546Sopenharmony_ci 3267bf215546Sopenharmony_ci for (unsigned i = 0; i < slots; i++) { 3268bf215546Sopenharmony_ci unsigned loc = var->data.location + i; 3269bf215546Sopenharmony_ci 3270bf215546Sopenharmony_ci /* Check if location is already used. */ 3271bf215546Sopenharmony_ci if (p->sh.SubroutineUniformRemapTable[loc] == INACTIVE_UNIFORM_EXPLICIT_LOCATION) { 3272bf215546Sopenharmony_ci 3273bf215546Sopenharmony_ci /* ARB_explicit_uniform_location specification states: 3274bf215546Sopenharmony_ci * "No two subroutine uniform variables can have the same location 3275bf215546Sopenharmony_ci * in the same shader stage, otherwise a compiler or linker error 3276bf215546Sopenharmony_ci * will be generated." 3277bf215546Sopenharmony_ci */ 3278bf215546Sopenharmony_ci linker_error(prog, 3279bf215546Sopenharmony_ci "location qualifier for uniform %s overlaps " 3280bf215546Sopenharmony_ci "previously used location\n", 3281bf215546Sopenharmony_ci var->name); 3282bf215546Sopenharmony_ci return false; 3283bf215546Sopenharmony_ci } 3284bf215546Sopenharmony_ci 3285bf215546Sopenharmony_ci /* Initialize location as inactive before optimization 3286bf215546Sopenharmony_ci * rounds and location assignment. 3287bf215546Sopenharmony_ci */ 3288bf215546Sopenharmony_ci p->sh.SubroutineUniformRemapTable[loc] = INACTIVE_UNIFORM_EXPLICIT_LOCATION; 3289bf215546Sopenharmony_ci } 3290bf215546Sopenharmony_ci 3291bf215546Sopenharmony_ci return true; 3292bf215546Sopenharmony_ci} 3293bf215546Sopenharmony_ci/** 3294bf215546Sopenharmony_ci * Check and reserve all explicit uniform locations, called before 3295bf215546Sopenharmony_ci * any optimizations happen to handle also inactive uniforms and 3296bf215546Sopenharmony_ci * inactive array elements that may get trimmed away. 3297bf215546Sopenharmony_ci */ 3298bf215546Sopenharmony_cistatic void 3299bf215546Sopenharmony_cicheck_explicit_uniform_locations(const struct gl_extensions *exts, 3300bf215546Sopenharmony_ci struct gl_shader_program *prog) 3301bf215546Sopenharmony_ci{ 3302bf215546Sopenharmony_ci prog->NumExplicitUniformLocations = 0; 3303bf215546Sopenharmony_ci 3304bf215546Sopenharmony_ci if (!exts->ARB_explicit_uniform_location) 3305bf215546Sopenharmony_ci return; 3306bf215546Sopenharmony_ci 3307bf215546Sopenharmony_ci /* This map is used to detect if overlapping explicit locations 3308bf215546Sopenharmony_ci * occur with the same uniform (from different stage) or a different one. 3309bf215546Sopenharmony_ci */ 3310bf215546Sopenharmony_ci string_to_uint_map *uniform_map = new string_to_uint_map; 3311bf215546Sopenharmony_ci 3312bf215546Sopenharmony_ci if (!uniform_map) { 3313bf215546Sopenharmony_ci linker_error(prog, "Out of memory during linking.\n"); 3314bf215546Sopenharmony_ci return; 3315bf215546Sopenharmony_ci } 3316bf215546Sopenharmony_ci 3317bf215546Sopenharmony_ci unsigned entries_total = 0; 3318bf215546Sopenharmony_ci unsigned mask = prog->data->linked_stages; 3319bf215546Sopenharmony_ci while (mask) { 3320bf215546Sopenharmony_ci const int i = u_bit_scan(&mask); 3321bf215546Sopenharmony_ci struct gl_program *p = prog->_LinkedShaders[i]->Program; 3322bf215546Sopenharmony_ci 3323bf215546Sopenharmony_ci foreach_in_list(ir_instruction, node, prog->_LinkedShaders[i]->ir) { 3324bf215546Sopenharmony_ci ir_variable *var = node->as_variable(); 3325bf215546Sopenharmony_ci if (!var || var->data.mode != ir_var_uniform) 3326bf215546Sopenharmony_ci continue; 3327bf215546Sopenharmony_ci 3328bf215546Sopenharmony_ci if (var->data.explicit_location) { 3329bf215546Sopenharmony_ci bool ret = false; 3330bf215546Sopenharmony_ci if (var->type->without_array()->is_subroutine()) 3331bf215546Sopenharmony_ci ret = reserve_subroutine_explicit_locations(prog, p, var); 3332bf215546Sopenharmony_ci else { 3333bf215546Sopenharmony_ci int slots = reserve_explicit_locations(prog, uniform_map, 3334bf215546Sopenharmony_ci var); 3335bf215546Sopenharmony_ci if (slots != -1) { 3336bf215546Sopenharmony_ci ret = true; 3337bf215546Sopenharmony_ci entries_total += slots; 3338bf215546Sopenharmony_ci } 3339bf215546Sopenharmony_ci } 3340bf215546Sopenharmony_ci if (!ret) { 3341bf215546Sopenharmony_ci delete uniform_map; 3342bf215546Sopenharmony_ci return; 3343bf215546Sopenharmony_ci } 3344bf215546Sopenharmony_ci } 3345bf215546Sopenharmony_ci } 3346bf215546Sopenharmony_ci } 3347bf215546Sopenharmony_ci 3348bf215546Sopenharmony_ci link_util_update_empty_uniform_locations(prog); 3349bf215546Sopenharmony_ci 3350bf215546Sopenharmony_ci delete uniform_map; 3351bf215546Sopenharmony_ci prog->NumExplicitUniformLocations = entries_total; 3352bf215546Sopenharmony_ci} 3353bf215546Sopenharmony_ci 3354bf215546Sopenharmony_cistatic void 3355bf215546Sopenharmony_cilink_assign_subroutine_types(struct gl_shader_program *prog) 3356bf215546Sopenharmony_ci{ 3357bf215546Sopenharmony_ci unsigned mask = prog->data->linked_stages; 3358bf215546Sopenharmony_ci while (mask) { 3359bf215546Sopenharmony_ci const int i = u_bit_scan(&mask); 3360bf215546Sopenharmony_ci gl_program *p = prog->_LinkedShaders[i]->Program; 3361bf215546Sopenharmony_ci 3362bf215546Sopenharmony_ci p->sh.MaxSubroutineFunctionIndex = 0; 3363bf215546Sopenharmony_ci foreach_in_list(ir_instruction, node, prog->_LinkedShaders[i]->ir) { 3364bf215546Sopenharmony_ci ir_function *fn = node->as_function(); 3365bf215546Sopenharmony_ci if (!fn) 3366bf215546Sopenharmony_ci continue; 3367bf215546Sopenharmony_ci 3368bf215546Sopenharmony_ci if (fn->is_subroutine) 3369bf215546Sopenharmony_ci p->sh.NumSubroutineUniformTypes++; 3370bf215546Sopenharmony_ci 3371bf215546Sopenharmony_ci if (!fn->num_subroutine_types) 3372bf215546Sopenharmony_ci continue; 3373bf215546Sopenharmony_ci 3374bf215546Sopenharmony_ci /* these should have been calculated earlier. */ 3375bf215546Sopenharmony_ci assert(fn->subroutine_index != -1); 3376bf215546Sopenharmony_ci if (p->sh.NumSubroutineFunctions + 1 > MAX_SUBROUTINES) { 3377bf215546Sopenharmony_ci linker_error(prog, "Too many subroutine functions declared.\n"); 3378bf215546Sopenharmony_ci return; 3379bf215546Sopenharmony_ci } 3380bf215546Sopenharmony_ci p->sh.SubroutineFunctions = reralloc(p, p->sh.SubroutineFunctions, 3381bf215546Sopenharmony_ci struct gl_subroutine_function, 3382bf215546Sopenharmony_ci p->sh.NumSubroutineFunctions + 1); 3383bf215546Sopenharmony_ci p->sh.SubroutineFunctions[p->sh.NumSubroutineFunctions].name.string = ralloc_strdup(p, fn->name); 3384bf215546Sopenharmony_ci resource_name_updated(&p->sh.SubroutineFunctions[p->sh.NumSubroutineFunctions].name); 3385bf215546Sopenharmony_ci p->sh.SubroutineFunctions[p->sh.NumSubroutineFunctions].num_compat_types = fn->num_subroutine_types; 3386bf215546Sopenharmony_ci p->sh.SubroutineFunctions[p->sh.NumSubroutineFunctions].types = 3387bf215546Sopenharmony_ci ralloc_array(p, const struct glsl_type *, 3388bf215546Sopenharmony_ci fn->num_subroutine_types); 3389bf215546Sopenharmony_ci 3390bf215546Sopenharmony_ci /* From Section 4.4.4(Subroutine Function Layout Qualifiers) of the 3391bf215546Sopenharmony_ci * GLSL 4.5 spec: 3392bf215546Sopenharmony_ci * 3393bf215546Sopenharmony_ci * "Each subroutine with an index qualifier in the shader must be 3394bf215546Sopenharmony_ci * given a unique index, otherwise a compile or link error will be 3395bf215546Sopenharmony_ci * generated." 3396bf215546Sopenharmony_ci */ 3397bf215546Sopenharmony_ci for (unsigned j = 0; j < p->sh.NumSubroutineFunctions; j++) { 3398bf215546Sopenharmony_ci if (p->sh.SubroutineFunctions[j].index != -1 && 3399bf215546Sopenharmony_ci p->sh.SubroutineFunctions[j].index == fn->subroutine_index) { 3400bf215546Sopenharmony_ci linker_error(prog, "each subroutine index qualifier in the " 3401bf215546Sopenharmony_ci "shader must be unique\n"); 3402bf215546Sopenharmony_ci return; 3403bf215546Sopenharmony_ci } 3404bf215546Sopenharmony_ci } 3405bf215546Sopenharmony_ci p->sh.SubroutineFunctions[p->sh.NumSubroutineFunctions].index = 3406bf215546Sopenharmony_ci fn->subroutine_index; 3407bf215546Sopenharmony_ci 3408bf215546Sopenharmony_ci if (fn->subroutine_index > (int)p->sh.MaxSubroutineFunctionIndex) 3409bf215546Sopenharmony_ci p->sh.MaxSubroutineFunctionIndex = fn->subroutine_index; 3410bf215546Sopenharmony_ci 3411bf215546Sopenharmony_ci for (int j = 0; j < fn->num_subroutine_types; j++) 3412bf215546Sopenharmony_ci p->sh.SubroutineFunctions[p->sh.NumSubroutineFunctions].types[j] = fn->subroutine_types[j]; 3413bf215546Sopenharmony_ci p->sh.NumSubroutineFunctions++; 3414bf215546Sopenharmony_ci } 3415bf215546Sopenharmony_ci } 3416bf215546Sopenharmony_ci} 3417bf215546Sopenharmony_ci 3418bf215546Sopenharmony_cistatic void 3419bf215546Sopenharmony_civerify_subroutine_associated_funcs(struct gl_shader_program *prog) 3420bf215546Sopenharmony_ci{ 3421bf215546Sopenharmony_ci unsigned mask = prog->data->linked_stages; 3422bf215546Sopenharmony_ci while (mask) { 3423bf215546Sopenharmony_ci const int i = u_bit_scan(&mask); 3424bf215546Sopenharmony_ci gl_program *p = prog->_LinkedShaders[i]->Program; 3425bf215546Sopenharmony_ci glsl_symbol_table *symbols = prog->_LinkedShaders[i]->symbols; 3426bf215546Sopenharmony_ci 3427bf215546Sopenharmony_ci /* Section 6.1.2 (Subroutines) of the GLSL 4.00 spec says: 3428bf215546Sopenharmony_ci * 3429bf215546Sopenharmony_ci * "A program will fail to compile or link if any shader 3430bf215546Sopenharmony_ci * or stage contains two or more functions with the same 3431bf215546Sopenharmony_ci * name if the name is associated with a subroutine type." 3432bf215546Sopenharmony_ci */ 3433bf215546Sopenharmony_ci for (unsigned j = 0; j < p->sh.NumSubroutineFunctions; j++) { 3434bf215546Sopenharmony_ci unsigned definitions = 0; 3435bf215546Sopenharmony_ci char *name = p->sh.SubroutineFunctions[j].name.string; 3436bf215546Sopenharmony_ci ir_function *fn = symbols->get_function(name); 3437bf215546Sopenharmony_ci 3438bf215546Sopenharmony_ci /* Calculate number of function definitions with the same name */ 3439bf215546Sopenharmony_ci foreach_in_list(ir_function_signature, sig, &fn->signatures) { 3440bf215546Sopenharmony_ci if (sig->is_defined) { 3441bf215546Sopenharmony_ci if (++definitions > 1) { 3442bf215546Sopenharmony_ci linker_error(prog, "%s shader contains two or more function " 3443bf215546Sopenharmony_ci "definitions with name `%s', which is " 3444bf215546Sopenharmony_ci "associated with a subroutine type.\n", 3445bf215546Sopenharmony_ci _mesa_shader_stage_to_string(i), 3446bf215546Sopenharmony_ci fn->name); 3447bf215546Sopenharmony_ci return; 3448bf215546Sopenharmony_ci } 3449bf215546Sopenharmony_ci } 3450bf215546Sopenharmony_ci } 3451bf215546Sopenharmony_ci } 3452bf215546Sopenharmony_ci } 3453bf215546Sopenharmony_ci} 3454bf215546Sopenharmony_ci 3455bf215546Sopenharmony_ci 3456bf215546Sopenharmony_cistatic void 3457bf215546Sopenharmony_ciset_always_active_io(exec_list *ir, ir_variable_mode io_mode) 3458bf215546Sopenharmony_ci{ 3459bf215546Sopenharmony_ci assert(io_mode == ir_var_shader_in || io_mode == ir_var_shader_out); 3460bf215546Sopenharmony_ci 3461bf215546Sopenharmony_ci foreach_in_list(ir_instruction, node, ir) { 3462bf215546Sopenharmony_ci ir_variable *const var = node->as_variable(); 3463bf215546Sopenharmony_ci 3464bf215546Sopenharmony_ci if (var == NULL || var->data.mode != io_mode) 3465bf215546Sopenharmony_ci continue; 3466bf215546Sopenharmony_ci 3467bf215546Sopenharmony_ci /* Don't set always active on builtins that haven't been redeclared */ 3468bf215546Sopenharmony_ci if (var->data.how_declared == ir_var_declared_implicitly) 3469bf215546Sopenharmony_ci continue; 3470bf215546Sopenharmony_ci 3471bf215546Sopenharmony_ci var->data.always_active_io = true; 3472bf215546Sopenharmony_ci } 3473bf215546Sopenharmony_ci} 3474bf215546Sopenharmony_ci 3475bf215546Sopenharmony_ci/** 3476bf215546Sopenharmony_ci * When separate shader programs are enabled, only input/outputs between 3477bf215546Sopenharmony_ci * the stages of a multi-stage separate program can be safely removed 3478bf215546Sopenharmony_ci * from the shader interface. Other inputs/outputs must remain active. 3479bf215546Sopenharmony_ci */ 3480bf215546Sopenharmony_cistatic void 3481bf215546Sopenharmony_cidisable_varying_optimizations_for_sso(struct gl_shader_program *prog) 3482bf215546Sopenharmony_ci{ 3483bf215546Sopenharmony_ci unsigned first, last; 3484bf215546Sopenharmony_ci assert(prog->SeparateShader); 3485bf215546Sopenharmony_ci 3486bf215546Sopenharmony_ci first = MESA_SHADER_STAGES; 3487bf215546Sopenharmony_ci last = 0; 3488bf215546Sopenharmony_ci 3489bf215546Sopenharmony_ci /* Determine first and last stage. Excluding the compute stage */ 3490bf215546Sopenharmony_ci for (unsigned i = 0; i < MESA_SHADER_COMPUTE; i++) { 3491bf215546Sopenharmony_ci if (!prog->_LinkedShaders[i]) 3492bf215546Sopenharmony_ci continue; 3493bf215546Sopenharmony_ci if (first == MESA_SHADER_STAGES) 3494bf215546Sopenharmony_ci first = i; 3495bf215546Sopenharmony_ci last = i; 3496bf215546Sopenharmony_ci } 3497bf215546Sopenharmony_ci 3498bf215546Sopenharmony_ci if (first == MESA_SHADER_STAGES) 3499bf215546Sopenharmony_ci return; 3500bf215546Sopenharmony_ci 3501bf215546Sopenharmony_ci for (unsigned stage = 0; stage < MESA_SHADER_STAGES; stage++) { 3502bf215546Sopenharmony_ci gl_linked_shader *sh = prog->_LinkedShaders[stage]; 3503bf215546Sopenharmony_ci if (!sh) 3504bf215546Sopenharmony_ci continue; 3505bf215546Sopenharmony_ci 3506bf215546Sopenharmony_ci /* Prevent the removal of inputs to the first and outputs from the last 3507bf215546Sopenharmony_ci * stage, unless they are the initial pipeline inputs or final pipeline 3508bf215546Sopenharmony_ci * outputs, respectively. 3509bf215546Sopenharmony_ci * 3510bf215546Sopenharmony_ci * The removal of IO between shaders in the same program is always 3511bf215546Sopenharmony_ci * allowed. 3512bf215546Sopenharmony_ci */ 3513bf215546Sopenharmony_ci if (stage == first && stage != MESA_SHADER_VERTEX) 3514bf215546Sopenharmony_ci set_always_active_io(sh->ir, ir_var_shader_in); 3515bf215546Sopenharmony_ci if (stage == last && stage != MESA_SHADER_FRAGMENT) 3516bf215546Sopenharmony_ci set_always_active_io(sh->ir, ir_var_shader_out); 3517bf215546Sopenharmony_ci } 3518bf215546Sopenharmony_ci} 3519bf215546Sopenharmony_ci 3520bf215546Sopenharmony_cistatic bool 3521bf215546Sopenharmony_cilink_varyings(const struct gl_constants *consts, struct gl_shader_program *prog, 3522bf215546Sopenharmony_ci void *mem_ctx) 3523bf215546Sopenharmony_ci{ 3524bf215546Sopenharmony_ci /* Mark all generic shader inputs and outputs as unpaired. */ 3525bf215546Sopenharmony_ci for (unsigned i = MESA_SHADER_VERTEX; i <= MESA_SHADER_FRAGMENT; i++) { 3526bf215546Sopenharmony_ci if (prog->_LinkedShaders[i] != NULL) { 3527bf215546Sopenharmony_ci link_invalidate_variable_locations(prog->_LinkedShaders[i]->ir); 3528bf215546Sopenharmony_ci } 3529bf215546Sopenharmony_ci } 3530bf215546Sopenharmony_ci 3531bf215546Sopenharmony_ci if (!assign_attribute_or_color_locations(mem_ctx, prog, consts, 3532bf215546Sopenharmony_ci MESA_SHADER_VERTEX, true)) { 3533bf215546Sopenharmony_ci return false; 3534bf215546Sopenharmony_ci } 3535bf215546Sopenharmony_ci 3536bf215546Sopenharmony_ci if (!assign_attribute_or_color_locations(mem_ctx, prog, consts, 3537bf215546Sopenharmony_ci MESA_SHADER_FRAGMENT, true)) { 3538bf215546Sopenharmony_ci return false; 3539bf215546Sopenharmony_ci } 3540bf215546Sopenharmony_ci 3541bf215546Sopenharmony_ci prog->last_vert_prog = NULL; 3542bf215546Sopenharmony_ci for (int i = MESA_SHADER_GEOMETRY; i >= MESA_SHADER_VERTEX; i--) { 3543bf215546Sopenharmony_ci if (prog->_LinkedShaders[i] == NULL) 3544bf215546Sopenharmony_ci continue; 3545bf215546Sopenharmony_ci 3546bf215546Sopenharmony_ci prog->last_vert_prog = prog->_LinkedShaders[i]->Program; 3547bf215546Sopenharmony_ci break; 3548bf215546Sopenharmony_ci } 3549bf215546Sopenharmony_ci 3550bf215546Sopenharmony_ci for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 3551bf215546Sopenharmony_ci if (prog->_LinkedShaders[i] == NULL) 3552bf215546Sopenharmony_ci continue; 3553bf215546Sopenharmony_ci 3554bf215546Sopenharmony_ci lower_vector_derefs(prog->_LinkedShaders[i]); 3555bf215546Sopenharmony_ci do_vec_index_to_swizzle(prog->_LinkedShaders[i]->ir); 3556bf215546Sopenharmony_ci } 3557bf215546Sopenharmony_ci 3558bf215546Sopenharmony_ci return true; 3559bf215546Sopenharmony_ci} 3560bf215546Sopenharmony_ci 3561bf215546Sopenharmony_civoid 3562bf215546Sopenharmony_cilink_shaders(struct gl_context *ctx, struct gl_shader_program *prog) 3563bf215546Sopenharmony_ci{ 3564bf215546Sopenharmony_ci const struct gl_constants *consts = &ctx->Const; 3565bf215546Sopenharmony_ci prog->data->LinkStatus = LINKING_SUCCESS; /* All error paths will set this to false */ 3566bf215546Sopenharmony_ci prog->data->Validated = false; 3567bf215546Sopenharmony_ci 3568bf215546Sopenharmony_ci /* Section 7.3 (Program Objects) of the OpenGL 4.5 Core Profile spec says: 3569bf215546Sopenharmony_ci * 3570bf215546Sopenharmony_ci * "Linking can fail for a variety of reasons as specified in the 3571bf215546Sopenharmony_ci * OpenGL Shading Language Specification, as well as any of the 3572bf215546Sopenharmony_ci * following reasons: 3573bf215546Sopenharmony_ci * 3574bf215546Sopenharmony_ci * - No shader objects are attached to program." 3575bf215546Sopenharmony_ci * 3576bf215546Sopenharmony_ci * The Compatibility Profile specification does not list the error. In 3577bf215546Sopenharmony_ci * Compatibility Profile missing shader stages are replaced by 3578bf215546Sopenharmony_ci * fixed-function. This applies to the case where all stages are 3579bf215546Sopenharmony_ci * missing. 3580bf215546Sopenharmony_ci */ 3581bf215546Sopenharmony_ci if (prog->NumShaders == 0) { 3582bf215546Sopenharmony_ci if (ctx->API != API_OPENGL_COMPAT) 3583bf215546Sopenharmony_ci linker_error(prog, "no shaders attached to the program\n"); 3584bf215546Sopenharmony_ci return; 3585bf215546Sopenharmony_ci } 3586bf215546Sopenharmony_ci 3587bf215546Sopenharmony_ci#ifdef ENABLE_SHADER_CACHE 3588bf215546Sopenharmony_ci if (shader_cache_read_program_metadata(ctx, prog)) 3589bf215546Sopenharmony_ci return; 3590bf215546Sopenharmony_ci#endif 3591bf215546Sopenharmony_ci 3592bf215546Sopenharmony_ci void *mem_ctx = ralloc_context(NULL); // temporary linker context 3593bf215546Sopenharmony_ci 3594bf215546Sopenharmony_ci prog->ARB_fragment_coord_conventions_enable = false; 3595bf215546Sopenharmony_ci 3596bf215546Sopenharmony_ci /* Separate the shaders into groups based on their type. 3597bf215546Sopenharmony_ci */ 3598bf215546Sopenharmony_ci struct gl_shader **shader_list[MESA_SHADER_STAGES]; 3599bf215546Sopenharmony_ci unsigned num_shaders[MESA_SHADER_STAGES]; 3600bf215546Sopenharmony_ci 3601bf215546Sopenharmony_ci for (int i = 0; i < MESA_SHADER_STAGES; i++) { 3602bf215546Sopenharmony_ci shader_list[i] = (struct gl_shader **) 3603bf215546Sopenharmony_ci calloc(prog->NumShaders, sizeof(struct gl_shader *)); 3604bf215546Sopenharmony_ci num_shaders[i] = 0; 3605bf215546Sopenharmony_ci } 3606bf215546Sopenharmony_ci 3607bf215546Sopenharmony_ci unsigned min_version = UINT_MAX; 3608bf215546Sopenharmony_ci unsigned max_version = 0; 3609bf215546Sopenharmony_ci for (unsigned i = 0; i < prog->NumShaders; i++) { 3610bf215546Sopenharmony_ci min_version = MIN2(min_version, prog->Shaders[i]->Version); 3611bf215546Sopenharmony_ci max_version = MAX2(max_version, prog->Shaders[i]->Version); 3612bf215546Sopenharmony_ci 3613bf215546Sopenharmony_ci if (!consts->AllowGLSLRelaxedES && 3614bf215546Sopenharmony_ci prog->Shaders[i]->IsES != prog->Shaders[0]->IsES) { 3615bf215546Sopenharmony_ci linker_error(prog, "all shaders must use same shading " 3616bf215546Sopenharmony_ci "language version\n"); 3617bf215546Sopenharmony_ci goto done; 3618bf215546Sopenharmony_ci } 3619bf215546Sopenharmony_ci 3620bf215546Sopenharmony_ci if (prog->Shaders[i]->ARB_fragment_coord_conventions_enable) { 3621bf215546Sopenharmony_ci prog->ARB_fragment_coord_conventions_enable = true; 3622bf215546Sopenharmony_ci } 3623bf215546Sopenharmony_ci 3624bf215546Sopenharmony_ci gl_shader_stage shader_type = prog->Shaders[i]->Stage; 3625bf215546Sopenharmony_ci shader_list[shader_type][num_shaders[shader_type]] = prog->Shaders[i]; 3626bf215546Sopenharmony_ci num_shaders[shader_type]++; 3627bf215546Sopenharmony_ci } 3628bf215546Sopenharmony_ci 3629bf215546Sopenharmony_ci /* In desktop GLSL, different shader versions may be linked together. In 3630bf215546Sopenharmony_ci * GLSL ES, all shader versions must be the same. 3631bf215546Sopenharmony_ci */ 3632bf215546Sopenharmony_ci if (!consts->AllowGLSLRelaxedES && prog->Shaders[0]->IsES && 3633bf215546Sopenharmony_ci min_version != max_version) { 3634bf215546Sopenharmony_ci linker_error(prog, "all shaders must use same shading " 3635bf215546Sopenharmony_ci "language version\n"); 3636bf215546Sopenharmony_ci goto done; 3637bf215546Sopenharmony_ci } 3638bf215546Sopenharmony_ci 3639bf215546Sopenharmony_ci prog->data->Version = max_version; 3640bf215546Sopenharmony_ci prog->IsES = prog->Shaders[0]->IsES; 3641bf215546Sopenharmony_ci 3642bf215546Sopenharmony_ci /* Some shaders have to be linked with some other shaders present. 3643bf215546Sopenharmony_ci */ 3644bf215546Sopenharmony_ci if (!prog->SeparateShader) { 3645bf215546Sopenharmony_ci if (num_shaders[MESA_SHADER_GEOMETRY] > 0 && 3646bf215546Sopenharmony_ci num_shaders[MESA_SHADER_VERTEX] == 0) { 3647bf215546Sopenharmony_ci linker_error(prog, "Geometry shader must be linked with " 3648bf215546Sopenharmony_ci "vertex shader\n"); 3649bf215546Sopenharmony_ci goto done; 3650bf215546Sopenharmony_ci } 3651bf215546Sopenharmony_ci if (num_shaders[MESA_SHADER_TESS_EVAL] > 0 && 3652bf215546Sopenharmony_ci num_shaders[MESA_SHADER_VERTEX] == 0) { 3653bf215546Sopenharmony_ci linker_error(prog, "Tessellation evaluation shader must be linked " 3654bf215546Sopenharmony_ci "with vertex shader\n"); 3655bf215546Sopenharmony_ci goto done; 3656bf215546Sopenharmony_ci } 3657bf215546Sopenharmony_ci if (num_shaders[MESA_SHADER_TESS_CTRL] > 0 && 3658bf215546Sopenharmony_ci num_shaders[MESA_SHADER_VERTEX] == 0) { 3659bf215546Sopenharmony_ci linker_error(prog, "Tessellation control shader must be linked with " 3660bf215546Sopenharmony_ci "vertex shader\n"); 3661bf215546Sopenharmony_ci goto done; 3662bf215546Sopenharmony_ci } 3663bf215546Sopenharmony_ci 3664bf215546Sopenharmony_ci /* Section 7.3 of the OpenGL ES 3.2 specification says: 3665bf215546Sopenharmony_ci * 3666bf215546Sopenharmony_ci * "Linking can fail for [...] any of the following reasons: 3667bf215546Sopenharmony_ci * 3668bf215546Sopenharmony_ci * * program contains an object to form a tessellation control 3669bf215546Sopenharmony_ci * shader [...] and [...] the program is not separable and 3670bf215546Sopenharmony_ci * contains no object to form a tessellation evaluation shader" 3671bf215546Sopenharmony_ci * 3672bf215546Sopenharmony_ci * The OpenGL spec is contradictory. It allows linking without a tess 3673bf215546Sopenharmony_ci * eval shader, but that can only be used with transform feedback and 3674bf215546Sopenharmony_ci * rasterization disabled. However, transform feedback isn't allowed 3675bf215546Sopenharmony_ci * with GL_PATCHES, so it can't be used. 3676bf215546Sopenharmony_ci * 3677bf215546Sopenharmony_ci * More investigation showed that the idea of transform feedback after 3678bf215546Sopenharmony_ci * a tess control shader was dropped, because some hw vendors couldn't 3679bf215546Sopenharmony_ci * support tessellation without a tess eval shader, but the linker 3680bf215546Sopenharmony_ci * section wasn't updated to reflect that. 3681bf215546Sopenharmony_ci * 3682bf215546Sopenharmony_ci * All specifications (ARB_tessellation_shader, GL 4.0-4.5) have this 3683bf215546Sopenharmony_ci * spec bug. 3684bf215546Sopenharmony_ci * 3685bf215546Sopenharmony_ci * Do what's reasonable and always require a tess eval shader if a tess 3686bf215546Sopenharmony_ci * control shader is present. 3687bf215546Sopenharmony_ci */ 3688bf215546Sopenharmony_ci if (num_shaders[MESA_SHADER_TESS_CTRL] > 0 && 3689bf215546Sopenharmony_ci num_shaders[MESA_SHADER_TESS_EVAL] == 0) { 3690bf215546Sopenharmony_ci linker_error(prog, "Tessellation control shader must be linked with " 3691bf215546Sopenharmony_ci "tessellation evaluation shader\n"); 3692bf215546Sopenharmony_ci goto done; 3693bf215546Sopenharmony_ci } 3694bf215546Sopenharmony_ci 3695bf215546Sopenharmony_ci if (prog->IsES) { 3696bf215546Sopenharmony_ci if (num_shaders[MESA_SHADER_TESS_EVAL] > 0 && 3697bf215546Sopenharmony_ci num_shaders[MESA_SHADER_TESS_CTRL] == 0) { 3698bf215546Sopenharmony_ci linker_error(prog, "GLSL ES requires non-separable programs " 3699bf215546Sopenharmony_ci "containing a tessellation evaluation shader to also " 3700bf215546Sopenharmony_ci "be linked with a tessellation control shader\n"); 3701bf215546Sopenharmony_ci goto done; 3702bf215546Sopenharmony_ci } 3703bf215546Sopenharmony_ci } 3704bf215546Sopenharmony_ci } 3705bf215546Sopenharmony_ci 3706bf215546Sopenharmony_ci /* Compute shaders have additional restrictions. */ 3707bf215546Sopenharmony_ci if (num_shaders[MESA_SHADER_COMPUTE] > 0 && 3708bf215546Sopenharmony_ci num_shaders[MESA_SHADER_COMPUTE] != prog->NumShaders) { 3709bf215546Sopenharmony_ci linker_error(prog, "Compute shaders may not be linked with any other " 3710bf215546Sopenharmony_ci "type of shader\n"); 3711bf215546Sopenharmony_ci } 3712bf215546Sopenharmony_ci 3713bf215546Sopenharmony_ci /* Link all shaders for a particular stage and validate the result. 3714bf215546Sopenharmony_ci */ 3715bf215546Sopenharmony_ci for (int stage = 0; stage < MESA_SHADER_STAGES; stage++) { 3716bf215546Sopenharmony_ci if (num_shaders[stage] > 0) { 3717bf215546Sopenharmony_ci gl_linked_shader *const sh = 3718bf215546Sopenharmony_ci link_intrastage_shaders(mem_ctx, ctx, prog, shader_list[stage], 3719bf215546Sopenharmony_ci num_shaders[stage], false); 3720bf215546Sopenharmony_ci 3721bf215546Sopenharmony_ci if (!prog->data->LinkStatus) { 3722bf215546Sopenharmony_ci if (sh) 3723bf215546Sopenharmony_ci _mesa_delete_linked_shader(ctx, sh); 3724bf215546Sopenharmony_ci goto done; 3725bf215546Sopenharmony_ci } 3726bf215546Sopenharmony_ci 3727bf215546Sopenharmony_ci switch (stage) { 3728bf215546Sopenharmony_ci case MESA_SHADER_VERTEX: 3729bf215546Sopenharmony_ci validate_vertex_shader_executable(prog, sh, consts); 3730bf215546Sopenharmony_ci break; 3731bf215546Sopenharmony_ci case MESA_SHADER_TESS_CTRL: 3732bf215546Sopenharmony_ci /* nothing to be done */ 3733bf215546Sopenharmony_ci break; 3734bf215546Sopenharmony_ci case MESA_SHADER_TESS_EVAL: 3735bf215546Sopenharmony_ci validate_tess_eval_shader_executable(prog, sh, consts); 3736bf215546Sopenharmony_ci break; 3737bf215546Sopenharmony_ci case MESA_SHADER_GEOMETRY: 3738bf215546Sopenharmony_ci validate_geometry_shader_executable(prog, sh, consts); 3739bf215546Sopenharmony_ci break; 3740bf215546Sopenharmony_ci case MESA_SHADER_FRAGMENT: 3741bf215546Sopenharmony_ci validate_fragment_shader_executable(prog, sh); 3742bf215546Sopenharmony_ci break; 3743bf215546Sopenharmony_ci } 3744bf215546Sopenharmony_ci if (!prog->data->LinkStatus) { 3745bf215546Sopenharmony_ci if (sh) 3746bf215546Sopenharmony_ci _mesa_delete_linked_shader(ctx, sh); 3747bf215546Sopenharmony_ci goto done; 3748bf215546Sopenharmony_ci } 3749bf215546Sopenharmony_ci 3750bf215546Sopenharmony_ci prog->_LinkedShaders[stage] = sh; 3751bf215546Sopenharmony_ci prog->data->linked_stages |= 1 << stage; 3752bf215546Sopenharmony_ci } 3753bf215546Sopenharmony_ci } 3754bf215546Sopenharmony_ci 3755bf215546Sopenharmony_ci /* Here begins the inter-stage linking phase. Some initial validation is 3756bf215546Sopenharmony_ci * performed, then locations are assigned for uniforms, attributes, and 3757bf215546Sopenharmony_ci * varyings. 3758bf215546Sopenharmony_ci */ 3759bf215546Sopenharmony_ci cross_validate_uniforms(consts, prog); 3760bf215546Sopenharmony_ci if (!prog->data->LinkStatus) 3761bf215546Sopenharmony_ci goto done; 3762bf215546Sopenharmony_ci 3763bf215546Sopenharmony_ci unsigned first, last, prev; 3764bf215546Sopenharmony_ci 3765bf215546Sopenharmony_ci first = MESA_SHADER_STAGES; 3766bf215546Sopenharmony_ci last = 0; 3767bf215546Sopenharmony_ci 3768bf215546Sopenharmony_ci /* Determine first and last stage. */ 3769bf215546Sopenharmony_ci for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 3770bf215546Sopenharmony_ci if (!prog->_LinkedShaders[i]) 3771bf215546Sopenharmony_ci continue; 3772bf215546Sopenharmony_ci if (first == MESA_SHADER_STAGES) 3773bf215546Sopenharmony_ci first = i; 3774bf215546Sopenharmony_ci last = i; 3775bf215546Sopenharmony_ci } 3776bf215546Sopenharmony_ci 3777bf215546Sopenharmony_ci check_explicit_uniform_locations(&ctx->Extensions, prog); 3778bf215546Sopenharmony_ci link_assign_subroutine_types(prog); 3779bf215546Sopenharmony_ci verify_subroutine_associated_funcs(prog); 3780bf215546Sopenharmony_ci 3781bf215546Sopenharmony_ci if (!prog->data->LinkStatus) 3782bf215546Sopenharmony_ci goto done; 3783bf215546Sopenharmony_ci 3784bf215546Sopenharmony_ci resize_tes_inputs(consts, prog); 3785bf215546Sopenharmony_ci 3786bf215546Sopenharmony_ci /* Validate the inputs of each stage with the output of the preceding 3787bf215546Sopenharmony_ci * stage. 3788bf215546Sopenharmony_ci */ 3789bf215546Sopenharmony_ci prev = first; 3790bf215546Sopenharmony_ci for (unsigned i = prev + 1; i <= MESA_SHADER_FRAGMENT; i++) { 3791bf215546Sopenharmony_ci if (prog->_LinkedShaders[i] == NULL) 3792bf215546Sopenharmony_ci continue; 3793bf215546Sopenharmony_ci 3794bf215546Sopenharmony_ci validate_interstage_inout_blocks(prog, prog->_LinkedShaders[prev], 3795bf215546Sopenharmony_ci prog->_LinkedShaders[i]); 3796bf215546Sopenharmony_ci if (!prog->data->LinkStatus) 3797bf215546Sopenharmony_ci goto done; 3798bf215546Sopenharmony_ci 3799bf215546Sopenharmony_ci cross_validate_outputs_to_inputs(consts, prog, 3800bf215546Sopenharmony_ci prog->_LinkedShaders[prev], 3801bf215546Sopenharmony_ci prog->_LinkedShaders[i]); 3802bf215546Sopenharmony_ci if (!prog->data->LinkStatus) 3803bf215546Sopenharmony_ci goto done; 3804bf215546Sopenharmony_ci 3805bf215546Sopenharmony_ci prev = i; 3806bf215546Sopenharmony_ci } 3807bf215546Sopenharmony_ci 3808bf215546Sopenharmony_ci /* The cross validation of outputs/inputs above validates interstage 3809bf215546Sopenharmony_ci * explicit locations. We need to do this also for the inputs in the first 3810bf215546Sopenharmony_ci * stage and outputs of the last stage included in the program, since there 3811bf215546Sopenharmony_ci * is no cross validation for these. 3812bf215546Sopenharmony_ci */ 3813bf215546Sopenharmony_ci validate_first_and_last_interface_explicit_locations(consts, prog, 3814bf215546Sopenharmony_ci (gl_shader_stage) first, 3815bf215546Sopenharmony_ci (gl_shader_stage) last); 3816bf215546Sopenharmony_ci 3817bf215546Sopenharmony_ci /* Cross-validate uniform blocks between shader stages */ 3818bf215546Sopenharmony_ci validate_interstage_uniform_blocks(prog, prog->_LinkedShaders); 3819bf215546Sopenharmony_ci if (!prog->data->LinkStatus) 3820bf215546Sopenharmony_ci goto done; 3821bf215546Sopenharmony_ci 3822bf215546Sopenharmony_ci for (unsigned int i = 0; i < MESA_SHADER_STAGES; i++) { 3823bf215546Sopenharmony_ci if (prog->_LinkedShaders[i] != NULL) 3824bf215546Sopenharmony_ci lower_named_interface_blocks(mem_ctx, prog->_LinkedShaders[i]); 3825bf215546Sopenharmony_ci } 3826bf215546Sopenharmony_ci 3827bf215546Sopenharmony_ci if (prog->IsES && prog->data->Version == 100) 3828bf215546Sopenharmony_ci if (!validate_invariant_builtins(prog, 3829bf215546Sopenharmony_ci prog->_LinkedShaders[MESA_SHADER_VERTEX], 3830bf215546Sopenharmony_ci prog->_LinkedShaders[MESA_SHADER_FRAGMENT])) 3831bf215546Sopenharmony_ci goto done; 3832bf215546Sopenharmony_ci 3833bf215546Sopenharmony_ci /* Implement the GLSL 1.30+ rule for discard vs infinite loops Do 3834bf215546Sopenharmony_ci * it before optimization because we want most of the checks to get 3835bf215546Sopenharmony_ci * dropped thanks to constant propagation. 3836bf215546Sopenharmony_ci * 3837bf215546Sopenharmony_ci * This rule also applies to GLSL ES 3.00. 3838bf215546Sopenharmony_ci */ 3839bf215546Sopenharmony_ci if (max_version >= (prog->IsES ? 300 : 130)) { 3840bf215546Sopenharmony_ci struct gl_linked_shader *sh = prog->_LinkedShaders[MESA_SHADER_FRAGMENT]; 3841bf215546Sopenharmony_ci if (sh) { 3842bf215546Sopenharmony_ci lower_discard_flow(sh->ir); 3843bf215546Sopenharmony_ci } 3844bf215546Sopenharmony_ci } 3845bf215546Sopenharmony_ci 3846bf215546Sopenharmony_ci if (prog->SeparateShader) 3847bf215546Sopenharmony_ci disable_varying_optimizations_for_sso(prog); 3848bf215546Sopenharmony_ci 3849bf215546Sopenharmony_ci /* Process UBOs */ 3850bf215546Sopenharmony_ci if (!interstage_cross_validate_uniform_blocks(prog, false)) 3851bf215546Sopenharmony_ci goto done; 3852bf215546Sopenharmony_ci 3853bf215546Sopenharmony_ci /* Process SSBOs */ 3854bf215546Sopenharmony_ci if (!interstage_cross_validate_uniform_blocks(prog, true)) 3855bf215546Sopenharmony_ci goto done; 3856bf215546Sopenharmony_ci 3857bf215546Sopenharmony_ci /* Do common optimization before assigning storage for attributes, 3858bf215546Sopenharmony_ci * uniforms, and varyings. Later optimization could possibly make 3859bf215546Sopenharmony_ci * some of that unused. 3860bf215546Sopenharmony_ci */ 3861bf215546Sopenharmony_ci for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 3862bf215546Sopenharmony_ci if (prog->_LinkedShaders[i] == NULL) 3863bf215546Sopenharmony_ci continue; 3864bf215546Sopenharmony_ci 3865bf215546Sopenharmony_ci detect_recursion_linked(prog, prog->_LinkedShaders[i]->ir); 3866bf215546Sopenharmony_ci if (!prog->data->LinkStatus) 3867bf215546Sopenharmony_ci goto done; 3868bf215546Sopenharmony_ci 3869bf215546Sopenharmony_ci if (consts->ShaderCompilerOptions[i].LowerCombinedClipCullDistance) { 3870bf215546Sopenharmony_ci lower_clip_cull_distance(prog, prog->_LinkedShaders[i]); 3871bf215546Sopenharmony_ci } 3872bf215546Sopenharmony_ci 3873bf215546Sopenharmony_ci if (consts->LowerTessLevel) { 3874bf215546Sopenharmony_ci lower_tess_level(prog->_LinkedShaders[i]); 3875bf215546Sopenharmony_ci } 3876bf215546Sopenharmony_ci 3877bf215546Sopenharmony_ci /* Section 13.46 (Vertex Attribute Aliasing) of the OpenGL ES 3.2 3878bf215546Sopenharmony_ci * specification says: 3879bf215546Sopenharmony_ci * 3880bf215546Sopenharmony_ci * "In general, the behavior of GLSL ES should not depend on compiler 3881bf215546Sopenharmony_ci * optimizations which might be implementation-dependent. Name matching 3882bf215546Sopenharmony_ci * rules in most languages, including C++ from which GLSL ES is derived, 3883bf215546Sopenharmony_ci * are based on declarations rather than use. 3884bf215546Sopenharmony_ci * 3885bf215546Sopenharmony_ci * RESOLUTION: The existence of aliasing is determined by declarations 3886bf215546Sopenharmony_ci * present after preprocessing." 3887bf215546Sopenharmony_ci * 3888bf215546Sopenharmony_ci * Because of this rule, we do a 'dry-run' of attribute assignment for 3889bf215546Sopenharmony_ci * vertex shader inputs here. 3890bf215546Sopenharmony_ci */ 3891bf215546Sopenharmony_ci if (prog->IsES && i == MESA_SHADER_VERTEX) { 3892bf215546Sopenharmony_ci if (!assign_attribute_or_color_locations(mem_ctx, prog, consts, 3893bf215546Sopenharmony_ci MESA_SHADER_VERTEX, false)) { 3894bf215546Sopenharmony_ci goto done; 3895bf215546Sopenharmony_ci } 3896bf215546Sopenharmony_ci } 3897bf215546Sopenharmony_ci 3898bf215546Sopenharmony_ci /* Run it just once, since NIR will do the real optimizaiton. */ 3899bf215546Sopenharmony_ci do_common_optimization(prog->_LinkedShaders[i]->ir, true, 3900bf215546Sopenharmony_ci &consts->ShaderCompilerOptions[i], 3901bf215546Sopenharmony_ci consts->NativeIntegers); 3902bf215546Sopenharmony_ci } 3903bf215546Sopenharmony_ci 3904bf215546Sopenharmony_ci /* Check and validate stream emissions in geometry shaders */ 3905bf215546Sopenharmony_ci validate_geometry_shader_emissions(consts, prog); 3906bf215546Sopenharmony_ci 3907bf215546Sopenharmony_ci store_fragdepth_layout(prog); 3908bf215546Sopenharmony_ci 3909bf215546Sopenharmony_ci if(!link_varyings(consts, prog, mem_ctx)) 3910bf215546Sopenharmony_ci goto done; 3911bf215546Sopenharmony_ci 3912bf215546Sopenharmony_ci /* OpenGL ES < 3.1 requires that a vertex shader and a fragment shader both 3913bf215546Sopenharmony_ci * be present in a linked program. GL_ARB_ES2_compatibility doesn't say 3914bf215546Sopenharmony_ci * anything about shader linking when one of the shaders (vertex or 3915bf215546Sopenharmony_ci * fragment shader) is absent. So, the extension shouldn't change the 3916bf215546Sopenharmony_ci * behavior specified in GLSL specification. 3917bf215546Sopenharmony_ci * 3918bf215546Sopenharmony_ci * From OpenGL ES 3.1 specification (7.3 Program Objects): 3919bf215546Sopenharmony_ci * "Linking can fail for a variety of reasons as specified in the 3920bf215546Sopenharmony_ci * OpenGL ES Shading Language Specification, as well as any of the 3921bf215546Sopenharmony_ci * following reasons: 3922bf215546Sopenharmony_ci * 3923bf215546Sopenharmony_ci * ... 3924bf215546Sopenharmony_ci * 3925bf215546Sopenharmony_ci * * program contains objects to form either a vertex shader or 3926bf215546Sopenharmony_ci * fragment shader, and program is not separable, and does not 3927bf215546Sopenharmony_ci * contain objects to form both a vertex shader and fragment 3928bf215546Sopenharmony_ci * shader." 3929bf215546Sopenharmony_ci * 3930bf215546Sopenharmony_ci * However, the only scenario in 3.1+ where we don't require them both is 3931bf215546Sopenharmony_ci * when we have a compute shader. For example: 3932bf215546Sopenharmony_ci * 3933bf215546Sopenharmony_ci * - No shaders is a link error. 3934bf215546Sopenharmony_ci * - Geom or Tess without a Vertex shader is a link error which means we 3935bf215546Sopenharmony_ci * always require a Vertex shader and hence a Fragment shader. 3936bf215546Sopenharmony_ci * - Finally a Compute shader linked with any other stage is a link error. 3937bf215546Sopenharmony_ci */ 3938bf215546Sopenharmony_ci if (!prog->SeparateShader && ctx->API == API_OPENGLES2 && 3939bf215546Sopenharmony_ci num_shaders[MESA_SHADER_COMPUTE] == 0) { 3940bf215546Sopenharmony_ci if (prog->_LinkedShaders[MESA_SHADER_VERTEX] == NULL) { 3941bf215546Sopenharmony_ci linker_error(prog, "program lacks a vertex shader\n"); 3942bf215546Sopenharmony_ci } else if (prog->_LinkedShaders[MESA_SHADER_FRAGMENT] == NULL) { 3943bf215546Sopenharmony_ci linker_error(prog, "program lacks a fragment shader\n"); 3944bf215546Sopenharmony_ci } 3945bf215546Sopenharmony_ci } 3946bf215546Sopenharmony_ci 3947bf215546Sopenharmony_cidone: 3948bf215546Sopenharmony_ci for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { 3949bf215546Sopenharmony_ci free(shader_list[i]); 3950bf215546Sopenharmony_ci if (prog->_LinkedShaders[i] == NULL) 3951bf215546Sopenharmony_ci continue; 3952bf215546Sopenharmony_ci 3953bf215546Sopenharmony_ci /* Do a final validation step to make sure that the IR wasn't 3954bf215546Sopenharmony_ci * invalidated by any modifications performed after intrastage linking. 3955bf215546Sopenharmony_ci */ 3956bf215546Sopenharmony_ci validate_ir_tree(prog->_LinkedShaders[i]->ir); 3957bf215546Sopenharmony_ci 3958bf215546Sopenharmony_ci /* Retain any live IR, but trash the rest. */ 3959bf215546Sopenharmony_ci reparent_ir(prog->_LinkedShaders[i]->ir, prog->_LinkedShaders[i]->ir); 3960bf215546Sopenharmony_ci 3961bf215546Sopenharmony_ci /* The symbol table in the linked shaders may contain references to 3962bf215546Sopenharmony_ci * variables that were removed (e.g., unused uniforms). Since it may 3963bf215546Sopenharmony_ci * contain junk, there is no possible valid use. Delete it and set the 3964bf215546Sopenharmony_ci * pointer to NULL. 3965bf215546Sopenharmony_ci */ 3966bf215546Sopenharmony_ci delete prog->_LinkedShaders[i]->symbols; 3967bf215546Sopenharmony_ci prog->_LinkedShaders[i]->symbols = NULL; 3968bf215546Sopenharmony_ci } 3969bf215546Sopenharmony_ci 3970bf215546Sopenharmony_ci ralloc_free(mem_ctx); 3971bf215546Sopenharmony_ci} 3972bf215546Sopenharmony_ci 3973bf215546Sopenharmony_civoid 3974bf215546Sopenharmony_ciresource_name_updated(struct gl_resource_name *name) 3975bf215546Sopenharmony_ci{ 3976bf215546Sopenharmony_ci if (name->string) { 3977bf215546Sopenharmony_ci name->length = strlen(name->string); 3978bf215546Sopenharmony_ci 3979bf215546Sopenharmony_ci const char *last_square_bracket = strrchr(name->string, '['); 3980bf215546Sopenharmony_ci if (last_square_bracket) { 3981bf215546Sopenharmony_ci name->last_square_bracket = last_square_bracket - name->string; 3982bf215546Sopenharmony_ci name->suffix_is_zero_square_bracketed = 3983bf215546Sopenharmony_ci strcmp(last_square_bracket, "[0]") == 0; 3984bf215546Sopenharmony_ci } else { 3985bf215546Sopenharmony_ci name->last_square_bracket = -1; 3986bf215546Sopenharmony_ci name->suffix_is_zero_square_bracketed = false; 3987bf215546Sopenharmony_ci } 3988bf215546Sopenharmony_ci } else { 3989bf215546Sopenharmony_ci name->length = 0; 3990bf215546Sopenharmony_ci name->last_square_bracket = -1; 3991bf215546Sopenharmony_ci name->suffix_is_zero_square_bracketed = false; 3992bf215546Sopenharmony_ci } 3993bf215546Sopenharmony_ci} 3994