[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