glsl: Set UsesDFdy appropriately for GLSL shaders.
authorPaul Berry <stereotype441@gmail.com>
Wed, 20 Jun 2012 19:49:29 +0000 (12:49 -0700)
committerPaul Berry <stereotype441@gmail.com>
Thu, 19 Jul 2012 17:02:21 +0000 (10:02 -0700)
This patch updates the ir_set_program_inouts_visitor so that it also
sets gl_fragment_program::UsesDFdy.

This is a bit of a hack (since dFdy() isn't an input or an output),
but there's no other obvious visitor to squeeze this functionality
into, and it would be silly to create a brand new visitor just for
this purpose.

v2: use local 'fprog' var to avoid repeated casting.

Reviewed-by: Brian Paul <brianp@vmware.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
src/glsl/ir_set_program_inouts.cpp

index a7415c7e3f83ed8e1e5a6f32f6d5afa1a65a2f34..845aa114477c81aa77be6e4ccd7a420a0ee8d95f 100644 (file)
@@ -26,8 +26,8 @@
  *
  * Sets the InputsRead and OutputsWritten of Mesa programs.
  *
- * Additionally, for fragment shaders, sets the InterpQualifier array and
- * IsCentroid bitfield.
+ * Additionally, for fragment shaders, sets the InterpQualifier array, the
+ * IsCentroid bitfield, and the UsesDFdy flag.
  *
  * Mesa programs (gl_program, not gl_shader_program) have a set of
  * flags indicating which varyings are read and written.  Computing
@@ -61,6 +61,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(ir_dereference_variable *);
    virtual ir_visitor_status visit(ir_variable *);
 
@@ -169,6 +170,16 @@ ir_set_program_inouts_visitor::visit_enter(ir_function_signature *ir)
    return visit_continue_with_parent;
 }
 
+ir_visitor_status
+ir_set_program_inouts_visitor::visit_enter(ir_expression *ir)
+{
+   if (is_fragment_shader && ir->operation == ir_unop_dFdy) {
+      gl_fragment_program *fprog = (gl_fragment_program *) prog;
+      fprog->UsesDFdy = true;
+   }
+   return visit_continue;
+}
+
 void
 do_set_program_inouts(exec_list *instructions, struct gl_program *prog,
                       bool is_fragment_shader)
@@ -179,9 +190,10 @@ do_set_program_inouts(exec_list *instructions, struct gl_program *prog,
    prog->OutputsWritten = 0;
    prog->SystemValuesRead = 0;
    if (is_fragment_shader) {
-      memset(((gl_fragment_program *) prog)->InterpQualifier, 0,
-             sizeof(((gl_fragment_program *) prog)->InterpQualifier));
-      ((gl_fragment_program *) prog)->IsCentroid = 0;
+      gl_fragment_program *fprog = (gl_fragment_program *) prog;
+      memset(fprog->InterpQualifier, 0, sizeof(fprog->InterpQualifier));
+      fprog->IsCentroid = 0;
+      fprog->UsesDFdy = false;
    }
    visit_list_elements(&v, instructions);
 }