diff options
-rw-r--r-- | src/glsl/ast_function.cpp | 9 | ||||
-rw-r--r-- | src/glsl/ir.cpp | 17 | ||||
-rw-r--r-- | src/glsl/ir.h | 1 | ||||
-rw-r--r-- | src/glsl/ir_function.cpp | 1 | ||||
-rw-r--r-- | src/glsl/ir_print_visitor.cpp | 2 | ||||
-rw-r--r-- | src/glsl/ir_reader.cpp | 2 | ||||
-rw-r--r-- | src/glsl/ir_variable.cpp | 1 | ||||
-rw-r--r-- | src/glsl/linker.cpp | 1 | ||||
-rw-r--r-- | src/glsl/lower_variable_index_to_cond_assign.cpp | 1 | ||||
-rw-r--r-- | src/glsl/opt_constant_folding.cpp | 2 | ||||
-rw-r--r-- | src/glsl/opt_function_inlining.cpp | 1 | ||||
-rw-r--r-- | src/glsl/opt_tree_grafting.cpp | 2 |
12 files changed, 36 insertions, 4 deletions
diff --git a/src/glsl/ast_function.cpp b/src/glsl/ast_function.cpp index b3635bf6867..b0f95dd73b6 100644 --- a/src/glsl/ast_function.cpp +++ b/src/glsl/ast_function.cpp @@ -132,6 +132,9 @@ match_function_by_name(exec_list *instructions, const char *name, /* Verify that 'out' and 'inout' actual parameters are lvalues. This * isn't done in ir_function::matching_signature because that function * cannot generate the necessary diagnostics. + * + * Also, validate that 'const_in' formal parameters (an extension of our + * IR) correspond to ir_constant actual parameters. */ exec_list_iterator actual_iter = actual_parameters->iterator(); exec_list_iterator formal_iter = sig->parameters.iterator(); @@ -143,6 +146,12 @@ match_function_by_name(exec_list *instructions, const char *name, assert(actual != NULL); assert(formal != NULL); + if (formal->mode == ir_var_const_in && !actual->as_constant()) { + _mesa_glsl_error(loc, state, + "parameter `%s' must be a constant expression", + formal->name); + } + if ((formal->mode == ir_var_out) || (formal->mode == ir_var_inout)) { const char *mode = NULL; diff --git a/src/glsl/ir.cpp b/src/glsl/ir.cpp index cc508e2a424..fc356ba5275 100644 --- a/src/glsl/ir.cpp +++ b/src/glsl/ir.cpp @@ -1379,6 +1379,21 @@ ir_function_signature::ir_function_signature(const glsl_type *return_type) } +static bool +modes_match(unsigned a, unsigned b) +{ + if (a == b) + return true; + + /* Accept "in" vs. "const in" */ + if ((a == ir_var_const_in && b == ir_var_in) || + (b == ir_var_const_in && a == ir_var_in)) + return true; + + return false; +} + + const char * ir_function_signature::qualifiers_match(exec_list *params) { @@ -1391,7 +1406,7 @@ ir_function_signature::qualifiers_match(exec_list *params) ir_variable *b = (ir_variable *)iter_b.get(); if (a->read_only != b->read_only || - a->mode != b->mode || + !modes_match(a->mode, b->mode) || a->interpolation != b->interpolation || a->centroid != b->centroid) { diff --git a/src/glsl/ir.h b/src/glsl/ir.h index 878c1779d85..74a8b06b1a3 100644 --- a/src/glsl/ir.h +++ b/src/glsl/ir.h @@ -222,6 +222,7 @@ enum ir_variable_mode { ir_var_in, ir_var_out, ir_var_inout, + ir_var_const_in, /**< "in" param that must be a constant expression */ ir_var_system_value, /**< Ex: front-face, instance-id, etc. */ ir_var_temporary /**< Temporary variable generated during compilation. */ }; diff --git a/src/glsl/ir_function.cpp b/src/glsl/ir_function.cpp index 8db70119ec2..caee9296af9 100644 --- a/src/glsl/ir_function.cpp +++ b/src/glsl/ir_function.cpp @@ -123,6 +123,7 @@ parameter_lists_match(const exec_list *list_a, const exec_list *list_b) assert(0); return -1; + case ir_var_const_in: case ir_var_in: score = type_compare(param->type, actual->type); break; diff --git a/src/glsl/ir_print_visitor.cpp b/src/glsl/ir_print_visitor.cpp index 630850048f6..82ccc722fa2 100644 --- a/src/glsl/ir_print_visitor.cpp +++ b/src/glsl/ir_print_visitor.cpp @@ -97,7 +97,7 @@ void ir_print_visitor::visit(ir_variable *ir) const char *const cent = (ir->centroid) ? "centroid " : ""; const char *const inv = (ir->invariant) ? "invariant " : ""; const char *const mode[] = { "", "uniform ", "in ", "out ", "inout ", - "sys ", "temporary " }; + "const_in ", "sys ", "temporary " }; const char *const interp[] = { "", "flat", "noperspective" }; printf("(%s%s%s%s) ", diff --git a/src/glsl/ir_reader.cpp b/src/glsl/ir_reader.cpp index 9ed3d23508a..af85e06ae0e 100644 --- a/src/glsl/ir_reader.cpp +++ b/src/glsl/ir_reader.cpp @@ -397,6 +397,8 @@ ir_reader::read_declaration(s_expression *expr) var->mode = ir_var_auto; } else if (strcmp(qualifier->value(), "in") == 0) { var->mode = ir_var_in; + } else if (strcmp(qualifier->value(), "const_in") == 0) { + var->mode = ir_var_const_in; } else if (strcmp(qualifier->value(), "out") == 0) { var->mode = ir_var_out; } else if (strcmp(qualifier->value(), "inout") == 0) { diff --git a/src/glsl/ir_variable.cpp b/src/glsl/ir_variable.cpp index 73da28faf4f..18a3e0fb0d9 100644 --- a/src/glsl/ir_variable.cpp +++ b/src/glsl/ir_variable.cpp @@ -45,6 +45,7 @@ add_variable(const char *name, enum ir_variable_mode mode, int slot, switch (var->mode) { case ir_var_auto: case ir_var_in: + case ir_var_const_in: case ir_var_uniform: case ir_var_system_value: var->read_only = true; diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp index 3d1b8a2f703..c7fb62437db 100644 --- a/src/glsl/linker.cpp +++ b/src/glsl/linker.cpp @@ -299,6 +299,7 @@ mode_string(const ir_variable *var) case ir_var_out: return "shader output"; case ir_var_inout: return "shader inout"; + case ir_var_const_in: case ir_var_temporary: default: assert(!"Should not get here."); diff --git a/src/glsl/lower_variable_index_to_cond_assign.cpp b/src/glsl/lower_variable_index_to_cond_assign.cpp index 147a6aea1ef..8eb1612f0a0 100644 --- a/src/glsl/lower_variable_index_to_cond_assign.cpp +++ b/src/glsl/lower_variable_index_to_cond_assign.cpp @@ -255,6 +255,7 @@ public: case ir_var_uniform: return this->lower_uniforms; case ir_var_in: + case ir_var_const_in: return (var->location == -1) ? this->lower_temps : this->lower_inputs; case ir_var_out: return (var->location == -1) ? this->lower_temps : this->lower_outputs; diff --git a/src/glsl/opt_constant_folding.cpp b/src/glsl/opt_constant_folding.cpp index d69ca75fe03..599b21525de 100644 --- a/src/glsl/opt_constant_folding.cpp +++ b/src/glsl/opt_constant_folding.cpp @@ -122,7 +122,7 @@ ir_constant_folding_visitor::visit_enter(ir_call *ir) ir_rvalue *param_rval = (ir_rvalue *)iter.get(); ir_variable *sig_param = (ir_variable *)sig_iter.get(); - if (sig_param->mode == ir_var_in) { + if (sig_param->mode == ir_var_in || sig_param->mode == ir_var_const_in) { ir_rvalue *new_param = param_rval; handle_rvalue(&new_param); diff --git a/src/glsl/opt_function_inlining.cpp b/src/glsl/opt_function_inlining.cpp index a0449a7427a..2e7831dcbdb 100644 --- a/src/glsl/opt_function_inlining.cpp +++ b/src/glsl/opt_function_inlining.cpp @@ -165,6 +165,7 @@ ir_call::generate_inline(ir_instruction *next_ir) /* Move the actual param into our param variable if it's an 'in' type. */ if (parameters[i] && (sig_param->mode == ir_var_in || + sig_param->mode == ir_var_const_in || sig_param->mode == ir_var_inout)) { ir_assignment *assign; diff --git a/src/glsl/opt_tree_grafting.cpp b/src/glsl/opt_tree_grafting.cpp index ae77408dbea..1ef940f9c72 100644 --- a/src/glsl/opt_tree_grafting.cpp +++ b/src/glsl/opt_tree_grafting.cpp @@ -195,7 +195,7 @@ ir_tree_grafting_visitor::visit_enter(ir_call *ir) ir_rvalue *ir = (ir_rvalue *)iter.get(); ir_rvalue *new_ir = ir; - if (sig_param->mode != ir_var_in) + if (sig_param->mode != ir_var_in && sig_param->mode != ir_var_const_in) continue; if (do_graft(&new_ir)) { |