summaryrefslogtreecommitdiffstats
path: root/src/compiler/glsl/ast_function.cpp
diff options
context:
space:
mode:
authorKenneth Graunke <[email protected]>2016-09-21 02:03:10 -0700
committerKenneth Graunke <[email protected]>2016-09-23 16:40:40 -0700
commit1617f59bc675d6e44d16ab56d95e910d2e2c8f4e (patch)
tree800a06d79988045ea7d94076bf240c3e56db70f5 /src/compiler/glsl/ast_function.cpp
parentf5a6aab4031bc4754756c1773411728ad9a73381 (diff)
glsl: Check TCS barrier restrictions at ast_to_hir time, not link time.
We want to check prior to optimization - otherwise we might fail to detect cases where barrier() is in control flow which is always taken (and therefore gets optimized away). We don't currently loop unroll if there are function calls inside; otherwise we might have a problem detecting barrier() in loops that get unrolled as well. Tapani's switch handling code adds a loop around switch statements, so even with the mess of if ladders, we'll properly reject it. Enforcing these rules at compile time makes more sense more sense than link time. Doing it at ast-to-hir time (rather than as an IR pass) allows us to emit an error message with proper line numbers. (Otherwise, I would have preferred the IR pass...) Fixes spec/arb_tessellation_shader/compiler/barrier-switch-always.tesc. Signed-off-by: Kenneth Graunke <[email protected]> Reviewed-by; Ian Romanick <[email protected]>
Diffstat (limited to 'src/compiler/glsl/ast_function.cpp')
-rw-r--r--src/compiler/glsl/ast_function.cpp19
1 files changed, 19 insertions, 0 deletions
diff --git a/src/compiler/glsl/ast_function.cpp b/src/compiler/glsl/ast_function.cpp
index ea3ac87d810..7e62ab7d56d 100644
--- a/src/compiler/glsl/ast_function.cpp
+++ b/src/compiler/glsl/ast_function.cpp
@@ -2143,6 +2143,25 @@ ast_function_expression::hir(exec_list *instructions,
/* an error has already been emitted */
value = ir_rvalue::error_value(ctx);
} else {
+ if (state->stage == MESA_SHADER_TESS_CTRL &&
+ sig->is_builtin() && strcmp(func_name, "barrier") == 0) {
+ if (state->current_function == NULL ||
+ strcmp(state->current_function->function_name(), "main") != 0) {
+ _mesa_glsl_error(&loc, state,
+ "barrier() may only be used in main()");
+ }
+
+ if (state->found_return) {
+ _mesa_glsl_error(&loc, state,
+ "barrier() may not be used after return");
+ }
+
+ if (instructions != &state->current_function->body) {
+ _mesa_glsl_error(&loc, state,
+ "barrier() may not be used in control flow");
+ }
+ }
+
value = generate_call(instructions, sig,
&actual_parameters, sub_var, array_idx, state);
if (!value) {