[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