[Mesa-dev] [PATCH 4/9] i965/fs: Lower gl_VertexID and friends to inputs at the NIR level

Kenneth Graunke kenneth at whitecape.org
Fri May 5 23:17:07 UTC 2017


On Thursday, May 4, 2017 7:11:42 PM PDT Jason Ekstrand wrote:
> NIR calls these system values but they come in from the VF unit as
> vertex data.  It's terribly convenient to just be able to treat them as
> such in the back-end.
> ---
>  src/intel/compiler/brw_fs.h           |  1 -
>  src/intel/compiler/brw_fs_nir.cpp     | 30 +--------------
>  src/intel/compiler/brw_fs_visitor.cpp | 38 ------------------
>  src/intel/compiler/brw_nir.c          | 72 ++++++++++++++++++++++++++++++++++-
>  4 files changed, 71 insertions(+), 70 deletions(-)
> 
> diff --git a/src/intel/compiler/brw_fs.h b/src/intel/compiler/brw_fs.h
> index e230b5e..6c8c027 100644
> --- a/src/intel/compiler/brw_fs.h
> +++ b/src/intel/compiler/brw_fs.h
> @@ -175,7 +175,6 @@ public:
>     fs_reg *emit_samplepos_setup();
>     fs_reg *emit_sampleid_setup();
>     fs_reg *emit_samplemaskin_setup();
> -   fs_reg *emit_vs_system_value(int location);
>     void emit_interpolation_setup_gen4();
>     void emit_interpolation_setup_gen6();
>     void compute_sample_position(fs_reg dst, fs_reg int_sample_pos);
> diff --git a/src/intel/compiler/brw_fs_nir.cpp b/src/intel/compiler/brw_fs_nir.cpp
> index 3ab41df..d4ce753 100644
> --- a/src/intel/compiler/brw_fs_nir.cpp
> +++ b/src/intel/compiler/brw_fs_nir.cpp
> @@ -89,39 +89,11 @@ emit_system_values_block(nir_block *block, fs_visitor *v)
>           unreachable("should be lowered by lower_vertex_id().");
>  
>        case nir_intrinsic_load_vertex_id_zero_base:
> -         assert(v->stage == MESA_SHADER_VERTEX);
> -         reg = &v->nir_system_values[SYSTEM_VALUE_VERTEX_ID_ZERO_BASE];
> -         if (reg->file == BAD_FILE)
> -            *reg = *v->emit_vs_system_value(SYSTEM_VALUE_VERTEX_ID_ZERO_BASE);
> -         break;
> -
>        case nir_intrinsic_load_base_vertex:
> -         assert(v->stage == MESA_SHADER_VERTEX);
> -         reg = &v->nir_system_values[SYSTEM_VALUE_BASE_VERTEX];
> -         if (reg->file == BAD_FILE)
> -            *reg = *v->emit_vs_system_value(SYSTEM_VALUE_BASE_VERTEX);
> -         break;
> -
>        case nir_intrinsic_load_instance_id:
> -         assert(v->stage == MESA_SHADER_VERTEX);
> -         reg = &v->nir_system_values[SYSTEM_VALUE_INSTANCE_ID];
> -         if (reg->file == BAD_FILE)
> -            *reg = *v->emit_vs_system_value(SYSTEM_VALUE_INSTANCE_ID);
> -         break;
> -
>        case nir_intrinsic_load_base_instance:
> -         assert(v->stage == MESA_SHADER_VERTEX);
> -         reg = &v->nir_system_values[SYSTEM_VALUE_BASE_INSTANCE];
> -         if (reg->file == BAD_FILE)
> -            *reg = *v->emit_vs_system_value(SYSTEM_VALUE_BASE_INSTANCE);
> -         break;
> -
>        case nir_intrinsic_load_draw_id:
> -         assert(v->stage == MESA_SHADER_VERTEX);
> -         reg = &v->nir_system_values[SYSTEM_VALUE_DRAW_ID];
> -         if (reg->file == BAD_FILE)
> -            *reg = *v->emit_vs_system_value(SYSTEM_VALUE_DRAW_ID);
> -         break;
> +         unreachable("should be lowered by brw_nir_lower_vs_inputs().");
>  
>        case nir_intrinsic_load_invocation_id:
>           if (v->stage == MESA_SHADER_TESS_CTRL)
> diff --git a/src/intel/compiler/brw_fs_visitor.cpp b/src/intel/compiler/brw_fs_visitor.cpp
> index 7904434..b6524d2 100644
> --- a/src/intel/compiler/brw_fs_visitor.cpp
> +++ b/src/intel/compiler/brw_fs_visitor.cpp
> @@ -32,44 +32,6 @@
>  
>  using namespace brw;
>  
> -fs_reg *
> -fs_visitor::emit_vs_system_value(int location)
> -{
> -   fs_reg *reg = new(this->mem_ctx)
> -      fs_reg(ATTR, 4 * _mesa_bitcount_64(nir->info->inputs_read),
> -             BRW_REGISTER_TYPE_D);
> -
> -   switch (location) {
> -   case SYSTEM_VALUE_BASE_VERTEX:
> -      reg->offset = 0;
> -      break;
> -   case SYSTEM_VALUE_BASE_INSTANCE:
> -      reg->offset = REG_SIZE;
> -      break;
> -   case SYSTEM_VALUE_VERTEX_ID:
> -      unreachable("should have been lowered");
> -   case SYSTEM_VALUE_VERTEX_ID_ZERO_BASE:
> -      reg->offset = 2 * REG_SIZE;
> -      break;
> -   case SYSTEM_VALUE_INSTANCE_ID:
> -      reg->offset = 3 * REG_SIZE;
> -      break;
> -   case SYSTEM_VALUE_DRAW_ID:
> -      if (nir->info->system_values_read &
> -          (BITFIELD64_BIT(SYSTEM_VALUE_BASE_VERTEX) |
> -           BITFIELD64_BIT(SYSTEM_VALUE_BASE_INSTANCE) |
> -           BITFIELD64_BIT(SYSTEM_VALUE_VERTEX_ID_ZERO_BASE) |
> -           BITFIELD64_BIT(SYSTEM_VALUE_INSTANCE_ID)))
> -         reg->nr += 4;
> -      reg->offset = 0;
> -      break;
> -   default:
> -      unreachable("not reached");
> -   }
> -
> -   return reg;
> -}
> -
>  /* Sample from the MCS surface attached to this multisample texture. */
>  fs_reg
>  fs_visitor::emit_mcs_fetch(const fs_reg &coordinate, unsigned components,
> diff --git a/src/intel/compiler/brw_nir.c b/src/intel/compiler/brw_nir.c
> index 7248594..556782e 100644
> --- a/src/intel/compiler/brw_nir.c
> +++ b/src/intel/compiler/brw_nir.c
> @@ -259,18 +259,81 @@ brw_nir_lower_vs_inputs(nir_shader *nir,
>     if (!is_scalar)
>        return;
>  
> +   const bool has_svgs =

has_sgvs (SGVs = System Generated Values)

> +      nir->info->system_values_read &
> +      (BITFIELD64_BIT(SYSTEM_VALUE_BASE_VERTEX) |
> +       BITFIELD64_BIT(SYSTEM_VALUE_BASE_INSTANCE) |
> +       BITFIELD64_BIT(SYSTEM_VALUE_VERTEX_ID_ZERO_BASE) |
> +       BITFIELD64_BIT(SYSTEM_VALUE_INSTANCE_ID));

Maybe a comment that DrawID is intentionally excluded?

> +
> +   const unsigned num_inputs = _mesa_bitcount_64(nir->info->inputs_read);
> +
>     nir_foreach_function(function, nir) {
>        if (!function->impl)
>           continue;
>  
> +      nir_builder b;
> +      nir_builder_init(&b, function->impl);
> +
>        nir_foreach_block(block, function->impl) {
> -         nir_foreach_instr(instr, block) {
> +         nir_foreach_instr_safe(instr, block) {
>              if (instr->type != nir_instr_type_intrinsic)
>                 continue;
>  
>              nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
>  
> -            if (intrin->intrinsic == nir_intrinsic_load_input) {
> +            switch (intrin->intrinsic) {
> +            case nir_intrinsic_load_base_vertex:
> +            case nir_intrinsic_load_base_instance:
> +            case nir_intrinsic_load_vertex_id_zero_base:
> +            case nir_intrinsic_load_instance_id:
> +            case nir_intrinsic_load_draw_id: {
> +               b.cursor = nir_after_instr(&intrin->instr);
> +
> +               /* gl_VertexID and friends are stored by the VF as the last
> +                * vertex element.  We convert them to load_input intrinsics at
> +                * the right location.
> +                */
> +               nir_intrinsic_instr *load =
> +                  nir_intrinsic_instr_create(nir, nir_intrinsic_load_input);
> +               load->src[0] = nir_src_for_ssa(nir_imm_int(&b, 0));
> +
> +               nir_intrinsic_set_base(load, num_inputs);
> +               switch (intrin->intrinsic) {
> +               case nir_intrinsic_load_base_vertex:
> +                  nir_intrinsic_set_component(load, 0);
> +                  break;
> +               case nir_intrinsic_load_base_instance:
> +                  nir_intrinsic_set_component(load, 1);
> +                  break;
> +               case nir_intrinsic_load_vertex_id_zero_base:
> +                  nir_intrinsic_set_component(load, 2);
> +                  break;
> +               case nir_intrinsic_load_instance_id:
> +                  nir_intrinsic_set_component(load, 3);
> +                  break;
> +               case nir_intrinsic_load_draw_id:
> +                  /* gl_DrawID is stored right after gl_VertexID and friends
> +                   * if any of them exist.
> +                   */
> +                  nir_intrinsic_set_base(load, num_inputs + has_svgs);
> +                  nir_intrinsic_set_component(load, 0);
> +                  break;
> +               default:
> +                  unreachable("Invalid SVGS intrinsic");

SVGS not a thing - Invalid system value intrinsic?

> +               }
> +
> +               load->num_components = 1;
> +               nir_ssa_dest_init(&load->instr, &load->dest, 1, 32, NULL);
> +               nir_builder_instr_insert(&b, &load->instr);
> +
> +               nir_ssa_def_rewrite_uses(&intrin->dest.ssa,
> +                                        nir_src_for_ssa(&load->dest.ssa));
> +               nir_instr_remove(&intrin->instr);
> +               break;
> +            }
> +
> +            case nir_intrinsic_load_input: {
>                 /* Attributes come in a contiguous block, ordered by their
>                  * gl_vert_attrib value.  That means we can compute the slot
>                  * number for an attribute by masking out the enabled attributes
> @@ -280,6 +343,11 @@ brw_nir_lower_vs_inputs(nir_shader *nir,
>                 int slot = _mesa_bitcount_64(nir->info->inputs_read &
>                                              BITFIELD64_MASK(attr));
>                 nir_intrinsic_set_base(intrin, slot);
> +               break;
> +            }
> +
> +            default:
> +               break; /* Nothing to do */
>              }
>           }
>        }
> 

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: This is a digitally signed message part.
URL: <https://lists.freedesktop.org/archives/mesa-dev/attachments/20170505/1868474b/attachment.sig>


More information about the mesa-dev mailing list