mesa: Set gl_fragment_program::UsesKill in do_set_program_inouts.
authorPaul Berry <stereotype441@gmail.com>
Thu, 19 Jul 2012 06:18:14 +0000 (23:18 -0700)
committerPaul Berry <stereotype441@gmail.com>
Fri, 20 Jul 2012 16:33:07 +0000 (09:33 -0700)
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>
src/glsl/ir_set_program_inouts.cpp
src/mesa/drivers/dri/i965/brw_shader.cpp
src/mesa/program/ir_to_mesa.cpp
src/mesa/state_tracker/st_glsl_to_tgsi.cpp

index 845aa114477c81aa77be6e4ccd7a420a0ee8d95f..e5de07e0122c764cf9fbba5bef7565903933d64e 100644 (file)
@@ -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);
 }
index 140a268cff76f090af5322ab89a9e8eb01158229..935671482c77dbc8942306571dc76c2dbb291289 100644 (file)
@@ -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;
 
index 217a264559a4179b57937db783ef023d8605fc23..8a4f31162e11518dea80ab374ab3344dd599b658 100644 (file)
@@ -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
index 1d91e366197b869c2c5bb4ea30f28541a5421bc0..34dbfd3b2b12940f2498665b03a8d63818cd9f22 100644 (file)
@@ -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