This will be used to store the total number of components used at this location when packing via ARB_enhanced_layouts. --- src/compiler/glsl/glsl_to_nir.cpp | 1 + src/compiler/glsl/ir.h | 5 +++ src/compiler/glsl/link_varyings.cpp | 74 ++++++++++++++++++++++++++++++++++++- src/compiler/glsl/linker.cpp | 2 + src/compiler/glsl/linker.h | 4 ++ src/compiler/nir/nir.h | 5 +++ 6 files changed, 89 insertions(+), 2 deletions(-)
diff --git a/src/compiler/glsl/glsl_to_nir.cpp b/src/compiler/glsl/glsl_to_nir.cpp index 20302e3..baba624 100644 --- a/src/compiler/glsl/glsl_to_nir.cpp +++ b/src/compiler/glsl/glsl_to_nir.cpp @@ -375,6 +375,7 @@ nir_visitor::visit(ir_variable *ir) var->data.explicit_binding = ir->data.explicit_binding; var->data.has_initializer = ir->data.has_initializer; var->data.location_frac = ir->data.location_frac; + var->data.num_packed_components = ir->data.num_packed_components; switch (ir->data.depth_layout) { case ir_depth_layout_none: diff --git a/src/compiler/glsl/ir.h b/src/compiler/glsl/ir.h index 1325e35..637b53c 100644 --- a/src/compiler/glsl/ir.h +++ b/src/compiler/glsl/ir.h @@ -770,6 +770,11 @@ public: unsigned location_frac:2; /** + * The total number of components packed into this location. + */ + unsigned num_packed_components:4; + + /** * Layout of the matrix. Uses glsl_matrix_layout values. */ unsigned matrix_layout:2; diff --git a/src/compiler/glsl/link_varyings.cpp b/src/compiler/glsl/link_varyings.cpp index 76d0be1..35f97a9 100644 --- a/src/compiler/glsl/link_varyings.cpp +++ b/src/compiler/glsl/link_varyings.cpp @@ -1975,6 +1975,70 @@ reserved_varying_slot(struct gl_linked_shader *stage, return slots; } +void +set_num_packed_components(struct gl_shader *shader, ir_variable_mode io_mode, + unsigned base_offset) +{ + /* Find the max number of components used at this location */ + unsigned num_components[MAX_VARYINGS_INCL_PATCH] = { 0 }; + + foreach_in_list(ir_instruction, node, shader->ir) { + ir_variable *const var = node->as_variable(); + + if (var == NULL || var->data.mode != io_mode || + !var->data.explicit_location) + continue; + + int idx = var->data.location - base_offset; + if (idx < 0 || idx >= MAX_VARYINGS_INCL_PATCH || + var->type->without_array()->is_record() || + var->type->without_array()->is_matrix()) + continue; + + if (var->type->is_array()) { + const glsl_type *type = get_varying_type(var, shader->Stage); + unsigned array_components = type->without_array()->vector_elements + + var->data.location_frac; + assert(type->arrays_of_arrays_size() + idx <= + ARRAY_SIZE(num_components)); + for (unsigned i = idx; i < type->arrays_of_arrays_size(); i++) { + num_components[i] = MAX2(array_components, num_components[i]); + } + } else { + unsigned comps = var->type->vector_elements + + var->data.location_frac; + num_components[idx] = MAX2(comps, num_components[idx]); + } + } + + foreach_in_list(ir_instruction, node, shader->ir) { + ir_variable *const var = node->as_variable(); + + if (var == NULL || var->data.mode != io_mode || + !var->data.explicit_location) + continue; + + int idx = var->data.location - base_offset; + if (idx < 0 || idx >= MAX_VARYINGS_INCL_PATCH || + var->type->without_array()->is_record() || + var->type->without_array()->is_matrix()) + continue; + + /* For arrays we need to check all elements in order to find the max + * number of components used. + */ + unsigned c = 0; + if (var->type->is_array()) { + const glsl_type *type = get_varying_type(var, shader->Stage); + for (unsigned i = idx; i < type->arrays_of_arrays_size(); i++) { + c = MAX2(c, num_components[i]); + } + } else { + c = num_components[idx]; + } + var->data.num_packed_components = c; + } +} /** * Assign locations for all variables that are produced in one pipeline stage @@ -2091,11 +2155,17 @@ assign_varying_locations(struct gl_context *ctx, * 4. Mark input variables in the consumer that do not have locations as * not being inputs. This lets the optimizer eliminate them. */ - if (consumer) + if (consumer) { canonicalize_shader_io(consumer->ir, ir_var_shader_in); + set_num_packed_components(consumer, ir_var_shader_in, + VARYING_SLOT_VAR0); + } - if (producer) + if (producer) { canonicalize_shader_io(producer->ir, ir_var_shader_out); + set_num_packed_components(producer, ir_var_shader_out, + VARYING_SLOT_VAR0); + } if (consumer) linker::populate_consumer_input_sets(mem_ctx, consumer->ir, diff --git a/src/compiler/glsl/linker.cpp b/src/compiler/glsl/linker.cpp index d963f54..d8bb58b 100644 --- a/src/compiler/glsl/linker.cpp +++ b/src/compiler/glsl/linker.cpp @@ -2625,6 +2625,8 @@ assign_attribute_or_color_locations(gl_shader_program *prog, (target_index == MESA_SHADER_VERTEX) ? ir_var_shader_in : ir_var_shader_out; + set_num_packed_components(sh, direction, generic_base); + /* Temporary storage for the set of attributes that need locations assigned. */ diff --git a/src/compiler/glsl/linker.h b/src/compiler/glsl/linker.h index e1a53d2..056ce97 100644 --- a/src/compiler/glsl/linker.h +++ b/src/compiler/glsl/linker.h @@ -86,6 +86,10 @@ extern void link_check_atomic_counter_resources(struct gl_context *ctx, struct gl_shader_program *prog); +void +set_num_packed_components(struct gl_shader *shader, ir_variable_mode io_mode, + unsigned base_offset); + /** * Class for processing all of the leaf fields of a variable that corresponds * to a program resource. diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index a7921ee..2bfedb2 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -227,6 +227,11 @@ typedef struct nir_variable { unsigned location_frac:2; /** + * The total number of components packed into this location. + */ + unsigned num_packed_components:4; + + /** * \brief Layout qualifier for gl_FragDepth. * * This is not equal to \c ir_depth_layout_none if and only if this -- 2.7.4 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev