• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2013 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  */
23 
24 /**
25  * \file link_interface_blocks.cpp
26  * Linker support for GLSL's interface blocks.
27  */
28 
29 #include "ir.h"
30 #include "glsl_symbol_table.h"
31 #include "linker.h"
32 #include "main/macros.h"
33 #include "util/hash_table.h"
34 
35 
36 namespace {
37 
38 /**
39  * Return true if interface members mismatch and its not allowed by GLSL.
40  */
41 static bool
interstage_member_mismatch(struct gl_shader_program * prog,const glsl_type * c,const glsl_type * p)42 interstage_member_mismatch(struct gl_shader_program *prog,
43                            const glsl_type *c, const glsl_type *p) {
44 
45    if (c->length != p->length)
46       return true;
47 
48    for (unsigned i = 0; i < c->length; i++) {
49       if (c->fields.structure[i].type != p->fields.structure[i].type)
50          return true;
51       if (strcmp(c->fields.structure[i].name,
52                  p->fields.structure[i].name) != 0)
53          return true;
54       if (c->fields.structure[i].location !=
55           p->fields.structure[i].location)
56          return true;
57       if (c->fields.structure[i].patch !=
58           p->fields.structure[i].patch)
59          return true;
60 
61       /* From Section 4.5 (Interpolation Qualifiers) of the GLSL 4.40 spec:
62        *
63        *    "It is a link-time error if, within the same stage, the
64        *    interpolation qualifiers of variables of the same name do not
65        *    match."
66        */
67       if (prog->IsES || prog->data->Version < 440)
68          if (c->fields.structure[i].interpolation !=
69              p->fields.structure[i].interpolation)
70             return true;
71 
72       /* From Section 4.3.4 (Input Variables) of the GLSL ES 3.0 spec:
73        *
74        *    "The output of the vertex shader and the input of the fragment
75        *    shader form an interface.  For this interface, vertex shader
76        *    output variables and fragment shader input variables of the same
77        *    name must match in type and qualification (other than precision
78        *    and out matching to in).
79        *
80        * The table in Section 9.2.1 Linked Shaders of the GLSL ES 3.1 spec
81        * says that centroid no longer needs to match for varyings.
82        *
83        * The table in Section 9.2.1 Linked Shaders of the GLSL ES 3.2 spec
84        * says that sample need not match for varyings.
85        */
86       if (!prog->IsES || prog->data->Version < 310)
87          if (c->fields.structure[i].centroid !=
88              p->fields.structure[i].centroid)
89             return true;
90       if (!prog->IsES)
91          if (c->fields.structure[i].sample !=
92              p->fields.structure[i].sample)
93             return true;
94    }
95 
96    return false;
97 }
98 
99 /**
100  * Check if two interfaces match, according to intrastage interface matching
101  * rules.  If they do, and the first interface uses an unsized array, it will
102  * be updated to reflect the array size declared in the second interface.
103  */
104 bool
intrastage_match(ir_variable * a,ir_variable * b,struct gl_shader_program * prog)105 intrastage_match(ir_variable *a,
106                  ir_variable *b,
107                  struct gl_shader_program *prog)
108 {
109    /* Types must match. */
110    if (a->get_interface_type() != b->get_interface_type()) {
111       /* Exception: if both the interface blocks are implicitly declared,
112        * don't force their types to match.  They might mismatch due to the two
113        * shaders using different GLSL versions, and that's ok.
114        */
115       if ((a->data.how_declared != ir_var_declared_implicitly ||
116            b->data.how_declared != ir_var_declared_implicitly) &&
117           (!prog->IsES || prog->data->Version != 310 ||
118            interstage_member_mismatch(prog, a->get_interface_type(),
119                                       b->get_interface_type())))
120          return false;
121    }
122 
123    /* Presence/absence of interface names must match. */
124    if (a->is_interface_instance() != b->is_interface_instance())
125       return false;
126 
127    /* For uniforms, instance names need not match.  For shader ins/outs,
128     * it's not clear from the spec whether they need to match, but
129     * Mesa's implementation relies on them matching.
130     */
131    if (a->is_interface_instance() && b->data.mode != ir_var_uniform &&
132        b->data.mode != ir_var_shader_storage &&
133        strcmp(a->name, b->name) != 0) {
134       return false;
135    }
136 
137    /* If a block is an array then it must match across the shader.
138     * Unsized arrays are also processed and matched agaist sized arrays.
139     */
140    if (b->type != a->type &&
141        (b->is_interface_instance() || a->is_interface_instance()) &&
142        !validate_intrastage_arrays(prog, b, a))
143       return false;
144 
145    return true;
146 }
147 
148 /**
149  * Check if two interfaces match, according to interstage (in/out) interface
150  * matching rules.
151  *
152  * If \c extra_array_level is true, the consumer interface is required to be
153  * an array and the producer interface is required to be a non-array.
154  * This is used for tessellation control and geometry shader consumers.
155  */
156 static bool
interstage_match(struct gl_shader_program * prog,ir_variable * producer,ir_variable * consumer,bool extra_array_level)157 interstage_match(struct gl_shader_program *prog, ir_variable *producer,
158                  ir_variable *consumer, bool extra_array_level)
159 {
160    /* Types must match. */
161    if (consumer->get_interface_type() != producer->get_interface_type()) {
162       /* Exception: if both the interface blocks are implicitly declared,
163        * don't force their types to match.  They might mismatch due to the two
164        * shaders using different GLSL versions, and that's ok.
165        *
166        * Also we store some member information such as interpolation in
167        * glsl_type that doesn't always have to match across shader stages.
168        * Therefore we make a pass over the members glsl_struct_field to make
169        * sure we don't reject shaders where fields don't need to match.
170        */
171       if ((consumer->data.how_declared != ir_var_declared_implicitly ||
172            producer->data.how_declared != ir_var_declared_implicitly) &&
173           interstage_member_mismatch(prog, consumer->get_interface_type(),
174                                      producer->get_interface_type()))
175          return false;
176    }
177 
178    /* Ignore outermost array if geom shader */
179    const glsl_type *consumer_instance_type;
180    if (extra_array_level) {
181       consumer_instance_type = consumer->type->fields.array;
182    } else {
183       consumer_instance_type = consumer->type;
184    }
185 
186    /* If a block is an array then it must match across shaders.
187     * Since unsized arrays have been ruled out, we can check this by just
188     * making sure the types are equal.
189     */
190    if ((consumer->is_interface_instance() &&
191         consumer_instance_type->is_array()) ||
192        (producer->is_interface_instance() &&
193         producer->type->is_array())) {
194       if (consumer_instance_type != producer->type)
195          return false;
196    }
197 
198    return true;
199 }
200 
201 
202 /**
203  * This class keeps track of a mapping from an interface block name to the
204  * necessary information about that interface block to determine whether to
205  * generate a link error.
206  *
207  * Note: this class is expected to be short lived, so it doesn't make copies
208  * of the strings it references; it simply borrows the pointers from the
209  * ir_variable class.
210  */
211 class interface_block_definitions
212 {
213 public:
interface_block_definitions()214    interface_block_definitions()
215       : mem_ctx(ralloc_context(NULL)),
216         ht(_mesa_hash_table_create(NULL, _mesa_key_hash_string,
217                                    _mesa_key_string_equal))
218    {
219    }
220 
~interface_block_definitions()221    ~interface_block_definitions()
222    {
223       ralloc_free(mem_ctx);
224       _mesa_hash_table_destroy(ht, NULL);
225    }
226 
227    /**
228     * Lookup the interface definition. Return NULL if none is found.
229     */
lookup(ir_variable * var)230    ir_variable *lookup(ir_variable *var)
231    {
232       if (var->data.explicit_location &&
233           var->data.location >= VARYING_SLOT_VAR0) {
234          char location_str[11];
235          snprintf(location_str, 11, "%d", var->data.location);
236 
237          const struct hash_entry *entry =
238             _mesa_hash_table_search(ht, location_str);
239          return entry ? (ir_variable *) entry->data : NULL;
240       } else {
241          const struct hash_entry *entry =
242             _mesa_hash_table_search(ht,
243                var->get_interface_type()->without_array()->name);
244          return entry ? (ir_variable *) entry->data : NULL;
245       }
246    }
247 
248    /**
249     * Add a new interface definition.
250     */
store(ir_variable * var)251    void store(ir_variable *var)
252    {
253       if (var->data.explicit_location &&
254           var->data.location >= VARYING_SLOT_VAR0) {
255          /* If explicit location is given then lookup the variable by location.
256           * We turn the location into a string and use this as the hash key
257           * rather than the name. Note: We allocate enough space for a 32-bit
258           * unsigned location value which is overkill but future proof.
259           */
260          char location_str[11];
261          snprintf(location_str, 11, "%d", var->data.location);
262          _mesa_hash_table_insert(ht, ralloc_strdup(mem_ctx, location_str), var);
263       } else {
264          _mesa_hash_table_insert(ht,
265             var->get_interface_type()->without_array()->name, var);
266       }
267    }
268 
269 private:
270    /**
271     * Ralloc context for data structures allocated by this class.
272     */
273    void *mem_ctx;
274 
275    /**
276     * Hash table mapping interface block name to an \c
277     * ir_variable.
278     */
279    hash_table *ht;
280 };
281 
282 
283 }; /* anonymous namespace */
284 
285 
286 void
validate_intrastage_interface_blocks(struct gl_shader_program * prog,const gl_shader ** shader_list,unsigned num_shaders)287 validate_intrastage_interface_blocks(struct gl_shader_program *prog,
288                                      const gl_shader **shader_list,
289                                      unsigned num_shaders)
290 {
291    interface_block_definitions in_interfaces;
292    interface_block_definitions out_interfaces;
293    interface_block_definitions uniform_interfaces;
294    interface_block_definitions buffer_interfaces;
295 
296    for (unsigned int i = 0; i < num_shaders; i++) {
297       if (shader_list[i] == NULL)
298          continue;
299 
300       foreach_in_list(ir_instruction, node, shader_list[i]->ir) {
301          ir_variable *var = node->as_variable();
302          if (!var)
303             continue;
304 
305          const glsl_type *iface_type = var->get_interface_type();
306 
307          if (iface_type == NULL)
308             continue;
309 
310          interface_block_definitions *definitions;
311          switch (var->data.mode) {
312          case ir_var_shader_in:
313             definitions = &in_interfaces;
314             break;
315          case ir_var_shader_out:
316             definitions = &out_interfaces;
317             break;
318          case ir_var_uniform:
319             definitions = &uniform_interfaces;
320             break;
321          case ir_var_shader_storage:
322             definitions = &buffer_interfaces;
323             break;
324          default:
325             /* Only in, out, and uniform interfaces are legal, so we should
326              * never get here.
327              */
328             assert(!"illegal interface type");
329             continue;
330          }
331 
332          ir_variable *prev_def = definitions->lookup(var);
333          if (prev_def == NULL) {
334             /* This is the first time we've seen the interface, so save
335              * it into the appropriate data structure.
336              */
337             definitions->store(var);
338          } else if (!intrastage_match(prev_def, var, prog)) {
339             linker_error(prog, "definitions of interface block `%s' do not"
340                          " match\n", iface_type->name);
341             return;
342          }
343       }
344    }
345 }
346 
347 static bool
is_builtin_gl_in_block(ir_variable * var,int consumer_stage)348 is_builtin_gl_in_block(ir_variable *var, int consumer_stage)
349 {
350    return !strcmp(var->name, "gl_in") &&
351           (consumer_stage == MESA_SHADER_TESS_CTRL ||
352            consumer_stage == MESA_SHADER_TESS_EVAL ||
353            consumer_stage == MESA_SHADER_GEOMETRY);
354 }
355 
356 void
validate_interstage_inout_blocks(struct gl_shader_program * prog,const gl_linked_shader * producer,const gl_linked_shader * consumer)357 validate_interstage_inout_blocks(struct gl_shader_program *prog,
358                                  const gl_linked_shader *producer,
359                                  const gl_linked_shader *consumer)
360 {
361    interface_block_definitions definitions;
362    /* VS -> GS, VS -> TCS, VS -> TES, TES -> GS */
363    const bool extra_array_level = (producer->Stage == MESA_SHADER_VERTEX &&
364                                    consumer->Stage != MESA_SHADER_FRAGMENT) ||
365                                   consumer->Stage == MESA_SHADER_GEOMETRY;
366 
367    /* Add output interfaces from the producer to the symbol table. */
368    foreach_in_list(ir_instruction, node, producer->ir) {
369       ir_variable *var = node->as_variable();
370       if (!var || !var->get_interface_type() || var->data.mode != ir_var_shader_out)
371          continue;
372 
373       definitions.store(var);
374    }
375 
376    /* Verify that the consumer's input interfaces match. */
377    foreach_in_list(ir_instruction, node, consumer->ir) {
378       ir_variable *var = node->as_variable();
379       if (!var || !var->get_interface_type() || var->data.mode != ir_var_shader_in)
380          continue;
381 
382       ir_variable *producer_def = definitions.lookup(var);
383 
384       /* The producer doesn't generate this input: fail to link. Skip built-in
385        * 'gl_in[]' since that may not be present if the producer does not
386        * write to any of the pre-defined outputs (e.g. if the vertex shader
387        * does not write to gl_Position, etc), which is allowed and results in
388        * undefined behavior.
389        */
390       if (producer_def == NULL &&
391           !is_builtin_gl_in_block(var, consumer->Stage)) {
392          linker_error(prog, "Input block `%s' is not an output of "
393                       "the previous stage\n", var->get_interface_type()->name);
394          return;
395       }
396 
397       if (producer_def &&
398           !interstage_match(prog, producer_def, var, extra_array_level)) {
399          linker_error(prog, "definitions of interface block `%s' do not "
400                       "match\n", var->get_interface_type()->name);
401          return;
402       }
403    }
404 }
405 
406 
407 void
validate_interstage_uniform_blocks(struct gl_shader_program * prog,gl_linked_shader ** stages)408 validate_interstage_uniform_blocks(struct gl_shader_program *prog,
409                                    gl_linked_shader **stages)
410 {
411    interface_block_definitions definitions;
412 
413    for (int i = 0; i < MESA_SHADER_STAGES; i++) {
414       if (stages[i] == NULL)
415          continue;
416 
417       const gl_linked_shader *stage = stages[i];
418       foreach_in_list(ir_instruction, node, stage->ir) {
419          ir_variable *var = node->as_variable();
420          if (!var || !var->get_interface_type() ||
421              (var->data.mode != ir_var_uniform &&
422               var->data.mode != ir_var_shader_storage))
423             continue;
424 
425          ir_variable *old_def = definitions.lookup(var);
426          if (old_def == NULL) {
427             definitions.store(var);
428          } else {
429             /* Interstage uniform matching rules are the same as intrastage
430              * uniform matchin rules (for uniforms, it is as though all
431              * shaders are in the same shader stage).
432              */
433             if (!intrastage_match(old_def, var, prog)) {
434                linker_error(prog, "definitions of uniform block `%s' do not "
435                             "match\n", var->get_interface_type()->name);
436                return;
437             }
438          }
439       }
440    }
441 }
442