[Mesa-dev] [PATCH v2 08/13] i965: Handle TCS outputs and TES inputs.
Jordan Justen
jordan.l.justen at intel.com
Sat Dec 12 22:21:19 PST 2015
On 2015-12-11 13:23:57, Kenneth Graunke wrote:
> TCS outputs and TES inputs both refer to a common "patch URB entry"
> shared across all invocations. First, there are some number of
> per-patch entries. Then, there are per-vertex entries accessed via
> an offset for the variable and a stride times the vertex index.
>
> Because these calculations need to be done in both the vec4 and scalar
> backends, it's simpler to just compute the offset calculations in NIR.
> It doesn't necessarily make much sense to use per-vertex intrinsics
> afterwards, but that at least means we don't lose the per-patch vs.
> per-vertex information.
>
> Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
> ---
> src/mesa/drivers/dri/i965/brw_nir.c | 122 +++++++++++++++++++++++++++++++++++-
> 1 file changed, 120 insertions(+), 2 deletions(-)
>
> diff --git a/src/mesa/drivers/dri/i965/brw_nir.c b/src/mesa/drivers/dri/i965/brw_nir.c
> index 9cf4944..e46e177 100644
> --- a/src/mesa/drivers/dri/i965/brw_nir.c
> +++ b/src/mesa/drivers/dri/i965/brw_nir.c
> @@ -133,6 +133,69 @@ remap_inputs_with_vue_map(nir_block *block, void *closure)
> return true;
> }
>
> +struct remap_patch_urb_offsets_state {
> + nir_builder b;
> + struct brw_vue_map vue_map;
> +};
> +
> +static bool
> +remap_patch_urb_offsets(nir_block *block, void *closure)
> +{
> + struct remap_patch_urb_offsets_state *state = closure;
> +
> + nir_foreach_instr_safe(block, instr) {
> + if (instr->type != nir_instr_type_intrinsic)
> + continue;
> +
> + nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
> +
> + bool is_input =
> + intrin->intrinsic == nir_intrinsic_load_input ||
> + intrin->intrinsic == nir_intrinsic_load_per_vertex_input;
> +
> + bool is_output =
> + intrin->intrinsic == nir_intrinsic_load_output ||
> + intrin->intrinsic == nir_intrinsic_load_per_vertex_output ||
> + intrin->intrinsic == nir_intrinsic_store_output ||
> + intrin->intrinsic == nir_intrinsic_store_per_vertex_output;
Can you call the functions you added previously? (i965: Separate base
offset/constant offset combining from remapping.)
7 & 8 Reviewed-by: Jordan Justen <jordan.l.justen at intel.com>
> +
> + if ((state->b.shader->stage == MESA_SHADER_TESS_CTRL && is_output) ||
> + (state->b.shader->stage == MESA_SHADER_TESS_EVAL && is_input)) {
> + int vue_slot = state->vue_map.varying_to_slot[intrin->const_index[0]];
> + assert(vue_slot != -1);
> + intrin->const_index[0] = vue_slot;
> +
> + nir_src *vertex = nir_get_io_vertex_index_src(intrin);
> + if (vertex) {
> + nir_const_value *const_vertex = nir_src_as_const_value(*vertex);
> + if (const_vertex) {
> + intrin->const_index[0] += const_vertex->u[0] *
> + state->vue_map.num_per_vertex_slots;
> + } else {
> + state->b.cursor = nir_before_instr(&intrin->instr);
> +
> + /* Multiply by the number of per-vertex slots. */
> + nir_ssa_def *vertex_offset =
> + nir_imul(&state->b,
> + nir_ssa_for_src(&state->b, *vertex, 1),
> + nir_imm_int(&state->b,
> + state->vue_map.num_per_vertex_slots));
> +
> + /* Add it to the existing offset */
> + nir_src *offset = nir_get_io_offset_src(intrin);
> + nir_ssa_def *total_offset =
> + nir_iadd(&state->b, vertex_offset,
> + nir_ssa_for_src(&state->b, *offset, 1));
> +
> + nir_instr_rewrite_src(&intrin->instr, offset,
> + nir_src_for_ssa(total_offset));
> + }
> + }
> + }
> + }
> + return true;
> +}
> +
> static void
> brw_nir_lower_inputs(nir_shader *nir,
> const struct brw_device_info *devinfo,
> @@ -223,6 +286,31 @@ brw_nir_lower_inputs(nir_shader *nir,
> }
> break;
> }
> + case MESA_SHADER_TESS_EVAL: {
> + struct remap_patch_urb_offsets_state state;
> + brw_compute_tess_vue_map(&state.vue_map,
> + nir->info.inputs_read & ~VARYING_BIT_PRIMITIVE_ID,
> + nir->info.patch_inputs_read);
> +
> + foreach_list_typed(nir_variable, var, node, &nir->inputs) {
> + var->data.driver_location = var->data.location;
> + }
> +
> + nir_lower_io(nir, nir_var_shader_in, type_size_vec4);
> +
> + /* This pass needs actual constants */
> + nir_opt_constant_folding(nir);
> +
> + nir_foreach_overload(nir, overload) {
> + if (overload->impl) {
> + nir_builder_init(¶ms.b, overload->impl);
> + nir_foreach_block(overload->impl, add_const_offset_to_base, ¶ms);
> + nir_builder_init(&state.b, overload->impl);
> + nir_foreach_block(overload->impl, remap_patch_urb_offsets, &state);
> + }
> + }
> + break;
> + }
> case MESA_SHADER_FRAGMENT:
> assert(is_scalar);
> nir_assign_var_locations(&nir->inputs, &nir->num_inputs,
> @@ -238,7 +326,9 @@ brw_nir_lower_inputs(nir_shader *nir,
> }
>
> static void
> -brw_nir_lower_outputs(nir_shader *nir, bool is_scalar)
> +brw_nir_lower_outputs(nir_shader *nir,
> + const struct brw_device_info *devinfo,
> + bool is_scalar)
> {
> switch (nir->stage) {
> case MESA_SHADER_VERTEX:
> @@ -253,6 +343,34 @@ brw_nir_lower_outputs(nir_shader *nir, bool is_scalar)
> var->data.driver_location = var->data.location;
> }
> break;
> + case MESA_SHADER_TESS_CTRL: {
> + struct add_const_offset_to_base_params params = {
> + .mode = nir_var_shader_out
> + };
> +
> + struct remap_patch_urb_offsets_state state;
> + brw_compute_tess_vue_map(&state.vue_map, nir->info.outputs_written,
> + nir->info.patch_outputs_written);
> +
> + nir_foreach_variable(var, &nir->outputs) {
> + var->data.driver_location = var->data.location;
> + }
> +
> + nir_lower_io(nir, nir_var_shader_out, type_size_vec4);
> +
> + /* This pass needs actual constants */
> + nir_opt_constant_folding(nir);
> +
> + nir_foreach_overload(nir, overload) {
> + if (overload->impl) {
> + nir_builder_init(¶ms.b, overload->impl);
> + nir_foreach_block(overload->impl, add_const_offset_to_base, ¶ms);
> + nir_builder_init(&state.b, overload->impl);
> + nir_foreach_block(overload->impl, remap_patch_urb_offsets, &state);
> + }
> + }
> + break;
> + }
> case MESA_SHADER_FRAGMENT:
> nir_assign_var_locations(&nir->outputs, &nir->num_outputs,
> type_size_scalar);
> @@ -420,7 +538,7 @@ brw_lower_nir(nir_shader *nir,
> (void)progress;
>
> OPT_V(brw_nir_lower_inputs, devinfo, is_scalar);
> - OPT_V(brw_nir_lower_outputs, is_scalar);
> + OPT_V(brw_nir_lower_outputs, devinfo, is_scalar);
> OPT_V(brw_nir_lower_uniforms, is_scalar);
> OPT_V(nir_lower_io, nir_var_all, is_scalar ? type_size_scalar : type_size_vec4);
>
> --
> 2.6.3
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
More information about the mesa-dev
mailing list