glsl: Eliminate ambiguity between function ins/outs and shader ins/outs

This patch replaces the three ir_variable_mode enums:

- ir_var_in
- ir_var_out
- ir_var_inout

with the following five:

- ir_var_shader_in
- ir_var_shader_out
- ir_var_function_in
- ir_var_function_out
- ir_var_function_inout

This eliminates a frustrating ambiguity: it used to be impossible to
tell whether an ir_var_{in,out} variable was a shader in/out or a
function in/out without seeing where the variable was declared in the
IR.  This complicated some optimization and lowering passes, and would
have become a problem for implementing varying structs.

In the lisp-style serialization of GLSL IR to strings performed by
ir_print_visitor.cpp and ir_reader.cpp, I've retained the names "in",
"out", and "inout" for function parameters, to avoid introducing code
churn to the src/glsl/builtins/ir/ directory.

Note: a couple of comments in the code seemed to indicate that we were
planning for a possible future in which geometry shaders could have
shader-scope inout variables.  Our GLSL grammar rejects shader-scope
inout variables, and I've been unable to find any evidence in the GLSL
standards documents (or extensions) that this will ever be allowed, so
I've eliminated these comments.

Reviewed-by: Carl Worth <cworth@cworth.org>
Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
Reviewed-by: Eric Anholt <eric@anholt.net>
This commit is contained in:
Paul Berry
2013-01-11 14:39:32 -08:00
parent 7d51ead56e
commit 42a29d89fd
31 changed files with 205 additions and 193 deletions

View File

@@ -132,12 +132,13 @@ verify_parameter_modes(_mesa_glsl_parse_state *state,
}
/* Verify that 'out' and 'inout' actual parameters are lvalues. */
if (formal->mode == ir_var_out || formal->mode == ir_var_inout) {
if (formal->mode == ir_var_function_out
|| formal->mode == ir_var_function_inout) {
const char *mode = NULL;
switch (formal->mode) {
case ir_var_out: mode = "out"; break;
case ir_var_inout: mode = "inout"; break;
default: assert(false); break;
case ir_var_function_out: mode = "out"; break;
case ir_var_function_inout: mode = "inout"; break;
default: assert(false); break;
}
/* This AST-based check catches errors like f(i++). The IR-based
@@ -210,13 +211,13 @@ generate_call(exec_list *instructions, ir_function_signature *sig,
if (formal->type->is_numeric() || formal->type->is_boolean()) {
switch (formal->mode) {
case ir_var_const_in:
case ir_var_in: {
case ir_var_function_in: {
ir_rvalue *converted
= convert_component(actual, formal->type);
actual->replace_with(converted);
break;
}
case ir_var_out:
case ir_var_function_out:
if (actual->type != formal->type) {
/* To convert an out parameter, we need to create a
* temporary variable to hold the value before conversion,
@@ -254,7 +255,7 @@ generate_call(exec_list *instructions, ir_function_signature *sig,
actual->replace_with(deref_tmp_2);
}
break;
case ir_var_inout:
case ir_var_function_inout:
/* Inout parameters should never require conversion, since that
* would require an implicit conversion to exist both to and
* from the formal parameter type, and there are no