Previously, the code for setting this flag for GLSL programs was duplicated in three places: brw_link_shader(), glsl_to_tgsi_visitor, and ir_to_mesa_visitor. In addition to the unnecessary duplication, there was a performance problem on i965: brw_link_shader() set the flag before doing its final round of optimizations, which meant that if the optimizations managed to eliminate all the discard operations, the flag would still be set, resulting (at least in theory) in slower performance.
This patch consolidates all of the code that sets UsesKill for GLSL programs into do_set_program_inouts(), which already is doing a similar job for UsesDFdy, and which occurs after i965's final round of optimizations. Non-GLSL programs (ARB programs and the state tracker's glBitmap program) are unaffected. --- src/glsl/ir_set_program_inouts.cpp | 14 ++++++++++++++ src/mesa/drivers/dri/i965/brw_shader.cpp | 25 ------------------------- src/mesa/program/ir_to_mesa.cpp | 4 ---- src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 4 ---- 4 files changed, 14 insertions(+), 33 deletions(-) diff --git a/src/glsl/ir_set_program_inouts.cpp b/src/glsl/ir_set_program_inouts.cpp index 845aa11..e5de07e 100644 --- a/src/glsl/ir_set_program_inouts.cpp +++ b/src/glsl/ir_set_program_inouts.cpp @@ -62,6 +62,7 @@ public: virtual ir_visitor_status visit_enter(ir_dereference_array *); virtual ir_visitor_status visit_enter(ir_function_signature *); virtual ir_visitor_status visit_enter(ir_expression *); + virtual ir_visitor_status visit_enter(ir_discard *); virtual ir_visitor_status visit(ir_dereference_variable *); virtual ir_visitor_status visit(ir_variable *); @@ -180,6 +181,18 @@ ir_set_program_inouts_visitor::visit_enter(ir_expression *ir) return visit_continue; } +ir_visitor_status +ir_set_program_inouts_visitor::visit_enter(ir_discard *) +{ + /* discards are only allowed in fragment shaders. */ + assert(is_fragment_shader); + + gl_fragment_program *fprog = (gl_fragment_program *) prog; + fprog->UsesKill = true; + + return visit_continue; +} + void do_set_program_inouts(exec_list *instructions, struct gl_program *prog, bool is_fragment_shader) @@ -194,6 +207,7 @@ do_set_program_inouts(exec_list *instructions, struct gl_program *prog, memset(fprog->InterpQualifier, 0, sizeof(fprog->InterpQualifier)); fprog->IsCentroid = 0; fprog->UsesDFdy = false; + fprog->UsesKill = false; } visit_list_elements(&v, instructions); } diff --git a/src/mesa/drivers/dri/i965/brw_shader.cpp b/src/mesa/drivers/dri/i965/brw_shader.cpp index 140a268..9356714 100644 --- a/src/mesa/drivers/dri/i965/brw_shader.cpp +++ b/src/mesa/drivers/dri/i965/brw_shader.cpp @@ -109,31 +109,6 @@ brw_link_shader(struct gl_context *ctx, struct gl_shader_program *shProg) vp->UsesClipDistance = shProg->Vert.UsesClipDistance; } - if (stage == 1) { - class uses_kill_visitor : public ir_hierarchical_visitor { - public: - uses_kill_visitor() : uses_kill(false) - { - /* empty */ - } - - virtual ir_visitor_status visit_enter(class ir_discard *ir) - { - this->uses_kill = true; - return visit_stop; - } - - bool uses_kill; - }; - - uses_kill_visitor v; - - v.run(shader->base.ir); - - struct gl_fragment_program *fp = (struct gl_fragment_program *) prog; - fp->UsesKill = v.uses_kill; - } - void *mem_ctx = ralloc_context(NULL); bool progress; diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp index 217a264..8a4f311 100644 --- a/src/mesa/program/ir_to_mesa.cpp +++ b/src/mesa/program/ir_to_mesa.cpp @@ -2157,8 +2157,6 @@ ir_to_mesa_visitor::visit(ir_return *ir) void ir_to_mesa_visitor::visit(ir_discard *ir) { - struct gl_fragment_program *fp = (struct gl_fragment_program *)this->prog; - if (ir->condition) { ir->condition->accept(this); this->result.negate = ~this->result.negate; @@ -2166,8 +2164,6 @@ ir_to_mesa_visitor::visit(ir_discard *ir) } else { emit(ir, OPCODE_KIL_NV); } - - fp->UsesKill = GL_TRUE; } void diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp index 1d91e36..34dbfd3 100644 --- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp +++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp @@ -2758,8 +2758,6 @@ glsl_to_tgsi_visitor::visit(ir_return *ir) void glsl_to_tgsi_visitor::visit(ir_discard *ir) { - struct gl_fragment_program *fp = (struct gl_fragment_program *)this->prog; - if (ir->condition) { ir->condition->accept(this); this->result.negate = ~this->result.negate; @@ -2767,8 +2765,6 @@ glsl_to_tgsi_visitor::visit(ir_discard *ir) } else { emit(ir, TGSI_OPCODE_KILP); } - - fp->UsesKill = GL_TRUE; } void -- 1.7.7.6 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev