[Piglit] [PATCH] Add tests for gl_ClipDistance and gl_ClipVertex.

Paul Berry stereotype441 at gmail.com
Tue Aug 9 14:55:27 PDT 2011


This patch is a preparation for work I'm about to do to add
gl_ClipDistance support to Mesa, and future work that I hope to do to
fix bugs in gl_ClipVertex in Mesa.  It adds a thorough set of tests
for the following behaviors of gl_ClipDistance and gl_ClipVertex:

For gl_ClipVertex:
- It behaves properly when equal to gl_Position.
- It behaves properly when not equal to gl_Position.
- It falls back to gl_Position when it is not set.
- Its homogeneous coordinate is respected.
- The homogeneous coordinate is respected when falling back to gl_Position.

For gl_ClipDistance:
- It works when all 6 clip planes are enabled.
- Its behavior is properly affected by clip plane enable flags.
- It can be explicitly or implicitly sized in the vertex shader.
- It can be sized up to gl_MaxVaryingComponents but no higher.
- In the fragment shader, it contains properly interpolated values.

For the interaction between the two:
- It is an error to assign to both gl_ClipDistance and gl_ClipVertex.

In addition, this patch renames a few of the existing clipping tests
so that their names more clearly reflect what they're testing.

All of these tests have been validated on the proprietary nVidia
driver for Linux, except the following:

- fs-clip-distance-interpolated: this fails with the error message
  "gl_ClipDistance is not accessible in this profile".  Based on a
  google search for this error message, I suspect this is an nVidia
  driver bug.  If I replace the fragment shader's reference to
  gl_ClipDistance with a reference to a user-defined vertex shader
  output that contains the same data, the test passes.

- vs-clip-based-on-position and
  vs-clip-based-on-position-homogenaiety: these tests fail--no
  clipping occurs.  But they pass if I add the line "gl_ClipVertex =
  gl_Position;" to the end of the vertex shader.  The GLSL 1.30 spec
  clearly states that if neither gl_ClipVertex nor gl_ClipDistance is
  statically written by the vertex shader, then gl_Position should be
  used for clipping, so I conclude that this is an nVidia driver bug.

- mixing-clip-distance-and-clip-vertex-disallowed: the nVidia driver
  fails to detect this error condition, in spite of clear language in
  the GLSL 1.30 spec.  I conclude that this is an nVidia driver bug.
---
 tests/all.tests                                    |    4 +
 tests/spec/CMakeLists.txt                          |    1 +
 ...clip-vertex-different-from-position.shader_test |   60 ++++++++
 .../vs-clip-vertex-equal-to-position.shader_test   |   55 ++++++++
 .../vs-clip-vertex-homogenaiety.shader_test        |   67 +++++++++
 .../execution/vs-clip-vertex-01.shader_test        |   55 --------
 .../execution/vs-clip-vertex-02.shader_test        |   60 --------
 tests/spec/glsl-1.30/CMakeLists.txt                |    1 +
 .../fs-clip-distance-interpolated.shader_test      |   89 ++++++++++++
 ...clip-based-on-position-homogenaiety.shader_test |   65 +++++++++
 .../clipping/vs-clip-based-on-position.shader_test |   62 ++++++++
 ...vs-clip-distance-all-planes-enabled.shader_test |   52 +++++++
 .../clipping/vs-clip-distance-enables.shader_test  |  147 ++++++++++++++++++++
 .../vs-clip-distance-explicitly-sized.shader_test  |   44 ++++++
 .../vs-clip-distance-implicitly-sized.shader_test  |   52 +++++++
 .../vs-clip-distance-sizeable-to-max.shader_test   |   45 ++++++
 .../execution/vs-clip-distance-01.shader_test      |   52 -------
 tests/spec/glsl-1.30/linker/CMakeLists.txt         |    1 +
 .../glsl-1.30/linker/clipping/CMakeLists.gl.txt    |   18 +++
 .../spec/glsl-1.30/linker/clipping/CMakeLists.txt  |    1 +
 .../clip-distance-not-sizeable-above-max.c         |  123 ++++++++++++++++
 ...xing-clip-distance-and-clip-vertex-disallowed.c |  111 +++++++++++++++
 22 files changed, 998 insertions(+), 167 deletions(-)
 create mode 100644 tests/spec/glsl-1.20/execution/clipping/vs-clip-vertex-different-from-position.shader_test
 create mode 100644 tests/spec/glsl-1.20/execution/clipping/vs-clip-vertex-equal-to-position.shader_test
 create mode 100644 tests/spec/glsl-1.20/execution/clipping/vs-clip-vertex-homogenaiety.shader_test
 delete mode 100644 tests/spec/glsl-1.20/execution/vs-clip-vertex-01.shader_test
 delete mode 100644 tests/spec/glsl-1.20/execution/vs-clip-vertex-02.shader_test
 create mode 100644 tests/spec/glsl-1.30/CMakeLists.txt
 create mode 100644 tests/spec/glsl-1.30/execution/clipping/fs-clip-distance-interpolated.shader_test
 create mode 100644 tests/spec/glsl-1.30/execution/clipping/vs-clip-based-on-position-homogenaiety.shader_test
 create mode 100644 tests/spec/glsl-1.30/execution/clipping/vs-clip-based-on-position.shader_test
 create mode 100644 tests/spec/glsl-1.30/execution/clipping/vs-clip-distance-all-planes-enabled.shader_test
 create mode 100644 tests/spec/glsl-1.30/execution/clipping/vs-clip-distance-enables.shader_test
 create mode 100644 tests/spec/glsl-1.30/execution/clipping/vs-clip-distance-explicitly-sized.shader_test
 create mode 100644 tests/spec/glsl-1.30/execution/clipping/vs-clip-distance-implicitly-sized.shader_test
 create mode 100644 tests/spec/glsl-1.30/execution/clipping/vs-clip-distance-sizeable-to-max.shader_test
 delete mode 100644 tests/spec/glsl-1.30/execution/vs-clip-distance-01.shader_test
 create mode 100644 tests/spec/glsl-1.30/linker/CMakeLists.txt
 create mode 100644 tests/spec/glsl-1.30/linker/clipping/CMakeLists.gl.txt
 create mode 100644 tests/spec/glsl-1.30/linker/clipping/CMakeLists.txt
 create mode 100644 tests/spec/glsl-1.30/linker/clipping/clip-distance-not-sizeable-above-max.c
 create mode 100644 tests/spec/glsl-1.30/linker/clipping/mixing-clip-distance-and-clip-vertex-disallowed.c
 delete mode 100644 tests/spec/glsl-1.30/linker/placeholder

diff --git a/tests/all.tests b/tests/all.tests
index 62deb87..e2afd3e 100644
--- a/tests/all.tests
+++ b/tests/all.tests
@@ -762,6 +762,10 @@ spec['glsl-1.30']['execution'] = Group()
 add_shader_test_dir(spec['glsl-1.30']['execution'],
 	            os.path.join(os.path.dirname(__file__), 'spec', 'glsl-1.30', 'execution'),
 		    recursive=True)
+spec['glsl-1.30']['linker'] = Group()
+spec['glsl-1.30']['linker']['clipping'] = Group()
+add_plain_test(spec['glsl-1.30']['linker']['clipping'], 'clip-distance-not-sizeable-above-max')
+add_plain_test(spec['glsl-1.30']['linker']['clipping'], 'mixing-clip-distance-and-clip-vertex-disallowed')
 
 # Group AMD_conservative_depth
 spec['AMD_conservative_depth'] = Group()
