glsl: move to compiler/
[mesa.git] / src / compiler / glsl / link_interface_blocks.cpp
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 * Check if two interfaces match, according to intrastage interface matching
40 * rules. If they do, and the first interface uses an unsized array, it will
41 * be updated to reflect the array size declared in the second interface.
42 */
43 bool
44 intrastage_match(ir_variable *a,
45 ir_variable *b,
46 struct gl_shader_program *prog)
47 {
48 /* Types must match. */
49 if (a->get_interface_type() != b->get_interface_type()) {
50 /* Exception: if both the interface blocks are implicitly declared,
51 * don't force their types to match. They might mismatch due to the two
52 * shaders using different GLSL versions, and that's ok.
53 */
54 if (a->data.how_declared != ir_var_declared_implicitly ||
55 b->data.how_declared != ir_var_declared_implicitly)
56 return false;
57 }
58
59 /* Presence/absence of interface names must match. */
60 if (a->is_interface_instance() != b->is_interface_instance())
61 return false;
62
63 /* For uniforms, instance names need not match. For shader ins/outs,
64 * it's not clear from the spec whether they need to match, but
65 * Mesa's implementation relies on them matching.
66 */
67 if (a->is_interface_instance() && b->data.mode != ir_var_uniform &&
68 b->data.mode != ir_var_shader_storage &&
69 strcmp(a->name, b->name) != 0) {
70 return false;
71 }
72
73 /* If a block is an array then it must match across the shader.
74 * Unsized arrays are also processed and matched agaist sized arrays.
75 */
76 if (b->type != a->type &&
77 (b->is_interface_instance() || a->is_interface_instance()) &&
78 !validate_intrastage_arrays(prog, b, a))
79 return false;
80
81 return true;
82 }
83
84
85 /**
86 * Check if two interfaces match, according to interstage (in/out) interface
87 * matching rules.
88 *
89 * If \c extra_array_level is true, the consumer interface is required to be
90 * an array and the producer interface is required to be a non-array.
91 * This is used for tessellation control and geometry shader consumers.
92 */
93 bool
94 interstage_match(ir_variable *producer,
95 ir_variable *consumer,
96 bool extra_array_level)
97 {
98 /* Unsized arrays should not occur during interstage linking. They
99 * should have all been assigned a size by link_intrastage_shaders.
100 */
101 assert(!consumer->type->is_unsized_array());
102 assert(!producer->type->is_unsized_array());
103
104 /* Types must match. */
105 if (consumer->get_interface_type() != producer->get_interface_type()) {
106 /* Exception: if both the interface blocks are implicitly declared,
107 * don't force their types to match. They might mismatch due to the two
108 * shaders using different GLSL versions, and that's ok.
109 */
110 if (consumer->data.how_declared != ir_var_declared_implicitly ||
111 producer->data.how_declared != ir_var_declared_implicitly)
112 return false;
113 }
114
115 /* Ignore outermost array if geom shader */
116 const glsl_type *consumer_instance_type;
117 if (extra_array_level) {
118 consumer_instance_type = consumer->type->fields.array;
119 } else {
120 consumer_instance_type = consumer->type;
121 }
122
123 /* If a block is an array then it must match across shaders.
124 * Since unsized arrays have been ruled out, we can check this by just
125 * making sure the types are equal.
126 */
127 if ((consumer->is_interface_instance() &&
128 consumer_instance_type->is_array()) ||
129 (producer->is_interface_instance() &&
130 producer->type->is_array())) {
131 if (consumer_instance_type != producer->type)
132 return false;
133 }
134
135 return true;
136 }
137
138
139 /**
140 * This class keeps track of a mapping from an interface block name to the
141 * necessary information about that interface block to determine whether to
142 * generate a link error.
143 *
144 * Note: this class is expected to be short lived, so it doesn't make copies
145 * of the strings it references; it simply borrows the pointers from the
146 * ir_variable class.
147 */
148 class interface_block_definitions
149 {
150 public:
151 interface_block_definitions()
152 : mem_ctx(ralloc_context(NULL)),
153 ht(_mesa_hash_table_create(NULL, _mesa_key_hash_string,
154 _mesa_key_string_equal))
155 {
156 }
157
158 ~interface_block_definitions()
159 {
160 ralloc_free(mem_ctx);
161 _mesa_hash_table_destroy(ht, NULL);
162 }
163
164 /**
165 * Lookup the interface definition. Return NULL if none is found.
166 */
167 ir_variable *lookup(ir_variable *var)
168 {
169 if (var->data.explicit_location &&
170 var->data.location >= VARYING_SLOT_VAR0) {
171 char location_str[11];
172 snprintf(location_str, 11, "%d", var->data.location);
173
174 const struct hash_entry *entry =
175 _mesa_hash_table_search(ht, location_str);
176 return entry ? (ir_variable *) entry->data : NULL;
177 } else {
178 const struct hash_entry *entry =
179 _mesa_hash_table_search(ht, var->get_interface_type()->name);
180 return entry ? (ir_variable *) entry->data : NULL;
181 }
182 }
183
184 /**
185 * Add a new interface definition.
186 */
187 void store(ir_variable *var)
188 {
189 if (var->data.explicit_location &&
190 var->data.location >= VARYING_SLOT_VAR0) {
191 /* If explicit location is given then lookup the variable by location.
192 * We turn the location into a string and use this as the hash key
193 * rather than the name. Note: We allocate enough space for a 32-bit
194 * unsigned location value which is overkill but future proof.
195 */
196 char location_str[11];
197 snprintf(location_str, 11, "%d", var->data.location);
198 _mesa_hash_table_insert(ht, ralloc_strdup(mem_ctx, location_str), var);
199 } else {
200 _mesa_hash_table_insert(ht, var->get_interface_type()->name, var);
201 }
202 }
203
204 private:
205 /**
206 * Ralloc context for data structures allocated by this class.
207 */
208 void *mem_ctx;
209
210 /**
211 * Hash table mapping interface block name to an \c
212 * ir_variable.
213 */
214 hash_table *ht;
215 };
216
217
218 }; /* anonymous namespace */
219
220
221 void
222 validate_intrastage_interface_blocks(struct gl_shader_program *prog,
223 const gl_shader **shader_list,
224 unsigned num_shaders)
225 {
226 interface_block_definitions in_interfaces;
227 interface_block_definitions out_interfaces;
228 interface_block_definitions uniform_interfaces;
229 interface_block_definitions buffer_interfaces;
230
231 for (unsigned int i = 0; i < num_shaders; i++) {
232 if (shader_list[i] == NULL)
233 continue;
234
235 foreach_in_list(ir_instruction, node, shader_list[i]->ir) {
236 ir_variable *var = node->as_variable();
237 if (!var)
238 continue;
239
240 const glsl_type *iface_type = var->get_interface_type();
241
242 if (iface_type == NULL)
243 continue;
244
245 interface_block_definitions *definitions;
246 switch (var->data.mode) {
247 case ir_var_shader_in:
248 definitions = &in_interfaces;
249 break;
250 case ir_var_shader_out:
251 definitions = &out_interfaces;
252 break;
253 case ir_var_uniform:
254 definitions = &uniform_interfaces;
255 break;
256 case ir_var_shader_storage:
257 definitions = &buffer_interfaces;
258 break;
259 default:
260 /* Only in, out, and uniform interfaces are legal, so we should
261 * never get here.
262 */
263 assert(!"illegal interface type");
264 continue;
265 }
266
267 ir_variable *prev_def = definitions->lookup(var);
268 if (prev_def == NULL) {
269 /* This is the first time we've seen the interface, so save
270 * it into the appropriate data structure.
271 */
272 definitions->store(var);
273 } else if (!intrastage_match(prev_def, var, prog)) {
274 linker_error(prog, "definitions of interface block `%s' do not"
275 " match\n", iface_type->name);
276 return;
277 }
278 }
279 }
280 }
281
282 void
283 validate_interstage_inout_blocks(struct gl_shader_program *prog,
284 const gl_shader *producer,
285 const gl_shader *consumer)
286 {
287 interface_block_definitions definitions;
288 /* VS -> GS, VS -> TCS, VS -> TES, TES -> GS */
289 const bool extra_array_level = (producer->Stage == MESA_SHADER_VERTEX &&
290 consumer->Stage != MESA_SHADER_FRAGMENT) ||
291 consumer->Stage == MESA_SHADER_GEOMETRY;
292
293 /* Add input interfaces from the consumer to the symbol table. */
294 foreach_in_list(ir_instruction, node, consumer->ir) {
295 ir_variable *var = node->as_variable();
296 if (!var || !var->get_interface_type() || var->data.mode != ir_var_shader_in)
297 continue;
298
299 definitions.store(var);
300 }
301
302 /* Verify that the producer's output interfaces match. */
303 foreach_in_list(ir_instruction, node, producer->ir) {
304 ir_variable *var = node->as_variable();
305 if (!var || !var->get_interface_type() || var->data.mode != ir_var_shader_out)
306 continue;
307
308 ir_variable *consumer_def = definitions.lookup(var);
309
310 /* The consumer doesn't use this output block. Ignore it. */
311 if (consumer_def == NULL)
312 continue;
313
314 if (!interstage_match(var, consumer_def, extra_array_level)) {
315 linker_error(prog, "definitions of interface block `%s' do not "
316 "match\n", var->get_interface_type()->name);
317 return;
318 }
319 }
320 }
321
322
323 void
324 validate_interstage_uniform_blocks(struct gl_shader_program *prog,
325 gl_shader **stages, int num_stages)
326 {
327 interface_block_definitions definitions;
328
329 for (int i = 0; i < num_stages; i++) {
330 if (stages[i] == NULL)
331 continue;
332
333 const gl_shader *stage = stages[i];
334 foreach_in_list(ir_instruction, node, stage->ir) {
335 ir_variable *var = node->as_variable();
336 if (!var || !var->get_interface_type() ||
337 (var->data.mode != ir_var_uniform &&
338 var->data.mode != ir_var_shader_storage))
339 continue;
340
341 ir_variable *old_def = definitions.lookup(var);
342 if (old_def == NULL) {
343 definitions.store(var);
344 } else {
345 /* Interstage uniform matching rules are the same as intrastage
346 * uniform matchin rules (for uniforms, it is as though all
347 * shaders are in the same shader stage).
348 */
349 if (!intrastage_match(old_def, var, prog)) {
350 linker_error(prog, "definitions of interface block `%s' do not "
351 "match\n", var->get_interface_type()->name);
352 return;
353 }
354 }
355 }
356 }
357 }