mesa: Add a flag to indicate whether a program uses gl_ClipDistance.
authorPaul Berry <stereotype441@gmail.com>
Sat, 17 Sep 2011 16:42:02 +0000 (09:42 -0700)
committerPaul Berry <stereotype441@gmail.com>
Fri, 23 Sep 2011 20:28:51 +0000 (13:28 -0700)
GLSL 1.30 requires us to use gl_ClipDistance for clipping if the
vertex shader contains a static write to it, and otherwise use
user-defined clipping planes.  Since the driver needs to behave
differently in these two cases, we need a flag to record whether the
shader has written to gl_ClipDistance.

The new flag is called UsesClipDistance.  We initially store it in
gl_shader_program (since that is the data structure that is available
when we check to see whethe gl_ClipDistance was written to), and we
later copy it to a flag with the same name in gl_vertex_program, since
that is a more convenient place for the driver to access it (in i965,
at least).

Reviewed-by: Eric Anholt <eric@anholt.net>
Tested-by: Brian Paul <brianp@vmware.com>
src/glsl/linker.cpp
src/mesa/main/mtypes.h
src/mesa/program/ir_to_mesa.cpp

index ceb49fd5b20f2fe47f3aed657b058a68bbf8a910..d802a0a9baeba04e230bceafaa5941f7e6ed2550 100644 (file)
@@ -244,7 +244,9 @@ count_attribute_slots(const glsl_type *t)
 
 
 /**
- * Verify that a vertex shader executable meets all semantic requirements
+ * Verify that a vertex shader executable meets all semantic requirements.
+ *
+ * Also sets prog->Vert.UsesClipDistance as a side effect.
  *
  * \param shader  Vertex shader executable to be verified
  */
@@ -279,6 +281,7 @@ validate_vertex_shader_executable(struct gl_shader_program *prog,
                       "and `gl_ClipDistance'\n");
          return false;
       }
+      prog->Vert.UsesClipDistance = clip_distance.variable_found();
    }
 
    return true;
index 74e7e2adf68941bc08b9507302974f2f08789976..81565c6c2eafaaeaeb1625a9a040d712a00ed26f 100644 (file)
@@ -1876,6 +1876,7 @@ struct gl_vertex_program
    struct gl_program Base;   /**< base class */
    GLboolean IsNVProgram;    /**< is this a GL_NV_vertex_program program? */
    GLboolean IsPositionInvariant;
+   GLboolean UsesClipDistance;
 };
 
 
@@ -2161,6 +2162,11 @@ struct gl_shader_program
       GLenum OutputType; /**< GL_POINTS, GL_LINE_STRIP or GL_TRIANGLE_STRIP */
    } Geom;
 
+   /** Vertex shader state - copied into gl_vertex_program at link time */
+   struct {
+      GLboolean UsesClipDistance; /**< True if gl_ClipDistance is written to. */
+   } Vert;
+
    /* post-link info: */
    struct gl_vertex_program *VertexProgram;     /**< Linked vertex program */
    struct gl_fragment_program *FragmentProgram; /**< Linked fragment prog */
index 5e565e4ed0859635bcabe930641af6f40d98738c..7b2c69fdbdb5168a77120f980200de21127480f2 100644 (file)
@@ -3291,6 +3291,8 @@ _mesa_ir_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
 
          switch (prog->_LinkedShaders[i]->Type) {
          case GL_VERTEX_SHADER:
+            ((struct gl_vertex_program *)linked_prog)->UsesClipDistance
+               = prog->Vert.UsesClipDistance;
             _mesa_reference_vertprog(ctx, &prog->VertexProgram,
                                      (struct gl_vertex_program *)linked_prog);
             ok = ctx->Driver.ProgramStringNotify(ctx, GL_VERTEX_PROGRAM_ARB,