[Mesa-dev] [PATCH 3/7] i965: Introduce the FIND_LIVE_CHANNEL pseudo-opcode.

Matt Turner mattst88 at gmail.com
Wed Apr 29 22:30:38 PDT 2015


On Fri, Feb 20, 2015 at 11:49 AM, Francisco Jerez <currojerez at riseup.net> wrote:
> This instruction calculates the index of an arbitrary channel enabled
> in the current execution mask.  It's expected to be used as input for
> the BROADCAST opcode, but it's implemented as a separate instruction
> rather than being baked into BROADCAST because FIND_LIVE_CHANNEL has
> no dependencies so it can always be CSE'ed with other instances of the
> same instruction within a basic block.
> ---
>  src/mesa/drivers/dri/i965/brw_defines.h          |  8 +++
>  src/mesa/drivers/dri/i965/brw_eu.h               |  4 ++
>  src/mesa/drivers/dri/i965/brw_eu_emit.c          | 70 ++++++++++++++++++++++++
>  src/mesa/drivers/dri/i965/brw_fs_generator.cpp   |  4 ++
>  src/mesa/drivers/dri/i965/brw_shader.cpp         |  2 +
>  src/mesa/drivers/dri/i965/brw_vec4_generator.cpp |  4 ++
>  6 files changed, 92 insertions(+)
>
> diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h
> index d4930e3..2b52fb2 100644
> --- a/src/mesa/drivers/dri/i965/brw_defines.h
> +++ b/src/mesa/drivers/dri/i965/brw_defines.h
> @@ -912,6 +912,14 @@ enum opcode {
>     SHADER_OPCODE_URB_WRITE_SIMD8,
>
>     /**
> +    * Return the index of an arbitrary live channel (i.e. one of the channels
> +    * enabled in the current execution mask) and assign it to the first
> +    * component of the destination.  Expected to be used as input for the
> +    * BROADCAST pseudo-opcode.
> +    */
> +   SHADER_OPCODE_FIND_LIVE_CHANNEL,
> +
> +   /**
>      * Pick the channel from its first source register given by the index
>      * specified as second source.  Useful for variable indexing of surfaces.
>      */
> diff --git a/src/mesa/drivers/dri/i965/brw_eu.h b/src/mesa/drivers/dri/i965/brw_eu.h
> index 2505480..1a8b38c 100644
> --- a/src/mesa/drivers/dri/i965/brw_eu.h
> +++ b/src/mesa/drivers/dri/i965/brw_eu.h
> @@ -414,6 +414,10 @@ brw_pixel_interpolator_query(struct brw_compile *p,
>                               unsigned response_length);
>
>  void
> +brw_find_live_channel(struct brw_compile *p,
> +                      struct brw_reg dst);
> +
> +void
>  brw_broadcast(struct brw_compile *p,
>                struct brw_reg dst,
>                struct brw_reg src,
> diff --git a/src/mesa/drivers/dri/i965/brw_eu_emit.c b/src/mesa/drivers/dri/i965/brw_eu_emit.c
> index d7e3995..7899f83 100644
> --- a/src/mesa/drivers/dri/i965/brw_eu_emit.c
> +++ b/src/mesa/drivers/dri/i965/brw_eu_emit.c
> @@ -2855,6 +2855,76 @@ brw_pixel_interpolator_query(struct brw_compile *p,
>  }
>
>  void
> +brw_find_live_channel(struct brw_compile *p, struct brw_reg dst)
> +{
> +   const struct brw_context *brw = p->brw;
> +   brw_inst *inst;
> +
> +   assert(brw->gen >= 7);
> +
> +   brw_push_insn_state(p);
> +   brw_set_default_mask_control(p, BRW_MASK_DISABLE);
> +
> +   if (brw_inst_access_mode(brw, p->current) == BRW_ALIGN_1) {
> +      if (brw->gen >= 8) {
> +         /* Getting the first active channel index is easy on Gen8: Just find
> +          * the first bit set in the mask register.  The same register exists
> +          * on HSW already but it reads back as all ones when the current
> +          * instruction has execution masking disabled, so it's kind of
> +          * useless.
> +          */
> +         inst = brw_FBL(p, vec1(dst),
> +                        retype(brw_mask_reg(0), BRW_REGISTER_TYPE_UD));

The mask register disappeared after Ironlake, AFAIK, and its location
was reused for the "Channel Enable Register" on Haswell+. Since the
brw_mask_reg function is unused it probably makes sense to to rename
it brw_channel_enable_reg().

I don't care if that's done in this series or as a follow up.

> +
> +         /* Quarter control has the effect of magically shifting the value of
> +          * this register.  Make sure it's set to zero.
> +          */
> +         brw_inst_set_qtr_control(brw, inst, GEN6_COMPRESSION_1Q);
> +

Extra new line.

> +      } else {
> +         const struct brw_reg flag = retype(brw_flag_reg(1, 0),
> +                                            BRW_REGISTER_TYPE_UD);
> +
> +         brw_MOV(p, flag, brw_imm_ud(0));
> +
> +         /* Run a 16-wide instruction returning zero with execution masking
> +          * and a conditional modifier enabled in order to get the current
> +          * execution mask in f1.0.
> +          */
> +         inst = brw_MOV(p, vec16(brw_null_reg()), brw_imm_ud(0));
> +         brw_inst_set_mask_control(brw, inst, BRW_MASK_ENABLE);
> +         brw_inst_set_cond_modifier(brw, inst, BRW_CONDITIONAL_Z);
> +         brw_inst_set_flag_reg_nr(brw, inst, 1);
> +
> +         brw_FBL(p, vec1(dst), flag);
> +      }
> +

Extra new line.


More information about the mesa-dev mailing list