This will allow dead components of varyings to be removed. BDW shader-db results:
total instructions in shared programs: 13190730 -> 13108459 (-0.62%) instructions in affected programs: 2110903 -> 2028632 (-3.90%) helped: 14043 HURT: 486 total cycles in shared programs: 541148990 -> 540544072 (-0.11%) cycles in affected programs: 290344296 -> 289739378 (-0.21%) helped: 23418 HURT: 11623 total loops in shared programs: 3923 -> 3920 (-0.08%) loops in affected programs: 3 -> 0 helped: 3 HURT: 0 total spills in shared programs: 85784 -> 85853 (0.08%) spills in affected programs: 1374 -> 1443 (5.02%) helped: 6 HURT: 15 total fills in shared programs: 88717 -> 88801 (0.09%) fills in affected programs: 1719 -> 1803 (4.89%) helped: 15 HURT: 9 LOST: 3 GAINED: 0 The fills/spills changes were all in the dolphin uber shaders. I tested enabling this on IVB but the results went in the other direction. --- src/mesa/drivers/dri/i965/brw_link.cpp | 35 ++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_link.cpp b/src/mesa/drivers/dri/i965/brw_link.cpp index 1a28e63fca..e4b642f49d 100644 --- a/src/mesa/drivers/dri/i965/brw_link.cpp +++ b/src/mesa/drivers/dri/i965/brw_link.cpp @@ -217,20 +217,31 @@ update_xfb_info(struct gl_transform_feedback_info *xfb_info, } extern "C" GLboolean brw_link_shader(struct gl_context *ctx, struct gl_shader_program *shProg) { struct brw_context *brw = brw_context(ctx); const struct brw_compiler *compiler = brw->screen->compiler; unsigned int stage; struct shader_info *infos[MESA_SHADER_STAGES] = { 0, }; + /* Determine first and last stage. */ + unsigned first = MESA_SHADER_STAGES; + unsigned last = 0; + for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { + if (!shProg->_LinkedShaders[i]) + continue; + if (first == MESA_SHADER_STAGES) + first = i; + last = i; + } + for (stage = 0; stage < ARRAY_SIZE(shProg->_LinkedShaders); stage++) { struct gl_linked_shader *shader = shProg->_LinkedShaders[stage]; if (!shader) continue; struct gl_program *prog = shader->Program; prog->Parameters = _mesa_new_parameter_list(); process_glsl_ir(brw, shProg, shader); @@ -244,31 +255,35 @@ brw_link_shader(struct gl_context *ctx, struct gl_shader_program *shProg) if (debug_enabled && shader->ir) { fprintf(stderr, "GLSL IR for native %s shader %d:\n", _mesa_shader_stage_to_string(shader->Stage), shProg->Name); _mesa_print_ir(stderr, shader->ir, NULL); fprintf(stderr, "\n\n"); } prog->nir = brw_create_nir(brw, shProg, prog, (gl_shader_stage) stage, compiler->scalar_stage[stage]); - } - /* Determine first and last stage. */ - unsigned first = MESA_SHADER_STAGES; - unsigned last = 0; - for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { - if (!shProg->_LinkedShaders[i]) - continue; - if (first == MESA_SHADER_STAGES) - first = i; - last = i; + if (brw->screen->devinfo.gen >= 8) { + nir_variable_mode mask = (nir_variable_mode) 0; + + if (stage != first) + mask = (nir_variable_mode)(mask | nir_var_shader_in); + + if (stage != last) + mask = (nir_variable_mode)(mask | nir_var_shader_out); + + nir_lower_io_to_scalar_early(prog->nir, mask); + + prog->nir = brw_nir_optimize(prog->nir, compiler, + compiler->scalar_stage[stage]); + } } /* Linking the stages in the opposite order (from fragment to vertex) * ensures that inter-shader outputs written to in an earlier stage * are eliminated if they are (transitively) not used in a later * stage. */ if (first != last) { int next = last; for (int i = next - 1; i >= 0; i--) { -- 2.13.6 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev