<p dir="ltr"><br>
On Aug 17, 2015 4:08 PM, "Kenneth Graunke" <<a href="mailto:kenneth@whitecape.org">kenneth@whitecape.org</a>> wrote:<br>
><br>
> Previously, we used nir_lower_io with the scalar type_size function,<br>
> which mapped VERT_ATTRIB_* locations to...some numbers. Then, in<br>
> fs_visitor::nir_setup_inputs(), we created temporaries indexed by<br>
> those numbers, and emitted MOVs from the actual ATTR registers to<br>
> those temporaries.<br>
><br>
> This patch reworks our input lowering to produce NIR lower_input<br>
> intrinsics that properly index into the ATTR file, so we can access<br>
> it directly.<br>
><br>
> No changes in shader-db.<br>
><br>
> Signed-off-by: Kenneth Graunke <<a href="mailto:kenneth@whitecape.org">kenneth@whitecape.org</a>><br>
> ---<br>
> src/mesa/drivers/dri/i965/brw_fs.cpp | 2 +-<br>
> src/mesa/drivers/dri/i965/brw_fs_nir.cpp | 71 +++++++++-----------------------<br>
> src/mesa/drivers/dri/i965/brw_nir.c | 25 ++++++++++-<br>
> 3 files changed, 45 insertions(+), 53 deletions(-)<br>
><br>
> diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp<br>
> index 93adbc6..efabb52 100644<br>
> --- a/src/mesa/drivers/dri/i965/brw_fs.cpp<br>
> +++ b/src/mesa/drivers/dri/i965/brw_fs.cpp<br>
> @@ -4527,7 +4527,7 @@ fs_visitor::dump_instruction(backend_instruction *be_inst, FILE *file)<br>
> fprintf(file, "***m%d***", inst->src[i].reg);<br>
> break;<br>
> case ATTR:<br>
> - fprintf(file, "attr%d", inst->src[i].reg + inst->src[i].reg_offset);<br>
> + fprintf(file, "attr%d+%d", inst->src[i].reg, inst->src[i].reg_offset);</p>
<p dir="ltr">This should probably be its own patch.</p>
<p dir="ltr">> break;<br>
> case UNIFORM:<br>
> fprintf(file, "u%d", inst->src[i].reg + inst->src[i].reg_offset);<br>
> diff --git a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp<br>
> index 51ba23b..397cdcb 100644<br>
> --- a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp<br>
> +++ b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp<br>
> @@ -56,61 +56,25 @@ fs_visitor::emit_nir_code()<br>
> void<br>
> fs_visitor::nir_setup_inputs(nir_shader *shader)<br>
> {<br>
> + if (stage != MESA_SHADER_FRAGMENT)<br>
> + return;<br>
> +<br>
> nir_inputs = bld.vgrf(BRW_REGISTER_TYPE_F, shader->num_inputs);<br>
><br>
> foreach_list_typed(nir_variable, var, node, &shader->inputs) {<br>
> - enum brw_reg_type type = brw_type_for_base_type(var->type);<br>
> fs_reg input = offset(nir_inputs, bld, var->data.driver_location);<br>
><br>
> fs_reg reg;<br>
> - switch (stage) {<br>
> - case MESA_SHADER_VERTEX: {<br>
> - /* Our ATTR file is indexed by VERT_ATTRIB_*, which is the value<br>
> - * stored in nir_variable::location.<br>
> - *<br>
> - * However, NIR's load_input intrinsics use a different index - an<br>
> - * offset into a single contiguous array containing all inputs.<br>
> - * This index corresponds to the nir_variable::driver_location field.<br>
> - *<br>
> - * So, we need to copy from fs_reg(ATTR, var->location) to<br>
> - * offset(nir_inputs, var->data.driver_location).<br>
> - */<br>
> - const glsl_type *const t = var->type->without_array();<br>
> - const unsigned components = t->components();<br>
> - const unsigned cols = t->matrix_columns;<br>
> - const unsigned elts = t->vector_elements;<br>
> - unsigned array_length = var->type->is_array() ? var->type->length : 1;<br>
> - for (unsigned i = 0; i < array_length; i++) {<br>
> - for (unsigned j = 0; j < cols; j++) {<br>
> - for (unsigned k = 0; k < elts; k++) {<br>
> - bld.MOV(offset(retype(input, type), bld,<br>
> - components * i + elts * j + k),<br>
> - offset(fs_reg(ATTR, var->data.location + i, type),<br>
> - bld, 4 * j + k));<br>
> - }<br>
> - }<br>
> - }<br>
> - break;<br>
> - }<br>
> - case MESA_SHADER_GEOMETRY:<br>
> - case MESA_SHADER_COMPUTE:<br>
> - case MESA_SHADER_TESS_CTRL:<br>
> - case MESA_SHADER_TESS_EVAL:<br>
> - unreachable("fs_visitor not used for these stages yet.");<br>
> - break;<br>
> - case MESA_SHADER_FRAGMENT:<br>
> - if (var->data.location == VARYING_SLOT_POS) {<br>
> - reg = *emit_fragcoord_interpolation(var->data.pixel_center_integer,<br>
> - var->data.origin_upper_left);<br>
> - emit_percomp(bld, fs_inst(BRW_OPCODE_MOV, bld.dispatch_width(),<br>
> - input, reg), 0xF);<br>
> - } else {<br>
> - emit_general_interpolation(input, var->name, var->type,<br>
> - (glsl_interp_qualifier) var->data.interpolation,<br>
> - var->data.location, var->data.centroid,<br>
> - var->data.sample);<br>
> - }<br>
> - break;<br>
> + if (var->data.location == VARYING_SLOT_POS) {<br>
> + reg = *emit_fragcoord_interpolation(var->data.pixel_center_integer,<br>
> + var->data.origin_upper_left);<br>
> + emit_percomp(bld, fs_inst(BRW_OPCODE_MOV, bld.dispatch_width(),<br>
> + input, reg), 0xF);<br>
> + } else {<br>
> + emit_general_interpolation(input, var->name, var->type,<br>
> + (glsl_interp_qualifier) var->data.interpolation,<br>
> + var->data.location, var->data.centroid,<br>
> + var->data.sample);<br>
> }<br>
> }<br>
> }<br>
> @@ -1557,8 +1521,13 @@ fs_visitor::nir_emit_intrinsic(const fs_builder &bld, nir_intrinsic_instr *instr<br>
> case nir_intrinsic_load_input: {<br>
> unsigned index = 0;<br>
> for (unsigned j = 0; j < instr->num_components; j++) {<br>
> - fs_reg src = offset(retype(nir_inputs, dest.type), bld,<br>
> - instr->const_index[0] + index);<br>
> + fs_reg src;<br>
> + if (stage == MESA_SHADER_VERTEX) {</p>
<p dir="ltr">== FRAGMENT should be the if case and ATTR should be the else to match the logic in nir_lower_io.</p>
<p dir="ltr">> + src = offset(fs_reg(ATTR, instr->const_index[0], dest.type), bld, index);<br>
> + } else {<br>
> + src = offset(retype(nir_inputs, dest.type), bld,<br>
> + instr->const_index[0] + index);<br>
> + }<br>
> if (has_indirect)<br>
> src.reladdr = new(mem_ctx) fs_reg(get_nir_src(instr->src[0]));<br>
> index++;<br>
> diff --git a/src/mesa/drivers/dri/i965/brw_nir.c b/src/mesa/drivers/dri/i965/brw_nir.c<br>
> index 224c207..2e2d02b 100644<br>
> --- a/src/mesa/drivers/dri/i965/brw_nir.c<br>
> +++ b/src/mesa/drivers/dri/i965/brw_nir.c<br>
> @@ -28,14 +28,37 @@<br>
> #include "program/prog_to_nir.h"<br>
><br>
> static void<br>
> +lower_scalar_vs_inputs(nir_shader *nir)<br>
> +{<br>
> + /* Start with the location of the variable's base. */<br>
> + foreach_list_typed(nir_variable, var, node, &nir->inputs) {<br>
> + var->data.driver_location = var->data.location;<br>
> + }<br>
> +<br>
> + /* Now use nir_lower_io to walk dereference chains. Attribute arrays<br>
> + * are loaded as one vec4 per element (or matrix column), so we use<br>
> + * type_size_vec4 here.<br>
> + */<br>
> + nir_lower_io(nir, nir_var_shader_in, type_size_vec4);<br>
> +}<br>
> +<br>
> +static void<br>
> brw_lower_nir_io_scalar(nir_shader *nir, gl_shader_stage stage)<br>
> {<br>
> nir_assign_var_locations_direct_first(nir, &nir->uniforms,<br>
> &nir->num_direct_uniforms,<br>
> &nir->num_uniforms,<br>
> type_size_scalar);<br>
> - nir_assign_var_locations(&nir->inputs, &nir->num_inputs, type_size_scalar);<br>
> nir_assign_var_locations(&nir->outputs, &nir->num_outputs, type_size_scalar);<br>
> +<br>
> + switch (stage) {<br>
> + case MESA_SHADER_VERTEX:<br>
> + lower_scalar_vs_inputs(nir);<br>
> + break;<br>
> + default:<br>
> + nir_assign_var_locations(&nir->inputs, &nir->num_inputs, type_size_scalar);<br>
> + break;<br>
> + }<br>
> nir_lower_io(nir, -1, type_size_scalar);<br>
> }<br>
><br>
> --<br>
> 2.5.0<br>
><br>
> _______________________________________________<br>
> mesa-dev mailing list<br>
><a href="mailto:mesa-dev@lists.freedesktop.org"> mesa-dev@lists.freedesktop.org</a><br>
><a href="http://lists.freedesktop.org/mailman/listinfo/mesa-dev"> http://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</p>