diff --git a/tests/spec/CMakeLists.txt b/tests/spec/CMakeLists.txt
index 9ce6b98..b123e72 100644
--- a/tests/spec/CMakeLists.txt
+++ b/tests/spec/CMakeLists.txt
@@ -17,3 +17,4 @@ add_subdirectory (nv_texture_barrier)
 add_subdirectory (arb_draw_elements_base_vertex)
 add_subdirectory (arb_vertex_buffer_object)
 add_subdirectory (arb_vertex_program)
+add_subdirectory (glsl-1.30)
diff --git a/tests/spec/glsl-1.20/execution/clipping/vs-clip-vertex-different-from-position.shader_test b/tests/spec/glsl-1.20/execution/clipping/vs-clip-vertex-different-from-position.shader_test
new file mode 100644
index 0000000..ae1440d
--- /dev/null
+++ b/tests/spec/glsl-1.20/execution/clipping/vs-clip-vertex-different-from-position.shader_test
@@ -0,0 +1,60 @@
+# [description]
+# Use all 6 clip planes to clip a rectangle to a hexagon shape.
+#
+# In this test, gl_Position and gl_ClipVertex are different to verify
+# that gl_Position determines screen position and gl_ClipVertex
+# determines clipping.
+
+[require]
+GLSL >= 1.20
+
+[vertex shader]
+#version 120
+void main(void)
+{
+	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
+
+	// Transform gl_ClipVertex in an arbitrary way so that
+	// we can verify it is being used for clipping instead of
+	// gl_Position.
+	gl_ClipVertex = gl_Vertex * vec4(10.0, 10.0, 1.0, 1.0);
+}
+
+[fragment shader]
+#version 120
+void main(void)
+{
+	gl_FragColor = vec4(1, 1, 1, 1);
+}
+
+[test]
+ortho 0 1 0 1
+clip plane 0 0 1 0 -2.5
+clip plane 1 -1 1 0 4
+clip plane 2 -1 -1 0 14
+clip plane 3 0 -1 0 7.5
+clip plane 4 1 -1 0 4
+clip plane 5 1 1 0 -6
+enable GL_CLIP_PLANE0
+enable GL_CLIP_PLANE1
+enable GL_CLIP_PLANE2
+enable GL_CLIP_PLANE3
+enable GL_CLIP_PLANE4
+enable GL_CLIP_PLANE5
+draw rect 0.1 0.1 0.8 0.8
+
+# Test points inside each hexagon edge
+relative probe rgba (0.3, 0.4) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.5, 0.3) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.7, 0.4) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.7, 0.6) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.5, 0.7) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.3, 0.6) (1.0, 1.0, 1.0, 1.0)
+
+# Test points outside each hexagon edge
+relative probe rgba (0.2, 0.3) (0.0, 0.0, 0.0, 0.0)
+relative probe rgba (0.5, 0.2) (0.0, 0.0, 0.0, 0.0)
+relative probe rgba (0.8, 0.3) (0.0, 0.0, 0.0, 0.0)
+relative probe rgba (0.8, 0.7) (0.0, 0.0, 0.0, 0.0)
+relative probe rgba (0.5, 0.8) (0.0, 0.0, 0.0, 0.0)
+relative probe rgba (0.2, 0.7) (0.0, 0.0, 0.0, 0.0)
diff --git a/tests/spec/glsl-1.20/execution/clipping/vs-clip-vertex-equal-to-position.shader_test b/tests/spec/glsl-1.20/execution/clipping/vs-clip-vertex-equal-to-position.shader_test
new file mode 100644
index 0000000..773936b
--- /dev/null
+++ b/tests/spec/glsl-1.20/execution/clipping/vs-clip-vertex-equal-to-position.shader_test
@@ -0,0 +1,55 @@
+# [description]
+# Use all 6 clip planes to clip a rectangle to a hexagon shape.
+#
+# In this test, gl_Position and gl_ClipVertex are the same.
+
+[require]
+GLSL >= 1.20
+
+[vertex shader]
+#version 120
+void main(void)
+{
+	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
+
+	gl_ClipVertex = gl_Position;
+}
+
+[fragment shader]
+#version 120
+void main(void)
+{
+	gl_FragColor = vec4(1, 1, 1, 1);
+}
+
+[test]
+ortho 0 1 0 1
+clip plane 0 0 1 0 0.5
+clip plane 1 -1 1 0 0.8
+clip plane 2 -1 -1 0 0.8
+clip plane 3 0 -1 0 0.5
+clip plane 4 1 -1 0 0.8
+clip plane 5 1 1 0 0.8
+enable GL_CLIP_PLANE0
+enable GL_CLIP_PLANE1
+enable GL_CLIP_PLANE2
+enable GL_CLIP_PLANE3
+enable GL_CLIP_PLANE4
+enable GL_CLIP_PLANE5
+draw rect 0.1 0.1 0.8 0.8
+
+# Test points inside each hexagon edge
+relative probe rgba (0.3, 0.4) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.5, 0.3) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.7, 0.4) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.7, 0.6) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.5, 0.7) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.3, 0.6) (1.0, 1.0, 1.0, 1.0)
+
+# Test points outside each hexagon edge
+relative probe rgba (0.2, 0.3) (0.0, 0.0, 0.0, 0.0)
+relative probe rgba (0.5, 0.2) (0.0, 0.0, 0.0, 0.0)
+relative probe rgba (0.8, 0.3) (0.0, 0.0, 0.0, 0.0)
+relative probe rgba (0.8, 0.7) (0.0, 0.0, 0.0, 0.0)
+relative probe rgba (0.5, 0.8) (0.0, 0.0, 0.0, 0.0)
+relative probe rgba (0.2, 0.7) (0.0, 0.0, 0.0, 0.0)
diff --git a/tests/spec/glsl-1.20/execution/clipping/vs-clip-vertex-homogenaiety.shader_test b/tests/spec/glsl-1.20/execution/clipping/vs-clip-vertex-homogenaiety.shader_test
new file mode 100644
index 0000000..03e8d73
--- /dev/null
+++ b/tests/spec/glsl-1.20/execution/clipping/vs-clip-vertex-homogenaiety.shader_test
@@ -0,0 +1,67 @@
+# This test verifies that the homogeneous coordinate of gl_ClipVertex
+# is properly respected, by doubling all the coordinates of
+# gl_ClipVertex (including the homogeneous coordinate) and verifying
+# that the clipped shape is still correct.
+#
+# In addition, this test:
+# - uses all 6 clip planes to clip a rectangle to a hexagon shape.
+# - sets gl_Position and gl_ClipVertex to different values, to verify
+#   that gl_Position determines screen position and gl_ClipVertex
+#   determines clipping.
+
+[require]
+GLSL >= 1.20
+
+[vertex shader]
+#version 120
+void main(void)
+{
+	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
+
+	// Transform gl_ClipVertex in an arbitrary way so that
+	// we can verify it is being used for clipping instead of
+	// gl_Position.  The x and y coordinates are multiplied by 5,
+	// and the homogeneous coordinate is multiplied by 0.5, so the
+	// net result should be that x and y are scaled by a factor of
+	// 10.
+	gl_ClipVertex = gl_Vertex * vec4(5.0, 5.0, 1.0, 0.5);
+}
+
+[fragment shader]
+#version 120
+void main(void)
+{
+	gl_FragColor = vec4(1, 1, 1, 1);
+}
+
+[test]
+ortho 0 1 0 1
+clip plane 0 0 1 0 -2.5
+clip plane 1 -1 1 0 4
+clip plane 2 -1 -1 0 14
+clip plane 3 0 -1 0 7.5
+clip plane 4 1 -1 0 4
+clip plane 5 1 1 0 -6
+enable GL_CLIP_PLANE0
+enable GL_CLIP_PLANE1
+enable GL_CLIP_PLANE2
+enable GL_CLIP_PLANE3
+enable GL_CLIP_PLANE4
+enable GL_CLIP_PLANE5
+draw rect 0.1 0.1 0.8 0.8
+
+# Test points inside each hexagon edge
+relative probe rgba (0.3, 0.4) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.5, 0.3) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.7, 0.4) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.7, 0.6) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.5, 0.7) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.3, 0.6) (1.0, 1.0, 1.0, 1.0)
+
+# Test points outside each hexagon edge
+relative probe rgba (0.2, 0.3) (0.0, 0.0, 0.0, 0.0)
+relative probe rgba (0.5, 0.2) (0.0, 0.0, 0.0, 0.0)
+relative probe rgba (0.8, 0.3) (0.0, 0.0, 0.0, 0.0)
+relative probe rgba (0.8, 0.7) (0.0, 0.0, 0.0, 0.0)
+relative probe rgba (0.5, 0.8) (0.0, 0.0, 0.0, 0.0)
+relative probe rgba (0.2, 0.7) (0.0, 0.0, 0.0, 0.0)
diff --git a/tests/spec/glsl-1.20/execution/vs-clip-vertex-01.shader_test b/tests/spec/glsl-1.20/execution/vs-clip-vertex-01.shader_test
deleted file mode 100644
index 773936b..0000000
--- a/tests/spec/glsl-1.20/execution/vs-clip-vertex-01.shader_test
+++ /dev/null
@@ -1,55 +0,0 @@
-# [description]
-# Use all 6 clip planes to clip a rectangle to a hexagon shape.
-#
-# In this test, gl_Position and gl_ClipVertex are the same.
-
-[require]
-GLSL >= 1.20
-
-[vertex shader]
-#version 120
-void main(void)
-{
-	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
-
-	gl_ClipVertex = gl_Position;
-}
-
-[fragment shader]
-#version 120
-void main(void)
-{
-	gl_FragColor = vec4(1, 1, 1, 1);
-}
-
-[test]
-ortho 0 1 0 1
-clip plane 0 0 1 0 0.5
-clip plane 1 -1 1 0 0.8
-clip plane 2 -1 -1 0 0.8
-clip plane 3 0 -1 0 0.5
-clip plane 4 1 -1 0 0.8
-clip plane 5 1 1 0 0.8
-enable GL_CLIP_PLANE0
-enable GL_CLIP_PLANE1
-enable GL_CLIP_PLANE2
-enable GL_CLIP_PLANE3
-enable GL_CLIP_PLANE4
-enable GL_CLIP_PLANE5
-draw rect 0.1 0.1 0.8 0.8
-
-# Test points inside each hexagon edge
-relative probe rgba (0.3, 0.4) (1.0, 1.0, 1.0, 1.0)
-relative probe rgba (0.5, 0.3) (1.0, 1.0, 1.0, 1.0)
-relative probe rgba (0.7, 0.4) (1.0, 1.0, 1.0, 1.0)
-relative probe rgba (0.7, 0.6) (1.0, 1.0, 1.0, 1.0)
-relative probe rgba (0.5, 0.7) (1.0, 1.0, 1.0, 1.0)
-relative probe rgba (0.3, 0.6) (1.0, 1.0, 1.0, 1.0)
-
-# Test points outside each hexagon edge
-relative probe rgba (0.2, 0.3) (0.0, 0.0, 0.0, 0.0)
-relative probe rgba (0.5, 0.2) (0.0, 0.0, 0.0, 0.0)
-relative probe rgba (0.8, 0.3) (0.0, 0.0, 0.0, 0.0)
-relative probe rgba (0.8, 0.7) (0.0, 0.0, 0.0, 0.0)
-relative probe rgba (0.5, 0.8) (0.0, 0.0, 0.0, 0.0)
-relative probe rgba (0.2, 0.7) (0.0, 0.0, 0.0, 0.0)
diff --git a/tests/spec/glsl-1.20/execution/vs-clip-vertex-02.shader_test b/tests/spec/glsl-1.20/execution/vs-clip-vertex-02.shader_test
deleted file mode 100644
index ae1440d..0000000
--- a/tests/spec/glsl-1.20/execution/vs-clip-vertex-02.shader_test
+++ /dev/null
@@ -1,60 +0,0 @@
-# [description]
-# Use all 6 clip planes to clip a rectangle to a hexagon shape.
-#
-# In this test, gl_Position and gl_ClipVertex are different to verify
-# that gl_Position determines screen position and gl_ClipVertex
-# determines clipping.
-
-[require]
-GLSL >= 1.20
-
-[vertex shader]
-#version 120
-void main(void)
-{
-	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
-
-	// Transform gl_ClipVertex in an arbitrary way so that
-	// we can verify it is being used for clipping instead of
-	// gl_Position.
-	gl_ClipVertex = gl_Vertex * vec4(10.0, 10.0, 1.0, 1.0);
-}
-
-[fragment shader]
-#version 120
-void main(void)
-{
-	gl_FragColor = vec4(1, 1, 1, 1);
-}
-
-[test]
-ortho 0 1 0 1
-clip plane 0 0 1 0 -2.5
-clip plane 1 -1 1 0 4
-clip plane 2 -1 -1 0 14
-clip plane 3 0 -1 0 7.5
-clip plane 4 1 -1 0 4
-clip plane 5 1 1 0 -6
-enable GL_CLIP_PLANE0
-enable GL_CLIP_PLANE1
-enable GL_CLIP_PLANE2
-enable GL_CLIP_PLANE3
-enable GL_CLIP_PLANE4
-enable GL_CLIP_PLANE5
-draw rect 0.1 0.1 0.8 0.8
-
-# Test points inside each hexagon edge
-relative probe rgba (0.3, 0.4) (1.0, 1.0, 1.0, 1.0)
-relative probe rgba (0.5, 0.3) (1.0, 1.0, 1.0, 1.0)
-relative probe rgba (0.7, 0.4) (1.0, 1.0, 1.0, 1.0)
-relative probe rgba (0.7, 0.6) (1.0, 1.0, 1.0, 1.0)
-relative probe rgba (0.5, 0.7) (1.0, 1.0, 1.0, 1.0)
-relative probe rgba (0.3, 0.6) (1.0, 1.0, 1.0, 1.0)
-
-# Test points outside each hexagon edge
-relative probe rgba (0.2, 0.3) (0.0, 0.0, 0.0, 0.0)
-relative probe rgba (0.5, 0.2) (0.0, 0.0, 0.0, 0.0)
-relative probe rgba (0.8, 0.3) (0.0, 0.0, 0.0, 0.0)
-relative probe rgba (0.8, 0.7) (0.0, 0.0, 0.0, 0.0)
-relative probe rgba (0.5, 0.8) (0.0, 0.0, 0.0, 0.0)
-relative probe rgba (0.2, 0.7) (0.0, 0.0, 0.0, 0.0)
diff --git a/tests/spec/glsl-1.30/CMakeLists.txt b/tests/spec/glsl-1.30/CMakeLists.txt
new file mode 100644
index 0000000..4d1c267
--- /dev/null
+++ b/tests/spec/glsl-1.30/CMakeLists.txt
@@ -0,0 +1 @@
+add_subdirectory (linker)
diff --git a/tests/spec/glsl-1.30/execution/clipping/fs-clip-distance-interpolated.shader_test b/tests/spec/glsl-1.30/execution/clipping/fs-clip-distance-interpolated.shader_test
new file mode 100644
index 0000000..af36030
--- /dev/null
+++ b/tests/spec/glsl-1.30/execution/clipping/fs-clip-distance-interpolated.shader_test
@@ -0,0 +1,89 @@
+# From the GLSL 1.30 spec, section 7.2 (Fragment Shader Special
+# Variables):
+#
+#   The built-in input variable gl_ClipDistance array contains
+#   linearly interpolated values for the vertex values written by the
+#   vertex shader to the gl_ClipDistance vertex output variable. This
+#   array must be sized in the fragment shader either implicitly or
+#   explicitly to be the same size as it was sized in the vertex
+#   shader. Only elements in this array that have clipping enabled
+#   will have defined values.
+#
+# This test checks proper operation of gl_ClipDistance in fragment
+# shaders by setting each element of gl_ClipDistance to simple linear
+# function of gl_Vertex (computed by taking the dot product of
+# gl_Vertex with a uniform vector, and dividing the result by
+# gl_Vertex's homogeneous coordinate).  gl_Vertex is also passed
+# through to the fragment shader, which uses the same dot product to
+# verify that gl_ClipDistance has been properly interpolated.
+
+[require]
+GLSL >= 1.30
+
+[vertex shader]
+#version 130
+uniform vec4 transform[6];
+out vec4 vertex;
+out float gl_ClipDistance[6];
+
+void main()
+{
+  gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
+
+  // Set each value of gl_ClipDistance to a linear transformation of
+  // gl_Vertex.
+  for (int i = 0; i < 6; ++i) {
+    gl_ClipDistance[i] = dot(transform[i], gl_Vertex) / gl_Vertex.w;
+  }
+
+  // Pass through gl_Vertex to the fragment shader so that it can
+  // verify the interpolated values of gl_ClipDistance.
+  vertex = gl_Vertex;
+}
+
+[fragment shader]
+#version 130
+uniform vec4 transform[6];
+in vec4 vertex;
+
+void main()
+{
+  bool test_passed = true;
+
+  // Check that each value of gl_ClipDistance matches the value
+  // computed in the vertex shader.
+  for (int i = 0; i < 6; ++i) {
+    float expected_distance = dot(transform[i], vertex) / vertex.w;
+    float deviation = distance(gl_ClipDistance[i], expected_distance);
+    if (deviation > 1.0e-5) {
+      test_passed = false;
+    }
+  }
+
+  // Report pass/fail as a red or green pixel.
+  gl_FragColor = test_passed ? vec4(0.0, 1.0, 0.0, 1.0)
+                             : vec4(1.0, 0.0, 0.0, 1.0);
+}
+
+[test]
+ortho 0 1 0 1
+
+# Since the fragment shader's gl_ClipDistance array is only defined
+# for elements that have clipping enabled, we need to enable all 6
+# clip planes and carefully shoose the transform vectors to make sure
+# that no pixels are actually clipped.
+enable GL_CLIP_PLANE0
+enable GL_CLIP_PLANE1
+enable GL_CLIP_PLANE2
+enable GL_CLIP_PLANE3
+enable GL_CLIP_PLANE4
+enable GL_CLIP_PLANE5
+uniform vec4 transform[0]  1.0  1.0 0.0 0.0 # clipDistance[0] = x + y
+uniform vec4 transform[1]  1.0  2.0 0.0 0.0 # clipDistance[1] = x + 2*y
+uniform vec4 transform[2]  2.0  1.0 0.0 0.0 # clipDistance[1] = 2*x + y
+uniform vec4 transform[3]  2.0  2.0 0.0 0.0 # clipDistance[1] = 2*x + 2*y
+uniform vec4 transform[4] -1.0 -1.0 0.0 2.0 # clipDistance[1] = 2.0 - x - y
+uniform vec4 transform[5] -1.0  1.0 0.0 1.0 # clipDistance[1] = 1.0 - x + y
+
+draw rect -1 -1 2 2
+probe all rgba 0.0 1.0 0.0 1.0
diff --git a/tests/spec/glsl-1.30/execution/clipping/vs-clip-based-on-position-homogenaiety.shader_test b/tests/spec/glsl-1.30/execution/clipping/vs-clip-based-on-position-homogenaiety.shader_test
new file mode 100644
index 0000000..bedd975
--- /dev/null
+++ b/tests/spec/glsl-1.30/execution/clipping/vs-clip-based-on-position-homogenaiety.shader_test
@@ -0,0 +1,65 @@
+# [description]
+#
+# From the GLSL 1.30 spec, section 7.1 (Vertex Shader Special
+# Variables):
+#
+#   If a linked set of shaders forming the vertex stage contains no
+#   static write to gl_ClipVertex or gl_ClipDistance, but the
+#   application has requested clipping against user clip planes
+#   through the API, then the coordinate written to gl_Position is
+#   used for comparison against the user clip planes.
+#
+# This test:
+# - uses all 6 clip planes to clip a rectangle to a hexagon shape.
+# - Multiplies all coordinates of gl_Position by 2 (including the
+#   homogeneous coordinate) to verify that homogenaiety is properly
+#   accounted for in clipping.
+
+[require]
+GLSL >= 1.30
+
+[vertex shader]
+#version 130
+void main(void)
+{
+	gl_Position = 2.0 * gl_ModelViewProjectionMatrix * gl_Vertex;
+}
+
+[fragment shader]
+#version 130
+void main(void)
+{
+	gl_FragColor = vec4(1, 1, 1, 1);
+}
+
+[test]
+ortho 0 1 0 1
+clip plane 0 0 1 0 0.5
+clip plane 1 -1 1 0 0.8
+clip plane 2 -1 -1 0 0.8
+clip plane 3 0 -1 0 0.5
+clip plane 4 1 -1 0 0.8
+clip plane 5 1 1 0 0.8
+enable GL_CLIP_PLANE0
+enable GL_CLIP_PLANE1
+enable GL_CLIP_PLANE2
+enable GL_CLIP_PLANE3
+enable GL_CLIP_PLANE4
+enable GL_CLIP_PLANE5
+draw rect 0.1 0.1 0.8 0.8
+
+# Test points inside each hexagon edge
+relative probe rgba (0.3, 0.4) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.5, 0.3) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.7, 0.4) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.7, 0.6) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.5, 0.7) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.3, 0.6) (1.0, 1.0, 1.0, 1.0)
+
+# Test points outside each hexagon edge
+relative probe rgba (0.2, 0.3) (0.0, 0.0, 0.0, 0.0)
+relative probe rgba (0.5, 0.2) (0.0, 0.0, 0.0, 0.0)
+relative probe rgba (0.8, 0.3) (0.0, 0.0, 0.0, 0.0)
+relative probe rgba (0.8, 0.7) (0.0, 0.0, 0.0, 0.0)
+relative probe rgba (0.5, 0.8) (0.0, 0.0, 0.0, 0.0)
+relative probe rgba (0.2, 0.7) (0.0, 0.0, 0.0, 0.0)
diff --git a/tests/spec/glsl-1.30/execution/clipping/vs-clip-based-on-position.shader_test b/tests/spec/glsl-1.30/execution/clipping/vs-clip-based-on-position.shader_test
new file mode 100644
index 0000000..d01cae4
--- /dev/null
+++ b/tests/spec/glsl-1.30/execution/clipping/vs-clip-based-on-position.shader_test
@@ -0,0 +1,62 @@
+# [description]
+#
+# From the GLSL 1.30 spec, section 7.1 (Vertex Shader Special
+# Variables):
+#
+#   If a linked set of shaders forming the vertex stage contains no
+#   static write to gl_ClipVertex or gl_ClipDistance, but the
+#   application has requested clipping against user clip planes
+#   through the API, then the coordinate written to gl_Position is
+#   used for comparison against the user clip planes.
+#
+# This test uses all 6 clip planes to clip a rectangle to a hexagon
+# shape.
+
+[require]
+GLSL >= 1.30
+
+[vertex shader]
+#version 130
+void main(void)
+{
+	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
+}
+
+[fragment shader]
+#version 130
+void main(void)
+{
+	gl_FragColor = vec4(1, 1, 1, 1);
+}
+
+[test]
+ortho 0 1 0 1
+clip plane 0 0 1 0 0.5
+clip plane 1 -1 1 0 0.8
+clip plane 2 -1 -1 0 0.8
+clip plane 3 0 -1 0 0.5
+clip plane 4 1 -1 0 0.8
+clip plane 5 1 1 0 0.8
+enable GL_CLIP_PLANE0
+enable GL_CLIP_PLANE1
+enable GL_CLIP_PLANE2
+enable GL_CLIP_PLANE3
+enable GL_CLIP_PLANE4
+enable GL_CLIP_PLANE5
+draw rect 0.1 0.1 0.8 0.8
+
+# Test points inside each hexagon edge
+relative probe rgba (0.3, 0.4) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.5, 0.3) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.7, 0.4) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.7, 0.6) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.5, 0.7) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.3, 0.6) (1.0, 1.0, 1.0, 1.0)
+
+# Test points outside each hexagon edge
+relative probe rgba (0.2, 0.3) (0.0, 0.0, 0.0, 0.0)
+relative probe rgba (0.5, 0.2) (0.0, 0.0, 0.0, 0.0)
+relative probe rgba (0.8, 0.3) (0.0, 0.0, 0.0, 0.0)
+relative probe rgba (0.8, 0.7) (0.0, 0.0, 0.0, 0.0)
+relative probe rgba (0.5, 0.8) (0.0, 0.0, 0.0, 0.0)
+relative probe rgba (0.2, 0.7) (0.0, 0.0, 0.0, 0.0)
diff --git a/tests/spec/glsl-1.30/execution/clipping/vs-clip-distance-all-planes-enabled.shader_test b/tests/spec/glsl-1.30/execution/clipping/vs-clip-distance-all-planes-enabled.shader_test
new file mode 100644
index 0000000..adb5ad2
--- /dev/null
+++ b/tests/spec/glsl-1.30/execution/clipping/vs-clip-distance-all-planes-enabled.shader_test
@@ -0,0 +1,52 @@
+# [description]
+# Use all 6 gl_ClipDistance values to clip a rectangle to a hexagon shape.
+
+[require]
+GLSL >= 1.30
+
+[vertex shader]
+#version 130
+void main(void)
+{
+	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
+
+	gl_ClipDistance[0] = gl_Vertex.y - 0.25;
+	gl_ClipDistance[1] = gl_Vertex.y - gl_Vertex.x + 0.4;
+	gl_ClipDistance[2] = 1.4 - gl_Vertex.x - gl_Vertex.y;
+	gl_ClipDistance[3] = 0.75 - gl_Vertex.y;
+	gl_ClipDistance[4] = gl_Vertex.x - gl_Vertex.y + 0.4;
+	gl_ClipDistance[5] = gl_Vertex.x + gl_Vertex.y - 0.6;
+}
+
+[fragment shader]
+#version 130
+void main(void)
+{
+	gl_FragColor = vec4(1, 1, 1, 1);
+}
+
+[test]
+ortho 0 1 0 1
+enable GL_CLIP_PLANE0
+enable GL_CLIP_PLANE1
+enable GL_CLIP_PLANE2
+enable GL_CLIP_PLANE3
+enable GL_CLIP_PLANE4
+enable GL_CLIP_PLANE5
+draw rect 0.1 0.1 0.8 0.8
+
+# Test points inside each hexagon edge
+relative probe rgba (0.3, 0.4) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.5, 0.3) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.7, 0.4) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.7, 0.6) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.5, 0.7) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.3, 0.6) (1.0, 1.0, 1.0, 1.0)
+
+# Test points outside each hexagon edge
+relative probe rgba (0.2, 0.3) (0.0, 0.0, 0.0, 0.0)
+relative probe rgba (0.5, 0.2) (0.0, 0.0, 0.0, 0.0)
+relative probe rgba (0.8, 0.3) (0.0, 0.0, 0.0, 0.0)
+relative probe rgba (0.8, 0.7) (0.0, 0.0, 0.0, 0.0)
+relative probe rgba (0.5, 0.8) (0.0, 0.0, 0.0, 0.0)
+relative probe rgba (0.2, 0.7) (0.0, 0.0, 0.0, 0.0)
diff --git a/tests/spec/glsl-1.30/execution/clipping/vs-clip-distance-enables.shader_test b/tests/spec/glsl-1.30/execution/clipping/vs-clip-distance-enables.shader_test
new file mode 100644
index 0000000..2cb0105
--- /dev/null
+++ b/tests/spec/glsl-1.30/execution/clipping/vs-clip-distance-enables.shader_test
@@ -0,0 +1,147 @@
+# From the GLSL 1.30 spec, section 7.1 (Vertex Shader Special
+# Variables):
+#
+#   Values written into gl_ClipDistance for planes that are not
+#   enabled have no effect.
+#
+# This test sets up 6 clipping planes using gl_ClipDistance, which
+# clip a rectangle to a hexagon shape.  Then it tests various
+# combinations of enables for the 6 clipping planes, and verifies that
+# they all create the correct shape.
+#
+# To verify that each enable works, the combinations of enables were
+# chosen such that:
+# - Every plane is enabled at least once and disbled at least once.
+# - Every plane is enabled and disabled in a different pattern.
+
+[require]
+GLSL >= 1.30
+
+[vertex shader]
+#version 130
+void main(void)
+{
+	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
+
+	gl_ClipDistance[0] = gl_Vertex.y - 0.25;
+	gl_ClipDistance[1] = gl_Vertex.y - gl_Vertex.x + 0.4;
+	gl_ClipDistance[2] = 1.4 - gl_Vertex.x - gl_Vertex.y;
+	gl_ClipDistance[3] = 0.75 - gl_Vertex.y;
+	gl_ClipDistance[4] = gl_Vertex.x - gl_Vertex.y + 0.4;
+	gl_ClipDistance[5] = gl_Vertex.x + gl_Vertex.y - 0.6;
+}
+
+[fragment shader]
+#version 130
+void main(void)
+{
+	gl_FragColor = vec4(1, 1, 1, 1);
+}
+
+[test]
+ortho 0 1 0 1
+clear color 0.0 0.0 0.0 0.0
+
+# Test with planes 0, 2, and 4 enabled.
+enable GL_CLIP_PLANE0
+disable GL_CLIP_PLANE1
+enable GL_CLIP_PLANE2
+disable GL_CLIP_PLANE3
+enable GL_CLIP_PLANE4
+disable GL_CLIP_PLANE5
+clear
+draw rect 0.1 0.1 0.8 0.8
+
+# Test points inside each hexagon edge
+relative probe rgba (0.3, 0.4) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.5, 0.3) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.7, 0.4) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.7, 0.6) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.5, 0.7) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.3, 0.6) (1.0, 1.0, 1.0, 1.0)
+
+# Test points outside each hexagon edge
+relative probe rgba (0.5, 0.2) (0.0, 0.0, 0.0, 0.0) # clipped by plane 0
+relative probe rgba (0.8, 0.3) (1.0, 1.0, 1.0, 1.0) # clipped by plane 1
+relative probe rgba (0.8, 0.7) (0.0, 0.0, 0.0, 0.0) # clipped by plane 2
+relative probe rgba (0.5, 0.8) (1.0, 1.0, 1.0, 1.0) # clipped by plane 3
+relative probe rgba (0.2, 0.7) (0.0, 0.0, 0.0, 0.0) # clipped by plane 4
+relative probe rgba (0.2, 0.3) (1.0, 1.0, 1.0, 1.0) # clipped by plane 5
+
+# Test with planes 0, 1, 4, and 5 enabled.
+enable GL_CLIP_PLANE0
+enable GL_CLIP_PLANE1
+disable GL_CLIP_PLANE2
+disable GL_CLIP_PLANE3
+enable GL_CLIP_PLANE4
+enable GL_CLIP_PLANE5
+clear
+draw rect 0.1 0.1 0.8 0.8
+
+# Test points inside each hexagon edge
+relative probe rgba (0.3, 0.4) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.5, 0.3) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.7, 0.4) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.7, 0.6) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.5, 0.7) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.3, 0.6) (1.0, 1.0, 1.0, 1.0)
+
+# Test points outside each hexagon edge
+relative probe rgba (0.5, 0.2) (0.0, 0.0, 0.0, 0.0) # clipped by plane 0
+relative probe rgba (0.8, 0.3) (0.0, 0.0, 0.0, 0.0) # clipped by plane 1
+relative probe rgba (0.8, 0.7) (1.0, 1.0, 1.0, 1.0) # clipped by plane 2
+relative probe rgba (0.5, 0.8) (1.0, 1.0, 1.0, 1.0) # clipped by plane 3
+relative probe rgba (0.2, 0.7) (0.0, 0.0, 0.0, 0.0) # clipped by plane 4
+relative probe rgba (0.2, 0.3) (0.0, 0.0, 0.0, 0.0) # clipped by plane 5
+
+# Test with planes 0, 1, 2, and 3 enabled.
+enable GL_CLIP_PLANE0
+enable GL_CLIP_PLANE1
+enable GL_CLIP_PLANE2
+enable GL_CLIP_PLANE3
+disable GL_CLIP_PLANE4
+disable GL_CLIP_PLANE5
+clear
+draw rect 0.1 0.1 0.8 0.8
+
+# Test points inside each hexagon edge
+relative probe rgba (0.3, 0.4) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.5, 0.3) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.7, 0.4) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.7, 0.6) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.5, 0.7) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.3, 0.6) (1.0, 1.0, 1.0, 1.0)
+
+# Test points outside each hexagon edge
+relative probe rgba (0.5, 0.2) (0.0, 0.0, 0.0, 0.0) # clipped by plane 0
+relative probe rgba (0.8, 0.3) (0.0, 0.0, 0.0, 0.0) # clipped by plane 1
+relative probe rgba (0.8, 0.7) (0.0, 0.0, 0.0, 0.0) # clipped by plane 2
+relative probe rgba (0.5, 0.8) (0.0, 0.0, 0.0, 0.0) # clipped by plane 3
+relative probe rgba (0.2, 0.7) (1.0, 1.0, 1.0, 1.0) # clipped by plane 4
+relative probe rgba (0.2, 0.3) (1.0, 1.0, 1.0, 1.0) # clipped by plane 5
+
+# Test with planes 4 and 5 enabled.
+disable GL_CLIP_PLANE0
+disable GL_CLIP_PLANE1
+disable GL_CLIP_PLANE2
+disable GL_CLIP_PLANE3
+enable GL_CLIP_PLANE4
+enable GL_CLIP_PLANE5
+clear
+draw rect 0.1 0.1 0.8 0.8
+
+# Test points inside each hexagon edge
+relative probe rgba (0.3, 0.4) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.5, 0.3) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.7, 0.4) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.7, 0.6) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.5, 0.7) (1.0, 1.0, 1.0, 1.0)
+relative probe rgba (0.3, 0.6) (1.0, 1.0, 1.0, 1.0)
+
+# Test points outside each hexagon edge
+relative probe rgba (0.5, 0.2) (1.0, 1.0, 1.0, 1.0) # clipped by plane 0
+relative probe rgba (0.8, 0.3) (1.0, 1.0, 1.0, 1.0) # clipped by plane 1
+relative probe rgba (0.8, 0.7) (1.0, 1.0, 1.0, 1.0) # clipped by plane 2
+relative probe rgba (0.5, 0.8) (1.0, 1.0, 1.0, 1.0) # clipped by plane 3
+relative probe rgba (0.2, 0.7) (0.0, 0.0, 0.0, 0.0) # clipped by plane 4
+relative probe rgba (0.2, 0.3) (0.0, 0.0, 0.0, 0.0) # clipped by plane 5
diff --git a/tests/spec/glsl-1.30/execution/clipping/vs-clip-distance-explicitly-sized.shader_test b/tests/spec/glsl-1.30/execution/clipping/vs-clip-distance-explicitly-sized.shader_test
new file mode 100644
index 0000000..00023c9
--- /dev/null
+++ b/tests/spec/glsl-1.30/execution/clipping/vs-clip-distance-explicitly-sized.shader_test
@@ -0,0 +1,44 @@
+# From the GLSL 1.30 spec section 7.1 (Vertex Shader Special
+# Variables):
+#
+#   The gl_ClipDistance array is predeclared as unsized and must be
+#   sized by the shader either redeclaring it with a size or indexing
+#   it only with integral constant expressions. This needs to size the
+#   array to include all the clip planes that are enabled via the
+#   OpenGL API; if the size does not include all enabled planes,
+#   results are undefined. The size can be at most
+#   gl_MaxClipDistances. The number of varying components (see
+#   gl_MaxVaryingComponents) consumed by gl_ClipDistance will match
+#   the size of the array, no matter how many planes are enabled. The
+#   shader must also set all values in gl_ClipDistance that have been
+#   enabled via the OpenGL API, or results are undefined. Values
+#   written into gl_ClipDistance for planes that are not enabled have
+#   no effect.
+#
+# This test checks that the GLSL compiler respects the size of
+# gl_ClipDistance when it is explicitly declared in the vertex shader.
+
+[require]
+GLSL >= 1.30
+
+[vertex shader]
+#version 130
+out float gl_ClipDistance[3];
+
+void main()
+{
+  gl_Position = gl_Vertex;
+  gl_FrontColor = (gl_ClipDistance.length() == 3) ? vec4(0.0, 1.0, 0.0, 1.0)
+                                                  : vec4(1.0, 0.0, 0.0, 1.0);
+}
+
+[fragment shader]
+#version 130
+void main()
+{
+  gl_FragColor = gl_Color;
+}
+
+[test]
+draw rect -1 -1 2 2
+probe all rgba 0.0 1.0 0.0 1.0
diff --git a/tests/spec/glsl-1.30/execution/clipping/vs-clip-distance-implicitly-sized.shader_test b/tests/spec/glsl-1.30/execution/clipping/vs-clip-distance-implicitly-sized.shader_test
new file mode 100644
index 0000000..185fb22
--- /dev/null
+++ b/tests/spec/glsl-1.30/execution/clipping/vs-clip-distance-implicitly-sized.shader_test
@@ -0,0 +1,52 @@
+# From the GLSL 1.30 spec section 7.1 (Vertex Shader Special
+# Variables):
+#
+#   The gl_ClipDistance array is predeclared as unsized and must be
+#   sized by the shader either redeclaring it with a size or indexing
+#   it only with integral constant expressions. This needs to size the
+#   array to include all the clip planes that are enabled via the
+#   OpenGL API; if the size does not include all enabled planes,
+#   results are undefined. The size can be at most
+#   gl_MaxClipDistances. The number of varying components (see
+#   gl_MaxVaryingComponents) consumed by gl_ClipDistance will match
+#   the size of the array, no matter how many planes are enabled. The
+#   shader must also set all values in gl_ClipDistance that have been
+#   enabled via the OpenGL API, or results are undefined. Values
+#   written into gl_ClipDistance for planes that are not enabled have
+#   no effect.
+#
+# This test checks that the GLSL compiler respects the size of
+# gl_ClipDistance when it is implicitly sized in the vertex shader by
+# indexing into it with integral constant expressions.
+#
+# The spec isn't clear about whether it's necessary for the GLSL
+# compiler to size gl_ClipDistance to the minimum size possible.  In
+# other words, if only gl_ClipDistance[2] is accessed, must the
+# compiler infer that the size of gl_ClipDistance is 3, or is any size
+# greater than or equal to 3 acceptable?  This test assumes any size
+# greater than or equal to 3 is acceptable.
+
+[require]
+GLSL >= 1.30
+
+[vertex shader]
+#version 130
+
+void main()
+{
+  gl_Position = gl_Vertex;
+  gl_FrontColor = (gl_ClipDistance.length() >= 3) ? vec4(0.0, 1.0, 0.0, 1.0)
+                                                  : vec4(1.0, 0.0, 0.0, 1.0);
+  gl_ClipDistance[2] = 1.0;
+}
+
+[fragment shader]
+#version 130
+void main()
+{
+  gl_FragColor = gl_Color;
+}
+
+[test]
+draw rect -1 -1 2 2
+probe all rgba 0.0 1.0 0.0 1.0
diff --git a/tests/spec/glsl-1.30/execution/clipping/vs-clip-distance-sizeable-to-max.shader_test b/tests/spec/glsl-1.30/execution/clipping/vs-clip-distance-sizeable-to-max.shader_test
new file mode 100644
index 0000000..accd639
--- /dev/null
+++ b/tests/spec/glsl-1.30/execution/clipping/vs-clip-distance-sizeable-to-max.shader_test
@@ -0,0 +1,45 @@
+# From the GLSL 1.30 spec section 7.1 (Vertex Shader Special
+# Variables):
+#
+#   The gl_ClipDistance array is predeclared as unsized and must be
+#   sized by the shader either redeclaring it with a size or indexing
+#   it only with integral constant expressions. This needs to size the
+#   array to include all the clip planes that are enabled via the
+#   OpenGL API; if the size does not include all enabled planes,
+#   results are undefined. The size can be at most
+#   gl_MaxClipDistances. The number of varying components (see
+#   gl_MaxVaryingComponents) consumed by gl_ClipDistance will match
+#   the size of the array, no matter how many planes are enabled. The
+#   shader must also set all values in gl_ClipDistance that have been
+#   enabled via the OpenGL API, or results are undefined. Values
+#   written into gl_ClipDistance for planes that are not enabled have
+#   no effect.
+#
+# This test checks that the size of gl_ClipDistance can be set to
+# gl_MaxClipDistances without error, and that this actually causes the
+# size of the array to be set properly.
+
+[require]
+GLSL >= 1.30
+
+[vertex shader]
+#version 130
+out float gl_ClipDistance[gl_MaxClipDistances];
+
+void main()
+{
+  gl_Position = gl_Vertex;
+  gl_FrontColor = (gl_ClipDistance.length() == gl_MaxClipDistances)
+    ? vec4(0.0, 1.0, 0.0, 1.0) : vec4(1.0, 0.0, 0.0, 1.0);
+}
+
+[fragment shader]
+#version 130
+void main()
+{
+  gl_FragColor = gl_Color;
+}
+
+[test]
+draw rect -1 -1 2 2
+probe all rgba 0.0 1.0 0.0 1.0
diff --git a/tests/spec/glsl-1.30/execution/vs-clip-distance-01.shader_test b/tests/spec/glsl-1.30/execution/vs-clip-distance-01.shader_test
deleted file mode 100644
index adb5ad2..0000000
--- a/tests/spec/glsl-1.30/execution/vs-clip-distance-01.shader_test
+++ /dev/null
@@ -1,52 +0,0 @@
-# [description]
-# Use all 6 gl_ClipDistance values to clip a rectangle to a hexagon shape.
-
-[require]
-GLSL >= 1.30
-
-[vertex shader]
-#version 130
-void main(void)
-{
-	gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
-
-	gl_ClipDistance[0] = gl_Vertex.y - 0.25;
-	gl_ClipDistance[1] = gl_Vertex.y - gl_Vertex.x + 0.4;
-	gl_ClipDistance[2] = 1.4 - gl_Vertex.x - gl_Vertex.y;
-	gl_ClipDistance[3] = 0.75 - gl_Vertex.y;
-	gl_ClipDistance[4] = gl_Vertex.x - gl_Vertex.y + 0.4;
-	gl_ClipDistance[5] = gl_Vertex.x + gl_Vertex.y - 0.6;
-}
-
-[fragment shader]
-#version 130
-void main(void)
-{
-	gl_FragColor = vec4(1, 1, 1, 1);
-}
-
-[test]
-ortho 0 1 0 1
-enable GL_CLIP_PLANE0
-enable GL_CLIP_PLANE1
-enable GL_CLIP_PLANE2
-enable GL_CLIP_PLANE3
-enable GL_CLIP_PLANE4
-enable GL_CLIP_PLANE5
-draw rect 0.1 0.1 0.8 0.8
-
-# Test points inside each hexagon edge
-relative probe rgba (0.3, 0.4) (1.0, 1.0, 1.0, 1.0)
-relative probe rgba (0.5, 0.3) (1.0, 1.0, 1.0, 1.0)
-relative probe rgba (0.7, 0.4) (1.0, 1.0, 1.0, 1.0)
-relative probe rgba (0.7, 0.6) (1.0, 1.0, 1.0, 1.0)
-relative probe rgba (0.5, 0.7) (1.0, 1.0, 1.0, 1.0)
-relative probe rgba (0.3, 0.6) (1.0, 1.0, 1.0, 1.0)
-
-# Test points outside each hexagon edge
-relative probe rgba (0.2, 0.3) (0.0, 0.0, 0.0, 0.0)
-relative probe rgba (0.5, 0.2) (0.0, 0.0, 0.0, 0.0)
-relative probe rgba (0.8, 0.3) (0.0, 0.0, 0.0, 0.0)
-relative probe rgba (0.8, 0.7) (0.0, 0.0, 0.0, 0.0)
-relative probe rgba (0.5, 0.8) (0.0, 0.0, 0.0, 0.0)
-relative probe rgba (0.2, 0.7) (0.0, 0.0, 0.0, 0.0)
diff --git a/tests/spec/glsl-1.30/linker/CMakeLists.txt b/tests/spec/glsl-1.30/linker/CMakeLists.txt
new file mode 100644
index 0000000..611a57e
--- /dev/null
+++ b/tests/spec/glsl-1.30/linker/CMakeLists.txt
@@ -0,0 +1 @@
+add_subdirectory (clipping)
diff --git a/tests/spec/glsl-1.30/linker/clipping/CMakeLists.gl.txt b/tests/spec/glsl-1.30/linker/clipping/CMakeLists.gl.txt
new file mode 100644
index 0000000..233c4f7
--- /dev/null
+++ b/tests/spec/glsl-1.30/linker/clipping/CMakeLists.gl.txt
@@ -0,0 +1,18 @@
+
+include_directories(
+	${GLEXT_INCLUDE_DIR}
+	${OPENGL_INCLUDE_PATH}
+	${GLUT_INCLUDE_DIR}
+	${piglit_SOURCE_DIR}/tests/mesa/util
+	${piglit_SOURCE_DIR}/tests/util
+)
+
+link_libraries (
+	piglitutil
+	${OPENGL_gl_LIBRARY}
+	${OPENGL_glu_LIBRARY}
+	${GLUT_glut_LIBRARY}
+)
+
+add_executable (clip-distance-not-sizeable-above-max clip-distance-not-sizeable-above-max.c)
+add_executable (mixing-clip-distance-and-clip-vertex-disallowed mixing-clip-distance-and-clip-vertex-disallowed.c)
diff --git a/tests/spec/glsl-1.30/linker/clipping/CMakeLists.txt b/tests/spec/glsl-1.30/linker/clipping/CMakeLists.txt
new file mode 100644
index 0000000..144a306
--- /dev/null
+++ b/tests/spec/glsl-1.30/linker/clipping/CMakeLists.txt
@@ -0,0 +1 @@
+piglit_include_target_api()
diff --git a/tests/spec/glsl-1.30/linker/clipping/clip-distance-not-sizeable-above-max.c b/tests/spec/glsl-1.30/linker/clipping/clip-distance-not-sizeable-above-max.c
new file mode 100644
index 0000000..249210d
--- /dev/null
+++ b/tests/spec/glsl-1.30/linker/clipping/clip-distance-not-sizeable-above-max.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file clip-distance-not-sizeable-above-max.c
+ *
+ * From the GLSL 1.30 spec section 7.1 (Vertex Shader Special
+ * Variables):
+ *
+ *   The gl_ClipDistance array is predeclared as unsized and must be
+ *   sized by the shader either redeclaring it with a size or indexing
+ *   it only with integral constant expressions. This needs to size
+ *   the array to include all the clip planes that are enabled via the
+ *   OpenGL API; if the size does not include all enabled planes,
+ *   results are undefined. The size can be at most
+ *   gl_MaxClipDistances. The number of varying components (see
+ *   gl_MaxVaryingComponents) consumed by gl_ClipDistance will match
+ *   the size of the array, no matter how many planes are enabled. The
+ *   shader must also set all values in gl_ClipDistance that have been
+ *   enabled via the OpenGL API, or results are undefined. Values
+ *   written into gl_ClipDistance for planes that are not enabled have
+ *   no effect.
+ *
+ * This test checks that the an error occurs when trying to set the
+ * size of gl_ClipDistance larger than gl_MaxClipDistances.
+ *
+ * Note: we don't care about the specific error that is generated or
+ * the precise circumstances under which it occurs--we just want to
+ * make sure that gl_MaxClipDistances isn't too small.  So to provoke
+ * the error into occurring, we also try to access the first
+ * disallowed element of the array.
+ */
+#include "piglit-util.h"
+
+int piglit_width = 100, piglit_height = 100;
+int piglit_window_mode = GLUT_RGB | GLUT_DOUBLE;
+
+static const char vert[] =
+	"#version 130\n"
+	"out float gl_ClipDistance[gl_MaxClipDistances + 1];\n"
+	"void main()\n"
+	"{\n"
+	"  gl_Position = gl_Vertex;\n"
+	"  gl_ClipDistance[gl_MaxClipDistances] = 1.0;\n"
+	"}\n";
+
+static const char frag[] =
+	"#version 130\n"
+	"void main()\n"
+	"{\n"
+	"  gl_FragColor = gl_Color;\n"
+	"}\n";
+
+enum piglit_result
+piglit_display(void)
+{
+	return PIGLIT_FAIL;
+}
+
+void
+piglit_init(int argc, char **argv)
+{
+	const char *glsl_version_string;
+	float glsl_version;
+	GLint ok;
+	GLuint prog;
+	GLuint vs;
+	GLuint fs;
+
+
+	piglit_require_GLSL();
+
+	glsl_version_string = (char *)
+		glGetString(GL_SHADING_LANGUAGE_VERSION);
+	glsl_version = (glsl_version_string == NULL)
+		? 0.0 : strtod(glsl_version_string, NULL);
+	if (glsl_version <= 1.299999) {
+		printf("Test requires GLSL version >= 1.3.  "
+		       "Actual version is %.1f.\n",
+		       glsl_version);
+		piglit_report_result(PIGLIT_SKIP);
+	}
+
+	vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vert);
+	fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, frag);
+	prog = glCreateProgram();
+	glAttachShader(prog, vs);
+	glAttachShader(prog, fs);
+	glLinkProgram(prog);
+	glDeleteShader(vs);
+	glDeleteShader(fs);
+
+	ok = piglit_link_check_status_quiet(prog);
+	if (ok) {
+		fprintf(stderr,
+			"Linking with a shader that accesses gl_ClipDistance "
+			"beyond gl_MaxClipDistances succeeded when it should "
+			"have failed.\n");
+		piglit_report_result(PIGLIT_FAIL);
+	}
+
+	piglit_report_result(PIGLIT_PASS);
+}
diff --git a/tests/spec/glsl-1.30/linker/clipping/mixing-clip-distance-and-clip-vertex-disallowed.c b/tests/spec/glsl-1.30/linker/clipping/mixing-clip-distance-and-clip-vertex-disallowed.c
new file mode 100644
index 0000000..94c3565
--- /dev/null
+++ b/tests/spec/glsl-1.30/linker/clipping/mixing-clip-distance-and-clip-vertex-disallowed.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright © 2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file mixing-clip-distance-and-clip-vertex-disallowed.c
+ *
+ * From the GLSL 1.30 spec, section 7.1 (Vertex Shader Special
+ * Variables):
+ *
+ *   It is an error for a shader to statically write both
+ *   gl_ClipVertex and gl_ClipDistance.
+ *
+ * This test verifies that an error is generated if the shader
+ * contains writes to both variables, even if those writes would never
+ * both occur in the same render.
+ */
+#include "piglit-util.h"
+
+int piglit_width = 100, piglit_height = 100;
+int piglit_window_mode = GLUT_RGB | GLUT_DOUBLE;
+
+static const char vert[] =
+	"#version 130\n"
+	"uniform bool use_ClipDistance;\n"
+	"void main()\n"
+	"{\n"
+	"  gl_Position = vec4(0.0);\n"
+	"  if (use_ClipDistance) {\n"
+	"    gl_ClipDistance[0] = 1.0;\n"
+	"  } else {\n"
+	"    gl_ClipVertex = vec4(0.0);\n"
+	"  }\n"
+	"}\n";
+
+static const char frag[] =
+	"#version 130\n"
+	"void main()\n"
+	"{\n"
+	"  gl_FragColor = gl_Color;\n"
+	"}\n";
+
+enum piglit_result
+piglit_display(void)
+{
+	return PIGLIT_FAIL;
+}
+
+void
+piglit_init(int argc, char **argv)
+{
+	const char *glsl_version_string;
+	float glsl_version;
+	GLint ok;
+	GLuint prog;
+	GLuint vs;
+	GLuint fs;
+
+
+	piglit_require_GLSL();
+
+	glsl_version_string = (char *)
+		glGetString(GL_SHADING_LANGUAGE_VERSION);
+	glsl_version = (glsl_version_string == NULL)
+		? 0.0 : strtod(glsl_version_string, NULL);
+	if (glsl_version <= 1.299999) {
+		printf("Test requires GLSL version >= 1.3.  "
+		       "Actual version is %.1f.\n",
+		       glsl_version);
+		piglit_report_result(PIGLIT_SKIP);
+	}
+
+	vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vert);
+	fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, frag);
+	prog = glCreateProgram();
+	glAttachShader(prog, vs);
+	glAttachShader(prog, fs);
+	glLinkProgram(prog);
+	glDeleteShader(vs);
+	glDeleteShader(fs);
+
+	ok = piglit_link_check_status_quiet(prog);
+	if (ok) {
+		fprintf(stderr,
+			"Linking with a shader that accesses both "
+			"gl_ClipDistance and gl_ClipVertex succeeded when it "
+			"should have failed.\n");
+		piglit_report_result(PIGLIT_FAIL);
+	}
+
+	piglit_report_result(PIGLIT_PASS);
+}
diff --git a/tests/spec/glsl-1.30/linker/placeholder b/tests/spec/glsl-1.30/linker/placeholder
deleted file mode 100644
index e69de29..0000000
-- 
1.7.6



More information about the Piglit mailing list