1 /*
2 * Copyright © 2010 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24 #include "ast.h"
25 #include "util/string_buffer.h"
26
27 void
print(void) const28 ast_type_specifier::print(void) const
29 {
30 if (structure) {
31 structure->print();
32 } else {
33 printf("%s ", type_name);
34 }
35
36 if (array_specifier) {
37 array_specifier->print();
38 }
39 }
40
41 bool
has_qualifiers(_mesa_glsl_parse_state * state) const42 ast_fully_specified_type::has_qualifiers(_mesa_glsl_parse_state *state) const
43 {
44 /* 'subroutine' isnt a real qualifier. */
45 ast_type_qualifier subroutine_only;
46 subroutine_only.flags.i = 0;
47 subroutine_only.flags.q.subroutine = 1;
48 if (state->has_explicit_uniform_location()) {
49 subroutine_only.flags.q.explicit_index = 1;
50 }
51 return (this->qualifier.flags.i & ~subroutine_only.flags.i) != 0;
52 }
53
has_interpolation() const54 bool ast_type_qualifier::has_interpolation() const
55 {
56 return this->flags.q.smooth
57 || this->flags.q.flat
58 || this->flags.q.noperspective;
59 }
60
61 bool
has_layout() const62 ast_type_qualifier::has_layout() const
63 {
64 return this->flags.q.origin_upper_left
65 || this->flags.q.pixel_center_integer
66 || this->flags.q.depth_type
67 || this->flags.q.std140
68 || this->flags.q.std430
69 || this->flags.q.shared
70 || this->flags.q.column_major
71 || this->flags.q.row_major
72 || this->flags.q.packed
73 || this->flags.q.bindless_sampler
74 || this->flags.q.bindless_image
75 || this->flags.q.bound_sampler
76 || this->flags.q.bound_image
77 || this->flags.q.explicit_align
78 || this->flags.q.explicit_component
79 || this->flags.q.explicit_location
80 || this->flags.q.explicit_image_format
81 || this->flags.q.explicit_index
82 || this->flags.q.explicit_binding
83 || this->flags.q.explicit_offset
84 || this->flags.q.explicit_stream
85 || this->flags.q.explicit_xfb_buffer
86 || this->flags.q.explicit_xfb_offset
87 || this->flags.q.explicit_xfb_stride;
88 }
89
90 bool
has_storage() const91 ast_type_qualifier::has_storage() const
92 {
93 return this->flags.q.constant
94 || this->flags.q.attribute
95 || this->flags.q.varying
96 || this->flags.q.in
97 || this->flags.q.out
98 || this->flags.q.uniform
99 || this->flags.q.buffer
100 || this->flags.q.shared_storage;
101 }
102
103 bool
has_auxiliary_storage() const104 ast_type_qualifier::has_auxiliary_storage() const
105 {
106 return this->flags.q.centroid
107 || this->flags.q.sample
108 || this->flags.q.patch;
109 }
110
has_memory() const111 bool ast_type_qualifier::has_memory() const
112 {
113 return this->flags.q.coherent
114 || this->flags.q._volatile
115 || this->flags.q.restrict_flag
116 || this->flags.q.read_only
117 || this->flags.q.write_only;
118 }
119
is_subroutine_decl() const120 bool ast_type_qualifier::is_subroutine_decl() const
121 {
122 return this->flags.q.subroutine && !this->subroutine_list;
123 }
124
125 static bool
validate_prim_type(YYLTYPE * loc,_mesa_glsl_parse_state * state,const ast_type_qualifier & qualifier,const ast_type_qualifier & new_qualifier)126 validate_prim_type(YYLTYPE *loc,
127 _mesa_glsl_parse_state *state,
128 const ast_type_qualifier &qualifier,
129 const ast_type_qualifier &new_qualifier)
130 {
131 /* Input layout qualifiers can be specified multiple
132 * times in separate declarations, as long as they match.
133 */
134 if (qualifier.flags.q.prim_type && new_qualifier.flags.q.prim_type
135 && qualifier.prim_type != new_qualifier.prim_type) {
136 _mesa_glsl_error(loc, state,
137 "conflicting input primitive %s specified",
138 state->stage == MESA_SHADER_GEOMETRY ?
139 "type" : "mode");
140 return false;
141 }
142
143 return true;
144 }
145
146 static bool
validate_vertex_spacing(YYLTYPE * loc,_mesa_glsl_parse_state * state,const ast_type_qualifier & qualifier,const ast_type_qualifier & new_qualifier)147 validate_vertex_spacing(YYLTYPE *loc,
148 _mesa_glsl_parse_state *state,
149 const ast_type_qualifier &qualifier,
150 const ast_type_qualifier &new_qualifier)
151 {
152 if (qualifier.flags.q.vertex_spacing && new_qualifier.flags.q.vertex_spacing
153 && qualifier.vertex_spacing != new_qualifier.vertex_spacing) {
154 _mesa_glsl_error(loc, state,
155 "conflicting vertex spacing specified");
156 return false;
157 }
158
159 return true;
160 }
161
162 static bool
validate_ordering(YYLTYPE * loc,_mesa_glsl_parse_state * state,const ast_type_qualifier & qualifier,const ast_type_qualifier & new_qualifier)163 validate_ordering(YYLTYPE *loc,
164 _mesa_glsl_parse_state *state,
165 const ast_type_qualifier &qualifier,
166 const ast_type_qualifier &new_qualifier)
167 {
168 if (qualifier.flags.q.ordering && new_qualifier.flags.q.ordering
169 && qualifier.ordering != new_qualifier.ordering) {
170 _mesa_glsl_error(loc, state,
171 "conflicting ordering specified");
172 return false;
173 }
174
175 return true;
176 }
177
178 static bool
validate_point_mode(ASSERTED const ast_type_qualifier & qualifier,ASSERTED const ast_type_qualifier & new_qualifier)179 validate_point_mode(ASSERTED const ast_type_qualifier &qualifier,
180 ASSERTED const ast_type_qualifier &new_qualifier)
181 {
182 /* Point mode can only be true if the flag is set. */
183 assert (!qualifier.flags.q.point_mode || !new_qualifier.flags.q.point_mode
184 || (qualifier.point_mode && new_qualifier.point_mode));
185
186 return true;
187 }
188
189 static void
merge_bindless_qualifier(_mesa_glsl_parse_state * state)190 merge_bindless_qualifier(_mesa_glsl_parse_state *state)
191 {
192 if (state->default_uniform_qualifier->flags.q.bindless_sampler) {
193 state->bindless_sampler_specified = true;
194 state->default_uniform_qualifier->flags.q.bindless_sampler = false;
195 }
196
197 if (state->default_uniform_qualifier->flags.q.bindless_image) {
198 state->bindless_image_specified = true;
199 state->default_uniform_qualifier->flags.q.bindless_image = false;
200 }
201
202 if (state->default_uniform_qualifier->flags.q.bound_sampler) {
203 state->bound_sampler_specified = true;
204 state->default_uniform_qualifier->flags.q.bound_sampler = false;
205 }
206
207 if (state->default_uniform_qualifier->flags.q.bound_image) {
208 state->bound_image_specified = true;
209 state->default_uniform_qualifier->flags.q.bound_image = false;
210 }
211 }
212
213 /**
214 * This function merges duplicate layout identifiers.
215 *
216 * It deals with duplicates within a single layout qualifier, among multiple
217 * layout qualifiers on a single declaration and on several declarations for
218 * the same variable.
219 *
220 * The is_single_layout_merge and is_multiple_layouts_merge parameters are
221 * used to differentiate among them.
222 */
223 bool
merge_qualifier(YYLTYPE * loc,_mesa_glsl_parse_state * state,const ast_type_qualifier & q,bool is_single_layout_merge,bool is_multiple_layouts_merge)224 ast_type_qualifier::merge_qualifier(YYLTYPE *loc,
225 _mesa_glsl_parse_state *state,
226 const ast_type_qualifier &q,
227 bool is_single_layout_merge,
228 bool is_multiple_layouts_merge)
229 {
230 bool r = true;
231 ast_type_qualifier ubo_mat_mask;
232 ubo_mat_mask.flags.i = 0;
233 ubo_mat_mask.flags.q.row_major = 1;
234 ubo_mat_mask.flags.q.column_major = 1;
235
236 ast_type_qualifier ubo_layout_mask;
237 ubo_layout_mask.flags.i = 0;
238 ubo_layout_mask.flags.q.std140 = 1;
239 ubo_layout_mask.flags.q.packed = 1;
240 ubo_layout_mask.flags.q.shared = 1;
241 ubo_layout_mask.flags.q.std430 = 1;
242
243 ast_type_qualifier ubo_binding_mask;
244 ubo_binding_mask.flags.i = 0;
245 ubo_binding_mask.flags.q.explicit_binding = 1;
246 ubo_binding_mask.flags.q.explicit_offset = 1;
247
248 ast_type_qualifier stream_layout_mask;
249 stream_layout_mask.flags.i = 0;
250 stream_layout_mask.flags.q.stream = 1;
251
252 /* FIXME: We should probably do interface and function param validation
253 * separately.
254 */
255 ast_type_qualifier input_layout_mask;
256 input_layout_mask.flags.i = 0;
257 input_layout_mask.flags.q.centroid = 1;
258 /* Function params can have constant */
259 input_layout_mask.flags.q.constant = 1;
260 input_layout_mask.flags.q.explicit_component = 1;
261 input_layout_mask.flags.q.explicit_location = 1;
262 input_layout_mask.flags.q.flat = 1;
263 input_layout_mask.flags.q.in = 1;
264 input_layout_mask.flags.q.invariant = 1;
265 input_layout_mask.flags.q.noperspective = 1;
266 input_layout_mask.flags.q.origin_upper_left = 1;
267 /* Function params 'inout' will set this */
268 input_layout_mask.flags.q.out = 1;
269 input_layout_mask.flags.q.patch = 1;
270 input_layout_mask.flags.q.pixel_center_integer = 1;
271 input_layout_mask.flags.q.precise = 1;
272 input_layout_mask.flags.q.sample = 1;
273 input_layout_mask.flags.q.smooth = 1;
274 input_layout_mask.flags.q.non_coherent = 1;
275
276 if (state->has_bindless()) {
277 /* Allow to use image qualifiers with shader inputs/outputs. */
278 input_layout_mask.flags.q.coherent = 1;
279 input_layout_mask.flags.q._volatile = 1;
280 input_layout_mask.flags.q.restrict_flag = 1;
281 input_layout_mask.flags.q.read_only = 1;
282 input_layout_mask.flags.q.write_only = 1;
283 input_layout_mask.flags.q.explicit_image_format = 1;
284 }
285
286 /* Uniform block layout qualifiers get to overwrite each
287 * other (rightmost having priority), while all other
288 * qualifiers currently don't allow duplicates.
289 */
290 ast_type_qualifier allowed_duplicates_mask;
291 allowed_duplicates_mask.flags.i =
292 ubo_mat_mask.flags.i |
293 ubo_layout_mask.flags.i |
294 ubo_binding_mask.flags.i;
295
296 /* Geometry shaders can have several layout qualifiers
297 * assigning different stream values.
298 */
299 if (state->stage == MESA_SHADER_GEOMETRY) {
300 allowed_duplicates_mask.flags.i |=
301 stream_layout_mask.flags.i;
302 }
303
304 if (is_single_layout_merge && !state->has_enhanced_layouts() &&
305 (this->flags.i & q.flags.i & ~allowed_duplicates_mask.flags.i) != 0) {
306 _mesa_glsl_error(loc, state, "duplicate layout qualifiers used");
307 return false;
308 }
309
310 if (is_multiple_layouts_merge && !state->has_420pack_or_es31()) {
311 _mesa_glsl_error(loc, state,
312 "duplicate layout(...) qualifiers");
313 return false;
314 }
315
316 if (q.flags.q.prim_type) {
317 r &= validate_prim_type(loc, state, *this, q);
318 this->flags.q.prim_type = 1;
319 this->prim_type = q.prim_type;
320 }
321
322 if (q.flags.q.max_vertices) {
323 if (this->flags.q.max_vertices
324 && !is_single_layout_merge && !is_multiple_layouts_merge) {
325 this->max_vertices->merge_qualifier(q.max_vertices);
326 } else {
327 this->flags.q.max_vertices = 1;
328 this->max_vertices = q.max_vertices;
329 }
330 }
331
332 if (q.subroutine_list) {
333 if (this->subroutine_list) {
334 _mesa_glsl_error(loc, state,
335 "conflicting subroutine qualifiers used");
336 } else {
337 this->subroutine_list = q.subroutine_list;
338 }
339 }
340
341 if (q.flags.q.invocations) {
342 if (this->flags.q.invocations
343 && !is_single_layout_merge && !is_multiple_layouts_merge) {
344 this->invocations->merge_qualifier(q.invocations);
345 } else {
346 this->flags.q.invocations = 1;
347 this->invocations = q.invocations;
348 }
349 }
350
351 if (state->stage == MESA_SHADER_GEOMETRY &&
352 state->has_explicit_attrib_stream()) {
353 if (!this->flags.q.explicit_stream) {
354 if (q.flags.q.stream) {
355 this->flags.q.stream = 1;
356 this->stream = q.stream;
357 } else if (!this->flags.q.stream && this->flags.q.out &&
358 !this->flags.q.in) {
359 /* Assign default global stream value */
360 this->flags.q.stream = 1;
361 this->stream = state->out_qualifier->stream;
362 }
363 }
364 }
365
366 if (state->has_enhanced_layouts()) {
367 if (!this->flags.q.explicit_xfb_buffer) {
368 if (q.flags.q.xfb_buffer) {
369 this->flags.q.xfb_buffer = 1;
370 this->xfb_buffer = q.xfb_buffer;
371 } else if (!this->flags.q.xfb_buffer && this->flags.q.out &&
372 !this->flags.q.in) {
373 /* Assign global xfb_buffer value */
374 this->flags.q.xfb_buffer = 1;
375 this->xfb_buffer = state->out_qualifier->xfb_buffer;
376 }
377 }
378
379 if (q.flags.q.explicit_xfb_stride) {
380 this->flags.q.xfb_stride = 1;
381 this->flags.q.explicit_xfb_stride = 1;
382 this->xfb_stride = q.xfb_stride;
383 }
384 }
385
386 if (q.flags.q.vertices) {
387 if (this->flags.q.vertices
388 && !is_single_layout_merge && !is_multiple_layouts_merge) {
389 this->vertices->merge_qualifier(q.vertices);
390 } else {
391 this->flags.q.vertices = 1;
392 this->vertices = q.vertices;
393 }
394 }
395
396 if (q.flags.q.vertex_spacing) {
397 r &= validate_vertex_spacing(loc, state, *this, q);
398 this->flags.q.vertex_spacing = 1;
399 this->vertex_spacing = q.vertex_spacing;
400 }
401
402 if (q.flags.q.ordering) {
403 r &= validate_ordering(loc, state, *this, q);
404 this->flags.q.ordering = 1;
405 this->ordering = q.ordering;
406 }
407
408 if (q.flags.q.point_mode) {
409 r &= validate_point_mode(*this, q);
410 this->flags.q.point_mode = 1;
411 this->point_mode = q.point_mode;
412 }
413
414 if (q.flags.q.early_fragment_tests)
415 this->flags.q.early_fragment_tests = true;
416
417 if ((q.flags.i & ubo_mat_mask.flags.i) != 0)
418 this->flags.i &= ~ubo_mat_mask.flags.i;
419 if ((q.flags.i & ubo_layout_mask.flags.i) != 0)
420 this->flags.i &= ~ubo_layout_mask.flags.i;
421
422 for (int i = 0; i < 3; i++) {
423 if (q.flags.q.local_size & (1 << i)) {
424 if (this->local_size[i]
425 && !is_single_layout_merge && !is_multiple_layouts_merge) {
426 this->local_size[i]->merge_qualifier(q.local_size[i]);
427 } else {
428 this->local_size[i] = q.local_size[i];
429 }
430 }
431 }
432
433 if (q.flags.q.local_size_variable)
434 this->flags.q.local_size_variable = true;
435
436 if (q.flags.q.bindless_sampler)
437 this->flags.q.bindless_sampler = true;
438
439 if (q.flags.q.bindless_image)
440 this->flags.q.bindless_image = true;
441
442 if (q.flags.q.bound_sampler)
443 this->flags.q.bound_sampler = true;
444
445 if (q.flags.q.bound_image)
446 this->flags.q.bound_image = true;
447
448 if (q.flags.q.derivative_group) {
449 this->flags.q.derivative_group = true;
450 this->derivative_group = q.derivative_group;
451 }
452
453 this->flags.i |= q.flags.i;
454
455 if (this->flags.q.in &&
456 (this->flags.i & ~input_layout_mask.flags.i) != 0) {
457 _mesa_glsl_error(loc, state, "invalid input layout qualifier used");
458 return false;
459 }
460
461 if (q.flags.q.explicit_align)
462 this->align = q.align;
463
464 if (q.flags.q.explicit_location)
465 this->location = q.location;
466
467 if (q.flags.q.explicit_index)
468 this->index = q.index;
469
470 if (q.flags.q.explicit_component)
471 this->component = q.component;
472
473 if (q.flags.q.explicit_binding)
474 this->binding = q.binding;
475
476 if (q.flags.q.explicit_offset || q.flags.q.explicit_xfb_offset)
477 this->offset = q.offset;
478
479 if (q.precision != ast_precision_none)
480 this->precision = q.precision;
481
482 if (q.flags.q.explicit_image_format) {
483 this->image_format = q.image_format;
484 this->image_base_type = q.image_base_type;
485 }
486
487 if (q.flags.q.bindless_sampler ||
488 q.flags.q.bindless_image ||
489 q.flags.q.bound_sampler ||
490 q.flags.q.bound_image)
491 merge_bindless_qualifier(state);
492
493 if (state->EXT_gpu_shader4_enable &&
494 state->stage == MESA_SHADER_FRAGMENT &&
495 this->flags.q.varying && q.flags.q.out) {
496 this->flags.q.varying = 0;
497 this->flags.q.out = 1;
498 }
499
500 return r;
501 }
502
503 bool
validate_out_qualifier(YYLTYPE * loc,_mesa_glsl_parse_state * state)504 ast_type_qualifier::validate_out_qualifier(YYLTYPE *loc,
505 _mesa_glsl_parse_state *state)
506 {
507 bool r = true;
508 ast_type_qualifier valid_out_mask;
509 valid_out_mask.flags.i = 0;
510
511 switch (state->stage) {
512 case MESA_SHADER_GEOMETRY:
513 if (this->flags.q.prim_type) {
514 /* Make sure this is a valid output primitive type. */
515 switch (this->prim_type) {
516 case GL_POINTS:
517 case GL_LINE_STRIP:
518 case GL_TRIANGLE_STRIP:
519 break;
520 default:
521 r = false;
522 _mesa_glsl_error(loc, state, "invalid geometry shader output "
523 "primitive type");
524 break;
525 }
526 }
527
528 valid_out_mask.flags.q.stream = 1;
529 valid_out_mask.flags.q.explicit_stream = 1;
530 valid_out_mask.flags.q.explicit_xfb_buffer = 1;
531 valid_out_mask.flags.q.xfb_buffer = 1;
532 valid_out_mask.flags.q.explicit_xfb_stride = 1;
533 valid_out_mask.flags.q.xfb_stride = 1;
534 valid_out_mask.flags.q.max_vertices = 1;
535 valid_out_mask.flags.q.prim_type = 1;
536 break;
537 case MESA_SHADER_TESS_CTRL:
538 valid_out_mask.flags.q.vertices = 1;
539 valid_out_mask.flags.q.explicit_xfb_buffer = 1;
540 valid_out_mask.flags.q.xfb_buffer = 1;
541 valid_out_mask.flags.q.explicit_xfb_stride = 1;
542 valid_out_mask.flags.q.xfb_stride = 1;
543 break;
544 case MESA_SHADER_TESS_EVAL:
545 case MESA_SHADER_VERTEX:
546 valid_out_mask.flags.q.explicit_xfb_buffer = 1;
547 valid_out_mask.flags.q.xfb_buffer = 1;
548 valid_out_mask.flags.q.explicit_xfb_stride = 1;
549 valid_out_mask.flags.q.xfb_stride = 1;
550 break;
551 case MESA_SHADER_FRAGMENT:
552 valid_out_mask.flags.q.blend_support = 1;
553 break;
554 default:
555 r = false;
556 _mesa_glsl_error(loc, state,
557 "out layout qualifiers only valid in "
558 "geometry, tessellation, vertex and fragment shaders");
559 }
560
561 /* Generate an error when invalid output layout qualifiers are used. */
562 if ((this->flags.i & ~valid_out_mask.flags.i) != 0) {
563 r = false;
564 _mesa_glsl_error(loc, state, "invalid output layout qualifiers used");
565 }
566
567 return r;
568 }
569
570 bool
merge_into_out_qualifier(YYLTYPE * loc,_mesa_glsl_parse_state * state,ast_node * & node)571 ast_type_qualifier::merge_into_out_qualifier(YYLTYPE *loc,
572 _mesa_glsl_parse_state *state,
573 ast_node* &node)
574 {
575 const bool r = state->out_qualifier->merge_qualifier(loc, state,
576 *this, false);
577
578 switch (state->stage) {
579 case MESA_SHADER_GEOMETRY:
580 /* Allow future assignments of global out's stream id value */
581 state->out_qualifier->flags.q.explicit_stream = 0;
582 break;
583 case MESA_SHADER_TESS_CTRL:
584 node = new(state->linalloc) ast_tcs_output_layout(*loc);
585 break;
586 default:
587 break;
588 }
589
590 /* Allow future assignments of global out's */
591 state->out_qualifier->flags.q.explicit_xfb_buffer = 0;
592 state->out_qualifier->flags.q.explicit_xfb_stride = 0;
593
594 return r;
595 }
596
597 bool
validate_in_qualifier(YYLTYPE * loc,_mesa_glsl_parse_state * state)598 ast_type_qualifier::validate_in_qualifier(YYLTYPE *loc,
599 _mesa_glsl_parse_state *state)
600 {
601 bool r = true;
602 ast_type_qualifier valid_in_mask;
603 valid_in_mask.flags.i = 0;
604
605 switch (state->stage) {
606 case MESA_SHADER_TESS_EVAL:
607 if (this->flags.q.prim_type) {
608 /* Make sure this is a valid input primitive type. */
609 switch (this->prim_type) {
610 case GL_TRIANGLES:
611 case GL_QUADS:
612 case GL_ISOLINES:
613 break;
614 default:
615 r = false;
616 _mesa_glsl_error(loc, state,
617 "invalid tessellation evaluation "
618 "shader input primitive type");
619 break;
620 }
621 }
622
623 valid_in_mask.flags.q.prim_type = 1;
624 valid_in_mask.flags.q.vertex_spacing = 1;
625 valid_in_mask.flags.q.ordering = 1;
626 valid_in_mask.flags.q.point_mode = 1;
627 break;
628 case MESA_SHADER_GEOMETRY:
629 if (this->flags.q.prim_type) {
630 /* Make sure this is a valid input primitive type. */
631 switch (this->prim_type) {
632 case GL_POINTS:
633 case GL_LINES:
634 case GL_LINES_ADJACENCY:
635 case GL_TRIANGLES:
636 case GL_TRIANGLES_ADJACENCY:
637 break;
638 default:
639 r = false;
640 _mesa_glsl_error(loc, state,
641 "invalid geometry shader input primitive type");
642 break;
643 }
644 }
645
646 valid_in_mask.flags.q.prim_type = 1;
647 valid_in_mask.flags.q.invocations = 1;
648 break;
649 case MESA_SHADER_FRAGMENT:
650 valid_in_mask.flags.q.early_fragment_tests = 1;
651 valid_in_mask.flags.q.inner_coverage = 1;
652 valid_in_mask.flags.q.post_depth_coverage = 1;
653 valid_in_mask.flags.q.pixel_interlock_ordered = 1;
654 valid_in_mask.flags.q.pixel_interlock_unordered = 1;
655 valid_in_mask.flags.q.sample_interlock_ordered = 1;
656 valid_in_mask.flags.q.sample_interlock_unordered = 1;
657 break;
658 case MESA_SHADER_COMPUTE:
659 valid_in_mask.flags.q.local_size = 7;
660 valid_in_mask.flags.q.local_size_variable = 1;
661 valid_in_mask.flags.q.derivative_group = 1;
662 break;
663 default:
664 r = false;
665 _mesa_glsl_error(loc, state,
666 "input layout qualifiers only valid in "
667 "geometry, tessellation, fragment and compute shaders");
668 break;
669 }
670
671 /* Generate an error when invalid input layout qualifiers are used. */
672 if ((this->flags.i & ~valid_in_mask.flags.i) != 0) {
673 r = false;
674 _mesa_glsl_error(loc, state, "invalid input layout qualifiers used");
675 }
676
677 /* The checks below are also performed when merging but we want to spit an
678 * error against the default global input qualifier as soon as we can, with
679 * the closest error location in the shader.
680 */
681 r &= validate_prim_type(loc, state, *state->in_qualifier, *this);
682 r &= validate_vertex_spacing(loc, state, *state->in_qualifier, *this);
683 r &= validate_ordering(loc, state, *state->in_qualifier, *this);
684 r &= validate_point_mode(*state->in_qualifier, *this);
685
686 return r;
687 }
688
689 bool
merge_into_in_qualifier(YYLTYPE * loc,_mesa_glsl_parse_state * state,ast_node * & node)690 ast_type_qualifier::merge_into_in_qualifier(YYLTYPE *loc,
691 _mesa_glsl_parse_state *state,
692 ast_node* &node)
693 {
694 bool r = true;
695 void *lin_ctx = state->linalloc;
696
697 /* We create the gs_input_layout node before merging so, in the future, no
698 * more repeated nodes will be created as we will have the flag set.
699 */
700 if (state->stage == MESA_SHADER_GEOMETRY
701 && this->flags.q.prim_type && !state->in_qualifier->flags.q.prim_type) {
702 node = new(lin_ctx) ast_gs_input_layout(*loc, this->prim_type);
703 }
704
705 r = state->in_qualifier->merge_qualifier(loc, state, *this, false);
706
707 if (state->in_qualifier->flags.q.early_fragment_tests) {
708 state->fs_early_fragment_tests = true;
709 state->in_qualifier->flags.q.early_fragment_tests = false;
710 }
711
712 if (state->in_qualifier->flags.q.inner_coverage) {
713 state->fs_inner_coverage = true;
714 state->in_qualifier->flags.q.inner_coverage = false;
715 }
716
717 if (state->in_qualifier->flags.q.post_depth_coverage) {
718 state->fs_post_depth_coverage = true;
719 state->in_qualifier->flags.q.post_depth_coverage = false;
720 }
721
722 if (state->fs_inner_coverage && state->fs_post_depth_coverage) {
723 _mesa_glsl_error(loc, state,
724 "inner_coverage & post_depth_coverage layout qualifiers "
725 "are mutally exclusives");
726 r = false;
727 }
728
729 if (state->in_qualifier->flags.q.pixel_interlock_ordered) {
730 state->fs_pixel_interlock_ordered = true;
731 state->in_qualifier->flags.q.pixel_interlock_ordered = false;
732 }
733
734 if (state->in_qualifier->flags.q.pixel_interlock_unordered) {
735 state->fs_pixel_interlock_unordered = true;
736 state->in_qualifier->flags.q.pixel_interlock_unordered = false;
737 }
738
739 if (state->in_qualifier->flags.q.sample_interlock_ordered) {
740 state->fs_sample_interlock_ordered = true;
741 state->in_qualifier->flags.q.sample_interlock_ordered = false;
742 }
743
744 if (state->in_qualifier->flags.q.sample_interlock_unordered) {
745 state->fs_sample_interlock_unordered = true;
746 state->in_qualifier->flags.q.sample_interlock_unordered = false;
747 }
748
749 if (state->fs_pixel_interlock_ordered +
750 state->fs_pixel_interlock_unordered +
751 state->fs_sample_interlock_ordered +
752 state->fs_sample_interlock_unordered > 1) {
753 _mesa_glsl_error(loc, state,
754 "only one interlock mode can be used at any time.");
755 r = false;
756 }
757
758 if (state->in_qualifier->flags.q.derivative_group) {
759 if (state->cs_derivative_group != DERIVATIVE_GROUP_NONE) {
760 if (state->in_qualifier->derivative_group != DERIVATIVE_GROUP_NONE &&
761 state->cs_derivative_group != state->in_qualifier->derivative_group) {
762 _mesa_glsl_error(loc, state,
763 "conflicting derivative groups.");
764 r = false;
765 }
766 } else {
767 state->cs_derivative_group = state->in_qualifier->derivative_group;
768 }
769 }
770
771 /* We allow the creation of multiple cs_input_layout nodes. Coherence among
772 * all existing nodes is checked later, when the AST node is transformed
773 * into HIR.
774 */
775 if (state->in_qualifier->flags.q.local_size) {
776 node = new(lin_ctx) ast_cs_input_layout(*loc,
777 state->in_qualifier->local_size);
778 state->in_qualifier->flags.q.local_size = 0;
779 for (int i = 0; i < 3; i++)
780 state->in_qualifier->local_size[i] = NULL;
781 }
782
783 if (state->in_qualifier->flags.q.local_size_variable) {
784 state->cs_input_local_size_variable_specified = true;
785 state->in_qualifier->flags.q.local_size_variable = false;
786 }
787
788 return r;
789 }
790
791 bool
push_to_global(YYLTYPE * loc,_mesa_glsl_parse_state * state)792 ast_type_qualifier::push_to_global(YYLTYPE *loc,
793 _mesa_glsl_parse_state *state)
794 {
795 if (this->flags.q.xfb_stride) {
796 this->flags.q.xfb_stride = 0;
797
798 unsigned buff_idx;
799 if (process_qualifier_constant(state, loc, "xfb_buffer",
800 this->xfb_buffer, &buff_idx)) {
801 if (state->out_qualifier->out_xfb_stride[buff_idx]) {
802 state->out_qualifier->out_xfb_stride[buff_idx]->merge_qualifier(
803 new(state->linalloc) ast_layout_expression(*loc,
804 this->xfb_stride));
805 } else {
806 state->out_qualifier->out_xfb_stride[buff_idx] =
807 new(state->linalloc) ast_layout_expression(*loc,
808 this->xfb_stride);
809 }
810 }
811 }
812
813 return true;
814 }
815
816 /**
817 * Check if the current type qualifier has any illegal flags.
818 *
819 * If so, print an error message, followed by a list of illegal flags.
820 *
821 * \param message The error message to print.
822 * \param allowed_flags A list of valid flags.
823 */
824 bool
validate_flags(YYLTYPE * loc,_mesa_glsl_parse_state * state,const ast_type_qualifier & allowed_flags,const char * message,const char * name)825 ast_type_qualifier::validate_flags(YYLTYPE *loc,
826 _mesa_glsl_parse_state *state,
827 const ast_type_qualifier &allowed_flags,
828 const char *message, const char *name)
829 {
830 ast_type_qualifier bad;
831 bad.flags.i = this->flags.i & ~allowed_flags.flags.i;
832 if (bad.flags.i == 0)
833 return true;
834
835 struct _mesa_string_buffer *buf = _mesa_string_buffer_create(NULL, 100);
836 #define Q(f) \
837 if (bad.flags.q.f) \
838 _mesa_string_buffer_append(buf, "" #f)
839 #define Q2(f, s) \
840 if (bad.flags.q.f) \
841 _mesa_string_buffer_append(buf, " " #s)
842
843 Q(invariant);
844 Q(precise);
845 Q(constant);
846 Q(attribute);
847 Q(varying);
848 Q(in);
849 Q(out);
850 Q(centroid);
851 Q(sample);
852 Q(patch);
853 Q(uniform);
854 Q(buffer);
855 Q(shared_storage);
856 Q(smooth);
857 Q(flat);
858 Q(noperspective);
859 Q(origin_upper_left);
860 Q(pixel_center_integer);
861 Q2(explicit_align, align);
862 Q2(explicit_component, component);
863 Q2(explicit_location, location);
864 Q2(explicit_index, index);
865 Q2(explicit_binding, binding);
866 Q2(explicit_offset, offset);
867 Q(depth_type);
868 Q(std140);
869 Q(std430);
870 Q(shared);
871 Q(packed);
872 Q(column_major);
873 Q(row_major);
874 Q(prim_type);
875 Q(max_vertices);
876 Q(local_size);
877 Q(local_size_variable);
878 Q(early_fragment_tests);
879 Q2(explicit_image_format, image_format);
880 Q(coherent);
881 Q2(_volatile, volatile);
882 Q(restrict_flag);
883 Q(read_only);
884 Q(write_only);
885 Q(invocations);
886 Q(stream);
887 Q(stream);
888 Q2(explicit_xfb_offset, xfb_offset);
889 Q2(xfb_buffer, xfb_buffer);
890 Q2(explicit_xfb_buffer, xfb_buffer);
891 Q2(xfb_stride, xfb_stride);
892 Q2(explicit_xfb_stride, xfb_stride);
893 Q(vertex_spacing);
894 Q(ordering);
895 Q(point_mode);
896 Q(vertices);
897 Q(subroutine);
898 Q(blend_support);
899 Q(inner_coverage);
900 Q(bindless_sampler);
901 Q(bindless_image);
902 Q(bound_sampler);
903 Q(bound_image);
904 Q(post_depth_coverage);
905 Q(pixel_interlock_ordered);
906 Q(pixel_interlock_unordered);
907 Q(sample_interlock_ordered);
908 Q(sample_interlock_unordered);
909 Q2(non_coherent, noncoherent);
910
911 #undef Q
912 #undef Q2
913
914 _mesa_glsl_error(loc, state,
915 "%s '%s': %s\n",
916 message, name,
917 buf->buf);
918 _mesa_string_buffer_destroy(buf);
919
920 return false;
921 }
922
923 bool
process_qualifier_constant(struct _mesa_glsl_parse_state * state,const char * qual_indentifier,unsigned * value,bool can_be_zero)924 ast_layout_expression::process_qualifier_constant(struct _mesa_glsl_parse_state *state,
925 const char *qual_indentifier,
926 unsigned *value,
927 bool can_be_zero)
928 {
929 int min_value = 0;
930 bool first_pass = true;
931 *value = 0;
932
933 if (!can_be_zero)
934 min_value = 1;
935
936 for (exec_node *node = layout_const_expressions.get_head_raw();
937 !node->is_tail_sentinel(); node = node->next) {
938
939 exec_list dummy_instructions;
940 ast_node *const_expression = exec_node_data(ast_node, node, link);
941
942 ir_rvalue *const ir = const_expression->hir(&dummy_instructions, state);
943
944 ir_constant *const const_int =
945 ir->constant_expression_value(ralloc_parent(ir));
946
947 if (const_int == NULL || !const_int->type->is_integer_32()) {
948 YYLTYPE loc = const_expression->get_location();
949 _mesa_glsl_error(&loc, state, "%s must be an integral constant "
950 "expression", qual_indentifier);
951 return false;
952 }
953
954 if (const_int->value.i[0] < min_value) {
955 YYLTYPE loc = const_expression->get_location();
956 _mesa_glsl_error(&loc, state, "%s layout qualifier is invalid "
957 "(%d < %d)", qual_indentifier,
958 const_int->value.i[0], min_value);
959 return false;
960 }
961
962 if (!first_pass && *value != const_int->value.u[0]) {
963 YYLTYPE loc = const_expression->get_location();
964 _mesa_glsl_error(&loc, state, "%s layout qualifier does not "
965 "match previous declaration (%d vs %d)",
966 qual_indentifier, *value, const_int->value.i[0]);
967 return false;
968 } else {
969 first_pass = false;
970 *value = const_int->value.u[0];
971 }
972
973 /* If the location is const (and we've verified that
974 * it is) then no instructions should have been emitted
975 * when we converted it to HIR. If they were emitted,
976 * then either the location isn't const after all, or
977 * we are emitting unnecessary instructions.
978 */
979 assert(dummy_instructions.is_empty());
980 }
981
982 return true;
983 }
984
985 bool
process_qualifier_constant(struct _mesa_glsl_parse_state * state,YYLTYPE * loc,const char * qual_indentifier,ast_expression * const_expression,unsigned * value)986 process_qualifier_constant(struct _mesa_glsl_parse_state *state,
987 YYLTYPE *loc,
988 const char *qual_indentifier,
989 ast_expression *const_expression,
990 unsigned *value)
991 {
992 exec_list dummy_instructions;
993
994 if (const_expression == NULL) {
995 *value = 0;
996 return true;
997 }
998
999 ir_rvalue *const ir = const_expression->hir(&dummy_instructions, state);
1000
1001 ir_constant *const const_int =
1002 ir->constant_expression_value(ralloc_parent(ir));
1003 if (const_int == NULL || !const_int->type->is_integer_32()) {
1004 _mesa_glsl_error(loc, state, "%s must be an integral constant "
1005 "expression", qual_indentifier);
1006 return false;
1007 }
1008
1009 if (const_int->value.i[0] < 0) {
1010 _mesa_glsl_error(loc, state, "%s layout qualifier is invalid (%d < 0)",
1011 qual_indentifier, const_int->value.u[0]);
1012 return false;
1013 }
1014
1015 /* If the location is const (and we've verified that
1016 * it is) then no instructions should have been emitted
1017 * when we converted it to HIR. If they were emitted,
1018 * then either the location isn't const after all, or
1019 * we are emitting unnecessary instructions.
1020 */
1021 assert(dummy_instructions.is_empty());
1022
1023 *value = const_int->value.u[0];
1024 return true;
1025 }
1026