1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Copyright © 2010 Intel Corporation
3*61046927SAndroid Build Coastguard Worker *
4*61046927SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
5*61046927SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"),
6*61046927SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation
7*61046927SAndroid Build Coastguard Worker * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*61046927SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the
9*61046927SAndroid Build Coastguard Worker * Software is furnished to do so, subject to the following conditions:
10*61046927SAndroid Build Coastguard Worker *
11*61046927SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the next
12*61046927SAndroid Build Coastguard Worker * paragraph) shall be included in all copies or substantial portions of the
13*61046927SAndroid Build Coastguard Worker * Software.
14*61046927SAndroid Build Coastguard Worker *
15*61046927SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*61046927SAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*61046927SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18*61046927SAndroid Build Coastguard Worker * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*61046927SAndroid Build Coastguard Worker * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*61046927SAndroid Build Coastguard Worker * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21*61046927SAndroid Build Coastguard Worker * DEALINGS IN THE SOFTWARE.
22*61046927SAndroid Build Coastguard Worker */
23*61046927SAndroid Build Coastguard Worker
24*61046927SAndroid Build Coastguard Worker /**
25*61046927SAndroid Build Coastguard Worker * \file linker.cpp
26*61046927SAndroid Build Coastguard Worker * GLSL linker implementation
27*61046927SAndroid Build Coastguard Worker *
28*61046927SAndroid Build Coastguard Worker * Given a set of shaders that are to be linked to generate a final program,
29*61046927SAndroid Build Coastguard Worker * there are three distinct stages.
30*61046927SAndroid Build Coastguard Worker *
31*61046927SAndroid Build Coastguard Worker * In the first stage shaders are partitioned into groups based on the shader
32*61046927SAndroid Build Coastguard Worker * type. All shaders of a particular type (e.g., vertex shaders) are linked
33*61046927SAndroid Build Coastguard Worker * together.
34*61046927SAndroid Build Coastguard Worker *
35*61046927SAndroid Build Coastguard Worker * - Undefined references in each shader are resolve to definitions in
36*61046927SAndroid Build Coastguard Worker * another shader.
37*61046927SAndroid Build Coastguard Worker * - Types and qualifiers of uniforms, outputs, and global variables defined
38*61046927SAndroid Build Coastguard Worker * in multiple shaders with the same name are verified to be the same.
39*61046927SAndroid Build Coastguard Worker * - Initializers for uniforms and global variables defined
40*61046927SAndroid Build Coastguard Worker * in multiple shaders with the same name are verified to be the same.
41*61046927SAndroid Build Coastguard Worker *
42*61046927SAndroid Build Coastguard Worker * The result, in the terminology of the GLSL spec, is a set of shader
43*61046927SAndroid Build Coastguard Worker * executables for each processing unit.
44*61046927SAndroid Build Coastguard Worker *
45*61046927SAndroid Build Coastguard Worker * After the first stage is complete, a series of semantic checks are performed
46*61046927SAndroid Build Coastguard Worker * on each of the shader executables.
47*61046927SAndroid Build Coastguard Worker *
48*61046927SAndroid Build Coastguard Worker * - Each shader executable must define a \c main function.
49*61046927SAndroid Build Coastguard Worker * - Each vertex shader executable must write to \c gl_Position.
50*61046927SAndroid Build Coastguard Worker * - Each fragment shader executable must write to either \c gl_FragData or
51*61046927SAndroid Build Coastguard Worker * \c gl_FragColor.
52*61046927SAndroid Build Coastguard Worker *
53*61046927SAndroid Build Coastguard Worker * In the final stage individual shader executables are linked to create a
54*61046927SAndroid Build Coastguard Worker * complete exectuable.
55*61046927SAndroid Build Coastguard Worker *
56*61046927SAndroid Build Coastguard Worker * - Types of uniforms defined in multiple shader stages with the same name
57*61046927SAndroid Build Coastguard Worker * are verified to be the same.
58*61046927SAndroid Build Coastguard Worker * - Initializers for uniforms defined in multiple shader stages with the
59*61046927SAndroid Build Coastguard Worker * same name are verified to be the same.
60*61046927SAndroid Build Coastguard Worker * - Types and qualifiers of outputs defined in one stage are verified to
61*61046927SAndroid Build Coastguard Worker * be the same as the types and qualifiers of inputs defined with the same
62*61046927SAndroid Build Coastguard Worker * name in a later stage.
63*61046927SAndroid Build Coastguard Worker *
64*61046927SAndroid Build Coastguard Worker * \author Ian Romanick <[email protected]>
65*61046927SAndroid Build Coastguard Worker */
66*61046927SAndroid Build Coastguard Worker
67*61046927SAndroid Build Coastguard Worker #include <ctype.h>
68*61046927SAndroid Build Coastguard Worker #include "util/strndup.h"
69*61046927SAndroid Build Coastguard Worker #include "glsl_symbol_table.h"
70*61046927SAndroid Build Coastguard Worker #include "glsl_parser_extras.h"
71*61046927SAndroid Build Coastguard Worker #include "ir.h"
72*61046927SAndroid Build Coastguard Worker #include "nir.h"
73*61046927SAndroid Build Coastguard Worker #include "program.h"
74*61046927SAndroid Build Coastguard Worker #include "program/prog_instruction.h"
75*61046927SAndroid Build Coastguard Worker #include "program/program.h"
76*61046927SAndroid Build Coastguard Worker #include "util/mesa-sha1.h"
77*61046927SAndroid Build Coastguard Worker #include "util/set.h"
78*61046927SAndroid Build Coastguard Worker #include "string_to_uint_map.h"
79*61046927SAndroid Build Coastguard Worker #include "linker.h"
80*61046927SAndroid Build Coastguard Worker #include "linker_util.h"
81*61046927SAndroid Build Coastguard Worker #include "ir_optimization.h"
82*61046927SAndroid Build Coastguard Worker #include "ir_rvalue_visitor.h"
83*61046927SAndroid Build Coastguard Worker #include "ir_uniform.h"
84*61046927SAndroid Build Coastguard Worker #include "builtin_functions.h"
85*61046927SAndroid Build Coastguard Worker #include "shader_cache.h"
86*61046927SAndroid Build Coastguard Worker #include "util/u_string.h"
87*61046927SAndroid Build Coastguard Worker #include "util/u_math.h"
88*61046927SAndroid Build Coastguard Worker
89*61046927SAndroid Build Coastguard Worker
90*61046927SAndroid Build Coastguard Worker #include "main/shaderobj.h"
91*61046927SAndroid Build Coastguard Worker #include "main/enums.h"
92*61046927SAndroid Build Coastguard Worker #include "main/mtypes.h"
93*61046927SAndroid Build Coastguard Worker #include "main/context.h"
94*61046927SAndroid Build Coastguard Worker
95*61046927SAndroid Build Coastguard Worker
96*61046927SAndroid Build Coastguard Worker namespace {
97*61046927SAndroid Build Coastguard Worker
98*61046927SAndroid Build Coastguard Worker /**
99*61046927SAndroid Build Coastguard Worker * A visitor helper that provides methods for updating the types of
100*61046927SAndroid Build Coastguard Worker * ir_dereferences. Classes that update variable types (say, updating
101*61046927SAndroid Build Coastguard Worker * array sizes) will want to use this so that dereference types stay in sync.
102*61046927SAndroid Build Coastguard Worker */
103*61046927SAndroid Build Coastguard Worker class deref_type_updater : public ir_hierarchical_visitor {
104*61046927SAndroid Build Coastguard Worker public:
visit(ir_dereference_variable * ir)105*61046927SAndroid Build Coastguard Worker virtual ir_visitor_status visit(ir_dereference_variable *ir)
106*61046927SAndroid Build Coastguard Worker {
107*61046927SAndroid Build Coastguard Worker ir->type = ir->var->type;
108*61046927SAndroid Build Coastguard Worker return visit_continue;
109*61046927SAndroid Build Coastguard Worker }
110*61046927SAndroid Build Coastguard Worker
visit_leave(ir_dereference_array * ir)111*61046927SAndroid Build Coastguard Worker virtual ir_visitor_status visit_leave(ir_dereference_array *ir)
112*61046927SAndroid Build Coastguard Worker {
113*61046927SAndroid Build Coastguard Worker const glsl_type *const vt = ir->array->type;
114*61046927SAndroid Build Coastguard Worker if (glsl_type_is_array(vt))
115*61046927SAndroid Build Coastguard Worker ir->type = vt->fields.array;
116*61046927SAndroid Build Coastguard Worker return visit_continue;
117*61046927SAndroid Build Coastguard Worker }
118*61046927SAndroid Build Coastguard Worker
visit_leave(ir_dereference_record * ir)119*61046927SAndroid Build Coastguard Worker virtual ir_visitor_status visit_leave(ir_dereference_record *ir)
120*61046927SAndroid Build Coastguard Worker {
121*61046927SAndroid Build Coastguard Worker ir->type = ir->record->type->fields.structure[ir->field_idx].type;
122*61046927SAndroid Build Coastguard Worker return visit_continue;
123*61046927SAndroid Build Coastguard Worker }
124*61046927SAndroid Build Coastguard Worker };
125*61046927SAndroid Build Coastguard Worker
126*61046927SAndroid Build Coastguard Worker
127*61046927SAndroid Build Coastguard Worker class array_length_to_const_visitor : public ir_rvalue_visitor {
128*61046927SAndroid Build Coastguard Worker public:
array_length_to_const_visitor()129*61046927SAndroid Build Coastguard Worker array_length_to_const_visitor()
130*61046927SAndroid Build Coastguard Worker {
131*61046927SAndroid Build Coastguard Worker this->progress = false;
132*61046927SAndroid Build Coastguard Worker }
133*61046927SAndroid Build Coastguard Worker
~array_length_to_const_visitor()134*61046927SAndroid Build Coastguard Worker virtual ~array_length_to_const_visitor()
135*61046927SAndroid Build Coastguard Worker {
136*61046927SAndroid Build Coastguard Worker /* empty */
137*61046927SAndroid Build Coastguard Worker }
138*61046927SAndroid Build Coastguard Worker
139*61046927SAndroid Build Coastguard Worker bool progress;
140*61046927SAndroid Build Coastguard Worker
handle_rvalue(ir_rvalue ** rvalue)141*61046927SAndroid Build Coastguard Worker virtual void handle_rvalue(ir_rvalue **rvalue)
142*61046927SAndroid Build Coastguard Worker {
143*61046927SAndroid Build Coastguard Worker if (*rvalue == NULL || (*rvalue)->ir_type != ir_type_expression)
144*61046927SAndroid Build Coastguard Worker return;
145*61046927SAndroid Build Coastguard Worker
146*61046927SAndroid Build Coastguard Worker ir_expression *expr = (*rvalue)->as_expression();
147*61046927SAndroid Build Coastguard Worker if (expr) {
148*61046927SAndroid Build Coastguard Worker if (expr->operation == ir_unop_implicitly_sized_array_length) {
149*61046927SAndroid Build Coastguard Worker assert(!glsl_type_is_unsized_array(expr->operands[0]->type));
150*61046927SAndroid Build Coastguard Worker ir_constant *constant = new(expr)
151*61046927SAndroid Build Coastguard Worker ir_constant(glsl_array_size(expr->operands[0]->type));
152*61046927SAndroid Build Coastguard Worker if (constant) {
153*61046927SAndroid Build Coastguard Worker *rvalue = constant;
154*61046927SAndroid Build Coastguard Worker }
155*61046927SAndroid Build Coastguard Worker }
156*61046927SAndroid Build Coastguard Worker }
157*61046927SAndroid Build Coastguard Worker }
158*61046927SAndroid Build Coastguard Worker };
159*61046927SAndroid Build Coastguard Worker
160*61046927SAndroid Build Coastguard Worker } /* anonymous namespace */
161*61046927SAndroid Build Coastguard Worker
162*61046927SAndroid Build Coastguard Worker void
linker_error(gl_shader_program * prog,const char * fmt,...)163*61046927SAndroid Build Coastguard Worker linker_error(gl_shader_program *prog, const char *fmt, ...)
164*61046927SAndroid Build Coastguard Worker {
165*61046927SAndroid Build Coastguard Worker va_list ap;
166*61046927SAndroid Build Coastguard Worker
167*61046927SAndroid Build Coastguard Worker ralloc_strcat(&prog->data->InfoLog, "error: ");
168*61046927SAndroid Build Coastguard Worker va_start(ap, fmt);
169*61046927SAndroid Build Coastguard Worker ralloc_vasprintf_append(&prog->data->InfoLog, fmt, ap);
170*61046927SAndroid Build Coastguard Worker va_end(ap);
171*61046927SAndroid Build Coastguard Worker
172*61046927SAndroid Build Coastguard Worker prog->data->LinkStatus = LINKING_FAILURE;
173*61046927SAndroid Build Coastguard Worker }
174*61046927SAndroid Build Coastguard Worker
175*61046927SAndroid Build Coastguard Worker
176*61046927SAndroid Build Coastguard Worker void
linker_warning(gl_shader_program * prog,const char * fmt,...)177*61046927SAndroid Build Coastguard Worker linker_warning(gl_shader_program *prog, const char *fmt, ...)
178*61046927SAndroid Build Coastguard Worker {
179*61046927SAndroid Build Coastguard Worker va_list ap;
180*61046927SAndroid Build Coastguard Worker
181*61046927SAndroid Build Coastguard Worker ralloc_strcat(&prog->data->InfoLog, "warning: ");
182*61046927SAndroid Build Coastguard Worker va_start(ap, fmt);
183*61046927SAndroid Build Coastguard Worker ralloc_vasprintf_append(&prog->data->InfoLog, fmt, ap);
184*61046927SAndroid Build Coastguard Worker va_end(ap);
185*61046927SAndroid Build Coastguard Worker
186*61046927SAndroid Build Coastguard Worker }
187*61046927SAndroid Build Coastguard Worker
188*61046927SAndroid Build Coastguard Worker bool
validate_intrastage_arrays(struct gl_shader_program * prog,ir_variable * const var,ir_variable * const existing,bool match_precision)189*61046927SAndroid Build Coastguard Worker validate_intrastage_arrays(struct gl_shader_program *prog,
190*61046927SAndroid Build Coastguard Worker ir_variable *const var,
191*61046927SAndroid Build Coastguard Worker ir_variable *const existing,
192*61046927SAndroid Build Coastguard Worker bool match_precision)
193*61046927SAndroid Build Coastguard Worker {
194*61046927SAndroid Build Coastguard Worker /* Consider the types to be "the same" if both types are arrays
195*61046927SAndroid Build Coastguard Worker * of the same type and one of the arrays is implicitly sized.
196*61046927SAndroid Build Coastguard Worker * In addition, set the type of the linked variable to the
197*61046927SAndroid Build Coastguard Worker * explicitly sized array.
198*61046927SAndroid Build Coastguard Worker */
199*61046927SAndroid Build Coastguard Worker if (glsl_type_is_array(var->type) && glsl_type_is_array(existing->type)) {
200*61046927SAndroid Build Coastguard Worker const glsl_type *no_array_var = var->type->fields.array;
201*61046927SAndroid Build Coastguard Worker const glsl_type *no_array_existing = existing->type->fields.array;
202*61046927SAndroid Build Coastguard Worker bool type_matches;
203*61046927SAndroid Build Coastguard Worker
204*61046927SAndroid Build Coastguard Worker type_matches = (match_precision ?
205*61046927SAndroid Build Coastguard Worker no_array_var == no_array_existing :
206*61046927SAndroid Build Coastguard Worker glsl_type_compare_no_precision(no_array_var, no_array_existing));
207*61046927SAndroid Build Coastguard Worker
208*61046927SAndroid Build Coastguard Worker if (type_matches &&
209*61046927SAndroid Build Coastguard Worker ((var->type->length == 0)|| (existing->type->length == 0))) {
210*61046927SAndroid Build Coastguard Worker if (var->type->length != 0) {
211*61046927SAndroid Build Coastguard Worker if ((int)var->type->length <= existing->data.max_array_access) {
212*61046927SAndroid Build Coastguard Worker linker_error(prog, "%s `%s' declared as type "
213*61046927SAndroid Build Coastguard Worker "`%s' but outermost dimension has an index"
214*61046927SAndroid Build Coastguard Worker " of `%i'\n",
215*61046927SAndroid Build Coastguard Worker mode_string(var),
216*61046927SAndroid Build Coastguard Worker var->name, glsl_get_type_name(var->type),
217*61046927SAndroid Build Coastguard Worker existing->data.max_array_access);
218*61046927SAndroid Build Coastguard Worker }
219*61046927SAndroid Build Coastguard Worker existing->type = var->type;
220*61046927SAndroid Build Coastguard Worker return true;
221*61046927SAndroid Build Coastguard Worker } else if (existing->type->length != 0) {
222*61046927SAndroid Build Coastguard Worker if((int)existing->type->length <= var->data.max_array_access &&
223*61046927SAndroid Build Coastguard Worker !existing->data.from_ssbo_unsized_array) {
224*61046927SAndroid Build Coastguard Worker linker_error(prog, "%s `%s' declared as type "
225*61046927SAndroid Build Coastguard Worker "`%s' but outermost dimension has an index"
226*61046927SAndroid Build Coastguard Worker " of `%i'\n",
227*61046927SAndroid Build Coastguard Worker mode_string(var),
228*61046927SAndroid Build Coastguard Worker var->name, glsl_get_type_name(existing->type),
229*61046927SAndroid Build Coastguard Worker var->data.max_array_access);
230*61046927SAndroid Build Coastguard Worker }
231*61046927SAndroid Build Coastguard Worker return true;
232*61046927SAndroid Build Coastguard Worker }
233*61046927SAndroid Build Coastguard Worker }
234*61046927SAndroid Build Coastguard Worker }
235*61046927SAndroid Build Coastguard Worker return false;
236*61046927SAndroid Build Coastguard Worker }
237*61046927SAndroid Build Coastguard Worker
238*61046927SAndroid Build Coastguard Worker
239*61046927SAndroid Build Coastguard Worker /**
240*61046927SAndroid Build Coastguard Worker * Perform validation of global variables used across multiple shaders
241*61046927SAndroid Build Coastguard Worker */
242*61046927SAndroid Build Coastguard Worker static void
cross_validate_globals(const struct gl_constants * consts,struct gl_shader_program * prog,struct exec_list * ir,glsl_symbol_table * variables,bool uniforms_only)243*61046927SAndroid Build Coastguard Worker cross_validate_globals(const struct gl_constants *consts,
244*61046927SAndroid Build Coastguard Worker struct gl_shader_program *prog,
245*61046927SAndroid Build Coastguard Worker struct exec_list *ir, glsl_symbol_table *variables,
246*61046927SAndroid Build Coastguard Worker bool uniforms_only)
247*61046927SAndroid Build Coastguard Worker {
248*61046927SAndroid Build Coastguard Worker foreach_in_list(ir_instruction, node, ir) {
249*61046927SAndroid Build Coastguard Worker ir_variable *const var = node->as_variable();
250*61046927SAndroid Build Coastguard Worker
251*61046927SAndroid Build Coastguard Worker if (var == NULL)
252*61046927SAndroid Build Coastguard Worker continue;
253*61046927SAndroid Build Coastguard Worker
254*61046927SAndroid Build Coastguard Worker if (uniforms_only && (var->data.mode != ir_var_uniform && var->data.mode != ir_var_shader_storage))
255*61046927SAndroid Build Coastguard Worker continue;
256*61046927SAndroid Build Coastguard Worker
257*61046927SAndroid Build Coastguard Worker /* don't cross validate subroutine uniforms */
258*61046927SAndroid Build Coastguard Worker if (glsl_contains_subroutine(var->type))
259*61046927SAndroid Build Coastguard Worker continue;
260*61046927SAndroid Build Coastguard Worker
261*61046927SAndroid Build Coastguard Worker /* Don't cross validate interface instances. These are only relevant
262*61046927SAndroid Build Coastguard Worker * inside a shader. The cross validation is done at the Interface Block
263*61046927SAndroid Build Coastguard Worker * name level.
264*61046927SAndroid Build Coastguard Worker */
265*61046927SAndroid Build Coastguard Worker if (var->is_interface_instance())
266*61046927SAndroid Build Coastguard Worker continue;
267*61046927SAndroid Build Coastguard Worker
268*61046927SAndroid Build Coastguard Worker /* Don't cross validate temporaries that are at global scope. These
269*61046927SAndroid Build Coastguard Worker * will eventually get pulled into the shaders 'main'.
270*61046927SAndroid Build Coastguard Worker */
271*61046927SAndroid Build Coastguard Worker if (var->data.mode == ir_var_temporary)
272*61046927SAndroid Build Coastguard Worker continue;
273*61046927SAndroid Build Coastguard Worker
274*61046927SAndroid Build Coastguard Worker /* If a global with this name has already been seen, verify that the
275*61046927SAndroid Build Coastguard Worker * new instance has the same type. In addition, if the globals have
276*61046927SAndroid Build Coastguard Worker * initializers, the values of the initializers must be the same.
277*61046927SAndroid Build Coastguard Worker */
278*61046927SAndroid Build Coastguard Worker ir_variable *const existing = variables->get_variable(var->name);
279*61046927SAndroid Build Coastguard Worker if (existing != NULL) {
280*61046927SAndroid Build Coastguard Worker /* Check if types match. */
281*61046927SAndroid Build Coastguard Worker if (var->type != existing->type) {
282*61046927SAndroid Build Coastguard Worker if (!validate_intrastage_arrays(prog, var, existing)) {
283*61046927SAndroid Build Coastguard Worker /* If it is an unsized array in a Shader Storage Block,
284*61046927SAndroid Build Coastguard Worker * two different shaders can access to different elements.
285*61046927SAndroid Build Coastguard Worker * Because of that, they might be converted to different
286*61046927SAndroid Build Coastguard Worker * sized arrays, then check that they are compatible but
287*61046927SAndroid Build Coastguard Worker * ignore the array size.
288*61046927SAndroid Build Coastguard Worker */
289*61046927SAndroid Build Coastguard Worker if (!(var->data.mode == ir_var_shader_storage &&
290*61046927SAndroid Build Coastguard Worker var->data.from_ssbo_unsized_array &&
291*61046927SAndroid Build Coastguard Worker existing->data.mode == ir_var_shader_storage &&
292*61046927SAndroid Build Coastguard Worker existing->data.from_ssbo_unsized_array &&
293*61046927SAndroid Build Coastguard Worker var->type->gl_type == existing->type->gl_type)) {
294*61046927SAndroid Build Coastguard Worker linker_error(prog, "%s `%s' declared as type "
295*61046927SAndroid Build Coastguard Worker "`%s' and type `%s'\n",
296*61046927SAndroid Build Coastguard Worker mode_string(var),
297*61046927SAndroid Build Coastguard Worker var->name, glsl_get_type_name(var->type),
298*61046927SAndroid Build Coastguard Worker glsl_get_type_name(existing->type));
299*61046927SAndroid Build Coastguard Worker return;
300*61046927SAndroid Build Coastguard Worker }
301*61046927SAndroid Build Coastguard Worker }
302*61046927SAndroid Build Coastguard Worker }
303*61046927SAndroid Build Coastguard Worker
304*61046927SAndroid Build Coastguard Worker if (var->data.explicit_location) {
305*61046927SAndroid Build Coastguard Worker if (existing->data.explicit_location
306*61046927SAndroid Build Coastguard Worker && (var->data.location != existing->data.location)) {
307*61046927SAndroid Build Coastguard Worker linker_error(prog, "explicit locations for %s "
308*61046927SAndroid Build Coastguard Worker "`%s' have differing values\n",
309*61046927SAndroid Build Coastguard Worker mode_string(var), var->name);
310*61046927SAndroid Build Coastguard Worker return;
311*61046927SAndroid Build Coastguard Worker }
312*61046927SAndroid Build Coastguard Worker
313*61046927SAndroid Build Coastguard Worker if (var->data.location_frac != existing->data.location_frac) {
314*61046927SAndroid Build Coastguard Worker linker_error(prog, "explicit components for %s `%s' have "
315*61046927SAndroid Build Coastguard Worker "differing values\n", mode_string(var), var->name);
316*61046927SAndroid Build Coastguard Worker return;
317*61046927SAndroid Build Coastguard Worker }
318*61046927SAndroid Build Coastguard Worker
319*61046927SAndroid Build Coastguard Worker existing->data.location = var->data.location;
320*61046927SAndroid Build Coastguard Worker existing->data.explicit_location = true;
321*61046927SAndroid Build Coastguard Worker } else {
322*61046927SAndroid Build Coastguard Worker /* Check if uniform with implicit location was marked explicit
323*61046927SAndroid Build Coastguard Worker * by earlier shader stage. If so, mark it explicit in this stage
324*61046927SAndroid Build Coastguard Worker * too to make sure later processing does not treat it as
325*61046927SAndroid Build Coastguard Worker * implicit one.
326*61046927SAndroid Build Coastguard Worker */
327*61046927SAndroid Build Coastguard Worker if (existing->data.explicit_location) {
328*61046927SAndroid Build Coastguard Worker var->data.location = existing->data.location;
329*61046927SAndroid Build Coastguard Worker var->data.explicit_location = true;
330*61046927SAndroid Build Coastguard Worker }
331*61046927SAndroid Build Coastguard Worker }
332*61046927SAndroid Build Coastguard Worker
333*61046927SAndroid Build Coastguard Worker /* From the GLSL 4.20 specification:
334*61046927SAndroid Build Coastguard Worker * "A link error will result if two compilation units in a program
335*61046927SAndroid Build Coastguard Worker * specify different integer-constant bindings for the same
336*61046927SAndroid Build Coastguard Worker * opaque-uniform name. However, it is not an error to specify a
337*61046927SAndroid Build Coastguard Worker * binding on some but not all declarations for the same name"
338*61046927SAndroid Build Coastguard Worker */
339*61046927SAndroid Build Coastguard Worker if (var->data.explicit_binding) {
340*61046927SAndroid Build Coastguard Worker if (existing->data.explicit_binding &&
341*61046927SAndroid Build Coastguard Worker var->data.binding != existing->data.binding) {
342*61046927SAndroid Build Coastguard Worker linker_error(prog, "explicit bindings for %s "
343*61046927SAndroid Build Coastguard Worker "`%s' have differing values\n",
344*61046927SAndroid Build Coastguard Worker mode_string(var), var->name);
345*61046927SAndroid Build Coastguard Worker return;
346*61046927SAndroid Build Coastguard Worker }
347*61046927SAndroid Build Coastguard Worker
348*61046927SAndroid Build Coastguard Worker existing->data.binding = var->data.binding;
349*61046927SAndroid Build Coastguard Worker existing->data.explicit_binding = true;
350*61046927SAndroid Build Coastguard Worker }
351*61046927SAndroid Build Coastguard Worker
352*61046927SAndroid Build Coastguard Worker if (glsl_contains_atomic(var->type) &&
353*61046927SAndroid Build Coastguard Worker var->data.offset != existing->data.offset) {
354*61046927SAndroid Build Coastguard Worker linker_error(prog, "offset specifications for %s "
355*61046927SAndroid Build Coastguard Worker "`%s' have differing values\n",
356*61046927SAndroid Build Coastguard Worker mode_string(var), var->name);
357*61046927SAndroid Build Coastguard Worker return;
358*61046927SAndroid Build Coastguard Worker }
359*61046927SAndroid Build Coastguard Worker
360*61046927SAndroid Build Coastguard Worker /* Validate layout qualifiers for gl_FragDepth.
361*61046927SAndroid Build Coastguard Worker *
362*61046927SAndroid Build Coastguard Worker * From the AMD/ARB_conservative_depth specs:
363*61046927SAndroid Build Coastguard Worker *
364*61046927SAndroid Build Coastguard Worker * "If gl_FragDepth is redeclared in any fragment shader in a
365*61046927SAndroid Build Coastguard Worker * program, it must be redeclared in all fragment shaders in
366*61046927SAndroid Build Coastguard Worker * that program that have static assignments to
367*61046927SAndroid Build Coastguard Worker * gl_FragDepth. All redeclarations of gl_FragDepth in all
368*61046927SAndroid Build Coastguard Worker * fragment shaders in a single program must have the same set
369*61046927SAndroid Build Coastguard Worker * of qualifiers."
370*61046927SAndroid Build Coastguard Worker */
371*61046927SAndroid Build Coastguard Worker if (strcmp(var->name, "gl_FragDepth") == 0) {
372*61046927SAndroid Build Coastguard Worker bool layout_declared = var->data.depth_layout != ir_depth_layout_none;
373*61046927SAndroid Build Coastguard Worker bool layout_differs =
374*61046927SAndroid Build Coastguard Worker var->data.depth_layout != existing->data.depth_layout;
375*61046927SAndroid Build Coastguard Worker
376*61046927SAndroid Build Coastguard Worker if (layout_declared && layout_differs) {
377*61046927SAndroid Build Coastguard Worker linker_error(prog,
378*61046927SAndroid Build Coastguard Worker "All redeclarations of gl_FragDepth in all "
379*61046927SAndroid Build Coastguard Worker "fragment shaders in a single program must have "
380*61046927SAndroid Build Coastguard Worker "the same set of qualifiers.\n");
381*61046927SAndroid Build Coastguard Worker }
382*61046927SAndroid Build Coastguard Worker
383*61046927SAndroid Build Coastguard Worker if (var->data.used && layout_differs) {
384*61046927SAndroid Build Coastguard Worker linker_error(prog,
385*61046927SAndroid Build Coastguard Worker "If gl_FragDepth is redeclared with a layout "
386*61046927SAndroid Build Coastguard Worker "qualifier in any fragment shader, it must be "
387*61046927SAndroid Build Coastguard Worker "redeclared with the same layout qualifier in "
388*61046927SAndroid Build Coastguard Worker "all fragment shaders that have assignments to "
389*61046927SAndroid Build Coastguard Worker "gl_FragDepth\n");
390*61046927SAndroid Build Coastguard Worker }
391*61046927SAndroid Build Coastguard Worker }
392*61046927SAndroid Build Coastguard Worker
393*61046927SAndroid Build Coastguard Worker /* Page 35 (page 41 of the PDF) of the GLSL 4.20 spec says:
394*61046927SAndroid Build Coastguard Worker *
395*61046927SAndroid Build Coastguard Worker * "If a shared global has multiple initializers, the
396*61046927SAndroid Build Coastguard Worker * initializers must all be constant expressions, and they
397*61046927SAndroid Build Coastguard Worker * must all have the same value. Otherwise, a link error will
398*61046927SAndroid Build Coastguard Worker * result. (A shared global having only one initializer does
399*61046927SAndroid Build Coastguard Worker * not require that initializer to be a constant expression.)"
400*61046927SAndroid Build Coastguard Worker *
401*61046927SAndroid Build Coastguard Worker * Previous to 4.20 the GLSL spec simply said that initializers
402*61046927SAndroid Build Coastguard Worker * must have the same value. In this case of non-constant
403*61046927SAndroid Build Coastguard Worker * initializers, this was impossible to determine. As a result,
404*61046927SAndroid Build Coastguard Worker * no vendor actually implemented that behavior. The 4.20
405*61046927SAndroid Build Coastguard Worker * behavior matches the implemented behavior of at least one other
406*61046927SAndroid Build Coastguard Worker * vendor, so we'll implement that for all GLSL versions.
407*61046927SAndroid Build Coastguard Worker * If (at least) one of these constant expressions is implicit,
408*61046927SAndroid Build Coastguard Worker * because it was added by glsl_zero_init, we skip the verification.
409*61046927SAndroid Build Coastguard Worker */
410*61046927SAndroid Build Coastguard Worker if (var->constant_initializer != NULL) {
411*61046927SAndroid Build Coastguard Worker if (existing->constant_initializer != NULL &&
412*61046927SAndroid Build Coastguard Worker !existing->data.is_implicit_initializer &&
413*61046927SAndroid Build Coastguard Worker !var->data.is_implicit_initializer) {
414*61046927SAndroid Build Coastguard Worker if (!var->constant_initializer->has_value(existing->constant_initializer)) {
415*61046927SAndroid Build Coastguard Worker linker_error(prog, "initializers for %s "
416*61046927SAndroid Build Coastguard Worker "`%s' have differing values\n",
417*61046927SAndroid Build Coastguard Worker mode_string(var), var->name);
418*61046927SAndroid Build Coastguard Worker return;
419*61046927SAndroid Build Coastguard Worker }
420*61046927SAndroid Build Coastguard Worker } else {
421*61046927SAndroid Build Coastguard Worker /* If the first-seen instance of a particular uniform did
422*61046927SAndroid Build Coastguard Worker * not have an initializer but a later instance does,
423*61046927SAndroid Build Coastguard Worker * replace the former with the later.
424*61046927SAndroid Build Coastguard Worker */
425*61046927SAndroid Build Coastguard Worker if (!var->data.is_implicit_initializer)
426*61046927SAndroid Build Coastguard Worker variables->replace_variable(existing->name, var);
427*61046927SAndroid Build Coastguard Worker }
428*61046927SAndroid Build Coastguard Worker }
429*61046927SAndroid Build Coastguard Worker
430*61046927SAndroid Build Coastguard Worker if (var->data.has_initializer) {
431*61046927SAndroid Build Coastguard Worker if (existing->data.has_initializer
432*61046927SAndroid Build Coastguard Worker && (var->constant_initializer == NULL
433*61046927SAndroid Build Coastguard Worker || existing->constant_initializer == NULL)) {
434*61046927SAndroid Build Coastguard Worker linker_error(prog,
435*61046927SAndroid Build Coastguard Worker "shared global variable `%s' has multiple "
436*61046927SAndroid Build Coastguard Worker "non-constant initializers.\n",
437*61046927SAndroid Build Coastguard Worker var->name);
438*61046927SAndroid Build Coastguard Worker return;
439*61046927SAndroid Build Coastguard Worker }
440*61046927SAndroid Build Coastguard Worker }
441*61046927SAndroid Build Coastguard Worker
442*61046927SAndroid Build Coastguard Worker if (existing->data.explicit_invariant != var->data.explicit_invariant) {
443*61046927SAndroid Build Coastguard Worker linker_error(prog, "declarations for %s `%s' have "
444*61046927SAndroid Build Coastguard Worker "mismatching invariant qualifiers\n",
445*61046927SAndroid Build Coastguard Worker mode_string(var), var->name);
446*61046927SAndroid Build Coastguard Worker return;
447*61046927SAndroid Build Coastguard Worker }
448*61046927SAndroid Build Coastguard Worker if (existing->data.centroid != var->data.centroid) {
449*61046927SAndroid Build Coastguard Worker linker_error(prog, "declarations for %s `%s' have "
450*61046927SAndroid Build Coastguard Worker "mismatching centroid qualifiers\n",
451*61046927SAndroid Build Coastguard Worker mode_string(var), var->name);
452*61046927SAndroid Build Coastguard Worker return;
453*61046927SAndroid Build Coastguard Worker }
454*61046927SAndroid Build Coastguard Worker if (existing->data.sample != var->data.sample) {
455*61046927SAndroid Build Coastguard Worker linker_error(prog, "declarations for %s `%s` have "
456*61046927SAndroid Build Coastguard Worker "mismatching sample qualifiers\n",
457*61046927SAndroid Build Coastguard Worker mode_string(var), var->name);
458*61046927SAndroid Build Coastguard Worker return;
459*61046927SAndroid Build Coastguard Worker }
460*61046927SAndroid Build Coastguard Worker if (existing->data.image_format != var->data.image_format) {
461*61046927SAndroid Build Coastguard Worker linker_error(prog, "declarations for %s `%s` have "
462*61046927SAndroid Build Coastguard Worker "mismatching image format qualifiers\n",
463*61046927SAndroid Build Coastguard Worker mode_string(var), var->name);
464*61046927SAndroid Build Coastguard Worker return;
465*61046927SAndroid Build Coastguard Worker }
466*61046927SAndroid Build Coastguard Worker
467*61046927SAndroid Build Coastguard Worker /* Check the precision qualifier matches for uniform variables on
468*61046927SAndroid Build Coastguard Worker * GLSL ES.
469*61046927SAndroid Build Coastguard Worker */
470*61046927SAndroid Build Coastguard Worker if (!consts->AllowGLSLRelaxedES &&
471*61046927SAndroid Build Coastguard Worker prog->IsES && !var->get_interface_type() &&
472*61046927SAndroid Build Coastguard Worker existing->data.precision != var->data.precision) {
473*61046927SAndroid Build Coastguard Worker if ((existing->data.used && var->data.used) ||
474*61046927SAndroid Build Coastguard Worker prog->GLSL_Version >= 300) {
475*61046927SAndroid Build Coastguard Worker linker_error(prog, "declarations for %s `%s` have "
476*61046927SAndroid Build Coastguard Worker "mismatching precision qualifiers\n",
477*61046927SAndroid Build Coastguard Worker mode_string(var), var->name);
478*61046927SAndroid Build Coastguard Worker return;
479*61046927SAndroid Build Coastguard Worker } else {
480*61046927SAndroid Build Coastguard Worker linker_warning(prog, "declarations for %s `%s` have "
481*61046927SAndroid Build Coastguard Worker "mismatching precision qualifiers\n",
482*61046927SAndroid Build Coastguard Worker mode_string(var), var->name);
483*61046927SAndroid Build Coastguard Worker }
484*61046927SAndroid Build Coastguard Worker }
485*61046927SAndroid Build Coastguard Worker
486*61046927SAndroid Build Coastguard Worker /* In OpenGL GLSL 3.20 spec, section 4.3.9:
487*61046927SAndroid Build Coastguard Worker *
488*61046927SAndroid Build Coastguard Worker * "It is a link-time error if any particular shader interface
489*61046927SAndroid Build Coastguard Worker * contains:
490*61046927SAndroid Build Coastguard Worker *
491*61046927SAndroid Build Coastguard Worker * - two different blocks, each having no instance name, and each
492*61046927SAndroid Build Coastguard Worker * having a member of the same name, or
493*61046927SAndroid Build Coastguard Worker *
494*61046927SAndroid Build Coastguard Worker * - a variable outside a block, and a block with no instance name,
495*61046927SAndroid Build Coastguard Worker * where the variable has the same name as a member in the block."
496*61046927SAndroid Build Coastguard Worker */
497*61046927SAndroid Build Coastguard Worker const glsl_type *var_itype = var->get_interface_type();
498*61046927SAndroid Build Coastguard Worker const glsl_type *existing_itype = existing->get_interface_type();
499*61046927SAndroid Build Coastguard Worker if (var_itype != existing_itype) {
500*61046927SAndroid Build Coastguard Worker if (!var_itype || !existing_itype) {
501*61046927SAndroid Build Coastguard Worker linker_error(prog, "declarations for %s `%s` are inside block "
502*61046927SAndroid Build Coastguard Worker "`%s` and outside a block",
503*61046927SAndroid Build Coastguard Worker mode_string(var), var->name,
504*61046927SAndroid Build Coastguard Worker glsl_get_type_name(var_itype ? var_itype : existing_itype));
505*61046927SAndroid Build Coastguard Worker return;
506*61046927SAndroid Build Coastguard Worker } else if (strcmp(glsl_get_type_name(var_itype), glsl_get_type_name(existing_itype)) != 0) {
507*61046927SAndroid Build Coastguard Worker linker_error(prog, "declarations for %s `%s` are inside blocks "
508*61046927SAndroid Build Coastguard Worker "`%s` and `%s`",
509*61046927SAndroid Build Coastguard Worker mode_string(var), var->name,
510*61046927SAndroid Build Coastguard Worker glsl_get_type_name(existing_itype),
511*61046927SAndroid Build Coastguard Worker glsl_get_type_name(var_itype));
512*61046927SAndroid Build Coastguard Worker return;
513*61046927SAndroid Build Coastguard Worker }
514*61046927SAndroid Build Coastguard Worker }
515*61046927SAndroid Build Coastguard Worker } else
516*61046927SAndroid Build Coastguard Worker variables->add_variable(var);
517*61046927SAndroid Build Coastguard Worker }
518*61046927SAndroid Build Coastguard Worker }
519*61046927SAndroid Build Coastguard Worker
520*61046927SAndroid Build Coastguard Worker /**
521*61046927SAndroid Build Coastguard Worker * Populates a shaders symbol table with all global declarations
522*61046927SAndroid Build Coastguard Worker */
523*61046927SAndroid Build Coastguard Worker static void
populate_symbol_table(gl_linked_shader * sh,glsl_symbol_table * symbols)524*61046927SAndroid Build Coastguard Worker populate_symbol_table(gl_linked_shader *sh, glsl_symbol_table *symbols)
525*61046927SAndroid Build Coastguard Worker {
526*61046927SAndroid Build Coastguard Worker sh->symbols = new(sh) glsl_symbol_table;
527*61046927SAndroid Build Coastguard Worker
528*61046927SAndroid Build Coastguard Worker _mesa_glsl_copy_symbols_from_table(sh->ir, symbols, sh->symbols);
529*61046927SAndroid Build Coastguard Worker }
530*61046927SAndroid Build Coastguard Worker
531*61046927SAndroid Build Coastguard Worker
532*61046927SAndroid Build Coastguard Worker /**
533*61046927SAndroid Build Coastguard Worker * Remap variables referenced in an instruction tree
534*61046927SAndroid Build Coastguard Worker *
535*61046927SAndroid Build Coastguard Worker * This is used when instruction trees are cloned from one shader and placed in
536*61046927SAndroid Build Coastguard Worker * another. These trees will contain references to \c ir_variable nodes that
537*61046927SAndroid Build Coastguard Worker * do not exist in the target shader. This function finds these \c ir_variable
538*61046927SAndroid Build Coastguard Worker * references and replaces the references with matching variables in the target
539*61046927SAndroid Build Coastguard Worker * shader.
540*61046927SAndroid Build Coastguard Worker *
541*61046927SAndroid Build Coastguard Worker * If there is no matching variable in the target shader, a clone of the
542*61046927SAndroid Build Coastguard Worker * \c ir_variable is made and added to the target shader. The new variable is
543*61046927SAndroid Build Coastguard Worker * added to \b both the instruction stream and the symbol table.
544*61046927SAndroid Build Coastguard Worker *
545*61046927SAndroid Build Coastguard Worker * \param inst IR tree that is to be processed.
546*61046927SAndroid Build Coastguard Worker * \param symbols Symbol table containing global scope symbols in the
547*61046927SAndroid Build Coastguard Worker * linked shader.
548*61046927SAndroid Build Coastguard Worker * \param instructions Instruction stream where new variable declarations
549*61046927SAndroid Build Coastguard Worker * should be added.
550*61046927SAndroid Build Coastguard Worker */
551*61046927SAndroid Build Coastguard Worker static void
remap_variables(ir_instruction * inst,struct gl_linked_shader * target,hash_table * temps)552*61046927SAndroid Build Coastguard Worker remap_variables(ir_instruction *inst, struct gl_linked_shader *target,
553*61046927SAndroid Build Coastguard Worker hash_table *temps)
554*61046927SAndroid Build Coastguard Worker {
555*61046927SAndroid Build Coastguard Worker class remap_visitor : public ir_hierarchical_visitor {
556*61046927SAndroid Build Coastguard Worker public:
557*61046927SAndroid Build Coastguard Worker remap_visitor(struct gl_linked_shader *target, hash_table *temps)
558*61046927SAndroid Build Coastguard Worker {
559*61046927SAndroid Build Coastguard Worker this->target = target;
560*61046927SAndroid Build Coastguard Worker this->symbols = target->symbols;
561*61046927SAndroid Build Coastguard Worker this->instructions = target->ir;
562*61046927SAndroid Build Coastguard Worker this->temps = temps;
563*61046927SAndroid Build Coastguard Worker }
564*61046927SAndroid Build Coastguard Worker
565*61046927SAndroid Build Coastguard Worker virtual ir_visitor_status visit(ir_dereference_variable *ir)
566*61046927SAndroid Build Coastguard Worker {
567*61046927SAndroid Build Coastguard Worker if (ir->var->data.mode == ir_var_temporary) {
568*61046927SAndroid Build Coastguard Worker hash_entry *entry = _mesa_hash_table_search(temps, ir->var);
569*61046927SAndroid Build Coastguard Worker ir_variable *var = entry ? (ir_variable *) entry->data : NULL;
570*61046927SAndroid Build Coastguard Worker
571*61046927SAndroid Build Coastguard Worker assert(var != NULL);
572*61046927SAndroid Build Coastguard Worker ir->var = var;
573*61046927SAndroid Build Coastguard Worker return visit_continue;
574*61046927SAndroid Build Coastguard Worker }
575*61046927SAndroid Build Coastguard Worker
576*61046927SAndroid Build Coastguard Worker ir_variable *const existing =
577*61046927SAndroid Build Coastguard Worker this->symbols->get_variable(ir->var->name);
578*61046927SAndroid Build Coastguard Worker if (existing != NULL)
579*61046927SAndroid Build Coastguard Worker ir->var = existing;
580*61046927SAndroid Build Coastguard Worker else {
581*61046927SAndroid Build Coastguard Worker ir_variable *copy = ir->var->clone(this->target, NULL);
582*61046927SAndroid Build Coastguard Worker
583*61046927SAndroid Build Coastguard Worker this->symbols->add_variable(copy);
584*61046927SAndroid Build Coastguard Worker this->instructions->push_head(copy);
585*61046927SAndroid Build Coastguard Worker ir->var = copy;
586*61046927SAndroid Build Coastguard Worker }
587*61046927SAndroid Build Coastguard Worker
588*61046927SAndroid Build Coastguard Worker return visit_continue;
589*61046927SAndroid Build Coastguard Worker }
590*61046927SAndroid Build Coastguard Worker
591*61046927SAndroid Build Coastguard Worker private:
592*61046927SAndroid Build Coastguard Worker struct gl_linked_shader *target;
593*61046927SAndroid Build Coastguard Worker glsl_symbol_table *symbols;
594*61046927SAndroid Build Coastguard Worker exec_list *instructions;
595*61046927SAndroid Build Coastguard Worker hash_table *temps;
596*61046927SAndroid Build Coastguard Worker };
597*61046927SAndroid Build Coastguard Worker
598*61046927SAndroid Build Coastguard Worker remap_visitor v(target, temps);
599*61046927SAndroid Build Coastguard Worker
600*61046927SAndroid Build Coastguard Worker inst->accept(&v);
601*61046927SAndroid Build Coastguard Worker }
602*61046927SAndroid Build Coastguard Worker
603*61046927SAndroid Build Coastguard Worker
604*61046927SAndroid Build Coastguard Worker /**
605*61046927SAndroid Build Coastguard Worker * Move non-declarations from one instruction stream to another
606*61046927SAndroid Build Coastguard Worker *
607*61046927SAndroid Build Coastguard Worker * The intended usage pattern of this function is to pass the pointer to the
608*61046927SAndroid Build Coastguard Worker * head sentinel of a list (i.e., a pointer to the list cast to an \c exec_node
609*61046927SAndroid Build Coastguard Worker * pointer) for \c last and \c false for \c make_copies on the first
610*61046927SAndroid Build Coastguard Worker * call. Successive calls pass the return value of the previous call for
611*61046927SAndroid Build Coastguard Worker * \c last and \c true for \c make_copies.
612*61046927SAndroid Build Coastguard Worker *
613*61046927SAndroid Build Coastguard Worker * \param instructions Source instruction stream
614*61046927SAndroid Build Coastguard Worker * \param last Instruction after which new instructions should be
615*61046927SAndroid Build Coastguard Worker * inserted in the target instruction stream
616*61046927SAndroid Build Coastguard Worker * \param make_copies Flag selecting whether instructions in \c instructions
617*61046927SAndroid Build Coastguard Worker * should be copied (via \c ir_instruction::clone) into the
618*61046927SAndroid Build Coastguard Worker * target list or moved.
619*61046927SAndroid Build Coastguard Worker *
620*61046927SAndroid Build Coastguard Worker * \return
621*61046927SAndroid Build Coastguard Worker * The new "last" instruction in the target instruction stream. This pointer
622*61046927SAndroid Build Coastguard Worker * is suitable for use as the \c last parameter of a later call to this
623*61046927SAndroid Build Coastguard Worker * function.
624*61046927SAndroid Build Coastguard Worker */
625*61046927SAndroid Build Coastguard Worker static exec_node *
move_non_declarations(exec_list * instructions,exec_node * last,bool make_copies,gl_linked_shader * target)626*61046927SAndroid Build Coastguard Worker move_non_declarations(exec_list *instructions, exec_node *last,
627*61046927SAndroid Build Coastguard Worker bool make_copies, gl_linked_shader *target)
628*61046927SAndroid Build Coastguard Worker {
629*61046927SAndroid Build Coastguard Worker hash_table *temps = NULL;
630*61046927SAndroid Build Coastguard Worker
631*61046927SAndroid Build Coastguard Worker if (make_copies)
632*61046927SAndroid Build Coastguard Worker temps = _mesa_pointer_hash_table_create(NULL);
633*61046927SAndroid Build Coastguard Worker
634*61046927SAndroid Build Coastguard Worker foreach_in_list_safe(ir_instruction, inst, instructions) {
635*61046927SAndroid Build Coastguard Worker if (inst->as_function())
636*61046927SAndroid Build Coastguard Worker continue;
637*61046927SAndroid Build Coastguard Worker
638*61046927SAndroid Build Coastguard Worker ir_variable *var = inst->as_variable();
639*61046927SAndroid Build Coastguard Worker if ((var != NULL) && (var->data.mode != ir_var_temporary))
640*61046927SAndroid Build Coastguard Worker continue;
641*61046927SAndroid Build Coastguard Worker
642*61046927SAndroid Build Coastguard Worker assert(inst->as_assignment()
643*61046927SAndroid Build Coastguard Worker || inst->as_call()
644*61046927SAndroid Build Coastguard Worker || inst->as_if() /* for initializers with the ?: operator */
645*61046927SAndroid Build Coastguard Worker || ((var != NULL) && (var->data.mode == ir_var_temporary)));
646*61046927SAndroid Build Coastguard Worker
647*61046927SAndroid Build Coastguard Worker if (make_copies) {
648*61046927SAndroid Build Coastguard Worker inst = inst->clone(target, NULL);
649*61046927SAndroid Build Coastguard Worker
650*61046927SAndroid Build Coastguard Worker if (var != NULL)
651*61046927SAndroid Build Coastguard Worker _mesa_hash_table_insert(temps, var, inst);
652*61046927SAndroid Build Coastguard Worker else
653*61046927SAndroid Build Coastguard Worker remap_variables(inst, target, temps);
654*61046927SAndroid Build Coastguard Worker } else {
655*61046927SAndroid Build Coastguard Worker inst->remove();
656*61046927SAndroid Build Coastguard Worker }
657*61046927SAndroid Build Coastguard Worker
658*61046927SAndroid Build Coastguard Worker last->insert_after(inst);
659*61046927SAndroid Build Coastguard Worker last = inst;
660*61046927SAndroid Build Coastguard Worker }
661*61046927SAndroid Build Coastguard Worker
662*61046927SAndroid Build Coastguard Worker if (make_copies)
663*61046927SAndroid Build Coastguard Worker _mesa_hash_table_destroy(temps, NULL);
664*61046927SAndroid Build Coastguard Worker
665*61046927SAndroid Build Coastguard Worker return last;
666*61046927SAndroid Build Coastguard Worker }
667*61046927SAndroid Build Coastguard Worker
668*61046927SAndroid Build Coastguard Worker
669*61046927SAndroid Build Coastguard Worker /**
670*61046927SAndroid Build Coastguard Worker * This class is only used in link_intrastage_shaders() below but declaring
671*61046927SAndroid Build Coastguard Worker * it inside that function leads to compiler warnings with some versions of
672*61046927SAndroid Build Coastguard Worker * gcc.
673*61046927SAndroid Build Coastguard Worker */
674*61046927SAndroid Build Coastguard Worker class array_sizing_visitor : public deref_type_updater {
675*61046927SAndroid Build Coastguard Worker public:
676*61046927SAndroid Build Coastguard Worker using deref_type_updater::visit;
677*61046927SAndroid Build Coastguard Worker
array_sizing_visitor()678*61046927SAndroid Build Coastguard Worker array_sizing_visitor()
679*61046927SAndroid Build Coastguard Worker : mem_ctx(ralloc_context(NULL)),
680*61046927SAndroid Build Coastguard Worker unnamed_interfaces(_mesa_pointer_hash_table_create(NULL))
681*61046927SAndroid Build Coastguard Worker {
682*61046927SAndroid Build Coastguard Worker }
683*61046927SAndroid Build Coastguard Worker
~array_sizing_visitor()684*61046927SAndroid Build Coastguard Worker ~array_sizing_visitor()
685*61046927SAndroid Build Coastguard Worker {
686*61046927SAndroid Build Coastguard Worker _mesa_hash_table_destroy(this->unnamed_interfaces, NULL);
687*61046927SAndroid Build Coastguard Worker ralloc_free(this->mem_ctx);
688*61046927SAndroid Build Coastguard Worker }
689*61046927SAndroid Build Coastguard Worker
690*61046927SAndroid Build Coastguard Worker array_sizing_visitor(const array_sizing_visitor &) = delete;
691*61046927SAndroid Build Coastguard Worker array_sizing_visitor & operator=(const array_sizing_visitor &) = delete;
692*61046927SAndroid Build Coastguard Worker
visit(ir_variable * var)693*61046927SAndroid Build Coastguard Worker virtual ir_visitor_status visit(ir_variable *var)
694*61046927SAndroid Build Coastguard Worker {
695*61046927SAndroid Build Coastguard Worker const glsl_type *type_without_array;
696*61046927SAndroid Build Coastguard Worker bool implicit_sized_array = var->data.implicit_sized_array;
697*61046927SAndroid Build Coastguard Worker fixup_type(&var->type, var->data.max_array_access,
698*61046927SAndroid Build Coastguard Worker var->data.from_ssbo_unsized_array,
699*61046927SAndroid Build Coastguard Worker &implicit_sized_array);
700*61046927SAndroid Build Coastguard Worker var->data.implicit_sized_array = implicit_sized_array;
701*61046927SAndroid Build Coastguard Worker type_without_array = glsl_without_array(var->type);
702*61046927SAndroid Build Coastguard Worker if (glsl_type_is_interface(var->type)) {
703*61046927SAndroid Build Coastguard Worker if (interface_contains_unsized_arrays(var->type)) {
704*61046927SAndroid Build Coastguard Worker const glsl_type *new_type =
705*61046927SAndroid Build Coastguard Worker resize_interface_members(var->type,
706*61046927SAndroid Build Coastguard Worker var->get_max_ifc_array_access(),
707*61046927SAndroid Build Coastguard Worker var->is_in_shader_storage_block());
708*61046927SAndroid Build Coastguard Worker var->type = new_type;
709*61046927SAndroid Build Coastguard Worker var->change_interface_type(new_type);
710*61046927SAndroid Build Coastguard Worker }
711*61046927SAndroid Build Coastguard Worker } else if (glsl_type_is_interface(type_without_array)) {
712*61046927SAndroid Build Coastguard Worker if (interface_contains_unsized_arrays(type_without_array)) {
713*61046927SAndroid Build Coastguard Worker const glsl_type *new_type =
714*61046927SAndroid Build Coastguard Worker resize_interface_members(type_without_array,
715*61046927SAndroid Build Coastguard Worker var->get_max_ifc_array_access(),
716*61046927SAndroid Build Coastguard Worker var->is_in_shader_storage_block());
717*61046927SAndroid Build Coastguard Worker var->change_interface_type(new_type);
718*61046927SAndroid Build Coastguard Worker var->type = update_interface_members_array(var->type, new_type);
719*61046927SAndroid Build Coastguard Worker }
720*61046927SAndroid Build Coastguard Worker } else if (const glsl_type *ifc_type = var->get_interface_type()) {
721*61046927SAndroid Build Coastguard Worker /* Store a pointer to the variable in the unnamed_interfaces
722*61046927SAndroid Build Coastguard Worker * hashtable.
723*61046927SAndroid Build Coastguard Worker */
724*61046927SAndroid Build Coastguard Worker hash_entry *entry =
725*61046927SAndroid Build Coastguard Worker _mesa_hash_table_search(this->unnamed_interfaces,
726*61046927SAndroid Build Coastguard Worker ifc_type);
727*61046927SAndroid Build Coastguard Worker
728*61046927SAndroid Build Coastguard Worker ir_variable **interface_vars = entry ? (ir_variable **) entry->data : NULL;
729*61046927SAndroid Build Coastguard Worker
730*61046927SAndroid Build Coastguard Worker if (interface_vars == NULL) {
731*61046927SAndroid Build Coastguard Worker interface_vars = rzalloc_array(mem_ctx, ir_variable *,
732*61046927SAndroid Build Coastguard Worker ifc_type->length);
733*61046927SAndroid Build Coastguard Worker _mesa_hash_table_insert(this->unnamed_interfaces, ifc_type,
734*61046927SAndroid Build Coastguard Worker interface_vars);
735*61046927SAndroid Build Coastguard Worker }
736*61046927SAndroid Build Coastguard Worker unsigned index = glsl_get_field_index(ifc_type, var->name);
737*61046927SAndroid Build Coastguard Worker assert(index < ifc_type->length);
738*61046927SAndroid Build Coastguard Worker assert(interface_vars[index] == NULL);
739*61046927SAndroid Build Coastguard Worker interface_vars[index] = var;
740*61046927SAndroid Build Coastguard Worker }
741*61046927SAndroid Build Coastguard Worker return visit_continue;
742*61046927SAndroid Build Coastguard Worker }
743*61046927SAndroid Build Coastguard Worker
744*61046927SAndroid Build Coastguard Worker /**
745*61046927SAndroid Build Coastguard Worker * For each unnamed interface block that was discovered while running the
746*61046927SAndroid Build Coastguard Worker * visitor, adjust the interface type to reflect the newly assigned array
747*61046927SAndroid Build Coastguard Worker * sizes, and fix up the ir_variable nodes to point to the new interface
748*61046927SAndroid Build Coastguard Worker * type.
749*61046927SAndroid Build Coastguard Worker */
fixup_unnamed_interface_types()750*61046927SAndroid Build Coastguard Worker void fixup_unnamed_interface_types()
751*61046927SAndroid Build Coastguard Worker {
752*61046927SAndroid Build Coastguard Worker hash_table_call_foreach(this->unnamed_interfaces,
753*61046927SAndroid Build Coastguard Worker fixup_unnamed_interface_type, NULL);
754*61046927SAndroid Build Coastguard Worker }
755*61046927SAndroid Build Coastguard Worker
756*61046927SAndroid Build Coastguard Worker private:
757*61046927SAndroid Build Coastguard Worker /**
758*61046927SAndroid Build Coastguard Worker * If the type pointed to by \c type represents an unsized array, replace
759*61046927SAndroid Build Coastguard Worker * it with a sized array whose size is determined by max_array_access.
760*61046927SAndroid Build Coastguard Worker */
fixup_type(const glsl_type ** type,unsigned max_array_access,bool from_ssbo_unsized_array,bool * implicit_sized)761*61046927SAndroid Build Coastguard Worker static void fixup_type(const glsl_type **type, unsigned max_array_access,
762*61046927SAndroid Build Coastguard Worker bool from_ssbo_unsized_array, bool *implicit_sized)
763*61046927SAndroid Build Coastguard Worker {
764*61046927SAndroid Build Coastguard Worker if (!from_ssbo_unsized_array && glsl_type_is_unsized_array(*type)) {
765*61046927SAndroid Build Coastguard Worker *type = glsl_array_type((*type)->fields.array,
766*61046927SAndroid Build Coastguard Worker max_array_access + 1, 0);
767*61046927SAndroid Build Coastguard Worker *implicit_sized = true;
768*61046927SAndroid Build Coastguard Worker assert(*type != NULL);
769*61046927SAndroid Build Coastguard Worker }
770*61046927SAndroid Build Coastguard Worker }
771*61046927SAndroid Build Coastguard Worker
772*61046927SAndroid Build Coastguard Worker static const glsl_type *
update_interface_members_array(const glsl_type * type,const glsl_type * new_interface_type)773*61046927SAndroid Build Coastguard Worker update_interface_members_array(const glsl_type *type,
774*61046927SAndroid Build Coastguard Worker const glsl_type *new_interface_type)
775*61046927SAndroid Build Coastguard Worker {
776*61046927SAndroid Build Coastguard Worker const glsl_type *element_type = type->fields.array;
777*61046927SAndroid Build Coastguard Worker if (glsl_type_is_array(element_type)) {
778*61046927SAndroid Build Coastguard Worker const glsl_type *new_array_type =
779*61046927SAndroid Build Coastguard Worker update_interface_members_array(element_type, new_interface_type);
780*61046927SAndroid Build Coastguard Worker return glsl_array_type(new_array_type, type->length, 0);
781*61046927SAndroid Build Coastguard Worker } else {
782*61046927SAndroid Build Coastguard Worker return glsl_array_type(new_interface_type, type->length, 0);
783*61046927SAndroid Build Coastguard Worker }
784*61046927SAndroid Build Coastguard Worker }
785*61046927SAndroid Build Coastguard Worker
786*61046927SAndroid Build Coastguard Worker /**
787*61046927SAndroid Build Coastguard Worker * Determine whether the given interface type contains unsized arrays (if
788*61046927SAndroid Build Coastguard Worker * it doesn't, array_sizing_visitor doesn't need to process it).
789*61046927SAndroid Build Coastguard Worker */
interface_contains_unsized_arrays(const glsl_type * type)790*61046927SAndroid Build Coastguard Worker static bool interface_contains_unsized_arrays(const glsl_type *type)
791*61046927SAndroid Build Coastguard Worker {
792*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < type->length; i++) {
793*61046927SAndroid Build Coastguard Worker const glsl_type *elem_type = type->fields.structure[i].type;
794*61046927SAndroid Build Coastguard Worker if (glsl_type_is_unsized_array(elem_type))
795*61046927SAndroid Build Coastguard Worker return true;
796*61046927SAndroid Build Coastguard Worker }
797*61046927SAndroid Build Coastguard Worker return false;
798*61046927SAndroid Build Coastguard Worker }
799*61046927SAndroid Build Coastguard Worker
800*61046927SAndroid Build Coastguard Worker /**
801*61046927SAndroid Build Coastguard Worker * Create a new interface type based on the given type, with unsized arrays
802*61046927SAndroid Build Coastguard Worker * replaced by sized arrays whose size is determined by
803*61046927SAndroid Build Coastguard Worker * max_ifc_array_access.
804*61046927SAndroid Build Coastguard Worker */
805*61046927SAndroid Build Coastguard Worker static const glsl_type *
resize_interface_members(const glsl_type * type,const int * max_ifc_array_access,bool is_ssbo)806*61046927SAndroid Build Coastguard Worker resize_interface_members(const glsl_type *type,
807*61046927SAndroid Build Coastguard Worker const int *max_ifc_array_access,
808*61046927SAndroid Build Coastguard Worker bool is_ssbo)
809*61046927SAndroid Build Coastguard Worker {
810*61046927SAndroid Build Coastguard Worker unsigned num_fields = type->length;
811*61046927SAndroid Build Coastguard Worker glsl_struct_field *fields = new glsl_struct_field[num_fields];
812*61046927SAndroid Build Coastguard Worker memcpy(fields, type->fields.structure,
813*61046927SAndroid Build Coastguard Worker num_fields * sizeof(*fields));
814*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_fields; i++) {
815*61046927SAndroid Build Coastguard Worker bool implicit_sized_array = fields[i].implicit_sized_array;
816*61046927SAndroid Build Coastguard Worker /* If SSBO last member is unsized array, we don't replace it by a sized
817*61046927SAndroid Build Coastguard Worker * array.
818*61046927SAndroid Build Coastguard Worker */
819*61046927SAndroid Build Coastguard Worker if (is_ssbo && i == (num_fields - 1))
820*61046927SAndroid Build Coastguard Worker fixup_type(&fields[i].type, max_ifc_array_access[i],
821*61046927SAndroid Build Coastguard Worker true, &implicit_sized_array);
822*61046927SAndroid Build Coastguard Worker else
823*61046927SAndroid Build Coastguard Worker fixup_type(&fields[i].type, max_ifc_array_access[i],
824*61046927SAndroid Build Coastguard Worker false, &implicit_sized_array);
825*61046927SAndroid Build Coastguard Worker fields[i].implicit_sized_array = implicit_sized_array;
826*61046927SAndroid Build Coastguard Worker }
827*61046927SAndroid Build Coastguard Worker glsl_interface_packing packing =
828*61046927SAndroid Build Coastguard Worker (glsl_interface_packing) type->interface_packing;
829*61046927SAndroid Build Coastguard Worker bool row_major = (bool) type->interface_row_major;
830*61046927SAndroid Build Coastguard Worker const glsl_type *new_ifc_type =
831*61046927SAndroid Build Coastguard Worker glsl_interface_type(fields, num_fields,
832*61046927SAndroid Build Coastguard Worker packing, row_major, glsl_get_type_name(type));
833*61046927SAndroid Build Coastguard Worker delete [] fields;
834*61046927SAndroid Build Coastguard Worker return new_ifc_type;
835*61046927SAndroid Build Coastguard Worker }
836*61046927SAndroid Build Coastguard Worker
fixup_unnamed_interface_type(const void * key,void * data,void *)837*61046927SAndroid Build Coastguard Worker static void fixup_unnamed_interface_type(const void *key, void *data,
838*61046927SAndroid Build Coastguard Worker void *)
839*61046927SAndroid Build Coastguard Worker {
840*61046927SAndroid Build Coastguard Worker const glsl_type *ifc_type = (const glsl_type *) key;
841*61046927SAndroid Build Coastguard Worker ir_variable **interface_vars = (ir_variable **) data;
842*61046927SAndroid Build Coastguard Worker unsigned num_fields = ifc_type->length;
843*61046927SAndroid Build Coastguard Worker glsl_struct_field *fields = new glsl_struct_field[num_fields];
844*61046927SAndroid Build Coastguard Worker memcpy(fields, ifc_type->fields.structure,
845*61046927SAndroid Build Coastguard Worker num_fields * sizeof(*fields));
846*61046927SAndroid Build Coastguard Worker bool interface_type_changed = false;
847*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_fields; i++) {
848*61046927SAndroid Build Coastguard Worker if (interface_vars[i] != NULL &&
849*61046927SAndroid Build Coastguard Worker fields[i].type != interface_vars[i]->type) {
850*61046927SAndroid Build Coastguard Worker fields[i].type = interface_vars[i]->type;
851*61046927SAndroid Build Coastguard Worker interface_type_changed = true;
852*61046927SAndroid Build Coastguard Worker }
853*61046927SAndroid Build Coastguard Worker }
854*61046927SAndroid Build Coastguard Worker if (!interface_type_changed) {
855*61046927SAndroid Build Coastguard Worker delete [] fields;
856*61046927SAndroid Build Coastguard Worker return;
857*61046927SAndroid Build Coastguard Worker }
858*61046927SAndroid Build Coastguard Worker glsl_interface_packing packing =
859*61046927SAndroid Build Coastguard Worker (glsl_interface_packing) ifc_type->interface_packing;
860*61046927SAndroid Build Coastguard Worker bool row_major = (bool) ifc_type->interface_row_major;
861*61046927SAndroid Build Coastguard Worker const glsl_type *new_ifc_type =
862*61046927SAndroid Build Coastguard Worker glsl_interface_type(fields, num_fields, packing,
863*61046927SAndroid Build Coastguard Worker row_major, glsl_get_type_name(ifc_type));
864*61046927SAndroid Build Coastguard Worker delete [] fields;
865*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_fields; i++) {
866*61046927SAndroid Build Coastguard Worker if (interface_vars[i] != NULL)
867*61046927SAndroid Build Coastguard Worker interface_vars[i]->change_interface_type(new_ifc_type);
868*61046927SAndroid Build Coastguard Worker }
869*61046927SAndroid Build Coastguard Worker }
870*61046927SAndroid Build Coastguard Worker
871*61046927SAndroid Build Coastguard Worker /**
872*61046927SAndroid Build Coastguard Worker * Memory context used to allocate the data in \c unnamed_interfaces.
873*61046927SAndroid Build Coastguard Worker */
874*61046927SAndroid Build Coastguard Worker void *mem_ctx;
875*61046927SAndroid Build Coastguard Worker
876*61046927SAndroid Build Coastguard Worker /**
877*61046927SAndroid Build Coastguard Worker * Hash table from const glsl_type * to an array of ir_variable *'s
878*61046927SAndroid Build Coastguard Worker * pointing to the ir_variables constituting each unnamed interface block.
879*61046927SAndroid Build Coastguard Worker */
880*61046927SAndroid Build Coastguard Worker hash_table *unnamed_interfaces;
881*61046927SAndroid Build Coastguard Worker };
882*61046927SAndroid Build Coastguard Worker
883*61046927SAndroid Build Coastguard Worker static bool
validate_xfb_buffer_stride(const struct gl_constants * consts,unsigned idx,struct gl_shader_program * prog)884*61046927SAndroid Build Coastguard Worker validate_xfb_buffer_stride(const struct gl_constants *consts, unsigned idx,
885*61046927SAndroid Build Coastguard Worker struct gl_shader_program *prog)
886*61046927SAndroid Build Coastguard Worker {
887*61046927SAndroid Build Coastguard Worker /* We will validate doubles at a later stage */
888*61046927SAndroid Build Coastguard Worker if (prog->TransformFeedback.BufferStride[idx] % 4) {
889*61046927SAndroid Build Coastguard Worker linker_error(prog, "invalid qualifier xfb_stride=%d must be a "
890*61046927SAndroid Build Coastguard Worker "multiple of 4 or if its applied to a type that is "
891*61046927SAndroid Build Coastguard Worker "or contains a double a multiple of 8.",
892*61046927SAndroid Build Coastguard Worker prog->TransformFeedback.BufferStride[idx]);
893*61046927SAndroid Build Coastguard Worker return false;
894*61046927SAndroid Build Coastguard Worker }
895*61046927SAndroid Build Coastguard Worker
896*61046927SAndroid Build Coastguard Worker if (prog->TransformFeedback.BufferStride[idx] / 4 >
897*61046927SAndroid Build Coastguard Worker consts->MaxTransformFeedbackInterleavedComponents) {
898*61046927SAndroid Build Coastguard Worker linker_error(prog, "The MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS "
899*61046927SAndroid Build Coastguard Worker "limit has been exceeded.");
900*61046927SAndroid Build Coastguard Worker return false;
901*61046927SAndroid Build Coastguard Worker }
902*61046927SAndroid Build Coastguard Worker
903*61046927SAndroid Build Coastguard Worker return true;
904*61046927SAndroid Build Coastguard Worker }
905*61046927SAndroid Build Coastguard Worker
906*61046927SAndroid Build Coastguard Worker /**
907*61046927SAndroid Build Coastguard Worker * Check for conflicting xfb_stride default qualifiers and store buffer stride
908*61046927SAndroid Build Coastguard Worker * for later use.
909*61046927SAndroid Build Coastguard Worker */
910*61046927SAndroid Build Coastguard Worker static void
link_xfb_stride_layout_qualifiers(const struct gl_constants * consts,struct gl_shader_program * prog,struct gl_shader ** shader_list,unsigned num_shaders)911*61046927SAndroid Build Coastguard Worker link_xfb_stride_layout_qualifiers(const struct gl_constants *consts,
912*61046927SAndroid Build Coastguard Worker struct gl_shader_program *prog,
913*61046927SAndroid Build Coastguard Worker struct gl_shader **shader_list,
914*61046927SAndroid Build Coastguard Worker unsigned num_shaders)
915*61046927SAndroid Build Coastguard Worker {
916*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < MAX_FEEDBACK_BUFFERS; i++) {
917*61046927SAndroid Build Coastguard Worker prog->TransformFeedback.BufferStride[i] = 0;
918*61046927SAndroid Build Coastguard Worker }
919*61046927SAndroid Build Coastguard Worker
920*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_shaders; i++) {
921*61046927SAndroid Build Coastguard Worker struct gl_shader *shader = shader_list[i];
922*61046927SAndroid Build Coastguard Worker
923*61046927SAndroid Build Coastguard Worker for (unsigned j = 0; j < MAX_FEEDBACK_BUFFERS; j++) {
924*61046927SAndroid Build Coastguard Worker if (shader->TransformFeedbackBufferStride[j]) {
925*61046927SAndroid Build Coastguard Worker if (prog->TransformFeedback.BufferStride[j] == 0) {
926*61046927SAndroid Build Coastguard Worker prog->TransformFeedback.BufferStride[j] =
927*61046927SAndroid Build Coastguard Worker shader->TransformFeedbackBufferStride[j];
928*61046927SAndroid Build Coastguard Worker if (!validate_xfb_buffer_stride(consts, j, prog))
929*61046927SAndroid Build Coastguard Worker return;
930*61046927SAndroid Build Coastguard Worker } else if (prog->TransformFeedback.BufferStride[j] !=
931*61046927SAndroid Build Coastguard Worker shader->TransformFeedbackBufferStride[j]){
932*61046927SAndroid Build Coastguard Worker linker_error(prog,
933*61046927SAndroid Build Coastguard Worker "intrastage shaders defined with conflicting "
934*61046927SAndroid Build Coastguard Worker "xfb_stride for buffer %d (%d and %d)\n", j,
935*61046927SAndroid Build Coastguard Worker prog->TransformFeedback.BufferStride[j],
936*61046927SAndroid Build Coastguard Worker shader->TransformFeedbackBufferStride[j]);
937*61046927SAndroid Build Coastguard Worker return;
938*61046927SAndroid Build Coastguard Worker }
939*61046927SAndroid Build Coastguard Worker }
940*61046927SAndroid Build Coastguard Worker }
941*61046927SAndroid Build Coastguard Worker }
942*61046927SAndroid Build Coastguard Worker }
943*61046927SAndroid Build Coastguard Worker
944*61046927SAndroid Build Coastguard Worker /**
945*61046927SAndroid Build Coastguard Worker * Check for conflicting bindless/bound sampler/image layout qualifiers at
946*61046927SAndroid Build Coastguard Worker * global scope.
947*61046927SAndroid Build Coastguard Worker */
948*61046927SAndroid Build Coastguard Worker static void
link_bindless_layout_qualifiers(struct gl_shader_program * prog,struct gl_shader ** shader_list,unsigned num_shaders)949*61046927SAndroid Build Coastguard Worker link_bindless_layout_qualifiers(struct gl_shader_program *prog,
950*61046927SAndroid Build Coastguard Worker struct gl_shader **shader_list,
951*61046927SAndroid Build Coastguard Worker unsigned num_shaders)
952*61046927SAndroid Build Coastguard Worker {
953*61046927SAndroid Build Coastguard Worker bool bindless_sampler, bindless_image;
954*61046927SAndroid Build Coastguard Worker bool bound_sampler, bound_image;
955*61046927SAndroid Build Coastguard Worker
956*61046927SAndroid Build Coastguard Worker bindless_sampler = bindless_image = false;
957*61046927SAndroid Build Coastguard Worker bound_sampler = bound_image = false;
958*61046927SAndroid Build Coastguard Worker
959*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_shaders; i++) {
960*61046927SAndroid Build Coastguard Worker struct gl_shader *shader = shader_list[i];
961*61046927SAndroid Build Coastguard Worker
962*61046927SAndroid Build Coastguard Worker if (shader->bindless_sampler)
963*61046927SAndroid Build Coastguard Worker bindless_sampler = true;
964*61046927SAndroid Build Coastguard Worker if (shader->bindless_image)
965*61046927SAndroid Build Coastguard Worker bindless_image = true;
966*61046927SAndroid Build Coastguard Worker if (shader->bound_sampler)
967*61046927SAndroid Build Coastguard Worker bound_sampler = true;
968*61046927SAndroid Build Coastguard Worker if (shader->bound_image)
969*61046927SAndroid Build Coastguard Worker bound_image = true;
970*61046927SAndroid Build Coastguard Worker
971*61046927SAndroid Build Coastguard Worker if ((bindless_sampler && bound_sampler) ||
972*61046927SAndroid Build Coastguard Worker (bindless_image && bound_image)) {
973*61046927SAndroid Build Coastguard Worker /* From section 4.4.6 of the ARB_bindless_texture spec:
974*61046927SAndroid Build Coastguard Worker *
975*61046927SAndroid Build Coastguard Worker * "If both bindless_sampler and bound_sampler, or bindless_image
976*61046927SAndroid Build Coastguard Worker * and bound_image, are declared at global scope in any
977*61046927SAndroid Build Coastguard Worker * compilation unit, a link- time error will be generated."
978*61046927SAndroid Build Coastguard Worker */
979*61046927SAndroid Build Coastguard Worker linker_error(prog, "both bindless_sampler and bound_sampler, or "
980*61046927SAndroid Build Coastguard Worker "bindless_image and bound_image, can't be declared at "
981*61046927SAndroid Build Coastguard Worker "global scope");
982*61046927SAndroid Build Coastguard Worker }
983*61046927SAndroid Build Coastguard Worker }
984*61046927SAndroid Build Coastguard Worker }
985*61046927SAndroid Build Coastguard Worker
986*61046927SAndroid Build Coastguard Worker /**
987*61046927SAndroid Build Coastguard Worker * Check for conflicting viewport_relative settings across shaders, and sets
988*61046927SAndroid Build Coastguard Worker * the value for the linked shader.
989*61046927SAndroid Build Coastguard Worker */
990*61046927SAndroid Build Coastguard Worker static void
link_layer_viewport_relative_qualifier(struct gl_shader_program * prog,struct gl_program * gl_prog,struct gl_shader ** shader_list,unsigned num_shaders)991*61046927SAndroid Build Coastguard Worker link_layer_viewport_relative_qualifier(struct gl_shader_program *prog,
992*61046927SAndroid Build Coastguard Worker struct gl_program *gl_prog,
993*61046927SAndroid Build Coastguard Worker struct gl_shader **shader_list,
994*61046927SAndroid Build Coastguard Worker unsigned num_shaders)
995*61046927SAndroid Build Coastguard Worker {
996*61046927SAndroid Build Coastguard Worker unsigned i;
997*61046927SAndroid Build Coastguard Worker
998*61046927SAndroid Build Coastguard Worker /* Find first shader with explicit layer declaration */
999*61046927SAndroid Build Coastguard Worker for (i = 0; i < num_shaders; i++) {
1000*61046927SAndroid Build Coastguard Worker if (shader_list[i]->redeclares_gl_layer) {
1001*61046927SAndroid Build Coastguard Worker gl_prog->info.layer_viewport_relative =
1002*61046927SAndroid Build Coastguard Worker shader_list[i]->layer_viewport_relative;
1003*61046927SAndroid Build Coastguard Worker break;
1004*61046927SAndroid Build Coastguard Worker }
1005*61046927SAndroid Build Coastguard Worker }
1006*61046927SAndroid Build Coastguard Worker
1007*61046927SAndroid Build Coastguard Worker /* Now make sure that each subsequent shader's explicit layer declaration
1008*61046927SAndroid Build Coastguard Worker * matches the first one's.
1009*61046927SAndroid Build Coastguard Worker */
1010*61046927SAndroid Build Coastguard Worker for (; i < num_shaders; i++) {
1011*61046927SAndroid Build Coastguard Worker if (shader_list[i]->redeclares_gl_layer &&
1012*61046927SAndroid Build Coastguard Worker shader_list[i]->layer_viewport_relative !=
1013*61046927SAndroid Build Coastguard Worker gl_prog->info.layer_viewport_relative) {
1014*61046927SAndroid Build Coastguard Worker linker_error(prog, "all gl_Layer redeclarations must have identical "
1015*61046927SAndroid Build Coastguard Worker "viewport_relative settings");
1016*61046927SAndroid Build Coastguard Worker }
1017*61046927SAndroid Build Coastguard Worker }
1018*61046927SAndroid Build Coastguard Worker }
1019*61046927SAndroid Build Coastguard Worker
1020*61046927SAndroid Build Coastguard Worker /**
1021*61046927SAndroid Build Coastguard Worker * Performs the cross-validation of tessellation control shader vertices and
1022*61046927SAndroid Build Coastguard Worker * layout qualifiers for the attached tessellation control shaders,
1023*61046927SAndroid Build Coastguard Worker * and propagates them to the linked TCS and linked shader program.
1024*61046927SAndroid Build Coastguard Worker */
1025*61046927SAndroid Build Coastguard Worker static void
link_tcs_out_layout_qualifiers(struct gl_shader_program * prog,struct gl_program * gl_prog,struct gl_shader ** shader_list,unsigned num_shaders)1026*61046927SAndroid Build Coastguard Worker link_tcs_out_layout_qualifiers(struct gl_shader_program *prog,
1027*61046927SAndroid Build Coastguard Worker struct gl_program *gl_prog,
1028*61046927SAndroid Build Coastguard Worker struct gl_shader **shader_list,
1029*61046927SAndroid Build Coastguard Worker unsigned num_shaders)
1030*61046927SAndroid Build Coastguard Worker {
1031*61046927SAndroid Build Coastguard Worker if (gl_prog->info.stage != MESA_SHADER_TESS_CTRL)
1032*61046927SAndroid Build Coastguard Worker return;
1033*61046927SAndroid Build Coastguard Worker
1034*61046927SAndroid Build Coastguard Worker gl_prog->info.tess.tcs_vertices_out = 0;
1035*61046927SAndroid Build Coastguard Worker
1036*61046927SAndroid Build Coastguard Worker /* From the GLSL 4.0 spec (chapter 4.3.8.2):
1037*61046927SAndroid Build Coastguard Worker *
1038*61046927SAndroid Build Coastguard Worker * "All tessellation control shader layout declarations in a program
1039*61046927SAndroid Build Coastguard Worker * must specify the same output patch vertex count. There must be at
1040*61046927SAndroid Build Coastguard Worker * least one layout qualifier specifying an output patch vertex count
1041*61046927SAndroid Build Coastguard Worker * in any program containing tessellation control shaders; however,
1042*61046927SAndroid Build Coastguard Worker * such a declaration is not required in all tessellation control
1043*61046927SAndroid Build Coastguard Worker * shaders."
1044*61046927SAndroid Build Coastguard Worker */
1045*61046927SAndroid Build Coastguard Worker
1046*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_shaders; i++) {
1047*61046927SAndroid Build Coastguard Worker struct gl_shader *shader = shader_list[i];
1048*61046927SAndroid Build Coastguard Worker
1049*61046927SAndroid Build Coastguard Worker if (shader->info.TessCtrl.VerticesOut != 0) {
1050*61046927SAndroid Build Coastguard Worker if (gl_prog->info.tess.tcs_vertices_out != 0 &&
1051*61046927SAndroid Build Coastguard Worker gl_prog->info.tess.tcs_vertices_out !=
1052*61046927SAndroid Build Coastguard Worker (unsigned) shader->info.TessCtrl.VerticesOut) {
1053*61046927SAndroid Build Coastguard Worker linker_error(prog, "tessellation control shader defined with "
1054*61046927SAndroid Build Coastguard Worker "conflicting output vertex count (%d and %d)\n",
1055*61046927SAndroid Build Coastguard Worker gl_prog->info.tess.tcs_vertices_out,
1056*61046927SAndroid Build Coastguard Worker shader->info.TessCtrl.VerticesOut);
1057*61046927SAndroid Build Coastguard Worker return;
1058*61046927SAndroid Build Coastguard Worker }
1059*61046927SAndroid Build Coastguard Worker gl_prog->info.tess.tcs_vertices_out =
1060*61046927SAndroid Build Coastguard Worker shader->info.TessCtrl.VerticesOut;
1061*61046927SAndroid Build Coastguard Worker }
1062*61046927SAndroid Build Coastguard Worker }
1063*61046927SAndroid Build Coastguard Worker
1064*61046927SAndroid Build Coastguard Worker /* Just do the intrastage -> interstage propagation right now,
1065*61046927SAndroid Build Coastguard Worker * since we already know we're in the right type of shader program
1066*61046927SAndroid Build Coastguard Worker * for doing it.
1067*61046927SAndroid Build Coastguard Worker */
1068*61046927SAndroid Build Coastguard Worker if (gl_prog->info.tess.tcs_vertices_out == 0) {
1069*61046927SAndroid Build Coastguard Worker linker_error(prog, "tessellation control shader didn't declare "
1070*61046927SAndroid Build Coastguard Worker "vertices out layout qualifier\n");
1071*61046927SAndroid Build Coastguard Worker return;
1072*61046927SAndroid Build Coastguard Worker }
1073*61046927SAndroid Build Coastguard Worker }
1074*61046927SAndroid Build Coastguard Worker
1075*61046927SAndroid Build Coastguard Worker
1076*61046927SAndroid Build Coastguard Worker /**
1077*61046927SAndroid Build Coastguard Worker * Performs the cross-validation of tessellation evaluation shader
1078*61046927SAndroid Build Coastguard Worker * primitive type, vertex spacing, ordering and point_mode layout qualifiers
1079*61046927SAndroid Build Coastguard Worker * for the attached tessellation evaluation shaders, and propagates them
1080*61046927SAndroid Build Coastguard Worker * to the linked TES and linked shader program.
1081*61046927SAndroid Build Coastguard Worker */
1082*61046927SAndroid Build Coastguard Worker static void
link_tes_in_layout_qualifiers(struct gl_shader_program * prog,struct gl_program * gl_prog,struct gl_shader ** shader_list,unsigned num_shaders)1083*61046927SAndroid Build Coastguard Worker link_tes_in_layout_qualifiers(struct gl_shader_program *prog,
1084*61046927SAndroid Build Coastguard Worker struct gl_program *gl_prog,
1085*61046927SAndroid Build Coastguard Worker struct gl_shader **shader_list,
1086*61046927SAndroid Build Coastguard Worker unsigned num_shaders)
1087*61046927SAndroid Build Coastguard Worker {
1088*61046927SAndroid Build Coastguard Worker if (gl_prog->info.stage != MESA_SHADER_TESS_EVAL)
1089*61046927SAndroid Build Coastguard Worker return;
1090*61046927SAndroid Build Coastguard Worker
1091*61046927SAndroid Build Coastguard Worker int point_mode = -1;
1092*61046927SAndroid Build Coastguard Worker unsigned vertex_order = 0;
1093*61046927SAndroid Build Coastguard Worker
1094*61046927SAndroid Build Coastguard Worker gl_prog->info.tess._primitive_mode = TESS_PRIMITIVE_UNSPECIFIED;
1095*61046927SAndroid Build Coastguard Worker gl_prog->info.tess.spacing = TESS_SPACING_UNSPECIFIED;
1096*61046927SAndroid Build Coastguard Worker
1097*61046927SAndroid Build Coastguard Worker /* From the GLSL 4.0 spec (chapter 4.3.8.1):
1098*61046927SAndroid Build Coastguard Worker *
1099*61046927SAndroid Build Coastguard Worker * "At least one tessellation evaluation shader (compilation unit) in
1100*61046927SAndroid Build Coastguard Worker * a program must declare a primitive mode in its input layout.
1101*61046927SAndroid Build Coastguard Worker * Declaration vertex spacing, ordering, and point mode identifiers is
1102*61046927SAndroid Build Coastguard Worker * optional. It is not required that all tessellation evaluation
1103*61046927SAndroid Build Coastguard Worker * shaders in a program declare a primitive mode. If spacing or
1104*61046927SAndroid Build Coastguard Worker * vertex ordering declarations are omitted, the tessellation
1105*61046927SAndroid Build Coastguard Worker * primitive generator will use equal spacing or counter-clockwise
1106*61046927SAndroid Build Coastguard Worker * vertex ordering, respectively. If a point mode declaration is
1107*61046927SAndroid Build Coastguard Worker * omitted, the tessellation primitive generator will produce lines or
1108*61046927SAndroid Build Coastguard Worker * triangles according to the primitive mode."
1109*61046927SAndroid Build Coastguard Worker */
1110*61046927SAndroid Build Coastguard Worker
1111*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_shaders; i++) {
1112*61046927SAndroid Build Coastguard Worker struct gl_shader *shader = shader_list[i];
1113*61046927SAndroid Build Coastguard Worker
1114*61046927SAndroid Build Coastguard Worker if (shader->info.TessEval._PrimitiveMode != TESS_PRIMITIVE_UNSPECIFIED) {
1115*61046927SAndroid Build Coastguard Worker if (gl_prog->info.tess._primitive_mode != TESS_PRIMITIVE_UNSPECIFIED &&
1116*61046927SAndroid Build Coastguard Worker gl_prog->info.tess._primitive_mode !=
1117*61046927SAndroid Build Coastguard Worker shader->info.TessEval._PrimitiveMode) {
1118*61046927SAndroid Build Coastguard Worker linker_error(prog, "tessellation evaluation shader defined with "
1119*61046927SAndroid Build Coastguard Worker "conflicting input primitive modes.\n");
1120*61046927SAndroid Build Coastguard Worker return;
1121*61046927SAndroid Build Coastguard Worker }
1122*61046927SAndroid Build Coastguard Worker gl_prog->info.tess._primitive_mode =
1123*61046927SAndroid Build Coastguard Worker shader->info.TessEval._PrimitiveMode;
1124*61046927SAndroid Build Coastguard Worker }
1125*61046927SAndroid Build Coastguard Worker
1126*61046927SAndroid Build Coastguard Worker if (shader->info.TessEval.Spacing != 0) {
1127*61046927SAndroid Build Coastguard Worker if (gl_prog->info.tess.spacing != 0 && gl_prog->info.tess.spacing !=
1128*61046927SAndroid Build Coastguard Worker shader->info.TessEval.Spacing) {
1129*61046927SAndroid Build Coastguard Worker linker_error(prog, "tessellation evaluation shader defined with "
1130*61046927SAndroid Build Coastguard Worker "conflicting vertex spacing.\n");
1131*61046927SAndroid Build Coastguard Worker return;
1132*61046927SAndroid Build Coastguard Worker }
1133*61046927SAndroid Build Coastguard Worker gl_prog->info.tess.spacing = shader->info.TessEval.Spacing;
1134*61046927SAndroid Build Coastguard Worker }
1135*61046927SAndroid Build Coastguard Worker
1136*61046927SAndroid Build Coastguard Worker if (shader->info.TessEval.VertexOrder != 0) {
1137*61046927SAndroid Build Coastguard Worker if (vertex_order != 0 &&
1138*61046927SAndroid Build Coastguard Worker vertex_order != shader->info.TessEval.VertexOrder) {
1139*61046927SAndroid Build Coastguard Worker linker_error(prog, "tessellation evaluation shader defined with "
1140*61046927SAndroid Build Coastguard Worker "conflicting ordering.\n");
1141*61046927SAndroid Build Coastguard Worker return;
1142*61046927SAndroid Build Coastguard Worker }
1143*61046927SAndroid Build Coastguard Worker vertex_order = shader->info.TessEval.VertexOrder;
1144*61046927SAndroid Build Coastguard Worker }
1145*61046927SAndroid Build Coastguard Worker
1146*61046927SAndroid Build Coastguard Worker if (shader->info.TessEval.PointMode != -1) {
1147*61046927SAndroid Build Coastguard Worker if (point_mode != -1 &&
1148*61046927SAndroid Build Coastguard Worker point_mode != shader->info.TessEval.PointMode) {
1149*61046927SAndroid Build Coastguard Worker linker_error(prog, "tessellation evaluation shader defined with "
1150*61046927SAndroid Build Coastguard Worker "conflicting point modes.\n");
1151*61046927SAndroid Build Coastguard Worker return;
1152*61046927SAndroid Build Coastguard Worker }
1153*61046927SAndroid Build Coastguard Worker point_mode = shader->info.TessEval.PointMode;
1154*61046927SAndroid Build Coastguard Worker }
1155*61046927SAndroid Build Coastguard Worker
1156*61046927SAndroid Build Coastguard Worker }
1157*61046927SAndroid Build Coastguard Worker
1158*61046927SAndroid Build Coastguard Worker /* Just do the intrastage -> interstage propagation right now,
1159*61046927SAndroid Build Coastguard Worker * since we already know we're in the right type of shader program
1160*61046927SAndroid Build Coastguard Worker * for doing it.
1161*61046927SAndroid Build Coastguard Worker */
1162*61046927SAndroid Build Coastguard Worker if (gl_prog->info.tess._primitive_mode == TESS_PRIMITIVE_UNSPECIFIED) {
1163*61046927SAndroid Build Coastguard Worker linker_error(prog,
1164*61046927SAndroid Build Coastguard Worker "tessellation evaluation shader didn't declare input "
1165*61046927SAndroid Build Coastguard Worker "primitive modes.\n");
1166*61046927SAndroid Build Coastguard Worker return;
1167*61046927SAndroid Build Coastguard Worker }
1168*61046927SAndroid Build Coastguard Worker
1169*61046927SAndroid Build Coastguard Worker if (gl_prog->info.tess.spacing == TESS_SPACING_UNSPECIFIED)
1170*61046927SAndroid Build Coastguard Worker gl_prog->info.tess.spacing = TESS_SPACING_EQUAL;
1171*61046927SAndroid Build Coastguard Worker
1172*61046927SAndroid Build Coastguard Worker if (vertex_order == 0 || vertex_order == GL_CCW)
1173*61046927SAndroid Build Coastguard Worker gl_prog->info.tess.ccw = true;
1174*61046927SAndroid Build Coastguard Worker else
1175*61046927SAndroid Build Coastguard Worker gl_prog->info.tess.ccw = false;
1176*61046927SAndroid Build Coastguard Worker
1177*61046927SAndroid Build Coastguard Worker
1178*61046927SAndroid Build Coastguard Worker if (point_mode == -1 || point_mode == GL_FALSE)
1179*61046927SAndroid Build Coastguard Worker gl_prog->info.tess.point_mode = false;
1180*61046927SAndroid Build Coastguard Worker else
1181*61046927SAndroid Build Coastguard Worker gl_prog->info.tess.point_mode = true;
1182*61046927SAndroid Build Coastguard Worker }
1183*61046927SAndroid Build Coastguard Worker
1184*61046927SAndroid Build Coastguard Worker
1185*61046927SAndroid Build Coastguard Worker /**
1186*61046927SAndroid Build Coastguard Worker * Performs the cross-validation of layout qualifiers specified in
1187*61046927SAndroid Build Coastguard Worker * redeclaration of gl_FragCoord for the attached fragment shaders,
1188*61046927SAndroid Build Coastguard Worker * and propagates them to the linked FS and linked shader program.
1189*61046927SAndroid Build Coastguard Worker */
1190*61046927SAndroid Build Coastguard Worker static void
link_fs_inout_layout_qualifiers(struct gl_shader_program * prog,struct gl_linked_shader * linked_shader,struct gl_shader ** shader_list,unsigned num_shaders,bool arb_fragment_coord_conventions_enable)1191*61046927SAndroid Build Coastguard Worker link_fs_inout_layout_qualifiers(struct gl_shader_program *prog,
1192*61046927SAndroid Build Coastguard Worker struct gl_linked_shader *linked_shader,
1193*61046927SAndroid Build Coastguard Worker struct gl_shader **shader_list,
1194*61046927SAndroid Build Coastguard Worker unsigned num_shaders,
1195*61046927SAndroid Build Coastguard Worker bool arb_fragment_coord_conventions_enable)
1196*61046927SAndroid Build Coastguard Worker {
1197*61046927SAndroid Build Coastguard Worker bool redeclares_gl_fragcoord = false;
1198*61046927SAndroid Build Coastguard Worker bool uses_gl_fragcoord = false;
1199*61046927SAndroid Build Coastguard Worker bool origin_upper_left = false;
1200*61046927SAndroid Build Coastguard Worker bool pixel_center_integer = false;
1201*61046927SAndroid Build Coastguard Worker
1202*61046927SAndroid Build Coastguard Worker if (linked_shader->Stage != MESA_SHADER_FRAGMENT ||
1203*61046927SAndroid Build Coastguard Worker (prog->GLSL_Version < 150 && !arb_fragment_coord_conventions_enable))
1204*61046927SAndroid Build Coastguard Worker return;
1205*61046927SAndroid Build Coastguard Worker
1206*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_shaders; i++) {
1207*61046927SAndroid Build Coastguard Worker struct gl_shader *shader = shader_list[i];
1208*61046927SAndroid Build Coastguard Worker /* From the GLSL 1.50 spec, page 39:
1209*61046927SAndroid Build Coastguard Worker *
1210*61046927SAndroid Build Coastguard Worker * "If gl_FragCoord is redeclared in any fragment shader in a program,
1211*61046927SAndroid Build Coastguard Worker * it must be redeclared in all the fragment shaders in that program
1212*61046927SAndroid Build Coastguard Worker * that have a static use gl_FragCoord."
1213*61046927SAndroid Build Coastguard Worker */
1214*61046927SAndroid Build Coastguard Worker if ((redeclares_gl_fragcoord && !shader->redeclares_gl_fragcoord &&
1215*61046927SAndroid Build Coastguard Worker shader->uses_gl_fragcoord)
1216*61046927SAndroid Build Coastguard Worker || (shader->redeclares_gl_fragcoord && !redeclares_gl_fragcoord &&
1217*61046927SAndroid Build Coastguard Worker uses_gl_fragcoord)) {
1218*61046927SAndroid Build Coastguard Worker linker_error(prog, "fragment shader defined with conflicting "
1219*61046927SAndroid Build Coastguard Worker "layout qualifiers for gl_FragCoord\n");
1220*61046927SAndroid Build Coastguard Worker }
1221*61046927SAndroid Build Coastguard Worker
1222*61046927SAndroid Build Coastguard Worker /* From the GLSL 1.50 spec, page 39:
1223*61046927SAndroid Build Coastguard Worker *
1224*61046927SAndroid Build Coastguard Worker * "All redeclarations of gl_FragCoord in all fragment shaders in a
1225*61046927SAndroid Build Coastguard Worker * single program must have the same set of qualifiers."
1226*61046927SAndroid Build Coastguard Worker */
1227*61046927SAndroid Build Coastguard Worker if (redeclares_gl_fragcoord && shader->redeclares_gl_fragcoord &&
1228*61046927SAndroid Build Coastguard Worker (shader->origin_upper_left != origin_upper_left ||
1229*61046927SAndroid Build Coastguard Worker shader->pixel_center_integer != pixel_center_integer)) {
1230*61046927SAndroid Build Coastguard Worker linker_error(prog, "fragment shader defined with conflicting "
1231*61046927SAndroid Build Coastguard Worker "layout qualifiers for gl_FragCoord\n");
1232*61046927SAndroid Build Coastguard Worker }
1233*61046927SAndroid Build Coastguard Worker
1234*61046927SAndroid Build Coastguard Worker /* Update the linked shader state. Note that uses_gl_fragcoord should
1235*61046927SAndroid Build Coastguard Worker * accumulate the results. The other values should replace. If there
1236*61046927SAndroid Build Coastguard Worker * are multiple redeclarations, all the fields except uses_gl_fragcoord
1237*61046927SAndroid Build Coastguard Worker * are already known to be the same.
1238*61046927SAndroid Build Coastguard Worker */
1239*61046927SAndroid Build Coastguard Worker if (shader->redeclares_gl_fragcoord || shader->uses_gl_fragcoord) {
1240*61046927SAndroid Build Coastguard Worker redeclares_gl_fragcoord = shader->redeclares_gl_fragcoord;
1241*61046927SAndroid Build Coastguard Worker uses_gl_fragcoord |= shader->uses_gl_fragcoord;
1242*61046927SAndroid Build Coastguard Worker origin_upper_left = shader->origin_upper_left;
1243*61046927SAndroid Build Coastguard Worker pixel_center_integer = shader->pixel_center_integer;
1244*61046927SAndroid Build Coastguard Worker }
1245*61046927SAndroid Build Coastguard Worker
1246*61046927SAndroid Build Coastguard Worker linked_shader->Program->info.fs.early_fragment_tests |=
1247*61046927SAndroid Build Coastguard Worker shader->EarlyFragmentTests || shader->PostDepthCoverage;
1248*61046927SAndroid Build Coastguard Worker linked_shader->Program->info.fs.inner_coverage |= shader->InnerCoverage;
1249*61046927SAndroid Build Coastguard Worker linked_shader->Program->info.fs.post_depth_coverage |=
1250*61046927SAndroid Build Coastguard Worker shader->PostDepthCoverage;
1251*61046927SAndroid Build Coastguard Worker linked_shader->Program->info.fs.pixel_interlock_ordered |=
1252*61046927SAndroid Build Coastguard Worker shader->PixelInterlockOrdered;
1253*61046927SAndroid Build Coastguard Worker linked_shader->Program->info.fs.pixel_interlock_unordered |=
1254*61046927SAndroid Build Coastguard Worker shader->PixelInterlockUnordered;
1255*61046927SAndroid Build Coastguard Worker linked_shader->Program->info.fs.sample_interlock_ordered |=
1256*61046927SAndroid Build Coastguard Worker shader->SampleInterlockOrdered;
1257*61046927SAndroid Build Coastguard Worker linked_shader->Program->info.fs.sample_interlock_unordered |=
1258*61046927SAndroid Build Coastguard Worker shader->SampleInterlockUnordered;
1259*61046927SAndroid Build Coastguard Worker linked_shader->Program->info.fs.advanced_blend_modes |= shader->BlendSupport;
1260*61046927SAndroid Build Coastguard Worker }
1261*61046927SAndroid Build Coastguard Worker
1262*61046927SAndroid Build Coastguard Worker linked_shader->Program->info.fs.pixel_center_integer = pixel_center_integer;
1263*61046927SAndroid Build Coastguard Worker linked_shader->Program->info.fs.origin_upper_left = origin_upper_left;
1264*61046927SAndroid Build Coastguard Worker }
1265*61046927SAndroid Build Coastguard Worker
1266*61046927SAndroid Build Coastguard Worker /**
1267*61046927SAndroid Build Coastguard Worker * Performs the cross-validation of geometry shader max_vertices and
1268*61046927SAndroid Build Coastguard Worker * primitive type layout qualifiers for the attached geometry shaders,
1269*61046927SAndroid Build Coastguard Worker * and propagates them to the linked GS and linked shader program.
1270*61046927SAndroid Build Coastguard Worker */
1271*61046927SAndroid Build Coastguard Worker static void
link_gs_inout_layout_qualifiers(struct gl_shader_program * prog,struct gl_program * gl_prog,struct gl_shader ** shader_list,unsigned num_shaders)1272*61046927SAndroid Build Coastguard Worker link_gs_inout_layout_qualifiers(struct gl_shader_program *prog,
1273*61046927SAndroid Build Coastguard Worker struct gl_program *gl_prog,
1274*61046927SAndroid Build Coastguard Worker struct gl_shader **shader_list,
1275*61046927SAndroid Build Coastguard Worker unsigned num_shaders)
1276*61046927SAndroid Build Coastguard Worker {
1277*61046927SAndroid Build Coastguard Worker /* No in/out qualifiers defined for anything but GLSL 1.50+
1278*61046927SAndroid Build Coastguard Worker * geometry shaders so far.
1279*61046927SAndroid Build Coastguard Worker */
1280*61046927SAndroid Build Coastguard Worker if (gl_prog->info.stage != MESA_SHADER_GEOMETRY || prog->GLSL_Version < 150)
1281*61046927SAndroid Build Coastguard Worker return;
1282*61046927SAndroid Build Coastguard Worker
1283*61046927SAndroid Build Coastguard Worker int vertices_out = -1;
1284*61046927SAndroid Build Coastguard Worker
1285*61046927SAndroid Build Coastguard Worker gl_prog->info.gs.invocations = 0;
1286*61046927SAndroid Build Coastguard Worker gl_prog->info.gs.input_primitive = MESA_PRIM_UNKNOWN;
1287*61046927SAndroid Build Coastguard Worker gl_prog->info.gs.output_primitive = MESA_PRIM_UNKNOWN;
1288*61046927SAndroid Build Coastguard Worker
1289*61046927SAndroid Build Coastguard Worker /* From the GLSL 1.50 spec, page 46:
1290*61046927SAndroid Build Coastguard Worker *
1291*61046927SAndroid Build Coastguard Worker * "All geometry shader output layout declarations in a program
1292*61046927SAndroid Build Coastguard Worker * must declare the same layout and same value for
1293*61046927SAndroid Build Coastguard Worker * max_vertices. There must be at least one geometry output
1294*61046927SAndroid Build Coastguard Worker * layout declaration somewhere in a program, but not all
1295*61046927SAndroid Build Coastguard Worker * geometry shaders (compilation units) are required to
1296*61046927SAndroid Build Coastguard Worker * declare it."
1297*61046927SAndroid Build Coastguard Worker */
1298*61046927SAndroid Build Coastguard Worker
1299*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_shaders; i++) {
1300*61046927SAndroid Build Coastguard Worker struct gl_shader *shader = shader_list[i];
1301*61046927SAndroid Build Coastguard Worker
1302*61046927SAndroid Build Coastguard Worker if (shader->info.Geom.InputType != MESA_PRIM_UNKNOWN) {
1303*61046927SAndroid Build Coastguard Worker if (gl_prog->info.gs.input_primitive != MESA_PRIM_UNKNOWN &&
1304*61046927SAndroid Build Coastguard Worker gl_prog->info.gs.input_primitive !=
1305*61046927SAndroid Build Coastguard Worker shader->info.Geom.InputType) {
1306*61046927SAndroid Build Coastguard Worker linker_error(prog, "geometry shader defined with conflicting "
1307*61046927SAndroid Build Coastguard Worker "input types\n");
1308*61046927SAndroid Build Coastguard Worker return;
1309*61046927SAndroid Build Coastguard Worker }
1310*61046927SAndroid Build Coastguard Worker gl_prog->info.gs.input_primitive = (enum mesa_prim)shader->info.Geom.InputType;
1311*61046927SAndroid Build Coastguard Worker }
1312*61046927SAndroid Build Coastguard Worker
1313*61046927SAndroid Build Coastguard Worker if (shader->info.Geom.OutputType != MESA_PRIM_UNKNOWN) {
1314*61046927SAndroid Build Coastguard Worker if (gl_prog->info.gs.output_primitive != MESA_PRIM_UNKNOWN &&
1315*61046927SAndroid Build Coastguard Worker gl_prog->info.gs.output_primitive !=
1316*61046927SAndroid Build Coastguard Worker shader->info.Geom.OutputType) {
1317*61046927SAndroid Build Coastguard Worker linker_error(prog, "geometry shader defined with conflicting "
1318*61046927SAndroid Build Coastguard Worker "output types\n");
1319*61046927SAndroid Build Coastguard Worker return;
1320*61046927SAndroid Build Coastguard Worker }
1321*61046927SAndroid Build Coastguard Worker gl_prog->info.gs.output_primitive = (enum mesa_prim)shader->info.Geom.OutputType;
1322*61046927SAndroid Build Coastguard Worker }
1323*61046927SAndroid Build Coastguard Worker
1324*61046927SAndroid Build Coastguard Worker if (shader->info.Geom.VerticesOut != -1) {
1325*61046927SAndroid Build Coastguard Worker if (vertices_out != -1 &&
1326*61046927SAndroid Build Coastguard Worker vertices_out != shader->info.Geom.VerticesOut) {
1327*61046927SAndroid Build Coastguard Worker linker_error(prog, "geometry shader defined with conflicting "
1328*61046927SAndroid Build Coastguard Worker "output vertex count (%d and %d)\n",
1329*61046927SAndroid Build Coastguard Worker vertices_out, shader->info.Geom.VerticesOut);
1330*61046927SAndroid Build Coastguard Worker return;
1331*61046927SAndroid Build Coastguard Worker }
1332*61046927SAndroid Build Coastguard Worker vertices_out = shader->info.Geom.VerticesOut;
1333*61046927SAndroid Build Coastguard Worker }
1334*61046927SAndroid Build Coastguard Worker
1335*61046927SAndroid Build Coastguard Worker if (shader->info.Geom.Invocations != 0) {
1336*61046927SAndroid Build Coastguard Worker if (gl_prog->info.gs.invocations != 0 &&
1337*61046927SAndroid Build Coastguard Worker gl_prog->info.gs.invocations !=
1338*61046927SAndroid Build Coastguard Worker (unsigned) shader->info.Geom.Invocations) {
1339*61046927SAndroid Build Coastguard Worker linker_error(prog, "geometry shader defined with conflicting "
1340*61046927SAndroid Build Coastguard Worker "invocation count (%d and %d)\n",
1341*61046927SAndroid Build Coastguard Worker gl_prog->info.gs.invocations,
1342*61046927SAndroid Build Coastguard Worker shader->info.Geom.Invocations);
1343*61046927SAndroid Build Coastguard Worker return;
1344*61046927SAndroid Build Coastguard Worker }
1345*61046927SAndroid Build Coastguard Worker gl_prog->info.gs.invocations = shader->info.Geom.Invocations;
1346*61046927SAndroid Build Coastguard Worker }
1347*61046927SAndroid Build Coastguard Worker }
1348*61046927SAndroid Build Coastguard Worker
1349*61046927SAndroid Build Coastguard Worker /* Just do the intrastage -> interstage propagation right now,
1350*61046927SAndroid Build Coastguard Worker * since we already know we're in the right type of shader program
1351*61046927SAndroid Build Coastguard Worker * for doing it.
1352*61046927SAndroid Build Coastguard Worker */
1353*61046927SAndroid Build Coastguard Worker if (gl_prog->info.gs.input_primitive == MESA_PRIM_UNKNOWN) {
1354*61046927SAndroid Build Coastguard Worker linker_error(prog,
1355*61046927SAndroid Build Coastguard Worker "geometry shader didn't declare primitive input type\n");
1356*61046927SAndroid Build Coastguard Worker return;
1357*61046927SAndroid Build Coastguard Worker }
1358*61046927SAndroid Build Coastguard Worker
1359*61046927SAndroid Build Coastguard Worker if (gl_prog->info.gs.output_primitive == MESA_PRIM_UNKNOWN) {
1360*61046927SAndroid Build Coastguard Worker linker_error(prog,
1361*61046927SAndroid Build Coastguard Worker "geometry shader didn't declare primitive output type\n");
1362*61046927SAndroid Build Coastguard Worker return;
1363*61046927SAndroid Build Coastguard Worker }
1364*61046927SAndroid Build Coastguard Worker
1365*61046927SAndroid Build Coastguard Worker if (vertices_out == -1) {
1366*61046927SAndroid Build Coastguard Worker linker_error(prog,
1367*61046927SAndroid Build Coastguard Worker "geometry shader didn't declare max_vertices\n");
1368*61046927SAndroid Build Coastguard Worker return;
1369*61046927SAndroid Build Coastguard Worker } else {
1370*61046927SAndroid Build Coastguard Worker gl_prog->info.gs.vertices_out = vertices_out;
1371*61046927SAndroid Build Coastguard Worker }
1372*61046927SAndroid Build Coastguard Worker
1373*61046927SAndroid Build Coastguard Worker if (gl_prog->info.gs.invocations == 0)
1374*61046927SAndroid Build Coastguard Worker gl_prog->info.gs.invocations = 1;
1375*61046927SAndroid Build Coastguard Worker }
1376*61046927SAndroid Build Coastguard Worker
1377*61046927SAndroid Build Coastguard Worker
1378*61046927SAndroid Build Coastguard Worker /**
1379*61046927SAndroid Build Coastguard Worker * Perform cross-validation of compute shader local_size_{x,y,z} layout and
1380*61046927SAndroid Build Coastguard Worker * derivative arrangement qualifiers for the attached compute shaders, and
1381*61046927SAndroid Build Coastguard Worker * propagate them to the linked CS and linked shader program.
1382*61046927SAndroid Build Coastguard Worker */
1383*61046927SAndroid Build Coastguard Worker static void
link_cs_input_layout_qualifiers(struct gl_shader_program * prog,struct gl_program * gl_prog,struct gl_shader ** shader_list,unsigned num_shaders)1384*61046927SAndroid Build Coastguard Worker link_cs_input_layout_qualifiers(struct gl_shader_program *prog,
1385*61046927SAndroid Build Coastguard Worker struct gl_program *gl_prog,
1386*61046927SAndroid Build Coastguard Worker struct gl_shader **shader_list,
1387*61046927SAndroid Build Coastguard Worker unsigned num_shaders)
1388*61046927SAndroid Build Coastguard Worker {
1389*61046927SAndroid Build Coastguard Worker /* This function is called for all shader stages, but it only has an effect
1390*61046927SAndroid Build Coastguard Worker * for compute shaders.
1391*61046927SAndroid Build Coastguard Worker */
1392*61046927SAndroid Build Coastguard Worker if (gl_prog->info.stage != MESA_SHADER_COMPUTE)
1393*61046927SAndroid Build Coastguard Worker return;
1394*61046927SAndroid Build Coastguard Worker
1395*61046927SAndroid Build Coastguard Worker for (int i = 0; i < 3; i++)
1396*61046927SAndroid Build Coastguard Worker gl_prog->info.workgroup_size[i] = 0;
1397*61046927SAndroid Build Coastguard Worker
1398*61046927SAndroid Build Coastguard Worker gl_prog->info.workgroup_size_variable = false;
1399*61046927SAndroid Build Coastguard Worker
1400*61046927SAndroid Build Coastguard Worker gl_prog->info.derivative_group = DERIVATIVE_GROUP_NONE;
1401*61046927SAndroid Build Coastguard Worker
1402*61046927SAndroid Build Coastguard Worker /* From the ARB_compute_shader spec, in the section describing local size
1403*61046927SAndroid Build Coastguard Worker * declarations:
1404*61046927SAndroid Build Coastguard Worker *
1405*61046927SAndroid Build Coastguard Worker * If multiple compute shaders attached to a single program object
1406*61046927SAndroid Build Coastguard Worker * declare local work-group size, the declarations must be identical;
1407*61046927SAndroid Build Coastguard Worker * otherwise a link-time error results. Furthermore, if a program
1408*61046927SAndroid Build Coastguard Worker * object contains any compute shaders, at least one must contain an
1409*61046927SAndroid Build Coastguard Worker * input layout qualifier specifying the local work sizes of the
1410*61046927SAndroid Build Coastguard Worker * program, or a link-time error will occur.
1411*61046927SAndroid Build Coastguard Worker */
1412*61046927SAndroid Build Coastguard Worker for (unsigned sh = 0; sh < num_shaders; sh++) {
1413*61046927SAndroid Build Coastguard Worker struct gl_shader *shader = shader_list[sh];
1414*61046927SAndroid Build Coastguard Worker
1415*61046927SAndroid Build Coastguard Worker if (shader->info.Comp.LocalSize[0] != 0) {
1416*61046927SAndroid Build Coastguard Worker if (gl_prog->info.workgroup_size[0] != 0) {
1417*61046927SAndroid Build Coastguard Worker for (int i = 0; i < 3; i++) {
1418*61046927SAndroid Build Coastguard Worker if (gl_prog->info.workgroup_size[i] !=
1419*61046927SAndroid Build Coastguard Worker shader->info.Comp.LocalSize[i]) {
1420*61046927SAndroid Build Coastguard Worker linker_error(prog, "compute shader defined with conflicting "
1421*61046927SAndroid Build Coastguard Worker "local sizes\n");
1422*61046927SAndroid Build Coastguard Worker return;
1423*61046927SAndroid Build Coastguard Worker }
1424*61046927SAndroid Build Coastguard Worker }
1425*61046927SAndroid Build Coastguard Worker }
1426*61046927SAndroid Build Coastguard Worker for (int i = 0; i < 3; i++) {
1427*61046927SAndroid Build Coastguard Worker gl_prog->info.workgroup_size[i] =
1428*61046927SAndroid Build Coastguard Worker shader->info.Comp.LocalSize[i];
1429*61046927SAndroid Build Coastguard Worker }
1430*61046927SAndroid Build Coastguard Worker } else if (shader->info.Comp.LocalSizeVariable) {
1431*61046927SAndroid Build Coastguard Worker if (gl_prog->info.workgroup_size[0] != 0) {
1432*61046927SAndroid Build Coastguard Worker /* The ARB_compute_variable_group_size spec says:
1433*61046927SAndroid Build Coastguard Worker *
1434*61046927SAndroid Build Coastguard Worker * If one compute shader attached to a program declares a
1435*61046927SAndroid Build Coastguard Worker * variable local group size and a second compute shader
1436*61046927SAndroid Build Coastguard Worker * attached to the same program declares a fixed local group
1437*61046927SAndroid Build Coastguard Worker * size, a link-time error results.
1438*61046927SAndroid Build Coastguard Worker */
1439*61046927SAndroid Build Coastguard Worker linker_error(prog, "compute shader defined with both fixed and "
1440*61046927SAndroid Build Coastguard Worker "variable local group size\n");
1441*61046927SAndroid Build Coastguard Worker return;
1442*61046927SAndroid Build Coastguard Worker }
1443*61046927SAndroid Build Coastguard Worker gl_prog->info.workgroup_size_variable = true;
1444*61046927SAndroid Build Coastguard Worker }
1445*61046927SAndroid Build Coastguard Worker
1446*61046927SAndroid Build Coastguard Worker enum gl_derivative_group group = shader->info.Comp.DerivativeGroup;
1447*61046927SAndroid Build Coastguard Worker if (group != DERIVATIVE_GROUP_NONE) {
1448*61046927SAndroid Build Coastguard Worker if (gl_prog->info.derivative_group != DERIVATIVE_GROUP_NONE &&
1449*61046927SAndroid Build Coastguard Worker gl_prog->info.derivative_group != group) {
1450*61046927SAndroid Build Coastguard Worker linker_error(prog, "compute shader defined with conflicting "
1451*61046927SAndroid Build Coastguard Worker "derivative groups\n");
1452*61046927SAndroid Build Coastguard Worker return;
1453*61046927SAndroid Build Coastguard Worker }
1454*61046927SAndroid Build Coastguard Worker gl_prog->info.derivative_group = group;
1455*61046927SAndroid Build Coastguard Worker }
1456*61046927SAndroid Build Coastguard Worker }
1457*61046927SAndroid Build Coastguard Worker
1458*61046927SAndroid Build Coastguard Worker /* Just do the intrastage -> interstage propagation right now,
1459*61046927SAndroid Build Coastguard Worker * since we already know we're in the right type of shader program
1460*61046927SAndroid Build Coastguard Worker * for doing it.
1461*61046927SAndroid Build Coastguard Worker */
1462*61046927SAndroid Build Coastguard Worker if (gl_prog->info.workgroup_size[0] == 0 &&
1463*61046927SAndroid Build Coastguard Worker !gl_prog->info.workgroup_size_variable) {
1464*61046927SAndroid Build Coastguard Worker linker_error(prog, "compute shader must contain a fixed or a variable "
1465*61046927SAndroid Build Coastguard Worker "local group size\n");
1466*61046927SAndroid Build Coastguard Worker return;
1467*61046927SAndroid Build Coastguard Worker }
1468*61046927SAndroid Build Coastguard Worker
1469*61046927SAndroid Build Coastguard Worker if (gl_prog->info.derivative_group == DERIVATIVE_GROUP_QUADS) {
1470*61046927SAndroid Build Coastguard Worker if (gl_prog->info.workgroup_size[0] % 2 != 0) {
1471*61046927SAndroid Build Coastguard Worker linker_error(prog, "derivative_group_quadsNV must be used with a "
1472*61046927SAndroid Build Coastguard Worker "local group size whose first dimension "
1473*61046927SAndroid Build Coastguard Worker "is a multiple of 2\n");
1474*61046927SAndroid Build Coastguard Worker return;
1475*61046927SAndroid Build Coastguard Worker }
1476*61046927SAndroid Build Coastguard Worker if (gl_prog->info.workgroup_size[1] % 2 != 0) {
1477*61046927SAndroid Build Coastguard Worker linker_error(prog, "derivative_group_quadsNV must be used with a local"
1478*61046927SAndroid Build Coastguard Worker "group size whose second dimension "
1479*61046927SAndroid Build Coastguard Worker "is a multiple of 2\n");
1480*61046927SAndroid Build Coastguard Worker return;
1481*61046927SAndroid Build Coastguard Worker }
1482*61046927SAndroid Build Coastguard Worker } else if (gl_prog->info.derivative_group == DERIVATIVE_GROUP_LINEAR) {
1483*61046927SAndroid Build Coastguard Worker if ((gl_prog->info.workgroup_size[0] *
1484*61046927SAndroid Build Coastguard Worker gl_prog->info.workgroup_size[1] *
1485*61046927SAndroid Build Coastguard Worker gl_prog->info.workgroup_size[2]) % 4 != 0) {
1486*61046927SAndroid Build Coastguard Worker linker_error(prog, "derivative_group_linearNV must be used with a "
1487*61046927SAndroid Build Coastguard Worker "local group size whose total number of invocations "
1488*61046927SAndroid Build Coastguard Worker "is a multiple of 4\n");
1489*61046927SAndroid Build Coastguard Worker return;
1490*61046927SAndroid Build Coastguard Worker }
1491*61046927SAndroid Build Coastguard Worker }
1492*61046927SAndroid Build Coastguard Worker }
1493*61046927SAndroid Build Coastguard Worker
1494*61046927SAndroid Build Coastguard Worker /**
1495*61046927SAndroid Build Coastguard Worker * Link all out variables on a single stage which are not
1496*61046927SAndroid Build Coastguard Worker * directly used in a shader with the main function.
1497*61046927SAndroid Build Coastguard Worker */
1498*61046927SAndroid Build Coastguard Worker static void
link_output_variables(struct gl_linked_shader * linked_shader,struct gl_shader ** shader_list,unsigned num_shaders)1499*61046927SAndroid Build Coastguard Worker link_output_variables(struct gl_linked_shader *linked_shader,
1500*61046927SAndroid Build Coastguard Worker struct gl_shader **shader_list,
1501*61046927SAndroid Build Coastguard Worker unsigned num_shaders)
1502*61046927SAndroid Build Coastguard Worker {
1503*61046927SAndroid Build Coastguard Worker struct glsl_symbol_table *symbols = linked_shader->symbols;
1504*61046927SAndroid Build Coastguard Worker
1505*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_shaders; i++) {
1506*61046927SAndroid Build Coastguard Worker
1507*61046927SAndroid Build Coastguard Worker /* Skip shader object with main function */
1508*61046927SAndroid Build Coastguard Worker if (shader_list[i]->symbols->get_function("main"))
1509*61046927SAndroid Build Coastguard Worker continue;
1510*61046927SAndroid Build Coastguard Worker
1511*61046927SAndroid Build Coastguard Worker foreach_in_list(ir_instruction, ir, shader_list[i]->ir) {
1512*61046927SAndroid Build Coastguard Worker if (ir->ir_type != ir_type_variable)
1513*61046927SAndroid Build Coastguard Worker continue;
1514*61046927SAndroid Build Coastguard Worker
1515*61046927SAndroid Build Coastguard Worker ir_variable *var = (ir_variable *) ir;
1516*61046927SAndroid Build Coastguard Worker
1517*61046927SAndroid Build Coastguard Worker if (var->data.mode == ir_var_shader_out &&
1518*61046927SAndroid Build Coastguard Worker !symbols->get_variable(var->name)) {
1519*61046927SAndroid Build Coastguard Worker var = var->clone(linked_shader, NULL);
1520*61046927SAndroid Build Coastguard Worker symbols->add_variable(var);
1521*61046927SAndroid Build Coastguard Worker linked_shader->ir->push_head(var);
1522*61046927SAndroid Build Coastguard Worker }
1523*61046927SAndroid Build Coastguard Worker }
1524*61046927SAndroid Build Coastguard Worker }
1525*61046927SAndroid Build Coastguard Worker
1526*61046927SAndroid Build Coastguard Worker return;
1527*61046927SAndroid Build Coastguard Worker }
1528*61046927SAndroid Build Coastguard Worker
1529*61046927SAndroid Build Coastguard Worker
1530*61046927SAndroid Build Coastguard Worker /**
1531*61046927SAndroid Build Coastguard Worker * Combine a group of shaders for a single stage to generate a linked shader
1532*61046927SAndroid Build Coastguard Worker *
1533*61046927SAndroid Build Coastguard Worker * \note
1534*61046927SAndroid Build Coastguard Worker * If this function is supplied a single shader, it is cloned, and the new
1535*61046927SAndroid Build Coastguard Worker * shader is returned.
1536*61046927SAndroid Build Coastguard Worker */
1537*61046927SAndroid Build Coastguard Worker struct gl_linked_shader *
link_intrastage_shaders(void * mem_ctx,struct gl_context * ctx,struct gl_shader_program * prog,struct gl_shader ** shader_list,unsigned num_shaders,bool allow_missing_main)1538*61046927SAndroid Build Coastguard Worker link_intrastage_shaders(void *mem_ctx,
1539*61046927SAndroid Build Coastguard Worker struct gl_context *ctx,
1540*61046927SAndroid Build Coastguard Worker struct gl_shader_program *prog,
1541*61046927SAndroid Build Coastguard Worker struct gl_shader **shader_list,
1542*61046927SAndroid Build Coastguard Worker unsigned num_shaders,
1543*61046927SAndroid Build Coastguard Worker bool allow_missing_main)
1544*61046927SAndroid Build Coastguard Worker {
1545*61046927SAndroid Build Coastguard Worker bool arb_fragment_coord_conventions_enable = false;
1546*61046927SAndroid Build Coastguard Worker bool KHR_shader_subgroup_basic_enable = false;
1547*61046927SAndroid Build Coastguard Worker
1548*61046927SAndroid Build Coastguard Worker /* Check that global variables defined in multiple shaders are consistent.
1549*61046927SAndroid Build Coastguard Worker */
1550*61046927SAndroid Build Coastguard Worker glsl_symbol_table variables;
1551*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_shaders; i++) {
1552*61046927SAndroid Build Coastguard Worker if (shader_list[i] == NULL)
1553*61046927SAndroid Build Coastguard Worker continue;
1554*61046927SAndroid Build Coastguard Worker cross_validate_globals(&ctx->Const, prog, shader_list[i]->ir, &variables,
1555*61046927SAndroid Build Coastguard Worker false);
1556*61046927SAndroid Build Coastguard Worker if (shader_list[i]->ARB_fragment_coord_conventions_enable)
1557*61046927SAndroid Build Coastguard Worker arb_fragment_coord_conventions_enable = true;
1558*61046927SAndroid Build Coastguard Worker if (shader_list[i]->KHR_shader_subgroup_basic_enable)
1559*61046927SAndroid Build Coastguard Worker KHR_shader_subgroup_basic_enable = true;
1560*61046927SAndroid Build Coastguard Worker }
1561*61046927SAndroid Build Coastguard Worker
1562*61046927SAndroid Build Coastguard Worker if (!prog->data->LinkStatus)
1563*61046927SAndroid Build Coastguard Worker return NULL;
1564*61046927SAndroid Build Coastguard Worker
1565*61046927SAndroid Build Coastguard Worker /* Check that interface blocks defined in multiple shaders are consistent.
1566*61046927SAndroid Build Coastguard Worker */
1567*61046927SAndroid Build Coastguard Worker validate_intrastage_interface_blocks(prog, (const gl_shader **)shader_list,
1568*61046927SAndroid Build Coastguard Worker num_shaders);
1569*61046927SAndroid Build Coastguard Worker if (!prog->data->LinkStatus)
1570*61046927SAndroid Build Coastguard Worker return NULL;
1571*61046927SAndroid Build Coastguard Worker
1572*61046927SAndroid Build Coastguard Worker /* Check that there is only a single definition of each function signature
1573*61046927SAndroid Build Coastguard Worker * across all shaders.
1574*61046927SAndroid Build Coastguard Worker */
1575*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < (num_shaders - 1); i++) {
1576*61046927SAndroid Build Coastguard Worker foreach_in_list(ir_instruction, node, shader_list[i]->ir) {
1577*61046927SAndroid Build Coastguard Worker ir_function *const f = node->as_function();
1578*61046927SAndroid Build Coastguard Worker
1579*61046927SAndroid Build Coastguard Worker if (f == NULL)
1580*61046927SAndroid Build Coastguard Worker continue;
1581*61046927SAndroid Build Coastguard Worker
1582*61046927SAndroid Build Coastguard Worker for (unsigned j = i + 1; j < num_shaders; j++) {
1583*61046927SAndroid Build Coastguard Worker ir_function *const other =
1584*61046927SAndroid Build Coastguard Worker shader_list[j]->symbols->get_function(f->name);
1585*61046927SAndroid Build Coastguard Worker
1586*61046927SAndroid Build Coastguard Worker /* If the other shader has no function (and therefore no function
1587*61046927SAndroid Build Coastguard Worker * signatures) with the same name, skip to the next shader.
1588*61046927SAndroid Build Coastguard Worker */
1589*61046927SAndroid Build Coastguard Worker if (other == NULL)
1590*61046927SAndroid Build Coastguard Worker continue;
1591*61046927SAndroid Build Coastguard Worker
1592*61046927SAndroid Build Coastguard Worker foreach_in_list(ir_function_signature, sig, &f->signatures) {
1593*61046927SAndroid Build Coastguard Worker if (!sig->is_defined)
1594*61046927SAndroid Build Coastguard Worker continue;
1595*61046927SAndroid Build Coastguard Worker
1596*61046927SAndroid Build Coastguard Worker ir_function_signature *other_sig =
1597*61046927SAndroid Build Coastguard Worker other->exact_matching_signature(NULL, &sig->parameters);
1598*61046927SAndroid Build Coastguard Worker
1599*61046927SAndroid Build Coastguard Worker if (other_sig != NULL && other_sig->is_defined) {
1600*61046927SAndroid Build Coastguard Worker linker_error(prog, "function `%s' is multiply defined\n",
1601*61046927SAndroid Build Coastguard Worker f->name);
1602*61046927SAndroid Build Coastguard Worker return NULL;
1603*61046927SAndroid Build Coastguard Worker }
1604*61046927SAndroid Build Coastguard Worker }
1605*61046927SAndroid Build Coastguard Worker }
1606*61046927SAndroid Build Coastguard Worker }
1607*61046927SAndroid Build Coastguard Worker }
1608*61046927SAndroid Build Coastguard Worker
1609*61046927SAndroid Build Coastguard Worker /* Find the shader that defines main, and make a clone of it.
1610*61046927SAndroid Build Coastguard Worker *
1611*61046927SAndroid Build Coastguard Worker * Starting with the clone, search for undefined references. If one is
1612*61046927SAndroid Build Coastguard Worker * found, find the shader that defines it. Clone the reference and add
1613*61046927SAndroid Build Coastguard Worker * it to the shader. Repeat until there are no undefined references or
1614*61046927SAndroid Build Coastguard Worker * until a reference cannot be resolved.
1615*61046927SAndroid Build Coastguard Worker */
1616*61046927SAndroid Build Coastguard Worker gl_shader *main = NULL;
1617*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_shaders; i++) {
1618*61046927SAndroid Build Coastguard Worker if (_mesa_get_main_function_signature(shader_list[i]->symbols)) {
1619*61046927SAndroid Build Coastguard Worker main = shader_list[i];
1620*61046927SAndroid Build Coastguard Worker break;
1621*61046927SAndroid Build Coastguard Worker }
1622*61046927SAndroid Build Coastguard Worker }
1623*61046927SAndroid Build Coastguard Worker
1624*61046927SAndroid Build Coastguard Worker if (main == NULL && allow_missing_main)
1625*61046927SAndroid Build Coastguard Worker main = shader_list[0];
1626*61046927SAndroid Build Coastguard Worker
1627*61046927SAndroid Build Coastguard Worker if (main == NULL) {
1628*61046927SAndroid Build Coastguard Worker linker_error(prog, "%s shader lacks `main'\n",
1629*61046927SAndroid Build Coastguard Worker _mesa_shader_stage_to_string(shader_list[0]->Stage));
1630*61046927SAndroid Build Coastguard Worker return NULL;
1631*61046927SAndroid Build Coastguard Worker }
1632*61046927SAndroid Build Coastguard Worker
1633*61046927SAndroid Build Coastguard Worker gl_linked_shader *linked = rzalloc(NULL, struct gl_linked_shader);
1634*61046927SAndroid Build Coastguard Worker linked->Stage = shader_list[0]->Stage;
1635*61046927SAndroid Build Coastguard Worker
1636*61046927SAndroid Build Coastguard Worker /* Create program and attach it to the linked shader */
1637*61046927SAndroid Build Coastguard Worker struct gl_program *gl_prog =
1638*61046927SAndroid Build Coastguard Worker ctx->Driver.NewProgram(ctx, shader_list[0]->Stage, prog->Name, false);
1639*61046927SAndroid Build Coastguard Worker if (!gl_prog) {
1640*61046927SAndroid Build Coastguard Worker prog->data->LinkStatus = LINKING_FAILURE;
1641*61046927SAndroid Build Coastguard Worker _mesa_delete_linked_shader(ctx, linked);
1642*61046927SAndroid Build Coastguard Worker return NULL;
1643*61046927SAndroid Build Coastguard Worker }
1644*61046927SAndroid Build Coastguard Worker
1645*61046927SAndroid Build Coastguard Worker _mesa_reference_shader_program_data(&gl_prog->sh.data, prog->data);
1646*61046927SAndroid Build Coastguard Worker
1647*61046927SAndroid Build Coastguard Worker /* Don't use _mesa_reference_program() just take ownership */
1648*61046927SAndroid Build Coastguard Worker linked->Program = gl_prog;
1649*61046927SAndroid Build Coastguard Worker
1650*61046927SAndroid Build Coastguard Worker linked->ir = new(linked) exec_list;
1651*61046927SAndroid Build Coastguard Worker clone_ir_list(mem_ctx, linked->ir, main->ir);
1652*61046927SAndroid Build Coastguard Worker
1653*61046927SAndroid Build Coastguard Worker link_fs_inout_layout_qualifiers(prog, linked, shader_list, num_shaders,
1654*61046927SAndroid Build Coastguard Worker arb_fragment_coord_conventions_enable);
1655*61046927SAndroid Build Coastguard Worker link_tcs_out_layout_qualifiers(prog, gl_prog, shader_list, num_shaders);
1656*61046927SAndroid Build Coastguard Worker link_tes_in_layout_qualifiers(prog, gl_prog, shader_list, num_shaders);
1657*61046927SAndroid Build Coastguard Worker link_gs_inout_layout_qualifiers(prog, gl_prog, shader_list, num_shaders);
1658*61046927SAndroid Build Coastguard Worker link_cs_input_layout_qualifiers(prog, gl_prog, shader_list, num_shaders);
1659*61046927SAndroid Build Coastguard Worker
1660*61046927SAndroid Build Coastguard Worker if (linked->Stage != MESA_SHADER_FRAGMENT)
1661*61046927SAndroid Build Coastguard Worker link_xfb_stride_layout_qualifiers(&ctx->Const, prog, shader_list, num_shaders);
1662*61046927SAndroid Build Coastguard Worker
1663*61046927SAndroid Build Coastguard Worker link_bindless_layout_qualifiers(prog, shader_list, num_shaders);
1664*61046927SAndroid Build Coastguard Worker
1665*61046927SAndroid Build Coastguard Worker link_layer_viewport_relative_qualifier(prog, gl_prog, shader_list, num_shaders);
1666*61046927SAndroid Build Coastguard Worker
1667*61046927SAndroid Build Coastguard Worker populate_symbol_table(linked, shader_list[0]->symbols);
1668*61046927SAndroid Build Coastguard Worker
1669*61046927SAndroid Build Coastguard Worker gl_prog->info.subgroup_size = KHR_shader_subgroup_basic_enable ?
1670*61046927SAndroid Build Coastguard Worker SUBGROUP_SIZE_API_CONSTANT : SUBGROUP_SIZE_UNIFORM;
1671*61046927SAndroid Build Coastguard Worker
1672*61046927SAndroid Build Coastguard Worker /* The pointer to the main function in the final linked shader (i.e., the
1673*61046927SAndroid Build Coastguard Worker * copy of the original shader that contained the main function).
1674*61046927SAndroid Build Coastguard Worker */
1675*61046927SAndroid Build Coastguard Worker ir_function_signature *const main_sig =
1676*61046927SAndroid Build Coastguard Worker _mesa_get_main_function_signature(linked->symbols);
1677*61046927SAndroid Build Coastguard Worker
1678*61046927SAndroid Build Coastguard Worker /* Move any instructions other than variable declarations or function
1679*61046927SAndroid Build Coastguard Worker * declarations into main.
1680*61046927SAndroid Build Coastguard Worker */
1681*61046927SAndroid Build Coastguard Worker if (main_sig != NULL) {
1682*61046927SAndroid Build Coastguard Worker exec_node *insertion_point =
1683*61046927SAndroid Build Coastguard Worker move_non_declarations(linked->ir, &main_sig->body.head_sentinel, false,
1684*61046927SAndroid Build Coastguard Worker linked);
1685*61046927SAndroid Build Coastguard Worker
1686*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_shaders; i++) {
1687*61046927SAndroid Build Coastguard Worker if (shader_list[i] == main)
1688*61046927SAndroid Build Coastguard Worker continue;
1689*61046927SAndroid Build Coastguard Worker
1690*61046927SAndroid Build Coastguard Worker insertion_point = move_non_declarations(shader_list[i]->ir,
1691*61046927SAndroid Build Coastguard Worker insertion_point, true, linked);
1692*61046927SAndroid Build Coastguard Worker }
1693*61046927SAndroid Build Coastguard Worker }
1694*61046927SAndroid Build Coastguard Worker
1695*61046927SAndroid Build Coastguard Worker if (!link_function_calls(prog, linked, main, shader_list, num_shaders)) {
1696*61046927SAndroid Build Coastguard Worker _mesa_delete_linked_shader(ctx, linked);
1697*61046927SAndroid Build Coastguard Worker return NULL;
1698*61046927SAndroid Build Coastguard Worker }
1699*61046927SAndroid Build Coastguard Worker
1700*61046927SAndroid Build Coastguard Worker if (linked->Stage != MESA_SHADER_FRAGMENT)
1701*61046927SAndroid Build Coastguard Worker link_output_variables(linked, shader_list, num_shaders);
1702*61046927SAndroid Build Coastguard Worker
1703*61046927SAndroid Build Coastguard Worker /* Make a pass over all variable declarations to ensure that arrays with
1704*61046927SAndroid Build Coastguard Worker * unspecified sizes have a size specified. The size is inferred from the
1705*61046927SAndroid Build Coastguard Worker * max_array_access field.
1706*61046927SAndroid Build Coastguard Worker */
1707*61046927SAndroid Build Coastguard Worker array_sizing_visitor v;
1708*61046927SAndroid Build Coastguard Worker v.run(linked->ir);
1709*61046927SAndroid Build Coastguard Worker v.fixup_unnamed_interface_types();
1710*61046927SAndroid Build Coastguard Worker
1711*61046927SAndroid Build Coastguard Worker /* Now that we know the sizes of all the arrays, we can replace .length()
1712*61046927SAndroid Build Coastguard Worker * calls with a constant expression.
1713*61046927SAndroid Build Coastguard Worker */
1714*61046927SAndroid Build Coastguard Worker array_length_to_const_visitor len_v;
1715*61046927SAndroid Build Coastguard Worker len_v.run(linked->ir);
1716*61046927SAndroid Build Coastguard Worker
1717*61046927SAndroid Build Coastguard Worker if (!prog->data->LinkStatus) {
1718*61046927SAndroid Build Coastguard Worker _mesa_delete_linked_shader(ctx, linked);
1719*61046927SAndroid Build Coastguard Worker return NULL;
1720*61046927SAndroid Build Coastguard Worker }
1721*61046927SAndroid Build Coastguard Worker
1722*61046927SAndroid Build Coastguard Worker /* At this point linked should contain all of the linked IR, so
1723*61046927SAndroid Build Coastguard Worker * validate it to make sure nothing went wrong.
1724*61046927SAndroid Build Coastguard Worker */
1725*61046927SAndroid Build Coastguard Worker validate_ir_tree(linked->ir);
1726*61046927SAndroid Build Coastguard Worker
1727*61046927SAndroid Build Coastguard Worker /* Set the linked source BLAKE3. */
1728*61046927SAndroid Build Coastguard Worker if (num_shaders == 1) {
1729*61046927SAndroid Build Coastguard Worker memcpy(linked->linked_source_blake3, shader_list[0]->compiled_source_blake3,
1730*61046927SAndroid Build Coastguard Worker BLAKE3_OUT_LEN);
1731*61046927SAndroid Build Coastguard Worker } else {
1732*61046927SAndroid Build Coastguard Worker struct mesa_blake3 blake3_ctx;
1733*61046927SAndroid Build Coastguard Worker _mesa_blake3_init(&blake3_ctx);
1734*61046927SAndroid Build Coastguard Worker
1735*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < num_shaders; i++) {
1736*61046927SAndroid Build Coastguard Worker if (shader_list[i] == NULL)
1737*61046927SAndroid Build Coastguard Worker continue;
1738*61046927SAndroid Build Coastguard Worker
1739*61046927SAndroid Build Coastguard Worker _mesa_blake3_update(&blake3_ctx, shader_list[i]->compiled_source_blake3,
1740*61046927SAndroid Build Coastguard Worker BLAKE3_OUT_LEN);
1741*61046927SAndroid Build Coastguard Worker }
1742*61046927SAndroid Build Coastguard Worker _mesa_blake3_final(&blake3_ctx, linked->linked_source_blake3);
1743*61046927SAndroid Build Coastguard Worker }
1744*61046927SAndroid Build Coastguard Worker
1745*61046927SAndroid Build Coastguard Worker return linked;
1746*61046927SAndroid Build Coastguard Worker }
1747*61046927SAndroid Build Coastguard Worker
1748*61046927SAndroid Build Coastguard Worker void
link_shaders(struct gl_context * ctx,struct gl_shader_program * prog)1749*61046927SAndroid Build Coastguard Worker link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
1750*61046927SAndroid Build Coastguard Worker {
1751*61046927SAndroid Build Coastguard Worker const struct gl_constants *consts = &ctx->Const;
1752*61046927SAndroid Build Coastguard Worker prog->data->LinkStatus = LINKING_SUCCESS; /* All error paths will set this to false */
1753*61046927SAndroid Build Coastguard Worker prog->data->Validated = false;
1754*61046927SAndroid Build Coastguard Worker
1755*61046927SAndroid Build Coastguard Worker /* Section 7.3 (Program Objects) of the OpenGL 4.5 Core Profile spec says:
1756*61046927SAndroid Build Coastguard Worker *
1757*61046927SAndroid Build Coastguard Worker * "Linking can fail for a variety of reasons as specified in the
1758*61046927SAndroid Build Coastguard Worker * OpenGL Shading Language Specification, as well as any of the
1759*61046927SAndroid Build Coastguard Worker * following reasons:
1760*61046927SAndroid Build Coastguard Worker *
1761*61046927SAndroid Build Coastguard Worker * - No shader objects are attached to program."
1762*61046927SAndroid Build Coastguard Worker *
1763*61046927SAndroid Build Coastguard Worker * The Compatibility Profile specification does not list the error. In
1764*61046927SAndroid Build Coastguard Worker * Compatibility Profile missing shader stages are replaced by
1765*61046927SAndroid Build Coastguard Worker * fixed-function. This applies to the case where all stages are
1766*61046927SAndroid Build Coastguard Worker * missing.
1767*61046927SAndroid Build Coastguard Worker */
1768*61046927SAndroid Build Coastguard Worker if (prog->NumShaders == 0) {
1769*61046927SAndroid Build Coastguard Worker if (ctx->API != API_OPENGL_COMPAT)
1770*61046927SAndroid Build Coastguard Worker linker_error(prog, "no shaders attached to the program\n");
1771*61046927SAndroid Build Coastguard Worker return;
1772*61046927SAndroid Build Coastguard Worker }
1773*61046927SAndroid Build Coastguard Worker
1774*61046927SAndroid Build Coastguard Worker #ifdef ENABLE_SHADER_CACHE
1775*61046927SAndroid Build Coastguard Worker if (shader_cache_read_program_metadata(ctx, prog))
1776*61046927SAndroid Build Coastguard Worker return;
1777*61046927SAndroid Build Coastguard Worker #endif
1778*61046927SAndroid Build Coastguard Worker
1779*61046927SAndroid Build Coastguard Worker void *mem_ctx = ralloc_context(NULL); // temporary linker context
1780*61046927SAndroid Build Coastguard Worker
1781*61046927SAndroid Build Coastguard Worker /* Separate the shaders into groups based on their type.
1782*61046927SAndroid Build Coastguard Worker */
1783*61046927SAndroid Build Coastguard Worker struct gl_shader **shader_list[MESA_SHADER_STAGES];
1784*61046927SAndroid Build Coastguard Worker unsigned num_shaders[MESA_SHADER_STAGES];
1785*61046927SAndroid Build Coastguard Worker
1786*61046927SAndroid Build Coastguard Worker for (int i = 0; i < MESA_SHADER_STAGES; i++) {
1787*61046927SAndroid Build Coastguard Worker shader_list[i] = (struct gl_shader **)
1788*61046927SAndroid Build Coastguard Worker calloc(prog->NumShaders, sizeof(struct gl_shader *));
1789*61046927SAndroid Build Coastguard Worker num_shaders[i] = 0;
1790*61046927SAndroid Build Coastguard Worker }
1791*61046927SAndroid Build Coastguard Worker
1792*61046927SAndroid Build Coastguard Worker unsigned min_version = UINT_MAX;
1793*61046927SAndroid Build Coastguard Worker unsigned max_version = 0;
1794*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < prog->NumShaders; i++) {
1795*61046927SAndroid Build Coastguard Worker min_version = MIN2(min_version, prog->Shaders[i]->Version);
1796*61046927SAndroid Build Coastguard Worker max_version = MAX2(max_version, prog->Shaders[i]->Version);
1797*61046927SAndroid Build Coastguard Worker
1798*61046927SAndroid Build Coastguard Worker if (!consts->AllowGLSLRelaxedES &&
1799*61046927SAndroid Build Coastguard Worker prog->Shaders[i]->IsES != prog->Shaders[0]->IsES) {
1800*61046927SAndroid Build Coastguard Worker linker_error(prog, "all shaders must use same shading "
1801*61046927SAndroid Build Coastguard Worker "language version\n");
1802*61046927SAndroid Build Coastguard Worker goto done;
1803*61046927SAndroid Build Coastguard Worker }
1804*61046927SAndroid Build Coastguard Worker
1805*61046927SAndroid Build Coastguard Worker gl_shader_stage shader_type = prog->Shaders[i]->Stage;
1806*61046927SAndroid Build Coastguard Worker shader_list[shader_type][num_shaders[shader_type]] = prog->Shaders[i];
1807*61046927SAndroid Build Coastguard Worker num_shaders[shader_type]++;
1808*61046927SAndroid Build Coastguard Worker }
1809*61046927SAndroid Build Coastguard Worker
1810*61046927SAndroid Build Coastguard Worker /* In desktop GLSL, different shader versions may be linked together. In
1811*61046927SAndroid Build Coastguard Worker * GLSL ES, all shader versions must be the same.
1812*61046927SAndroid Build Coastguard Worker */
1813*61046927SAndroid Build Coastguard Worker if (!consts->AllowGLSLRelaxedES && prog->Shaders[0]->IsES &&
1814*61046927SAndroid Build Coastguard Worker min_version != max_version) {
1815*61046927SAndroid Build Coastguard Worker linker_error(prog, "all shaders must use same shading "
1816*61046927SAndroid Build Coastguard Worker "language version\n");
1817*61046927SAndroid Build Coastguard Worker goto done;
1818*61046927SAndroid Build Coastguard Worker }
1819*61046927SAndroid Build Coastguard Worker
1820*61046927SAndroid Build Coastguard Worker prog->GLSL_Version = max_version;
1821*61046927SAndroid Build Coastguard Worker prog->IsES = prog->Shaders[0]->IsES;
1822*61046927SAndroid Build Coastguard Worker
1823*61046927SAndroid Build Coastguard Worker /* Some shaders have to be linked with some other shaders present.
1824*61046927SAndroid Build Coastguard Worker */
1825*61046927SAndroid Build Coastguard Worker if (!prog->SeparateShader) {
1826*61046927SAndroid Build Coastguard Worker if (num_shaders[MESA_SHADER_GEOMETRY] > 0 &&
1827*61046927SAndroid Build Coastguard Worker num_shaders[MESA_SHADER_VERTEX] == 0) {
1828*61046927SAndroid Build Coastguard Worker linker_error(prog, "Geometry shader must be linked with "
1829*61046927SAndroid Build Coastguard Worker "vertex shader\n");
1830*61046927SAndroid Build Coastguard Worker goto done;
1831*61046927SAndroid Build Coastguard Worker }
1832*61046927SAndroid Build Coastguard Worker if (num_shaders[MESA_SHADER_TESS_EVAL] > 0 &&
1833*61046927SAndroid Build Coastguard Worker num_shaders[MESA_SHADER_VERTEX] == 0) {
1834*61046927SAndroid Build Coastguard Worker linker_error(prog, "Tessellation evaluation shader must be linked "
1835*61046927SAndroid Build Coastguard Worker "with vertex shader\n");
1836*61046927SAndroid Build Coastguard Worker goto done;
1837*61046927SAndroid Build Coastguard Worker }
1838*61046927SAndroid Build Coastguard Worker if (num_shaders[MESA_SHADER_TESS_CTRL] > 0 &&
1839*61046927SAndroid Build Coastguard Worker num_shaders[MESA_SHADER_VERTEX] == 0) {
1840*61046927SAndroid Build Coastguard Worker linker_error(prog, "Tessellation control shader must be linked with "
1841*61046927SAndroid Build Coastguard Worker "vertex shader\n");
1842*61046927SAndroid Build Coastguard Worker goto done;
1843*61046927SAndroid Build Coastguard Worker }
1844*61046927SAndroid Build Coastguard Worker
1845*61046927SAndroid Build Coastguard Worker /* Section 7.3 of the OpenGL ES 3.2 specification says:
1846*61046927SAndroid Build Coastguard Worker *
1847*61046927SAndroid Build Coastguard Worker * "Linking can fail for [...] any of the following reasons:
1848*61046927SAndroid Build Coastguard Worker *
1849*61046927SAndroid Build Coastguard Worker * * program contains an object to form a tessellation control
1850*61046927SAndroid Build Coastguard Worker * shader [...] and [...] the program is not separable and
1851*61046927SAndroid Build Coastguard Worker * contains no object to form a tessellation evaluation shader"
1852*61046927SAndroid Build Coastguard Worker *
1853*61046927SAndroid Build Coastguard Worker * The OpenGL spec is contradictory. It allows linking without a tess
1854*61046927SAndroid Build Coastguard Worker * eval shader, but that can only be used with transform feedback and
1855*61046927SAndroid Build Coastguard Worker * rasterization disabled. However, transform feedback isn't allowed
1856*61046927SAndroid Build Coastguard Worker * with GL_PATCHES, so it can't be used.
1857*61046927SAndroid Build Coastguard Worker *
1858*61046927SAndroid Build Coastguard Worker * More investigation showed that the idea of transform feedback after
1859*61046927SAndroid Build Coastguard Worker * a tess control shader was dropped, because some hw vendors couldn't
1860*61046927SAndroid Build Coastguard Worker * support tessellation without a tess eval shader, but the linker
1861*61046927SAndroid Build Coastguard Worker * section wasn't updated to reflect that.
1862*61046927SAndroid Build Coastguard Worker *
1863*61046927SAndroid Build Coastguard Worker * All specifications (ARB_tessellation_shader, GL 4.0-4.5) have this
1864*61046927SAndroid Build Coastguard Worker * spec bug.
1865*61046927SAndroid Build Coastguard Worker *
1866*61046927SAndroid Build Coastguard Worker * Do what's reasonable and always require a tess eval shader if a tess
1867*61046927SAndroid Build Coastguard Worker * control shader is present.
1868*61046927SAndroid Build Coastguard Worker */
1869*61046927SAndroid Build Coastguard Worker if (num_shaders[MESA_SHADER_TESS_CTRL] > 0 &&
1870*61046927SAndroid Build Coastguard Worker num_shaders[MESA_SHADER_TESS_EVAL] == 0) {
1871*61046927SAndroid Build Coastguard Worker linker_error(prog, "Tessellation control shader must be linked with "
1872*61046927SAndroid Build Coastguard Worker "tessellation evaluation shader\n");
1873*61046927SAndroid Build Coastguard Worker goto done;
1874*61046927SAndroid Build Coastguard Worker }
1875*61046927SAndroid Build Coastguard Worker
1876*61046927SAndroid Build Coastguard Worker if (prog->IsES) {
1877*61046927SAndroid Build Coastguard Worker if (num_shaders[MESA_SHADER_TESS_EVAL] > 0 &&
1878*61046927SAndroid Build Coastguard Worker num_shaders[MESA_SHADER_TESS_CTRL] == 0) {
1879*61046927SAndroid Build Coastguard Worker linker_error(prog, "GLSL ES requires non-separable programs "
1880*61046927SAndroid Build Coastguard Worker "containing a tessellation evaluation shader to also "
1881*61046927SAndroid Build Coastguard Worker "be linked with a tessellation control shader\n");
1882*61046927SAndroid Build Coastguard Worker goto done;
1883*61046927SAndroid Build Coastguard Worker }
1884*61046927SAndroid Build Coastguard Worker }
1885*61046927SAndroid Build Coastguard Worker }
1886*61046927SAndroid Build Coastguard Worker
1887*61046927SAndroid Build Coastguard Worker /* Compute shaders have additional restrictions. */
1888*61046927SAndroid Build Coastguard Worker if (num_shaders[MESA_SHADER_COMPUTE] > 0 &&
1889*61046927SAndroid Build Coastguard Worker num_shaders[MESA_SHADER_COMPUTE] != prog->NumShaders) {
1890*61046927SAndroid Build Coastguard Worker linker_error(prog, "Compute shaders may not be linked with any other "
1891*61046927SAndroid Build Coastguard Worker "type of shader\n");
1892*61046927SAndroid Build Coastguard Worker }
1893*61046927SAndroid Build Coastguard Worker
1894*61046927SAndroid Build Coastguard Worker /* Link all shaders for a particular stage and validate the result.
1895*61046927SAndroid Build Coastguard Worker */
1896*61046927SAndroid Build Coastguard Worker for (int stage = 0; stage < MESA_SHADER_STAGES; stage++) {
1897*61046927SAndroid Build Coastguard Worker if (num_shaders[stage] > 0) {
1898*61046927SAndroid Build Coastguard Worker gl_linked_shader *const sh =
1899*61046927SAndroid Build Coastguard Worker link_intrastage_shaders(mem_ctx, ctx, prog, shader_list[stage],
1900*61046927SAndroid Build Coastguard Worker num_shaders[stage], false);
1901*61046927SAndroid Build Coastguard Worker
1902*61046927SAndroid Build Coastguard Worker if (!prog->data->LinkStatus) {
1903*61046927SAndroid Build Coastguard Worker if (sh)
1904*61046927SAndroid Build Coastguard Worker _mesa_delete_linked_shader(ctx, sh);
1905*61046927SAndroid Build Coastguard Worker goto done;
1906*61046927SAndroid Build Coastguard Worker }
1907*61046927SAndroid Build Coastguard Worker
1908*61046927SAndroid Build Coastguard Worker prog->_LinkedShaders[stage] = sh;
1909*61046927SAndroid Build Coastguard Worker prog->data->linked_stages |= 1 << stage;
1910*61046927SAndroid Build Coastguard Worker }
1911*61046927SAndroid Build Coastguard Worker }
1912*61046927SAndroid Build Coastguard Worker
1913*61046927SAndroid Build Coastguard Worker done:
1914*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) {
1915*61046927SAndroid Build Coastguard Worker free(shader_list[i]);
1916*61046927SAndroid Build Coastguard Worker if (prog->_LinkedShaders[i] == NULL)
1917*61046927SAndroid Build Coastguard Worker continue;
1918*61046927SAndroid Build Coastguard Worker
1919*61046927SAndroid Build Coastguard Worker /* Do a final validation step to make sure that the IR wasn't
1920*61046927SAndroid Build Coastguard Worker * invalidated by any modifications performed after intrastage linking.
1921*61046927SAndroid Build Coastguard Worker */
1922*61046927SAndroid Build Coastguard Worker validate_ir_tree(prog->_LinkedShaders[i]->ir);
1923*61046927SAndroid Build Coastguard Worker
1924*61046927SAndroid Build Coastguard Worker /* Retain any live IR, but trash the rest. */
1925*61046927SAndroid Build Coastguard Worker reparent_ir(prog->_LinkedShaders[i]->ir, prog->_LinkedShaders[i]->ir);
1926*61046927SAndroid Build Coastguard Worker
1927*61046927SAndroid Build Coastguard Worker /* The symbol table in the linked shaders may contain references to
1928*61046927SAndroid Build Coastguard Worker * variables that were removed (e.g., unused uniforms). Since it may
1929*61046927SAndroid Build Coastguard Worker * contain junk, there is no possible valid use. Delete it and set the
1930*61046927SAndroid Build Coastguard Worker * pointer to NULL.
1931*61046927SAndroid Build Coastguard Worker */
1932*61046927SAndroid Build Coastguard Worker delete prog->_LinkedShaders[i]->symbols;
1933*61046927SAndroid Build Coastguard Worker prog->_LinkedShaders[i]->symbols = NULL;
1934*61046927SAndroid Build Coastguard Worker }
1935*61046927SAndroid Build Coastguard Worker
1936*61046927SAndroid Build Coastguard Worker ralloc_free(mem_ctx);
1937*61046927SAndroid Build Coastguard Worker }
1938*61046927SAndroid Build Coastguard Worker
1939*61046927SAndroid Build Coastguard Worker void
resource_name_updated(struct gl_resource_name * name)1940*61046927SAndroid Build Coastguard Worker resource_name_updated(struct gl_resource_name *name)
1941*61046927SAndroid Build Coastguard Worker {
1942*61046927SAndroid Build Coastguard Worker if (name->string) {
1943*61046927SAndroid Build Coastguard Worker name->length = strlen(name->string);
1944*61046927SAndroid Build Coastguard Worker
1945*61046927SAndroid Build Coastguard Worker const char *last_square_bracket = strrchr(name->string, '[');
1946*61046927SAndroid Build Coastguard Worker if (last_square_bracket) {
1947*61046927SAndroid Build Coastguard Worker name->last_square_bracket = last_square_bracket - name->string;
1948*61046927SAndroid Build Coastguard Worker name->suffix_is_zero_square_bracketed =
1949*61046927SAndroid Build Coastguard Worker strcmp(last_square_bracket, "[0]") == 0;
1950*61046927SAndroid Build Coastguard Worker } else {
1951*61046927SAndroid Build Coastguard Worker name->last_square_bracket = -1;
1952*61046927SAndroid Build Coastguard Worker name->suffix_is_zero_square_bracketed = false;
1953*61046927SAndroid Build Coastguard Worker }
1954*61046927SAndroid Build Coastguard Worker } else {
1955*61046927SAndroid Build Coastguard Worker name->length = 0;
1956*61046927SAndroid Build Coastguard Worker name->last_square_bracket = -1;
1957*61046927SAndroid Build Coastguard Worker name->suffix_is_zero_square_bracketed = false;
1958*61046927SAndroid Build Coastguard Worker }
1959*61046927SAndroid Build Coastguard Worker }
1960