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 <kenn...@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 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev