[Mesa-dev] [PATCH] nir: add lowering for gl_HelperInvocation

Ian Romanick idr at freedesktop.org
Mon Jun 25 18:23:52 UTC 2018


On 06/19/2018 08:24 AM, Rob Clark wrote:
> v2: reword comment about lower_helper_invocations to be more clear
>     that it might not work on all hardware
> v3: add special variant of load_sample_id which does not imply per-
>     sample shading
> 
> Signed-off-by: Rob Clark <robdclark at gmail.com>
> ---
> Yeah, new intrinsic name is a bit funny sounding, but I couldn't
> think of anything better.
> 
>  src/compiler/nir/nir.h                          | 12 ++++++++++++
>  src/compiler/nir/nir_intrinsics.py              |  3 +++
>  src/compiler/nir/nir_lower_system_values.c      | 17 +++++++++++++++++
>  .../drivers/freedreno/ir3/ir3_compiler_nir.c    |  1 +
>  src/gallium/drivers/freedreno/ir3/ir3_nir.c     |  1 +
>  5 files changed, 34 insertions(+)
> 
> diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h
> index 2d620454796..cb9a4af64cf 100644
> --- a/src/compiler/nir/nir.h
> +++ b/src/compiler/nir/nir.h
> @@ -1981,6 +1981,18 @@ typedef struct nir_shader_compiler_options {
>      */
>     bool lower_base_vertex;
>  
> +   /**
> +    * If enabled, gl_HelperInvocation will be lowered as:
> +    *
> +    *   !((1 << sample_id) & sample_mask_in))

I recently encountered something related to this.  Issue #22 of the
GL_ARB_shader_image_load_store spec suggests using (gl_SampleMaskIn[0]
== 0) to detect a helper invocation.  There's a note that
implementations that support > 32 samples will also need to check
gl_SampleMaskIn[1].  Did you try that?  It should generate less code.

See also piglit commit c89439fcaba7259b25d090df43a6bf2aac6483d7.

> +    *
> +    * This depends on some possibly hw implementation details, which may
> +    * not be true for all hw.  In particular that the FS is only executed
> +    * for covered samples or for helper invocations.  So, do not blindly
> +    * enable this option.
> +    */
> +   bool lower_helper_invocation;
> +
>     bool lower_cs_local_index_from_id;
>  
>     bool lower_device_index_to_zero;
> diff --git a/src/compiler/nir/nir_intrinsics.py b/src/compiler/nir/nir_intrinsics.py
> index 484b2d4fd68..5523243a564 100644
> --- a/src/compiler/nir/nir_intrinsics.py
> +++ b/src/compiler/nir/nir_intrinsics.py
> @@ -422,6 +422,9 @@ system_value("instance_id", 1)
>  system_value("base_instance", 1)
>  system_value("draw_id", 1)
>  system_value("sample_id", 1)
> +# sample_id_no_per_sample is like sample_id but does not imply per-
> +# sample shading.  See the lower_helper_invocation option.
> +system_value("sample_id_no_per_sample", 1)
>  system_value("sample_pos", 2)
>  system_value("sample_mask_in", 1)
>  system_value("primitive_id", 1)
> diff --git a/src/compiler/nir/nir_lower_system_values.c b/src/compiler/nir/nir_lower_system_values.c
> index 487da042620..8c5fdbb1f54 100644
> --- a/src/compiler/nir/nir_lower_system_values.c
> +++ b/src/compiler/nir/nir_lower_system_values.c
> @@ -136,6 +136,23 @@ convert_block(nir_block *block, nir_builder *b)
>                                nir_load_first_vertex(b));
>           break;
>  
> +      case SYSTEM_VALUE_HELPER_INVOCATION:
> +         if (b->shader->options->lower_helper_invocation) {
> +            nir_ssa_def *tmp;
> +
> +            tmp = nir_ishl(b,
> +                           nir_imm_int(b, 1),
> +                           nir_load_sample_id_no_per_sample(b));
> +
> +            tmp = nir_iand(b,
> +                           nir_load_sample_mask_in(b),
> +                           tmp);
> +
> +            sysval = nir_inot(b, nir_i2b(b, tmp));
> +         }
> +
> +         break;
> +
>        case SYSTEM_VALUE_INSTANCE_INDEX:
>           sysval = nir_iadd(b,
>                             nir_load_instance_id(b),
> diff --git a/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c b/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c
> index ed87eff9976..9cad7c6e559 100644
> --- a/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c
> +++ b/src/gallium/drivers/freedreno/ir3/ir3_compiler_nir.c
> @@ -2360,6 +2360,7 @@ emit_intrinsic(struct ir3_context *ctx, nir_intrinsic_instr *intr)
>  		dst[0] = ctx->instance_id;
>  		break;
>  	case nir_intrinsic_load_sample_id:
> +	case nir_intrinsic_load_sample_id_no_per_sample:
>  		if (!ctx->samp_id) {
>  			ctx->samp_id = create_input(b, 0);
>  			ctx->samp_id->regs[0]->flags |= IR3_REG_HALF;
> diff --git a/src/gallium/drivers/freedreno/ir3/ir3_nir.c b/src/gallium/drivers/freedreno/ir3/ir3_nir.c
> index 9ada3889eb9..e665fb933b9 100644
> --- a/src/gallium/drivers/freedreno/ir3/ir3_nir.c
> +++ b/src/gallium/drivers/freedreno/ir3/ir3_nir.c
> @@ -52,6 +52,7 @@ static const nir_shader_compiler_options options = {
>  		.lower_extract_byte = true,
>  		.lower_extract_word = true,
>  		.lower_all_io_to_temps = true,
> +		.lower_helper_invocation = true,
>  };
>  
>  struct nir_shader *
> 



More information about the mesa-dev mailing list