[Mesa-dev] [PATCH 5/6] i965/fs: Add ARB_fragment_program support to the NIR backend.

Jordan Justen jordan.l.justen at intel.com
Tue Mar 24 23:49:28 PDT 2015


On 2015-03-23 17:37:59, Kenneth Graunke wrote:
> Use prog_to_nir where we would normally call glsl_to_nir, handle program
> parameter lists, and skip a few things that don't exist.
> 
> Using NIR generates much better shader code than Mesa IR, since we get
> real optimizations, as opposed to prog_optimize:
> 
> total instructions in shared programs: 314007 -> 279892 (-10.86%)
> instructions in affected programs:     285173 -> 251058 (-11.96%)
> helped:                                2001
> HURT:                                  67
> GAINED:                                4
> LOST:                                  7
> 
> Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
> ---
>  src/mesa/drivers/dri/i965/brw_fs.cpp     | 16 +++++-------
>  src/mesa/drivers/dri/i965/brw_fs_nir.cpp | 45 ++++++++++++++++++++++++++------
>  2 files changed, 44 insertions(+), 17 deletions(-)
> 
> diff --git a/src/mesa/drivers/dri/i965/brw_fs.cpp b/src/mesa/drivers/dri/i965/brw_fs.cpp
> index a57f501..6969286 100644
> --- a/src/mesa/drivers/dri/i965/brw_fs.cpp
> +++ b/src/mesa/drivers/dri/i965/brw_fs.cpp
> @@ -3954,15 +3954,13 @@ fs_visitor::run_fs()
>        /* Generate FS IR for main().  (the visitor only descends into
>         * functions called "main").
>         */
> -      if (shader) {
> -         if (env_var_as_boolean("INTEL_USE_NIR", false)) {
> -            emit_nir_code();
> -         } else {
> -            foreach_in_list(ir_instruction, ir, shader->base.ir) {
> -               base_ir = ir;
> -               this->result = reg_undef;
> -               ir->accept(this);
> -            }
> +      if (env_var_as_boolean("INTEL_USE_NIR", false)) {
> +         emit_nir_code();
> +      } else if (shader) {
> +         foreach_in_list(ir_instruction, ir, shader->base.ir) {
> +            base_ir = ir;
> +            this->result = reg_undef;
> +            ir->accept(this);
>           }
>        } else {
>           emit_fragment_program_code();
> diff --git a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
> index 63d5e3b..4c0fd97 100644
> --- a/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
> +++ b/src/mesa/drivers/dri/i965/brw_fs_nir.cpp
> @@ -24,6 +24,7 @@
>  #include "glsl/ir.h"
>  #include "glsl/ir_optimization.h"
>  #include "glsl/nir/glsl_to_nir.h"
> +#include "program/prog_to_nir.h"
>  #include "brw_fs.h"
>  #include "brw_nir.h"
>  
> @@ -86,9 +87,15 @@ fs_visitor::emit_nir_code()
>     const nir_shader_compiler_options *options =
>        ctx->Const.ShaderCompilerOptions[stage].NirOptions;
>  
> -   /* first, lower the GLSL IR shader to NIR */
> -   lower_output_reads(shader->base.ir);
> -   nir_shader *nir = glsl_to_nir(&shader->base, options);
> +   nir_shader *nir;
> +   /* First, lower the GLSL IR or Mesa IR to NIR */
> +   if (shader_prog) {
> +      lower_output_reads(shader->base.ir);
> +      nir = glsl_to_nir(&shader->base, options);
> +   } else {
> +      nir = prog_to_nir(prog, options);
> +      nir_convert_to_ssa(nir); /* turn registers into SSA */
> +   }
>     nir_validate_shader(nir);
>  
>     nir_lower_global_vars_to_local(nir);
> @@ -106,9 +113,18 @@ fs_visitor::emit_nir_code()
>     /* Get rid of split copies */
>     nir_optimize(nir);
>  
> -   nir_assign_var_locations_scalar_direct_first(nir, &nir->uniforms,
> -                                                &num_direct_uniforms,
> -                                                &nir->num_uniforms);
> +   if (shader_prog) {
> +      nir_assign_var_locations_scalar_direct_first(nir, &nir->uniforms,
> +                                                   &num_direct_uniforms,
> +                                                   &nir->num_uniforms);
> +   } else {
> +      /* ARB programs generally create a giant array of "uniform" data, and allow
> +       * indirect addressing without any boundaries.  In the absence of bounds
> +       * analysis, it's all or nothing.  num_direct_uniforms is only useful when
> +       * we have some direct and some indirect access; it doesn't matter here.
> +       */
> +      num_direct_uniforms = 0;
> +   }
>     nir_assign_var_locations_scalar(&nir->inputs, &nir->num_inputs);
>     nir_assign_var_locations_scalar(&nir->outputs, &nir->num_outputs);
>  
> @@ -118,8 +134,10 @@ fs_visitor::emit_nir_code()
>     nir_remove_dead_variables(nir);
>     nir_validate_shader(nir);
>  
> -   nir_lower_samplers(nir, shader_prog, shader->base.Program);
> -   nir_validate_shader(nir);
> +   if (shader_prog) {
> +      nir_lower_samplers(nir, shader_prog, shader->base.Program);
> +      nir_validate_shader(nir);
> +   }
>  
>     nir_lower_system_values(nir);
>     nir_validate_shader(nir);
> @@ -320,6 +338,17 @@ fs_visitor::nir_setup_uniforms(nir_shader *shader)
>     if (dispatch_width != 8)
>        return;
>  
> +   if (!shader_prog) {
> +      /* prog_to_nir doesn't create uniform variables; set it up directly. */
> +      for (unsigned p = 0; p < prog->Parameters->NumParameters; p++) {
> +         for (unsigned int i = 0; i < 4; i++) {
> +            stage_prog_data->param[4 * p + i] =
> +               &prog->Parameters->ParameterValues[p][i];
> +         }
> +      }
> +      return;
> +   }
> +
>     foreach_list_typed(nir_variable, var, node, &shader->uniforms) {
>        /* UBO's and atomics don't take up space in the uniform file */

How about if (shader_prog) do this ^^
else do ARB_fp version?

(Instead of the using the 'return')

-Jordan


More information about the mesa-dev mailing list