diff options
author | Fabian Bieler <[email protected]> | 2014-03-05 13:43:17 +0100 |
---|---|---|
committer | Marek Olšák <[email protected]> | 2015-07-23 00:59:26 +0200 |
commit | 1009b3311febe3909e82d4b5be38ceecad6afcc1 (patch) | |
tree | c5efbaf2e95c6656617e3b4efd2b3bb8372d53fc /src/glsl/ir_set_program_inouts.cpp | |
parent | 1036b024d4c8ce2376ac41219dfda01d5a59b3ef (diff) |
glsl: add the patch in/out qualifier (v2)
v2: Dropped some unrelated reordering in glsl_parser.yy as Ken suggested.
Reviewed-by: Kenneth Graunke <[email protected]>
Diffstat (limited to 'src/glsl/ir_set_program_inouts.cpp')
-rw-r--r-- | src/glsl/ir_set_program_inouts.cpp | 69 |
1 files changed, 61 insertions, 8 deletions
diff --git a/src/glsl/ir_set_program_inouts.cpp b/src/glsl/ir_set_program_inouts.cpp index b968a1efd3e..fe4d6da45db 100644 --- a/src/glsl/ir_set_program_inouts.cpp +++ b/src/glsl/ir_set_program_inouts.cpp @@ -140,6 +140,24 @@ ir_set_program_inouts_visitor::mark_whole_variable(ir_variable *var) type = type->fields.array; } + if (this->shader_stage == MESA_SHADER_TESS_CTRL && + var->data.mode == ir_var_shader_in) { + assert(type->is_array()); + type = type->fields.array; + } + + if (this->shader_stage == MESA_SHADER_TESS_CTRL && + var->data.mode == ir_var_shader_out && !var->data.patch) { + assert(type->is_array()); + type = type->fields.array; + } + + if (this->shader_stage == MESA_SHADER_TESS_EVAL && + var->data.mode == ir_var_shader_in && !var->data.patch) { + assert(type->is_array()); + type = type->fields.array; + } + mark(this->prog, var, 0, type->count_attribute_slots(), this->shader_stage == MESA_SHADER_FRAGMENT); } @@ -165,6 +183,9 @@ ir_set_program_inouts_visitor::visit(ir_dereference_variable *ir) * * *Except gl_PrimitiveIDIn, as noted below. * + * For tessellation control shaders all inputs and non-patch outputs are + * arrays. For tessellation evaluation shaders non-patch inputs are arrays. + * * If the index can't be interpreted as a constant, or some other problem * occurs, then nothing will be marked and false will be returned. */ @@ -184,6 +205,24 @@ ir_set_program_inouts_visitor::try_mark_partial_variable(ir_variable *var, type = type->fields.array; } + if (this->shader_stage == MESA_SHADER_TESS_CTRL && + var->data.mode == ir_var_shader_in) { + assert(type->is_array()); + type = type->fields.array; + } + + if (this->shader_stage == MESA_SHADER_TESS_CTRL && + var->data.mode == ir_var_shader_out && !var->data.patch) { + assert(type->is_array()); + type = type->fields.array; + } + + if (this->shader_stage == MESA_SHADER_TESS_EVAL && + var->data.mode == ir_var_shader_in && !var->data.patch) { + assert(type->is_array()); + type = type->fields.array; + } + /* The code below only handles: * * - Indexing into matrices @@ -242,6 +281,22 @@ ir_set_program_inouts_visitor::try_mark_partial_variable(ir_variable *var, return true; } +static bool +is_multiple_vertices(gl_shader_stage stage, ir_variable *var) +{ + if (var->data.patch) + return false; + + if (var->data.mode == ir_var_shader_in) + return stage == MESA_SHADER_GEOMETRY || + stage == MESA_SHADER_TESS_CTRL || + stage == MESA_SHADER_TESS_EVAL; + if (var->data.mode == ir_var_shader_out) + return stage == MESA_SHADER_TESS_CTRL; + + return false; +} + ir_visitor_status ir_set_program_inouts_visitor::visit_enter(ir_dereference_array *ir) { @@ -256,10 +311,9 @@ ir_set_program_inouts_visitor::visit_enter(ir_dereference_array *ir) */ if (ir_dereference_variable * const deref_var = inner_array->array->as_dereference_variable()) { - if (this->shader_stage == MESA_SHADER_GEOMETRY && - deref_var->var->data.mode == ir_var_shader_in) { - /* foo is a geometry shader input, so i is the vertex, and j the - * part of the input we're accessing. + if (is_multiple_vertices(this->shader_stage, deref_var->var)) { + /* foo is a geometry or tessellation shader input, so i is + * the vertex, and j the part of the input we're accessing. */ if (try_mark_partial_variable(deref_var->var, ir->array_index)) { @@ -275,10 +329,9 @@ ir_set_program_inouts_visitor::visit_enter(ir_dereference_array *ir) } else if (ir_dereference_variable * const deref_var = ir->array->as_dereference_variable()) { /* ir => foo[i], where foo is a variable. */ - if (this->shader_stage == MESA_SHADER_GEOMETRY && - deref_var->var->data.mode == ir_var_shader_in) { - /* foo is a geometry shader input, so i is the vertex, and we're - * accessing the entire input. + if (is_multiple_vertices(this->shader_stage, deref_var->var)) { + /* foo is a geometry or tessellation shader input, so i is + * the vertex, and we're accessing the entire input. */ mark_whole_variable(deref_var->var); /* We've now taken care of foo, but i might contain a subexpression |