[Mesa-dev] [PATCH 06/11] i965/nir: Split shader optimization and lowering into three satages

Iago Toral itoral at igalia.com
Thu Nov 12 08:06:02 PST 2015


s/satages/stages in the shortlog. Other than that it looks good to me:
Reviewed-by: Iago Toral Quiroga <itoral at igalia.com>

On Wed, 2015-11-11 at 17:26 -0800, Jason Ekstrand wrote:
> At the moment, brw_create_nir just calls the three stages in sequence so
> there's not much difference.  Soon, however, we will want to start doing
> variants in NIR at which point the postprocessing step will have to move
> from shader create time to codegen time.
> ---
>  src/mesa/drivers/dri/i965/brw_nir.c | 129 +++++++++++++++++++++++++-----------
>  src/mesa/drivers/dri/i965/brw_nir.h |   9 +++
>  2 files changed, 100 insertions(+), 38 deletions(-)
> 
> diff --git a/src/mesa/drivers/dri/i965/brw_nir.c b/src/mesa/drivers/dri/i965/brw_nir.c
> index 7826729..21c2648 100644
> --- a/src/mesa/drivers/dri/i965/brw_nir.c
> +++ b/src/mesa/drivers/dri/i965/brw_nir.c
> @@ -221,43 +221,33 @@ nir_optimize(nir_shader *nir, bool is_scalar)
>     } while (progress);
>  }
>  
> -nir_shader *
> -brw_create_nir(struct brw_context *brw,
> -               const struct gl_shader_program *shader_prog,
> -               const struct gl_program *prog,
> -               gl_shader_stage stage,
> -               bool is_scalar)
> +/* Does some simple lowering and runs the standard suite of optimizations
> + *
> + * This is intended to be called more-or-less directly after you get the
> + * shader out of GLSL or some other source.  While it is geared towards i965,
> + * it is not at all generator-specific except for the is_scalar flag.  Even
> + * there, it is safe to call with is_scalar = false for a shader that is
> + * intended for the FS backend as long as nir_optimize is called again with
> + * is_scalar = true to scalarize everything prior to code gen.
> + */
> +void
> +brw_preprocess_nir(nir_shader *nir, bool is_scalar)
>  {
> -   struct gl_context *ctx = &brw->ctx;
> -   const struct brw_device_info *devinfo = brw->intelScreen->devinfo;
> -   const nir_shader_compiler_options *options =
> -      ctx->Const.ShaderCompilerOptions[stage].NirOptions;
> -   static const nir_lower_tex_options tex_options = {
> -      .lower_txp = ~0,
> -   };
> -   bool debug_enabled = INTEL_DEBUG & intel_debug_flag_for_shader_stage(stage);
> -   bool progress = false;
> -   nir_shader *nir;
> -
> -   /* First, lower the GLSL IR or Mesa IR to NIR */
> -   if (shader_prog) {
> -      nir = glsl_to_nir(shader_prog, stage, options);
> -   } else {
> -      nir = prog_to_nir(prog, options);
> -      OPT_V(nir_convert_to_ssa); /* turn registers into SSA */
> -   }
> -   nir_validate_shader(nir);
> +   bool progress; /* Written by OPT and OPT_V */
> +   (void)progress;
>  
> -   if (stage == MESA_SHADER_GEOMETRY) {
> +   if (nir->stage == MESA_SHADER_GEOMETRY)
>        OPT(nir_lower_gs_intrinsics);
> -   }
>  
> -   OPT(nir_lower_global_vars_to_local);
> +   static const nir_lower_tex_options tex_options = {
> +      .lower_txp = ~0,
> +   };
>  
>     OPT_V(nir_lower_tex, &tex_options);
> -
>     OPT(nir_normalize_cubemap_coords);
>  
> +   OPT(nir_lower_global_vars_to_local);
> +
>     OPT(nir_split_var_copies);
>  
>     nir_optimize(nir, is_scalar);
> @@ -268,6 +258,25 @@ brw_create_nir(struct brw_context *brw,
>     /* Get rid of split copies */
>     nir_optimize(nir, is_scalar);
>  
> +   OPT(nir_remove_dead_variables);
> +}
> +
> +/* Lowers inputs, outputs, uniforms, and samplers for i965
> + *
> + * This function does all of the standard lowering prior to post-processing.
> + * The lowering done is highly gen, stage, and backend-specific.  The
> + * shader_prog parameter is optional and is used only for lowering sampler
> + * derefs and atomics for GLSL shaders.
> + */
> +void
> +brw_lower_nir(nir_shader *nir,
> +              const struct brw_device_info *devinfo,
> +              const struct gl_shader_program *shader_prog,
> +              bool is_scalar)
> +{
> +   bool progress; /* Written by OPT and OPT_V */
> +   (void)progress;
> +
>     OPT_V(brw_nir_lower_inputs, devinfo, is_scalar);
>     OPT_V(brw_nir_lower_outputs, is_scalar);
>     nir_assign_var_locations(&nir->uniforms,
> @@ -275,8 +284,6 @@ brw_create_nir(struct brw_context *brw,
>                              is_scalar ? type_size_scalar : type_size_vec4);
>     OPT_V(nir_lower_io, -1, is_scalar ? type_size_scalar : type_size_vec4);
>  
> -   OPT(nir_remove_dead_variables);
> -
>     if (shader_prog) {
>        OPT_V(nir_lower_samplers, shader_prog);
>     }
> @@ -288,8 +295,27 @@ brw_create_nir(struct brw_context *brw,
>     }
>  
>     nir_optimize(nir, is_scalar);
> +}
> +
> +/* Prepare the given shader for codegen
> + *
> + * This function is intended to be called right before going into the actual
> + * backend and is highly backend-specific.  Also, once this function has been
> + * called on a shader, it will no longer be in SSA form so most optimizations
> + * will not work.
> + */
> +void
> +brw_postprocess_nir(nir_shader *nir,
> +                    const struct brw_device_info *devinfo,
> +                    bool is_scalar)
> +{
> +   bool debug_enabled =
> +      (INTEL_DEBUG & intel_debug_flag_for_shader_stage(nir->stage));
> +
> +   bool progress; /* Written by OPT and OPT_V */
> +   (void)progress;
>  
> -   if (brw->gen >= 6) {
> +   if (devinfo->gen >= 6) {
>        /* Try and fuse multiply-adds */
>        OPT(brw_nir_opt_peephole_ffma);
>     }
> @@ -310,7 +336,7 @@ brw_create_nir(struct brw_context *brw,
>        }
>  
>        fprintf(stderr, "NIR (SSA form) for %s shader:\n",
> -              _mesa_shader_stage_to_string(stage));
> +              _mesa_shader_stage_to_string(nir->stage));
>        nir_print_shader(nir, stderr);
>     }
>  
> @@ -321,24 +347,51 @@ brw_create_nir(struct brw_context *brw,
>        OPT(nir_lower_vec_to_movs);
>     }
>  
> -   /* Needed only so that OPT and OPT_V can set it */
> -   (void)progress;
> -
>     /* This is the last pass we run before we start emitting stuff.  It
>      * determines when we need to insert boolean resolves on Gen <= 5.  We
>      * run it last because it stashes data in instr->pass_flags and we don't
>      * want that to be squashed by other NIR passes.
>      */
> -   if (brw->gen <= 5)
> +   if (devinfo->gen <= 5)
>        brw_nir_analyze_boolean_resolves(nir);
>  
>     nir_sweep(nir);
>  
>     if (unlikely(debug_enabled)) {
>        fprintf(stderr, "NIR (final form) for %s shader:\n",
> -              _mesa_shader_stage_to_string(stage));
> +              _mesa_shader_stage_to_string(nir->stage));
>        nir_print_shader(nir, stderr);
>     }
> +}
> +
> +nir_shader *
> +brw_create_nir(struct brw_context *brw,
> +               const struct gl_shader_program *shader_prog,
> +               const struct gl_program *prog,
> +               gl_shader_stage stage,
> +               bool is_scalar)
> +{
> +   struct gl_context *ctx = &brw->ctx;
> +   const struct brw_device_info *devinfo = brw->intelScreen->devinfo;
> +   const nir_shader_compiler_options *options =
> +      ctx->Const.ShaderCompilerOptions[stage].NirOptions;
> +   bool progress;
> +   nir_shader *nir;
> +
> +   /* First, lower the GLSL IR or Mesa IR to NIR */
> +   if (shader_prog) {
> +      nir = glsl_to_nir(shader_prog, stage, options);
> +   } else {
> +      nir = prog_to_nir(prog, options);
> +      OPT_V(nir_convert_to_ssa); /* turn registers into SSA */
> +   }
> +   nir_validate_shader(nir);
> +
> +   (void)progress;
> +
> +   brw_preprocess_nir(nir, is_scalar);
> +   brw_lower_nir(nir, devinfo, shader_prog, is_scalar);
> +   brw_postprocess_nir(nir, devinfo, is_scalar);
>  
>     return nir;
>  }
> diff --git a/src/mesa/drivers/dri/i965/brw_nir.h b/src/mesa/drivers/dri/i965/brw_nir.h
> index e7c9368..1cdfe00 100644
> --- a/src/mesa/drivers/dri/i965/brw_nir.h
> +++ b/src/mesa/drivers/dri/i965/brw_nir.h
> @@ -81,6 +81,15 @@ nir_shader *brw_create_nir(struct brw_context *brw,
>                             gl_shader_stage stage,
>                             bool is_scalar);
>  
> +void brw_preprocess_nir(nir_shader *nir, bool is_scalar);
> +void brw_lower_nir(nir_shader *nir,
> +                   const struct brw_device_info *devinfo,
> +                   const struct gl_shader_program *shader_prog,
> +                   bool is_scalar);
> +void brw_postprocess_nir(nir_shader *nir,
> +                         const struct brw_device_info *devinfo,
> +                         bool is_scalar);
> +
>  enum brw_reg_type brw_type_for_nir_type(nir_alu_type type);
>  
>  enum glsl_base_type brw_glsl_base_type_for_nir_type(nir_alu_type type);




More information about the mesa-dev mailing list