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 "main/shader_types.h"
34 #include "util/hash_table.h"
35 #include "util/u_string.h"
36
37
38 namespace {
39
40 /**
41 * Return true if interface members mismatch and its not allowed by GLSL.
42 */
43 static bool
interstage_member_mismatch(struct gl_shader_program * prog,const glsl_type * c,const glsl_type * p)44 interstage_member_mismatch(struct gl_shader_program *prog,
45 const glsl_type *c, const glsl_type *p) {
46
47 if (c->length != p->length)
48 return true;
49
50 for (unsigned i = 0; i < c->length; i++) {
51 if (c->fields.structure[i].type != p->fields.structure[i].type)
52 return true;
53 if (strcmp(c->fields.structure[i].name,
54 p->fields.structure[i].name) != 0)
55 return true;
56 if (c->fields.structure[i].location !=
57 p->fields.structure[i].location)
58 return true;
59 if (c->fields.structure[i].component !=
60 p->fields.structure[i].component)
61 return true;
62 if (c->fields.structure[i].patch !=
63 p->fields.structure[i].patch)
64 return true;
65
66 /* From Section 4.5 (Interpolation Qualifiers) of the GLSL 4.40 spec:
67 *
68 * "It is a link-time error if, within the same stage, the
69 * interpolation qualifiers of variables of the same name do not
70 * match."
71 */
72 if (prog->IsES || prog->GLSL_Version < 440)
73 if (c->fields.structure[i].interpolation !=
74 p->fields.structure[i].interpolation)
75 return true;
76
77 /* From Section 4.3.4 (Input Variables) of the GLSL ES 3.0 spec:
78 *
79 * "The output of the vertex shader and the input of the fragment
80 * shader form an interface. For this interface, vertex shader
81 * output variables and fragment shader input variables of the same
82 * name must match in type and qualification (other than precision
83 * and out matching to in).
84 *
85 * The table in Section 9.2.1 Linked Shaders of the GLSL ES 3.1 spec
86 * says that centroid no longer needs to match for varyings.
87 *
88 * The table in Section 9.2.1 Linked Shaders of the GLSL ES 3.2 spec
89 * says that sample need not match for varyings.
90 */
91 if (!prog->IsES || prog->GLSL_Version < 310)
92 if (c->fields.structure[i].centroid !=
93 p->fields.structure[i].centroid)
94 return true;
95 if (!prog->IsES)
96 if (c->fields.structure[i].sample !=
97 p->fields.structure[i].sample)
98 return true;
99 }
100
101 return false;
102 }
103
104 /**
105 * Check if two interfaces match, according to intrastage interface matching
106 * rules. If they do, and the first interface uses an unsized array, it will
107 * be updated to reflect the array size declared in the second interface.
108 */
109 bool
intrastage_match(ir_variable * a,ir_variable * b,struct gl_shader_program * prog,bool match_precision)110 intrastage_match(ir_variable *a,
111 ir_variable *b,
112 struct gl_shader_program *prog,
113 bool match_precision)
114 {
115 /* From section 4.7 "Precision and Precision Qualifiers" in GLSL 4.50:
116 *
117 * "For the purposes of determining if an output from one shader
118 * stage matches an input of the next stage, the precision qualifier
119 * need not match."
120 */
121 bool interface_type_match =
122 (prog->IsES ?
123 a->get_interface_type() == b->get_interface_type() :
124 glsl_type_compare_no_precision(a->get_interface_type(), b->get_interface_type()));
125
126 /* Types must match. */
127 if (!interface_type_match) {
128 /* Exception: if both the interface blocks are implicitly declared,
129 * don't force their types to match. They might mismatch due to the two
130 * shaders using different GLSL versions, and that's ok.
131 */
132 if ((a->data.how_declared != ir_var_declared_implicitly ||
133 b->data.how_declared != ir_var_declared_implicitly) &&
134 (!prog->IsES ||
135 interstage_member_mismatch(prog, a->get_interface_type(),
136 b->get_interface_type())))
137 return false;
138 }
139
140 /* Presence/absence of interface names must match. */
141 if (a->is_interface_instance() != b->is_interface_instance())
142 return false;
143
144 /* For uniforms, instance names need not match. For shader ins/outs,
145 * it's not clear from the spec whether they need to match, but
146 * Mesa's implementation relies on them matching.
147 */
148 if (a->is_interface_instance() && b->data.mode != ir_var_uniform &&
149 b->data.mode != ir_var_shader_storage &&
150 strcmp(a->name, b->name) != 0) {
151 return false;
152 }
153
154 bool type_match = (match_precision ?
155 a->type == b->type :
156 glsl_type_compare_no_precision(a->type, b->type));
157
158 /* If a block is an array then it must match across the shader.
159 * Unsized arrays are also processed and matched agaist sized arrays.
160 */
161 if (!type_match && (glsl_type_is_array(b->type) || glsl_type_is_array(a->type)) &&
162 (b->is_interface_instance() || a->is_interface_instance()) &&
163 !validate_intrastage_arrays(prog, b, a, match_precision))
164 return false;
165
166 return true;
167 }
168
169
170 /**
171 * This class keeps track of a mapping from an interface block name to the
172 * necessary information about that interface block to determine whether to
173 * generate a link error.
174 *
175 * Note: this class is expected to be short lived, so it doesn't make copies
176 * of the strings it references; it simply borrows the pointers from the
177 * ir_variable class.
178 */
179 class interface_block_definitions
180 {
181 public:
interface_block_definitions()182 interface_block_definitions()
183 : mem_ctx(ralloc_context(NULL)),
184 ht(_mesa_hash_table_create(NULL, _mesa_hash_string,
185 _mesa_key_string_equal))
186 {
187 }
188
~interface_block_definitions()189 ~interface_block_definitions()
190 {
191 ralloc_free(mem_ctx);
192 _mesa_hash_table_destroy(ht, NULL);
193 }
194
195 interface_block_definitions(const interface_block_definitions &) = delete;
196 interface_block_definitions & operator=(const interface_block_definitions &) = delete;
197
198 /**
199 * Lookup the interface definition. Return NULL if none is found.
200 */
lookup(ir_variable * var)201 ir_variable *lookup(ir_variable *var)
202 {
203 if (var->data.explicit_location &&
204 var->data.location >= VARYING_SLOT_VAR0) {
205 char location_str[11];
206 snprintf(location_str, 11, "%d", var->data.location);
207
208 const struct hash_entry *entry =
209 _mesa_hash_table_search(ht, location_str);
210 return entry ? (ir_variable *) entry->data : NULL;
211 } else {
212 const struct hash_entry *entry =
213 _mesa_hash_table_search(ht,
214 glsl_get_type_name(glsl_without_array(var->get_interface_type())));
215 return entry ? (ir_variable *) entry->data : NULL;
216 }
217 }
218
219 /**
220 * Add a new interface definition.
221 */
store(ir_variable * var)222 void store(ir_variable *var)
223 {
224 if (var->data.explicit_location &&
225 var->data.location >= VARYING_SLOT_VAR0) {
226 /* If explicit location is given then lookup the variable by location.
227 * We turn the location into a string and use this as the hash key
228 * rather than the name. Note: We allocate enough space for a 32-bit
229 * unsigned location value which is overkill but future proof.
230 */
231 char location_str[11];
232 snprintf(location_str, 11, "%d", var->data.location);
233 _mesa_hash_table_insert(ht, ralloc_strdup(mem_ctx, location_str), var);
234 } else {
235 _mesa_hash_table_insert(ht,
236 glsl_get_type_name(glsl_without_array(var->get_interface_type())), var);
237 }
238 }
239
240 private:
241 /**
242 * Ralloc context for data structures allocated by this class.
243 */
244 void *mem_ctx;
245
246 /**
247 * Hash table mapping interface block name to an \c
248 * ir_variable.
249 */
250 hash_table *ht;
251 };
252
253
254 }; /* anonymous namespace */
255
256
257 void
validate_intrastage_interface_blocks(struct gl_shader_program * prog,const gl_shader ** shader_list,unsigned num_shaders)258 validate_intrastage_interface_blocks(struct gl_shader_program *prog,
259 const gl_shader **shader_list,
260 unsigned num_shaders)
261 {
262 interface_block_definitions in_interfaces;
263 interface_block_definitions out_interfaces;
264 interface_block_definitions uniform_interfaces;
265 interface_block_definitions buffer_interfaces;
266
267 for (unsigned int i = 0; i < num_shaders; i++) {
268 if (shader_list[i] == NULL)
269 continue;
270
271 foreach_in_list(ir_instruction, node, shader_list[i]->ir) {
272 ir_variable *var = node->as_variable();
273 if (!var)
274 continue;
275
276 const glsl_type *iface_type = var->get_interface_type();
277
278 if (iface_type == NULL)
279 continue;
280
281 interface_block_definitions *definitions;
282 switch (var->data.mode) {
283 case ir_var_shader_in:
284 definitions = &in_interfaces;
285 break;
286 case ir_var_shader_out:
287 definitions = &out_interfaces;
288 break;
289 case ir_var_uniform:
290 definitions = &uniform_interfaces;
291 break;
292 case ir_var_shader_storage:
293 definitions = &buffer_interfaces;
294 break;
295 default:
296 /* Only in, out, and uniform interfaces are legal, so we should
297 * never get here.
298 */
299 assert(!"illegal interface type");
300 continue;
301 }
302
303 ir_variable *prev_def = definitions->lookup(var);
304 if (prev_def == NULL) {
305 /* This is the first time we've seen the interface, so save
306 * it into the appropriate data structure.
307 */
308 definitions->store(var);
309 } else if (!intrastage_match(prev_def, var, prog,
310 true /* match_precision */)) {
311 linker_error(prog, "definitions of interface block `%s' do not"
312 " match\n", glsl_get_type_name(iface_type));
313 return;
314 }
315 }
316 }
317 }
318