101e04c3fSmrg/*
201e04c3fSmrg * Copyright © 2013 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 link_interface_blocks.cpp
2601e04c3fSmrg * Linker support for GLSL's interface blocks.
2701e04c3fSmrg */
2801e04c3fSmrg
2901e04c3fSmrg#include "ir.h"
3001e04c3fSmrg#include "glsl_symbol_table.h"
3101e04c3fSmrg#include "linker.h"
3201e04c3fSmrg#include "main/macros.h"
3301e04c3fSmrg#include "main/mtypes.h"
3401e04c3fSmrg#include "util/hash_table.h"
3501e04c3fSmrg#include "util/u_string.h"
3601e04c3fSmrg
3701e04c3fSmrg
3801e04c3fSmrgnamespace {
3901e04c3fSmrg
4001e04c3fSmrg/**
4101e04c3fSmrg * Return true if interface members mismatch and its not allowed by GLSL.
4201e04c3fSmrg */
4301e04c3fSmrgstatic bool
4401e04c3fSmrginterstage_member_mismatch(struct gl_shader_program *prog,
4501e04c3fSmrg                           const glsl_type *c, const glsl_type *p) {
4601e04c3fSmrg
4701e04c3fSmrg   if (c->length != p->length)
4801e04c3fSmrg      return true;
4901e04c3fSmrg
5001e04c3fSmrg   for (unsigned i = 0; i < c->length; i++) {
5101e04c3fSmrg      if (c->fields.structure[i].type != p->fields.structure[i].type)
5201e04c3fSmrg         return true;
5301e04c3fSmrg      if (strcmp(c->fields.structure[i].name,
5401e04c3fSmrg                 p->fields.structure[i].name) != 0)
5501e04c3fSmrg         return true;
5601e04c3fSmrg      if (c->fields.structure[i].location !=
5701e04c3fSmrg          p->fields.structure[i].location)
5801e04c3fSmrg         return true;
597ec681f3Smrg      if (c->fields.structure[i].component !=
607ec681f3Smrg          p->fields.structure[i].component)
617ec681f3Smrg         return true;
6201e04c3fSmrg      if (c->fields.structure[i].patch !=
6301e04c3fSmrg          p->fields.structure[i].patch)
6401e04c3fSmrg         return true;
6501e04c3fSmrg
6601e04c3fSmrg      /* From Section 4.5 (Interpolation Qualifiers) of the GLSL 4.40 spec:
6701e04c3fSmrg       *
6801e04c3fSmrg       *    "It is a link-time error if, within the same stage, the
6901e04c3fSmrg       *    interpolation qualifiers of variables of the same name do not
7001e04c3fSmrg       *    match."
7101e04c3fSmrg       */
7201e04c3fSmrg      if (prog->IsES || prog->data->Version < 440)
7301e04c3fSmrg         if (c->fields.structure[i].interpolation !=
7401e04c3fSmrg             p->fields.structure[i].interpolation)
7501e04c3fSmrg            return true;
7601e04c3fSmrg
7701e04c3fSmrg      /* From Section 4.3.4 (Input Variables) of the GLSL ES 3.0 spec:
7801e04c3fSmrg       *
7901e04c3fSmrg       *    "The output of the vertex shader and the input of the fragment
8001e04c3fSmrg       *    shader form an interface.  For this interface, vertex shader
8101e04c3fSmrg       *    output variables and fragment shader input variables of the same
8201e04c3fSmrg       *    name must match in type and qualification (other than precision
8301e04c3fSmrg       *    and out matching to in).
8401e04c3fSmrg       *
8501e04c3fSmrg       * The table in Section 9.2.1 Linked Shaders of the GLSL ES 3.1 spec
8601e04c3fSmrg       * says that centroid no longer needs to match for varyings.
8701e04c3fSmrg       *
8801e04c3fSmrg       * The table in Section 9.2.1 Linked Shaders of the GLSL ES 3.2 spec
8901e04c3fSmrg       * says that sample need not match for varyings.
9001e04c3fSmrg       */
9101e04c3fSmrg      if (!prog->IsES || prog->data->Version < 310)
9201e04c3fSmrg         if (c->fields.structure[i].centroid !=
9301e04c3fSmrg             p->fields.structure[i].centroid)
9401e04c3fSmrg            return true;
9501e04c3fSmrg      if (!prog->IsES)
9601e04c3fSmrg         if (c->fields.structure[i].sample !=
9701e04c3fSmrg             p->fields.structure[i].sample)
9801e04c3fSmrg            return true;
9901e04c3fSmrg   }
10001e04c3fSmrg
10101e04c3fSmrg   return false;
10201e04c3fSmrg}
10301e04c3fSmrg
10401e04c3fSmrg/**
10501e04c3fSmrg * Check if two interfaces match, according to intrastage interface matching
10601e04c3fSmrg * rules.  If they do, and the first interface uses an unsized array, it will
10701e04c3fSmrg * be updated to reflect the array size declared in the second interface.
10801e04c3fSmrg */
10901e04c3fSmrgbool
11001e04c3fSmrgintrastage_match(ir_variable *a,
11101e04c3fSmrg                 ir_variable *b,
1127ec681f3Smrg                 struct gl_shader_program *prog,
1137ec681f3Smrg                 bool match_precision)
11401e04c3fSmrg{
1157ec681f3Smrg   /* From section 4.7 "Precision and Precision Qualifiers" in GLSL 4.50:
1167ec681f3Smrg    *
1177ec681f3Smrg    *    "For the purposes of determining if an output from one shader
1187ec681f3Smrg    *    stage matches an input of the next stage, the precision qualifier
1197ec681f3Smrg    *    need not match."
1207ec681f3Smrg    */
1217ec681f3Smrg   bool interface_type_match =
1227ec681f3Smrg      (prog->IsES ?
1237ec681f3Smrg       a->get_interface_type() == b->get_interface_type() :
1247ec681f3Smrg       a->get_interface_type()->compare_no_precision(b->get_interface_type()));
1257ec681f3Smrg
12601e04c3fSmrg   /* Types must match. */
1277ec681f3Smrg   if (!interface_type_match) {
12801e04c3fSmrg      /* Exception: if both the interface blocks are implicitly declared,
12901e04c3fSmrg       * don't force their types to match.  They might mismatch due to the two
13001e04c3fSmrg       * shaders using different GLSL versions, and that's ok.
13101e04c3fSmrg       */
13201e04c3fSmrg      if ((a->data.how_declared != ir_var_declared_implicitly ||
13301e04c3fSmrg           b->data.how_declared != ir_var_declared_implicitly) &&
13401e04c3fSmrg          (!prog->IsES ||
13501e04c3fSmrg           interstage_member_mismatch(prog, a->get_interface_type(),
13601e04c3fSmrg                                      b->get_interface_type())))
13701e04c3fSmrg         return false;
13801e04c3fSmrg   }
13901e04c3fSmrg
14001e04c3fSmrg   /* Presence/absence of interface names must match. */
14101e04c3fSmrg   if (a->is_interface_instance() != b->is_interface_instance())
14201e04c3fSmrg      return false;
14301e04c3fSmrg
14401e04c3fSmrg   /* For uniforms, instance names need not match.  For shader ins/outs,
14501e04c3fSmrg    * it's not clear from the spec whether they need to match, but
14601e04c3fSmrg    * Mesa's implementation relies on them matching.
14701e04c3fSmrg    */
14801e04c3fSmrg   if (a->is_interface_instance() && b->data.mode != ir_var_uniform &&
14901e04c3fSmrg       b->data.mode != ir_var_shader_storage &&
15001e04c3fSmrg       strcmp(a->name, b->name) != 0) {
15101e04c3fSmrg      return false;
15201e04c3fSmrg   }
15301e04c3fSmrg
1547ec681f3Smrg   bool type_match = (match_precision ?
1557ec681f3Smrg                      a->type == b->type :
1567ec681f3Smrg                      a->type->compare_no_precision(b->type));
1577ec681f3Smrg
15801e04c3fSmrg   /* If a block is an array then it must match across the shader.
15901e04c3fSmrg    * Unsized arrays are also processed and matched agaist sized arrays.
16001e04c3fSmrg    */
1617ec681f3Smrg   if (!type_match && (b->type->is_array() || a->type->is_array()) &&
16201e04c3fSmrg       (b->is_interface_instance() || a->is_interface_instance()) &&
1637ec681f3Smrg       !validate_intrastage_arrays(prog, b, a, match_precision))
16401e04c3fSmrg      return false;
16501e04c3fSmrg
16601e04c3fSmrg   return true;
16701e04c3fSmrg}
16801e04c3fSmrg
16901e04c3fSmrg/**
17001e04c3fSmrg * Check if two interfaces match, according to interstage (in/out) interface
17101e04c3fSmrg * matching rules.
17201e04c3fSmrg *
17301e04c3fSmrg * If \c extra_array_level is true, the consumer interface is required to be
17401e04c3fSmrg * an array and the producer interface is required to be a non-array.
17501e04c3fSmrg * This is used for tessellation control and geometry shader consumers.
17601e04c3fSmrg */
17701e04c3fSmrgstatic bool
17801e04c3fSmrginterstage_match(struct gl_shader_program *prog, ir_variable *producer,
17901e04c3fSmrg                 ir_variable *consumer, bool extra_array_level)
18001e04c3fSmrg{
18101e04c3fSmrg   /* Types must match. */
18201e04c3fSmrg   if (consumer->get_interface_type() != producer->get_interface_type()) {
18301e04c3fSmrg      /* Exception: if both the interface blocks are implicitly declared,
18401e04c3fSmrg       * don't force their types to match.  They might mismatch due to the two
18501e04c3fSmrg       * shaders using different GLSL versions, and that's ok.
18601e04c3fSmrg       *
18701e04c3fSmrg       * Also we store some member information such as interpolation in
18801e04c3fSmrg       * glsl_type that doesn't always have to match across shader stages.
18901e04c3fSmrg       * Therefore we make a pass over the members glsl_struct_field to make
19001e04c3fSmrg       * sure we don't reject shaders where fields don't need to match.
19101e04c3fSmrg       */
19201e04c3fSmrg      if ((consumer->data.how_declared != ir_var_declared_implicitly ||
19301e04c3fSmrg           producer->data.how_declared != ir_var_declared_implicitly) &&
19401e04c3fSmrg          interstage_member_mismatch(prog, consumer->get_interface_type(),
19501e04c3fSmrg                                     producer->get_interface_type()))
19601e04c3fSmrg         return false;
19701e04c3fSmrg   }
19801e04c3fSmrg
19901e04c3fSmrg   /* Ignore outermost array if geom shader */
20001e04c3fSmrg   const glsl_type *consumer_instance_type;
20101e04c3fSmrg   if (extra_array_level) {
20201e04c3fSmrg      consumer_instance_type = consumer->type->fields.array;
20301e04c3fSmrg   } else {
20401e04c3fSmrg      consumer_instance_type = consumer->type;
20501e04c3fSmrg   }
20601e04c3fSmrg
20701e04c3fSmrg   /* If a block is an array then it must match across shaders.
20801e04c3fSmrg    * Since unsized arrays have been ruled out, we can check this by just
20901e04c3fSmrg    * making sure the types are equal.
21001e04c3fSmrg    */
21101e04c3fSmrg   if ((consumer->is_interface_instance() &&
21201e04c3fSmrg        consumer_instance_type->is_array()) ||
21301e04c3fSmrg       (producer->is_interface_instance() &&
21401e04c3fSmrg        producer->type->is_array())) {
21501e04c3fSmrg      if (consumer_instance_type != producer->type)
21601e04c3fSmrg         return false;
21701e04c3fSmrg   }
21801e04c3fSmrg
21901e04c3fSmrg   return true;
22001e04c3fSmrg}
22101e04c3fSmrg
22201e04c3fSmrg
22301e04c3fSmrg/**
22401e04c3fSmrg * This class keeps track of a mapping from an interface block name to the
22501e04c3fSmrg * necessary information about that interface block to determine whether to
22601e04c3fSmrg * generate a link error.
22701e04c3fSmrg *
22801e04c3fSmrg * Note: this class is expected to be short lived, so it doesn't make copies
22901e04c3fSmrg * of the strings it references; it simply borrows the pointers from the
23001e04c3fSmrg * ir_variable class.
23101e04c3fSmrg */
23201e04c3fSmrgclass interface_block_definitions
23301e04c3fSmrg{
23401e04c3fSmrgpublic:
23501e04c3fSmrg   interface_block_definitions()
23601e04c3fSmrg      : mem_ctx(ralloc_context(NULL)),
2377ec681f3Smrg        ht(_mesa_hash_table_create(NULL, _mesa_hash_string,
23801e04c3fSmrg                                   _mesa_key_string_equal))
23901e04c3fSmrg   {
24001e04c3fSmrg   }
24101e04c3fSmrg
24201e04c3fSmrg   ~interface_block_definitions()
24301e04c3fSmrg   {
24401e04c3fSmrg      ralloc_free(mem_ctx);
24501e04c3fSmrg      _mesa_hash_table_destroy(ht, NULL);
24601e04c3fSmrg   }
24701e04c3fSmrg
24801e04c3fSmrg   /**
24901e04c3fSmrg    * Lookup the interface definition. Return NULL if none is found.
25001e04c3fSmrg    */
25101e04c3fSmrg   ir_variable *lookup(ir_variable *var)
25201e04c3fSmrg   {
25301e04c3fSmrg      if (var->data.explicit_location &&
25401e04c3fSmrg          var->data.location >= VARYING_SLOT_VAR0) {
25501e04c3fSmrg         char location_str[11];
2567ec681f3Smrg         snprintf(location_str, 11, "%d", var->data.location);
25701e04c3fSmrg
25801e04c3fSmrg         const struct hash_entry *entry =
25901e04c3fSmrg            _mesa_hash_table_search(ht, location_str);
26001e04c3fSmrg         return entry ? (ir_variable *) entry->data : NULL;
26101e04c3fSmrg      } else {
26201e04c3fSmrg         const struct hash_entry *entry =
26301e04c3fSmrg            _mesa_hash_table_search(ht,
26401e04c3fSmrg               var->get_interface_type()->without_array()->name);
26501e04c3fSmrg         return entry ? (ir_variable *) entry->data : NULL;
26601e04c3fSmrg      }
26701e04c3fSmrg   }
26801e04c3fSmrg
26901e04c3fSmrg   /**
27001e04c3fSmrg    * Add a new interface definition.
27101e04c3fSmrg    */
27201e04c3fSmrg   void store(ir_variable *var)
27301e04c3fSmrg   {
27401e04c3fSmrg      if (var->data.explicit_location &&
27501e04c3fSmrg          var->data.location >= VARYING_SLOT_VAR0) {
27601e04c3fSmrg         /* If explicit location is given then lookup the variable by location.
27701e04c3fSmrg          * We turn the location into a string and use this as the hash key
27801e04c3fSmrg          * rather than the name. Note: We allocate enough space for a 32-bit
27901e04c3fSmrg          * unsigned location value which is overkill but future proof.
28001e04c3fSmrg          */
28101e04c3fSmrg         char location_str[11];
2827ec681f3Smrg         snprintf(location_str, 11, "%d", var->data.location);
28301e04c3fSmrg         _mesa_hash_table_insert(ht, ralloc_strdup(mem_ctx, location_str), var);
28401e04c3fSmrg      } else {
28501e04c3fSmrg         _mesa_hash_table_insert(ht,
28601e04c3fSmrg            var->get_interface_type()->without_array()->name, var);
28701e04c3fSmrg      }
28801e04c3fSmrg   }
28901e04c3fSmrg
29001e04c3fSmrgprivate:
29101e04c3fSmrg   /**
29201e04c3fSmrg    * Ralloc context for data structures allocated by this class.
29301e04c3fSmrg    */
29401e04c3fSmrg   void *mem_ctx;
29501e04c3fSmrg
29601e04c3fSmrg   /**
29701e04c3fSmrg    * Hash table mapping interface block name to an \c
29801e04c3fSmrg    * ir_variable.
29901e04c3fSmrg    */
30001e04c3fSmrg   hash_table *ht;
30101e04c3fSmrg};
30201e04c3fSmrg
30301e04c3fSmrg
30401e04c3fSmrg}; /* anonymous namespace */
30501e04c3fSmrg
30601e04c3fSmrg
30701e04c3fSmrgvoid
30801e04c3fSmrgvalidate_intrastage_interface_blocks(struct gl_shader_program *prog,
30901e04c3fSmrg                                     const gl_shader **shader_list,
31001e04c3fSmrg                                     unsigned num_shaders)
31101e04c3fSmrg{
31201e04c3fSmrg   interface_block_definitions in_interfaces;
31301e04c3fSmrg   interface_block_definitions out_interfaces;
31401e04c3fSmrg   interface_block_definitions uniform_interfaces;
31501e04c3fSmrg   interface_block_definitions buffer_interfaces;
31601e04c3fSmrg
31701e04c3fSmrg   for (unsigned int i = 0; i < num_shaders; i++) {
31801e04c3fSmrg      if (shader_list[i] == NULL)
31901e04c3fSmrg         continue;
32001e04c3fSmrg
32101e04c3fSmrg      foreach_in_list(ir_instruction, node, shader_list[i]->ir) {
32201e04c3fSmrg         ir_variable *var = node->as_variable();
32301e04c3fSmrg         if (!var)
32401e04c3fSmrg            continue;
32501e04c3fSmrg
32601e04c3fSmrg         const glsl_type *iface_type = var->get_interface_type();
32701e04c3fSmrg
32801e04c3fSmrg         if (iface_type == NULL)
32901e04c3fSmrg            continue;
33001e04c3fSmrg
33101e04c3fSmrg         interface_block_definitions *definitions;
33201e04c3fSmrg         switch (var->data.mode) {
33301e04c3fSmrg         case ir_var_shader_in:
33401e04c3fSmrg            definitions = &in_interfaces;
33501e04c3fSmrg            break;
33601e04c3fSmrg         case ir_var_shader_out:
33701e04c3fSmrg            definitions = &out_interfaces;
33801e04c3fSmrg            break;
33901e04c3fSmrg         case ir_var_uniform:
34001e04c3fSmrg            definitions = &uniform_interfaces;
34101e04c3fSmrg            break;
34201e04c3fSmrg         case ir_var_shader_storage:
34301e04c3fSmrg            definitions = &buffer_interfaces;
34401e04c3fSmrg            break;
34501e04c3fSmrg         default:
34601e04c3fSmrg            /* Only in, out, and uniform interfaces are legal, so we should
34701e04c3fSmrg             * never get here.
34801e04c3fSmrg             */
34901e04c3fSmrg            assert(!"illegal interface type");
35001e04c3fSmrg            continue;
35101e04c3fSmrg         }
35201e04c3fSmrg
35301e04c3fSmrg         ir_variable *prev_def = definitions->lookup(var);
35401e04c3fSmrg         if (prev_def == NULL) {
35501e04c3fSmrg            /* This is the first time we've seen the interface, so save
35601e04c3fSmrg             * it into the appropriate data structure.
35701e04c3fSmrg             */
35801e04c3fSmrg            definitions->store(var);
3597ec681f3Smrg         } else if (!intrastage_match(prev_def, var, prog,
3607ec681f3Smrg                                      true /* match_precision */)) {
36101e04c3fSmrg            linker_error(prog, "definitions of interface block `%s' do not"
36201e04c3fSmrg                         " match\n", iface_type->name);
36301e04c3fSmrg            return;
36401e04c3fSmrg         }
36501e04c3fSmrg      }
36601e04c3fSmrg   }
36701e04c3fSmrg}
36801e04c3fSmrg
36901e04c3fSmrgstatic bool
37001e04c3fSmrgis_builtin_gl_in_block(ir_variable *var, int consumer_stage)
37101e04c3fSmrg{
37201e04c3fSmrg   return !strcmp(var->name, "gl_in") &&
37301e04c3fSmrg          (consumer_stage == MESA_SHADER_TESS_CTRL ||
37401e04c3fSmrg           consumer_stage == MESA_SHADER_TESS_EVAL ||
37501e04c3fSmrg           consumer_stage == MESA_SHADER_GEOMETRY);
37601e04c3fSmrg}
37701e04c3fSmrg
37801e04c3fSmrgvoid
37901e04c3fSmrgvalidate_interstage_inout_blocks(struct gl_shader_program *prog,
38001e04c3fSmrg                                 const gl_linked_shader *producer,
38101e04c3fSmrg                                 const gl_linked_shader *consumer)
38201e04c3fSmrg{
38301e04c3fSmrg   interface_block_definitions definitions;
38401e04c3fSmrg   /* VS -> GS, VS -> TCS, VS -> TES, TES -> GS */
38501e04c3fSmrg   const bool extra_array_level = (producer->Stage == MESA_SHADER_VERTEX &&
38601e04c3fSmrg                                   consumer->Stage != MESA_SHADER_FRAGMENT) ||
38701e04c3fSmrg                                  consumer->Stage == MESA_SHADER_GEOMETRY;
38801e04c3fSmrg
38901e04c3fSmrg   /* Check that block re-declarations of gl_PerVertex are compatible
39001e04c3fSmrg    * across shaders: From OpenGL Shading Language 4.5, section
39101e04c3fSmrg    * "7.1 Built-In Language Variables", page 130 of the PDF:
39201e04c3fSmrg    *
39301e04c3fSmrg    *    "If multiple shaders using members of a built-in block belonging
39401e04c3fSmrg    *     to the same interface are linked together in the same program,
39501e04c3fSmrg    *     they must all redeclare the built-in block in the same way, as
39601e04c3fSmrg    *     described in section 4.3.9 “Interface Blocks” for interface-block
39701e04c3fSmrg    *     matching, or a link-time error will result."
39801e04c3fSmrg    *
39901e04c3fSmrg    * This is done explicitly outside of iterating the member variable
40001e04c3fSmrg    * declarations because it is possible that the variables are not used and
40101e04c3fSmrg    * so they would have been optimised out.
40201e04c3fSmrg    */
40301e04c3fSmrg   const glsl_type *consumer_iface =
40401e04c3fSmrg      consumer->symbols->get_interface("gl_PerVertex",
40501e04c3fSmrg                                       ir_var_shader_in);
40601e04c3fSmrg
40701e04c3fSmrg   const glsl_type *producer_iface =
40801e04c3fSmrg      producer->symbols->get_interface("gl_PerVertex",
40901e04c3fSmrg                                       ir_var_shader_out);
41001e04c3fSmrg
41101e04c3fSmrg   if (producer_iface && consumer_iface &&
41201e04c3fSmrg       interstage_member_mismatch(prog, consumer_iface, producer_iface)) {
41301e04c3fSmrg      linker_error(prog, "Incompatible or missing gl_PerVertex re-declaration "
41401e04c3fSmrg                   "in consecutive shaders");
41501e04c3fSmrg      return;
41601e04c3fSmrg   }
41701e04c3fSmrg
4187ec681f3Smrg   /* Desktop OpenGL requires redeclaration of the built-in interfaces for
4197ec681f3Smrg    * SSO programs. Passes above implement following rules:
4207ec681f3Smrg    *
4217ec681f3Smrg    * From Section 7.4 (Program Pipeline Objects) of the OpenGL 4.6 Core
4227ec681f3Smrg    * spec:
4237ec681f3Smrg    *
4247ec681f3Smrg    *    "To use any built-in input or output in the gl_PerVertex and
4257ec681f3Smrg    *     gl_PerFragment blocks in separable program objects, shader code
4267ec681f3Smrg    *     must redeclare those blocks prior to use.  A separable program
4277ec681f3Smrg    *     will fail to link if:
4287ec681f3Smrg    *
4297ec681f3Smrg    *     it contains multiple shaders of a single type with different
4307ec681f3Smrg    *     redeclarations of these built-in input and output blocks; or
4317ec681f3Smrg    *
4327ec681f3Smrg    *     any shader uses a built-in block member not found in the
4337ec681f3Smrg    *     redeclaration of that block."
4347ec681f3Smrg    *
4357ec681f3Smrg    * ARB_separate_shader_objects issues section (issue #28) states that
4367ec681f3Smrg    * redeclaration is not required for GLSL shaders using #version 140 or
4377ec681f3Smrg    * earlier (since interface blocks are not possible with older versions).
4387ec681f3Smrg    *
4397ec681f3Smrg    * From Section 7.4.1 (Shader Interface Matching) of the OpenGL ES 3.1
4407ec681f3Smrg    * spec:
4417ec681f3Smrg    *
4427ec681f3Smrg    *    "Built-in inputs or outputs do not affect interface matching."
4437ec681f3Smrg    *
4447ec681f3Smrg    * GL_OES_shader_io_blocks adds following:
4457ec681f3Smrg    *
4467ec681f3Smrg    *    "When using any built-in input or output in the gl_PerVertex block
4477ec681f3Smrg    *     in separable program objects, shader code may redeclare that block
4487ec681f3Smrg    *     prior to use. If the shader does not redeclare the block, the
4497ec681f3Smrg    *     intrinsically declared definition of that block will be used."
4507ec681f3Smrg    */
4517ec681f3Smrg
45201e04c3fSmrg   /* Add output interfaces from the producer to the symbol table. */
45301e04c3fSmrg   foreach_in_list(ir_instruction, node, producer->ir) {
45401e04c3fSmrg      ir_variable *var = node->as_variable();
45501e04c3fSmrg      if (!var || !var->get_interface_type() || var->data.mode != ir_var_shader_out)
45601e04c3fSmrg         continue;
45701e04c3fSmrg
4587ec681f3Smrg      /* Built-in interface redeclaration check. */
4597ec681f3Smrg      if (prog->SeparateShader && !prog->IsES && prog->data->Version >= 150 &&
4607ec681f3Smrg          var->data.how_declared == ir_var_declared_implicitly &&
4617ec681f3Smrg          var->data.used && !producer_iface) {
4627ec681f3Smrg         linker_error(prog, "missing output builtin block %s redeclaration "
4637ec681f3Smrg                      "in separable shader program",
4647ec681f3Smrg                      var->get_interface_type()->name);
4657ec681f3Smrg         return;
4667ec681f3Smrg      }
4677ec681f3Smrg
46801e04c3fSmrg      definitions.store(var);
46901e04c3fSmrg   }
47001e04c3fSmrg
47101e04c3fSmrg   /* Verify that the consumer's input interfaces match. */
47201e04c3fSmrg   foreach_in_list(ir_instruction, node, consumer->ir) {
47301e04c3fSmrg      ir_variable *var = node->as_variable();
47401e04c3fSmrg      if (!var || !var->get_interface_type() || var->data.mode != ir_var_shader_in)
47501e04c3fSmrg         continue;
47601e04c3fSmrg
47701e04c3fSmrg      ir_variable *producer_def = definitions.lookup(var);
47801e04c3fSmrg
4797ec681f3Smrg      /* Built-in interface redeclaration check. */
4807ec681f3Smrg      if (prog->SeparateShader && !prog->IsES && prog->data->Version >= 150 &&
4817ec681f3Smrg          var->data.how_declared == ir_var_declared_implicitly &&
4827ec681f3Smrg          var->data.used && !producer_iface) {
4837ec681f3Smrg         linker_error(prog, "missing input builtin block %s redeclaration "
4847ec681f3Smrg                      "in separable shader program",
4857ec681f3Smrg                      var->get_interface_type()->name);
4867ec681f3Smrg         return;
4877ec681f3Smrg      }
4887ec681f3Smrg
48901e04c3fSmrg      /* The producer doesn't generate this input: fail to link. Skip built-in
49001e04c3fSmrg       * 'gl_in[]' since that may not be present if the producer does not
49101e04c3fSmrg       * write to any of the pre-defined outputs (e.g. if the vertex shader
49201e04c3fSmrg       * does not write to gl_Position, etc), which is allowed and results in
49301e04c3fSmrg       * undefined behavior.
49401e04c3fSmrg       *
49501e04c3fSmrg       * From Section 4.3.4 (Inputs) of the GLSL 1.50 spec:
49601e04c3fSmrg       *
49701e04c3fSmrg       *    "Only the input variables that are actually read need to be written
49801e04c3fSmrg       *     by the previous stage; it is allowed to have superfluous
49901e04c3fSmrg       *     declarations of input variables."
50001e04c3fSmrg       */
50101e04c3fSmrg      if (producer_def == NULL &&
50201e04c3fSmrg          !is_builtin_gl_in_block(var, consumer->Stage) && var->data.used) {
50301e04c3fSmrg         linker_error(prog, "Input block `%s' is not an output of "
50401e04c3fSmrg                      "the previous stage\n", var->get_interface_type()->name);
50501e04c3fSmrg         return;
50601e04c3fSmrg      }
50701e04c3fSmrg
50801e04c3fSmrg      if (producer_def &&
50901e04c3fSmrg          !interstage_match(prog, producer_def, var, extra_array_level)) {
51001e04c3fSmrg         linker_error(prog, "definitions of interface block `%s' do not "
51101e04c3fSmrg                      "match\n", var->get_interface_type()->name);
51201e04c3fSmrg         return;
51301e04c3fSmrg      }
51401e04c3fSmrg   }
51501e04c3fSmrg}
51601e04c3fSmrg
51701e04c3fSmrg
51801e04c3fSmrgvoid
51901e04c3fSmrgvalidate_interstage_uniform_blocks(struct gl_shader_program *prog,
52001e04c3fSmrg                                   gl_linked_shader **stages)
52101e04c3fSmrg{
52201e04c3fSmrg   interface_block_definitions definitions;
52301e04c3fSmrg
52401e04c3fSmrg   for (int i = 0; i < MESA_SHADER_STAGES; i++) {
52501e04c3fSmrg      if (stages[i] == NULL)
52601e04c3fSmrg         continue;
52701e04c3fSmrg
52801e04c3fSmrg      const gl_linked_shader *stage = stages[i];
52901e04c3fSmrg      foreach_in_list(ir_instruction, node, stage->ir) {
53001e04c3fSmrg         ir_variable *var = node->as_variable();
53101e04c3fSmrg         if (!var || !var->get_interface_type() ||
53201e04c3fSmrg             (var->data.mode != ir_var_uniform &&
53301e04c3fSmrg              var->data.mode != ir_var_shader_storage))
53401e04c3fSmrg            continue;
53501e04c3fSmrg
53601e04c3fSmrg         ir_variable *old_def = definitions.lookup(var);
53701e04c3fSmrg         if (old_def == NULL) {
53801e04c3fSmrg            definitions.store(var);
53901e04c3fSmrg         } else {
54001e04c3fSmrg            /* Interstage uniform matching rules are the same as intrastage
54101e04c3fSmrg             * uniform matchin rules (for uniforms, it is as though all
54201e04c3fSmrg             * shaders are in the same shader stage).
54301e04c3fSmrg             */
5447ec681f3Smrg            if (!intrastage_match(old_def, var, prog, false /* precision */)) {
54501e04c3fSmrg               linker_error(prog, "definitions of uniform block `%s' do not "
54601e04c3fSmrg                            "match\n", var->get_interface_type()->name);
54701e04c3fSmrg               return;
54801e04c3fSmrg            }
54901e04c3fSmrg         }
55001e04c3fSmrg      }
55101e04c3fSmrg   }
55201e04c3fSmrg}
553