[Mesa-dev] [PATCH 8/8] glsl: Modify ir_set_program_inouts to handle geometry shaders.
Ian Romanick
idr at freedesktop.org
Thu Aug 1 16:03:03 PDT 2013
A couple of comments below. Other than that,
Reviewed-by: Ian Romanick <ian.d.romanick at intel.com>
On 07/31/2013 02:18 PM, Paul Berry wrote:
> ---
> src/glsl/ir_set_program_inouts.cpp | 85 ++++++++++++++++++++++++++++++++------
> 1 file changed, 73 insertions(+), 12 deletions(-)
>
> diff --git a/src/glsl/ir_set_program_inouts.cpp b/src/glsl/ir_set_program_inouts.cpp
> index 018342b..8f96324 100644
> --- a/src/glsl/ir_set_program_inouts.cpp
> +++ b/src/glsl/ir_set_program_inouts.cpp
> @@ -114,7 +114,13 @@ mark(struct gl_program *prog, ir_variable *var, int offset, int len,
> void
> ir_set_program_inouts_visitor::mark_whole_variable(ir_variable *var)
> {
> - mark(this->prog, var, 0, var->type->count_attribute_slots(),
> + const glsl_type *type = var->type;
> + if (this->shader_type == GL_GEOMETRY_SHADER &&
> + var->mode == ir_var_shader_in && type->is_array()) {
> + type = type->fields.array;
> + }
> +
> + mark(this->prog, var, 0, type->count_attribute_slots(),
> this->shader_type == GL_FRAGMENT_SHADER);
> }
>
> @@ -133,7 +139,9 @@ ir_set_program_inouts_visitor::visit(ir_dereference_variable *ir)
> /**
> * Try to mark a portion of the given variable as used. Caller must ensure
> * that the variable represents a shader input or output which can be indexed
> - * into in array fashion (an array, matrix, or vector).
> + * into in array fashion (an array, matrix, or vector). For the purpose of
> + * geometry shader inputs (which are always arrays), this means that the array
> + * element must be something that can be indexed into in array fashion.
Except gl_PrimitiveIDIn, as noted below.
> *
> * 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.
> @@ -144,6 +152,16 @@ ir_set_program_inouts_visitor::try_mark_partial_variable(ir_variable *var,
> {
> const glsl_type *type = var->type;
>
> + if (this->shader_type == GL_GEOMETRY_SHADER &&
> + var->mode == ir_var_shader_in) {
> + /* The only geometry shader input that is not an array is
> + * gl_PrimitiveIDIn, and in that case, this code will never be reached,
> + * because gl_PrimitiveIDIn can't be indexed into in array fashion.
> + */
> + assert(type->is_array());
> + type = type->fields.array;
> + }
> +
> /* The code below only handles:
> *
> * - Indexing into matrices
> @@ -205,17 +223,60 @@ ir_set_program_inouts_visitor::try_mark_partial_variable(ir_variable *var,
> ir_visitor_status
> ir_set_program_inouts_visitor::visit_enter(ir_dereference_array *ir)
> {
> - ir_dereference_variable *deref_var;
> - deref_var = ir->array->as_dereference_variable();
> - ir_variable *var = deref_var ? deref_var->var : NULL;
> -
> - /* Check that we're dereferencing a shader in or out */
> - if (!var || !is_shader_inout(var))
> - return visit_continue;
> -
> - if (try_mark_partial_variable(var, ir->array_index))
> - return visit_continue_with_parent;
> + /* Note: for geometry shader inputs, lower_named_interface_blocks may
> + * create 2D arrays, so we need to be able to handle those. 2D arrays
> + * shouldn't be able to crop up for any other reason.
> + */
> + if (ir_dereference_array *inner_array =
> + ir->array->as_dereference_array()) {
'ir_dereference_array *const'?
I'm not sure whether I love or hate this style. I seem some significant
advantages to it (the big one being the limited scope of the variable),
but it has some stylistic issues (the long if-condition). Having an
assignment in an if-condition also feels icky.
I guess it's pretty similar to what we already do with for-loops, so I'm
leaning towards liking it.
> + /* ir => foo[i][j]
> + * inner_array => foo[i]
> + */
> + if (ir_dereference_variable *deref_var =
> + inner_array->as_dereference_variable()) {
> + if (this->shader_type == GL_GEOMETRY_SHADER &&
> + deref_var->var->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 (try_mark_partial_variable(deref_var->var, ir->array_index))
> + {
> + /* We've now taken care of foo and j, but i might contain a
> + * subexpression that accesses shader inputs. So manually
> + * visit i and then continue with the parent.
> + */
> + inner_array->array_index->accept(this);
> + return visit_continue_with_parent;
> + }
> + }
> + }
> + } else if (ir_dereference_variable *deref_var =
> + ir->as_dereference_variable()) {
> + /* ir => foo[i], where foo is a variable. */
> + if (this->shader_type == GL_GEOMETRY_SHADER &&
> + deref_var->var->mode == ir_var_shader_in) {
> + /* foo is a geometry 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
> + * that accesses shader inputs. So manually visit i and then
> + * continue with the parent.
> + */
> + ir->array_index->accept(this);
> + return visit_continue_with_parent;
> + } else if (is_shader_inout(deref_var->var)) {
> + /* foo is a shader input/output, but not a geometry shader input,
> + * so i is the part of the input we're accessing.
> + */
> + if (try_mark_partial_variable(deref_var->var, ir->array_index))
> + return visit_continue_with_parent;
> + }
> + }
>
> + /* The expression is something we don't recognize. Just visit its
> + * subexpressions.
> + */
> return visit_continue;
> }
>
>
More information about the mesa-dev
mailing list