mesa: Set gl_fragment_program::UsesKill in do_set_program_inouts.

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.

Reviewed-by: Eric Anholt <eric@anholt.net>
This commit is contained in:
Paul Berry
2012-07-18 23:18:14 -07:00
parent a8c092266e
commit 0f1f2ff8db
4 changed files with 14 additions and 33 deletions

View File

@@ -62,6 +62,7 @@ public:
virtual ir_visitor_status visit_enter(ir_dereference_array *); 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_function_signature *);
virtual ir_visitor_status visit_enter(ir_expression *); 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_dereference_variable *);
virtual ir_visitor_status visit(ir_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; 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 void
do_set_program_inouts(exec_list *instructions, struct gl_program *prog, do_set_program_inouts(exec_list *instructions, struct gl_program *prog,
bool is_fragment_shader) 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)); memset(fprog->InterpQualifier, 0, sizeof(fprog->InterpQualifier));
fprog->IsCentroid = 0; fprog->IsCentroid = 0;
fprog->UsesDFdy = false; fprog->UsesDFdy = false;
fprog->UsesKill = false;
} }
visit_list_elements(&v, instructions); visit_list_elements(&v, instructions);
} }

View File

@@ -109,31 +109,6 @@ brw_link_shader(struct gl_context *ctx, struct gl_shader_program *shProg)
vp->UsesClipDistance = shProg->Vert.UsesClipDistance; 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); void *mem_ctx = ralloc_context(NULL);
bool progress; bool progress;

View File

@@ -2157,8 +2157,6 @@ ir_to_mesa_visitor::visit(ir_return *ir)
void void
ir_to_mesa_visitor::visit(ir_discard *ir) ir_to_mesa_visitor::visit(ir_discard *ir)
{ {
struct gl_fragment_program *fp = (struct gl_fragment_program *)this->prog;
if (ir->condition) { if (ir->condition) {
ir->condition->accept(this); ir->condition->accept(this);
this->result.negate = ~this->result.negate; this->result.negate = ~this->result.negate;
@@ -2166,8 +2164,6 @@ ir_to_mesa_visitor::visit(ir_discard *ir)
} else { } else {
emit(ir, OPCODE_KIL_NV); emit(ir, OPCODE_KIL_NV);
} }
fp->UsesKill = GL_TRUE;
} }
void void

View File

@@ -2758,8 +2758,6 @@ glsl_to_tgsi_visitor::visit(ir_return *ir)
void void
glsl_to_tgsi_visitor::visit(ir_discard *ir) glsl_to_tgsi_visitor::visit(ir_discard *ir)
{ {
struct gl_fragment_program *fp = (struct gl_fragment_program *)this->prog;
if (ir->condition) { if (ir->condition) {
ir->condition->accept(this); ir->condition->accept(this);
this->result.negate = ~this->result.negate; this->result.negate = ~this->result.negate;
@@ -2767,8 +2765,6 @@ glsl_to_tgsi_visitor::visit(ir_discard *ir)
} else { } else {
emit(ir, TGSI_OPCODE_KILP); emit(ir, TGSI_OPCODE_KILP);
} }
fp->UsesKill = GL_TRUE;
} }
void void