/**
+ * Set UsesClipDistance and ClipDistanceArraySize based on the given shader.
+ *
+ * Also check for errors based on incorrect usage of gl_ClipVertex and
+ * gl_ClipDistance.
+ *
+ * Return false if an error was reported.
+ */
+static void
+analyze_clip_usage(const char *shader_type, struct gl_shader_program *prog,
+ struct gl_shader *shader, GLboolean *UsesClipDistance,
+ GLuint *ClipDistanceArraySize)
+{
+ *ClipDistanceArraySize = 0;
+
+ if (!prog->IsES && prog->Version >= 130) {
+ /* From section 7.1 (Vertex Shader Special Variables) of the
+ * GLSL 1.30 spec:
+ *
+ * "It is an error for a shader to statically write both
+ * gl_ClipVertex and gl_ClipDistance."
+ *
+ * This does not apply to GLSL ES shaders, since GLSL ES defines neither
+ * gl_ClipVertex nor gl_ClipDistance.
+ */
+ find_assignment_visitor clip_vertex("gl_ClipVertex");
+ find_assignment_visitor clip_distance("gl_ClipDistance");
+
+ clip_vertex.run(shader->ir);
+ clip_distance.run(shader->ir);
+ if (clip_vertex.variable_found() && clip_distance.variable_found()) {
+ linker_error(prog, "%s shader writes to both `gl_ClipVertex' "
+ "and `gl_ClipDistance'\n", shader_type);
+ return;
+ }
+ *UsesClipDistance = clip_distance.variable_found();
+ ir_variable *clip_distance_var =
+ shader->symbols->get_variable("gl_ClipDistance");
+ if (clip_distance_var)
+ *ClipDistanceArraySize = clip_distance_var->type->length;
+ } else {
+ *UsesClipDistance = false;
+ }
+}
+
+
+/**
* Verify that a vertex shader executable meets all semantic requirements.
*
* Also sets prog->Vert.UsesClipDistance and prog->Vert.ClipDistanceArraySize
}
}
- prog->Vert.ClipDistanceArraySize = 0;
-
- if (!prog->IsES && prog->Version >= 130) {
- /* From section 7.1 (Vertex Shader Special Variables) of the
- * GLSL 1.30 spec:
- *
- * "It is an error for a shader to statically write both
- * gl_ClipVertex and gl_ClipDistance."
- *
- * This does not apply to GLSL ES shaders, since GLSL ES defines neither
- * gl_ClipVertex nor gl_ClipDistance.
- */
- find_assignment_visitor clip_vertex("gl_ClipVertex");
- find_assignment_visitor clip_distance("gl_ClipDistance");
-
- clip_vertex.run(shader->ir);
- clip_distance.run(shader->ir);
- if (clip_vertex.variable_found() && clip_distance.variable_found()) {
- linker_error(prog, "vertex shader writes to both `gl_ClipVertex' "
- "and `gl_ClipDistance'\n");
- return;
- }
- prog->Vert.UsesClipDistance = clip_distance.variable_found();
- ir_variable *clip_distance_var =
- shader->symbols->get_variable("gl_ClipDistance");
- if (clip_distance_var)
- prog->Vert.ClipDistanceArraySize = clip_distance_var->type->length;
- }
+ analyze_clip_usage("vertex", prog, shader, &prog->Vert.UsesClipDistance,
+ &prog->Vert.ClipDistanceArraySize);
}
/**
* Verify that a geometry shader executable meets all semantic requirements
*
- * Also sets prog->Geom.VerticesIn as a side effect.
+ * Also sets prog->Geom.VerticesIn, prog->Geom.UsesClipDistance, and
+ * prog->Geom.ClipDistanceArraySize as a side effect.
*
* \param shader Geometry shader executable to be verified
*/
unsigned num_vertices = vertices_per_prim(prog->Geom.InputType);
prog->Geom.VerticesIn = num_vertices;
+
+ analyze_clip_usage("geometry", prog, shader, &prog->Geom.UsesClipDistance,
+ &prog->Geom.ClipDistanceArraySize);
}
GLenum InputType; /**< GL_POINTS, GL_LINES, GL_LINES_ADJACENCY_ARB,
GL_TRIANGLES, or GL_TRIANGLES_ADJACENCY_ARB */
GLenum OutputType; /**< GL_POINTS, GL_LINE_STRIP or GL_TRIANGLE_STRIP */
+ GLboolean UsesClipDistance;
};
GLenum InputType; /**< GL_POINTS, GL_LINES, GL_LINES_ADJACENCY_ARB,
GL_TRIANGLES, or GL_TRIANGLES_ADJACENCY_ARB */
GLenum OutputType; /**< GL_POINTS, GL_LINE_STRIP or GL_TRIANGLE_STRIP */
+ /**
+ * True if gl_ClipDistance is written to. Copied into
+ * gl_geometry_program by _mesa_copy_linked_program_data().
+ */
+ GLboolean UsesClipDistance;
+ GLuint ClipDistanceArraySize; /**< Size of the gl_ClipDistance array, or
+ 0 if not present. */
} Geom;
/** Vertex shader state */