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 "program/hash_table.h"
34 
35 
36 namespace {
37 
38 /**
39  * Information about a single interface block definition that we need to keep
40  * track of in order to check linkage rules.
41  *
42  * Note: this class is expected to be short lived, so it doesn't make copies
43  * of the strings it references; it simply borrows the pointers from the
44  * ir_variable class.
45  */
46 struct interface_block_definition
47 {
48    /**
49     * Extract an interface block definition from an ir_variable that
50     * represents either the interface instance (for named interfaces), or a
51     * member of the interface (for unnamed interfaces).
52     */
interface_block_definition__anonf0ecdd850111::interface_block_definition53    explicit interface_block_definition(const ir_variable *var)
54       : type(var->get_interface_type()),
55         instance_name(NULL),
56         array_size(-1)
57    {
58       if (var->is_interface_instance()) {
59          instance_name = var->name;
60          if (var->type->is_array())
61             array_size = var->type->length;
62       }
63       explicitly_declared = (var->data.how_declared != ir_var_declared_implicitly);
64    }
65 
66    /**
67     * Interface block type
68     */
69    const glsl_type *type;
70 
71    /**
72     * For a named interface block, the instance name.  Otherwise NULL.
73     */
74    const char *instance_name;
75 
76    /**
77     * For an interface block array, the array size (or 0 if unsized).
78     * Otherwise -1.
79     */
80    int array_size;
81 
82    /**
83     * True if this interface block was explicitly declared in the shader;
84     * false if it was an implicitly declared built-in interface block.
85     */
86    bool explicitly_declared;
87 };
88 
89 
90 /**
91  * Check if two interfaces match, according to intrastage interface matching
92  * rules.  If they do, and the first interface uses an unsized array, it will
93  * be updated to reflect the array size declared in the second interface.
94  */
95 bool
intrastage_match(interface_block_definition * a,const interface_block_definition * b,ir_variable_mode mode)96 intrastage_match(interface_block_definition *a,
97                  const interface_block_definition *b,
98                  ir_variable_mode mode)
99 {
100    /* Types must match. */
101    if (a->type != b->type) {
102       /* Exception: if both the interface blocks are implicitly declared,
103        * don't force their types to match.  They might mismatch due to the two
104        * shaders using different GLSL versions, and that's ok.
105        */
106       if (a->explicitly_declared || b->explicitly_declared)
107          return false;
108    }
109 
110    /* Presence/absence of interface names must match. */
111    if ((a->instance_name == NULL) != (b->instance_name == NULL))
112       return false;
113 
114    /* For uniforms, instance names need not match.  For shader ins/outs,
115     * it's not clear from the spec whether they need to match, but
116     * Mesa's implementation relies on them matching.
117     */
118    if (a->instance_name != NULL && mode != ir_var_uniform &&
119        strcmp(a->instance_name, b->instance_name) != 0) {
120       return false;
121    }
122 
123    /* Array vs. nonarray must be consistent, and sizes must be
124     * consistent, with the exception that unsized arrays match sized
125     * arrays.
126     */
127    if ((a->array_size == -1) != (b->array_size == -1))
128       return false;
129    if (b->array_size != 0) {
130       if (a->array_size == 0)
131          a->array_size = b->array_size;
132       else if (a->array_size != b->array_size)
133          return false;
134    }
135 
136    return true;
137 }
138 
139 
140 /**
141  * Check if two interfaces match, according to interstage (in/out) interface
142  * matching rules.
143  *
144  * If \c extra_array_level is true, then vertex-to-geometry shader matching
145  * rules are enforced (i.e. a successful match requires the consumer interface
146  * to be an array and the producer interface to be a non-array).
147  */
148 bool
interstage_match(const interface_block_definition * producer,const interface_block_definition * consumer,bool extra_array_level)149 interstage_match(const interface_block_definition *producer,
150                  const interface_block_definition *consumer,
151                  bool extra_array_level)
152 {
153    /* Unsized arrays should not occur during interstage linking.  They
154     * should have all been assigned a size by link_intrastage_shaders.
155     */
156    assert(consumer->array_size != 0);
157    assert(producer->array_size != 0);
158 
159    /* Types must match. */
160    if (consumer->type != producer->type) {
161       /* Exception: if both the interface blocks are implicitly declared,
162        * don't force their types to match.  They might mismatch due to the two
163        * shaders using different GLSL versions, and that's ok.
164        */
165       if (consumer->explicitly_declared || producer->explicitly_declared)
166          return false;
167    }
168    if (extra_array_level) {
169       /* Consumer must be an array, and producer must not. */
170       if (consumer->array_size == -1)
171          return false;
172       if (producer->array_size != -1)
173          return false;
174    } else {
175       /* Array vs. nonarray must be consistent, and sizes must be consistent.
176        * Since unsized arrays have been ruled out, we can check this by just
177        * making sure the sizes are equal.
178        */
179       if (consumer->array_size != producer->array_size)
180          return false;
181    }
182    return true;
183 }
184 
185 
186 /**
187  * This class keeps track of a mapping from an interface block name to the
188  * necessary information about that interface block to determine whether to
189  * generate a link error.
190  *
191  * Note: this class is expected to be short lived, so it doesn't make copies
192  * of the strings it references; it simply borrows the pointers from the
193  * ir_variable class.
194  */
195 class interface_block_definitions
196 {
197 public:
interface_block_definitions()198    interface_block_definitions()
199       : mem_ctx(ralloc_context(NULL)),
200         ht(hash_table_ctor(0, hash_table_string_hash,
201                            hash_table_string_compare))
202    {
203    }
204 
~interface_block_definitions()205    ~interface_block_definitions()
206    {
207       hash_table_dtor(ht);
208       ralloc_free(mem_ctx);
209    }
210 
211    /**
212     * Lookup the interface definition having the given block name.  Return
213     * NULL if none is found.
214     */
lookup(const char * block_name)215    interface_block_definition *lookup(const char *block_name)
216    {
217       return (interface_block_definition *) hash_table_find(ht, block_name);
218    }
219 
220    /**
221     * Add a new interface definition.
222     */
store(const interface_block_definition & def)223    void store(const interface_block_definition &def)
224    {
225       interface_block_definition *hash_entry =
226          rzalloc(mem_ctx, interface_block_definition);
227       *hash_entry = def;
228       hash_table_insert(ht, hash_entry, def.type->name);
229    }
230 
231 private:
232    /**
233     * Ralloc context for data structures allocated by this class.
234     */
235    void *mem_ctx;
236 
237    /**
238     * Hash table mapping interface block name to an \c
239     * interface_block_definition struct.  interface_block_definition structs
240     * are allocated using \c mem_ctx.
241     */
242    hash_table *ht;
243 };
244 
245 
246 }; /* anonymous namespace */
247 
248 
249 void
validate_intrastage_interface_blocks(struct gl_shader_program * prog,const gl_shader ** shader_list,unsigned num_shaders)250 validate_intrastage_interface_blocks(struct gl_shader_program *prog,
251                                      const gl_shader **shader_list,
252                                      unsigned num_shaders)
253 {
254    interface_block_definitions in_interfaces;
255    interface_block_definitions out_interfaces;
256    interface_block_definitions uniform_interfaces;
257 
258    for (unsigned int i = 0; i < num_shaders; i++) {
259       if (shader_list[i] == NULL)
260          continue;
261 
262       foreach_in_list(ir_instruction, node, shader_list[i]->ir) {
263          ir_variable *var = node->as_variable();
264          if (!var)
265             continue;
266 
267          const glsl_type *iface_type = var->get_interface_type();
268 
269          if (iface_type == NULL)
270             continue;
271 
272          interface_block_definitions *definitions;
273          switch (var->data.mode) {
274          case ir_var_shader_in:
275             definitions = &in_interfaces;
276             break;
277          case ir_var_shader_out:
278             definitions = &out_interfaces;
279             break;
280          case ir_var_uniform:
281             definitions = &uniform_interfaces;
282             break;
283          default:
284             /* Only in, out, and uniform interfaces are legal, so we should
285              * never get here.
286              */
287             assert(!"illegal interface type");
288             continue;
289          }
290 
291          const interface_block_definition def(var);
292          interface_block_definition *prev_def =
293             definitions->lookup(iface_type->name);
294 
295          if (prev_def == NULL) {
296             /* This is the first time we've seen the interface, so save
297              * it into the appropriate data structure.
298              */
299             definitions->store(def);
300          } else if (!intrastage_match(prev_def, &def,
301                                       (ir_variable_mode) var->data.mode)) {
302             linker_error(prog, "definitions of interface block `%s' do not"
303                          " match\n", iface_type->name);
304             return;
305          }
306       }
307    }
308 }
309 
310 void
validate_interstage_inout_blocks(struct gl_shader_program * prog,const gl_shader * producer,const gl_shader * consumer)311 validate_interstage_inout_blocks(struct gl_shader_program *prog,
312                                  const gl_shader *producer,
313                                  const gl_shader *consumer)
314 {
315    interface_block_definitions definitions;
316    const bool extra_array_level = consumer->Stage == MESA_SHADER_GEOMETRY;
317 
318    /* Add input interfaces from the consumer to the symbol table. */
319    foreach_in_list(ir_instruction, node, consumer->ir) {
320       ir_variable *var = node->as_variable();
321       if (!var || !var->get_interface_type() || var->data.mode != ir_var_shader_in)
322          continue;
323 
324       definitions.store(interface_block_definition(var));
325    }
326 
327    /* Verify that the producer's output interfaces match. */
328    foreach_in_list(ir_instruction, node, producer->ir) {
329       ir_variable *var = node->as_variable();
330       if (!var || !var->get_interface_type() || var->data.mode != ir_var_shader_out)
331          continue;
332 
333       interface_block_definition *consumer_def =
334          definitions.lookup(var->get_interface_type()->name);
335 
336       /* The consumer doesn't use this output block.  Ignore it. */
337       if (consumer_def == NULL)
338          continue;
339 
340       const interface_block_definition producer_def(var);
341 
342       if (!interstage_match(&producer_def, consumer_def, extra_array_level)) {
343          linker_error(prog, "definitions of interface block `%s' do not "
344                       "match\n", var->get_interface_type()->name);
345          return;
346       }
347    }
348 }
349 
350 
351 void
validate_interstage_uniform_blocks(struct gl_shader_program * prog,gl_shader ** stages,int num_stages)352 validate_interstage_uniform_blocks(struct gl_shader_program *prog,
353                                    gl_shader **stages, int num_stages)
354 {
355    interface_block_definitions definitions;
356 
357    for (int i = 0; i < num_stages; i++) {
358       if (stages[i] == NULL)
359          continue;
360 
361       const gl_shader *stage = stages[i];
362       foreach_in_list(ir_instruction, node, stage->ir) {
363          ir_variable *var = node->as_variable();
364          if (!var || !var->get_interface_type() || var->data.mode != ir_var_uniform)
365             continue;
366 
367          interface_block_definition *old_def =
368             definitions.lookup(var->get_interface_type()->name);
369          const interface_block_definition new_def(var);
370          if (old_def == NULL) {
371             definitions.store(new_def);
372          } else {
373             /* Interstage uniform matching rules are the same as intrastage
374              * uniform matchin rules (for uniforms, it is as though all
375              * shaders are in the same shader stage).
376              */
377             if (!intrastage_match(old_def, &new_def, ir_var_uniform)) {
378                linker_error(prog, "definitions of interface block `%s' do not "
379                             "match\n", var->get_interface_type()->name);
380                return;
381             }
382          }
383       }
384    }
385 }
386