diff options
author | Paul Berry <[email protected]> | 2013-01-11 14:39:32 -0800 |
---|---|---|
committer | Paul Berry <[email protected]> | 2013-01-24 16:30:30 -0800 |
commit | 42a29d89fd85c86387f0d119950e243b6de76d79 (patch) | |
tree | 9eee8f2d609855dc9c6813aac84f5fdcd6786a54 /src/glsl/ast_to_hir.cpp | |
parent | 7d51ead56e2b97d313c6a0fda22cc930b5c41e9d (diff) |
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 <[email protected]>
Reviewed-by: Jordan Justen <[email protected]>
Reviewed-by: Eric Anholt <[email protected]>
Diffstat (limited to 'src/glsl/ast_to_hir.cpp')
-rw-r--r-- | src/glsl/ast_to_hir.cpp | 64 |
1 files changed, 33 insertions, 31 deletions
diff --git a/src/glsl/ast_to_hir.cpp b/src/glsl/ast_to_hir.cpp index de3ce902e0d..3c2ce15389a 100644 --- a/src/glsl/ast_to_hir.cpp +++ b/src/glsl/ast_to_hir.cpp @@ -1924,11 +1924,11 @@ is_varying_var(ir_variable *var, _mesa_glsl_parser_targets target) { switch (target) { case vertex_shader: - return var->mode == ir_var_out; + return var->mode == ir_var_shader_out; case fragment_shader: - return var->mode == ir_var_in; + return var->mode == ir_var_shader_in; default: - return var->mode == ir_var_out || var->mode == ir_var_in; + return var->mode == ir_var_shader_out || var->mode == ir_var_shader_in; } } @@ -1997,13 +1997,16 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, * the setting alone. */ if (qual->flags.q.in && qual->flags.q.out) - var->mode = ir_var_inout; - else if (qual->flags.q.attribute || qual->flags.q.in + var->mode = ir_var_function_inout; + else if (qual->flags.q.in) + var->mode = is_parameter ? ir_var_function_in : ir_var_shader_in; + else if (qual->flags.q.attribute || (qual->flags.q.varying && (state->target == fragment_shader))) - var->mode = ir_var_in; - else if (qual->flags.q.out - || (qual->flags.q.varying && (state->target == vertex_shader))) - var->mode = ir_var_out; + var->mode = ir_var_shader_in; + else if (qual->flags.q.out) + var->mode = is_parameter ? ir_var_function_out : ir_var_shader_out; + else if (qual->flags.q.varying && (state->target == vertex_shader)) + var->mode = ir_var_shader_out; else if (qual->flags.q.uniform) var->mode = ir_var_uniform; @@ -2058,15 +2061,16 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, if (state->all_invariant && (state->current_function == NULL)) { switch (state->target) { case vertex_shader: - if (var->mode == ir_var_out) + if (var->mode == ir_var_shader_out) var->invariant = true; break; case geometry_shader: - if ((var->mode == ir_var_in) || (var->mode == ir_var_out)) + if ((var->mode == ir_var_shader_in) + || (var->mode == ir_var_shader_out)) var->invariant = true; break; case fragment_shader: - if (var->mode == ir_var_in) + if (var->mode == ir_var_shader_in) var->invariant = true; break; } @@ -2082,8 +2086,8 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, var->interpolation = INTERP_QUALIFIER_NONE; if (var->interpolation != INTERP_QUALIFIER_NONE && - !(state->target == vertex_shader && var->mode == ir_var_out) && - !(state->target == fragment_shader && var->mode == ir_var_in)) { + !(state->target == vertex_shader && var->mode == ir_var_shader_out) && + !(state->target == fragment_shader && var->mode == ir_var_shader_in)) { _mesa_glsl_error(loc, state, "interpolation qualifier `%s' can only be applied to " "vertex shader outputs and fragment shader inputs.", @@ -2116,7 +2120,7 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, */ switch (state->target) { case vertex_shader: - if (!global_scope || (var->mode != ir_var_in)) { + if (!global_scope || (var->mode != ir_var_shader_in)) { fail = true; string = "input"; } @@ -2129,7 +2133,7 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual, break; case fragment_shader: - if (!global_scope || (var->mode != ir_var_out)) { + if (!global_scope || (var->mode != ir_var_shader_out)) { fail = true; string = "output"; } @@ -2440,7 +2444,7 @@ process_initializer(ir_variable *var, ast_declaration *decl, "cannot initialize samplers"); } - if ((var->mode == ir_var_in) && (state->current_function == NULL)) { + if ((var->mode == ir_var_shader_in) && (state->current_function == NULL)) { _mesa_glsl_error(& initializer_loc, state, "cannot initialize %s shader input / %s", _mesa_glsl_shader_target_name(state->target), @@ -2579,12 +2583,12 @@ ast_declarator_list::hir(exec_list *instructions, "Undeclared variable `%s' cannot be marked " "invariant\n", decl->identifier); } else if ((state->target == vertex_shader) - && (earlier->mode != ir_var_out)) { + && (earlier->mode != ir_var_shader_out)) { _mesa_glsl_error(& loc, state, "`%s' cannot be marked invariant, vertex shader " "outputs only\n", decl->identifier); } else if ((state->target == fragment_shader) - && (earlier->mode != ir_var_in)) { + && (earlier->mode != ir_var_shader_in)) { _mesa_glsl_error(& loc, state, "`%s' cannot be marked invariant, fragment shader " "inputs only\n", decl->identifier); @@ -2707,16 +2711,13 @@ ast_declarator_list::hir(exec_list *instructions, & loc, this->ubo_qualifiers_valid, false); if (this->type->qualifier.flags.q.invariant) { - if ((state->target == vertex_shader) && !(var->mode == ir_var_out || - var->mode == ir_var_inout)) { - /* FINISHME: Note that this doesn't work for invariant on - * a function signature outval - */ + if ((state->target == vertex_shader) && + var->mode != ir_var_shader_out) { _mesa_glsl_error(& loc, state, "`%s' cannot be marked invariant, vertex shader " "outputs only\n", var->name); } else if ((state->target == fragment_shader) && - !(var->mode == ir_var_in || var->mode == ir_var_inout)) { + var->mode != ir_var_shader_in) { /* FINISHME: Note that this doesn't work for invariant on * a function signature inval */ @@ -2753,7 +2754,7 @@ ast_declarator_list::hir(exec_list *instructions, "global scope%s", mode, var->name, extra); } - } else if (var->mode == ir_var_in) { + } else if (var->mode == ir_var_shader_in) { var->read_only = true; if (state->target == vertex_shader) { @@ -2833,7 +2834,7 @@ ast_declarator_list::hir(exec_list *instructions, && state->target == vertex_shader && state->current_function == NULL && var->type->is_integer() - && var->mode == ir_var_out + && var->mode == ir_var_shader_out && var->interpolation != INTERP_QUALIFIER_FLAT) { _mesa_glsl_error(&loc, state, "If a vertex output is an integer, " @@ -3137,7 +3138,8 @@ ast_parameter_declarator::hir(exec_list *instructions, } is_void = false; - ir_variable *var = new(ctx) ir_variable(type, this->identifier, ir_var_in); + ir_variable *var = new(ctx) + ir_variable(type, this->identifier, ir_var_function_in); /* Apply any specified qualifiers to the parameter declaration. Note that * for function parameters the default mode is 'in'. @@ -3151,7 +3153,7 @@ ast_parameter_declarator::hir(exec_list *instructions, * as out or inout function parameters, nor can they be assigned * into." */ - if ((var->mode == ir_var_inout || var->mode == ir_var_out) + if ((var->mode == ir_var_function_inout || var->mode == ir_var_function_out) && type->contains_sampler()) { _mesa_glsl_error(&loc, state, "out and inout parameters cannot contain samplers"); type = glsl_type::error_type; @@ -3171,7 +3173,7 @@ ast_parameter_declarator::hir(exec_list *instructions, * So for GLSL 1.10, passing an array as an out or inout parameter is not * allowed. This restriction is removed in GLSL 1.20, and in GLSL ES. */ - if ((var->mode == ir_var_inout || var->mode == ir_var_out) + if ((var->mode == ir_var_function_inout || var->mode == ir_var_function_out) && type->is_array() && !state->check_version(120, 100, &loc, "Arrays cannot be out or inout parameters")) { @@ -4222,7 +4224,7 @@ detect_conflicting_assignments(struct _mesa_glsl_parse_state *state, gl_FragData_assigned = true; else if (strncmp(var->name, "gl_", 3) != 0) { if (state->target == fragment_shader && - (var->mode == ir_var_out || var->mode == ir_var_inout)) { + var->mode == ir_var_shader_out) { user_defined_fs_output_assigned = true; user_defined_fs_output = var; } |