linker.cpp revision 7e102996
101e04c3fSmrg/*
201e04c3fSmrg * Copyright © 2010 Intel Corporation
301e04c3fSmrg *
401e04c3fSmrg * Permission is hereby granted, free of charge, to any person obtaining a
501e04c3fSmrg * copy of this software and associated documentation files (the "Software"),
601e04c3fSmrg * to deal in the Software without restriction, including without limitation
701e04c3fSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
801e04c3fSmrg * and/or sell copies of the Software, and to permit persons to whom the
901e04c3fSmrg * Software is furnished to do so, subject to the following conditions:
1001e04c3fSmrg *
1101e04c3fSmrg * The above copyright notice and this permission notice (including the next
1201e04c3fSmrg * paragraph) shall be included in all copies or substantial portions of the
1301e04c3fSmrg * Software.
1401e04c3fSmrg *
1501e04c3fSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1601e04c3fSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1701e04c3fSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1801e04c3fSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1901e04c3fSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2001e04c3fSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
2101e04c3fSmrg * DEALINGS IN THE SOFTWARE.
2201e04c3fSmrg */
2301e04c3fSmrg
2401e04c3fSmrg/**
2501e04c3fSmrg * \file linker.cpp
2601e04c3fSmrg * GLSL linker implementation
2701e04c3fSmrg *
2801e04c3fSmrg * Given a set of shaders that are to be linked to generate a final program,
2901e04c3fSmrg * there are three distinct stages.
3001e04c3fSmrg *
3101e04c3fSmrg * In the first stage shaders are partitioned into groups based on the shader
3201e04c3fSmrg * type.  All shaders of a particular type (e.g., vertex shaders) are linked
3301e04c3fSmrg * together.
3401e04c3fSmrg *
3501e04c3fSmrg *   - Undefined references in each shader are resolve to definitions in
3601e04c3fSmrg *     another shader.
3701e04c3fSmrg *   - Types and qualifiers of uniforms, outputs, and global variables defined
3801e04c3fSmrg *     in multiple shaders with the same name are verified to be the same.
3901e04c3fSmrg *   - Initializers for uniforms and global variables defined
4001e04c3fSmrg *     in multiple shaders with the same name are verified to be the same.
4101e04c3fSmrg *
4201e04c3fSmrg * The result, in the terminology of the GLSL spec, is a set of shader
4301e04c3fSmrg * executables for each processing unit.
4401e04c3fSmrg *
4501e04c3fSmrg * After the first stage is complete, a series of semantic checks are performed
4601e04c3fSmrg * on each of the shader executables.
4701e04c3fSmrg *
4801e04c3fSmrg *   - Each shader executable must define a \c main function.
4901e04c3fSmrg *   - Each vertex shader executable must write to \c gl_Position.
5001e04c3fSmrg *   - Each fragment shader executable must write to either \c gl_FragData or
5101e04c3fSmrg *     \c gl_FragColor.
5201e04c3fSmrg *
5301e04c3fSmrg * In the final stage individual shader executables are linked to create a
5401e04c3fSmrg * complete exectuable.
5501e04c3fSmrg *
5601e04c3fSmrg *   - Types of uniforms defined in multiple shader stages with the same name
5701e04c3fSmrg *     are verified to be the same.
5801e04c3fSmrg *   - Initializers for uniforms defined in multiple shader stages with the
5901e04c3fSmrg *     same name are verified to be the same.
6001e04c3fSmrg *   - Types and qualifiers of outputs defined in one stage are verified to
6101e04c3fSmrg *     be the same as the types and qualifiers of inputs defined with the same
6201e04c3fSmrg *     name in a later stage.
6301e04c3fSmrg *
6401e04c3fSmrg * \author Ian Romanick <ian.d.romanick@intel.com>
6501e04c3fSmrg */
6601e04c3fSmrg
6701e04c3fSmrg#include <ctype.h>
6801e04c3fSmrg#include "util/strndup.h"
6901e04c3fSmrg#include "glsl_symbol_table.h"
7001e04c3fSmrg#include "glsl_parser_extras.h"
7101e04c3fSmrg#include "ir.h"
7201e04c3fSmrg#include "program.h"
7301e04c3fSmrg#include "program/prog_instruction.h"
7401e04c3fSmrg#include "program/program.h"
7501e04c3fSmrg#include "util/mesa-sha1.h"
7601e04c3fSmrg#include "util/set.h"
7701e04c3fSmrg#include "string_to_uint_map.h"
7801e04c3fSmrg#include "linker.h"
7901e04c3fSmrg#include "linker_util.h"
8001e04c3fSmrg#include "link_varyings.h"
8101e04c3fSmrg#include "ir_optimization.h"
8201e04c3fSmrg#include "ir_rvalue_visitor.h"
8301e04c3fSmrg#include "ir_uniform.h"
8401e04c3fSmrg#include "builtin_functions.h"
8501e04c3fSmrg#include "shader_cache.h"
8601e04c3fSmrg#include "util/u_string.h"
8701e04c3fSmrg#include "util/u_math.h"
8801e04c3fSmrg
8901e04c3fSmrg#include "main/imports.h"
9001e04c3fSmrg#include "main/shaderobj.h"
9101e04c3fSmrg#include "main/enums.h"
9201e04c3fSmrg#include "main/mtypes.h"
9301e04c3fSmrg
9401e04c3fSmrg
9501e04c3fSmrgnamespace {
9601e04c3fSmrg
9701e04c3fSmrgstruct find_variable {
9801e04c3fSmrg   const char *name;
9901e04c3fSmrg   bool found;
10001e04c3fSmrg
10101e04c3fSmrg   find_variable(const char *name) : name(name), found(false) {}
10201e04c3fSmrg};
10301e04c3fSmrg
10401e04c3fSmrg/**
10501e04c3fSmrg * Visitor that determines whether or not a variable is ever written.
10601e04c3fSmrg *
10701e04c3fSmrg * Use \ref find_assignments for convenience.
10801e04c3fSmrg */
10901e04c3fSmrgclass find_assignment_visitor : public ir_hierarchical_visitor {
11001e04c3fSmrgpublic:
11101e04c3fSmrg   find_assignment_visitor(unsigned num_vars,
11201e04c3fSmrg                           find_variable * const *vars)
11301e04c3fSmrg      : num_variables(num_vars), num_found(0), variables(vars)
11401e04c3fSmrg   {
11501e04c3fSmrg   }
11601e04c3fSmrg
11701e04c3fSmrg   virtual ir_visitor_status visit_enter(ir_assignment *ir)
11801e04c3fSmrg   {
11901e04c3fSmrg      ir_variable *const var = ir->lhs->variable_referenced();
12001e04c3fSmrg
12101e04c3fSmrg      return check_variable_name(var->name);
12201e04c3fSmrg   }
12301e04c3fSmrg
12401e04c3fSmrg   virtual ir_visitor_status visit_enter(ir_call *ir)
12501e04c3fSmrg   {
12601e04c3fSmrg      foreach_two_lists(formal_node, &ir->callee->parameters,
12701e04c3fSmrg                        actual_node, &ir->actual_parameters) {
12801e04c3fSmrg         ir_rvalue *param_rval = (ir_rvalue *) actual_node;
12901e04c3fSmrg         ir_variable *sig_param = (ir_variable *) formal_node;
13001e04c3fSmrg
13101e04c3fSmrg         if (sig_param->data.mode == ir_var_function_out ||
13201e04c3fSmrg             sig_param->data.mode == ir_var_function_inout) {
13301e04c3fSmrg            ir_variable *var = param_rval->variable_referenced();
13401e04c3fSmrg            if (var && check_variable_name(var->name) == visit_stop)
13501e04c3fSmrg               return visit_stop;
13601e04c3fSmrg         }
13701e04c3fSmrg      }
13801e04c3fSmrg
13901e04c3fSmrg      if (ir->return_deref != NULL) {
14001e04c3fSmrg         ir_variable *const var = ir->return_deref->variable_referenced();
14101e04c3fSmrg
14201e04c3fSmrg         if (check_variable_name(var->name) == visit_stop)
14301e04c3fSmrg            return visit_stop;
14401e04c3fSmrg      }
14501e04c3fSmrg
14601e04c3fSmrg      return visit_continue_with_parent;
14701e04c3fSmrg   }
14801e04c3fSmrg
14901e04c3fSmrgprivate:
15001e04c3fSmrg   ir_visitor_status check_variable_name(const char *name)
15101e04c3fSmrg   {
15201e04c3fSmrg      for (unsigned i = 0; i < num_variables; ++i) {
15301e04c3fSmrg         if (strcmp(variables[i]->name, name) == 0) {
15401e04c3fSmrg            if (!variables[i]->found) {
15501e04c3fSmrg               variables[i]->found = true;
15601e04c3fSmrg
15701e04c3fSmrg               assert(num_found < num_variables);
15801e04c3fSmrg               if (++num_found == num_variables)
15901e04c3fSmrg                  return visit_stop;
16001e04c3fSmrg            }
16101e04c3fSmrg            break;
16201e04c3fSmrg         }
16301e04c3fSmrg      }
16401e04c3fSmrg
16501e04c3fSmrg      return visit_continue_with_parent;
16601e04c3fSmrg   }
16701e04c3fSmrg
16801e04c3fSmrgprivate:
16901e04c3fSmrg   unsigned num_variables;           /**< Number of variables to find */
17001e04c3fSmrg   unsigned num_found;               /**< Number of variables already found */
17101e04c3fSmrg   find_variable * const *variables; /**< Variables to find */
17201e04c3fSmrg};
17301e04c3fSmrg
17401e04c3fSmrg/**
17501e04c3fSmrg * Determine whether or not any of NULL-terminated list of variables is ever
17601e04c3fSmrg * written to.
17701e04c3fSmrg */
17801e04c3fSmrgstatic void
17901e04c3fSmrgfind_assignments(exec_list *ir, find_variable * const *vars)
18001e04c3fSmrg{
18101e04c3fSmrg   unsigned num_variables = 0;
18201e04c3fSmrg
18301e04c3fSmrg   for (find_variable * const *v = vars; *v; ++v)
18401e04c3fSmrg      num_variables++;
18501e04c3fSmrg
18601e04c3fSmrg   find_assignment_visitor visitor(num_variables, vars);
18701e04c3fSmrg   visitor.run(ir);
18801e04c3fSmrg}
18901e04c3fSmrg
19001e04c3fSmrg/**
19101e04c3fSmrg * Determine whether or not the given variable is ever written to.
19201e04c3fSmrg */
19301e04c3fSmrgstatic void
19401e04c3fSmrgfind_assignments(exec_list *ir, find_variable *var)
19501e04c3fSmrg{
19601e04c3fSmrg   find_assignment_visitor visitor(1, &var);
19701e04c3fSmrg   visitor.run(ir);
19801e04c3fSmrg}
19901e04c3fSmrg
20001e04c3fSmrg/**
20101e04c3fSmrg * Visitor that determines whether or not a variable is ever read.
20201e04c3fSmrg */
20301e04c3fSmrgclass find_deref_visitor : public ir_hierarchical_visitor {
20401e04c3fSmrgpublic:
20501e04c3fSmrg   find_deref_visitor(const char *name)
20601e04c3fSmrg      : name(name), found(false)
20701e04c3fSmrg   {
20801e04c3fSmrg      /* empty */
20901e04c3fSmrg   }
21001e04c3fSmrg
21101e04c3fSmrg   virtual ir_visitor_status visit(ir_dereference_variable *ir)
21201e04c3fSmrg   {
21301e04c3fSmrg      if (strcmp(this->name, ir->var->name) == 0) {
21401e04c3fSmrg         this->found = true;
21501e04c3fSmrg         return visit_stop;
21601e04c3fSmrg      }
21701e04c3fSmrg
21801e04c3fSmrg      return visit_continue;
21901e04c3fSmrg   }
22001e04c3fSmrg
22101e04c3fSmrg   bool variable_found() const
22201e04c3fSmrg   {
22301e04c3fSmrg      return this->found;
22401e04c3fSmrg   }
22501e04c3fSmrg
22601e04c3fSmrgprivate:
22701e04c3fSmrg   const char *name;       /**< Find writes to a variable with this name. */
22801e04c3fSmrg   bool found;             /**< Was a write to the variable found? */
22901e04c3fSmrg};
23001e04c3fSmrg
23101e04c3fSmrg
23201e04c3fSmrg/**
23301e04c3fSmrg * A visitor helper that provides methods for updating the types of
23401e04c3fSmrg * ir_dereferences.  Classes that update variable types (say, updating
23501e04c3fSmrg * array sizes) will want to use this so that dereference types stay in sync.
23601e04c3fSmrg */
23701e04c3fSmrgclass deref_type_updater : public ir_hierarchical_visitor {
23801e04c3fSmrgpublic:
23901e04c3fSmrg   virtual ir_visitor_status visit(ir_dereference_variable *ir)
24001e04c3fSmrg   {
24101e04c3fSmrg      ir->type = ir->var->type;
24201e04c3fSmrg      return visit_continue;
24301e04c3fSmrg   }
24401e04c3fSmrg
24501e04c3fSmrg   virtual ir_visitor_status visit_leave(ir_dereference_array *ir)
24601e04c3fSmrg   {
24701e04c3fSmrg      const glsl_type *const vt = ir->array->type;
24801e04c3fSmrg      if (vt->is_array())
24901e04c3fSmrg         ir->type = vt->fields.array;
25001e04c3fSmrg      return visit_continue;
25101e04c3fSmrg   }
25201e04c3fSmrg
25301e04c3fSmrg   virtual ir_visitor_status visit_leave(ir_dereference_record *ir)
25401e04c3fSmrg   {
25501e04c3fSmrg      ir->type = ir->record->type->fields.structure[ir->field_idx].type;
25601e04c3fSmrg      return visit_continue;
25701e04c3fSmrg   }
25801e04c3fSmrg};
25901e04c3fSmrg
26001e04c3fSmrg
26101e04c3fSmrgclass array_resize_visitor : public deref_type_updater {
26201e04c3fSmrgpublic:
26301e04c3fSmrg   unsigned num_vertices;
26401e04c3fSmrg   gl_shader_program *prog;
26501e04c3fSmrg   gl_shader_stage stage;
26601e04c3fSmrg
26701e04c3fSmrg   array_resize_visitor(unsigned num_vertices,
26801e04c3fSmrg                        gl_shader_program *prog,
26901e04c3fSmrg                        gl_shader_stage stage)
27001e04c3fSmrg   {
27101e04c3fSmrg      this->num_vertices = num_vertices;
27201e04c3fSmrg      this->prog = prog;
27301e04c3fSmrg      this->stage = stage;
27401e04c3fSmrg   }
27501e04c3fSmrg
27601e04c3fSmrg   virtual ~array_resize_visitor()
27701e04c3fSmrg   {
27801e04c3fSmrg      /* empty */
27901e04c3fSmrg   }
28001e04c3fSmrg
28101e04c3fSmrg   virtual ir_visitor_status visit(ir_variable *var)
28201e04c3fSmrg   {
28301e04c3fSmrg      if (!var->type->is_array() || var->data.mode != ir_var_shader_in ||
28401e04c3fSmrg          var->data.patch)
28501e04c3fSmrg         return visit_continue;
28601e04c3fSmrg
28701e04c3fSmrg      unsigned size = var->type->length;
28801e04c3fSmrg
28901e04c3fSmrg      if (stage == MESA_SHADER_GEOMETRY) {
29001e04c3fSmrg         /* Generate a link error if the shader has declared this array with
29101e04c3fSmrg          * an incorrect size.
29201e04c3fSmrg          */
29301e04c3fSmrg         if (!var->data.implicit_sized_array &&
29401e04c3fSmrg             size && size != this->num_vertices) {
29501e04c3fSmrg            linker_error(this->prog, "size of array %s declared as %u, "
29601e04c3fSmrg                         "but number of input vertices is %u\n",
29701e04c3fSmrg                         var->name, size, this->num_vertices);
29801e04c3fSmrg            return visit_continue;
29901e04c3fSmrg         }
30001e04c3fSmrg
30101e04c3fSmrg         /* Generate a link error if the shader attempts to access an input
30201e04c3fSmrg          * array using an index too large for its actual size assigned at
30301e04c3fSmrg          * link time.
30401e04c3fSmrg          */
30501e04c3fSmrg         if (var->data.max_array_access >= (int)this->num_vertices) {
30601e04c3fSmrg            linker_error(this->prog, "%s shader accesses element %i of "
30701e04c3fSmrg                         "%s, but only %i input vertices\n",
30801e04c3fSmrg                         _mesa_shader_stage_to_string(this->stage),
30901e04c3fSmrg                         var->data.max_array_access, var->name, this->num_vertices);
31001e04c3fSmrg            return visit_continue;
31101e04c3fSmrg         }
31201e04c3fSmrg      }
31301e04c3fSmrg
31401e04c3fSmrg      var->type = glsl_type::get_array_instance(var->type->fields.array,
31501e04c3fSmrg                                                this->num_vertices);
31601e04c3fSmrg      var->data.max_array_access = this->num_vertices - 1;
31701e04c3fSmrg
31801e04c3fSmrg      return visit_continue;
31901e04c3fSmrg   }
32001e04c3fSmrg};
32101e04c3fSmrg
32201e04c3fSmrg/**
32301e04c3fSmrg * Visitor that determines the highest stream id to which a (geometry) shader
32401e04c3fSmrg * emits vertices. It also checks whether End{Stream}Primitive is ever called.
32501e04c3fSmrg */
32601e04c3fSmrgclass find_emit_vertex_visitor : public ir_hierarchical_visitor {
32701e04c3fSmrgpublic:
32801e04c3fSmrg   find_emit_vertex_visitor(int max_allowed)
32901e04c3fSmrg      : max_stream_allowed(max_allowed),
33001e04c3fSmrg        invalid_stream_id(0),
33101e04c3fSmrg        invalid_stream_id_from_emit_vertex(false),
33201e04c3fSmrg        end_primitive_found(false),
33301e04c3fSmrg        uses_non_zero_stream(false)
33401e04c3fSmrg   {
33501e04c3fSmrg      /* empty */
33601e04c3fSmrg   }
33701e04c3fSmrg
33801e04c3fSmrg   virtual ir_visitor_status visit_leave(ir_emit_vertex *ir)
33901e04c3fSmrg   {
34001e04c3fSmrg      int stream_id = ir->stream_id();
34101e04c3fSmrg
34201e04c3fSmrg      if (stream_id < 0) {
34301e04c3fSmrg         invalid_stream_id = stream_id;
34401e04c3fSmrg         invalid_stream_id_from_emit_vertex = true;
34501e04c3fSmrg         return visit_stop;
34601e04c3fSmrg      }
34701e04c3fSmrg
34801e04c3fSmrg      if (stream_id > max_stream_allowed) {
34901e04c3fSmrg         invalid_stream_id = stream_id;
35001e04c3fSmrg         invalid_stream_id_from_emit_vertex = true;
35101e04c3fSmrg         return visit_stop;
35201e04c3fSmrg      }
35301e04c3fSmrg
35401e04c3fSmrg      if (stream_id != 0)
35501e04c3fSmrg         uses_non_zero_stream = true;
35601e04c3fSmrg
35701e04c3fSmrg      return visit_continue;
35801e04c3fSmrg   }
35901e04c3fSmrg
36001e04c3fSmrg   virtual ir_visitor_status visit_leave(ir_end_primitive *ir)
36101e04c3fSmrg   {
36201e04c3fSmrg      end_primitive_found = true;
36301e04c3fSmrg
36401e04c3fSmrg      int stream_id = ir->stream_id();
36501e04c3fSmrg
36601e04c3fSmrg      if (stream_id < 0) {
36701e04c3fSmrg         invalid_stream_id = stream_id;
36801e04c3fSmrg         invalid_stream_id_from_emit_vertex = false;
36901e04c3fSmrg         return visit_stop;
37001e04c3fSmrg      }
37101e04c3fSmrg
37201e04c3fSmrg      if (stream_id > max_stream_allowed) {
37301e04c3fSmrg         invalid_stream_id = stream_id;
37401e04c3fSmrg         invalid_stream_id_from_emit_vertex = false;
37501e04c3fSmrg         return visit_stop;
37601e04c3fSmrg      }
37701e04c3fSmrg
37801e04c3fSmrg      if (stream_id != 0)
37901e04c3fSmrg         uses_non_zero_stream = true;
38001e04c3fSmrg
38101e04c3fSmrg      return visit_continue;
38201e04c3fSmrg   }
38301e04c3fSmrg
38401e04c3fSmrg   bool error()
38501e04c3fSmrg   {
38601e04c3fSmrg      return invalid_stream_id != 0;
38701e04c3fSmrg   }
38801e04c3fSmrg
38901e04c3fSmrg   const char *error_func()
39001e04c3fSmrg   {
39101e04c3fSmrg      return invalid_stream_id_from_emit_vertex ?
39201e04c3fSmrg         "EmitStreamVertex" : "EndStreamPrimitive";
39301e04c3fSmrg   }
39401e04c3fSmrg
39501e04c3fSmrg   int error_stream()
39601e04c3fSmrg   {
39701e04c3fSmrg      return invalid_stream_id;
39801e04c3fSmrg   }
39901e04c3fSmrg
40001e04c3fSmrg   bool uses_streams()
40101e04c3fSmrg   {
40201e04c3fSmrg      return uses_non_zero_stream;
40301e04c3fSmrg   }
40401e04c3fSmrg
40501e04c3fSmrg   bool uses_end_primitive()
40601e04c3fSmrg   {
40701e04c3fSmrg      return end_primitive_found;
40801e04c3fSmrg   }
40901e04c3fSmrg
41001e04c3fSmrgprivate:
41101e04c3fSmrg   int max_stream_allowed;
41201e04c3fSmrg   int invalid_stream_id;
41301e04c3fSmrg   bool invalid_stream_id_from_emit_vertex;
41401e04c3fSmrg   bool end_primitive_found;
41501e04c3fSmrg   bool uses_non_zero_stream;
41601e04c3fSmrg};
41701e04c3fSmrg
41801e04c3fSmrg/* Class that finds array derefs and check if indexes are dynamic. */
41901e04c3fSmrgclass dynamic_sampler_array_indexing_visitor : public ir_hierarchical_visitor
42001e04c3fSmrg{
42101e04c3fSmrgpublic:
42201e04c3fSmrg   dynamic_sampler_array_indexing_visitor() :
42301e04c3fSmrg      dynamic_sampler_array_indexing(false)
42401e04c3fSmrg   {
42501e04c3fSmrg   }
42601e04c3fSmrg
42701e04c3fSmrg   ir_visitor_status visit_enter(ir_dereference_array *ir)
42801e04c3fSmrg   {
42901e04c3fSmrg      if (!ir->variable_referenced())
43001e04c3fSmrg         return visit_continue;
43101e04c3fSmrg
43201e04c3fSmrg      if (!ir->variable_referenced()->type->contains_sampler())
43301e04c3fSmrg         return visit_continue;
43401e04c3fSmrg
43501e04c3fSmrg      if (!ir->array_index->constant_expression_value(ralloc_parent(ir))) {
43601e04c3fSmrg         dynamic_sampler_array_indexing = true;
43701e04c3fSmrg         return visit_stop;
43801e04c3fSmrg      }
43901e04c3fSmrg      return visit_continue;
44001e04c3fSmrg   }
44101e04c3fSmrg
44201e04c3fSmrg   bool uses_dynamic_sampler_array_indexing()
44301e04c3fSmrg   {
44401e04c3fSmrg      return dynamic_sampler_array_indexing;
44501e04c3fSmrg   }
44601e04c3fSmrg
44701e04c3fSmrgprivate:
44801e04c3fSmrg   bool dynamic_sampler_array_indexing;
44901e04c3fSmrg};
45001e04c3fSmrg
45101e04c3fSmrg} /* anonymous namespace */
45201e04c3fSmrg
45301e04c3fSmrgvoid
45401e04c3fSmrglinker_error(gl_shader_program *prog, const char *fmt, ...)
45501e04c3fSmrg{
45601e04c3fSmrg   va_list ap;
45701e04c3fSmrg
45801e04c3fSmrg   ralloc_strcat(&prog->data->InfoLog, "error: ");
45901e04c3fSmrg   va_start(ap, fmt);
46001e04c3fSmrg   ralloc_vasprintf_append(&prog->data->InfoLog, fmt, ap);
46101e04c3fSmrg   va_end(ap);
46201e04c3fSmrg
46301e04c3fSmrg   prog->data->LinkStatus = LINKING_FAILURE;
46401e04c3fSmrg}
46501e04c3fSmrg
46601e04c3fSmrg
46701e04c3fSmrgvoid
46801e04c3fSmrglinker_warning(gl_shader_program *prog, const char *fmt, ...)
46901e04c3fSmrg{
47001e04c3fSmrg   va_list ap;
47101e04c3fSmrg
47201e04c3fSmrg   ralloc_strcat(&prog->data->InfoLog, "warning: ");
47301e04c3fSmrg   va_start(ap, fmt);
47401e04c3fSmrg   ralloc_vasprintf_append(&prog->data->InfoLog, fmt, ap);
47501e04c3fSmrg   va_end(ap);
47601e04c3fSmrg
47701e04c3fSmrg}
47801e04c3fSmrg
47901e04c3fSmrg
48001e04c3fSmrg/**
48101e04c3fSmrg * Given a string identifying a program resource, break it into a base name
48201e04c3fSmrg * and an optional array index in square brackets.
48301e04c3fSmrg *
48401e04c3fSmrg * If an array index is present, \c out_base_name_end is set to point to the
48501e04c3fSmrg * "[" that precedes the array index, and the array index itself is returned
48601e04c3fSmrg * as a long.
48701e04c3fSmrg *
48801e04c3fSmrg * If no array index is present (or if the array index is negative or
48901e04c3fSmrg * mal-formed), \c out_base_name_end, is set to point to the null terminator
49001e04c3fSmrg * at the end of the input string, and -1 is returned.
49101e04c3fSmrg *
49201e04c3fSmrg * Only the final array index is parsed; if the string contains other array
49301e04c3fSmrg * indices (or structure field accesses), they are left in the base name.
49401e04c3fSmrg *
49501e04c3fSmrg * No attempt is made to check that the base name is properly formed;
49601e04c3fSmrg * typically the caller will look up the base name in a hash table, so
49701e04c3fSmrg * ill-formed base names simply turn into hash table lookup failures.
49801e04c3fSmrg */
49901e04c3fSmrglong
50001e04c3fSmrgparse_program_resource_name(const GLchar *name,
50101e04c3fSmrg                            const GLchar **out_base_name_end)
50201e04c3fSmrg{
50301e04c3fSmrg   /* Section 7.3.1 ("Program Interfaces") of the OpenGL 4.3 spec says:
50401e04c3fSmrg    *
50501e04c3fSmrg    *     "When an integer array element or block instance number is part of
50601e04c3fSmrg    *     the name string, it will be specified in decimal form without a "+"
50701e04c3fSmrg    *     or "-" sign or any extra leading zeroes. Additionally, the name
50801e04c3fSmrg    *     string will not include white space anywhere in the string."
50901e04c3fSmrg    */
51001e04c3fSmrg
51101e04c3fSmrg   const size_t len = strlen(name);
51201e04c3fSmrg   *out_base_name_end = name + len;
51301e04c3fSmrg
51401e04c3fSmrg   if (len == 0 || name[len-1] != ']')
51501e04c3fSmrg      return -1;
51601e04c3fSmrg
51701e04c3fSmrg   /* Walk backwards over the string looking for a non-digit character.  This
51801e04c3fSmrg    * had better be the opening bracket for an array index.
51901e04c3fSmrg    *
52001e04c3fSmrg    * Initially, i specifies the location of the ']'.  Since the string may
52101e04c3fSmrg    * contain only the ']' charcater, walk backwards very carefully.
52201e04c3fSmrg    */
52301e04c3fSmrg   unsigned i;
52401e04c3fSmrg   for (i = len - 1; (i > 0) && isdigit(name[i-1]); --i)
52501e04c3fSmrg      /* empty */ ;
52601e04c3fSmrg
52701e04c3fSmrg   if ((i == 0) || name[i-1] != '[')
52801e04c3fSmrg      return -1;
52901e04c3fSmrg
53001e04c3fSmrg   long array_index = strtol(&name[i], NULL, 10);
53101e04c3fSmrg   if (array_index < 0)
53201e04c3fSmrg      return -1;
53301e04c3fSmrg
53401e04c3fSmrg   /* Check for leading zero */
53501e04c3fSmrg   if (name[i] == '0' && name[i+1] != ']')
53601e04c3fSmrg      return -1;
53701e04c3fSmrg
53801e04c3fSmrg   *out_base_name_end = name + (i - 1);
53901e04c3fSmrg   return array_index;
54001e04c3fSmrg}
54101e04c3fSmrg
54201e04c3fSmrg
54301e04c3fSmrgvoid
54401e04c3fSmrglink_invalidate_variable_locations(exec_list *ir)
54501e04c3fSmrg{
54601e04c3fSmrg   foreach_in_list(ir_instruction, node, ir) {
54701e04c3fSmrg      ir_variable *const var = node->as_variable();
54801e04c3fSmrg
54901e04c3fSmrg      if (var == NULL)
55001e04c3fSmrg         continue;
55101e04c3fSmrg
55201e04c3fSmrg      /* Only assign locations for variables that lack an explicit location.
55301e04c3fSmrg       * Explicit locations are set for all built-in variables, generic vertex
55401e04c3fSmrg       * shader inputs (via layout(location=...)), and generic fragment shader
55501e04c3fSmrg       * outputs (also via layout(location=...)).
55601e04c3fSmrg       */
55701e04c3fSmrg      if (!var->data.explicit_location) {
55801e04c3fSmrg         var->data.location = -1;
55901e04c3fSmrg         var->data.location_frac = 0;
56001e04c3fSmrg      }
56101e04c3fSmrg
56201e04c3fSmrg      /* ir_variable::is_unmatched_generic_inout is used by the linker while
56301e04c3fSmrg       * connecting outputs from one stage to inputs of the next stage.
56401e04c3fSmrg       */
56501e04c3fSmrg      if (var->data.explicit_location &&
56601e04c3fSmrg          var->data.location < VARYING_SLOT_VAR0) {
56701e04c3fSmrg         var->data.is_unmatched_generic_inout = 0;
56801e04c3fSmrg      } else {
56901e04c3fSmrg         var->data.is_unmatched_generic_inout = 1;
57001e04c3fSmrg      }
57101e04c3fSmrg   }
57201e04c3fSmrg}
57301e04c3fSmrg
57401e04c3fSmrg
57501e04c3fSmrg/**
57601e04c3fSmrg * Set clip_distance_array_size based and cull_distance_array_size on the given
57701e04c3fSmrg * shader.
57801e04c3fSmrg *
57901e04c3fSmrg * Also check for errors based on incorrect usage of gl_ClipVertex and
58001e04c3fSmrg * gl_ClipDistance and gl_CullDistance.
58101e04c3fSmrg * Additionally test whether the arrays gl_ClipDistance and gl_CullDistance
58201e04c3fSmrg * exceed the maximum size defined by gl_MaxCombinedClipAndCullDistances.
58301e04c3fSmrg *
58401e04c3fSmrg * Return false if an error was reported.
58501e04c3fSmrg */
58601e04c3fSmrgstatic void
58701e04c3fSmrganalyze_clip_cull_usage(struct gl_shader_program *prog,
58801e04c3fSmrg                        struct gl_linked_shader *shader,
58901e04c3fSmrg                        struct gl_context *ctx,
59001e04c3fSmrg                        GLuint *clip_distance_array_size,
59101e04c3fSmrg                        GLuint *cull_distance_array_size)
59201e04c3fSmrg{
59301e04c3fSmrg   *clip_distance_array_size = 0;
59401e04c3fSmrg   *cull_distance_array_size = 0;
59501e04c3fSmrg
59601e04c3fSmrg   if (prog->data->Version >= (prog->IsES ? 300 : 130)) {
59701e04c3fSmrg      /* From section 7.1 (Vertex Shader Special Variables) of the
59801e04c3fSmrg       * GLSL 1.30 spec:
59901e04c3fSmrg       *
60001e04c3fSmrg       *   "It is an error for a shader to statically write both
60101e04c3fSmrg       *   gl_ClipVertex and gl_ClipDistance."
60201e04c3fSmrg       *
60301e04c3fSmrg       * This does not apply to GLSL ES shaders, since GLSL ES defines neither
60401e04c3fSmrg       * gl_ClipVertex nor gl_ClipDistance. However with
60501e04c3fSmrg       * GL_EXT_clip_cull_distance, this functionality is exposed in ES 3.0.
60601e04c3fSmrg       */
60701e04c3fSmrg      find_variable gl_ClipDistance("gl_ClipDistance");
60801e04c3fSmrg      find_variable gl_CullDistance("gl_CullDistance");
60901e04c3fSmrg      find_variable gl_ClipVertex("gl_ClipVertex");
61001e04c3fSmrg      find_variable * const variables[] = {
61101e04c3fSmrg         &gl_ClipDistance,
61201e04c3fSmrg         &gl_CullDistance,
61301e04c3fSmrg         !prog->IsES ? &gl_ClipVertex : NULL,
61401e04c3fSmrg         NULL
61501e04c3fSmrg      };
61601e04c3fSmrg      find_assignments(shader->ir, variables);
61701e04c3fSmrg
61801e04c3fSmrg      /* From the ARB_cull_distance spec:
61901e04c3fSmrg       *
62001e04c3fSmrg       * It is a compile-time or link-time error for the set of shaders forming
62101e04c3fSmrg       * a program to statically read or write both gl_ClipVertex and either
62201e04c3fSmrg       * gl_ClipDistance or gl_CullDistance.
62301e04c3fSmrg       *
62401e04c3fSmrg       * This does not apply to GLSL ES shaders, since GLSL ES doesn't define
62501e04c3fSmrg       * gl_ClipVertex.
62601e04c3fSmrg       */
62701e04c3fSmrg      if (!prog->IsES) {
62801e04c3fSmrg         if (gl_ClipVertex.found && gl_ClipDistance.found) {
62901e04c3fSmrg            linker_error(prog, "%s shader writes to both `gl_ClipVertex' "
63001e04c3fSmrg                         "and `gl_ClipDistance'\n",
63101e04c3fSmrg                         _mesa_shader_stage_to_string(shader->Stage));
63201e04c3fSmrg            return;
63301e04c3fSmrg         }
63401e04c3fSmrg         if (gl_ClipVertex.found && gl_CullDistance.found) {
63501e04c3fSmrg            linker_error(prog, "%s shader writes to both `gl_ClipVertex' "
63601e04c3fSmrg                         "and `gl_CullDistance'\n",
63701e04c3fSmrg                         _mesa_shader_stage_to_string(shader->Stage));
63801e04c3fSmrg            return;
63901e04c3fSmrg         }
64001e04c3fSmrg      }
64101e04c3fSmrg
64201e04c3fSmrg      if (gl_ClipDistance.found) {
64301e04c3fSmrg         ir_variable *clip_distance_var =
64401e04c3fSmrg                shader->symbols->get_variable("gl_ClipDistance");
64501e04c3fSmrg         assert(clip_distance_var);
64601e04c3fSmrg         *clip_distance_array_size = clip_distance_var->type->length;
64701e04c3fSmrg      }
64801e04c3fSmrg      if (gl_CullDistance.found) {
64901e04c3fSmrg         ir_variable *cull_distance_var =
65001e04c3fSmrg                shader->symbols->get_variable("gl_CullDistance");
65101e04c3fSmrg         assert(cull_distance_var);
65201e04c3fSmrg         *cull_distance_array_size = cull_distance_var->type->length;
65301e04c3fSmrg      }
65401e04c3fSmrg      /* From the ARB_cull_distance spec:
65501e04c3fSmrg       *
65601e04c3fSmrg       * It is a compile-time or link-time error for the set of shaders forming
65701e04c3fSmrg       * a program to have the sum of the sizes of the gl_ClipDistance and
65801e04c3fSmrg       * gl_CullDistance arrays to be larger than
65901e04c3fSmrg       * gl_MaxCombinedClipAndCullDistances.
66001e04c3fSmrg       */
66101e04c3fSmrg      if ((*clip_distance_array_size + *cull_distance_array_size) >
66201e04c3fSmrg          ctx->Const.MaxClipPlanes) {
66301e04c3fSmrg          linker_error(prog, "%s shader: the combined size of "
66401e04c3fSmrg                       "'gl_ClipDistance' and 'gl_CullDistance' size cannot "
66501e04c3fSmrg                       "be larger than "
66601e04c3fSmrg                       "gl_MaxCombinedClipAndCullDistances (%u)",
66701e04c3fSmrg                       _mesa_shader_stage_to_string(shader->Stage),
66801e04c3fSmrg                       ctx->Const.MaxClipPlanes);
66901e04c3fSmrg      }
67001e04c3fSmrg   }
67101e04c3fSmrg}
67201e04c3fSmrg
67301e04c3fSmrg
67401e04c3fSmrg/**
67501e04c3fSmrg * Verify that a vertex shader executable meets all semantic requirements.
67601e04c3fSmrg *
67701e04c3fSmrg * Also sets info.clip_distance_array_size and
67801e04c3fSmrg * info.cull_distance_array_size as a side effect.
67901e04c3fSmrg *
68001e04c3fSmrg * \param shader  Vertex shader executable to be verified
68101e04c3fSmrg */
68201e04c3fSmrgstatic void
68301e04c3fSmrgvalidate_vertex_shader_executable(struct gl_shader_program *prog,
68401e04c3fSmrg                                  struct gl_linked_shader *shader,
68501e04c3fSmrg                                  struct gl_context *ctx)
68601e04c3fSmrg{
68701e04c3fSmrg   if (shader == NULL)
68801e04c3fSmrg      return;
68901e04c3fSmrg
69001e04c3fSmrg   /* From the GLSL 1.10 spec, page 48:
69101e04c3fSmrg    *
69201e04c3fSmrg    *     "The variable gl_Position is available only in the vertex
69301e04c3fSmrg    *      language and is intended for writing the homogeneous vertex
69401e04c3fSmrg    *      position. All executions of a well-formed vertex shader
69501e04c3fSmrg    *      executable must write a value into this variable. [...] The
69601e04c3fSmrg    *      variable gl_Position is available only in the vertex
69701e04c3fSmrg    *      language and is intended for writing the homogeneous vertex
69801e04c3fSmrg    *      position. All executions of a well-formed vertex shader
69901e04c3fSmrg    *      executable must write a value into this variable."
70001e04c3fSmrg    *
70101e04c3fSmrg    * while in GLSL 1.40 this text is changed to:
70201e04c3fSmrg    *
70301e04c3fSmrg    *     "The variable gl_Position is available only in the vertex
70401e04c3fSmrg    *      language and is intended for writing the homogeneous vertex
70501e04c3fSmrg    *      position. It can be written at any time during shader
70601e04c3fSmrg    *      execution. It may also be read back by a vertex shader
70701e04c3fSmrg    *      after being written. This value will be used by primitive
70801e04c3fSmrg    *      assembly, clipping, culling, and other fixed functionality
70901e04c3fSmrg    *      operations, if present, that operate on primitives after
71001e04c3fSmrg    *      vertex processing has occurred. Its value is undefined if
71101e04c3fSmrg    *      the vertex shader executable does not write gl_Position."
71201e04c3fSmrg    *
71301e04c3fSmrg    * All GLSL ES Versions are similar to GLSL 1.40--failing to write to
71401e04c3fSmrg    * gl_Position is not an error.
71501e04c3fSmrg    */
71601e04c3fSmrg   if (prog->data->Version < (prog->IsES ? 300 : 140)) {
71701e04c3fSmrg      find_variable gl_Position("gl_Position");
71801e04c3fSmrg      find_assignments(shader->ir, &gl_Position);
71901e04c3fSmrg      if (!gl_Position.found) {
72001e04c3fSmrg        if (prog->IsES) {
72101e04c3fSmrg          linker_warning(prog,
72201e04c3fSmrg                         "vertex shader does not write to `gl_Position'. "
72301e04c3fSmrg                         "Its value is undefined. \n");
72401e04c3fSmrg        } else {
72501e04c3fSmrg          linker_error(prog,
72601e04c3fSmrg                       "vertex shader does not write to `gl_Position'. \n");
72701e04c3fSmrg        }
72801e04c3fSmrg         return;
72901e04c3fSmrg      }
73001e04c3fSmrg   }
73101e04c3fSmrg
73201e04c3fSmrg   analyze_clip_cull_usage(prog, shader, ctx,
73301e04c3fSmrg                           &shader->Program->info.clip_distance_array_size,
73401e04c3fSmrg                           &shader->Program->info.cull_distance_array_size);
73501e04c3fSmrg}
73601e04c3fSmrg
73701e04c3fSmrgstatic void
73801e04c3fSmrgvalidate_tess_eval_shader_executable(struct gl_shader_program *prog,
73901e04c3fSmrg                                     struct gl_linked_shader *shader,
74001e04c3fSmrg                                     struct gl_context *ctx)
74101e04c3fSmrg{
74201e04c3fSmrg   if (shader == NULL)
74301e04c3fSmrg      return;
74401e04c3fSmrg
74501e04c3fSmrg   analyze_clip_cull_usage(prog, shader, ctx,
74601e04c3fSmrg                           &shader->Program->info.clip_distance_array_size,
74701e04c3fSmrg                           &shader->Program->info.cull_distance_array_size);
74801e04c3fSmrg}
74901e04c3fSmrg
75001e04c3fSmrg
75101e04c3fSmrg/**
75201e04c3fSmrg * Verify that a fragment shader executable meets all semantic requirements
75301e04c3fSmrg *
75401e04c3fSmrg * \param shader  Fragment shader executable to be verified
75501e04c3fSmrg */
75601e04c3fSmrgstatic void
75701e04c3fSmrgvalidate_fragment_shader_executable(struct gl_shader_program *prog,
75801e04c3fSmrg                                    struct gl_linked_shader *shader)
75901e04c3fSmrg{
76001e04c3fSmrg   if (shader == NULL)
76101e04c3fSmrg      return;
76201e04c3fSmrg
76301e04c3fSmrg   find_variable gl_FragColor("gl_FragColor");
76401e04c3fSmrg   find_variable gl_FragData("gl_FragData");
76501e04c3fSmrg   find_variable * const variables[] = { &gl_FragColor, &gl_FragData, NULL };
76601e04c3fSmrg   find_assignments(shader->ir, variables);
76701e04c3fSmrg
76801e04c3fSmrg   if (gl_FragColor.found && gl_FragData.found) {
76901e04c3fSmrg      linker_error(prog,  "fragment shader writes to both "
77001e04c3fSmrg                   "`gl_FragColor' and `gl_FragData'\n");
77101e04c3fSmrg   }
77201e04c3fSmrg}
77301e04c3fSmrg
77401e04c3fSmrg/**
77501e04c3fSmrg * Verify that a geometry shader executable meets all semantic requirements
77601e04c3fSmrg *
77701e04c3fSmrg * Also sets prog->Geom.VerticesIn, and info.clip_distance_array_sizeand
77801e04c3fSmrg * info.cull_distance_array_size as a side effect.
77901e04c3fSmrg *
78001e04c3fSmrg * \param shader Geometry shader executable to be verified
78101e04c3fSmrg */
78201e04c3fSmrgstatic void
78301e04c3fSmrgvalidate_geometry_shader_executable(struct gl_shader_program *prog,
78401e04c3fSmrg                                    struct gl_linked_shader *shader,
78501e04c3fSmrg                                    struct gl_context *ctx)
78601e04c3fSmrg{
78701e04c3fSmrg   if (shader == NULL)
78801e04c3fSmrg      return;
78901e04c3fSmrg
79001e04c3fSmrg   unsigned num_vertices =
79101e04c3fSmrg      vertices_per_prim(shader->Program->info.gs.input_primitive);
79201e04c3fSmrg   prog->Geom.VerticesIn = num_vertices;
79301e04c3fSmrg
79401e04c3fSmrg   analyze_clip_cull_usage(prog, shader, ctx,
79501e04c3fSmrg                           &shader->Program->info.clip_distance_array_size,
79601e04c3fSmrg                           &shader->Program->info.cull_distance_array_size);
79701e04c3fSmrg}
79801e04c3fSmrg
79901e04c3fSmrg/**
80001e04c3fSmrg * Check if geometry shaders emit to non-zero streams and do corresponding
80101e04c3fSmrg * validations.
80201e04c3fSmrg */
80301e04c3fSmrgstatic void
80401e04c3fSmrgvalidate_geometry_shader_emissions(struct gl_context *ctx,
80501e04c3fSmrg                                   struct gl_shader_program *prog)
80601e04c3fSmrg{
80701e04c3fSmrg   struct gl_linked_shader *sh = prog->_LinkedShaders[MESA_SHADER_GEOMETRY];
80801e04c3fSmrg
80901e04c3fSmrg   if (sh != NULL) {
81001e04c3fSmrg      find_emit_vertex_visitor emit_vertex(ctx->Const.MaxVertexStreams - 1);
81101e04c3fSmrg      emit_vertex.run(sh->ir);
81201e04c3fSmrg      if (emit_vertex.error()) {
81301e04c3fSmrg         linker_error(prog, "Invalid call %s(%d). Accepted values for the "
81401e04c3fSmrg                      "stream parameter are in the range [0, %d].\n",
81501e04c3fSmrg                      emit_vertex.error_func(),
81601e04c3fSmrg                      emit_vertex.error_stream(),
81701e04c3fSmrg                      ctx->Const.MaxVertexStreams - 1);
81801e04c3fSmrg      }
81901e04c3fSmrg      prog->Geom.UsesStreams = emit_vertex.uses_streams();
82001e04c3fSmrg      prog->Geom.UsesEndPrimitive = emit_vertex.uses_end_primitive();
82101e04c3fSmrg
82201e04c3fSmrg      /* From the ARB_gpu_shader5 spec:
82301e04c3fSmrg       *
82401e04c3fSmrg       *   "Multiple vertex streams are supported only if the output primitive
82501e04c3fSmrg       *    type is declared to be "points".  A program will fail to link if it
82601e04c3fSmrg       *    contains a geometry shader calling EmitStreamVertex() or
82701e04c3fSmrg       *    EndStreamPrimitive() if its output primitive type is not "points".
82801e04c3fSmrg       *
82901e04c3fSmrg       * However, in the same spec:
83001e04c3fSmrg       *
83101e04c3fSmrg       *   "The function EmitVertex() is equivalent to calling EmitStreamVertex()
83201e04c3fSmrg       *    with <stream> set to zero."
83301e04c3fSmrg       *
83401e04c3fSmrg       * And:
83501e04c3fSmrg       *
83601e04c3fSmrg       *   "The function EndPrimitive() is equivalent to calling
83701e04c3fSmrg       *    EndStreamPrimitive() with <stream> set to zero."
83801e04c3fSmrg       *
83901e04c3fSmrg       * Since we can call EmitVertex() and EndPrimitive() when we output
84001e04c3fSmrg       * primitives other than points, calling EmitStreamVertex(0) or
84101e04c3fSmrg       * EmitEndPrimitive(0) should not produce errors. This it also what Nvidia
84201e04c3fSmrg       * does. Currently we only set prog->Geom.UsesStreams to TRUE when
84301e04c3fSmrg       * EmitStreamVertex() or EmitEndPrimitive() are called with a non-zero
84401e04c3fSmrg       * stream.
84501e04c3fSmrg       */
84601e04c3fSmrg      if (prog->Geom.UsesStreams &&
84701e04c3fSmrg          sh->Program->info.gs.output_primitive != GL_POINTS) {
84801e04c3fSmrg         linker_error(prog, "EmitStreamVertex(n) and EndStreamPrimitive(n) "
84901e04c3fSmrg                      "with n>0 requires point output\n");
85001e04c3fSmrg      }
85101e04c3fSmrg   }
85201e04c3fSmrg}
85301e04c3fSmrg
85401e04c3fSmrgbool
85501e04c3fSmrgvalidate_intrastage_arrays(struct gl_shader_program *prog,
85601e04c3fSmrg                           ir_variable *const var,
85701e04c3fSmrg                           ir_variable *const existing)
85801e04c3fSmrg{
85901e04c3fSmrg   /* Consider the types to be "the same" if both types are arrays
86001e04c3fSmrg    * of the same type and one of the arrays is implicitly sized.
86101e04c3fSmrg    * In addition, set the type of the linked variable to the
86201e04c3fSmrg    * explicitly sized array.
86301e04c3fSmrg    */
86401e04c3fSmrg   if (var->type->is_array() && existing->type->is_array()) {
86501e04c3fSmrg      if ((var->type->fields.array == existing->type->fields.array) &&
86601e04c3fSmrg          ((var->type->length == 0)|| (existing->type->length == 0))) {
86701e04c3fSmrg         if (var->type->length != 0) {
86801e04c3fSmrg            if ((int)var->type->length <= existing->data.max_array_access) {
86901e04c3fSmrg               linker_error(prog, "%s `%s' declared as type "
87001e04c3fSmrg                           "`%s' but outermost dimension has an index"
87101e04c3fSmrg                           " of `%i'\n",
87201e04c3fSmrg                           mode_string(var),
87301e04c3fSmrg                           var->name, var->type->name,
87401e04c3fSmrg                           existing->data.max_array_access);
87501e04c3fSmrg            }
87601e04c3fSmrg            existing->type = var->type;
87701e04c3fSmrg            return true;
87801e04c3fSmrg         } else if (existing->type->length != 0) {
87901e04c3fSmrg            if((int)existing->type->length <= var->data.max_array_access &&
88001e04c3fSmrg               !existing->data.from_ssbo_unsized_array) {
88101e04c3fSmrg               linker_error(prog, "%s `%s' declared as type "
88201e04c3fSmrg                           "`%s' but outermost dimension has an index"
88301e04c3fSmrg                           " of `%i'\n",
88401e04c3fSmrg                           mode_string(var),
88501e04c3fSmrg                           var->name, existing->type->name,
88601e04c3fSmrg                           var->data.max_array_access);
88701e04c3fSmrg            }
88801e04c3fSmrg            return true;
88901e04c3fSmrg         }
89001e04c3fSmrg      }
89101e04c3fSmrg   }
89201e04c3fSmrg   return false;
89301e04c3fSmrg}
89401e04c3fSmrg
89501e04c3fSmrg
89601e04c3fSmrg/**
89701e04c3fSmrg * Perform validation of global variables used across multiple shaders
89801e04c3fSmrg */
89901e04c3fSmrgstatic void
90001e04c3fSmrgcross_validate_globals(struct gl_context *ctx, struct gl_shader_program *prog,
90101e04c3fSmrg                       struct exec_list *ir, glsl_symbol_table *variables,
90201e04c3fSmrg                       bool uniforms_only)
90301e04c3fSmrg{
90401e04c3fSmrg   foreach_in_list(ir_instruction, node, ir) {
90501e04c3fSmrg      ir_variable *const var = node->as_variable();
90601e04c3fSmrg
90701e04c3fSmrg      if (var == NULL)
90801e04c3fSmrg         continue;
90901e04c3fSmrg
91001e04c3fSmrg      if (uniforms_only && (var->data.mode != ir_var_uniform && var->data.mode != ir_var_shader_storage))
91101e04c3fSmrg         continue;
91201e04c3fSmrg
91301e04c3fSmrg      /* don't cross validate subroutine uniforms */
91401e04c3fSmrg      if (var->type->contains_subroutine())
91501e04c3fSmrg         continue;
91601e04c3fSmrg
91701e04c3fSmrg      /* Don't cross validate interface instances. These are only relevant
91801e04c3fSmrg       * inside a shader. The cross validation is done at the Interface Block
91901e04c3fSmrg       * name level.
92001e04c3fSmrg       */
92101e04c3fSmrg      if (var->is_interface_instance())
92201e04c3fSmrg         continue;
92301e04c3fSmrg
92401e04c3fSmrg      /* Don't cross validate temporaries that are at global scope.  These
92501e04c3fSmrg       * will eventually get pulled into the shaders 'main'.
92601e04c3fSmrg       */
92701e04c3fSmrg      if (var->data.mode == ir_var_temporary)
92801e04c3fSmrg         continue;
92901e04c3fSmrg
93001e04c3fSmrg      /* If a global with this name has already been seen, verify that the
93101e04c3fSmrg       * new instance has the same type.  In addition, if the globals have
93201e04c3fSmrg       * initializers, the values of the initializers must be the same.
93301e04c3fSmrg       */
93401e04c3fSmrg      ir_variable *const existing = variables->get_variable(var->name);
93501e04c3fSmrg      if (existing != NULL) {
93601e04c3fSmrg         /* Check if types match. */
93701e04c3fSmrg         if (var->type != existing->type) {
93801e04c3fSmrg            if (!validate_intrastage_arrays(prog, var, existing)) {
93901e04c3fSmrg               /* If it is an unsized array in a Shader Storage Block,
94001e04c3fSmrg                * two different shaders can access to different elements.
94101e04c3fSmrg                * Because of that, they might be converted to different
94201e04c3fSmrg                * sized arrays, then check that they are compatible but
94301e04c3fSmrg                * ignore the array size.
94401e04c3fSmrg                */
94501e04c3fSmrg               if (!(var->data.mode == ir_var_shader_storage &&
94601e04c3fSmrg                     var->data.from_ssbo_unsized_array &&
94701e04c3fSmrg                     existing->data.mode == ir_var_shader_storage &&
94801e04c3fSmrg                     existing->data.from_ssbo_unsized_array &&
94901e04c3fSmrg                     var->type->gl_type == existing->type->gl_type)) {
95001e04c3fSmrg                  linker_error(prog, "%s `%s' declared as type "
95101e04c3fSmrg                                 "`%s' and type `%s'\n",
95201e04c3fSmrg                                 mode_string(var),
95301e04c3fSmrg                                 var->name, var->type->name,
95401e04c3fSmrg                                 existing->type->name);
95501e04c3fSmrg                  return;
95601e04c3fSmrg               }
95701e04c3fSmrg            }
95801e04c3fSmrg         }
95901e04c3fSmrg
96001e04c3fSmrg         if (var->data.explicit_location) {
96101e04c3fSmrg            if (existing->data.explicit_location
96201e04c3fSmrg                && (var->data.location != existing->data.location)) {
96301e04c3fSmrg               linker_error(prog, "explicit locations for %s "
96401e04c3fSmrg                            "`%s' have differing values\n",
96501e04c3fSmrg                            mode_string(var), var->name);
96601e04c3fSmrg               return;
96701e04c3fSmrg            }
96801e04c3fSmrg
96901e04c3fSmrg            if (var->data.location_frac != existing->data.location_frac) {
97001e04c3fSmrg               linker_error(prog, "explicit components for %s `%s' have "
97101e04c3fSmrg                            "differing values\n", mode_string(var), var->name);
97201e04c3fSmrg               return;
97301e04c3fSmrg            }
97401e04c3fSmrg
97501e04c3fSmrg            existing->data.location = var->data.location;
97601e04c3fSmrg            existing->data.explicit_location = true;
97701e04c3fSmrg         } else {
97801e04c3fSmrg            /* Check if uniform with implicit location was marked explicit
97901e04c3fSmrg             * by earlier shader stage. If so, mark it explicit in this stage
98001e04c3fSmrg             * too to make sure later processing does not treat it as
98101e04c3fSmrg             * implicit one.
98201e04c3fSmrg             */
98301e04c3fSmrg            if (existing->data.explicit_location) {
98401e04c3fSmrg               var->data.location = existing->data.location;
98501e04c3fSmrg               var->data.explicit_location = true;
98601e04c3fSmrg            }
98701e04c3fSmrg         }
98801e04c3fSmrg
98901e04c3fSmrg         /* From the GLSL 4.20 specification:
99001e04c3fSmrg          * "A link error will result if two compilation units in a program
99101e04c3fSmrg          *  specify different integer-constant bindings for the same
99201e04c3fSmrg          *  opaque-uniform name.  However, it is not an error to specify a
99301e04c3fSmrg          *  binding on some but not all declarations for the same name"
99401e04c3fSmrg          */
99501e04c3fSmrg         if (var->data.explicit_binding) {
99601e04c3fSmrg            if (existing->data.explicit_binding &&
99701e04c3fSmrg                var->data.binding != existing->data.binding) {
99801e04c3fSmrg               linker_error(prog, "explicit bindings for %s "
99901e04c3fSmrg                            "`%s' have differing values\n",
100001e04c3fSmrg                            mode_string(var), var->name);
100101e04c3fSmrg               return;
100201e04c3fSmrg            }
100301e04c3fSmrg
100401e04c3fSmrg            existing->data.binding = var->data.binding;
100501e04c3fSmrg            existing->data.explicit_binding = true;
100601e04c3fSmrg         }
100701e04c3fSmrg
100801e04c3fSmrg         if (var->type->contains_atomic() &&
100901e04c3fSmrg             var->data.offset != existing->data.offset) {
101001e04c3fSmrg            linker_error(prog, "offset specifications for %s "
101101e04c3fSmrg                         "`%s' have differing values\n",
101201e04c3fSmrg                         mode_string(var), var->name);
101301e04c3fSmrg            return;
101401e04c3fSmrg         }
101501e04c3fSmrg
101601e04c3fSmrg         /* Validate layout qualifiers for gl_FragDepth.
101701e04c3fSmrg          *
101801e04c3fSmrg          * From the AMD/ARB_conservative_depth specs:
101901e04c3fSmrg          *
102001e04c3fSmrg          *    "If gl_FragDepth is redeclared in any fragment shader in a
102101e04c3fSmrg          *    program, it must be redeclared in all fragment shaders in
102201e04c3fSmrg          *    that program that have static assignments to
102301e04c3fSmrg          *    gl_FragDepth. All redeclarations of gl_FragDepth in all
102401e04c3fSmrg          *    fragment shaders in a single program must have the same set
102501e04c3fSmrg          *    of qualifiers."
102601e04c3fSmrg          */
102701e04c3fSmrg         if (strcmp(var->name, "gl_FragDepth") == 0) {
102801e04c3fSmrg            bool layout_declared = var->data.depth_layout != ir_depth_layout_none;
102901e04c3fSmrg            bool layout_differs =
103001e04c3fSmrg               var->data.depth_layout != existing->data.depth_layout;
103101e04c3fSmrg
103201e04c3fSmrg            if (layout_declared && layout_differs) {
103301e04c3fSmrg               linker_error(prog,
103401e04c3fSmrg                            "All redeclarations of gl_FragDepth in all "
103501e04c3fSmrg                            "fragment shaders in a single program must have "
103601e04c3fSmrg                            "the same set of qualifiers.\n");
103701e04c3fSmrg            }
103801e04c3fSmrg
103901e04c3fSmrg            if (var->data.used && layout_differs) {
104001e04c3fSmrg               linker_error(prog,
104101e04c3fSmrg                            "If gl_FragDepth is redeclared with a layout "
104201e04c3fSmrg                            "qualifier in any fragment shader, it must be "
104301e04c3fSmrg                            "redeclared with the same layout qualifier in "
104401e04c3fSmrg                            "all fragment shaders that have assignments to "
104501e04c3fSmrg                            "gl_FragDepth\n");
104601e04c3fSmrg            }
104701e04c3fSmrg         }
104801e04c3fSmrg
104901e04c3fSmrg         /* Page 35 (page 41 of the PDF) of the GLSL 4.20 spec says:
105001e04c3fSmrg          *
105101e04c3fSmrg          *     "If a shared global has multiple initializers, the
105201e04c3fSmrg          *     initializers must all be constant expressions, and they
105301e04c3fSmrg          *     must all have the same value. Otherwise, a link error will
105401e04c3fSmrg          *     result. (A shared global having only one initializer does
105501e04c3fSmrg          *     not require that initializer to be a constant expression.)"
105601e04c3fSmrg          *
105701e04c3fSmrg          * Previous to 4.20 the GLSL spec simply said that initializers
105801e04c3fSmrg          * must have the same value.  In this case of non-constant
105901e04c3fSmrg          * initializers, this was impossible to determine.  As a result,
106001e04c3fSmrg          * no vendor actually implemented that behavior.  The 4.20
106101e04c3fSmrg          * behavior matches the implemented behavior of at least one other
106201e04c3fSmrg          * vendor, so we'll implement that for all GLSL versions.
106301e04c3fSmrg          */
106401e04c3fSmrg         if (var->constant_initializer != NULL) {
106501e04c3fSmrg            if (existing->constant_initializer != NULL) {
106601e04c3fSmrg               if (!var->constant_initializer->has_value(existing->constant_initializer)) {
106701e04c3fSmrg                  linker_error(prog, "initializers for %s "
106801e04c3fSmrg                               "`%s' have differing values\n",
106901e04c3fSmrg                               mode_string(var), var->name);
107001e04c3fSmrg                  return;
107101e04c3fSmrg               }
107201e04c3fSmrg            } else {
107301e04c3fSmrg               /* If the first-seen instance of a particular uniform did
107401e04c3fSmrg                * not have an initializer but a later instance does,
107501e04c3fSmrg                * replace the former with the later.
107601e04c3fSmrg                */
107701e04c3fSmrg               variables->replace_variable(existing->name, var);
107801e04c3fSmrg            }
107901e04c3fSmrg         }
108001e04c3fSmrg
108101e04c3fSmrg         if (var->data.has_initializer) {
108201e04c3fSmrg            if (existing->data.has_initializer
108301e04c3fSmrg                && (var->constant_initializer == NULL
108401e04c3fSmrg                    || existing->constant_initializer == NULL)) {
108501e04c3fSmrg               linker_error(prog,
108601e04c3fSmrg                            "shared global variable `%s' has multiple "
108701e04c3fSmrg                            "non-constant initializers.\n",
108801e04c3fSmrg                            var->name);
108901e04c3fSmrg               return;
109001e04c3fSmrg            }
109101e04c3fSmrg         }
109201e04c3fSmrg
1093993e1d59Smrg         if (existing->data.explicit_invariant != var->data.explicit_invariant) {
109401e04c3fSmrg            linker_error(prog, "declarations for %s `%s' have "
109501e04c3fSmrg                         "mismatching invariant qualifiers\n",
109601e04c3fSmrg                         mode_string(var), var->name);
109701e04c3fSmrg            return;
109801e04c3fSmrg         }
109901e04c3fSmrg         if (existing->data.centroid != var->data.centroid) {
110001e04c3fSmrg            linker_error(prog, "declarations for %s `%s' have "
110101e04c3fSmrg                         "mismatching centroid qualifiers\n",
110201e04c3fSmrg                         mode_string(var), var->name);
110301e04c3fSmrg            return;
110401e04c3fSmrg         }
110501e04c3fSmrg         if (existing->data.sample != var->data.sample) {
110601e04c3fSmrg            linker_error(prog, "declarations for %s `%s` have "
110701e04c3fSmrg                         "mismatching sample qualifiers\n",
110801e04c3fSmrg                         mode_string(var), var->name);
110901e04c3fSmrg            return;
111001e04c3fSmrg         }
111101e04c3fSmrg         if (existing->data.image_format != var->data.image_format) {
111201e04c3fSmrg            linker_error(prog, "declarations for %s `%s` have "
111301e04c3fSmrg                         "mismatching image format qualifiers\n",
111401e04c3fSmrg                         mode_string(var), var->name);
111501e04c3fSmrg            return;
111601e04c3fSmrg         }
111701e04c3fSmrg
111801e04c3fSmrg         /* Check the precision qualifier matches for uniform variables on
111901e04c3fSmrg          * GLSL ES.
112001e04c3fSmrg          */
112101e04c3fSmrg         if (!ctx->Const.AllowGLSLRelaxedES &&
112201e04c3fSmrg             prog->IsES && !var->get_interface_type() &&
112301e04c3fSmrg             existing->data.precision != var->data.precision) {
112401e04c3fSmrg            if ((existing->data.used && var->data.used) || prog->data->Version >= 300) {
112501e04c3fSmrg               linker_error(prog, "declarations for %s `%s` have "
112601e04c3fSmrg                            "mismatching precision qualifiers\n",
112701e04c3fSmrg                            mode_string(var), var->name);
112801e04c3fSmrg               return;
112901e04c3fSmrg            } else {
113001e04c3fSmrg               linker_warning(prog, "declarations for %s `%s` have "
113101e04c3fSmrg                              "mismatching precision qualifiers\n",
113201e04c3fSmrg                              mode_string(var), var->name);
113301e04c3fSmrg            }
113401e04c3fSmrg         }
113501e04c3fSmrg
113601e04c3fSmrg         /* In OpenGL GLSL 3.20 spec, section 4.3.9:
113701e04c3fSmrg          *
113801e04c3fSmrg          *   "It is a link-time error if any particular shader interface
113901e04c3fSmrg          *    contains:
114001e04c3fSmrg          *
114101e04c3fSmrg          *    - two different blocks, each having no instance name, and each
114201e04c3fSmrg          *      having a member of the same name, or
114301e04c3fSmrg          *
114401e04c3fSmrg          *    - a variable outside a block, and a block with no instance name,
114501e04c3fSmrg          *      where the variable has the same name as a member in the block."
114601e04c3fSmrg          */
114701e04c3fSmrg         const glsl_type *var_itype = var->get_interface_type();
114801e04c3fSmrg         const glsl_type *existing_itype = existing->get_interface_type();
114901e04c3fSmrg         if (var_itype != existing_itype) {
115001e04c3fSmrg            if (!var_itype || !existing_itype) {
115101e04c3fSmrg               linker_error(prog, "declarations for %s `%s` are inside block "
115201e04c3fSmrg                            "`%s` and outside a block",
115301e04c3fSmrg                            mode_string(var), var->name,
115401e04c3fSmrg                            var_itype ? var_itype->name : existing_itype->name);
115501e04c3fSmrg               return;
115601e04c3fSmrg            } else if (strcmp(var_itype->name, existing_itype->name) != 0) {
115701e04c3fSmrg               linker_error(prog, "declarations for %s `%s` are inside blocks "
115801e04c3fSmrg                            "`%s` and `%s`",
115901e04c3fSmrg                            mode_string(var), var->name,
116001e04c3fSmrg                            existing_itype->name,
116101e04c3fSmrg                            var_itype->name);
116201e04c3fSmrg               return;
116301e04c3fSmrg            }
116401e04c3fSmrg         }
116501e04c3fSmrg      } else
116601e04c3fSmrg         variables->add_variable(var);
116701e04c3fSmrg   }
116801e04c3fSmrg}
116901e04c3fSmrg
117001e04c3fSmrg
117101e04c3fSmrg/**
117201e04c3fSmrg * Perform validation of uniforms used across multiple shader stages
117301e04c3fSmrg */
117401e04c3fSmrgstatic void
117501e04c3fSmrgcross_validate_uniforms(struct gl_context *ctx,
117601e04c3fSmrg                        struct gl_shader_program *prog)
117701e04c3fSmrg{
117801e04c3fSmrg   glsl_symbol_table variables;
117901e04c3fSmrg   for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
118001e04c3fSmrg      if (prog->_LinkedShaders[i] == NULL)
118101e04c3fSmrg         continue;
118201e04c3fSmrg
118301e04c3fSmrg      cross_validate_globals(ctx, prog, prog->_LinkedShaders[i]->ir,
118401e04c3fSmrg                             &variables, true);
118501e04c3fSmrg   }
118601e04c3fSmrg}
118701e04c3fSmrg
118801e04c3fSmrg/**
118901e04c3fSmrg * Accumulates the array of buffer blocks and checks that all definitions of
119001e04c3fSmrg * blocks agree on their contents.
119101e04c3fSmrg */
119201e04c3fSmrgstatic bool
119301e04c3fSmrginterstage_cross_validate_uniform_blocks(struct gl_shader_program *prog,
119401e04c3fSmrg                                         bool validate_ssbo)
119501e04c3fSmrg{
119601e04c3fSmrg   int *InterfaceBlockStageIndex[MESA_SHADER_STAGES];
119701e04c3fSmrg   struct gl_uniform_block *blks = NULL;
119801e04c3fSmrg   unsigned *num_blks = validate_ssbo ? &prog->data->NumShaderStorageBlocks :
119901e04c3fSmrg      &prog->data->NumUniformBlocks;
120001e04c3fSmrg
120101e04c3fSmrg   unsigned max_num_buffer_blocks = 0;
120201e04c3fSmrg   for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
120301e04c3fSmrg      if (prog->_LinkedShaders[i]) {
120401e04c3fSmrg         if (validate_ssbo) {
120501e04c3fSmrg            max_num_buffer_blocks +=
120601e04c3fSmrg               prog->_LinkedShaders[i]->Program->info.num_ssbos;
120701e04c3fSmrg         } else {
120801e04c3fSmrg            max_num_buffer_blocks +=
120901e04c3fSmrg               prog->_LinkedShaders[i]->Program->info.num_ubos;
121001e04c3fSmrg         }
121101e04c3fSmrg      }
121201e04c3fSmrg   }
121301e04c3fSmrg
121401e04c3fSmrg   for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
121501e04c3fSmrg      struct gl_linked_shader *sh = prog->_LinkedShaders[i];
121601e04c3fSmrg
121701e04c3fSmrg      InterfaceBlockStageIndex[i] = new int[max_num_buffer_blocks];
121801e04c3fSmrg      for (unsigned int j = 0; j < max_num_buffer_blocks; j++)
121901e04c3fSmrg         InterfaceBlockStageIndex[i][j] = -1;
122001e04c3fSmrg
122101e04c3fSmrg      if (sh == NULL)
122201e04c3fSmrg         continue;
122301e04c3fSmrg
122401e04c3fSmrg      unsigned sh_num_blocks;
122501e04c3fSmrg      struct gl_uniform_block **sh_blks;
122601e04c3fSmrg      if (validate_ssbo) {
122701e04c3fSmrg         sh_num_blocks = prog->_LinkedShaders[i]->Program->info.num_ssbos;
122801e04c3fSmrg         sh_blks = sh->Program->sh.ShaderStorageBlocks;
122901e04c3fSmrg      } else {
123001e04c3fSmrg         sh_num_blocks = prog->_LinkedShaders[i]->Program->info.num_ubos;
123101e04c3fSmrg         sh_blks = sh->Program->sh.UniformBlocks;
123201e04c3fSmrg      }
123301e04c3fSmrg
123401e04c3fSmrg      for (unsigned int j = 0; j < sh_num_blocks; j++) {
123501e04c3fSmrg         int index = link_cross_validate_uniform_block(prog->data, &blks,
123601e04c3fSmrg                                                       num_blks, sh_blks[j]);
123701e04c3fSmrg
123801e04c3fSmrg         if (index == -1) {
123901e04c3fSmrg            linker_error(prog, "buffer block `%s' has mismatching "
124001e04c3fSmrg                         "definitions\n", sh_blks[j]->Name);
124101e04c3fSmrg
124201e04c3fSmrg            for (unsigned k = 0; k <= i; k++) {
124301e04c3fSmrg               delete[] InterfaceBlockStageIndex[k];
124401e04c3fSmrg            }
124501e04c3fSmrg
124601e04c3fSmrg            /* Reset the block count. This will help avoid various segfaults
124701e04c3fSmrg             * from api calls that assume the array exists due to the count
124801e04c3fSmrg             * being non-zero.
124901e04c3fSmrg             */
125001e04c3fSmrg            *num_blks = 0;
125101e04c3fSmrg            return false;
125201e04c3fSmrg         }
125301e04c3fSmrg
125401e04c3fSmrg         InterfaceBlockStageIndex[i][index] = j;
125501e04c3fSmrg      }
125601e04c3fSmrg   }
125701e04c3fSmrg
125801e04c3fSmrg   /* Update per stage block pointers to point to the program list.
125901e04c3fSmrg    * FIXME: We should be able to free the per stage blocks here.
126001e04c3fSmrg    */
126101e04c3fSmrg   for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
126201e04c3fSmrg      for (unsigned j = 0; j < *num_blks; j++) {
126301e04c3fSmrg         int stage_index = InterfaceBlockStageIndex[i][j];
126401e04c3fSmrg
126501e04c3fSmrg         if (stage_index != -1) {
126601e04c3fSmrg            struct gl_linked_shader *sh = prog->_LinkedShaders[i];
126701e04c3fSmrg
126801e04c3fSmrg            struct gl_uniform_block **sh_blks = validate_ssbo ?
126901e04c3fSmrg               sh->Program->sh.ShaderStorageBlocks :
127001e04c3fSmrg               sh->Program->sh.UniformBlocks;
127101e04c3fSmrg
127201e04c3fSmrg            blks[j].stageref |= sh_blks[stage_index]->stageref;
127301e04c3fSmrg            sh_blks[stage_index] = &blks[j];
127401e04c3fSmrg         }
127501e04c3fSmrg      }
127601e04c3fSmrg   }
127701e04c3fSmrg
127801e04c3fSmrg   for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
127901e04c3fSmrg      delete[] InterfaceBlockStageIndex[i];
128001e04c3fSmrg   }
128101e04c3fSmrg
128201e04c3fSmrg   if (validate_ssbo)
128301e04c3fSmrg      prog->data->ShaderStorageBlocks = blks;
128401e04c3fSmrg   else
128501e04c3fSmrg      prog->data->UniformBlocks = blks;
128601e04c3fSmrg
128701e04c3fSmrg   return true;
128801e04c3fSmrg}
128901e04c3fSmrg
129001e04c3fSmrg/**
129101e04c3fSmrg * Verifies the invariance of built-in special variables.
129201e04c3fSmrg */
129301e04c3fSmrgstatic bool
129401e04c3fSmrgvalidate_invariant_builtins(struct gl_shader_program *prog,
129501e04c3fSmrg                            const gl_linked_shader *vert,
129601e04c3fSmrg                            const gl_linked_shader *frag)
129701e04c3fSmrg{
129801e04c3fSmrg   const ir_variable *var_vert;
129901e04c3fSmrg   const ir_variable *var_frag;
130001e04c3fSmrg
130101e04c3fSmrg   if (!vert || !frag)
130201e04c3fSmrg      return true;
130301e04c3fSmrg
130401e04c3fSmrg   /*
130501e04c3fSmrg    * From OpenGL ES Shading Language 1.0 specification
130601e04c3fSmrg    * (4.6.4 Invariance and Linkage):
130701e04c3fSmrg    *     "The invariance of varyings that are declared in both the vertex and
130801e04c3fSmrg    *     fragment shaders must match. For the built-in special variables,
130901e04c3fSmrg    *     gl_FragCoord can only be declared invariant if and only if
131001e04c3fSmrg    *     gl_Position is declared invariant. Similarly gl_PointCoord can only
131101e04c3fSmrg    *     be declared invariant if and only if gl_PointSize is declared
131201e04c3fSmrg    *     invariant. It is an error to declare gl_FrontFacing as invariant.
131301e04c3fSmrg    *     The invariance of gl_FrontFacing is the same as the invariance of
131401e04c3fSmrg    *     gl_Position."
131501e04c3fSmrg    */
131601e04c3fSmrg   var_frag = frag->symbols->get_variable("gl_FragCoord");
131701e04c3fSmrg   if (var_frag && var_frag->data.invariant) {
131801e04c3fSmrg      var_vert = vert->symbols->get_variable("gl_Position");
131901e04c3fSmrg      if (var_vert && !var_vert->data.invariant) {
132001e04c3fSmrg         linker_error(prog,
132101e04c3fSmrg               "fragment shader built-in `%s' has invariant qualifier, "
132201e04c3fSmrg               "but vertex shader built-in `%s' lacks invariant qualifier\n",
132301e04c3fSmrg               var_frag->name, var_vert->name);
132401e04c3fSmrg         return false;
132501e04c3fSmrg      }
132601e04c3fSmrg   }
132701e04c3fSmrg
132801e04c3fSmrg   var_frag = frag->symbols->get_variable("gl_PointCoord");
132901e04c3fSmrg   if (var_frag && var_frag->data.invariant) {
133001e04c3fSmrg      var_vert = vert->symbols->get_variable("gl_PointSize");
133101e04c3fSmrg      if (var_vert && !var_vert->data.invariant) {
133201e04c3fSmrg         linker_error(prog,
133301e04c3fSmrg               "fragment shader built-in `%s' has invariant qualifier, "
133401e04c3fSmrg               "but vertex shader built-in `%s' lacks invariant qualifier\n",
133501e04c3fSmrg               var_frag->name, var_vert->name);
133601e04c3fSmrg         return false;
133701e04c3fSmrg      }
133801e04c3fSmrg   }
133901e04c3fSmrg
134001e04c3fSmrg   var_frag = frag->symbols->get_variable("gl_FrontFacing");
134101e04c3fSmrg   if (var_frag && var_frag->data.invariant) {
134201e04c3fSmrg      linker_error(prog,
134301e04c3fSmrg            "fragment shader built-in `%s' can not be declared as invariant\n",
134401e04c3fSmrg            var_frag->name);
134501e04c3fSmrg      return false;
134601e04c3fSmrg   }
134701e04c3fSmrg
134801e04c3fSmrg   return true;
134901e04c3fSmrg}
135001e04c3fSmrg
135101e04c3fSmrg/**
135201e04c3fSmrg * Populates a shaders symbol table with all global declarations
135301e04c3fSmrg */
135401e04c3fSmrgstatic void
135501e04c3fSmrgpopulate_symbol_table(gl_linked_shader *sh, glsl_symbol_table *symbols)
135601e04c3fSmrg{
135701e04c3fSmrg   sh->symbols = new(sh) glsl_symbol_table;
135801e04c3fSmrg
135901e04c3fSmrg   _mesa_glsl_copy_symbols_from_table(sh->ir, symbols, sh->symbols);
136001e04c3fSmrg}
136101e04c3fSmrg
136201e04c3fSmrg
136301e04c3fSmrg/**
136401e04c3fSmrg * Remap variables referenced in an instruction tree
136501e04c3fSmrg *
136601e04c3fSmrg * This is used when instruction trees are cloned from one shader and placed in
136701e04c3fSmrg * another.  These trees will contain references to \c ir_variable nodes that
136801e04c3fSmrg * do not exist in the target shader.  This function finds these \c ir_variable
136901e04c3fSmrg * references and replaces the references with matching variables in the target
137001e04c3fSmrg * shader.
137101e04c3fSmrg *
137201e04c3fSmrg * If there is no matching variable in the target shader, a clone of the
137301e04c3fSmrg * \c ir_variable is made and added to the target shader.  The new variable is
137401e04c3fSmrg * added to \b both the instruction stream and the symbol table.
137501e04c3fSmrg *
137601e04c3fSmrg * \param inst         IR tree that is to be processed.
137701e04c3fSmrg * \param symbols      Symbol table containing global scope symbols in the
137801e04c3fSmrg *                     linked shader.
137901e04c3fSmrg * \param instructions Instruction stream where new variable declarations
138001e04c3fSmrg *                     should be added.
138101e04c3fSmrg */
138201e04c3fSmrgstatic void
138301e04c3fSmrgremap_variables(ir_instruction *inst, struct gl_linked_shader *target,
138401e04c3fSmrg                hash_table *temps)
138501e04c3fSmrg{
138601e04c3fSmrg   class remap_visitor : public ir_hierarchical_visitor {
138701e04c3fSmrg   public:
138801e04c3fSmrg         remap_visitor(struct gl_linked_shader *target, hash_table *temps)
138901e04c3fSmrg      {
139001e04c3fSmrg         this->target = target;
139101e04c3fSmrg         this->symbols = target->symbols;
139201e04c3fSmrg         this->instructions = target->ir;
139301e04c3fSmrg         this->temps = temps;
139401e04c3fSmrg      }
139501e04c3fSmrg
139601e04c3fSmrg      virtual ir_visitor_status visit(ir_dereference_variable *ir)
139701e04c3fSmrg      {
139801e04c3fSmrg         if (ir->var->data.mode == ir_var_temporary) {
139901e04c3fSmrg            hash_entry *entry = _mesa_hash_table_search(temps, ir->var);
140001e04c3fSmrg            ir_variable *var = entry ? (ir_variable *) entry->data : NULL;
140101e04c3fSmrg
140201e04c3fSmrg            assert(var != NULL);
140301e04c3fSmrg            ir->var = var;
140401e04c3fSmrg            return visit_continue;
140501e04c3fSmrg         }
140601e04c3fSmrg
140701e04c3fSmrg         ir_variable *const existing =
140801e04c3fSmrg            this->symbols->get_variable(ir->var->name);
140901e04c3fSmrg         if (existing != NULL)
141001e04c3fSmrg            ir->var = existing;
141101e04c3fSmrg         else {
141201e04c3fSmrg            ir_variable *copy = ir->var->clone(this->target, NULL);
141301e04c3fSmrg
141401e04c3fSmrg            this->symbols->add_variable(copy);
141501e04c3fSmrg            this->instructions->push_head(copy);
141601e04c3fSmrg            ir->var = copy;
141701e04c3fSmrg         }
141801e04c3fSmrg
141901e04c3fSmrg         return visit_continue;
142001e04c3fSmrg      }
142101e04c3fSmrg
142201e04c3fSmrg   private:
142301e04c3fSmrg      struct gl_linked_shader *target;
142401e04c3fSmrg      glsl_symbol_table *symbols;
142501e04c3fSmrg      exec_list *instructions;
142601e04c3fSmrg      hash_table *temps;
142701e04c3fSmrg   };
142801e04c3fSmrg
142901e04c3fSmrg   remap_visitor v(target, temps);
143001e04c3fSmrg
143101e04c3fSmrg   inst->accept(&v);
143201e04c3fSmrg}
143301e04c3fSmrg
143401e04c3fSmrg
143501e04c3fSmrg/**
143601e04c3fSmrg * Move non-declarations from one instruction stream to another
143701e04c3fSmrg *
143801e04c3fSmrg * The intended usage pattern of this function is to pass the pointer to the
143901e04c3fSmrg * head sentinel of a list (i.e., a pointer to the list cast to an \c exec_node
144001e04c3fSmrg * pointer) for \c last and \c false for \c make_copies on the first
144101e04c3fSmrg * call.  Successive calls pass the return value of the previous call for
144201e04c3fSmrg * \c last and \c true for \c make_copies.
144301e04c3fSmrg *
144401e04c3fSmrg * \param instructions Source instruction stream
144501e04c3fSmrg * \param last         Instruction after which new instructions should be
144601e04c3fSmrg *                     inserted in the target instruction stream
144701e04c3fSmrg * \param make_copies  Flag selecting whether instructions in \c instructions
144801e04c3fSmrg *                     should be copied (via \c ir_instruction::clone) into the
144901e04c3fSmrg *                     target list or moved.
145001e04c3fSmrg *
145101e04c3fSmrg * \return
145201e04c3fSmrg * The new "last" instruction in the target instruction stream.  This pointer
145301e04c3fSmrg * is suitable for use as the \c last parameter of a later call to this
145401e04c3fSmrg * function.
145501e04c3fSmrg */
145601e04c3fSmrgstatic exec_node *
145701e04c3fSmrgmove_non_declarations(exec_list *instructions, exec_node *last,
145801e04c3fSmrg                      bool make_copies, gl_linked_shader *target)
145901e04c3fSmrg{
146001e04c3fSmrg   hash_table *temps = NULL;
146101e04c3fSmrg
146201e04c3fSmrg   if (make_copies)
14637e102996Smaya      temps = _mesa_pointer_hash_table_create(NULL);
146401e04c3fSmrg
146501e04c3fSmrg   foreach_in_list_safe(ir_instruction, inst, instructions) {
146601e04c3fSmrg      if (inst->as_function())
146701e04c3fSmrg         continue;
146801e04c3fSmrg
146901e04c3fSmrg      ir_variable *var = inst->as_variable();
147001e04c3fSmrg      if ((var != NULL) && (var->data.mode != ir_var_temporary))
147101e04c3fSmrg         continue;
147201e04c3fSmrg
147301e04c3fSmrg      assert(inst->as_assignment()
147401e04c3fSmrg             || inst->as_call()
147501e04c3fSmrg             || inst->as_if() /* for initializers with the ?: operator */
147601e04c3fSmrg             || ((var != NULL) && (var->data.mode == ir_var_temporary)));
147701e04c3fSmrg
147801e04c3fSmrg      if (make_copies) {
147901e04c3fSmrg         inst = inst->clone(target, NULL);
148001e04c3fSmrg
148101e04c3fSmrg         if (var != NULL)
148201e04c3fSmrg            _mesa_hash_table_insert(temps, var, inst);
148301e04c3fSmrg         else
148401e04c3fSmrg            remap_variables(inst, target, temps);
148501e04c3fSmrg      } else {
148601e04c3fSmrg         inst->remove();
148701e04c3fSmrg      }
148801e04c3fSmrg
148901e04c3fSmrg      last->insert_after(inst);
149001e04c3fSmrg      last = inst;
149101e04c3fSmrg   }
149201e04c3fSmrg
149301e04c3fSmrg   if (make_copies)
149401e04c3fSmrg      _mesa_hash_table_destroy(temps, NULL);
149501e04c3fSmrg
149601e04c3fSmrg   return last;
149701e04c3fSmrg}
149801e04c3fSmrg
149901e04c3fSmrg
150001e04c3fSmrg/**
150101e04c3fSmrg * This class is only used in link_intrastage_shaders() below but declaring
150201e04c3fSmrg * it inside that function leads to compiler warnings with some versions of
150301e04c3fSmrg * gcc.
150401e04c3fSmrg */
150501e04c3fSmrgclass array_sizing_visitor : public deref_type_updater {
150601e04c3fSmrgpublic:
150701e04c3fSmrg   array_sizing_visitor()
150801e04c3fSmrg      : mem_ctx(ralloc_context(NULL)),
15097e102996Smaya        unnamed_interfaces(_mesa_pointer_hash_table_create(NULL))
151001e04c3fSmrg   {
151101e04c3fSmrg   }
151201e04c3fSmrg
151301e04c3fSmrg   ~array_sizing_visitor()
151401e04c3fSmrg   {
151501e04c3fSmrg      _mesa_hash_table_destroy(this->unnamed_interfaces, NULL);
151601e04c3fSmrg      ralloc_free(this->mem_ctx);
151701e04c3fSmrg   }
151801e04c3fSmrg
151901e04c3fSmrg   virtual ir_visitor_status visit(ir_variable *var)
152001e04c3fSmrg   {
152101e04c3fSmrg      const glsl_type *type_without_array;
152201e04c3fSmrg      bool implicit_sized_array = var->data.implicit_sized_array;
152301e04c3fSmrg      fixup_type(&var->type, var->data.max_array_access,
152401e04c3fSmrg                 var->data.from_ssbo_unsized_array,
152501e04c3fSmrg                 &implicit_sized_array);
152601e04c3fSmrg      var->data.implicit_sized_array = implicit_sized_array;
152701e04c3fSmrg      type_without_array = var->type->without_array();
152801e04c3fSmrg      if (var->type->is_interface()) {
152901e04c3fSmrg         if (interface_contains_unsized_arrays(var->type)) {
153001e04c3fSmrg            const glsl_type *new_type =
153101e04c3fSmrg               resize_interface_members(var->type,
153201e04c3fSmrg                                        var->get_max_ifc_array_access(),
153301e04c3fSmrg                                        var->is_in_shader_storage_block());
153401e04c3fSmrg            var->type = new_type;
153501e04c3fSmrg            var->change_interface_type(new_type);
153601e04c3fSmrg         }
153701e04c3fSmrg      } else if (type_without_array->is_interface()) {
153801e04c3fSmrg         if (interface_contains_unsized_arrays(type_without_array)) {
153901e04c3fSmrg            const glsl_type *new_type =
154001e04c3fSmrg               resize_interface_members(type_without_array,
154101e04c3fSmrg                                        var->get_max_ifc_array_access(),
154201e04c3fSmrg                                        var->is_in_shader_storage_block());
154301e04c3fSmrg            var->change_interface_type(new_type);
154401e04c3fSmrg            var->type = update_interface_members_array(var->type, new_type);
154501e04c3fSmrg         }
154601e04c3fSmrg      } else if (const glsl_type *ifc_type = var->get_interface_type()) {
154701e04c3fSmrg         /* Store a pointer to the variable in the unnamed_interfaces
154801e04c3fSmrg          * hashtable.
154901e04c3fSmrg          */
155001e04c3fSmrg         hash_entry *entry =
155101e04c3fSmrg               _mesa_hash_table_search(this->unnamed_interfaces,
155201e04c3fSmrg                                       ifc_type);
155301e04c3fSmrg
155401e04c3fSmrg         ir_variable **interface_vars = entry ? (ir_variable **) entry->data : NULL;
155501e04c3fSmrg
155601e04c3fSmrg         if (interface_vars == NULL) {
155701e04c3fSmrg            interface_vars = rzalloc_array(mem_ctx, ir_variable *,
155801e04c3fSmrg                                           ifc_type->length);
155901e04c3fSmrg            _mesa_hash_table_insert(this->unnamed_interfaces, ifc_type,
156001e04c3fSmrg                                    interface_vars);
156101e04c3fSmrg         }
156201e04c3fSmrg         unsigned index = ifc_type->field_index(var->name);
156301e04c3fSmrg         assert(index < ifc_type->length);
156401e04c3fSmrg         assert(interface_vars[index] == NULL);
156501e04c3fSmrg         interface_vars[index] = var;
156601e04c3fSmrg      }
156701e04c3fSmrg      return visit_continue;
156801e04c3fSmrg   }
156901e04c3fSmrg
157001e04c3fSmrg   /**
157101e04c3fSmrg    * For each unnamed interface block that was discovered while running the
157201e04c3fSmrg    * visitor, adjust the interface type to reflect the newly assigned array
157301e04c3fSmrg    * sizes, and fix up the ir_variable nodes to point to the new interface
157401e04c3fSmrg    * type.
157501e04c3fSmrg    */
157601e04c3fSmrg   void fixup_unnamed_interface_types()
157701e04c3fSmrg   {
157801e04c3fSmrg      hash_table_call_foreach(this->unnamed_interfaces,
157901e04c3fSmrg                              fixup_unnamed_interface_type, NULL);
158001e04c3fSmrg   }
158101e04c3fSmrg
158201e04c3fSmrgprivate:
158301e04c3fSmrg   /**
158401e04c3fSmrg    * If the type pointed to by \c type represents an unsized array, replace
158501e04c3fSmrg    * it with a sized array whose size is determined by max_array_access.
158601e04c3fSmrg    */
158701e04c3fSmrg   static void fixup_type(const glsl_type **type, unsigned max_array_access,
158801e04c3fSmrg                          bool from_ssbo_unsized_array, bool *implicit_sized)
158901e04c3fSmrg   {
159001e04c3fSmrg      if (!from_ssbo_unsized_array && (*type)->is_unsized_array()) {
159101e04c3fSmrg         *type = glsl_type::get_array_instance((*type)->fields.array,
159201e04c3fSmrg                                               max_array_access + 1);
159301e04c3fSmrg         *implicit_sized = true;
159401e04c3fSmrg         assert(*type != NULL);
159501e04c3fSmrg      }
159601e04c3fSmrg   }
159701e04c3fSmrg
159801e04c3fSmrg   static const glsl_type *
159901e04c3fSmrg   update_interface_members_array(const glsl_type *type,
160001e04c3fSmrg                                  const glsl_type *new_interface_type)
160101e04c3fSmrg   {
160201e04c3fSmrg      const glsl_type *element_type = type->fields.array;
160301e04c3fSmrg      if (element_type->is_array()) {
160401e04c3fSmrg         const glsl_type *new_array_type =
160501e04c3fSmrg            update_interface_members_array(element_type, new_interface_type);
160601e04c3fSmrg         return glsl_type::get_array_instance(new_array_type, type->length);
160701e04c3fSmrg      } else {
160801e04c3fSmrg         return glsl_type::get_array_instance(new_interface_type,
160901e04c3fSmrg                                              type->length);
161001e04c3fSmrg      }
161101e04c3fSmrg   }
161201e04c3fSmrg
161301e04c3fSmrg   /**
161401e04c3fSmrg    * Determine whether the given interface type contains unsized arrays (if
161501e04c3fSmrg    * it doesn't, array_sizing_visitor doesn't need to process it).
161601e04c3fSmrg    */
161701e04c3fSmrg   static bool interface_contains_unsized_arrays(const glsl_type *type)
161801e04c3fSmrg   {
161901e04c3fSmrg      for (unsigned i = 0; i < type->length; i++) {
162001e04c3fSmrg         const glsl_type *elem_type = type->fields.structure[i].type;
162101e04c3fSmrg         if (elem_type->is_unsized_array())
162201e04c3fSmrg            return true;
162301e04c3fSmrg      }
162401e04c3fSmrg      return false;
162501e04c3fSmrg   }
162601e04c3fSmrg
162701e04c3fSmrg   /**
162801e04c3fSmrg    * Create a new interface type based on the given type, with unsized arrays
162901e04c3fSmrg    * replaced by sized arrays whose size is determined by
163001e04c3fSmrg    * max_ifc_array_access.
163101e04c3fSmrg    */
163201e04c3fSmrg   static const glsl_type *
163301e04c3fSmrg   resize_interface_members(const glsl_type *type,
163401e04c3fSmrg                            const int *max_ifc_array_access,
163501e04c3fSmrg                            bool is_ssbo)
163601e04c3fSmrg   {
163701e04c3fSmrg      unsigned num_fields = type->length;
163801e04c3fSmrg      glsl_struct_field *fields = new glsl_struct_field[num_fields];
163901e04c3fSmrg      memcpy(fields, type->fields.structure,
164001e04c3fSmrg             num_fields * sizeof(*fields));
164101e04c3fSmrg      for (unsigned i = 0; i < num_fields; i++) {
164201e04c3fSmrg         bool implicit_sized_array = fields[i].implicit_sized_array;
164301e04c3fSmrg         /* If SSBO last member is unsized array, we don't replace it by a sized
164401e04c3fSmrg          * array.
164501e04c3fSmrg          */
164601e04c3fSmrg         if (is_ssbo && i == (num_fields - 1))
164701e04c3fSmrg            fixup_type(&fields[i].type, max_ifc_array_access[i],
164801e04c3fSmrg                       true, &implicit_sized_array);
164901e04c3fSmrg         else
165001e04c3fSmrg            fixup_type(&fields[i].type, max_ifc_array_access[i],
165101e04c3fSmrg                       false, &implicit_sized_array);
165201e04c3fSmrg         fields[i].implicit_sized_array = implicit_sized_array;
165301e04c3fSmrg      }
165401e04c3fSmrg      glsl_interface_packing packing =
165501e04c3fSmrg         (glsl_interface_packing) type->interface_packing;
165601e04c3fSmrg      bool row_major = (bool) type->interface_row_major;
165701e04c3fSmrg      const glsl_type *new_ifc_type =
165801e04c3fSmrg         glsl_type::get_interface_instance(fields, num_fields,
165901e04c3fSmrg                                           packing, row_major, type->name);
166001e04c3fSmrg      delete [] fields;
166101e04c3fSmrg      return new_ifc_type;
166201e04c3fSmrg   }
166301e04c3fSmrg
166401e04c3fSmrg   static void fixup_unnamed_interface_type(const void *key, void *data,
166501e04c3fSmrg                                            void *)
166601e04c3fSmrg   {
166701e04c3fSmrg      const glsl_type *ifc_type = (const glsl_type *) key;
166801e04c3fSmrg      ir_variable **interface_vars = (ir_variable **) data;
166901e04c3fSmrg      unsigned num_fields = ifc_type->length;
167001e04c3fSmrg      glsl_struct_field *fields = new glsl_struct_field[num_fields];
167101e04c3fSmrg      memcpy(fields, ifc_type->fields.structure,
167201e04c3fSmrg             num_fields * sizeof(*fields));
167301e04c3fSmrg      bool interface_type_changed = false;
167401e04c3fSmrg      for (unsigned i = 0; i < num_fields; i++) {
167501e04c3fSmrg         if (interface_vars[i] != NULL &&
167601e04c3fSmrg             fields[i].type != interface_vars[i]->type) {
167701e04c3fSmrg            fields[i].type = interface_vars[i]->type;
167801e04c3fSmrg            interface_type_changed = true;
167901e04c3fSmrg         }
168001e04c3fSmrg      }
168101e04c3fSmrg      if (!interface_type_changed) {
168201e04c3fSmrg         delete [] fields;
168301e04c3fSmrg         return;
168401e04c3fSmrg      }
168501e04c3fSmrg      glsl_interface_packing packing =
168601e04c3fSmrg         (glsl_interface_packing) ifc_type->interface_packing;
168701e04c3fSmrg      bool row_major = (bool) ifc_type->interface_row_major;
168801e04c3fSmrg      const glsl_type *new_ifc_type =
168901e04c3fSmrg         glsl_type::get_interface_instance(fields, num_fields, packing,
169001e04c3fSmrg                                           row_major, ifc_type->name);
169101e04c3fSmrg      delete [] fields;
169201e04c3fSmrg      for (unsigned i = 0; i < num_fields; i++) {
169301e04c3fSmrg         if (interface_vars[i] != NULL)
169401e04c3fSmrg            interface_vars[i]->change_interface_type(new_ifc_type);
169501e04c3fSmrg      }
169601e04c3fSmrg   }
169701e04c3fSmrg
169801e04c3fSmrg   /**
169901e04c3fSmrg    * Memory context used to allocate the data in \c unnamed_interfaces.
170001e04c3fSmrg    */
170101e04c3fSmrg   void *mem_ctx;
170201e04c3fSmrg
170301e04c3fSmrg   /**
170401e04c3fSmrg    * Hash table from const glsl_type * to an array of ir_variable *'s
170501e04c3fSmrg    * pointing to the ir_variables constituting each unnamed interface block.
170601e04c3fSmrg    */
170701e04c3fSmrg   hash_table *unnamed_interfaces;
170801e04c3fSmrg};
170901e04c3fSmrg
171001e04c3fSmrgstatic bool
171101e04c3fSmrgvalidate_xfb_buffer_stride(struct gl_context *ctx, unsigned idx,
171201e04c3fSmrg                           struct gl_shader_program *prog)
171301e04c3fSmrg{
171401e04c3fSmrg   /* We will validate doubles at a later stage */
171501e04c3fSmrg   if (prog->TransformFeedback.BufferStride[idx] % 4) {
171601e04c3fSmrg      linker_error(prog, "invalid qualifier xfb_stride=%d must be a "
171701e04c3fSmrg                   "multiple of 4 or if its applied to a type that is "
171801e04c3fSmrg                   "or contains a double a multiple of 8.",
171901e04c3fSmrg                   prog->TransformFeedback.BufferStride[idx]);
172001e04c3fSmrg      return false;
172101e04c3fSmrg   }
172201e04c3fSmrg
172301e04c3fSmrg   if (prog->TransformFeedback.BufferStride[idx] / 4 >
172401e04c3fSmrg       ctx->Const.MaxTransformFeedbackInterleavedComponents) {
172501e04c3fSmrg      linker_error(prog, "The MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS "
172601e04c3fSmrg                   "limit has been exceeded.");
172701e04c3fSmrg      return false;
172801e04c3fSmrg   }
172901e04c3fSmrg
173001e04c3fSmrg   return true;
173101e04c3fSmrg}
173201e04c3fSmrg
173301e04c3fSmrg/**
173401e04c3fSmrg * Check for conflicting xfb_stride default qualifiers and store buffer stride
173501e04c3fSmrg * for later use.
173601e04c3fSmrg */
173701e04c3fSmrgstatic void
173801e04c3fSmrglink_xfb_stride_layout_qualifiers(struct gl_context *ctx,
173901e04c3fSmrg                                  struct gl_shader_program *prog,
174001e04c3fSmrg                                  struct gl_shader **shader_list,
174101e04c3fSmrg                                  unsigned num_shaders)
174201e04c3fSmrg{
174301e04c3fSmrg   for (unsigned i = 0; i < MAX_FEEDBACK_BUFFERS; i++) {
174401e04c3fSmrg      prog->TransformFeedback.BufferStride[i] = 0;
174501e04c3fSmrg   }
174601e04c3fSmrg
174701e04c3fSmrg   for (unsigned i = 0; i < num_shaders; i++) {
174801e04c3fSmrg      struct gl_shader *shader = shader_list[i];
174901e04c3fSmrg
175001e04c3fSmrg      for (unsigned j = 0; j < MAX_FEEDBACK_BUFFERS; j++) {
175101e04c3fSmrg         if (shader->TransformFeedbackBufferStride[j]) {
175201e04c3fSmrg            if (prog->TransformFeedback.BufferStride[j] == 0) {
175301e04c3fSmrg               prog->TransformFeedback.BufferStride[j] =
175401e04c3fSmrg                  shader->TransformFeedbackBufferStride[j];
175501e04c3fSmrg               if (!validate_xfb_buffer_stride(ctx, j, prog))
175601e04c3fSmrg                  return;
175701e04c3fSmrg            } else if (prog->TransformFeedback.BufferStride[j] !=
175801e04c3fSmrg                       shader->TransformFeedbackBufferStride[j]){
175901e04c3fSmrg               linker_error(prog,
176001e04c3fSmrg                            "intrastage shaders defined with conflicting "
176101e04c3fSmrg                            "xfb_stride for buffer %d (%d and %d)\n", j,
176201e04c3fSmrg                            prog->TransformFeedback.BufferStride[j],
176301e04c3fSmrg                            shader->TransformFeedbackBufferStride[j]);
176401e04c3fSmrg               return;
176501e04c3fSmrg            }
176601e04c3fSmrg         }
176701e04c3fSmrg      }
176801e04c3fSmrg   }
176901e04c3fSmrg}
177001e04c3fSmrg
177101e04c3fSmrg/**
177201e04c3fSmrg * Check for conflicting bindless/bound sampler/image layout qualifiers at
177301e04c3fSmrg * global scope.
177401e04c3fSmrg */
177501e04c3fSmrgstatic void
177601e04c3fSmrglink_bindless_layout_qualifiers(struct gl_shader_program *prog,
177701e04c3fSmrg                                struct gl_shader **shader_list,
177801e04c3fSmrg                                unsigned num_shaders)
177901e04c3fSmrg{
178001e04c3fSmrg   bool bindless_sampler, bindless_image;
178101e04c3fSmrg   bool bound_sampler, bound_image;
178201e04c3fSmrg
178301e04c3fSmrg   bindless_sampler = bindless_image = false;
178401e04c3fSmrg   bound_sampler = bound_image = false;
178501e04c3fSmrg
178601e04c3fSmrg   for (unsigned i = 0; i < num_shaders; i++) {
178701e04c3fSmrg      struct gl_shader *shader = shader_list[i];
178801e04c3fSmrg
178901e04c3fSmrg      if (shader->bindless_sampler)
179001e04c3fSmrg         bindless_sampler = true;
179101e04c3fSmrg      if (shader->bindless_image)
179201e04c3fSmrg         bindless_image = true;
179301e04c3fSmrg      if (shader->bound_sampler)
179401e04c3fSmrg         bound_sampler = true;
179501e04c3fSmrg      if (shader->bound_image)
179601e04c3fSmrg         bound_image = true;
179701e04c3fSmrg
179801e04c3fSmrg      if ((bindless_sampler && bound_sampler) ||
179901e04c3fSmrg          (bindless_image && bound_image)) {
180001e04c3fSmrg         /* From section 4.4.6 of the ARB_bindless_texture spec:
180101e04c3fSmrg          *
180201e04c3fSmrg          *     "If both bindless_sampler and bound_sampler, or bindless_image
180301e04c3fSmrg          *      and bound_image, are declared at global scope in any
180401e04c3fSmrg          *      compilation unit, a link- time error will be generated."
180501e04c3fSmrg          */
180601e04c3fSmrg         linker_error(prog, "both bindless_sampler and bound_sampler, or "
180701e04c3fSmrg                      "bindless_image and bound_image, can't be declared at "
180801e04c3fSmrg                      "global scope");
180901e04c3fSmrg      }
181001e04c3fSmrg   }
181101e04c3fSmrg}
181201e04c3fSmrg
181301e04c3fSmrg/**
181401e04c3fSmrg * Performs the cross-validation of tessellation control shader vertices and
181501e04c3fSmrg * layout qualifiers for the attached tessellation control shaders,
181601e04c3fSmrg * and propagates them to the linked TCS and linked shader program.
181701e04c3fSmrg */
181801e04c3fSmrgstatic void
181901e04c3fSmrglink_tcs_out_layout_qualifiers(struct gl_shader_program *prog,
182001e04c3fSmrg                               struct gl_program *gl_prog,
182101e04c3fSmrg                               struct gl_shader **shader_list,
182201e04c3fSmrg                               unsigned num_shaders)
182301e04c3fSmrg{
182401e04c3fSmrg   if (gl_prog->info.stage != MESA_SHADER_TESS_CTRL)
182501e04c3fSmrg      return;
182601e04c3fSmrg
182701e04c3fSmrg   gl_prog->info.tess.tcs_vertices_out = 0;
182801e04c3fSmrg
182901e04c3fSmrg   /* From the GLSL 4.0 spec (chapter 4.3.8.2):
183001e04c3fSmrg    *
183101e04c3fSmrg    *     "All tessellation control shader layout declarations in a program
183201e04c3fSmrg    *      must specify the same output patch vertex count.  There must be at
183301e04c3fSmrg    *      least one layout qualifier specifying an output patch vertex count
183401e04c3fSmrg    *      in any program containing tessellation control shaders; however,
183501e04c3fSmrg    *      such a declaration is not required in all tessellation control
183601e04c3fSmrg    *      shaders."
183701e04c3fSmrg    */
183801e04c3fSmrg
183901e04c3fSmrg   for (unsigned i = 0; i < num_shaders; i++) {
184001e04c3fSmrg      struct gl_shader *shader = shader_list[i];
184101e04c3fSmrg
184201e04c3fSmrg      if (shader->info.TessCtrl.VerticesOut != 0) {
184301e04c3fSmrg         if (gl_prog->info.tess.tcs_vertices_out != 0 &&
184401e04c3fSmrg             gl_prog->info.tess.tcs_vertices_out !=
184501e04c3fSmrg             (unsigned) shader->info.TessCtrl.VerticesOut) {
184601e04c3fSmrg            linker_error(prog, "tessellation control shader defined with "
184701e04c3fSmrg                         "conflicting output vertex count (%d and %d)\n",
184801e04c3fSmrg                         gl_prog->info.tess.tcs_vertices_out,
184901e04c3fSmrg                         shader->info.TessCtrl.VerticesOut);
185001e04c3fSmrg            return;
185101e04c3fSmrg         }
185201e04c3fSmrg         gl_prog->info.tess.tcs_vertices_out =
185301e04c3fSmrg            shader->info.TessCtrl.VerticesOut;
185401e04c3fSmrg      }
185501e04c3fSmrg   }
185601e04c3fSmrg
185701e04c3fSmrg   /* Just do the intrastage -> interstage propagation right now,
185801e04c3fSmrg    * since we already know we're in the right type of shader program
185901e04c3fSmrg    * for doing it.
186001e04c3fSmrg    */
186101e04c3fSmrg   if (gl_prog->info.tess.tcs_vertices_out == 0) {
186201e04c3fSmrg      linker_error(prog, "tessellation control shader didn't declare "
186301e04c3fSmrg                   "vertices out layout qualifier\n");
186401e04c3fSmrg      return;
186501e04c3fSmrg   }
186601e04c3fSmrg}
186701e04c3fSmrg
186801e04c3fSmrg
186901e04c3fSmrg/**
187001e04c3fSmrg * Performs the cross-validation of tessellation evaluation shader
187101e04c3fSmrg * primitive type, vertex spacing, ordering and point_mode layout qualifiers
187201e04c3fSmrg * for the attached tessellation evaluation shaders, and propagates them
187301e04c3fSmrg * to the linked TES and linked shader program.
187401e04c3fSmrg */
187501e04c3fSmrgstatic void
187601e04c3fSmrglink_tes_in_layout_qualifiers(struct gl_shader_program *prog,
187701e04c3fSmrg                              struct gl_program *gl_prog,
187801e04c3fSmrg                              struct gl_shader **shader_list,
187901e04c3fSmrg                              unsigned num_shaders)
188001e04c3fSmrg{
188101e04c3fSmrg   if (gl_prog->info.stage != MESA_SHADER_TESS_EVAL)
188201e04c3fSmrg      return;
188301e04c3fSmrg
188401e04c3fSmrg   int point_mode = -1;
188501e04c3fSmrg   unsigned vertex_order = 0;
188601e04c3fSmrg
188701e04c3fSmrg   gl_prog->info.tess.primitive_mode = PRIM_UNKNOWN;
188801e04c3fSmrg   gl_prog->info.tess.spacing = TESS_SPACING_UNSPECIFIED;
188901e04c3fSmrg
189001e04c3fSmrg   /* From the GLSL 4.0 spec (chapter 4.3.8.1):
189101e04c3fSmrg    *
189201e04c3fSmrg    *     "At least one tessellation evaluation shader (compilation unit) in
189301e04c3fSmrg    *      a program must declare a primitive mode in its input layout.
189401e04c3fSmrg    *      Declaration vertex spacing, ordering, and point mode identifiers is
189501e04c3fSmrg    *      optional.  It is not required that all tessellation evaluation
189601e04c3fSmrg    *      shaders in a program declare a primitive mode.  If spacing or
189701e04c3fSmrg    *      vertex ordering declarations are omitted, the tessellation
189801e04c3fSmrg    *      primitive generator will use equal spacing or counter-clockwise
189901e04c3fSmrg    *      vertex ordering, respectively.  If a point mode declaration is
190001e04c3fSmrg    *      omitted, the tessellation primitive generator will produce lines or
190101e04c3fSmrg    *      triangles according to the primitive mode."
190201e04c3fSmrg    */
190301e04c3fSmrg
190401e04c3fSmrg   for (unsigned i = 0; i < num_shaders; i++) {
190501e04c3fSmrg      struct gl_shader *shader = shader_list[i];
190601e04c3fSmrg
190701e04c3fSmrg      if (shader->info.TessEval.PrimitiveMode != PRIM_UNKNOWN) {
190801e04c3fSmrg         if (gl_prog->info.tess.primitive_mode != PRIM_UNKNOWN &&
190901e04c3fSmrg             gl_prog->info.tess.primitive_mode !=
191001e04c3fSmrg             shader->info.TessEval.PrimitiveMode) {
191101e04c3fSmrg            linker_error(prog, "tessellation evaluation shader defined with "
191201e04c3fSmrg                         "conflicting input primitive modes.\n");
191301e04c3fSmrg            return;
191401e04c3fSmrg         }
191501e04c3fSmrg         gl_prog->info.tess.primitive_mode =
191601e04c3fSmrg            shader->info.TessEval.PrimitiveMode;
191701e04c3fSmrg      }
191801e04c3fSmrg
191901e04c3fSmrg      if (shader->info.TessEval.Spacing != 0) {
192001e04c3fSmrg         if (gl_prog->info.tess.spacing != 0 && gl_prog->info.tess.spacing !=
192101e04c3fSmrg             shader->info.TessEval.Spacing) {
192201e04c3fSmrg            linker_error(prog, "tessellation evaluation shader defined with "
192301e04c3fSmrg                         "conflicting vertex spacing.\n");
192401e04c3fSmrg            return;
192501e04c3fSmrg         }
192601e04c3fSmrg         gl_prog->info.tess.spacing = shader->info.TessEval.Spacing;
192701e04c3fSmrg      }
192801e04c3fSmrg
192901e04c3fSmrg      if (shader->info.TessEval.VertexOrder != 0) {
193001e04c3fSmrg         if (vertex_order != 0 &&
193101e04c3fSmrg             vertex_order != shader->info.TessEval.VertexOrder) {
193201e04c3fSmrg            linker_error(prog, "tessellation evaluation shader defined with "
193301e04c3fSmrg                         "conflicting ordering.\n");
193401e04c3fSmrg            return;
193501e04c3fSmrg         }
193601e04c3fSmrg         vertex_order = shader->info.TessEval.VertexOrder;
193701e04c3fSmrg      }
193801e04c3fSmrg
193901e04c3fSmrg      if (shader->info.TessEval.PointMode != -1) {
194001e04c3fSmrg         if (point_mode != -1 &&
194101e04c3fSmrg             point_mode != shader->info.TessEval.PointMode) {
194201e04c3fSmrg            linker_error(prog, "tessellation evaluation shader defined with "
194301e04c3fSmrg                         "conflicting point modes.\n");
194401e04c3fSmrg            return;
194501e04c3fSmrg         }
194601e04c3fSmrg         point_mode = shader->info.TessEval.PointMode;
194701e04c3fSmrg      }
194801e04c3fSmrg
194901e04c3fSmrg   }
195001e04c3fSmrg
195101e04c3fSmrg   /* Just do the intrastage -> interstage propagation right now,
195201e04c3fSmrg    * since we already know we're in the right type of shader program
195301e04c3fSmrg    * for doing it.
195401e04c3fSmrg    */
195501e04c3fSmrg   if (gl_prog->info.tess.primitive_mode == PRIM_UNKNOWN) {
195601e04c3fSmrg      linker_error(prog,
195701e04c3fSmrg                   "tessellation evaluation shader didn't declare input "
195801e04c3fSmrg                   "primitive modes.\n");
195901e04c3fSmrg      return;
196001e04c3fSmrg   }
196101e04c3fSmrg
196201e04c3fSmrg   if (gl_prog->info.tess.spacing == TESS_SPACING_UNSPECIFIED)
196301e04c3fSmrg      gl_prog->info.tess.spacing = TESS_SPACING_EQUAL;
196401e04c3fSmrg
196501e04c3fSmrg   if (vertex_order == 0 || vertex_order == GL_CCW)
196601e04c3fSmrg      gl_prog->info.tess.ccw = true;
196701e04c3fSmrg   else
196801e04c3fSmrg      gl_prog->info.tess.ccw = false;
196901e04c3fSmrg
197001e04c3fSmrg
197101e04c3fSmrg   if (point_mode == -1 || point_mode == GL_FALSE)
197201e04c3fSmrg      gl_prog->info.tess.point_mode = false;
197301e04c3fSmrg   else
197401e04c3fSmrg      gl_prog->info.tess.point_mode = true;
197501e04c3fSmrg}
197601e04c3fSmrg
197701e04c3fSmrg
197801e04c3fSmrg/**
197901e04c3fSmrg * Performs the cross-validation of layout qualifiers specified in
198001e04c3fSmrg * redeclaration of gl_FragCoord for the attached fragment shaders,
198101e04c3fSmrg * and propagates them to the linked FS and linked shader program.
198201e04c3fSmrg */
198301e04c3fSmrgstatic void
198401e04c3fSmrglink_fs_inout_layout_qualifiers(struct gl_shader_program *prog,
198501e04c3fSmrg                                struct gl_linked_shader *linked_shader,
198601e04c3fSmrg                                struct gl_shader **shader_list,
198701e04c3fSmrg                                unsigned num_shaders)
198801e04c3fSmrg{
198901e04c3fSmrg   bool redeclares_gl_fragcoord = false;
199001e04c3fSmrg   bool uses_gl_fragcoord = false;
199101e04c3fSmrg   bool origin_upper_left = false;
199201e04c3fSmrg   bool pixel_center_integer = false;
199301e04c3fSmrg
199401e04c3fSmrg   if (linked_shader->Stage != MESA_SHADER_FRAGMENT ||
199501e04c3fSmrg       (prog->data->Version < 150 &&
199601e04c3fSmrg        !prog->ARB_fragment_coord_conventions_enable))
199701e04c3fSmrg      return;
199801e04c3fSmrg
199901e04c3fSmrg   for (unsigned i = 0; i < num_shaders; i++) {
200001e04c3fSmrg      struct gl_shader *shader = shader_list[i];
200101e04c3fSmrg      /* From the GLSL 1.50 spec, page 39:
200201e04c3fSmrg       *
200301e04c3fSmrg       *   "If gl_FragCoord is redeclared in any fragment shader in a program,
200401e04c3fSmrg       *    it must be redeclared in all the fragment shaders in that program
200501e04c3fSmrg       *    that have a static use gl_FragCoord."
200601e04c3fSmrg       */
200701e04c3fSmrg      if ((redeclares_gl_fragcoord && !shader->redeclares_gl_fragcoord &&
200801e04c3fSmrg           shader->uses_gl_fragcoord)
200901e04c3fSmrg          || (shader->redeclares_gl_fragcoord && !redeclares_gl_fragcoord &&
201001e04c3fSmrg              uses_gl_fragcoord)) {
201101e04c3fSmrg             linker_error(prog, "fragment shader defined with conflicting "
201201e04c3fSmrg                         "layout qualifiers for gl_FragCoord\n");
201301e04c3fSmrg      }
201401e04c3fSmrg
201501e04c3fSmrg      /* From the GLSL 1.50 spec, page 39:
201601e04c3fSmrg       *
201701e04c3fSmrg       *   "All redeclarations of gl_FragCoord in all fragment shaders in a
201801e04c3fSmrg       *    single program must have the same set of qualifiers."
201901e04c3fSmrg       */
202001e04c3fSmrg      if (redeclares_gl_fragcoord && shader->redeclares_gl_fragcoord &&
202101e04c3fSmrg          (shader->origin_upper_left != origin_upper_left ||
202201e04c3fSmrg           shader->pixel_center_integer != pixel_center_integer)) {
202301e04c3fSmrg         linker_error(prog, "fragment shader defined with conflicting "
202401e04c3fSmrg                      "layout qualifiers for gl_FragCoord\n");
202501e04c3fSmrg      }
202601e04c3fSmrg
202701e04c3fSmrg      /* Update the linked shader state.  Note that uses_gl_fragcoord should
202801e04c3fSmrg       * accumulate the results.  The other values should replace.  If there
202901e04c3fSmrg       * are multiple redeclarations, all the fields except uses_gl_fragcoord
203001e04c3fSmrg       * are already known to be the same.
203101e04c3fSmrg       */
203201e04c3fSmrg      if (shader->redeclares_gl_fragcoord || shader->uses_gl_fragcoord) {
203301e04c3fSmrg         redeclares_gl_fragcoord = shader->redeclares_gl_fragcoord;
203401e04c3fSmrg         uses_gl_fragcoord |= shader->uses_gl_fragcoord;
203501e04c3fSmrg         origin_upper_left = shader->origin_upper_left;
203601e04c3fSmrg         pixel_center_integer = shader->pixel_center_integer;
203701e04c3fSmrg      }
203801e04c3fSmrg
203901e04c3fSmrg      linked_shader->Program->info.fs.early_fragment_tests |=
204001e04c3fSmrg         shader->EarlyFragmentTests || shader->PostDepthCoverage;
204101e04c3fSmrg      linked_shader->Program->info.fs.inner_coverage |= shader->InnerCoverage;
204201e04c3fSmrg      linked_shader->Program->info.fs.post_depth_coverage |=
204301e04c3fSmrg         shader->PostDepthCoverage;
204401e04c3fSmrg      linked_shader->Program->info.fs.pixel_interlock_ordered |=
204501e04c3fSmrg         shader->PixelInterlockOrdered;
204601e04c3fSmrg      linked_shader->Program->info.fs.pixel_interlock_unordered |=
204701e04c3fSmrg         shader->PixelInterlockUnordered;
204801e04c3fSmrg      linked_shader->Program->info.fs.sample_interlock_ordered |=
204901e04c3fSmrg         shader->SampleInterlockOrdered;
205001e04c3fSmrg      linked_shader->Program->info.fs.sample_interlock_unordered |=
205101e04c3fSmrg         shader->SampleInterlockUnordered;
205201e04c3fSmrg      linked_shader->Program->sh.fs.BlendSupport |= shader->BlendSupport;
205301e04c3fSmrg   }
20547e102996Smaya
20557e102996Smaya   linked_shader->Program->info.fs.pixel_center_integer = pixel_center_integer;
20567e102996Smaya   linked_shader->Program->info.fs.origin_upper_left = origin_upper_left;
205701e04c3fSmrg}
205801e04c3fSmrg
205901e04c3fSmrg/**
206001e04c3fSmrg * Performs the cross-validation of geometry shader max_vertices and
206101e04c3fSmrg * primitive type layout qualifiers for the attached geometry shaders,
206201e04c3fSmrg * and propagates them to the linked GS and linked shader program.
206301e04c3fSmrg */
206401e04c3fSmrgstatic void
206501e04c3fSmrglink_gs_inout_layout_qualifiers(struct gl_shader_program *prog,
206601e04c3fSmrg                                struct gl_program *gl_prog,
206701e04c3fSmrg                                struct gl_shader **shader_list,
206801e04c3fSmrg                                unsigned num_shaders)
206901e04c3fSmrg{
207001e04c3fSmrg   /* No in/out qualifiers defined for anything but GLSL 1.50+
207101e04c3fSmrg    * geometry shaders so far.
207201e04c3fSmrg    */
207301e04c3fSmrg   if (gl_prog->info.stage != MESA_SHADER_GEOMETRY ||
207401e04c3fSmrg       prog->data->Version < 150)
207501e04c3fSmrg      return;
207601e04c3fSmrg
207701e04c3fSmrg   int vertices_out = -1;
207801e04c3fSmrg
207901e04c3fSmrg   gl_prog->info.gs.invocations = 0;
208001e04c3fSmrg   gl_prog->info.gs.input_primitive = PRIM_UNKNOWN;
208101e04c3fSmrg   gl_prog->info.gs.output_primitive = PRIM_UNKNOWN;
208201e04c3fSmrg
208301e04c3fSmrg   /* From the GLSL 1.50 spec, page 46:
208401e04c3fSmrg    *
208501e04c3fSmrg    *     "All geometry shader output layout declarations in a program
208601e04c3fSmrg    *      must declare the same layout and same value for
208701e04c3fSmrg    *      max_vertices. There must be at least one geometry output
208801e04c3fSmrg    *      layout declaration somewhere in a program, but not all
208901e04c3fSmrg    *      geometry shaders (compilation units) are required to
209001e04c3fSmrg    *      declare it."
209101e04c3fSmrg    */
209201e04c3fSmrg
209301e04c3fSmrg   for (unsigned i = 0; i < num_shaders; i++) {
209401e04c3fSmrg      struct gl_shader *shader = shader_list[i];
209501e04c3fSmrg
209601e04c3fSmrg      if (shader->info.Geom.InputType != PRIM_UNKNOWN) {
209701e04c3fSmrg         if (gl_prog->info.gs.input_primitive != PRIM_UNKNOWN &&
209801e04c3fSmrg             gl_prog->info.gs.input_primitive !=
209901e04c3fSmrg             shader->info.Geom.InputType) {
210001e04c3fSmrg            linker_error(prog, "geometry shader defined with conflicting "
210101e04c3fSmrg                         "input types\n");
210201e04c3fSmrg            return;
210301e04c3fSmrg         }
210401e04c3fSmrg         gl_prog->info.gs.input_primitive = shader->info.Geom.InputType;
210501e04c3fSmrg      }
210601e04c3fSmrg
210701e04c3fSmrg      if (shader->info.Geom.OutputType != PRIM_UNKNOWN) {
210801e04c3fSmrg         if (gl_prog->info.gs.output_primitive != PRIM_UNKNOWN &&
210901e04c3fSmrg             gl_prog->info.gs.output_primitive !=
211001e04c3fSmrg             shader->info.Geom.OutputType) {
211101e04c3fSmrg            linker_error(prog, "geometry shader defined with conflicting "
211201e04c3fSmrg                         "output types\n");
211301e04c3fSmrg            return;
211401e04c3fSmrg         }
211501e04c3fSmrg         gl_prog->info.gs.output_primitive = shader->info.Geom.OutputType;
211601e04c3fSmrg      }
211701e04c3fSmrg
211801e04c3fSmrg      if (shader->info.Geom.VerticesOut != -1) {
211901e04c3fSmrg         if (vertices_out != -1 &&
212001e04c3fSmrg             vertices_out != shader->info.Geom.VerticesOut) {
212101e04c3fSmrg            linker_error(prog, "geometry shader defined with conflicting "
212201e04c3fSmrg                         "output vertex count (%d and %d)\n",
212301e04c3fSmrg                         vertices_out, shader->info.Geom.VerticesOut);
212401e04c3fSmrg            return;
212501e04c3fSmrg         }
212601e04c3fSmrg         vertices_out = shader->info.Geom.VerticesOut;
212701e04c3fSmrg      }
212801e04c3fSmrg
212901e04c3fSmrg      if (shader->info.Geom.Invocations != 0) {
213001e04c3fSmrg         if (gl_prog->info.gs.invocations != 0 &&
213101e04c3fSmrg             gl_prog->info.gs.invocations !=
213201e04c3fSmrg             (unsigned) shader->info.Geom.Invocations) {
213301e04c3fSmrg            linker_error(prog, "geometry shader defined with conflicting "
213401e04c3fSmrg                         "invocation count (%d and %d)\n",
213501e04c3fSmrg                         gl_prog->info.gs.invocations,
213601e04c3fSmrg                         shader->info.Geom.Invocations);
213701e04c3fSmrg            return;
213801e04c3fSmrg         }
213901e04c3fSmrg         gl_prog->info.gs.invocations = shader->info.Geom.Invocations;
214001e04c3fSmrg      }
214101e04c3fSmrg   }
214201e04c3fSmrg
214301e04c3fSmrg   /* Just do the intrastage -> interstage propagation right now,
214401e04c3fSmrg    * since we already know we're in the right type of shader program
214501e04c3fSmrg    * for doing it.
214601e04c3fSmrg    */
214701e04c3fSmrg   if (gl_prog->info.gs.input_primitive == PRIM_UNKNOWN) {
214801e04c3fSmrg      linker_error(prog,
214901e04c3fSmrg                   "geometry shader didn't declare primitive input type\n");
215001e04c3fSmrg      return;
215101e04c3fSmrg   }
215201e04c3fSmrg
215301e04c3fSmrg   if (gl_prog->info.gs.output_primitive == PRIM_UNKNOWN) {
215401e04c3fSmrg      linker_error(prog,
215501e04c3fSmrg                   "geometry shader didn't declare primitive output type\n");
215601e04c3fSmrg      return;
215701e04c3fSmrg   }
215801e04c3fSmrg
215901e04c3fSmrg   if (vertices_out == -1) {
216001e04c3fSmrg      linker_error(prog,
216101e04c3fSmrg                   "geometry shader didn't declare max_vertices\n");
216201e04c3fSmrg      return;
216301e04c3fSmrg   } else {
216401e04c3fSmrg      gl_prog->info.gs.vertices_out = vertices_out;
216501e04c3fSmrg   }
216601e04c3fSmrg
216701e04c3fSmrg   if (gl_prog->info.gs.invocations == 0)
216801e04c3fSmrg      gl_prog->info.gs.invocations = 1;
216901e04c3fSmrg}
217001e04c3fSmrg
217101e04c3fSmrg
217201e04c3fSmrg/**
21737e102996Smaya * Perform cross-validation of compute shader local_size_{x,y,z} layout and
21747e102996Smaya * derivative arrangement qualifiers for the attached compute shaders, and
21757e102996Smaya * propagate them to the linked CS and linked shader program.
217601e04c3fSmrg */
217701e04c3fSmrgstatic void
217801e04c3fSmrglink_cs_input_layout_qualifiers(struct gl_shader_program *prog,
217901e04c3fSmrg                                struct gl_program *gl_prog,
218001e04c3fSmrg                                struct gl_shader **shader_list,
218101e04c3fSmrg                                unsigned num_shaders)
218201e04c3fSmrg{
218301e04c3fSmrg   /* This function is called for all shader stages, but it only has an effect
218401e04c3fSmrg    * for compute shaders.
218501e04c3fSmrg    */
218601e04c3fSmrg   if (gl_prog->info.stage != MESA_SHADER_COMPUTE)
218701e04c3fSmrg      return;
218801e04c3fSmrg
218901e04c3fSmrg   for (int i = 0; i < 3; i++)
219001e04c3fSmrg      gl_prog->info.cs.local_size[i] = 0;
219101e04c3fSmrg
219201e04c3fSmrg   gl_prog->info.cs.local_size_variable = false;
219301e04c3fSmrg
21947e102996Smaya   gl_prog->info.cs.derivative_group = DERIVATIVE_GROUP_NONE;
21957e102996Smaya
219601e04c3fSmrg   /* From the ARB_compute_shader spec, in the section describing local size
219701e04c3fSmrg    * declarations:
219801e04c3fSmrg    *
219901e04c3fSmrg    *     If multiple compute shaders attached to a single program object
220001e04c3fSmrg    *     declare local work-group size, the declarations must be identical;
220101e04c3fSmrg    *     otherwise a link-time error results. Furthermore, if a program
220201e04c3fSmrg    *     object contains any compute shaders, at least one must contain an
220301e04c3fSmrg    *     input layout qualifier specifying the local work sizes of the
220401e04c3fSmrg    *     program, or a link-time error will occur.
220501e04c3fSmrg    */
220601e04c3fSmrg   for (unsigned sh = 0; sh < num_shaders; sh++) {
220701e04c3fSmrg      struct gl_shader *shader = shader_list[sh];
220801e04c3fSmrg
220901e04c3fSmrg      if (shader->info.Comp.LocalSize[0] != 0) {
221001e04c3fSmrg         if (gl_prog->info.cs.local_size[0] != 0) {
221101e04c3fSmrg            for (int i = 0; i < 3; i++) {
221201e04c3fSmrg               if (gl_prog->info.cs.local_size[i] !=
221301e04c3fSmrg                   shader->info.Comp.LocalSize[i]) {
221401e04c3fSmrg                  linker_error(prog, "compute shader defined with conflicting "
221501e04c3fSmrg                               "local sizes\n");
221601e04c3fSmrg                  return;
221701e04c3fSmrg               }
221801e04c3fSmrg            }
221901e04c3fSmrg         }
222001e04c3fSmrg         for (int i = 0; i < 3; i++) {
222101e04c3fSmrg            gl_prog->info.cs.local_size[i] =
222201e04c3fSmrg               shader->info.Comp.LocalSize[i];
222301e04c3fSmrg         }
222401e04c3fSmrg      } else if (shader->info.Comp.LocalSizeVariable) {
222501e04c3fSmrg         if (gl_prog->info.cs.local_size[0] != 0) {
222601e04c3fSmrg            /* The ARB_compute_variable_group_size spec says:
222701e04c3fSmrg             *
222801e04c3fSmrg             *     If one compute shader attached to a program declares a
222901e04c3fSmrg             *     variable local group size and a second compute shader
223001e04c3fSmrg             *     attached to the same program declares a fixed local group
223101e04c3fSmrg             *     size, a link-time error results.
223201e04c3fSmrg             */
223301e04c3fSmrg            linker_error(prog, "compute shader defined with both fixed and "
223401e04c3fSmrg                         "variable local group size\n");
223501e04c3fSmrg            return;
223601e04c3fSmrg         }
223701e04c3fSmrg         gl_prog->info.cs.local_size_variable = true;
223801e04c3fSmrg      }
22397e102996Smaya
22407e102996Smaya      enum gl_derivative_group group = shader->info.Comp.DerivativeGroup;
22417e102996Smaya      if (group != DERIVATIVE_GROUP_NONE) {
22427e102996Smaya         if (gl_prog->info.cs.derivative_group != DERIVATIVE_GROUP_NONE &&
22437e102996Smaya             gl_prog->info.cs.derivative_group != group) {
22447e102996Smaya            linker_error(prog, "compute shader defined with conflicting "
22457e102996Smaya                         "derivative groups\n");
22467e102996Smaya            return;
22477e102996Smaya         }
22487e102996Smaya         gl_prog->info.cs.derivative_group = group;
22497e102996Smaya      }
225001e04c3fSmrg   }
225101e04c3fSmrg
225201e04c3fSmrg   /* Just do the intrastage -> interstage propagation right now,
225301e04c3fSmrg    * since we already know we're in the right type of shader program
225401e04c3fSmrg    * for doing it.
225501e04c3fSmrg    */
225601e04c3fSmrg   if (gl_prog->info.cs.local_size[0] == 0 &&
225701e04c3fSmrg       !gl_prog->info.cs.local_size_variable) {
225801e04c3fSmrg      linker_error(prog, "compute shader must contain a fixed or a variable "
225901e04c3fSmrg                         "local group size\n");
226001e04c3fSmrg      return;
226101e04c3fSmrg   }
22627e102996Smaya
22637e102996Smaya   if (gl_prog->info.cs.derivative_group == DERIVATIVE_GROUP_QUADS) {
22647e102996Smaya      if (gl_prog->info.cs.local_size[0] % 2 != 0) {
22657e102996Smaya         linker_error(prog, "derivative_group_quadsNV must be used with a "
22667e102996Smaya                      "local group size whose first dimension "
22677e102996Smaya                      "is a multiple of 2\n");
22687e102996Smaya         return;
22697e102996Smaya      }
22707e102996Smaya      if (gl_prog->info.cs.local_size[1] % 2 != 0) {
22717e102996Smaya         linker_error(prog, "derivative_group_quadsNV must be used with a local"
22727e102996Smaya                      "group size whose second dimension "
22737e102996Smaya                      "is a multiple of 2\n");
22747e102996Smaya         return;
22757e102996Smaya      }
22767e102996Smaya   } else if (gl_prog->info.cs.derivative_group == DERIVATIVE_GROUP_LINEAR) {
22777e102996Smaya      if ((gl_prog->info.cs.local_size[0] *
22787e102996Smaya           gl_prog->info.cs.local_size[1] *
22797e102996Smaya           gl_prog->info.cs.local_size[2]) % 4 != 0) {
22807e102996Smaya         linker_error(prog, "derivative_group_linearNV must be used with a "
22817e102996Smaya                      "local group size whose total number of invocations "
22827e102996Smaya                      "is a multiple of 4\n");
22837e102996Smaya         return;
22847e102996Smaya      }
22857e102996Smaya   }
228601e04c3fSmrg}
228701e04c3fSmrg
228801e04c3fSmrg/**
228901e04c3fSmrg * Link all out variables on a single stage which are not
229001e04c3fSmrg * directly used in a shader with the main function.
229101e04c3fSmrg */
229201e04c3fSmrgstatic void
229301e04c3fSmrglink_output_variables(struct gl_linked_shader *linked_shader,
229401e04c3fSmrg                      struct gl_shader **shader_list,
229501e04c3fSmrg                      unsigned num_shaders)
229601e04c3fSmrg{
229701e04c3fSmrg   struct glsl_symbol_table *symbols = linked_shader->symbols;
229801e04c3fSmrg
229901e04c3fSmrg   for (unsigned i = 0; i < num_shaders; i++) {
230001e04c3fSmrg
230101e04c3fSmrg      /* Skip shader object with main function */
230201e04c3fSmrg      if (shader_list[i]->symbols->get_function("main"))
230301e04c3fSmrg         continue;
230401e04c3fSmrg
230501e04c3fSmrg      foreach_in_list(ir_instruction, ir, shader_list[i]->ir) {
230601e04c3fSmrg         if (ir->ir_type != ir_type_variable)
230701e04c3fSmrg            continue;
230801e04c3fSmrg
230901e04c3fSmrg         ir_variable *var = (ir_variable *) ir;
231001e04c3fSmrg
231101e04c3fSmrg         if (var->data.mode == ir_var_shader_out &&
231201e04c3fSmrg               !symbols->get_variable(var->name)) {
231301e04c3fSmrg            var = var->clone(linked_shader, NULL);
231401e04c3fSmrg            symbols->add_variable(var);
231501e04c3fSmrg            linked_shader->ir->push_head(var);
231601e04c3fSmrg         }
231701e04c3fSmrg      }
231801e04c3fSmrg   }
231901e04c3fSmrg
232001e04c3fSmrg   return;
232101e04c3fSmrg}
232201e04c3fSmrg
232301e04c3fSmrg
232401e04c3fSmrg/**
232501e04c3fSmrg * Combine a group of shaders for a single stage to generate a linked shader
232601e04c3fSmrg *
232701e04c3fSmrg * \note
232801e04c3fSmrg * If this function is supplied a single shader, it is cloned, and the new
232901e04c3fSmrg * shader is returned.
233001e04c3fSmrg */
233101e04c3fSmrgstruct gl_linked_shader *
233201e04c3fSmrglink_intrastage_shaders(void *mem_ctx,
233301e04c3fSmrg                        struct gl_context *ctx,
233401e04c3fSmrg                        struct gl_shader_program *prog,
233501e04c3fSmrg                        struct gl_shader **shader_list,
233601e04c3fSmrg                        unsigned num_shaders,
233701e04c3fSmrg                        bool allow_missing_main)
233801e04c3fSmrg{
233901e04c3fSmrg   struct gl_uniform_block *ubo_blocks = NULL;
234001e04c3fSmrg   struct gl_uniform_block *ssbo_blocks = NULL;
234101e04c3fSmrg   unsigned num_ubo_blocks = 0;
234201e04c3fSmrg   unsigned num_ssbo_blocks = 0;
234301e04c3fSmrg
234401e04c3fSmrg   /* Check that global variables defined in multiple shaders are consistent.
234501e04c3fSmrg    */
234601e04c3fSmrg   glsl_symbol_table variables;
234701e04c3fSmrg   for (unsigned i = 0; i < num_shaders; i++) {
234801e04c3fSmrg      if (shader_list[i] == NULL)
234901e04c3fSmrg         continue;
235001e04c3fSmrg      cross_validate_globals(ctx, prog, shader_list[i]->ir, &variables,
235101e04c3fSmrg                             false);
235201e04c3fSmrg   }
235301e04c3fSmrg
235401e04c3fSmrg   if (!prog->data->LinkStatus)
235501e04c3fSmrg      return NULL;
235601e04c3fSmrg
235701e04c3fSmrg   /* Check that interface blocks defined in multiple shaders are consistent.
235801e04c3fSmrg    */
235901e04c3fSmrg   validate_intrastage_interface_blocks(prog, (const gl_shader **)shader_list,
236001e04c3fSmrg                                        num_shaders);
236101e04c3fSmrg   if (!prog->data->LinkStatus)
236201e04c3fSmrg      return NULL;
236301e04c3fSmrg
236401e04c3fSmrg   /* Check that there is only a single definition of each function signature
236501e04c3fSmrg    * across all shaders.
236601e04c3fSmrg    */
236701e04c3fSmrg   for (unsigned i = 0; i < (num_shaders - 1); i++) {
236801e04c3fSmrg      foreach_in_list(ir_instruction, node, shader_list[i]->ir) {
236901e04c3fSmrg         ir_function *const f = node->as_function();
237001e04c3fSmrg
237101e04c3fSmrg         if (f == NULL)
237201e04c3fSmrg            continue;
237301e04c3fSmrg
237401e04c3fSmrg         for (unsigned j = i + 1; j < num_shaders; j++) {
237501e04c3fSmrg            ir_function *const other =
237601e04c3fSmrg               shader_list[j]->symbols->get_function(f->name);
237701e04c3fSmrg
237801e04c3fSmrg            /* If the other shader has no function (and therefore no function
237901e04c3fSmrg             * signatures) with the same name, skip to the next shader.
238001e04c3fSmrg             */
238101e04c3fSmrg            if (other == NULL)
238201e04c3fSmrg               continue;
238301e04c3fSmrg
238401e04c3fSmrg            foreach_in_list(ir_function_signature, sig, &f->signatures) {
238501e04c3fSmrg               if (!sig->is_defined)
238601e04c3fSmrg                  continue;
238701e04c3fSmrg
238801e04c3fSmrg               ir_function_signature *other_sig =
238901e04c3fSmrg                  other->exact_matching_signature(NULL, &sig->parameters);
239001e04c3fSmrg
239101e04c3fSmrg               if (other_sig != NULL && other_sig->is_defined) {
239201e04c3fSmrg                  linker_error(prog, "function `%s' is multiply defined\n",
239301e04c3fSmrg                               f->name);
239401e04c3fSmrg                  return NULL;
239501e04c3fSmrg               }
239601e04c3fSmrg            }
239701e04c3fSmrg         }
239801e04c3fSmrg      }
239901e04c3fSmrg   }
240001e04c3fSmrg
240101e04c3fSmrg   /* Find the shader that defines main, and make a clone of it.
240201e04c3fSmrg    *
240301e04c3fSmrg    * Starting with the clone, search for undefined references.  If one is
240401e04c3fSmrg    * found, find the shader that defines it.  Clone the reference and add
240501e04c3fSmrg    * it to the shader.  Repeat until there are no undefined references or
240601e04c3fSmrg    * until a reference cannot be resolved.
240701e04c3fSmrg    */
240801e04c3fSmrg   gl_shader *main = NULL;
240901e04c3fSmrg   for (unsigned i = 0; i < num_shaders; i++) {
241001e04c3fSmrg      if (_mesa_get_main_function_signature(shader_list[i]->symbols)) {
241101e04c3fSmrg         main = shader_list[i];
241201e04c3fSmrg         break;
241301e04c3fSmrg      }
241401e04c3fSmrg   }
241501e04c3fSmrg
241601e04c3fSmrg   if (main == NULL && allow_missing_main)
241701e04c3fSmrg      main = shader_list[0];
241801e04c3fSmrg
241901e04c3fSmrg   if (main == NULL) {
242001e04c3fSmrg      linker_error(prog, "%s shader lacks `main'\n",
242101e04c3fSmrg                   _mesa_shader_stage_to_string(shader_list[0]->Stage));
242201e04c3fSmrg      return NULL;
242301e04c3fSmrg   }
242401e04c3fSmrg
242501e04c3fSmrg   gl_linked_shader *linked = rzalloc(NULL, struct gl_linked_shader);
242601e04c3fSmrg   linked->Stage = shader_list[0]->Stage;
242701e04c3fSmrg
242801e04c3fSmrg   /* Create program and attach it to the linked shader */
242901e04c3fSmrg   struct gl_program *gl_prog =
243001e04c3fSmrg      ctx->Driver.NewProgram(ctx,
243101e04c3fSmrg                             _mesa_shader_stage_to_program(shader_list[0]->Stage),
243201e04c3fSmrg                             prog->Name, false);
243301e04c3fSmrg   if (!gl_prog) {
243401e04c3fSmrg      prog->data->LinkStatus = LINKING_FAILURE;
243501e04c3fSmrg      _mesa_delete_linked_shader(ctx, linked);
243601e04c3fSmrg      return NULL;
243701e04c3fSmrg   }
243801e04c3fSmrg
243901e04c3fSmrg   _mesa_reference_shader_program_data(ctx, &gl_prog->sh.data, prog->data);
244001e04c3fSmrg
244101e04c3fSmrg   /* Don't use _mesa_reference_program() just take ownership */
244201e04c3fSmrg   linked->Program = gl_prog;
244301e04c3fSmrg
244401e04c3fSmrg   linked->ir = new(linked) exec_list;
244501e04c3fSmrg   clone_ir_list(mem_ctx, linked->ir, main->ir);
244601e04c3fSmrg
244701e04c3fSmrg   link_fs_inout_layout_qualifiers(prog, linked, shader_list, num_shaders);
244801e04c3fSmrg   link_tcs_out_layout_qualifiers(prog, gl_prog, shader_list, num_shaders);
244901e04c3fSmrg   link_tes_in_layout_qualifiers(prog, gl_prog, shader_list, num_shaders);
245001e04c3fSmrg   link_gs_inout_layout_qualifiers(prog, gl_prog, shader_list, num_shaders);
245101e04c3fSmrg   link_cs_input_layout_qualifiers(prog, gl_prog, shader_list, num_shaders);
245201e04c3fSmrg
245301e04c3fSmrg   if (linked->Stage != MESA_SHADER_FRAGMENT)
245401e04c3fSmrg      link_xfb_stride_layout_qualifiers(ctx, prog, shader_list, num_shaders);
245501e04c3fSmrg
245601e04c3fSmrg   link_bindless_layout_qualifiers(prog, shader_list, num_shaders);
245701e04c3fSmrg
245801e04c3fSmrg   populate_symbol_table(linked, shader_list[0]->symbols);
245901e04c3fSmrg
246001e04c3fSmrg   /* The pointer to the main function in the final linked shader (i.e., the
246101e04c3fSmrg    * copy of the original shader that contained the main function).
246201e04c3fSmrg    */
246301e04c3fSmrg   ir_function_signature *const main_sig =
246401e04c3fSmrg      _mesa_get_main_function_signature(linked->symbols);
246501e04c3fSmrg
246601e04c3fSmrg   /* Move any instructions other than variable declarations or function
246701e04c3fSmrg    * declarations into main.
246801e04c3fSmrg    */
246901e04c3fSmrg   if (main_sig != NULL) {
247001e04c3fSmrg      exec_node *insertion_point =
247101e04c3fSmrg         move_non_declarations(linked->ir, (exec_node *) &main_sig->body, false,
247201e04c3fSmrg                               linked);
247301e04c3fSmrg
247401e04c3fSmrg      for (unsigned i = 0; i < num_shaders; i++) {
247501e04c3fSmrg         if (shader_list[i] == main)
247601e04c3fSmrg            continue;
247701e04c3fSmrg
247801e04c3fSmrg         insertion_point = move_non_declarations(shader_list[i]->ir,
247901e04c3fSmrg                                                 insertion_point, true, linked);
248001e04c3fSmrg      }
248101e04c3fSmrg   }
248201e04c3fSmrg
248301e04c3fSmrg   if (!link_function_calls(prog, linked, shader_list, num_shaders)) {
248401e04c3fSmrg      _mesa_delete_linked_shader(ctx, linked);
248501e04c3fSmrg      return NULL;
248601e04c3fSmrg   }
248701e04c3fSmrg
248801e04c3fSmrg   if (linked->Stage != MESA_SHADER_FRAGMENT)
248901e04c3fSmrg      link_output_variables(linked, shader_list, num_shaders);
249001e04c3fSmrg
249101e04c3fSmrg   /* Make a pass over all variable declarations to ensure that arrays with
249201e04c3fSmrg    * unspecified sizes have a size specified.  The size is inferred from the
249301e04c3fSmrg    * max_array_access field.
249401e04c3fSmrg    */
249501e04c3fSmrg   array_sizing_visitor v;
249601e04c3fSmrg   v.run(linked->ir);
249701e04c3fSmrg   v.fixup_unnamed_interface_types();
249801e04c3fSmrg
249901e04c3fSmrg   /* Link up uniform blocks defined within this stage. */
250001e04c3fSmrg   link_uniform_blocks(mem_ctx, ctx, prog, linked, &ubo_blocks,
250101e04c3fSmrg                       &num_ubo_blocks, &ssbo_blocks, &num_ssbo_blocks);
250201e04c3fSmrg
250301e04c3fSmrg   if (!prog->data->LinkStatus) {
250401e04c3fSmrg      _mesa_delete_linked_shader(ctx, linked);
250501e04c3fSmrg      return NULL;
250601e04c3fSmrg   }
250701e04c3fSmrg
250801e04c3fSmrg   /* Copy ubo blocks to linked shader list */
250901e04c3fSmrg   linked->Program->sh.UniformBlocks =
251001e04c3fSmrg      ralloc_array(linked, gl_uniform_block *, num_ubo_blocks);
251101e04c3fSmrg   ralloc_steal(linked, ubo_blocks);
251201e04c3fSmrg   for (unsigned i = 0; i < num_ubo_blocks; i++) {
251301e04c3fSmrg      linked->Program->sh.UniformBlocks[i] = &ubo_blocks[i];
251401e04c3fSmrg   }
251501e04c3fSmrg   linked->Program->info.num_ubos = num_ubo_blocks;
251601e04c3fSmrg
251701e04c3fSmrg   /* Copy ssbo blocks to linked shader list */
251801e04c3fSmrg   linked->Program->sh.ShaderStorageBlocks =
251901e04c3fSmrg      ralloc_array(linked, gl_uniform_block *, num_ssbo_blocks);
252001e04c3fSmrg   ralloc_steal(linked, ssbo_blocks);
252101e04c3fSmrg   for (unsigned i = 0; i < num_ssbo_blocks; i++) {
252201e04c3fSmrg      linked->Program->sh.ShaderStorageBlocks[i] = &ssbo_blocks[i];
252301e04c3fSmrg   }
252401e04c3fSmrg   linked->Program->info.num_ssbos = num_ssbo_blocks;
252501e04c3fSmrg
252601e04c3fSmrg   /* At this point linked should contain all of the linked IR, so
252701e04c3fSmrg    * validate it to make sure nothing went wrong.
252801e04c3fSmrg    */
252901e04c3fSmrg   validate_ir_tree(linked->ir);
253001e04c3fSmrg
253101e04c3fSmrg   /* Set the size of geometry shader input arrays */
253201e04c3fSmrg   if (linked->Stage == MESA_SHADER_GEOMETRY) {
253301e04c3fSmrg      unsigned num_vertices =
253401e04c3fSmrg         vertices_per_prim(gl_prog->info.gs.input_primitive);
253501e04c3fSmrg      array_resize_visitor input_resize_visitor(num_vertices, prog,
253601e04c3fSmrg                                                MESA_SHADER_GEOMETRY);
253701e04c3fSmrg      foreach_in_list(ir_instruction, ir, linked->ir) {
253801e04c3fSmrg         ir->accept(&input_resize_visitor);
253901e04c3fSmrg      }
254001e04c3fSmrg   }
254101e04c3fSmrg
254201e04c3fSmrg   if (ctx->Const.VertexID_is_zero_based)
254301e04c3fSmrg      lower_vertex_id(linked);
254401e04c3fSmrg
254501e04c3fSmrg   if (ctx->Const.LowerCsDerivedVariables)
254601e04c3fSmrg      lower_cs_derived(linked);
254701e04c3fSmrg
254801e04c3fSmrg#ifdef DEBUG
254901e04c3fSmrg   /* Compute the source checksum. */
255001e04c3fSmrg   linked->SourceChecksum = 0;
255101e04c3fSmrg   for (unsigned i = 0; i < num_shaders; i++) {
255201e04c3fSmrg      if (shader_list[i] == NULL)
255301e04c3fSmrg         continue;
255401e04c3fSmrg      linked->SourceChecksum ^= shader_list[i]->SourceChecksum;
255501e04c3fSmrg   }
255601e04c3fSmrg#endif
255701e04c3fSmrg
255801e04c3fSmrg   return linked;
255901e04c3fSmrg}
256001e04c3fSmrg
256101e04c3fSmrg/**
256201e04c3fSmrg * Update the sizes of linked shader uniform arrays to the maximum
256301e04c3fSmrg * array index used.
256401e04c3fSmrg *
256501e04c3fSmrg * From page 81 (page 95 of the PDF) of the OpenGL 2.1 spec:
256601e04c3fSmrg *
256701e04c3fSmrg *     If one or more elements of an array are active,
256801e04c3fSmrg *     GetActiveUniform will return the name of the array in name,
256901e04c3fSmrg *     subject to the restrictions listed above. The type of the array
257001e04c3fSmrg *     is returned in type. The size parameter contains the highest
257101e04c3fSmrg *     array element index used, plus one. The compiler or linker
257201e04c3fSmrg *     determines the highest index used.  There will be only one
257301e04c3fSmrg *     active uniform reported by the GL per uniform array.
257401e04c3fSmrg
257501e04c3fSmrg */
257601e04c3fSmrgstatic void
257701e04c3fSmrgupdate_array_sizes(struct gl_shader_program *prog)
257801e04c3fSmrg{
257901e04c3fSmrg   for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
258001e04c3fSmrg         if (prog->_LinkedShaders[i] == NULL)
258101e04c3fSmrg            continue;
258201e04c3fSmrg
258301e04c3fSmrg      bool types_were_updated = false;
258401e04c3fSmrg
258501e04c3fSmrg      foreach_in_list(ir_instruction, node, prog->_LinkedShaders[i]->ir) {
258601e04c3fSmrg         ir_variable *const var = node->as_variable();
258701e04c3fSmrg
258801e04c3fSmrg         if ((var == NULL) || (var->data.mode != ir_var_uniform) ||
258901e04c3fSmrg             !var->type->is_array())
259001e04c3fSmrg            continue;
259101e04c3fSmrg
259201e04c3fSmrg         /* GL_ARB_uniform_buffer_object says that std140 uniforms
259301e04c3fSmrg          * will not be eliminated.  Since we always do std140, just
259401e04c3fSmrg          * don't resize arrays in UBOs.
259501e04c3fSmrg          *
259601e04c3fSmrg          * Atomic counters are supposed to get deterministic
259701e04c3fSmrg          * locations assigned based on the declaration ordering and
259801e04c3fSmrg          * sizes, array compaction would mess that up.
259901e04c3fSmrg          *
260001e04c3fSmrg          * Subroutine uniforms are not removed.
260101e04c3fSmrg          */
260201e04c3fSmrg         if (var->is_in_buffer_block() || var->type->contains_atomic() ||
260301e04c3fSmrg             var->type->contains_subroutine() || var->constant_initializer)
260401e04c3fSmrg            continue;
260501e04c3fSmrg
260601e04c3fSmrg         int size = var->data.max_array_access;
260701e04c3fSmrg         for (unsigned j = 0; j < MESA_SHADER_STAGES; j++) {
260801e04c3fSmrg               if (prog->_LinkedShaders[j] == NULL)
260901e04c3fSmrg                  continue;
261001e04c3fSmrg
261101e04c3fSmrg            foreach_in_list(ir_instruction, node2, prog->_LinkedShaders[j]->ir) {
261201e04c3fSmrg               ir_variable *other_var = node2->as_variable();
261301e04c3fSmrg               if (!other_var)
261401e04c3fSmrg                  continue;
261501e04c3fSmrg
261601e04c3fSmrg               if (strcmp(var->name, other_var->name) == 0 &&
261701e04c3fSmrg                   other_var->data.max_array_access > size) {
261801e04c3fSmrg                  size = other_var->data.max_array_access;
261901e04c3fSmrg               }
262001e04c3fSmrg            }
262101e04c3fSmrg         }
262201e04c3fSmrg
262301e04c3fSmrg         if (size + 1 != (int)var->type->length) {
262401e04c3fSmrg            /* If this is a built-in uniform (i.e., it's backed by some
262501e04c3fSmrg             * fixed-function state), adjust the number of state slots to
262601e04c3fSmrg             * match the new array size.  The number of slots per array entry
262701e04c3fSmrg             * is not known.  It seems safe to assume that the total number of
262801e04c3fSmrg             * slots is an integer multiple of the number of array elements.
262901e04c3fSmrg             * Determine the number of slots per array element by dividing by
263001e04c3fSmrg             * the old (total) size.
263101e04c3fSmrg             */
263201e04c3fSmrg            const unsigned num_slots = var->get_num_state_slots();
263301e04c3fSmrg            if (num_slots > 0) {
263401e04c3fSmrg               var->set_num_state_slots((size + 1)
263501e04c3fSmrg                                        * (num_slots / var->type->length));
263601e04c3fSmrg            }
263701e04c3fSmrg
263801e04c3fSmrg            var->type = glsl_type::get_array_instance(var->type->fields.array,
263901e04c3fSmrg                                                      size + 1);
264001e04c3fSmrg            types_were_updated = true;
264101e04c3fSmrg         }
264201e04c3fSmrg      }
264301e04c3fSmrg
264401e04c3fSmrg      /* Update the types of dereferences in case we changed any. */
264501e04c3fSmrg      if (types_were_updated) {
264601e04c3fSmrg         deref_type_updater v;
264701e04c3fSmrg         v.run(prog->_LinkedShaders[i]->ir);
264801e04c3fSmrg      }
264901e04c3fSmrg   }
265001e04c3fSmrg}
265101e04c3fSmrg
265201e04c3fSmrg/**
265301e04c3fSmrg * Resize tessellation evaluation per-vertex inputs to the size of
265401e04c3fSmrg * tessellation control per-vertex outputs.
265501e04c3fSmrg */
265601e04c3fSmrgstatic void
265701e04c3fSmrgresize_tes_inputs(struct gl_context *ctx,
265801e04c3fSmrg                  struct gl_shader_program *prog)
265901e04c3fSmrg{
266001e04c3fSmrg   if (prog->_LinkedShaders[MESA_SHADER_TESS_EVAL] == NULL)
266101e04c3fSmrg      return;
266201e04c3fSmrg
266301e04c3fSmrg   gl_linked_shader *const tcs = prog->_LinkedShaders[MESA_SHADER_TESS_CTRL];
266401e04c3fSmrg   gl_linked_shader *const tes = prog->_LinkedShaders[MESA_SHADER_TESS_EVAL];
266501e04c3fSmrg
266601e04c3fSmrg   /* If no control shader is present, then the TES inputs are statically
266701e04c3fSmrg    * sized to MaxPatchVertices; the actual size of the arrays won't be
266801e04c3fSmrg    * known until draw time.
266901e04c3fSmrg    */
267001e04c3fSmrg   const int num_vertices = tcs
267101e04c3fSmrg      ? tcs->Program->info.tess.tcs_vertices_out
267201e04c3fSmrg      : ctx->Const.MaxPatchVertices;
267301e04c3fSmrg
267401e04c3fSmrg   array_resize_visitor input_resize_visitor(num_vertices, prog,
267501e04c3fSmrg                                             MESA_SHADER_TESS_EVAL);
267601e04c3fSmrg   foreach_in_list(ir_instruction, ir, tes->ir) {
267701e04c3fSmrg      ir->accept(&input_resize_visitor);
267801e04c3fSmrg   }
267901e04c3fSmrg
268001e04c3fSmrg   if (tcs) {
268101e04c3fSmrg      /* Convert the gl_PatchVerticesIn system value into a constant, since
268201e04c3fSmrg       * the value is known at this point.
268301e04c3fSmrg       */
268401e04c3fSmrg      foreach_in_list(ir_instruction, ir, tes->ir) {
268501e04c3fSmrg         ir_variable *var = ir->as_variable();
268601e04c3fSmrg         if (var && var->data.mode == ir_var_system_value &&
268701e04c3fSmrg             var->data.location == SYSTEM_VALUE_VERTICES_IN) {
268801e04c3fSmrg            void *mem_ctx = ralloc_parent(var);
268901e04c3fSmrg            var->data.location = 0;
269001e04c3fSmrg            var->data.explicit_location = false;
269101e04c3fSmrg            var->data.mode = ir_var_auto;
269201e04c3fSmrg            var->constant_value = new(mem_ctx) ir_constant(num_vertices);
269301e04c3fSmrg         }
269401e04c3fSmrg      }
269501e04c3fSmrg   }
269601e04c3fSmrg}
269701e04c3fSmrg
269801e04c3fSmrg/**
269901e04c3fSmrg * Find a contiguous set of available bits in a bitmask.
270001e04c3fSmrg *
270101e04c3fSmrg * \param used_mask     Bits representing used (1) and unused (0) locations
270201e04c3fSmrg * \param needed_count  Number of contiguous bits needed.
270301e04c3fSmrg *
270401e04c3fSmrg * \return
270501e04c3fSmrg * Base location of the available bits on success or -1 on failure.
270601e04c3fSmrg */
270701e04c3fSmrgstatic int
270801e04c3fSmrgfind_available_slots(unsigned used_mask, unsigned needed_count)
270901e04c3fSmrg{
271001e04c3fSmrg   unsigned needed_mask = (1 << needed_count) - 1;
271101e04c3fSmrg   const int max_bit_to_test = (8 * sizeof(used_mask)) - needed_count;
271201e04c3fSmrg
271301e04c3fSmrg   /* The comparison to 32 is redundant, but without it GCC emits "warning:
271401e04c3fSmrg    * cannot optimize possibly infinite loops" for the loop below.
271501e04c3fSmrg    */
271601e04c3fSmrg   if ((needed_count == 0) || (max_bit_to_test < 0) || (max_bit_to_test > 32))
271701e04c3fSmrg      return -1;
271801e04c3fSmrg
271901e04c3fSmrg   for (int i = 0; i <= max_bit_to_test; i++) {
272001e04c3fSmrg      if ((needed_mask & ~used_mask) == needed_mask)
272101e04c3fSmrg         return i;
272201e04c3fSmrg
272301e04c3fSmrg      needed_mask <<= 1;
272401e04c3fSmrg   }
272501e04c3fSmrg
272601e04c3fSmrg   return -1;
272701e04c3fSmrg}
272801e04c3fSmrg
272901e04c3fSmrg
273001e04c3fSmrg#define SAFE_MASK_FROM_INDEX(i) (((i) >= 32) ? ~0 : ((1 << (i)) - 1))
273101e04c3fSmrg
273201e04c3fSmrg/**
27337e102996Smaya * Assign locations for either VS inputs or FS outputs.
273401e04c3fSmrg *
27357e102996Smaya * \param mem_ctx        Temporary ralloc context used for linking.
27367e102996Smaya * \param prog           Shader program whose variables need locations
27377e102996Smaya *                       assigned.
27387e102996Smaya * \param constants      Driver specific constant values for the program.
27397e102996Smaya * \param target_index   Selector for the program target to receive location
27407e102996Smaya *                       assignmnets.  Must be either \c MESA_SHADER_VERTEX or
27417e102996Smaya *                       \c MESA_SHADER_FRAGMENT.
27427e102996Smaya * \param do_assignment  Whether we are actually marking the assignment or we
27437e102996Smaya *                       are just doing a dry-run checking.
274401e04c3fSmrg *
274501e04c3fSmrg * \return
27467e102996Smaya * If locations are (or can be, in case of dry-running) successfully assigned,
27477e102996Smaya * true is returned.  Otherwise an error is emitted to the shader link log and
27487e102996Smaya * false is returned.
274901e04c3fSmrg */
275001e04c3fSmrgstatic bool
275101e04c3fSmrgassign_attribute_or_color_locations(void *mem_ctx,
275201e04c3fSmrg                                    gl_shader_program *prog,
275301e04c3fSmrg                                    struct gl_constants *constants,
275401e04c3fSmrg                                    unsigned target_index,
275501e04c3fSmrg                                    bool do_assignment)
275601e04c3fSmrg{
275701e04c3fSmrg   /* Maximum number of generic locations.  This corresponds to either the
275801e04c3fSmrg    * maximum number of draw buffers or the maximum number of generic
275901e04c3fSmrg    * attributes.
276001e04c3fSmrg    */
276101e04c3fSmrg   unsigned max_index = (target_index == MESA_SHADER_VERTEX) ?
276201e04c3fSmrg      constants->Program[target_index].MaxAttribs :
276301e04c3fSmrg      MAX2(constants->MaxDrawBuffers, constants->MaxDualSourceDrawBuffers);
276401e04c3fSmrg
276501e04c3fSmrg   /* Mark invalid locations as being used.
276601e04c3fSmrg    */
276701e04c3fSmrg   unsigned used_locations = ~SAFE_MASK_FROM_INDEX(max_index);
276801e04c3fSmrg   unsigned double_storage_locations = 0;
276901e04c3fSmrg
277001e04c3fSmrg   assert((target_index == MESA_SHADER_VERTEX)
277101e04c3fSmrg          || (target_index == MESA_SHADER_FRAGMENT));
277201e04c3fSmrg
277301e04c3fSmrg   gl_linked_shader *const sh = prog->_LinkedShaders[target_index];
277401e04c3fSmrg   if (sh == NULL)
277501e04c3fSmrg      return true;
277601e04c3fSmrg
277701e04c3fSmrg   /* Operate in a total of four passes.
277801e04c3fSmrg    *
277901e04c3fSmrg    * 1. Invalidate the location assignments for all vertex shader inputs.
278001e04c3fSmrg    *
278101e04c3fSmrg    * 2. Assign locations for inputs that have user-defined (via
278201e04c3fSmrg    *    glBindVertexAttribLocation) locations and outputs that have
278301e04c3fSmrg    *    user-defined locations (via glBindFragDataLocation).
278401e04c3fSmrg    *
278501e04c3fSmrg    * 3. Sort the attributes without assigned locations by number of slots
278601e04c3fSmrg    *    required in decreasing order.  Fragmentation caused by attribute
278701e04c3fSmrg    *    locations assigned by the application may prevent large attributes
278801e04c3fSmrg    *    from having enough contiguous space.
278901e04c3fSmrg    *
279001e04c3fSmrg    * 4. Assign locations to any inputs without assigned locations.
279101e04c3fSmrg    */
279201e04c3fSmrg
279301e04c3fSmrg   const int generic_base = (target_index == MESA_SHADER_VERTEX)
279401e04c3fSmrg      ? (int) VERT_ATTRIB_GENERIC0 : (int) FRAG_RESULT_DATA0;
279501e04c3fSmrg
279601e04c3fSmrg   const enum ir_variable_mode direction =
279701e04c3fSmrg      (target_index == MESA_SHADER_VERTEX)
279801e04c3fSmrg      ? ir_var_shader_in : ir_var_shader_out;
279901e04c3fSmrg
280001e04c3fSmrg
280101e04c3fSmrg   /* Temporary storage for the set of attributes that need locations assigned.
280201e04c3fSmrg    */
280301e04c3fSmrg   struct temp_attr {
280401e04c3fSmrg      unsigned slots;
280501e04c3fSmrg      ir_variable *var;
280601e04c3fSmrg
280701e04c3fSmrg      /* Used below in the call to qsort. */
280801e04c3fSmrg      static int compare(const void *a, const void *b)
280901e04c3fSmrg      {
281001e04c3fSmrg         const temp_attr *const l = (const temp_attr *) a;
281101e04c3fSmrg         const temp_attr *const r = (const temp_attr *) b;
281201e04c3fSmrg
281301e04c3fSmrg         /* Reversed because we want a descending order sort below. */
281401e04c3fSmrg         return r->slots - l->slots;
281501e04c3fSmrg      }
281601e04c3fSmrg   } to_assign[32];
281701e04c3fSmrg   assert(max_index <= 32);
281801e04c3fSmrg
281901e04c3fSmrg   /* Temporary array for the set of attributes that have locations assigned,
282001e04c3fSmrg    * for the purpose of checking overlapping slots/components of (non-ES)
282101e04c3fSmrg    * fragment shader outputs.
282201e04c3fSmrg    */
282301e04c3fSmrg   ir_variable *assigned[12 * 4]; /* (max # of FS outputs) * # components */
282401e04c3fSmrg   unsigned assigned_attr = 0;
282501e04c3fSmrg
282601e04c3fSmrg   unsigned num_attr = 0;
282701e04c3fSmrg
282801e04c3fSmrg   foreach_in_list(ir_instruction, node, sh->ir) {
282901e04c3fSmrg      ir_variable *const var = node->as_variable();
283001e04c3fSmrg
283101e04c3fSmrg      if ((var == NULL) || (var->data.mode != (unsigned) direction))
283201e04c3fSmrg         continue;
283301e04c3fSmrg
283401e04c3fSmrg      if (var->data.explicit_location) {
283501e04c3fSmrg         var->data.is_unmatched_generic_inout = 0;
283601e04c3fSmrg         if ((var->data.location >= (int)(max_index + generic_base))
283701e04c3fSmrg             || (var->data.location < 0)) {
283801e04c3fSmrg            linker_error(prog,
283901e04c3fSmrg                         "invalid explicit location %d specified for `%s'\n",
284001e04c3fSmrg                         (var->data.location < 0)
284101e04c3fSmrg                         ? var->data.location
284201e04c3fSmrg                         : var->data.location - generic_base,
284301e04c3fSmrg                         var->name);
284401e04c3fSmrg            return false;
284501e04c3fSmrg         }
284601e04c3fSmrg      } else if (target_index == MESA_SHADER_VERTEX) {
284701e04c3fSmrg         unsigned binding;
284801e04c3fSmrg
284901e04c3fSmrg         if (prog->AttributeBindings->get(binding, var->name)) {
285001e04c3fSmrg            assert(binding >= VERT_ATTRIB_GENERIC0);
285101e04c3fSmrg            var->data.location = binding;
285201e04c3fSmrg            var->data.is_unmatched_generic_inout = 0;
285301e04c3fSmrg         }
285401e04c3fSmrg      } else if (target_index == MESA_SHADER_FRAGMENT) {
285501e04c3fSmrg         unsigned binding;
285601e04c3fSmrg         unsigned index;
285701e04c3fSmrg         const char *name = var->name;
285801e04c3fSmrg         const glsl_type *type = var->type;
285901e04c3fSmrg
286001e04c3fSmrg         while (type) {
286101e04c3fSmrg            /* Check if there's a binding for the variable name */
286201e04c3fSmrg            if (prog->FragDataBindings->get(binding, name)) {
286301e04c3fSmrg               assert(binding >= FRAG_RESULT_DATA0);
286401e04c3fSmrg               var->data.location = binding;
286501e04c3fSmrg               var->data.is_unmatched_generic_inout = 0;
286601e04c3fSmrg
286701e04c3fSmrg               if (prog->FragDataIndexBindings->get(index, name)) {
286801e04c3fSmrg                  var->data.index = index;
286901e04c3fSmrg               }
287001e04c3fSmrg               break;
287101e04c3fSmrg            }
287201e04c3fSmrg
287301e04c3fSmrg            /* If not, but it's an array type, look for name[0] */
287401e04c3fSmrg            if (type->is_array()) {
287501e04c3fSmrg               name = ralloc_asprintf(mem_ctx, "%s[0]", name);
287601e04c3fSmrg               type = type->fields.array;
287701e04c3fSmrg               continue;
287801e04c3fSmrg            }
287901e04c3fSmrg
288001e04c3fSmrg            break;
288101e04c3fSmrg         }
288201e04c3fSmrg      }
288301e04c3fSmrg
288401e04c3fSmrg      if (strcmp(var->name, "gl_LastFragData") == 0)
288501e04c3fSmrg         continue;
288601e04c3fSmrg
288701e04c3fSmrg      /* From GL4.5 core spec, section 15.2 (Shader Execution):
288801e04c3fSmrg       *
288901e04c3fSmrg       *     "Output binding assignments will cause LinkProgram to fail:
289001e04c3fSmrg       *     ...
289101e04c3fSmrg       *     If the program has an active output assigned to a location greater
289201e04c3fSmrg       *     than or equal to the value of MAX_DUAL_SOURCE_DRAW_BUFFERS and has
289301e04c3fSmrg       *     an active output assigned an index greater than or equal to one;"
289401e04c3fSmrg       */
289501e04c3fSmrg      if (target_index == MESA_SHADER_FRAGMENT && var->data.index >= 1 &&
289601e04c3fSmrg          var->data.location - generic_base >=
289701e04c3fSmrg          (int) constants->MaxDualSourceDrawBuffers) {
289801e04c3fSmrg         linker_error(prog,
289901e04c3fSmrg                      "output location %d >= GL_MAX_DUAL_SOURCE_DRAW_BUFFERS "
290001e04c3fSmrg                      "with index %u for %s\n",
290101e04c3fSmrg                      var->data.location - generic_base, var->data.index,
290201e04c3fSmrg                      var->name);
290301e04c3fSmrg         return false;
290401e04c3fSmrg      }
290501e04c3fSmrg
290601e04c3fSmrg      const unsigned slots = var->type->count_attribute_slots(target_index == MESA_SHADER_VERTEX);
290701e04c3fSmrg
290801e04c3fSmrg      /* If the variable is not a built-in and has a location statically
290901e04c3fSmrg       * assigned in the shader (presumably via a layout qualifier), make sure
291001e04c3fSmrg       * that it doesn't collide with other assigned locations.  Otherwise,
291101e04c3fSmrg       * add it to the list of variables that need linker-assigned locations.
291201e04c3fSmrg       */
291301e04c3fSmrg      if (var->data.location != -1) {
291401e04c3fSmrg         if (var->data.location >= generic_base && var->data.index < 1) {
291501e04c3fSmrg            /* From page 61 of the OpenGL 4.0 spec:
291601e04c3fSmrg             *
291701e04c3fSmrg             *     "LinkProgram will fail if the attribute bindings assigned
291801e04c3fSmrg             *     by BindAttribLocation do not leave not enough space to
291901e04c3fSmrg             *     assign a location for an active matrix attribute or an
292001e04c3fSmrg             *     active attribute array, both of which require multiple
292101e04c3fSmrg             *     contiguous generic attributes."
292201e04c3fSmrg             *
292301e04c3fSmrg             * I think above text prohibits the aliasing of explicit and
292401e04c3fSmrg             * automatic assignments. But, aliasing is allowed in manual
292501e04c3fSmrg             * assignments of attribute locations. See below comments for
292601e04c3fSmrg             * the details.
292701e04c3fSmrg             *
292801e04c3fSmrg             * From OpenGL 4.0 spec, page 61:
292901e04c3fSmrg             *
293001e04c3fSmrg             *     "It is possible for an application to bind more than one
293101e04c3fSmrg             *     attribute name to the same location. This is referred to as
293201e04c3fSmrg             *     aliasing. This will only work if only one of the aliased
293301e04c3fSmrg             *     attributes is active in the executable program, or if no
293401e04c3fSmrg             *     path through the shader consumes more than one attribute of
293501e04c3fSmrg             *     a set of attributes aliased to the same location. A link
293601e04c3fSmrg             *     error can occur if the linker determines that every path
293701e04c3fSmrg             *     through the shader consumes multiple aliased attributes,
293801e04c3fSmrg             *     but implementations are not required to generate an error
293901e04c3fSmrg             *     in this case."
294001e04c3fSmrg             *
294101e04c3fSmrg             * From GLSL 4.30 spec, page 54:
294201e04c3fSmrg             *
294301e04c3fSmrg             *    "A program will fail to link if any two non-vertex shader
294401e04c3fSmrg             *     input variables are assigned to the same location. For
294501e04c3fSmrg             *     vertex shaders, multiple input variables may be assigned
294601e04c3fSmrg             *     to the same location using either layout qualifiers or via
294701e04c3fSmrg             *     the OpenGL API. However, such aliasing is intended only to
294801e04c3fSmrg             *     support vertex shaders where each execution path accesses
294901e04c3fSmrg             *     at most one input per each location. Implementations are
295001e04c3fSmrg             *     permitted, but not required, to generate link-time errors
295101e04c3fSmrg             *     if they detect that every path through the vertex shader
295201e04c3fSmrg             *     executable accesses multiple inputs assigned to any single
295301e04c3fSmrg             *     location. For all shader types, a program will fail to link
295401e04c3fSmrg             *     if explicit location assignments leave the linker unable
295501e04c3fSmrg             *     to find space for other variables without explicit
295601e04c3fSmrg             *     assignments."
295701e04c3fSmrg             *
295801e04c3fSmrg             * From OpenGL ES 3.0 spec, page 56:
295901e04c3fSmrg             *
296001e04c3fSmrg             *    "Binding more than one attribute name to the same location
296101e04c3fSmrg             *     is referred to as aliasing, and is not permitted in OpenGL
296201e04c3fSmrg             *     ES Shading Language 3.00 vertex shaders. LinkProgram will
296301e04c3fSmrg             *     fail when this condition exists. However, aliasing is
296401e04c3fSmrg             *     possible in OpenGL ES Shading Language 1.00 vertex shaders.
296501e04c3fSmrg             *     This will only work if only one of the aliased attributes
296601e04c3fSmrg             *     is active in the executable program, or if no path through
296701e04c3fSmrg             *     the shader consumes more than one attribute of a set of
296801e04c3fSmrg             *     attributes aliased to the same location. A link error can
296901e04c3fSmrg             *     occur if the linker determines that every path through the
297001e04c3fSmrg             *     shader consumes multiple aliased attributes, but implemen-
297101e04c3fSmrg             *     tations are not required to generate an error in this case."
297201e04c3fSmrg             *
297301e04c3fSmrg             * After looking at above references from OpenGL, OpenGL ES and
297401e04c3fSmrg             * GLSL specifications, we allow aliasing of vertex input variables
297501e04c3fSmrg             * in: OpenGL 2.0 (and above) and OpenGL ES 2.0.
297601e04c3fSmrg             *
297701e04c3fSmrg             * NOTE: This is not required by the spec but its worth mentioning
297801e04c3fSmrg             * here that we're not doing anything to make sure that no path
297901e04c3fSmrg             * through the vertex shader executable accesses multiple inputs
298001e04c3fSmrg             * assigned to any single location.
298101e04c3fSmrg             */
298201e04c3fSmrg
298301e04c3fSmrg            /* Mask representing the contiguous slots that will be used by
298401e04c3fSmrg             * this attribute.
298501e04c3fSmrg             */
298601e04c3fSmrg            const unsigned attr = var->data.location - generic_base;
298701e04c3fSmrg            const unsigned use_mask = (1 << slots) - 1;
298801e04c3fSmrg            const char *const string = (target_index == MESA_SHADER_VERTEX)
298901e04c3fSmrg               ? "vertex shader input" : "fragment shader output";
299001e04c3fSmrg
299101e04c3fSmrg            /* Generate a link error if the requested locations for this
299201e04c3fSmrg             * attribute exceed the maximum allowed attribute location.
299301e04c3fSmrg             */
299401e04c3fSmrg            if (attr + slots > max_index) {
299501e04c3fSmrg               linker_error(prog,
299601e04c3fSmrg                           "insufficient contiguous locations "
299701e04c3fSmrg                           "available for %s `%s' %d %d %d\n", string,
299801e04c3fSmrg                           var->name, used_locations, use_mask, attr);
299901e04c3fSmrg               return false;
300001e04c3fSmrg            }
300101e04c3fSmrg
300201e04c3fSmrg            /* Generate a link error if the set of bits requested for this
300301e04c3fSmrg             * attribute overlaps any previously allocated bits.
300401e04c3fSmrg             */
300501e04c3fSmrg            if ((~(use_mask << attr) & used_locations) != used_locations) {
300601e04c3fSmrg               if (target_index == MESA_SHADER_FRAGMENT && !prog->IsES) {
300701e04c3fSmrg                  /* From section 4.4.2 (Output Layout Qualifiers) of the GLSL
300801e04c3fSmrg                   * 4.40 spec:
300901e04c3fSmrg                   *
301001e04c3fSmrg                   *    "Additionally, for fragment shader outputs, if two
301101e04c3fSmrg                   *    variables are placed within the same location, they
301201e04c3fSmrg                   *    must have the same underlying type (floating-point or
301301e04c3fSmrg                   *    integer). No component aliasing of output variables or
301401e04c3fSmrg                   *    members is allowed.
301501e04c3fSmrg                   */
301601e04c3fSmrg                  for (unsigned i = 0; i < assigned_attr; i++) {
301701e04c3fSmrg                     unsigned assigned_slots =
301801e04c3fSmrg                        assigned[i]->type->count_attribute_slots(false);
301901e04c3fSmrg                     unsigned assig_attr =
302001e04c3fSmrg                        assigned[i]->data.location - generic_base;
302101e04c3fSmrg                     unsigned assigned_use_mask = (1 << assigned_slots) - 1;
302201e04c3fSmrg
302301e04c3fSmrg                     if ((assigned_use_mask << assig_attr) &
302401e04c3fSmrg                         (use_mask << attr)) {
302501e04c3fSmrg
302601e04c3fSmrg                        const glsl_type *assigned_type =
302701e04c3fSmrg                           assigned[i]->type->without_array();
302801e04c3fSmrg                        const glsl_type *type = var->type->without_array();
302901e04c3fSmrg                        if (assigned_type->base_type != type->base_type) {
303001e04c3fSmrg                           linker_error(prog, "types do not match for aliased"
303101e04c3fSmrg                                        " %ss %s and %s\n", string,
303201e04c3fSmrg                                        assigned[i]->name, var->name);
303301e04c3fSmrg                           return false;
303401e04c3fSmrg                        }
303501e04c3fSmrg
303601e04c3fSmrg                        unsigned assigned_component_mask =
303701e04c3fSmrg                           ((1 << assigned_type->vector_elements) - 1) <<
303801e04c3fSmrg                           assigned[i]->data.location_frac;
303901e04c3fSmrg                        unsigned component_mask =
304001e04c3fSmrg                           ((1 << type->vector_elements) - 1) <<
304101e04c3fSmrg                           var->data.location_frac;
304201e04c3fSmrg                        if (assigned_component_mask & component_mask) {
304301e04c3fSmrg                           linker_error(prog, "overlapping component is "
304401e04c3fSmrg                                        "assigned to %ss %s and %s "
304501e04c3fSmrg                                        "(component=%d)\n",
304601e04c3fSmrg                                        string, assigned[i]->name, var->name,
304701e04c3fSmrg                                        var->data.location_frac);
304801e04c3fSmrg                           return false;
304901e04c3fSmrg                        }
305001e04c3fSmrg                     }
305101e04c3fSmrg                  }
305201e04c3fSmrg               } else if (target_index == MESA_SHADER_FRAGMENT ||
305301e04c3fSmrg                          (prog->IsES && prog->data->Version >= 300)) {
305401e04c3fSmrg                  linker_error(prog, "overlapping location is assigned "
305501e04c3fSmrg                               "to %s `%s' %d %d %d\n", string, var->name,
305601e04c3fSmrg                               used_locations, use_mask, attr);
305701e04c3fSmrg                  return false;
305801e04c3fSmrg               } else {
305901e04c3fSmrg                  linker_warning(prog, "overlapping location is assigned "
306001e04c3fSmrg                                 "to %s `%s' %d %d %d\n", string, var->name,
306101e04c3fSmrg                                 used_locations, use_mask, attr);
306201e04c3fSmrg               }
306301e04c3fSmrg            }
306401e04c3fSmrg
306501e04c3fSmrg            if (target_index == MESA_SHADER_FRAGMENT && !prog->IsES) {
306601e04c3fSmrg               /* Only track assigned variables for non-ES fragment shaders
306701e04c3fSmrg                * to avoid overflowing the array.
306801e04c3fSmrg                *
306901e04c3fSmrg                * At most one variable per fragment output component should
307001e04c3fSmrg                * reach this.
307101e04c3fSmrg                */
307201e04c3fSmrg               assert(assigned_attr < ARRAY_SIZE(assigned));
307301e04c3fSmrg               assigned[assigned_attr] = var;
307401e04c3fSmrg               assigned_attr++;
307501e04c3fSmrg            }
307601e04c3fSmrg
307701e04c3fSmrg            used_locations |= (use_mask << attr);
307801e04c3fSmrg
307901e04c3fSmrg            /* From the GL 4.5 core spec, section 11.1.1 (Vertex Attributes):
308001e04c3fSmrg             *
308101e04c3fSmrg             * "A program with more than the value of MAX_VERTEX_ATTRIBS
308201e04c3fSmrg             *  active attribute variables may fail to link, unless
308301e04c3fSmrg             *  device-dependent optimizations are able to make the program
308401e04c3fSmrg             *  fit within available hardware resources. For the purposes
308501e04c3fSmrg             *  of this test, attribute variables of the type dvec3, dvec4,
308601e04c3fSmrg             *  dmat2x3, dmat2x4, dmat3, dmat3x4, dmat4x3, and dmat4 may
308701e04c3fSmrg             *  count as consuming twice as many attributes as equivalent
308801e04c3fSmrg             *  single-precision types. While these types use the same number
308901e04c3fSmrg             *  of generic attributes as their single-precision equivalents,
309001e04c3fSmrg             *  implementations are permitted to consume two single-precision
309101e04c3fSmrg             *  vectors of internal storage for each three- or four-component
309201e04c3fSmrg             *  double-precision vector."
309301e04c3fSmrg             *
309401e04c3fSmrg             * Mark this attribute slot as taking up twice as much space
309501e04c3fSmrg             * so we can count it properly against limits.  According to
309601e04c3fSmrg             * issue (3) of the GL_ARB_vertex_attrib_64bit behavior, this
309701e04c3fSmrg             * is optional behavior, but it seems preferable.
309801e04c3fSmrg             */
309901e04c3fSmrg            if (var->type->without_array()->is_dual_slot())
310001e04c3fSmrg               double_storage_locations |= (use_mask << attr);
310101e04c3fSmrg         }
310201e04c3fSmrg
310301e04c3fSmrg         continue;
310401e04c3fSmrg      }
310501e04c3fSmrg
310601e04c3fSmrg      if (num_attr >= max_index) {
310701e04c3fSmrg         linker_error(prog, "too many %s (max %u)",
310801e04c3fSmrg                      target_index == MESA_SHADER_VERTEX ?
310901e04c3fSmrg                      "vertex shader inputs" : "fragment shader outputs",
311001e04c3fSmrg                      max_index);
311101e04c3fSmrg         return false;
311201e04c3fSmrg      }
311301e04c3fSmrg      to_assign[num_attr].slots = slots;
311401e04c3fSmrg      to_assign[num_attr].var = var;
311501e04c3fSmrg      num_attr++;
311601e04c3fSmrg   }
311701e04c3fSmrg
311801e04c3fSmrg   if (!do_assignment)
311901e04c3fSmrg      return true;
312001e04c3fSmrg
312101e04c3fSmrg   if (target_index == MESA_SHADER_VERTEX) {
312201e04c3fSmrg      unsigned total_attribs_size =
312301e04c3fSmrg         util_bitcount(used_locations & SAFE_MASK_FROM_INDEX(max_index)) +
312401e04c3fSmrg         util_bitcount(double_storage_locations);
312501e04c3fSmrg      if (total_attribs_size > max_index) {
312601e04c3fSmrg         linker_error(prog,
312701e04c3fSmrg                      "attempt to use %d vertex attribute slots only %d available ",
312801e04c3fSmrg                      total_attribs_size, max_index);
312901e04c3fSmrg         return false;
313001e04c3fSmrg      }
313101e04c3fSmrg   }
313201e04c3fSmrg
313301e04c3fSmrg   /* If all of the attributes were assigned locations by the application (or
313401e04c3fSmrg    * are built-in attributes with fixed locations), return early.  This should
313501e04c3fSmrg    * be the common case.
313601e04c3fSmrg    */
313701e04c3fSmrg   if (num_attr == 0)
313801e04c3fSmrg      return true;
313901e04c3fSmrg
314001e04c3fSmrg   qsort(to_assign, num_attr, sizeof(to_assign[0]), temp_attr::compare);
314101e04c3fSmrg
314201e04c3fSmrg   if (target_index == MESA_SHADER_VERTEX) {
314301e04c3fSmrg      /* VERT_ATTRIB_GENERIC0 is a pseudo-alias for VERT_ATTRIB_POS.  It can
314401e04c3fSmrg       * only be explicitly assigned by via glBindAttribLocation.  Mark it as
314501e04c3fSmrg       * reserved to prevent it from being automatically allocated below.
314601e04c3fSmrg       */
314701e04c3fSmrg      find_deref_visitor find("gl_Vertex");
314801e04c3fSmrg      find.run(sh->ir);
314901e04c3fSmrg      if (find.variable_found())
315001e04c3fSmrg         used_locations |= (1 << 0);
315101e04c3fSmrg   }
315201e04c3fSmrg
315301e04c3fSmrg   for (unsigned i = 0; i < num_attr; i++) {
315401e04c3fSmrg      /* Mask representing the contiguous slots that will be used by this
315501e04c3fSmrg       * attribute.
315601e04c3fSmrg       */
315701e04c3fSmrg      const unsigned use_mask = (1 << to_assign[i].slots) - 1;
315801e04c3fSmrg
315901e04c3fSmrg      int location = find_available_slots(used_locations, to_assign[i].slots);
316001e04c3fSmrg
316101e04c3fSmrg      if (location < 0) {
316201e04c3fSmrg         const char *const string = (target_index == MESA_SHADER_VERTEX)
316301e04c3fSmrg            ? "vertex shader input" : "fragment shader output";
316401e04c3fSmrg
316501e04c3fSmrg         linker_error(prog,
316601e04c3fSmrg                      "insufficient contiguous locations "
316701e04c3fSmrg                      "available for %s `%s'\n",
316801e04c3fSmrg                      string, to_assign[i].var->name);
316901e04c3fSmrg         return false;
317001e04c3fSmrg      }
317101e04c3fSmrg
317201e04c3fSmrg      to_assign[i].var->data.location = generic_base + location;
317301e04c3fSmrg      to_assign[i].var->data.is_unmatched_generic_inout = 0;
317401e04c3fSmrg      used_locations |= (use_mask << location);
317501e04c3fSmrg
317601e04c3fSmrg      if (to_assign[i].var->type->without_array()->is_dual_slot())
317701e04c3fSmrg         double_storage_locations |= (use_mask << location);
317801e04c3fSmrg   }
317901e04c3fSmrg
318001e04c3fSmrg   /* Now that we have all the locations, from the GL 4.5 core spec, section
318101e04c3fSmrg    * 11.1.1 (Vertex Attributes), dvec3, dvec4, dmat2x3, dmat2x4, dmat3,
318201e04c3fSmrg    * dmat3x4, dmat4x3, and dmat4 count as consuming twice as many attributes
318301e04c3fSmrg    * as equivalent single-precision types.
318401e04c3fSmrg    */
318501e04c3fSmrg   if (target_index == MESA_SHADER_VERTEX) {
318601e04c3fSmrg      unsigned total_attribs_size =
318701e04c3fSmrg         util_bitcount(used_locations & SAFE_MASK_FROM_INDEX(max_index)) +
318801e04c3fSmrg         util_bitcount(double_storage_locations);
318901e04c3fSmrg      if (total_attribs_size > max_index) {
319001e04c3fSmrg         linker_error(prog,
319101e04c3fSmrg                      "attempt to use %d vertex attribute slots only %d available ",
319201e04c3fSmrg                      total_attribs_size, max_index);
319301e04c3fSmrg         return false;
319401e04c3fSmrg      }
319501e04c3fSmrg   }
319601e04c3fSmrg
319701e04c3fSmrg   return true;
319801e04c3fSmrg}
319901e04c3fSmrg
320001e04c3fSmrg/**
320101e04c3fSmrg * Match explicit locations of outputs to inputs and deactivate the
320201e04c3fSmrg * unmatch flag if found so we don't optimise them away.
320301e04c3fSmrg */
320401e04c3fSmrgstatic void
320501e04c3fSmrgmatch_explicit_outputs_to_inputs(gl_linked_shader *producer,
320601e04c3fSmrg                                 gl_linked_shader *consumer)
320701e04c3fSmrg{
320801e04c3fSmrg   glsl_symbol_table parameters;
320901e04c3fSmrg   ir_variable *explicit_locations[MAX_VARYINGS_INCL_PATCH][4] =
321001e04c3fSmrg      { {NULL, NULL} };
321101e04c3fSmrg
321201e04c3fSmrg   /* Find all shader outputs in the "producer" stage.
321301e04c3fSmrg    */
321401e04c3fSmrg   foreach_in_list(ir_instruction, node, producer->ir) {
321501e04c3fSmrg      ir_variable *const var = node->as_variable();
321601e04c3fSmrg
321701e04c3fSmrg      if ((var == NULL) || (var->data.mode != ir_var_shader_out))
321801e04c3fSmrg         continue;
321901e04c3fSmrg
322001e04c3fSmrg      if (var->data.explicit_location &&
322101e04c3fSmrg          var->data.location >= VARYING_SLOT_VAR0) {
322201e04c3fSmrg         const unsigned idx = var->data.location - VARYING_SLOT_VAR0;
322301e04c3fSmrg         if (explicit_locations[idx][var->data.location_frac] == NULL)
322401e04c3fSmrg            explicit_locations[idx][var->data.location_frac] = var;
3225993e1d59Smrg
3226993e1d59Smrg         /* Always match TCS outputs. They are shared by all invocations
3227993e1d59Smrg          * within a patch and can be used as shared memory.
3228993e1d59Smrg          */
3229993e1d59Smrg         if (producer->Stage == MESA_SHADER_TESS_CTRL)
3230993e1d59Smrg            var->data.is_unmatched_generic_inout = 0;
323101e04c3fSmrg      }
323201e04c3fSmrg   }
323301e04c3fSmrg
323401e04c3fSmrg   /* Match inputs to outputs */
323501e04c3fSmrg   foreach_in_list(ir_instruction, node, consumer->ir) {
323601e04c3fSmrg      ir_variable *const input = node->as_variable();
323701e04c3fSmrg
323801e04c3fSmrg      if ((input == NULL) || (input->data.mode != ir_var_shader_in))
323901e04c3fSmrg         continue;
324001e04c3fSmrg
324101e04c3fSmrg      ir_variable *output = NULL;
324201e04c3fSmrg      if (input->data.explicit_location
324301e04c3fSmrg          && input->data.location >= VARYING_SLOT_VAR0) {
324401e04c3fSmrg         output = explicit_locations[input->data.location - VARYING_SLOT_VAR0]
324501e04c3fSmrg            [input->data.location_frac];
324601e04c3fSmrg
324701e04c3fSmrg         if (output != NULL){
324801e04c3fSmrg            input->data.is_unmatched_generic_inout = 0;
324901e04c3fSmrg            output->data.is_unmatched_generic_inout = 0;
325001e04c3fSmrg         }
325101e04c3fSmrg      }
325201e04c3fSmrg   }
325301e04c3fSmrg}
325401e04c3fSmrg
325501e04c3fSmrg/**
325601e04c3fSmrg * Store the gl_FragDepth layout in the gl_shader_program struct.
325701e04c3fSmrg */
325801e04c3fSmrgstatic void
325901e04c3fSmrgstore_fragdepth_layout(struct gl_shader_program *prog)
326001e04c3fSmrg{
326101e04c3fSmrg   if (prog->_LinkedShaders[MESA_SHADER_FRAGMENT] == NULL) {
326201e04c3fSmrg      return;
326301e04c3fSmrg   }
326401e04c3fSmrg
326501e04c3fSmrg   struct exec_list *ir = prog->_LinkedShaders[MESA_SHADER_FRAGMENT]->ir;
326601e04c3fSmrg
326701e04c3fSmrg   /* We don't look up the gl_FragDepth symbol directly because if
326801e04c3fSmrg    * gl_FragDepth is not used in the shader, it's removed from the IR.
326901e04c3fSmrg    * However, the symbol won't be removed from the symbol table.
327001e04c3fSmrg    *
327101e04c3fSmrg    * We're only interested in the cases where the variable is NOT removed
327201e04c3fSmrg    * from the IR.
327301e04c3fSmrg    */
327401e04c3fSmrg   foreach_in_list(ir_instruction, node, ir) {
327501e04c3fSmrg      ir_variable *const var = node->as_variable();
327601e04c3fSmrg
327701e04c3fSmrg      if (var == NULL || var->data.mode != ir_var_shader_out) {
327801e04c3fSmrg         continue;
327901e04c3fSmrg      }
328001e04c3fSmrg
328101e04c3fSmrg      if (strcmp(var->name, "gl_FragDepth") == 0) {
328201e04c3fSmrg         switch (var->data.depth_layout) {
328301e04c3fSmrg         case ir_depth_layout_none:
328401e04c3fSmrg            prog->FragDepthLayout = FRAG_DEPTH_LAYOUT_NONE;
328501e04c3fSmrg            return;
328601e04c3fSmrg         case ir_depth_layout_any:
328701e04c3fSmrg            prog->FragDepthLayout = FRAG_DEPTH_LAYOUT_ANY;
328801e04c3fSmrg            return;
328901e04c3fSmrg         case ir_depth_layout_greater:
329001e04c3fSmrg            prog->FragDepthLayout = FRAG_DEPTH_LAYOUT_GREATER;
329101e04c3fSmrg            return;
329201e04c3fSmrg         case ir_depth_layout_less:
329301e04c3fSmrg            prog->FragDepthLayout = FRAG_DEPTH_LAYOUT_LESS;
329401e04c3fSmrg            return;
329501e04c3fSmrg         case ir_depth_layout_unchanged:
329601e04c3fSmrg            prog->FragDepthLayout = FRAG_DEPTH_LAYOUT_UNCHANGED;
329701e04c3fSmrg            return;
329801e04c3fSmrg         default:
329901e04c3fSmrg            assert(0);
330001e04c3fSmrg            return;
330101e04c3fSmrg         }
330201e04c3fSmrg      }
330301e04c3fSmrg   }
330401e04c3fSmrg}
330501e04c3fSmrg
330601e04c3fSmrg/**
330701e04c3fSmrg * Validate the resources used by a program versus the implementation limits
330801e04c3fSmrg */
330901e04c3fSmrgstatic void
331001e04c3fSmrgcheck_resources(struct gl_context *ctx, struct gl_shader_program *prog)
331101e04c3fSmrg{
331201e04c3fSmrg   unsigned total_uniform_blocks = 0;
331301e04c3fSmrg   unsigned total_shader_storage_blocks = 0;
331401e04c3fSmrg
331501e04c3fSmrg   for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
331601e04c3fSmrg      struct gl_linked_shader *sh = prog->_LinkedShaders[i];
331701e04c3fSmrg
331801e04c3fSmrg      if (sh == NULL)
331901e04c3fSmrg         continue;
332001e04c3fSmrg
332101e04c3fSmrg      if (sh->Program->info.num_textures >
332201e04c3fSmrg          ctx->Const.Program[i].MaxTextureImageUnits) {
332301e04c3fSmrg         linker_error(prog, "Too many %s shader texture samplers\n",
332401e04c3fSmrg                      _mesa_shader_stage_to_string(i));
332501e04c3fSmrg      }
332601e04c3fSmrg
332701e04c3fSmrg      if (sh->num_uniform_components >
332801e04c3fSmrg          ctx->Const.Program[i].MaxUniformComponents) {
332901e04c3fSmrg         if (ctx->Const.GLSLSkipStrictMaxUniformLimitCheck) {
333001e04c3fSmrg            linker_warning(prog, "Too many %s shader default uniform block "
333101e04c3fSmrg                           "components, but the driver will try to optimize "
333201e04c3fSmrg                           "them out; this is non-portable out-of-spec "
333301e04c3fSmrg                           "behavior\n",
333401e04c3fSmrg                           _mesa_shader_stage_to_string(i));
333501e04c3fSmrg         } else {
333601e04c3fSmrg            linker_error(prog, "Too many %s shader default uniform block "
333701e04c3fSmrg                         "components\n",
333801e04c3fSmrg                         _mesa_shader_stage_to_string(i));
333901e04c3fSmrg         }
334001e04c3fSmrg      }
334101e04c3fSmrg
334201e04c3fSmrg      if (sh->num_combined_uniform_components >
334301e04c3fSmrg          ctx->Const.Program[i].MaxCombinedUniformComponents) {
334401e04c3fSmrg         if (ctx->Const.GLSLSkipStrictMaxUniformLimitCheck) {
334501e04c3fSmrg            linker_warning(prog, "Too many %s shader uniform components, "
334601e04c3fSmrg                           "but the driver will try to optimize them out; "
334701e04c3fSmrg                           "this is non-portable out-of-spec behavior\n",
334801e04c3fSmrg                           _mesa_shader_stage_to_string(i));
334901e04c3fSmrg         } else {
335001e04c3fSmrg            linker_error(prog, "Too many %s shader uniform components\n",
335101e04c3fSmrg                         _mesa_shader_stage_to_string(i));
335201e04c3fSmrg         }
335301e04c3fSmrg      }
335401e04c3fSmrg
335501e04c3fSmrg      total_shader_storage_blocks += sh->Program->info.num_ssbos;
335601e04c3fSmrg      total_uniform_blocks += sh->Program->info.num_ubos;
335701e04c3fSmrg
335801e04c3fSmrg      const unsigned max_uniform_blocks =
335901e04c3fSmrg         ctx->Const.Program[i].MaxUniformBlocks;
336001e04c3fSmrg      if (max_uniform_blocks < sh->Program->info.num_ubos) {
336101e04c3fSmrg         linker_error(prog, "Too many %s uniform blocks (%d/%d)\n",
336201e04c3fSmrg                      _mesa_shader_stage_to_string(i),
336301e04c3fSmrg                      sh->Program->info.num_ubos, max_uniform_blocks);
336401e04c3fSmrg      }
336501e04c3fSmrg
336601e04c3fSmrg      const unsigned max_shader_storage_blocks =
336701e04c3fSmrg         ctx->Const.Program[i].MaxShaderStorageBlocks;
336801e04c3fSmrg      if (max_shader_storage_blocks < sh->Program->info.num_ssbos) {
336901e04c3fSmrg         linker_error(prog, "Too many %s shader storage blocks (%d/%d)\n",
337001e04c3fSmrg                      _mesa_shader_stage_to_string(i),
337101e04c3fSmrg                      sh->Program->info.num_ssbos, max_shader_storage_blocks);
337201e04c3fSmrg      }
337301e04c3fSmrg   }
337401e04c3fSmrg
337501e04c3fSmrg   if (total_uniform_blocks > ctx->Const.MaxCombinedUniformBlocks) {
337601e04c3fSmrg      linker_error(prog, "Too many combined uniform blocks (%d/%d)\n",
337701e04c3fSmrg                   total_uniform_blocks, ctx->Const.MaxCombinedUniformBlocks);
337801e04c3fSmrg   }
337901e04c3fSmrg
338001e04c3fSmrg   if (total_shader_storage_blocks > ctx->Const.MaxCombinedShaderStorageBlocks) {
338101e04c3fSmrg      linker_error(prog, "Too many combined shader storage blocks (%d/%d)\n",
338201e04c3fSmrg                   total_shader_storage_blocks,
338301e04c3fSmrg                   ctx->Const.MaxCombinedShaderStorageBlocks);
338401e04c3fSmrg   }
338501e04c3fSmrg
338601e04c3fSmrg   for (unsigned i = 0; i < prog->data->NumUniformBlocks; i++) {
338701e04c3fSmrg      if (prog->data->UniformBlocks[i].UniformBufferSize >
338801e04c3fSmrg          ctx->Const.MaxUniformBlockSize) {
338901e04c3fSmrg         linker_error(prog, "Uniform block %s too big (%d/%d)\n",
339001e04c3fSmrg                      prog->data->UniformBlocks[i].Name,
339101e04c3fSmrg                      prog->data->UniformBlocks[i].UniformBufferSize,
339201e04c3fSmrg                      ctx->Const.MaxUniformBlockSize);
339301e04c3fSmrg      }
339401e04c3fSmrg   }
339501e04c3fSmrg
339601e04c3fSmrg   for (unsigned i = 0; i < prog->data->NumShaderStorageBlocks; i++) {
339701e04c3fSmrg      if (prog->data->ShaderStorageBlocks[i].UniformBufferSize >
339801e04c3fSmrg          ctx->Const.MaxShaderStorageBlockSize) {
339901e04c3fSmrg         linker_error(prog, "Shader storage block %s too big (%d/%d)\n",
340001e04c3fSmrg                      prog->data->ShaderStorageBlocks[i].Name,
340101e04c3fSmrg                      prog->data->ShaderStorageBlocks[i].UniformBufferSize,
340201e04c3fSmrg                      ctx->Const.MaxShaderStorageBlockSize);
340301e04c3fSmrg      }
340401e04c3fSmrg   }
340501e04c3fSmrg}
340601e04c3fSmrg
340701e04c3fSmrgstatic void
340801e04c3fSmrglink_calculate_subroutine_compat(struct gl_shader_program *prog)
340901e04c3fSmrg{
341001e04c3fSmrg   unsigned mask = prog->data->linked_stages;
341101e04c3fSmrg   while (mask) {
341201e04c3fSmrg      const int i = u_bit_scan(&mask);
341301e04c3fSmrg      struct gl_program *p = prog->_LinkedShaders[i]->Program;
341401e04c3fSmrg
341501e04c3fSmrg      for (unsigned j = 0; j < p->sh.NumSubroutineUniformRemapTable; j++) {
341601e04c3fSmrg         if (p->sh.SubroutineUniformRemapTable[j] == INACTIVE_UNIFORM_EXPLICIT_LOCATION)
341701e04c3fSmrg            continue;
341801e04c3fSmrg
341901e04c3fSmrg         struct gl_uniform_storage *uni = p->sh.SubroutineUniformRemapTable[j];
342001e04c3fSmrg
342101e04c3fSmrg         if (!uni)
342201e04c3fSmrg            continue;
342301e04c3fSmrg
342401e04c3fSmrg         int count = 0;
342501e04c3fSmrg         if (p->sh.NumSubroutineFunctions == 0) {
342601e04c3fSmrg            linker_error(prog, "subroutine uniform %s defined but no valid functions found\n", uni->type->name);
342701e04c3fSmrg            continue;
342801e04c3fSmrg         }
342901e04c3fSmrg         for (unsigned f = 0; f < p->sh.NumSubroutineFunctions; f++) {
343001e04c3fSmrg            struct gl_subroutine_function *fn = &p->sh.SubroutineFunctions[f];
343101e04c3fSmrg            for (int k = 0; k < fn->num_compat_types; k++) {
343201e04c3fSmrg               if (fn->types[k] == uni->type) {
343301e04c3fSmrg                  count++;
343401e04c3fSmrg                  break;
343501e04c3fSmrg               }
343601e04c3fSmrg            }
343701e04c3fSmrg         }
343801e04c3fSmrg         uni->num_compatible_subroutines = count;
343901e04c3fSmrg      }
344001e04c3fSmrg   }
344101e04c3fSmrg}
344201e04c3fSmrg
344301e04c3fSmrgstatic void
344401e04c3fSmrgcheck_subroutine_resources(struct gl_shader_program *prog)
344501e04c3fSmrg{
344601e04c3fSmrg   unsigned mask = prog->data->linked_stages;
344701e04c3fSmrg   while (mask) {
344801e04c3fSmrg      const int i = u_bit_scan(&mask);
344901e04c3fSmrg      struct gl_program *p = prog->_LinkedShaders[i]->Program;
345001e04c3fSmrg
345101e04c3fSmrg      if (p->sh.NumSubroutineUniformRemapTable > MAX_SUBROUTINE_UNIFORM_LOCATIONS) {
345201e04c3fSmrg         linker_error(prog, "Too many %s shader subroutine uniforms\n",
345301e04c3fSmrg                      _mesa_shader_stage_to_string(i));
345401e04c3fSmrg      }
345501e04c3fSmrg   }
345601e04c3fSmrg}
345701e04c3fSmrg/**
345801e04c3fSmrg * Validate shader image resources.
345901e04c3fSmrg */
346001e04c3fSmrgstatic void
346101e04c3fSmrgcheck_image_resources(struct gl_context *ctx, struct gl_shader_program *prog)
346201e04c3fSmrg{
346301e04c3fSmrg   unsigned total_image_units = 0;
346401e04c3fSmrg   unsigned fragment_outputs = 0;
346501e04c3fSmrg   unsigned total_shader_storage_blocks = 0;
346601e04c3fSmrg
346701e04c3fSmrg   if (!ctx->Extensions.ARB_shader_image_load_store)
346801e04c3fSmrg      return;
346901e04c3fSmrg
347001e04c3fSmrg   for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
347101e04c3fSmrg      struct gl_linked_shader *sh = prog->_LinkedShaders[i];
347201e04c3fSmrg
347301e04c3fSmrg      if (sh) {
347401e04c3fSmrg         if (sh->Program->info.num_images > ctx->Const.Program[i].MaxImageUniforms)
347501e04c3fSmrg            linker_error(prog, "Too many %s shader image uniforms (%u > %u)\n",
347601e04c3fSmrg                         _mesa_shader_stage_to_string(i),
347701e04c3fSmrg                         sh->Program->info.num_images,
347801e04c3fSmrg                         ctx->Const.Program[i].MaxImageUniforms);
347901e04c3fSmrg
348001e04c3fSmrg         total_image_units += sh->Program->info.num_images;
348101e04c3fSmrg         total_shader_storage_blocks += sh->Program->info.num_ssbos;
348201e04c3fSmrg
348301e04c3fSmrg         if (i == MESA_SHADER_FRAGMENT) {
348401e04c3fSmrg            foreach_in_list(ir_instruction, node, sh->ir) {
348501e04c3fSmrg               ir_variable *var = node->as_variable();
348601e04c3fSmrg               if (var && var->data.mode == ir_var_shader_out)
348701e04c3fSmrg                  /* since there are no double fs outputs - pass false */
348801e04c3fSmrg                  fragment_outputs += var->type->count_attribute_slots(false);
348901e04c3fSmrg            }
349001e04c3fSmrg         }
349101e04c3fSmrg      }
349201e04c3fSmrg   }
349301e04c3fSmrg
349401e04c3fSmrg   if (total_image_units > ctx->Const.MaxCombinedImageUniforms)
349501e04c3fSmrg      linker_error(prog, "Too many combined image uniforms\n");
349601e04c3fSmrg
349701e04c3fSmrg   if (total_image_units + fragment_outputs + total_shader_storage_blocks >
349801e04c3fSmrg       ctx->Const.MaxCombinedShaderOutputResources)
349901e04c3fSmrg      linker_error(prog, "Too many combined image uniforms, shader storage "
350001e04c3fSmrg                         " buffers and fragment outputs\n");
350101e04c3fSmrg}
350201e04c3fSmrg
350301e04c3fSmrg
350401e04c3fSmrg/**
350501e04c3fSmrg * Initializes explicit location slots to INACTIVE_UNIFORM_EXPLICIT_LOCATION
350601e04c3fSmrg * for a variable, checks for overlaps between other uniforms using explicit
350701e04c3fSmrg * locations.
350801e04c3fSmrg */
350901e04c3fSmrgstatic int
351001e04c3fSmrgreserve_explicit_locations(struct gl_shader_program *prog,
351101e04c3fSmrg                           string_to_uint_map *map, ir_variable *var)
351201e04c3fSmrg{
351301e04c3fSmrg   unsigned slots = var->type->uniform_locations();
351401e04c3fSmrg   unsigned max_loc = var->data.location + slots - 1;
351501e04c3fSmrg   unsigned return_value = slots;
351601e04c3fSmrg
351701e04c3fSmrg   /* Resize remap table if locations do not fit in the current one. */
351801e04c3fSmrg   if (max_loc + 1 > prog->NumUniformRemapTable) {
351901e04c3fSmrg      prog->UniformRemapTable =
352001e04c3fSmrg         reralloc(prog, prog->UniformRemapTable,
352101e04c3fSmrg                  gl_uniform_storage *,
352201e04c3fSmrg                  max_loc + 1);
352301e04c3fSmrg
352401e04c3fSmrg      if (!prog->UniformRemapTable) {
352501e04c3fSmrg         linker_error(prog, "Out of memory during linking.\n");
352601e04c3fSmrg         return -1;
352701e04c3fSmrg      }
352801e04c3fSmrg
352901e04c3fSmrg      /* Initialize allocated space. */
353001e04c3fSmrg      for (unsigned i = prog->NumUniformRemapTable; i < max_loc + 1; i++)
353101e04c3fSmrg         prog->UniformRemapTable[i] = NULL;
353201e04c3fSmrg
353301e04c3fSmrg      prog->NumUniformRemapTable = max_loc + 1;
353401e04c3fSmrg   }
353501e04c3fSmrg
353601e04c3fSmrg   for (unsigned i = 0; i < slots; i++) {
353701e04c3fSmrg      unsigned loc = var->data.location + i;
353801e04c3fSmrg
353901e04c3fSmrg      /* Check if location is already used. */
354001e04c3fSmrg      if (prog->UniformRemapTable[loc] == INACTIVE_UNIFORM_EXPLICIT_LOCATION) {
354101e04c3fSmrg
354201e04c3fSmrg         /* Possibly same uniform from a different stage, this is ok. */
354301e04c3fSmrg         unsigned hash_loc;
354401e04c3fSmrg         if (map->get(hash_loc, var->name) && hash_loc == loc - i) {
354501e04c3fSmrg            return_value = 0;
354601e04c3fSmrg            continue;
354701e04c3fSmrg         }
354801e04c3fSmrg
354901e04c3fSmrg         /* ARB_explicit_uniform_location specification states:
355001e04c3fSmrg          *
355101e04c3fSmrg          *     "No two default-block uniform variables in the program can have
355201e04c3fSmrg          *     the same location, even if they are unused, otherwise a compiler
355301e04c3fSmrg          *     or linker error will be generated."
355401e04c3fSmrg          */
355501e04c3fSmrg         linker_error(prog,
355601e04c3fSmrg                      "location qualifier for uniform %s overlaps "
355701e04c3fSmrg                      "previously used location\n",
355801e04c3fSmrg                      var->name);
355901e04c3fSmrg         return -1;
356001e04c3fSmrg      }
356101e04c3fSmrg
356201e04c3fSmrg      /* Initialize location as inactive before optimization
356301e04c3fSmrg       * rounds and location assignment.
356401e04c3fSmrg       */
356501e04c3fSmrg      prog->UniformRemapTable[loc] = INACTIVE_UNIFORM_EXPLICIT_LOCATION;
356601e04c3fSmrg   }
356701e04c3fSmrg
356801e04c3fSmrg   /* Note, base location used for arrays. */
356901e04c3fSmrg   map->put(var->data.location, var->name);
357001e04c3fSmrg
357101e04c3fSmrg   return return_value;
357201e04c3fSmrg}
357301e04c3fSmrg
357401e04c3fSmrgstatic bool
357501e04c3fSmrgreserve_subroutine_explicit_locations(struct gl_shader_program *prog,
357601e04c3fSmrg                                      struct gl_program *p,
357701e04c3fSmrg                                      ir_variable *var)
357801e04c3fSmrg{
357901e04c3fSmrg   unsigned slots = var->type->uniform_locations();
358001e04c3fSmrg   unsigned max_loc = var->data.location + slots - 1;
358101e04c3fSmrg
358201e04c3fSmrg   /* Resize remap table if locations do not fit in the current one. */
358301e04c3fSmrg   if (max_loc + 1 > p->sh.NumSubroutineUniformRemapTable) {
358401e04c3fSmrg      p->sh.SubroutineUniformRemapTable =
358501e04c3fSmrg         reralloc(p, p->sh.SubroutineUniformRemapTable,
358601e04c3fSmrg                  gl_uniform_storage *,
358701e04c3fSmrg                  max_loc + 1);
358801e04c3fSmrg
358901e04c3fSmrg      if (!p->sh.SubroutineUniformRemapTable) {
359001e04c3fSmrg         linker_error(prog, "Out of memory during linking.\n");
359101e04c3fSmrg         return false;
359201e04c3fSmrg      }
359301e04c3fSmrg
359401e04c3fSmrg      /* Initialize allocated space. */
359501e04c3fSmrg      for (unsigned i = p->sh.NumSubroutineUniformRemapTable; i < max_loc + 1; i++)
359601e04c3fSmrg         p->sh.SubroutineUniformRemapTable[i] = NULL;
359701e04c3fSmrg
359801e04c3fSmrg      p->sh.NumSubroutineUniformRemapTable = max_loc + 1;
359901e04c3fSmrg   }
360001e04c3fSmrg
360101e04c3fSmrg   for (unsigned i = 0; i < slots; i++) {
360201e04c3fSmrg      unsigned loc = var->data.location + i;
360301e04c3fSmrg
360401e04c3fSmrg      /* Check if location is already used. */
360501e04c3fSmrg      if (p->sh.SubroutineUniformRemapTable[loc] == INACTIVE_UNIFORM_EXPLICIT_LOCATION) {
360601e04c3fSmrg
360701e04c3fSmrg         /* ARB_explicit_uniform_location specification states:
360801e04c3fSmrg          *     "No two subroutine uniform variables can have the same location
360901e04c3fSmrg          *     in the same shader stage, otherwise a compiler or linker error
361001e04c3fSmrg          *     will be generated."
361101e04c3fSmrg          */
361201e04c3fSmrg         linker_error(prog,
361301e04c3fSmrg                      "location qualifier for uniform %s overlaps "
361401e04c3fSmrg                      "previously used location\n",
361501e04c3fSmrg                      var->name);
361601e04c3fSmrg         return false;
361701e04c3fSmrg      }
361801e04c3fSmrg
361901e04c3fSmrg      /* Initialize location as inactive before optimization
362001e04c3fSmrg       * rounds and location assignment.
362101e04c3fSmrg       */
362201e04c3fSmrg      p->sh.SubroutineUniformRemapTable[loc] = INACTIVE_UNIFORM_EXPLICIT_LOCATION;
362301e04c3fSmrg   }
362401e04c3fSmrg
362501e04c3fSmrg   return true;
362601e04c3fSmrg}
362701e04c3fSmrg/**
362801e04c3fSmrg * Check and reserve all explicit uniform locations, called before
362901e04c3fSmrg * any optimizations happen to handle also inactive uniforms and
363001e04c3fSmrg * inactive array elements that may get trimmed away.
363101e04c3fSmrg */
363201e04c3fSmrgstatic void
363301e04c3fSmrgcheck_explicit_uniform_locations(struct gl_context *ctx,
363401e04c3fSmrg                                 struct gl_shader_program *prog)
363501e04c3fSmrg{
363601e04c3fSmrg   prog->NumExplicitUniformLocations = 0;
363701e04c3fSmrg
363801e04c3fSmrg   if (!ctx->Extensions.ARB_explicit_uniform_location)
363901e04c3fSmrg      return;
364001e04c3fSmrg
364101e04c3fSmrg   /* This map is used to detect if overlapping explicit locations
364201e04c3fSmrg    * occur with the same uniform (from different stage) or a different one.
364301e04c3fSmrg    */
364401e04c3fSmrg   string_to_uint_map *uniform_map = new string_to_uint_map;
364501e04c3fSmrg
364601e04c3fSmrg   if (!uniform_map) {
364701e04c3fSmrg      linker_error(prog, "Out of memory during linking.\n");
364801e04c3fSmrg      return;
364901e04c3fSmrg   }
365001e04c3fSmrg
365101e04c3fSmrg   unsigned entries_total = 0;
365201e04c3fSmrg   unsigned mask = prog->data->linked_stages;
365301e04c3fSmrg   while (mask) {
365401e04c3fSmrg      const int i = u_bit_scan(&mask);
365501e04c3fSmrg      struct gl_program *p = prog->_LinkedShaders[i]->Program;
365601e04c3fSmrg
365701e04c3fSmrg      foreach_in_list(ir_instruction, node, prog->_LinkedShaders[i]->ir) {
365801e04c3fSmrg         ir_variable *var = node->as_variable();
365901e04c3fSmrg         if (!var || var->data.mode != ir_var_uniform)
366001e04c3fSmrg            continue;
366101e04c3fSmrg
366201e04c3fSmrg         if (var->data.explicit_location) {
366301e04c3fSmrg            bool ret = false;
366401e04c3fSmrg            if (var->type->without_array()->is_subroutine())
366501e04c3fSmrg               ret = reserve_subroutine_explicit_locations(prog, p, var);
366601e04c3fSmrg            else {
366701e04c3fSmrg               int slots = reserve_explicit_locations(prog, uniform_map,
366801e04c3fSmrg                                                      var);
366901e04c3fSmrg               if (slots != -1) {
367001e04c3fSmrg                  ret = true;
367101e04c3fSmrg                  entries_total += slots;
367201e04c3fSmrg               }
367301e04c3fSmrg            }
367401e04c3fSmrg            if (!ret) {
367501e04c3fSmrg               delete uniform_map;
367601e04c3fSmrg               return;
367701e04c3fSmrg            }
367801e04c3fSmrg         }
367901e04c3fSmrg      }
368001e04c3fSmrg   }
368101e04c3fSmrg
368201e04c3fSmrg   link_util_update_empty_uniform_locations(prog);
368301e04c3fSmrg
368401e04c3fSmrg   delete uniform_map;
368501e04c3fSmrg   prog->NumExplicitUniformLocations = entries_total;
368601e04c3fSmrg}
368701e04c3fSmrg
368801e04c3fSmrgstatic bool
368901e04c3fSmrgshould_add_buffer_variable(struct gl_shader_program *shProg,
369001e04c3fSmrg                           GLenum type, const char *name)
369101e04c3fSmrg{
369201e04c3fSmrg   bool found_interface = false;
369301e04c3fSmrg   unsigned block_name_len = 0;
369401e04c3fSmrg   const char *block_name_dot = strchr(name, '.');
369501e04c3fSmrg
369601e04c3fSmrg   /* These rules only apply to buffer variables. So we return
369701e04c3fSmrg    * true for the rest of types.
369801e04c3fSmrg    */
369901e04c3fSmrg   if (type != GL_BUFFER_VARIABLE)
370001e04c3fSmrg      return true;
370101e04c3fSmrg
370201e04c3fSmrg   for (unsigned i = 0; i < shProg->data->NumShaderStorageBlocks; i++) {
370301e04c3fSmrg      const char *block_name = shProg->data->ShaderStorageBlocks[i].Name;
370401e04c3fSmrg      block_name_len = strlen(block_name);
370501e04c3fSmrg
370601e04c3fSmrg      const char *block_square_bracket = strchr(block_name, '[');
370701e04c3fSmrg      if (block_square_bracket) {
370801e04c3fSmrg         /* The block is part of an array of named interfaces,
370901e04c3fSmrg          * for the name comparison we ignore the "[x]" part.
371001e04c3fSmrg          */
371101e04c3fSmrg         block_name_len -= strlen(block_square_bracket);
371201e04c3fSmrg      }
371301e04c3fSmrg
371401e04c3fSmrg      if (block_name_dot) {
371501e04c3fSmrg         /* Check if the variable name starts with the interface
371601e04c3fSmrg          * name. The interface name (if present) should have the
371701e04c3fSmrg          * length than the interface block name we are comparing to.
371801e04c3fSmrg          */
371901e04c3fSmrg         unsigned len = strlen(name) - strlen(block_name_dot);
372001e04c3fSmrg         if (len != block_name_len)
372101e04c3fSmrg            continue;
372201e04c3fSmrg      }
372301e04c3fSmrg
372401e04c3fSmrg      if (strncmp(block_name, name, block_name_len) == 0) {
372501e04c3fSmrg         found_interface = true;
372601e04c3fSmrg         break;
372701e04c3fSmrg      }
372801e04c3fSmrg   }
372901e04c3fSmrg
373001e04c3fSmrg   /* We remove the interface name from the buffer variable name,
373101e04c3fSmrg    * including the dot that follows it.
373201e04c3fSmrg    */
373301e04c3fSmrg   if (found_interface)
373401e04c3fSmrg      name = name + block_name_len + 1;
373501e04c3fSmrg
373601e04c3fSmrg   /* The ARB_program_interface_query spec says:
373701e04c3fSmrg    *
373801e04c3fSmrg    *     "For an active shader storage block member declared as an array, an
373901e04c3fSmrg    *     entry will be generated only for the first array element, regardless
374001e04c3fSmrg    *     of its type.  For arrays of aggregate types, the enumeration rules
374101e04c3fSmrg    *     are applied recursively for the single enumerated array element."
374201e04c3fSmrg    */
374301e04c3fSmrg   const char *struct_first_dot = strchr(name, '.');
374401e04c3fSmrg   const char *first_square_bracket = strchr(name, '[');
374501e04c3fSmrg
374601e04c3fSmrg   /* The buffer variable is on top level and it is not an array */
374701e04c3fSmrg   if (!first_square_bracket) {
374801e04c3fSmrg      return true;
374901e04c3fSmrg   /* The shader storage block member is a struct, then generate the entry */
375001e04c3fSmrg   } else if (struct_first_dot && struct_first_dot < first_square_bracket) {
375101e04c3fSmrg      return true;
375201e04c3fSmrg   } else {
375301e04c3fSmrg      /* Shader storage block member is an array, only generate an entry for the
375401e04c3fSmrg       * first array element.
375501e04c3fSmrg       */
375601e04c3fSmrg      if (strncmp(first_square_bracket, "[0]", 3) == 0)
375701e04c3fSmrg         return true;
375801e04c3fSmrg   }
375901e04c3fSmrg
376001e04c3fSmrg   return false;
376101e04c3fSmrg}
376201e04c3fSmrg
376301e04c3fSmrg/* Function checks if a variable var is a packed varying and
376401e04c3fSmrg * if given name is part of packed varying's list.
376501e04c3fSmrg *
376601e04c3fSmrg * If a variable is a packed varying, it has a name like
376701e04c3fSmrg * 'packed:a,b,c' where a, b and c are separate variables.
376801e04c3fSmrg */
376901e04c3fSmrgstatic bool
377001e04c3fSmrgincluded_in_packed_varying(ir_variable *var, const char *name)
377101e04c3fSmrg{
377201e04c3fSmrg   if (strncmp(var->name, "packed:", 7) != 0)
377301e04c3fSmrg      return false;
377401e04c3fSmrg
377501e04c3fSmrg   char *list = strdup(var->name + 7);
377601e04c3fSmrg   assert(list);
377701e04c3fSmrg
377801e04c3fSmrg   bool found = false;
377901e04c3fSmrg   char *saveptr;
378001e04c3fSmrg   char *token = strtok_r(list, ",", &saveptr);
378101e04c3fSmrg   while (token) {
378201e04c3fSmrg      if (strcmp(token, name) == 0) {
378301e04c3fSmrg         found = true;
378401e04c3fSmrg         break;
378501e04c3fSmrg      }
378601e04c3fSmrg      token = strtok_r(NULL, ",", &saveptr);
378701e04c3fSmrg   }
378801e04c3fSmrg   free(list);
378901e04c3fSmrg   return found;
379001e04c3fSmrg}
379101e04c3fSmrg
379201e04c3fSmrg/**
379301e04c3fSmrg * Function builds a stage reference bitmask from variable name.
379401e04c3fSmrg */
379501e04c3fSmrgstatic uint8_t
379601e04c3fSmrgbuild_stageref(struct gl_shader_program *shProg, const char *name,
379701e04c3fSmrg               unsigned mode)
379801e04c3fSmrg{
379901e04c3fSmrg   uint8_t stages = 0;
380001e04c3fSmrg
380101e04c3fSmrg   /* Note, that we assume MAX 8 stages, if there will be more stages, type
380201e04c3fSmrg    * used for reference mask in gl_program_resource will need to be changed.
380301e04c3fSmrg    */
380401e04c3fSmrg   assert(MESA_SHADER_STAGES < 8);
380501e04c3fSmrg
380601e04c3fSmrg   for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
380701e04c3fSmrg      struct gl_linked_shader *sh = shProg->_LinkedShaders[i];
380801e04c3fSmrg      if (!sh)
380901e04c3fSmrg         continue;
381001e04c3fSmrg
381101e04c3fSmrg      /* Shader symbol table may contain variables that have
381201e04c3fSmrg       * been optimized away. Search IR for the variable instead.
381301e04c3fSmrg       */
381401e04c3fSmrg      foreach_in_list(ir_instruction, node, sh->ir) {
381501e04c3fSmrg         ir_variable *var = node->as_variable();
381601e04c3fSmrg         if (var) {
381701e04c3fSmrg            unsigned baselen = strlen(var->name);
381801e04c3fSmrg
381901e04c3fSmrg            if (included_in_packed_varying(var, name)) {
382001e04c3fSmrg                  stages |= (1 << i);
382101e04c3fSmrg                  break;
382201e04c3fSmrg            }
382301e04c3fSmrg
382401e04c3fSmrg            /* Type needs to match if specified, otherwise we might
382501e04c3fSmrg             * pick a variable with same name but different interface.
382601e04c3fSmrg             */
382701e04c3fSmrg            if (var->data.mode != mode)
382801e04c3fSmrg               continue;
382901e04c3fSmrg
383001e04c3fSmrg            if (strncmp(var->name, name, baselen) == 0) {
383101e04c3fSmrg               /* Check for exact name matches but also check for arrays and
383201e04c3fSmrg                * structs.
383301e04c3fSmrg                */
383401e04c3fSmrg               if (name[baselen] == '\0' ||
383501e04c3fSmrg                   name[baselen] == '[' ||
383601e04c3fSmrg                   name[baselen] == '.') {
383701e04c3fSmrg                  stages |= (1 << i);
383801e04c3fSmrg                  break;
383901e04c3fSmrg               }
384001e04c3fSmrg            }
384101e04c3fSmrg         }
384201e04c3fSmrg      }
384301e04c3fSmrg   }
384401e04c3fSmrg   return stages;
384501e04c3fSmrg}
384601e04c3fSmrg
384701e04c3fSmrg/**
384801e04c3fSmrg * Create gl_shader_variable from ir_variable class.
384901e04c3fSmrg */
385001e04c3fSmrgstatic gl_shader_variable *
385101e04c3fSmrgcreate_shader_variable(struct gl_shader_program *shProg,
385201e04c3fSmrg                       const ir_variable *in,
385301e04c3fSmrg                       const char *name, const glsl_type *type,
385401e04c3fSmrg                       const glsl_type *interface_type,
385501e04c3fSmrg                       bool use_implicit_location, int location,
385601e04c3fSmrg                       const glsl_type *outermost_struct_type)
385701e04c3fSmrg{
385801e04c3fSmrg   /* Allocate zero-initialized memory to ensure that bitfield padding
385901e04c3fSmrg    * is zero.
386001e04c3fSmrg    */
386101e04c3fSmrg   gl_shader_variable *out = rzalloc(shProg, struct gl_shader_variable);
386201e04c3fSmrg   if (!out)
386301e04c3fSmrg      return NULL;
386401e04c3fSmrg
386501e04c3fSmrg   /* Since gl_VertexID may be lowered to gl_VertexIDMESA, but applications
386601e04c3fSmrg    * expect to see gl_VertexID in the program resource list.  Pretend.
386701e04c3fSmrg    */
386801e04c3fSmrg   if (in->data.mode == ir_var_system_value &&
386901e04c3fSmrg       in->data.location == SYSTEM_VALUE_VERTEX_ID_ZERO_BASE) {
387001e04c3fSmrg      out->name = ralloc_strdup(shProg, "gl_VertexID");
387101e04c3fSmrg   } else if ((in->data.mode == ir_var_shader_out &&
387201e04c3fSmrg               in->data.location == VARYING_SLOT_TESS_LEVEL_OUTER) ||
387301e04c3fSmrg              (in->data.mode == ir_var_system_value &&
387401e04c3fSmrg               in->data.location == SYSTEM_VALUE_TESS_LEVEL_OUTER)) {
387501e04c3fSmrg      out->name = ralloc_strdup(shProg, "gl_TessLevelOuter");
387601e04c3fSmrg      type = glsl_type::get_array_instance(glsl_type::float_type, 4);
387701e04c3fSmrg   } else if ((in->data.mode == ir_var_shader_out &&
387801e04c3fSmrg               in->data.location == VARYING_SLOT_TESS_LEVEL_INNER) ||
387901e04c3fSmrg              (in->data.mode == ir_var_system_value &&
388001e04c3fSmrg               in->data.location == SYSTEM_VALUE_TESS_LEVEL_INNER)) {
388101e04c3fSmrg      out->name = ralloc_strdup(shProg, "gl_TessLevelInner");
388201e04c3fSmrg      type = glsl_type::get_array_instance(glsl_type::float_type, 2);
388301e04c3fSmrg   } else {
388401e04c3fSmrg      out->name = ralloc_strdup(shProg, name);
388501e04c3fSmrg   }
388601e04c3fSmrg
388701e04c3fSmrg   if (!out->name)
388801e04c3fSmrg      return NULL;
388901e04c3fSmrg
389001e04c3fSmrg   /* The ARB_program_interface_query spec says:
389101e04c3fSmrg    *
389201e04c3fSmrg    *     "Not all active variables are assigned valid locations; the
389301e04c3fSmrg    *     following variables will have an effective location of -1:
389401e04c3fSmrg    *
389501e04c3fSmrg    *      * uniforms declared as atomic counters;
389601e04c3fSmrg    *
389701e04c3fSmrg    *      * members of a uniform block;
389801e04c3fSmrg    *
389901e04c3fSmrg    *      * built-in inputs, outputs, and uniforms (starting with "gl_"); and
390001e04c3fSmrg    *
390101e04c3fSmrg    *      * inputs or outputs not declared with a "location" layout
390201e04c3fSmrg    *        qualifier, except for vertex shader inputs and fragment shader
390301e04c3fSmrg    *        outputs."
390401e04c3fSmrg    */
390501e04c3fSmrg   if (in->type->is_atomic_uint() || is_gl_identifier(in->name) ||
390601e04c3fSmrg       !(in->data.explicit_location || use_implicit_location)) {
390701e04c3fSmrg      out->location = -1;
390801e04c3fSmrg   } else {
390901e04c3fSmrg      out->location = location;
391001e04c3fSmrg   }
391101e04c3fSmrg
391201e04c3fSmrg   out->type = type;
391301e04c3fSmrg   out->outermost_struct_type = outermost_struct_type;
391401e04c3fSmrg   out->interface_type = interface_type;
391501e04c3fSmrg   out->component = in->data.location_frac;
391601e04c3fSmrg   out->index = in->data.index;
391701e04c3fSmrg   out->patch = in->data.patch;
391801e04c3fSmrg   out->mode = in->data.mode;
391901e04c3fSmrg   out->interpolation = in->data.interpolation;
392001e04c3fSmrg   out->explicit_location = in->data.explicit_location;
392101e04c3fSmrg   out->precision = in->data.precision;
392201e04c3fSmrg
392301e04c3fSmrg   return out;
392401e04c3fSmrg}
392501e04c3fSmrg
392601e04c3fSmrgstatic bool
392701e04c3fSmrgadd_shader_variable(const struct gl_context *ctx,
392801e04c3fSmrg                    struct gl_shader_program *shProg,
392901e04c3fSmrg                    struct set *resource_set,
393001e04c3fSmrg                    unsigned stage_mask,
393101e04c3fSmrg                    GLenum programInterface, ir_variable *var,
393201e04c3fSmrg                    const char *name, const glsl_type *type,
393301e04c3fSmrg                    bool use_implicit_location, int location,
393401e04c3fSmrg                    bool inouts_share_location,
393501e04c3fSmrg                    const glsl_type *outermost_struct_type = NULL)
393601e04c3fSmrg{
393701e04c3fSmrg   const glsl_type *interface_type = var->get_interface_type();
393801e04c3fSmrg
393901e04c3fSmrg   if (outermost_struct_type == NULL) {
394001e04c3fSmrg      if (var->data.from_named_ifc_block) {
394101e04c3fSmrg         const char *interface_name = interface_type->name;
394201e04c3fSmrg
394301e04c3fSmrg         if (interface_type->is_array()) {
394401e04c3fSmrg            /* Issue #16 of the ARB_program_interface_query spec says:
394501e04c3fSmrg             *
394601e04c3fSmrg             * "* If a variable is a member of an interface block without an
394701e04c3fSmrg             *    instance name, it is enumerated using just the variable name.
394801e04c3fSmrg             *
394901e04c3fSmrg             *  * If a variable is a member of an interface block with an
395001e04c3fSmrg             *    instance name, it is enumerated as "BlockName.Member", where
395101e04c3fSmrg             *    "BlockName" is the name of the interface block (not the
395201e04c3fSmrg             *    instance name) and "Member" is the name of the variable."
395301e04c3fSmrg             *
395401e04c3fSmrg             * In particular, it indicates that it should be "BlockName",
395501e04c3fSmrg             * not "BlockName[array length]".  The conformance suite and
395601e04c3fSmrg             * dEQP both require this behavior.
395701e04c3fSmrg             *
395801e04c3fSmrg             * Here, we unwrap the extra array level added by named interface
395901e04c3fSmrg             * block array lowering so we have the correct variable type.  We
396001e04c3fSmrg             * also unwrap the interface type when constructing the name.
396101e04c3fSmrg             *
396201e04c3fSmrg             * We leave interface_type the same so that ES 3.x SSO pipeline
396301e04c3fSmrg             * validation can enforce the rules requiring array length to
396401e04c3fSmrg             * match on interface blocks.
396501e04c3fSmrg             */
396601e04c3fSmrg            type = type->fields.array;
396701e04c3fSmrg
396801e04c3fSmrg            interface_name = interface_type->fields.array->name;
396901e04c3fSmrg         }
397001e04c3fSmrg
397101e04c3fSmrg         name = ralloc_asprintf(shProg, "%s.%s", interface_name, name);
397201e04c3fSmrg      }
397301e04c3fSmrg   }
397401e04c3fSmrg
397501e04c3fSmrg   switch (type->base_type) {
397601e04c3fSmrg   case GLSL_TYPE_STRUCT: {
397701e04c3fSmrg      /* The ARB_program_interface_query spec says:
397801e04c3fSmrg       *
397901e04c3fSmrg       *     "For an active variable declared as a structure, a separate entry
398001e04c3fSmrg       *     will be generated for each active structure member.  The name of
398101e04c3fSmrg       *     each entry is formed by concatenating the name of the structure,
398201e04c3fSmrg       *     the "."  character, and the name of the structure member.  If a
398301e04c3fSmrg       *     structure member to enumerate is itself a structure or array,
398401e04c3fSmrg       *     these enumeration rules are applied recursively."
398501e04c3fSmrg       */
398601e04c3fSmrg      if (outermost_struct_type == NULL)
398701e04c3fSmrg         outermost_struct_type = type;
398801e04c3fSmrg
398901e04c3fSmrg      unsigned field_location = location;
399001e04c3fSmrg      for (unsigned i = 0; i < type->length; i++) {
399101e04c3fSmrg         const struct glsl_struct_field *field = &type->fields.structure[i];
399201e04c3fSmrg         char *field_name = ralloc_asprintf(shProg, "%s.%s", name, field->name);
399301e04c3fSmrg         if (!add_shader_variable(ctx, shProg, resource_set,
399401e04c3fSmrg                                  stage_mask, programInterface,
399501e04c3fSmrg                                  var, field_name, field->type,
399601e04c3fSmrg                                  use_implicit_location, field_location,
399701e04c3fSmrg                                  false, outermost_struct_type))
399801e04c3fSmrg            return false;
399901e04c3fSmrg
400001e04c3fSmrg         field_location += field->type->count_attribute_slots(false);
400101e04c3fSmrg      }
400201e04c3fSmrg      return true;
400301e04c3fSmrg   }
400401e04c3fSmrg
400501e04c3fSmrg   case GLSL_TYPE_ARRAY: {
400601e04c3fSmrg      /* The ARB_program_interface_query spec says:
400701e04c3fSmrg       *
400801e04c3fSmrg       *     "For an active variable declared as an array of basic types, a
400901e04c3fSmrg       *      single entry will be generated, with its name string formed by
401001e04c3fSmrg       *      concatenating the name of the array and the string "[0]"."
401101e04c3fSmrg       *
401201e04c3fSmrg       *     "For an active variable declared as an array of an aggregate data
401301e04c3fSmrg       *      type (structures or arrays), a separate entry will be generated
401401e04c3fSmrg       *      for each active array element, unless noted immediately below.
401501e04c3fSmrg       *      The name of each entry is formed by concatenating the name of
401601e04c3fSmrg       *      the array, the "[" character, an integer identifying the element
401701e04c3fSmrg       *      number, and the "]" character.  These enumeration rules are
401801e04c3fSmrg       *      applied recursively, treating each enumerated array element as a
401901e04c3fSmrg       *      separate active variable."
402001e04c3fSmrg       */
402101e04c3fSmrg      const struct glsl_type *array_type = type->fields.array;
402201e04c3fSmrg      if (array_type->base_type == GLSL_TYPE_STRUCT ||
402301e04c3fSmrg          array_type->base_type == GLSL_TYPE_ARRAY) {
402401e04c3fSmrg         unsigned elem_location = location;
402501e04c3fSmrg         unsigned stride = inouts_share_location ? 0 :
402601e04c3fSmrg                           array_type->count_attribute_slots(false);
402701e04c3fSmrg         for (unsigned i = 0; i < type->length; i++) {
402801e04c3fSmrg            char *elem = ralloc_asprintf(shProg, "%s[%d]", name, i);
402901e04c3fSmrg            if (!add_shader_variable(ctx, shProg, resource_set,
403001e04c3fSmrg                                     stage_mask, programInterface,
403101e04c3fSmrg                                     var, elem, array_type,
403201e04c3fSmrg                                     use_implicit_location, elem_location,
403301e04c3fSmrg                                     false, outermost_struct_type))
403401e04c3fSmrg               return false;
403501e04c3fSmrg            elem_location += stride;
403601e04c3fSmrg         }
403701e04c3fSmrg         return true;
403801e04c3fSmrg      }
403901e04c3fSmrg      /* fallthrough */
404001e04c3fSmrg   }
404101e04c3fSmrg
404201e04c3fSmrg   default: {
404301e04c3fSmrg      /* The ARB_program_interface_query spec says:
404401e04c3fSmrg       *
404501e04c3fSmrg       *     "For an active variable declared as a single instance of a basic
404601e04c3fSmrg       *     type, a single entry will be generated, using the variable name
404701e04c3fSmrg       *     from the shader source."
404801e04c3fSmrg       */
404901e04c3fSmrg      gl_shader_variable *sha_v =
405001e04c3fSmrg         create_shader_variable(shProg, var, name, type, interface_type,
405101e04c3fSmrg                                use_implicit_location, location,
405201e04c3fSmrg                                outermost_struct_type);
405301e04c3fSmrg      if (!sha_v)
405401e04c3fSmrg         return false;
405501e04c3fSmrg
405601e04c3fSmrg      return link_util_add_program_resource(shProg, resource_set,
405701e04c3fSmrg                                            programInterface, sha_v, stage_mask);
405801e04c3fSmrg   }
405901e04c3fSmrg   }
406001e04c3fSmrg}
406101e04c3fSmrg
406201e04c3fSmrgstatic bool
406301e04c3fSmrginout_has_same_location(const ir_variable *var, unsigned stage)
406401e04c3fSmrg{
406501e04c3fSmrg   if (!var->data.patch &&
406601e04c3fSmrg       ((var->data.mode == ir_var_shader_out &&
406701e04c3fSmrg         stage == MESA_SHADER_TESS_CTRL) ||
406801e04c3fSmrg        (var->data.mode == ir_var_shader_in &&
406901e04c3fSmrg         (stage == MESA_SHADER_TESS_CTRL || stage == MESA_SHADER_TESS_EVAL ||
407001e04c3fSmrg          stage == MESA_SHADER_GEOMETRY))))
407101e04c3fSmrg      return true;
407201e04c3fSmrg   else
407301e04c3fSmrg      return false;
407401e04c3fSmrg}
407501e04c3fSmrg
407601e04c3fSmrgstatic bool
407701e04c3fSmrgadd_interface_variables(const struct gl_context *ctx,
407801e04c3fSmrg                        struct gl_shader_program *shProg,
407901e04c3fSmrg                        struct set *resource_set,
408001e04c3fSmrg                        unsigned stage, GLenum programInterface)
408101e04c3fSmrg{
408201e04c3fSmrg   exec_list *ir = shProg->_LinkedShaders[stage]->ir;
408301e04c3fSmrg
408401e04c3fSmrg   foreach_in_list(ir_instruction, node, ir) {
408501e04c3fSmrg      ir_variable *var = node->as_variable();
408601e04c3fSmrg
408701e04c3fSmrg      if (!var || var->data.how_declared == ir_var_hidden)
408801e04c3fSmrg         continue;
408901e04c3fSmrg
409001e04c3fSmrg      int loc_bias;
409101e04c3fSmrg
409201e04c3fSmrg      switch (var->data.mode) {
409301e04c3fSmrg      case ir_var_system_value:
409401e04c3fSmrg      case ir_var_shader_in:
409501e04c3fSmrg         if (programInterface != GL_PROGRAM_INPUT)
409601e04c3fSmrg            continue;
409701e04c3fSmrg         loc_bias = (stage == MESA_SHADER_VERTEX) ? int(VERT_ATTRIB_GENERIC0)
409801e04c3fSmrg                                                  : int(VARYING_SLOT_VAR0);
409901e04c3fSmrg         break;
410001e04c3fSmrg      case ir_var_shader_out:
410101e04c3fSmrg         if (programInterface != GL_PROGRAM_OUTPUT)
410201e04c3fSmrg            continue;
410301e04c3fSmrg         loc_bias = (stage == MESA_SHADER_FRAGMENT) ? int(FRAG_RESULT_DATA0)
410401e04c3fSmrg                                                    : int(VARYING_SLOT_VAR0);
410501e04c3fSmrg         break;
410601e04c3fSmrg      default:
410701e04c3fSmrg         continue;
410801e04c3fSmrg      };
410901e04c3fSmrg
411001e04c3fSmrg      if (var->data.patch)
411101e04c3fSmrg         loc_bias = int(VARYING_SLOT_PATCH0);
411201e04c3fSmrg
411301e04c3fSmrg      /* Skip packed varyings, packed varyings are handled separately
411401e04c3fSmrg       * by add_packed_varyings.
411501e04c3fSmrg       */
411601e04c3fSmrg      if (strncmp(var->name, "packed:", 7) == 0)
411701e04c3fSmrg         continue;
411801e04c3fSmrg
411901e04c3fSmrg      /* Skip fragdata arrays, these are handled separately
412001e04c3fSmrg       * by add_fragdata_arrays.
412101e04c3fSmrg       */
412201e04c3fSmrg      if (strncmp(var->name, "gl_out_FragData", 15) == 0)
412301e04c3fSmrg         continue;
412401e04c3fSmrg
412501e04c3fSmrg      const bool vs_input_or_fs_output =
412601e04c3fSmrg         (stage == MESA_SHADER_VERTEX && var->data.mode == ir_var_shader_in) ||
412701e04c3fSmrg         (stage == MESA_SHADER_FRAGMENT && var->data.mode == ir_var_shader_out);
412801e04c3fSmrg
412901e04c3fSmrg      if (!add_shader_variable(ctx, shProg, resource_set,
413001e04c3fSmrg                               1 << stage, programInterface,
413101e04c3fSmrg                               var, var->name, var->type, vs_input_or_fs_output,
413201e04c3fSmrg                               var->data.location - loc_bias,
413301e04c3fSmrg                               inout_has_same_location(var, stage)))
413401e04c3fSmrg         return false;
413501e04c3fSmrg   }
413601e04c3fSmrg   return true;
413701e04c3fSmrg}
413801e04c3fSmrg
413901e04c3fSmrgstatic bool
414001e04c3fSmrgadd_packed_varyings(const struct gl_context *ctx,
414101e04c3fSmrg                    struct gl_shader_program *shProg,
414201e04c3fSmrg                    struct set *resource_set,
414301e04c3fSmrg                    int stage, GLenum type)
414401e04c3fSmrg{
414501e04c3fSmrg   struct gl_linked_shader *sh = shProg->_LinkedShaders[stage];
414601e04c3fSmrg   GLenum iface;
414701e04c3fSmrg
414801e04c3fSmrg   if (!sh || !sh->packed_varyings)
414901e04c3fSmrg      return true;
415001e04c3fSmrg
415101e04c3fSmrg   foreach_in_list(ir_instruction, node, sh->packed_varyings) {
415201e04c3fSmrg      ir_variable *var = node->as_variable();
415301e04c3fSmrg      if (var) {
415401e04c3fSmrg         switch (var->data.mode) {
415501e04c3fSmrg         case ir_var_shader_in:
415601e04c3fSmrg            iface = GL_PROGRAM_INPUT;
415701e04c3fSmrg            break;
415801e04c3fSmrg         case ir_var_shader_out:
415901e04c3fSmrg            iface = GL_PROGRAM_OUTPUT;
416001e04c3fSmrg            break;
416101e04c3fSmrg         default:
416201e04c3fSmrg            unreachable("unexpected type");
416301e04c3fSmrg         }
416401e04c3fSmrg
416501e04c3fSmrg         if (type == iface) {
416601e04c3fSmrg            const int stage_mask =
416701e04c3fSmrg               build_stageref(shProg, var->name, var->data.mode);
416801e04c3fSmrg            if (!add_shader_variable(ctx, shProg, resource_set,
416901e04c3fSmrg                                     stage_mask,
417001e04c3fSmrg                                     iface, var, var->name, var->type, false,
417101e04c3fSmrg                                     var->data.location - VARYING_SLOT_VAR0,
417201e04c3fSmrg                                     inout_has_same_location(var, stage)))
417301e04c3fSmrg               return false;
417401e04c3fSmrg         }
417501e04c3fSmrg      }
417601e04c3fSmrg   }
417701e04c3fSmrg   return true;
417801e04c3fSmrg}
417901e04c3fSmrg
418001e04c3fSmrgstatic bool
418101e04c3fSmrgadd_fragdata_arrays(const struct gl_context *ctx,
418201e04c3fSmrg                    struct gl_shader_program *shProg,
418301e04c3fSmrg                    struct set *resource_set)
418401e04c3fSmrg{
418501e04c3fSmrg   struct gl_linked_shader *sh = shProg->_LinkedShaders[MESA_SHADER_FRAGMENT];
418601e04c3fSmrg
418701e04c3fSmrg   if (!sh || !sh->fragdata_arrays)
418801e04c3fSmrg      return true;
418901e04c3fSmrg
419001e04c3fSmrg   foreach_in_list(ir_instruction, node, sh->fragdata_arrays) {
419101e04c3fSmrg      ir_variable *var = node->as_variable();
419201e04c3fSmrg      if (var) {
419301e04c3fSmrg         assert(var->data.mode == ir_var_shader_out);
419401e04c3fSmrg
419501e04c3fSmrg         if (!add_shader_variable(ctx, shProg, resource_set,
419601e04c3fSmrg                                  1 << MESA_SHADER_FRAGMENT,
419701e04c3fSmrg                                  GL_PROGRAM_OUTPUT, var, var->name, var->type,
419801e04c3fSmrg                                  true, var->data.location - FRAG_RESULT_DATA0,
419901e04c3fSmrg                                  false))
420001e04c3fSmrg            return false;
420101e04c3fSmrg      }
420201e04c3fSmrg   }
420301e04c3fSmrg   return true;
420401e04c3fSmrg}
420501e04c3fSmrg
420601e04c3fSmrgstatic char*
420701e04c3fSmrgget_top_level_name(const char *name)
420801e04c3fSmrg{
420901e04c3fSmrg   const char *first_dot = strchr(name, '.');
421001e04c3fSmrg   const char *first_square_bracket = strchr(name, '[');
421101e04c3fSmrg   int name_size = 0;
421201e04c3fSmrg
421301e04c3fSmrg   /* The ARB_program_interface_query spec says:
421401e04c3fSmrg    *
421501e04c3fSmrg    *     "For the property TOP_LEVEL_ARRAY_SIZE, a single integer identifying
421601e04c3fSmrg    *     the number of active array elements of the top-level shader storage
421701e04c3fSmrg    *     block member containing to the active variable is written to
421801e04c3fSmrg    *     <params>.  If the top-level block member is not declared as an
421901e04c3fSmrg    *     array, the value one is written to <params>.  If the top-level block
422001e04c3fSmrg    *     member is an array with no declared size, the value zero is written
422101e04c3fSmrg    *     to <params>."
422201e04c3fSmrg    */
422301e04c3fSmrg
422401e04c3fSmrg   /* The buffer variable is on top level.*/
422501e04c3fSmrg   if (!first_square_bracket && !first_dot)
422601e04c3fSmrg      name_size = strlen(name);
422701e04c3fSmrg   else if ((!first_square_bracket ||
422801e04c3fSmrg            (first_dot && first_dot < first_square_bracket)))
422901e04c3fSmrg      name_size = first_dot - name;
423001e04c3fSmrg   else
423101e04c3fSmrg      name_size = first_square_bracket - name;
423201e04c3fSmrg
423301e04c3fSmrg   return strndup(name, name_size);
423401e04c3fSmrg}
423501e04c3fSmrg
423601e04c3fSmrgstatic char*
423701e04c3fSmrgget_var_name(const char *name)
423801e04c3fSmrg{
423901e04c3fSmrg   const char *first_dot = strchr(name, '.');
424001e04c3fSmrg
424101e04c3fSmrg   if (!first_dot)
424201e04c3fSmrg      return strdup(name);
424301e04c3fSmrg
424401e04c3fSmrg   return strndup(first_dot+1, strlen(first_dot) - 1);
424501e04c3fSmrg}
424601e04c3fSmrg
424701e04c3fSmrgstatic bool
424801e04c3fSmrgis_top_level_shader_storage_block_member(const char* name,
424901e04c3fSmrg                                         const char* interface_name,
425001e04c3fSmrg                                         const char* field_name)
425101e04c3fSmrg{
425201e04c3fSmrg   bool result = false;
425301e04c3fSmrg
425401e04c3fSmrg   /* If the given variable is already a top-level shader storage
425501e04c3fSmrg    * block member, then return array_size = 1.
425601e04c3fSmrg    * We could have two possibilities: if we have an instanced
425701e04c3fSmrg    * shader storage block or not instanced.
425801e04c3fSmrg    *
425901e04c3fSmrg    * For the first, we check create a name as it was in top level and
426001e04c3fSmrg    * compare it with the real name. If they are the same, then
426101e04c3fSmrg    * the variable is already at top-level.
426201e04c3fSmrg    *
426301e04c3fSmrg    * Full instanced name is: interface name + '.' + var name +
426401e04c3fSmrg    *    NULL character
426501e04c3fSmrg    */
426601e04c3fSmrg   int name_length = strlen(interface_name) + 1 + strlen(field_name) + 1;
426701e04c3fSmrg   char *full_instanced_name = (char *) calloc(name_length, sizeof(char));
426801e04c3fSmrg   if (!full_instanced_name) {
426901e04c3fSmrg      fprintf(stderr, "%s: Cannot allocate space for name\n", __func__);
427001e04c3fSmrg      return false;
427101e04c3fSmrg   }
427201e04c3fSmrg
427301e04c3fSmrg   util_snprintf(full_instanced_name, name_length, "%s.%s",
427401e04c3fSmrg                 interface_name, field_name);
427501e04c3fSmrg
427601e04c3fSmrg   /* Check if its top-level shader storage block member of an
427701e04c3fSmrg    * instanced interface block, or of a unnamed interface block.
427801e04c3fSmrg    */
427901e04c3fSmrg   if (strcmp(name, full_instanced_name) == 0 ||
428001e04c3fSmrg       strcmp(name, field_name) == 0)
428101e04c3fSmrg      result = true;
428201e04c3fSmrg
428301e04c3fSmrg   free(full_instanced_name);
428401e04c3fSmrg   return result;
428501e04c3fSmrg}
428601e04c3fSmrg
428701e04c3fSmrgstatic int
428801e04c3fSmrgget_array_size(struct gl_uniform_storage *uni, const glsl_struct_field *field,
428901e04c3fSmrg               char *interface_name, char *var_name)
429001e04c3fSmrg{
429101e04c3fSmrg   /* The ARB_program_interface_query spec says:
429201e04c3fSmrg    *
429301e04c3fSmrg    *     "For the property TOP_LEVEL_ARRAY_SIZE, a single integer identifying
429401e04c3fSmrg    *     the number of active array elements of the top-level shader storage
429501e04c3fSmrg    *     block member containing to the active variable is written to
429601e04c3fSmrg    *     <params>.  If the top-level block member is not declared as an
429701e04c3fSmrg    *     array, the value one is written to <params>.  If the top-level block
429801e04c3fSmrg    *     member is an array with no declared size, the value zero is written
429901e04c3fSmrg    *     to <params>."
430001e04c3fSmrg    */
430101e04c3fSmrg   if (is_top_level_shader_storage_block_member(uni->name,
430201e04c3fSmrg                                                interface_name,
430301e04c3fSmrg                                                var_name))
430401e04c3fSmrg      return  1;
430501e04c3fSmrg   else if (field->type->is_unsized_array())
430601e04c3fSmrg      return 0;
430701e04c3fSmrg   else if (field->type->is_array())
430801e04c3fSmrg      return field->type->length;
430901e04c3fSmrg
431001e04c3fSmrg   return 1;
431101e04c3fSmrg}
431201e04c3fSmrg
431301e04c3fSmrgstatic int
431401e04c3fSmrgget_array_stride(struct gl_context *ctx, struct gl_uniform_storage *uni,
431501e04c3fSmrg                 const glsl_type *iface, const glsl_struct_field *field,
431601e04c3fSmrg                 char *interface_name, char *var_name)
431701e04c3fSmrg{
431801e04c3fSmrg   /* The ARB_program_interface_query spec says:
431901e04c3fSmrg    *
432001e04c3fSmrg    *     "For the property TOP_LEVEL_ARRAY_STRIDE, a single integer
432101e04c3fSmrg    *     identifying the stride between array elements of the top-level
432201e04c3fSmrg    *     shader storage block member containing the active variable is
432301e04c3fSmrg    *     written to <params>.  For top-level block members declared as
432401e04c3fSmrg    *     arrays, the value written is the difference, in basic machine units,
432501e04c3fSmrg    *     between the offsets of the active variable for consecutive elements
432601e04c3fSmrg    *     in the top-level array.  For top-level block members not declared as
432701e04c3fSmrg    *     an array, zero is written to <params>."
432801e04c3fSmrg    */
432901e04c3fSmrg   if (field->type->is_array()) {
433001e04c3fSmrg      const enum glsl_matrix_layout matrix_layout =
433101e04c3fSmrg         glsl_matrix_layout(field->matrix_layout);
433201e04c3fSmrg      bool row_major = matrix_layout == GLSL_MATRIX_LAYOUT_ROW_MAJOR;
433301e04c3fSmrg      const glsl_type *array_type = field->type->fields.array;
433401e04c3fSmrg
433501e04c3fSmrg      if (is_top_level_shader_storage_block_member(uni->name,
433601e04c3fSmrg                                                   interface_name,
433701e04c3fSmrg                                                   var_name))
433801e04c3fSmrg         return 0;
433901e04c3fSmrg
434001e04c3fSmrg      if (GLSL_INTERFACE_PACKING_STD140 ==
434101e04c3fSmrg          iface->
434201e04c3fSmrg             get_internal_ifc_packing(ctx->Const.UseSTD430AsDefaultPacking)) {
43437e102996Smaya         if (array_type->is_struct() || array_type->is_array())
434401e04c3fSmrg            return glsl_align(array_type->std140_size(row_major), 16);
434501e04c3fSmrg         else
434601e04c3fSmrg            return MAX2(array_type->std140_base_alignment(row_major), 16);
434701e04c3fSmrg      } else {
434801e04c3fSmrg         return array_type->std430_array_stride(row_major);
434901e04c3fSmrg      }
435001e04c3fSmrg   }
435101e04c3fSmrg   return 0;
435201e04c3fSmrg}
435301e04c3fSmrg
435401e04c3fSmrgstatic void
435501e04c3fSmrgcalculate_array_size_and_stride(struct gl_context *ctx,
435601e04c3fSmrg                                struct gl_shader_program *shProg,
435701e04c3fSmrg                                struct gl_uniform_storage *uni)
435801e04c3fSmrg{
435901e04c3fSmrg   int block_index = uni->block_index;
436001e04c3fSmrg   int array_size = -1;
436101e04c3fSmrg   int array_stride = -1;
436201e04c3fSmrg   char *var_name = get_top_level_name(uni->name);
436301e04c3fSmrg   char *interface_name =
436401e04c3fSmrg      get_top_level_name(uni->is_shader_storage ?
436501e04c3fSmrg                         shProg->data->ShaderStorageBlocks[block_index].Name :
436601e04c3fSmrg                         shProg->data->UniformBlocks[block_index].Name);
436701e04c3fSmrg
436801e04c3fSmrg   if (strcmp(var_name, interface_name) == 0) {
436901e04c3fSmrg      /* Deal with instanced array of SSBOs */
437001e04c3fSmrg      char *temp_name = get_var_name(uni->name);
437101e04c3fSmrg      if (!temp_name) {
437201e04c3fSmrg         linker_error(shProg, "Out of memory during linking.\n");
437301e04c3fSmrg         goto write_top_level_array_size_and_stride;
437401e04c3fSmrg      }
437501e04c3fSmrg      free(var_name);
437601e04c3fSmrg      var_name = get_top_level_name(temp_name);
437701e04c3fSmrg      free(temp_name);
437801e04c3fSmrg      if (!var_name) {
437901e04c3fSmrg         linker_error(shProg, "Out of memory during linking.\n");
438001e04c3fSmrg         goto write_top_level_array_size_and_stride;
438101e04c3fSmrg      }
438201e04c3fSmrg   }
438301e04c3fSmrg
438401e04c3fSmrg   for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
438501e04c3fSmrg      const gl_linked_shader *sh = shProg->_LinkedShaders[i];
438601e04c3fSmrg      if (sh == NULL)
438701e04c3fSmrg         continue;
438801e04c3fSmrg
438901e04c3fSmrg      foreach_in_list(ir_instruction, node, sh->ir) {
439001e04c3fSmrg         ir_variable *var = node->as_variable();
439101e04c3fSmrg         if (!var || !var->get_interface_type() ||
439201e04c3fSmrg             var->data.mode != ir_var_shader_storage)
439301e04c3fSmrg            continue;
439401e04c3fSmrg
439501e04c3fSmrg         const glsl_type *iface = var->get_interface_type();
439601e04c3fSmrg
439701e04c3fSmrg         if (strcmp(interface_name, iface->name) != 0)
439801e04c3fSmrg            continue;
439901e04c3fSmrg
440001e04c3fSmrg         for (unsigned i = 0; i < iface->length; i++) {
440101e04c3fSmrg            const glsl_struct_field *field = &iface->fields.structure[i];
440201e04c3fSmrg            if (strcmp(field->name, var_name) != 0)
440301e04c3fSmrg               continue;
440401e04c3fSmrg
440501e04c3fSmrg            array_stride = get_array_stride(ctx, uni, iface, field,
440601e04c3fSmrg                                            interface_name, var_name);
440701e04c3fSmrg            array_size = get_array_size(uni, field, interface_name, var_name);
440801e04c3fSmrg            goto write_top_level_array_size_and_stride;
440901e04c3fSmrg         }
441001e04c3fSmrg      }
441101e04c3fSmrg   }
441201e04c3fSmrgwrite_top_level_array_size_and_stride:
441301e04c3fSmrg   free(interface_name);
441401e04c3fSmrg   free(var_name);
441501e04c3fSmrg   uni->top_level_array_stride = array_stride;
441601e04c3fSmrg   uni->top_level_array_size = array_size;
441701e04c3fSmrg}
441801e04c3fSmrg
441901e04c3fSmrg/**
442001e04c3fSmrg * Builds up a list of program resources that point to existing
442101e04c3fSmrg * resource data.
442201e04c3fSmrg */
442301e04c3fSmrgvoid
442401e04c3fSmrgbuild_program_resource_list(struct gl_context *ctx,
442501e04c3fSmrg                            struct gl_shader_program *shProg)
442601e04c3fSmrg{
442701e04c3fSmrg   /* Rebuild resource list. */
442801e04c3fSmrg   if (shProg->data->ProgramResourceList) {
442901e04c3fSmrg      ralloc_free(shProg->data->ProgramResourceList);
443001e04c3fSmrg      shProg->data->ProgramResourceList = NULL;
443101e04c3fSmrg      shProg->data->NumProgramResourceList = 0;
443201e04c3fSmrg   }
443301e04c3fSmrg
443401e04c3fSmrg   int input_stage = MESA_SHADER_STAGES, output_stage = 0;
443501e04c3fSmrg
443601e04c3fSmrg   /* Determine first input and final output stage. These are used to
443701e04c3fSmrg    * detect which variables should be enumerated in the resource list
443801e04c3fSmrg    * for GL_PROGRAM_INPUT and GL_PROGRAM_OUTPUT.
443901e04c3fSmrg    */
444001e04c3fSmrg   for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
444101e04c3fSmrg      if (!shProg->_LinkedShaders[i])
444201e04c3fSmrg         continue;
444301e04c3fSmrg      if (input_stage == MESA_SHADER_STAGES)
444401e04c3fSmrg         input_stage = i;
444501e04c3fSmrg      output_stage = i;
444601e04c3fSmrg   }
444701e04c3fSmrg
444801e04c3fSmrg   /* Empty shader, no resources. */
444901e04c3fSmrg   if (input_stage == MESA_SHADER_STAGES && output_stage == 0)
445001e04c3fSmrg      return;
445101e04c3fSmrg
44527e102996Smaya   struct set *resource_set = _mesa_pointer_set_create(NULL);
445301e04c3fSmrg
445401e04c3fSmrg   /* Program interface needs to expose varyings in case of SSO. */
445501e04c3fSmrg   if (shProg->SeparateShader) {
445601e04c3fSmrg      if (!add_packed_varyings(ctx, shProg, resource_set,
445701e04c3fSmrg                               input_stage, GL_PROGRAM_INPUT))
445801e04c3fSmrg         return;
445901e04c3fSmrg
446001e04c3fSmrg      if (!add_packed_varyings(ctx, shProg, resource_set,
446101e04c3fSmrg                               output_stage, GL_PROGRAM_OUTPUT))
446201e04c3fSmrg         return;
446301e04c3fSmrg   }
446401e04c3fSmrg
446501e04c3fSmrg   if (!add_fragdata_arrays(ctx, shProg, resource_set))
446601e04c3fSmrg      return;
446701e04c3fSmrg
446801e04c3fSmrg   /* Add inputs and outputs to the resource list. */
446901e04c3fSmrg   if (!add_interface_variables(ctx, shProg, resource_set,
447001e04c3fSmrg                                input_stage, GL_PROGRAM_INPUT))
447101e04c3fSmrg      return;
447201e04c3fSmrg
447301e04c3fSmrg   if (!add_interface_variables(ctx, shProg, resource_set,
447401e04c3fSmrg                                output_stage, GL_PROGRAM_OUTPUT))
447501e04c3fSmrg      return;
447601e04c3fSmrg
447701e04c3fSmrg   if (shProg->last_vert_prog) {
447801e04c3fSmrg      struct gl_transform_feedback_info *linked_xfb =
447901e04c3fSmrg         shProg->last_vert_prog->sh.LinkedTransformFeedback;
448001e04c3fSmrg
448101e04c3fSmrg      /* Add transform feedback varyings. */
448201e04c3fSmrg      if (linked_xfb->NumVarying > 0) {
448301e04c3fSmrg         for (int i = 0; i < linked_xfb->NumVarying; i++) {
448401e04c3fSmrg            if (!link_util_add_program_resource(shProg, resource_set,
448501e04c3fSmrg                                                GL_TRANSFORM_FEEDBACK_VARYING,
448601e04c3fSmrg                                                &linked_xfb->Varyings[i], 0))
448701e04c3fSmrg            return;
448801e04c3fSmrg         }
448901e04c3fSmrg      }
449001e04c3fSmrg
449101e04c3fSmrg      /* Add transform feedback buffers. */
449201e04c3fSmrg      for (unsigned i = 0; i < ctx->Const.MaxTransformFeedbackBuffers; i++) {
449301e04c3fSmrg         if ((linked_xfb->ActiveBuffers >> i) & 1) {
449401e04c3fSmrg            linked_xfb->Buffers[i].Binding = i;
449501e04c3fSmrg            if (!link_util_add_program_resource(shProg, resource_set,
449601e04c3fSmrg                                                GL_TRANSFORM_FEEDBACK_BUFFER,
449701e04c3fSmrg                                                &linked_xfb->Buffers[i], 0))
449801e04c3fSmrg            return;
449901e04c3fSmrg         }
450001e04c3fSmrg      }
450101e04c3fSmrg   }
450201e04c3fSmrg
450301e04c3fSmrg   /* Add uniforms from uniform storage. */
450401e04c3fSmrg   for (unsigned i = 0; i < shProg->data->NumUniformStorage; i++) {
450501e04c3fSmrg      /* Do not add uniforms internally used by Mesa. */
450601e04c3fSmrg      if (shProg->data->UniformStorage[i].hidden)
450701e04c3fSmrg         continue;
450801e04c3fSmrg
450901e04c3fSmrg      uint8_t stageref =
451001e04c3fSmrg         build_stageref(shProg, shProg->data->UniformStorage[i].name,
451101e04c3fSmrg                        ir_var_uniform);
451201e04c3fSmrg
451301e04c3fSmrg      /* Add stagereferences for uniforms in a uniform block. */
451401e04c3fSmrg      bool is_shader_storage =
451501e04c3fSmrg        shProg->data->UniformStorage[i].is_shader_storage;
451601e04c3fSmrg      int block_index = shProg->data->UniformStorage[i].block_index;
451701e04c3fSmrg      if (block_index != -1) {
451801e04c3fSmrg         stageref |= is_shader_storage ?
451901e04c3fSmrg            shProg->data->ShaderStorageBlocks[block_index].stageref :
452001e04c3fSmrg            shProg->data->UniformBlocks[block_index].stageref;
452101e04c3fSmrg      }
452201e04c3fSmrg
452301e04c3fSmrg      GLenum type = is_shader_storage ? GL_BUFFER_VARIABLE : GL_UNIFORM;
452401e04c3fSmrg      if (!should_add_buffer_variable(shProg, type,
452501e04c3fSmrg                                      shProg->data->UniformStorage[i].name))
452601e04c3fSmrg         continue;
452701e04c3fSmrg
452801e04c3fSmrg      if (is_shader_storage) {
452901e04c3fSmrg         calculate_array_size_and_stride(ctx, shProg,
453001e04c3fSmrg                                         &shProg->data->UniformStorage[i]);
453101e04c3fSmrg      }
453201e04c3fSmrg
453301e04c3fSmrg      if (!link_util_add_program_resource(shProg, resource_set, type,
453401e04c3fSmrg                                          &shProg->data->UniformStorage[i], stageref))
453501e04c3fSmrg         return;
453601e04c3fSmrg   }
453701e04c3fSmrg
453801e04c3fSmrg   /* Add program uniform blocks. */
453901e04c3fSmrg   for (unsigned i = 0; i < shProg->data->NumUniformBlocks; i++) {
454001e04c3fSmrg      if (!link_util_add_program_resource(shProg, resource_set, GL_UNIFORM_BLOCK,
454101e04c3fSmrg                                          &shProg->data->UniformBlocks[i], 0))
454201e04c3fSmrg         return;
454301e04c3fSmrg   }
454401e04c3fSmrg
454501e04c3fSmrg   /* Add program shader storage blocks. */
454601e04c3fSmrg   for (unsigned i = 0; i < shProg->data->NumShaderStorageBlocks; i++) {
454701e04c3fSmrg      if (!link_util_add_program_resource(shProg, resource_set, GL_SHADER_STORAGE_BLOCK,
454801e04c3fSmrg                                          &shProg->data->ShaderStorageBlocks[i], 0))
454901e04c3fSmrg         return;
455001e04c3fSmrg   }
455101e04c3fSmrg
455201e04c3fSmrg   /* Add atomic counter buffers. */
455301e04c3fSmrg   for (unsigned i = 0; i < shProg->data->NumAtomicBuffers; i++) {
455401e04c3fSmrg      if (!link_util_add_program_resource(shProg, resource_set, GL_ATOMIC_COUNTER_BUFFER,
455501e04c3fSmrg                                          &shProg->data->AtomicBuffers[i], 0))
455601e04c3fSmrg         return;
455701e04c3fSmrg   }
455801e04c3fSmrg
455901e04c3fSmrg   for (unsigned i = 0; i < shProg->data->NumUniformStorage; i++) {
456001e04c3fSmrg      GLenum type;
456101e04c3fSmrg      if (!shProg->data->UniformStorage[i].hidden)
456201e04c3fSmrg         continue;
456301e04c3fSmrg
456401e04c3fSmrg      for (int j = MESA_SHADER_VERTEX; j < MESA_SHADER_STAGES; j++) {
456501e04c3fSmrg         if (!shProg->data->UniformStorage[i].opaque[j].active ||
456601e04c3fSmrg             !shProg->data->UniformStorage[i].type->is_subroutine())
456701e04c3fSmrg            continue;
456801e04c3fSmrg
456901e04c3fSmrg         type = _mesa_shader_stage_to_subroutine_uniform((gl_shader_stage)j);
457001e04c3fSmrg         /* add shader subroutines */
457101e04c3fSmrg         if (!link_util_add_program_resource(shProg, resource_set,
457201e04c3fSmrg                                             type, &shProg->data->UniformStorage[i], 0))
457301e04c3fSmrg            return;
457401e04c3fSmrg      }
457501e04c3fSmrg   }
457601e04c3fSmrg
457701e04c3fSmrg   unsigned mask = shProg->data->linked_stages;
457801e04c3fSmrg   while (mask) {
457901e04c3fSmrg      const int i = u_bit_scan(&mask);
458001e04c3fSmrg      struct gl_program *p = shProg->_LinkedShaders[i]->Program;
458101e04c3fSmrg
458201e04c3fSmrg      GLuint type = _mesa_shader_stage_to_subroutine((gl_shader_stage)i);
458301e04c3fSmrg      for (unsigned j = 0; j < p->sh.NumSubroutineFunctions; j++) {
458401e04c3fSmrg         if (!link_util_add_program_resource(shProg, resource_set,
458501e04c3fSmrg                                             type, &p->sh.SubroutineFunctions[j], 0))
458601e04c3fSmrg            return;
458701e04c3fSmrg      }
458801e04c3fSmrg   }
458901e04c3fSmrg
459001e04c3fSmrg   _mesa_set_destroy(resource_set, NULL);
459101e04c3fSmrg}
459201e04c3fSmrg
459301e04c3fSmrg/**
459401e04c3fSmrg * This check is done to make sure we allow only constant expression
459501e04c3fSmrg * indexing and "constant-index-expression" (indexing with an expression
459601e04c3fSmrg * that includes loop induction variable).
459701e04c3fSmrg */
459801e04c3fSmrgstatic bool
459901e04c3fSmrgvalidate_sampler_array_indexing(struct gl_context *ctx,
460001e04c3fSmrg                                struct gl_shader_program *prog)
460101e04c3fSmrg{
460201e04c3fSmrg   dynamic_sampler_array_indexing_visitor v;
460301e04c3fSmrg   for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
460401e04c3fSmrg      if (prog->_LinkedShaders[i] == NULL)
460501e04c3fSmrg         continue;
460601e04c3fSmrg
460701e04c3fSmrg      bool no_dynamic_indexing =
460801e04c3fSmrg         ctx->Const.ShaderCompilerOptions[i].EmitNoIndirectSampler;
460901e04c3fSmrg
461001e04c3fSmrg      /* Search for array derefs in shader. */
461101e04c3fSmrg      v.run(prog->_LinkedShaders[i]->ir);
461201e04c3fSmrg      if (v.uses_dynamic_sampler_array_indexing()) {
461301e04c3fSmrg         const char *msg = "sampler arrays indexed with non-constant "
461401e04c3fSmrg                           "expressions is forbidden in GLSL %s %u";
461501e04c3fSmrg         /* Backend has indicated that it has no dynamic indexing support. */
461601e04c3fSmrg         if (no_dynamic_indexing) {
461701e04c3fSmrg            linker_error(prog, msg, prog->IsES ? "ES" : "",
461801e04c3fSmrg                         prog->data->Version);
461901e04c3fSmrg            return false;
462001e04c3fSmrg         } else {
462101e04c3fSmrg            linker_warning(prog, msg, prog->IsES ? "ES" : "",
462201e04c3fSmrg                           prog->data->Version);
462301e04c3fSmrg         }
462401e04c3fSmrg      }
462501e04c3fSmrg   }
462601e04c3fSmrg   return true;
462701e04c3fSmrg}
462801e04c3fSmrg
462901e04c3fSmrgstatic void
463001e04c3fSmrglink_assign_subroutine_types(struct gl_shader_program *prog)
463101e04c3fSmrg{
463201e04c3fSmrg   unsigned mask = prog->data->linked_stages;
463301e04c3fSmrg   while (mask) {
463401e04c3fSmrg      const int i = u_bit_scan(&mask);
463501e04c3fSmrg      gl_program *p = prog->_LinkedShaders[i]->Program;
463601e04c3fSmrg
463701e04c3fSmrg      p->sh.MaxSubroutineFunctionIndex = 0;
463801e04c3fSmrg      foreach_in_list(ir_instruction, node, prog->_LinkedShaders[i]->ir) {
463901e04c3fSmrg         ir_function *fn = node->as_function();
464001e04c3fSmrg         if (!fn)
464101e04c3fSmrg            continue;
464201e04c3fSmrg
464301e04c3fSmrg         if (fn->is_subroutine)
464401e04c3fSmrg            p->sh.NumSubroutineUniformTypes++;
464501e04c3fSmrg
464601e04c3fSmrg         if (!fn->num_subroutine_types)
464701e04c3fSmrg            continue;
464801e04c3fSmrg
464901e04c3fSmrg         /* these should have been calculated earlier. */
465001e04c3fSmrg         assert(fn->subroutine_index != -1);
465101e04c3fSmrg         if (p->sh.NumSubroutineFunctions + 1 > MAX_SUBROUTINES) {
465201e04c3fSmrg            linker_error(prog, "Too many subroutine functions declared.\n");
465301e04c3fSmrg            return;
465401e04c3fSmrg         }
465501e04c3fSmrg         p->sh.SubroutineFunctions = reralloc(p, p->sh.SubroutineFunctions,
465601e04c3fSmrg                                            struct gl_subroutine_function,
465701e04c3fSmrg                                            p->sh.NumSubroutineFunctions + 1);
465801e04c3fSmrg         p->sh.SubroutineFunctions[p->sh.NumSubroutineFunctions].name = ralloc_strdup(p, fn->name);
465901e04c3fSmrg         p->sh.SubroutineFunctions[p->sh.NumSubroutineFunctions].num_compat_types = fn->num_subroutine_types;
466001e04c3fSmrg         p->sh.SubroutineFunctions[p->sh.NumSubroutineFunctions].types =
466101e04c3fSmrg            ralloc_array(p, const struct glsl_type *,
466201e04c3fSmrg                         fn->num_subroutine_types);
466301e04c3fSmrg
466401e04c3fSmrg         /* From Section 4.4.4(Subroutine Function Layout Qualifiers) of the
466501e04c3fSmrg          * GLSL 4.5 spec:
466601e04c3fSmrg          *
466701e04c3fSmrg          *    "Each subroutine with an index qualifier in the shader must be
466801e04c3fSmrg          *    given a unique index, otherwise a compile or link error will be
466901e04c3fSmrg          *    generated."
467001e04c3fSmrg          */
467101e04c3fSmrg         for (unsigned j = 0; j < p->sh.NumSubroutineFunctions; j++) {
467201e04c3fSmrg            if (p->sh.SubroutineFunctions[j].index != -1 &&
467301e04c3fSmrg                p->sh.SubroutineFunctions[j].index == fn->subroutine_index) {
467401e04c3fSmrg               linker_error(prog, "each subroutine index qualifier in the "
467501e04c3fSmrg                            "shader must be unique\n");
467601e04c3fSmrg               return;
467701e04c3fSmrg            }
467801e04c3fSmrg         }
467901e04c3fSmrg         p->sh.SubroutineFunctions[p->sh.NumSubroutineFunctions].index =
468001e04c3fSmrg            fn->subroutine_index;
468101e04c3fSmrg
468201e04c3fSmrg         if (fn->subroutine_index > (int)p->sh.MaxSubroutineFunctionIndex)
468301e04c3fSmrg            p->sh.MaxSubroutineFunctionIndex = fn->subroutine_index;
468401e04c3fSmrg
468501e04c3fSmrg         for (int j = 0; j < fn->num_subroutine_types; j++)
468601e04c3fSmrg            p->sh.SubroutineFunctions[p->sh.NumSubroutineFunctions].types[j] = fn->subroutine_types[j];
468701e04c3fSmrg         p->sh.NumSubroutineFunctions++;
468801e04c3fSmrg      }
468901e04c3fSmrg   }
469001e04c3fSmrg}
469101e04c3fSmrg
469201e04c3fSmrgstatic void
469301e04c3fSmrgverify_subroutine_associated_funcs(struct gl_shader_program *prog)
469401e04c3fSmrg{
469501e04c3fSmrg   unsigned mask = prog->data->linked_stages;
469601e04c3fSmrg   while (mask) {
469701e04c3fSmrg      const int i = u_bit_scan(&mask);
469801e04c3fSmrg      gl_program *p = prog->_LinkedShaders[i]->Program;
469901e04c3fSmrg      glsl_symbol_table *symbols = prog->_LinkedShaders[i]->symbols;
470001e04c3fSmrg
470101e04c3fSmrg      /* Section 6.1.2 (Subroutines) of the GLSL 4.00 spec says:
470201e04c3fSmrg       *
470301e04c3fSmrg       *   "A program will fail to compile or link if any shader
470401e04c3fSmrg       *    or stage contains two or more functions with the same
470501e04c3fSmrg       *    name if the name is associated with a subroutine type."
470601e04c3fSmrg       */
470701e04c3fSmrg      for (unsigned j = 0; j < p->sh.NumSubroutineFunctions; j++) {
470801e04c3fSmrg         unsigned definitions = 0;
470901e04c3fSmrg         char *name = p->sh.SubroutineFunctions[j].name;
471001e04c3fSmrg         ir_function *fn = symbols->get_function(name);
471101e04c3fSmrg
471201e04c3fSmrg         /* Calculate number of function definitions with the same name */
471301e04c3fSmrg         foreach_in_list(ir_function_signature, sig, &fn->signatures) {
471401e04c3fSmrg            if (sig->is_defined) {
471501e04c3fSmrg               if (++definitions > 1) {
471601e04c3fSmrg                  linker_error(prog, "%s shader contains two or more function "
471701e04c3fSmrg                               "definitions with name `%s', which is "
471801e04c3fSmrg                               "associated with a subroutine type.\n",
471901e04c3fSmrg                               _mesa_shader_stage_to_string(i),
472001e04c3fSmrg                               fn->name);
472101e04c3fSmrg                  return;
472201e04c3fSmrg               }
472301e04c3fSmrg            }
472401e04c3fSmrg         }
472501e04c3fSmrg      }
472601e04c3fSmrg   }
472701e04c3fSmrg}
472801e04c3fSmrg
472901e04c3fSmrg
473001e04c3fSmrgstatic void
473101e04c3fSmrgset_always_active_io(exec_list *ir, ir_variable_mode io_mode)
473201e04c3fSmrg{
473301e04c3fSmrg   assert(io_mode == ir_var_shader_in || io_mode == ir_var_shader_out);
473401e04c3fSmrg
473501e04c3fSmrg   foreach_in_list(ir_instruction, node, ir) {
473601e04c3fSmrg      ir_variable *const var = node->as_variable();
473701e04c3fSmrg
473801e04c3fSmrg      if (var == NULL || var->data.mode != io_mode)
473901e04c3fSmrg         continue;
474001e04c3fSmrg
474101e04c3fSmrg      /* Don't set always active on builtins that haven't been redeclared */
474201e04c3fSmrg      if (var->data.how_declared == ir_var_declared_implicitly)
474301e04c3fSmrg         continue;
474401e04c3fSmrg
474501e04c3fSmrg      var->data.always_active_io = true;
474601e04c3fSmrg   }
474701e04c3fSmrg}
474801e04c3fSmrg
474901e04c3fSmrg/**
475001e04c3fSmrg * When separate shader programs are enabled, only input/outputs between
475101e04c3fSmrg * the stages of a multi-stage separate program can be safely removed
475201e04c3fSmrg * from the shader interface. Other inputs/outputs must remain active.
475301e04c3fSmrg */
475401e04c3fSmrgstatic void
475501e04c3fSmrgdisable_varying_optimizations_for_sso(struct gl_shader_program *prog)
475601e04c3fSmrg{
475701e04c3fSmrg   unsigned first, last;
475801e04c3fSmrg   assert(prog->SeparateShader);
475901e04c3fSmrg
476001e04c3fSmrg   first = MESA_SHADER_STAGES;
476101e04c3fSmrg   last = 0;
476201e04c3fSmrg
476301e04c3fSmrg   /* Determine first and last stage. Excluding the compute stage */
476401e04c3fSmrg   for (unsigned i = 0; i < MESA_SHADER_COMPUTE; i++) {
476501e04c3fSmrg      if (!prog->_LinkedShaders[i])
476601e04c3fSmrg         continue;
476701e04c3fSmrg      if (first == MESA_SHADER_STAGES)
476801e04c3fSmrg         first = i;
476901e04c3fSmrg      last = i;
477001e04c3fSmrg   }
477101e04c3fSmrg
477201e04c3fSmrg   if (first == MESA_SHADER_STAGES)
477301e04c3fSmrg      return;
477401e04c3fSmrg
477501e04c3fSmrg   for (unsigned stage = 0; stage < MESA_SHADER_STAGES; stage++) {
477601e04c3fSmrg      gl_linked_shader *sh = prog->_LinkedShaders[stage];
477701e04c3fSmrg      if (!sh)
477801e04c3fSmrg         continue;
477901e04c3fSmrg
478001e04c3fSmrg      /* Prevent the removal of inputs to the first and outputs from the last
478101e04c3fSmrg       * stage, unless they are the initial pipeline inputs or final pipeline
478201e04c3fSmrg       * outputs, respectively.
478301e04c3fSmrg       *
478401e04c3fSmrg       * The removal of IO between shaders in the same program is always
478501e04c3fSmrg       * allowed.
478601e04c3fSmrg       */
478701e04c3fSmrg      if (stage == first && stage != MESA_SHADER_VERTEX)
478801e04c3fSmrg         set_always_active_io(sh->ir, ir_var_shader_in);
478901e04c3fSmrg      if (stage == last && stage != MESA_SHADER_FRAGMENT)
479001e04c3fSmrg         set_always_active_io(sh->ir, ir_var_shader_out);
479101e04c3fSmrg   }
479201e04c3fSmrg}
479301e04c3fSmrg
479401e04c3fSmrgstatic void
479501e04c3fSmrglink_and_validate_uniforms(struct gl_context *ctx,
479601e04c3fSmrg                           struct gl_shader_program *prog)
479701e04c3fSmrg{
479801e04c3fSmrg   update_array_sizes(prog);
479901e04c3fSmrg   link_assign_uniform_locations(prog, ctx);
480001e04c3fSmrg
480101e04c3fSmrg   link_assign_atomic_counter_resources(ctx, prog);
480201e04c3fSmrg   link_calculate_subroutine_compat(prog);
480301e04c3fSmrg   check_resources(ctx, prog);
480401e04c3fSmrg   check_subroutine_resources(prog);
480501e04c3fSmrg   check_image_resources(ctx, prog);
480601e04c3fSmrg   link_check_atomic_counter_resources(ctx, prog);
480701e04c3fSmrg}
480801e04c3fSmrg
480901e04c3fSmrgstatic bool
481001e04c3fSmrglink_varyings_and_uniforms(unsigned first, unsigned last,
481101e04c3fSmrg                           struct gl_context *ctx,
481201e04c3fSmrg                           struct gl_shader_program *prog, void *mem_ctx)
481301e04c3fSmrg{
481401e04c3fSmrg   /* Mark all generic shader inputs and outputs as unpaired. */
481501e04c3fSmrg   for (unsigned i = MESA_SHADER_VERTEX; i <= MESA_SHADER_FRAGMENT; i++) {
481601e04c3fSmrg      if (prog->_LinkedShaders[i] != NULL) {
481701e04c3fSmrg         link_invalidate_variable_locations(prog->_LinkedShaders[i]->ir);
481801e04c3fSmrg      }
481901e04c3fSmrg   }
482001e04c3fSmrg
482101e04c3fSmrg   unsigned prev = first;
482201e04c3fSmrg   for (unsigned i = prev + 1; i <= MESA_SHADER_FRAGMENT; i++) {
482301e04c3fSmrg      if (prog->_LinkedShaders[i] == NULL)
482401e04c3fSmrg         continue;
482501e04c3fSmrg
482601e04c3fSmrg      match_explicit_outputs_to_inputs(prog->_LinkedShaders[prev],
482701e04c3fSmrg                                       prog->_LinkedShaders[i]);
482801e04c3fSmrg      prev = i;
482901e04c3fSmrg   }
483001e04c3fSmrg
483101e04c3fSmrg   if (!assign_attribute_or_color_locations(mem_ctx, prog, &ctx->Const,
483201e04c3fSmrg                                            MESA_SHADER_VERTEX, true)) {
483301e04c3fSmrg      return false;
483401e04c3fSmrg   }
483501e04c3fSmrg
483601e04c3fSmrg   if (!assign_attribute_or_color_locations(mem_ctx, prog, &ctx->Const,
483701e04c3fSmrg                                            MESA_SHADER_FRAGMENT, true)) {
483801e04c3fSmrg      return false;
483901e04c3fSmrg   }
484001e04c3fSmrg
484101e04c3fSmrg   prog->last_vert_prog = NULL;
484201e04c3fSmrg   for (int i = MESA_SHADER_GEOMETRY; i >= MESA_SHADER_VERTEX; i--) {
484301e04c3fSmrg      if (prog->_LinkedShaders[i] == NULL)
484401e04c3fSmrg         continue;
484501e04c3fSmrg
484601e04c3fSmrg      prog->last_vert_prog = prog->_LinkedShaders[i]->Program;
484701e04c3fSmrg      break;
484801e04c3fSmrg   }
484901e04c3fSmrg
485001e04c3fSmrg   if (!link_varyings(prog, first, last, ctx, mem_ctx))
485101e04c3fSmrg      return false;
485201e04c3fSmrg
485301e04c3fSmrg   link_and_validate_uniforms(ctx, prog);
485401e04c3fSmrg
485501e04c3fSmrg   if (!prog->data->LinkStatus)
485601e04c3fSmrg      return false;
485701e04c3fSmrg
485801e04c3fSmrg   for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
485901e04c3fSmrg      if (prog->_LinkedShaders[i] == NULL)
486001e04c3fSmrg         continue;
486101e04c3fSmrg
486201e04c3fSmrg      const struct gl_shader_compiler_options *options =
486301e04c3fSmrg         &ctx->Const.ShaderCompilerOptions[i];
486401e04c3fSmrg
486501e04c3fSmrg      if (options->LowerBufferInterfaceBlocks)
486601e04c3fSmrg         lower_ubo_reference(prog->_LinkedShaders[i],
486701e04c3fSmrg                             options->ClampBlockIndicesToArrayBounds,
486801e04c3fSmrg                             ctx->Const.UseSTD430AsDefaultPacking);
486901e04c3fSmrg
487001e04c3fSmrg      if (i == MESA_SHADER_COMPUTE)
487101e04c3fSmrg         lower_shared_reference(ctx, prog, prog->_LinkedShaders[i]);
487201e04c3fSmrg
487301e04c3fSmrg      lower_vector_derefs(prog->_LinkedShaders[i]);
487401e04c3fSmrg      do_vec_index_to_swizzle(prog->_LinkedShaders[i]->ir);
487501e04c3fSmrg   }
487601e04c3fSmrg
487701e04c3fSmrg   return true;
487801e04c3fSmrg}
487901e04c3fSmrg
488001e04c3fSmrgstatic void
488101e04c3fSmrglinker_optimisation_loop(struct gl_context *ctx, exec_list *ir,
488201e04c3fSmrg                         unsigned stage)
488301e04c3fSmrg{
488401e04c3fSmrg      if (ctx->Const.GLSLOptimizeConservatively) {
488501e04c3fSmrg         /* Run it just once. */
488601e04c3fSmrg         do_common_optimization(ir, true, false,
488701e04c3fSmrg                                &ctx->Const.ShaderCompilerOptions[stage],
488801e04c3fSmrg                                ctx->Const.NativeIntegers);
488901e04c3fSmrg      } else {
489001e04c3fSmrg         /* Repeat it until it stops making changes. */
489101e04c3fSmrg         while (do_common_optimization(ir, true, false,
489201e04c3fSmrg                                       &ctx->Const.ShaderCompilerOptions[stage],
489301e04c3fSmrg                                       ctx->Const.NativeIntegers))
489401e04c3fSmrg            ;
489501e04c3fSmrg      }
489601e04c3fSmrg}
489701e04c3fSmrg
489801e04c3fSmrgvoid
489901e04c3fSmrglink_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
490001e04c3fSmrg{
490101e04c3fSmrg   prog->data->LinkStatus = LINKING_SUCCESS; /* All error paths will set this to false */
490201e04c3fSmrg   prog->data->Validated = false;
490301e04c3fSmrg
490401e04c3fSmrg   /* Section 7.3 (Program Objects) of the OpenGL 4.5 Core Profile spec says:
490501e04c3fSmrg    *
490601e04c3fSmrg    *     "Linking can fail for a variety of reasons as specified in the
490701e04c3fSmrg    *     OpenGL Shading Language Specification, as well as any of the
490801e04c3fSmrg    *     following reasons:
490901e04c3fSmrg    *
491001e04c3fSmrg    *     - No shader objects are attached to program."
491101e04c3fSmrg    *
491201e04c3fSmrg    * The Compatibility Profile specification does not list the error.  In
491301e04c3fSmrg    * Compatibility Profile missing shader stages are replaced by
491401e04c3fSmrg    * fixed-function.  This applies to the case where all stages are
491501e04c3fSmrg    * missing.
491601e04c3fSmrg    */
491701e04c3fSmrg   if (prog->NumShaders == 0) {
491801e04c3fSmrg      if (ctx->API != API_OPENGL_COMPAT)
491901e04c3fSmrg         linker_error(prog, "no shaders attached to the program\n");
492001e04c3fSmrg      return;
492101e04c3fSmrg   }
492201e04c3fSmrg
492301e04c3fSmrg#ifdef ENABLE_SHADER_CACHE
492401e04c3fSmrg   if (shader_cache_read_program_metadata(ctx, prog))
492501e04c3fSmrg      return;
492601e04c3fSmrg#endif
492701e04c3fSmrg
492801e04c3fSmrg   void *mem_ctx = ralloc_context(NULL); // temporary linker context
492901e04c3fSmrg
493001e04c3fSmrg   prog->ARB_fragment_coord_conventions_enable = false;
493101e04c3fSmrg
493201e04c3fSmrg   /* Separate the shaders into groups based on their type.
493301e04c3fSmrg    */
493401e04c3fSmrg   struct gl_shader **shader_list[MESA_SHADER_STAGES];
493501e04c3fSmrg   unsigned num_shaders[MESA_SHADER_STAGES];
493601e04c3fSmrg
493701e04c3fSmrg   for (int i = 0; i < MESA_SHADER_STAGES; i++) {
493801e04c3fSmrg      shader_list[i] = (struct gl_shader **)
493901e04c3fSmrg         calloc(prog->NumShaders, sizeof(struct gl_shader *));
494001e04c3fSmrg      num_shaders[i] = 0;
494101e04c3fSmrg   }
494201e04c3fSmrg
494301e04c3fSmrg   unsigned min_version = UINT_MAX;
494401e04c3fSmrg   unsigned max_version = 0;
494501e04c3fSmrg   for (unsigned i = 0; i < prog->NumShaders; i++) {
494601e04c3fSmrg      min_version = MIN2(min_version, prog->Shaders[i]->Version);
494701e04c3fSmrg      max_version = MAX2(max_version, prog->Shaders[i]->Version);
494801e04c3fSmrg
494901e04c3fSmrg      if (!ctx->Const.AllowGLSLRelaxedES &&
495001e04c3fSmrg          prog->Shaders[i]->IsES != prog->Shaders[0]->IsES) {
495101e04c3fSmrg         linker_error(prog, "all shaders must use same shading "
495201e04c3fSmrg                      "language version\n");
495301e04c3fSmrg         goto done;
495401e04c3fSmrg      }
495501e04c3fSmrg
495601e04c3fSmrg      if (prog->Shaders[i]->ARB_fragment_coord_conventions_enable) {
495701e04c3fSmrg         prog->ARB_fragment_coord_conventions_enable = true;
495801e04c3fSmrg      }
495901e04c3fSmrg
496001e04c3fSmrg      gl_shader_stage shader_type = prog->Shaders[i]->Stage;
496101e04c3fSmrg      shader_list[shader_type][num_shaders[shader_type]] = prog->Shaders[i];
496201e04c3fSmrg      num_shaders[shader_type]++;
496301e04c3fSmrg   }
496401e04c3fSmrg
496501e04c3fSmrg   /* In desktop GLSL, different shader versions may be linked together.  In
496601e04c3fSmrg    * GLSL ES, all shader versions must be the same.
496701e04c3fSmrg    */
496801e04c3fSmrg   if (!ctx->Const.AllowGLSLRelaxedES && prog->Shaders[0]->IsES &&
496901e04c3fSmrg       min_version != max_version) {
497001e04c3fSmrg      linker_error(prog, "all shaders must use same shading "
497101e04c3fSmrg                   "language version\n");
497201e04c3fSmrg      goto done;
497301e04c3fSmrg   }
497401e04c3fSmrg
497501e04c3fSmrg   prog->data->Version = max_version;
497601e04c3fSmrg   prog->IsES = prog->Shaders[0]->IsES;
497701e04c3fSmrg
497801e04c3fSmrg   /* Some shaders have to be linked with some other shaders present.
497901e04c3fSmrg    */
498001e04c3fSmrg   if (!prog->SeparateShader) {
498101e04c3fSmrg      if (num_shaders[MESA_SHADER_GEOMETRY] > 0 &&
498201e04c3fSmrg          num_shaders[MESA_SHADER_VERTEX] == 0) {
498301e04c3fSmrg         linker_error(prog, "Geometry shader must be linked with "
498401e04c3fSmrg                      "vertex shader\n");
498501e04c3fSmrg         goto done;
498601e04c3fSmrg      }
498701e04c3fSmrg      if (num_shaders[MESA_SHADER_TESS_EVAL] > 0 &&
498801e04c3fSmrg          num_shaders[MESA_SHADER_VERTEX] == 0) {
498901e04c3fSmrg         linker_error(prog, "Tessellation evaluation shader must be linked "
499001e04c3fSmrg                      "with vertex shader\n");
499101e04c3fSmrg         goto done;
499201e04c3fSmrg      }
499301e04c3fSmrg      if (num_shaders[MESA_SHADER_TESS_CTRL] > 0 &&
499401e04c3fSmrg          num_shaders[MESA_SHADER_VERTEX] == 0) {
499501e04c3fSmrg         linker_error(prog, "Tessellation control shader must be linked with "
499601e04c3fSmrg                      "vertex shader\n");
499701e04c3fSmrg         goto done;
499801e04c3fSmrg      }
499901e04c3fSmrg
500001e04c3fSmrg      /* Section 7.3 of the OpenGL ES 3.2 specification says:
500101e04c3fSmrg       *
500201e04c3fSmrg       *    "Linking can fail for [...] any of the following reasons:
500301e04c3fSmrg       *
500401e04c3fSmrg       *     * program contains an object to form a tessellation control
500501e04c3fSmrg       *       shader [...] and [...] the program is not separable and
500601e04c3fSmrg       *       contains no object to form a tessellation evaluation shader"
500701e04c3fSmrg       *
500801e04c3fSmrg       * The OpenGL spec is contradictory. It allows linking without a tess
500901e04c3fSmrg       * eval shader, but that can only be used with transform feedback and
501001e04c3fSmrg       * rasterization disabled. However, transform feedback isn't allowed
501101e04c3fSmrg       * with GL_PATCHES, so it can't be used.
501201e04c3fSmrg       *
501301e04c3fSmrg       * More investigation showed that the idea of transform feedback after
501401e04c3fSmrg       * a tess control shader was dropped, because some hw vendors couldn't
501501e04c3fSmrg       * support tessellation without a tess eval shader, but the linker
501601e04c3fSmrg       * section wasn't updated to reflect that.
501701e04c3fSmrg       *
501801e04c3fSmrg       * All specifications (ARB_tessellation_shader, GL 4.0-4.5) have this
501901e04c3fSmrg       * spec bug.
502001e04c3fSmrg       *
502101e04c3fSmrg       * Do what's reasonable and always require a tess eval shader if a tess
502201e04c3fSmrg       * control shader is present.
502301e04c3fSmrg       */
502401e04c3fSmrg      if (num_shaders[MESA_SHADER_TESS_CTRL] > 0 &&
502501e04c3fSmrg          num_shaders[MESA_SHADER_TESS_EVAL] == 0) {
502601e04c3fSmrg         linker_error(prog, "Tessellation control shader must be linked with "
502701e04c3fSmrg                      "tessellation evaluation shader\n");
502801e04c3fSmrg         goto done;
502901e04c3fSmrg      }
503001e04c3fSmrg
503101e04c3fSmrg      if (prog->IsES) {
503201e04c3fSmrg         if (num_shaders[MESA_SHADER_TESS_EVAL] > 0 &&
503301e04c3fSmrg             num_shaders[MESA_SHADER_TESS_CTRL] == 0) {
503401e04c3fSmrg            linker_error(prog, "GLSL ES requires non-separable programs "
503501e04c3fSmrg                         "containing a tessellation evaluation shader to also "
503601e04c3fSmrg                         "be linked with a tessellation control shader\n");
503701e04c3fSmrg            goto done;
503801e04c3fSmrg         }
503901e04c3fSmrg      }
504001e04c3fSmrg   }
504101e04c3fSmrg
504201e04c3fSmrg   /* Compute shaders have additional restrictions. */
504301e04c3fSmrg   if (num_shaders[MESA_SHADER_COMPUTE] > 0 &&
504401e04c3fSmrg       num_shaders[MESA_SHADER_COMPUTE] != prog->NumShaders) {
504501e04c3fSmrg      linker_error(prog, "Compute shaders may not be linked with any other "
504601e04c3fSmrg                   "type of shader\n");
504701e04c3fSmrg   }
504801e04c3fSmrg
504901e04c3fSmrg   /* Link all shaders for a particular stage and validate the result.
505001e04c3fSmrg    */
505101e04c3fSmrg   for (int stage = 0; stage < MESA_SHADER_STAGES; stage++) {
505201e04c3fSmrg      if (num_shaders[stage] > 0) {
505301e04c3fSmrg         gl_linked_shader *const sh =
505401e04c3fSmrg            link_intrastage_shaders(mem_ctx, ctx, prog, shader_list[stage],
505501e04c3fSmrg                                    num_shaders[stage], false);
505601e04c3fSmrg
505701e04c3fSmrg         if (!prog->data->LinkStatus) {
505801e04c3fSmrg            if (sh)
505901e04c3fSmrg               _mesa_delete_linked_shader(ctx, sh);
506001e04c3fSmrg            goto done;
506101e04c3fSmrg         }
506201e04c3fSmrg
506301e04c3fSmrg         switch (stage) {
506401e04c3fSmrg         case MESA_SHADER_VERTEX:
506501e04c3fSmrg            validate_vertex_shader_executable(prog, sh, ctx);
506601e04c3fSmrg            break;
506701e04c3fSmrg         case MESA_SHADER_TESS_CTRL:
506801e04c3fSmrg            /* nothing to be done */
506901e04c3fSmrg            break;
507001e04c3fSmrg         case MESA_SHADER_TESS_EVAL:
507101e04c3fSmrg            validate_tess_eval_shader_executable(prog, sh, ctx);
507201e04c3fSmrg            break;
507301e04c3fSmrg         case MESA_SHADER_GEOMETRY:
507401e04c3fSmrg            validate_geometry_shader_executable(prog, sh, ctx);
507501e04c3fSmrg            break;
507601e04c3fSmrg         case MESA_SHADER_FRAGMENT:
507701e04c3fSmrg            validate_fragment_shader_executable(prog, sh);
507801e04c3fSmrg            break;
507901e04c3fSmrg         }
508001e04c3fSmrg         if (!prog->data->LinkStatus) {
508101e04c3fSmrg            if (sh)
508201e04c3fSmrg               _mesa_delete_linked_shader(ctx, sh);
508301e04c3fSmrg            goto done;
508401e04c3fSmrg         }
508501e04c3fSmrg
508601e04c3fSmrg         prog->_LinkedShaders[stage] = sh;
508701e04c3fSmrg         prog->data->linked_stages |= 1 << stage;
508801e04c3fSmrg      }
508901e04c3fSmrg   }
509001e04c3fSmrg
509101e04c3fSmrg   /* Here begins the inter-stage linking phase.  Some initial validation is
509201e04c3fSmrg    * performed, then locations are assigned for uniforms, attributes, and
509301e04c3fSmrg    * varyings.
509401e04c3fSmrg    */
509501e04c3fSmrg   cross_validate_uniforms(ctx, prog);
509601e04c3fSmrg   if (!prog->data->LinkStatus)
509701e04c3fSmrg      goto done;
509801e04c3fSmrg
509901e04c3fSmrg   unsigned first, last, prev;
510001e04c3fSmrg
510101e04c3fSmrg   first = MESA_SHADER_STAGES;
510201e04c3fSmrg   last = 0;
510301e04c3fSmrg
510401e04c3fSmrg   /* Determine first and last stage. */
510501e04c3fSmrg   for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
510601e04c3fSmrg      if (!prog->_LinkedShaders[i])
510701e04c3fSmrg         continue;
510801e04c3fSmrg      if (first == MESA_SHADER_STAGES)
510901e04c3fSmrg         first = i;
511001e04c3fSmrg      last = i;
511101e04c3fSmrg   }
511201e04c3fSmrg
511301e04c3fSmrg   check_explicit_uniform_locations(ctx, prog);
511401e04c3fSmrg   link_assign_subroutine_types(prog);
511501e04c3fSmrg   verify_subroutine_associated_funcs(prog);
511601e04c3fSmrg
511701e04c3fSmrg   if (!prog->data->LinkStatus)
511801e04c3fSmrg      goto done;
511901e04c3fSmrg
512001e04c3fSmrg   resize_tes_inputs(ctx, prog);
512101e04c3fSmrg
512201e04c3fSmrg   /* Validate the inputs of each stage with the output of the preceding
512301e04c3fSmrg    * stage.
512401e04c3fSmrg    */
512501e04c3fSmrg   prev = first;
512601e04c3fSmrg   for (unsigned i = prev + 1; i <= MESA_SHADER_FRAGMENT; i++) {
512701e04c3fSmrg      if (prog->_LinkedShaders[i] == NULL)
512801e04c3fSmrg         continue;
512901e04c3fSmrg
513001e04c3fSmrg      validate_interstage_inout_blocks(prog, prog->_LinkedShaders[prev],
513101e04c3fSmrg                                       prog->_LinkedShaders[i]);
513201e04c3fSmrg      if (!prog->data->LinkStatus)
513301e04c3fSmrg         goto done;
513401e04c3fSmrg
513501e04c3fSmrg      cross_validate_outputs_to_inputs(ctx, prog,
513601e04c3fSmrg                                       prog->_LinkedShaders[prev],
513701e04c3fSmrg                                       prog->_LinkedShaders[i]);
513801e04c3fSmrg      if (!prog->data->LinkStatus)
513901e04c3fSmrg         goto done;
514001e04c3fSmrg
514101e04c3fSmrg      prev = i;
514201e04c3fSmrg   }
514301e04c3fSmrg
51447e102996Smaya   /* The cross validation of outputs/inputs above validates interstage
51457e102996Smaya    * explicit locations. We need to do this also for the inputs in the first
51467e102996Smaya    * stage and outputs of the last stage included in the program, since there
51477e102996Smaya    * is no cross validation for these.
514801e04c3fSmrg    */
51497e102996Smaya   validate_first_and_last_interface_explicit_locations(ctx, prog,
51507e102996Smaya                                                        (gl_shader_stage) first,
51517e102996Smaya                                                        (gl_shader_stage) last);
515201e04c3fSmrg
515301e04c3fSmrg   /* Cross-validate uniform blocks between shader stages */
515401e04c3fSmrg   validate_interstage_uniform_blocks(prog, prog->_LinkedShaders);
515501e04c3fSmrg   if (!prog->data->LinkStatus)
515601e04c3fSmrg      goto done;
515701e04c3fSmrg
515801e04c3fSmrg   for (unsigned int i = 0; i < MESA_SHADER_STAGES; i++) {
515901e04c3fSmrg      if (prog->_LinkedShaders[i] != NULL)
516001e04c3fSmrg         lower_named_interface_blocks(mem_ctx, prog->_LinkedShaders[i]);
516101e04c3fSmrg   }
516201e04c3fSmrg
516301e04c3fSmrg   if (prog->IsES && prog->data->Version == 100)
516401e04c3fSmrg      if (!validate_invariant_builtins(prog,
516501e04c3fSmrg            prog->_LinkedShaders[MESA_SHADER_VERTEX],
516601e04c3fSmrg            prog->_LinkedShaders[MESA_SHADER_FRAGMENT]))
516701e04c3fSmrg         goto done;
516801e04c3fSmrg
516901e04c3fSmrg   /* Implement the GLSL 1.30+ rule for discard vs infinite loops Do
517001e04c3fSmrg    * it before optimization because we want most of the checks to get
517101e04c3fSmrg    * dropped thanks to constant propagation.
517201e04c3fSmrg    *
517301e04c3fSmrg    * This rule also applies to GLSL ES 3.00.
517401e04c3fSmrg    */
517501e04c3fSmrg   if (max_version >= (prog->IsES ? 300 : 130)) {
517601e04c3fSmrg      struct gl_linked_shader *sh = prog->_LinkedShaders[MESA_SHADER_FRAGMENT];
517701e04c3fSmrg      if (sh) {
517801e04c3fSmrg         lower_discard_flow(sh->ir);
517901e04c3fSmrg      }
518001e04c3fSmrg   }
518101e04c3fSmrg
518201e04c3fSmrg   if (prog->SeparateShader)
518301e04c3fSmrg      disable_varying_optimizations_for_sso(prog);
518401e04c3fSmrg
518501e04c3fSmrg   /* Process UBOs */
518601e04c3fSmrg   if (!interstage_cross_validate_uniform_blocks(prog, false))
518701e04c3fSmrg      goto done;
518801e04c3fSmrg
518901e04c3fSmrg   /* Process SSBOs */
519001e04c3fSmrg   if (!interstage_cross_validate_uniform_blocks(prog, true))
519101e04c3fSmrg      goto done;
519201e04c3fSmrg
519301e04c3fSmrg   /* Do common optimization before assigning storage for attributes,
519401e04c3fSmrg    * uniforms, and varyings.  Later optimization could possibly make
519501e04c3fSmrg    * some of that unused.
519601e04c3fSmrg    */
519701e04c3fSmrg   for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
519801e04c3fSmrg      if (prog->_LinkedShaders[i] == NULL)
519901e04c3fSmrg         continue;
520001e04c3fSmrg
520101e04c3fSmrg      detect_recursion_linked(prog, prog->_LinkedShaders[i]->ir);
520201e04c3fSmrg      if (!prog->data->LinkStatus)
520301e04c3fSmrg         goto done;
520401e04c3fSmrg
520501e04c3fSmrg      if (ctx->Const.ShaderCompilerOptions[i].LowerCombinedClipCullDistance) {
520601e04c3fSmrg         lower_clip_cull_distance(prog, prog->_LinkedShaders[i]);
520701e04c3fSmrg      }
520801e04c3fSmrg
520901e04c3fSmrg      if (ctx->Const.LowerTessLevel) {
521001e04c3fSmrg         lower_tess_level(prog->_LinkedShaders[i]);
521101e04c3fSmrg      }
521201e04c3fSmrg
521301e04c3fSmrg      /* Section 13.46 (Vertex Attribute Aliasing) of the OpenGL ES 3.2
521401e04c3fSmrg       * specification says:
521501e04c3fSmrg       *
521601e04c3fSmrg       *    "In general, the behavior of GLSL ES should not depend on compiler
521701e04c3fSmrg       *    optimizations which might be implementation-dependent. Name matching
521801e04c3fSmrg       *    rules in most languages, including C++ from which GLSL ES is derived,
521901e04c3fSmrg       *    are based on declarations rather than use.
522001e04c3fSmrg       *
522101e04c3fSmrg       *    RESOLUTION: The existence of aliasing is determined by declarations
522201e04c3fSmrg       *    present after preprocessing."
522301e04c3fSmrg       *
522401e04c3fSmrg       * Because of this rule, we do a 'dry-run' of attribute assignment for
522501e04c3fSmrg       * vertex shader inputs here.
522601e04c3fSmrg       */
522701e04c3fSmrg      if (prog->IsES && i == MESA_SHADER_VERTEX) {
522801e04c3fSmrg         if (!assign_attribute_or_color_locations(mem_ctx, prog, &ctx->Const,
522901e04c3fSmrg                                                  MESA_SHADER_VERTEX, false)) {
523001e04c3fSmrg            goto done;
523101e04c3fSmrg         }
523201e04c3fSmrg      }
523301e04c3fSmrg
523401e04c3fSmrg      /* Call opts before lowering const arrays to uniforms so we can const
523501e04c3fSmrg       * propagate any elements accessed directly.
523601e04c3fSmrg       */
523701e04c3fSmrg      linker_optimisation_loop(ctx, prog->_LinkedShaders[i]->ir, i);
523801e04c3fSmrg
523901e04c3fSmrg      /* Call opts after lowering const arrays to copy propagate things. */
524001e04c3fSmrg      if (lower_const_arrays_to_uniforms(prog->_LinkedShaders[i]->ir, i))
524101e04c3fSmrg         linker_optimisation_loop(ctx, prog->_LinkedShaders[i]->ir, i);
524201e04c3fSmrg
524301e04c3fSmrg      propagate_invariance(prog->_LinkedShaders[i]->ir);
524401e04c3fSmrg   }
524501e04c3fSmrg
524601e04c3fSmrg   /* Validation for special cases where we allow sampler array indexing
524701e04c3fSmrg    * with loop induction variable. This check emits a warning or error
524801e04c3fSmrg    * depending if backend can handle dynamic indexing.
524901e04c3fSmrg    */
525001e04c3fSmrg   if ((!prog->IsES && prog->data->Version < 130) ||
525101e04c3fSmrg       (prog->IsES && prog->data->Version < 300)) {
525201e04c3fSmrg      if (!validate_sampler_array_indexing(ctx, prog))
525301e04c3fSmrg         goto done;
525401e04c3fSmrg   }
525501e04c3fSmrg
525601e04c3fSmrg   /* Check and validate stream emissions in geometry shaders */
525701e04c3fSmrg   validate_geometry_shader_emissions(ctx, prog);
525801e04c3fSmrg
525901e04c3fSmrg   store_fragdepth_layout(prog);
526001e04c3fSmrg
526101e04c3fSmrg   if(!link_varyings_and_uniforms(first, last, ctx, prog, mem_ctx))
526201e04c3fSmrg      goto done;
526301e04c3fSmrg
526401e04c3fSmrg   /* Linking varyings can cause some extra, useless swizzles to be generated
526501e04c3fSmrg    * due to packing and unpacking.
526601e04c3fSmrg    */
526701e04c3fSmrg   for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
526801e04c3fSmrg      if (prog->_LinkedShaders[i] == NULL)
526901e04c3fSmrg         continue;
527001e04c3fSmrg
527101e04c3fSmrg      optimize_swizzles(prog->_LinkedShaders[i]->ir);
527201e04c3fSmrg   }
527301e04c3fSmrg
527401e04c3fSmrg   /* OpenGL ES < 3.1 requires that a vertex shader and a fragment shader both
527501e04c3fSmrg    * be present in a linked program. GL_ARB_ES2_compatibility doesn't say
527601e04c3fSmrg    * anything about shader linking when one of the shaders (vertex or
527701e04c3fSmrg    * fragment shader) is absent. So, the extension shouldn't change the
527801e04c3fSmrg    * behavior specified in GLSL specification.
527901e04c3fSmrg    *
528001e04c3fSmrg    * From OpenGL ES 3.1 specification (7.3 Program Objects):
528101e04c3fSmrg    *     "Linking can fail for a variety of reasons as specified in the
528201e04c3fSmrg    *     OpenGL ES Shading Language Specification, as well as any of the
528301e04c3fSmrg    *     following reasons:
528401e04c3fSmrg    *
528501e04c3fSmrg    *     ...
528601e04c3fSmrg    *
528701e04c3fSmrg    *     * program contains objects to form either a vertex shader or
528801e04c3fSmrg    *       fragment shader, and program is not separable, and does not
528901e04c3fSmrg    *       contain objects to form both a vertex shader and fragment
529001e04c3fSmrg    *       shader."
529101e04c3fSmrg    *
529201e04c3fSmrg    * However, the only scenario in 3.1+ where we don't require them both is
529301e04c3fSmrg    * when we have a compute shader. For example:
529401e04c3fSmrg    *
529501e04c3fSmrg    * - No shaders is a link error.
529601e04c3fSmrg    * - Geom or Tess without a Vertex shader is a link error which means we
529701e04c3fSmrg    *   always require a Vertex shader and hence a Fragment shader.
529801e04c3fSmrg    * - Finally a Compute shader linked with any other stage is a link error.
529901e04c3fSmrg    */
530001e04c3fSmrg   if (!prog->SeparateShader && ctx->API == API_OPENGLES2 &&
530101e04c3fSmrg       num_shaders[MESA_SHADER_COMPUTE] == 0) {
530201e04c3fSmrg      if (prog->_LinkedShaders[MESA_SHADER_VERTEX] == NULL) {
530301e04c3fSmrg         linker_error(prog, "program lacks a vertex shader\n");
530401e04c3fSmrg      } else if (prog->_LinkedShaders[MESA_SHADER_FRAGMENT] == NULL) {
530501e04c3fSmrg         linker_error(prog, "program lacks a fragment shader\n");
530601e04c3fSmrg      }
530701e04c3fSmrg   }
530801e04c3fSmrg
530901e04c3fSmrgdone:
531001e04c3fSmrg   for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
531101e04c3fSmrg      free(shader_list[i]);
531201e04c3fSmrg      if (prog->_LinkedShaders[i] == NULL)
531301e04c3fSmrg         continue;
531401e04c3fSmrg
531501e04c3fSmrg      /* Do a final validation step to make sure that the IR wasn't
531601e04c3fSmrg       * invalidated by any modifications performed after intrastage linking.
531701e04c3fSmrg       */
531801e04c3fSmrg      validate_ir_tree(prog->_LinkedShaders[i]->ir);
531901e04c3fSmrg
532001e04c3fSmrg      /* Retain any live IR, but trash the rest. */
532101e04c3fSmrg      reparent_ir(prog->_LinkedShaders[i]->ir, prog->_LinkedShaders[i]->ir);
532201e04c3fSmrg
532301e04c3fSmrg      /* The symbol table in the linked shaders may contain references to
532401e04c3fSmrg       * variables that were removed (e.g., unused uniforms).  Since it may
532501e04c3fSmrg       * contain junk, there is no possible valid use.  Delete it and set the
532601e04c3fSmrg       * pointer to NULL.
532701e04c3fSmrg       */
532801e04c3fSmrg      delete prog->_LinkedShaders[i]->symbols;
532901e04c3fSmrg      prog->_LinkedShaders[i]->symbols = NULL;
533001e04c3fSmrg   }
533101e04c3fSmrg
533201e04c3fSmrg   ralloc_free(mem_ctx);
533301e04c3fSmrg}
5334