[Piglit] [PATCH 4/9] gen_interpolation_tests: Support geometry shader tests.

Fabian Bieler fabianbieler at fastmail.fm
Mon Jun 24 15:30:41 PDT 2013


For every non-gs test, add one test for every possible interpolation qualifier
in the geometry shader.
If a geometry shader is present, the interpolation qualifier in the vertex
shader should be ignored.

>From the ARB_geometry_shader4 spec section 2.16:
"This new geometry shader pipeline stage is inserted after primitive assembly,
right before color clamping (section 2.14.6), flat shading (section 2.14.7)
and clipping (sections 2.12 and 2.14.8)."

Also add a comment in the generated test with the name of the script that
generated the test.

Note that this commit makes use of the gl_ClipDistanceIn variable, which is not
mentioned in any spec (the ARB_geometry_dhader4 spec is written against the
GLSL 1.1 spec and gl_ClipDistance was only introduced in version 1.3). Version
1.5 geometry shaders require the use of the gl_in interface block when reading
gl_ClipDistance passed from the vertex shader.
---
 generated_tests/gen_interpolation_tests.py | 141 ++++++++++++++++++++++++-----
 1 file changed, 118 insertions(+), 23 deletions(-)

diff --git a/generated_tests/gen_interpolation_tests.py b/generated_tests/gen_interpolation_tests.py
index da88f68..16800e5 100644
--- a/generated_tests/gen_interpolation_tests.py
+++ b/generated_tests/gen_interpolation_tests.py
@@ -21,11 +21,13 @@
 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 # DEALINGS IN THE SOFTWARE.
 
-# Correct interpolation of vertex shader outputs depends on (a)
-# whether an interpolation qualifier is present in the shader source,
-# and if so which qualifier is used, (b) if no interpolation qualifier
-# is present, whether the output is a user-defined variable or a
-# built-in color, and (c) if the output is a built-in color, the
+# Correct interpolation of vertex data during rasterization depends on (a)
+# whether an interpolation qualifier is present in the geometry shader
+# source, and if so which qualifier is used, (b) if no geometry shader
+# is present, whether an interpolation qualifier is present in the vertex
+# shader source, and if so which qualifier is used, (c) if no interpolation
+# qualifier is present, whether the variable is user-defined or a
+# built-in color, and (d) if the output is a built-in color, the
 # setting of the ShadeModel() setting.  In addition, we would like to
 # test correct interpolation under various clipping scenarios.
 #
@@ -34,8 +36,8 @@
 # proper interpolation for every combination of the following
 # variables:
 #
-# - which interpolation qualifier is used ("flat", "noperspective",
-#   "smooth", or no qualifier)
+# - which interpolation qualifier is used in the vertex shader ("flat",
+#   "noperspective", "smooth", or no qualifier)
 #
 # - which variable is used (gl_FrontColor, gl_BackColor,
 #   gl_FrontSecondaryColor, gl_BackSecondaryColor, or a non-built-in
@@ -47,6 +49,9 @@
 #   clipped using gl_ClipDistance, clipped against the fixed viewing
 #   volume, or unclipped.
 #
+# - which interpolation qualifier is used in the geometry shader ("flat",
+#   "noperspective", "smooth", no qualifier, or no geometry shader)
+#
 # The tests operate by drawing a triangle with a different value of
 # the variable at each vertex, and then probing within the interior of
 # the triangle to verify that interpolation was performed correctly.
@@ -63,16 +68,16 @@
 #
 # This program outputs, to stdout, the name of each file it generates.
 
-import os
+import os, sys
 
 
 class Test(object):
-    def __init__(self, interpolation_qualifier, variable, shade_model,
-		 clipping):
+    def __init__(self, vs_interpolation_qualifier, variable, shade_model,
+		 clipping, gs_interpolation_qualifier = False):
 	"""Get ready to generate a test using the given settings.
 
-	interpolation_qualifier is a string representing the desired
-	interpolation qualifier that should appear in GLSL code
+	vs_interpolation_qualifier is a string representing the desired
+	interpolation qualifier that should appear in GLSL vertex code
 	('flat', 'noperspective', or 'smooth'), or None if no
 	qualifier should appear.
 
@@ -93,11 +98,22 @@ class Test(object):
 	'vertex' to test a triangle which has one corner clipped using
 	gl_ClipVertex, or 'distance' to test a triangle which has one
 	corner clipped using gl_ClipDistance.
+
+	gs_interpolation_qualifier is analoguous to vs_interpolation_qualifier
+	but in the geometry shader. If no parameter was passed (not even
+	'None') create a test without a geometry shader.
 	"""
-	self.interpolation_qualifier = interpolation_qualifier
+	self.vs_interpolation_qualifier = vs_interpolation_qualifier
+	self.variable = variable
 	self.vs_variable = variable
 	self.shade_model = shade_model
 	self.clipping = clipping
+	if gs_interpolation_qualifier != False:
+		self.gs = True;
+		self.gs_interpolation_qualifier = gs_interpolation_qualifier
+	else:
+		self.gs = False
+		self.gs_interpolation_qualifier = None
 
 	# When colors are mapped into the fragment shader, the string
 	# 'Front' or 'Back' is dropped from the variable name, since
@@ -113,21 +129,34 @@ class Test(object):
 	# we are testing a generic vertex shader output.
 	self.builtin_variable = variable[:3] == 'gl_'
 
+	# If we're using a geometry shader and no builtin variable,
+	# Add a postfix to the vertex shader output to prevent
+	# conflicting variable names.
+	if self.gs:
+	    self.gs_variable = variable
+	    if not self.builtin_variable:
+		self.vs_variable = variable + 'In'
+
 	# Determine whether the test requires GLSL 1.30.  If it does,
 	# use "in" and "out" to qualify shader inputs and outputs.
 	# Otherwise use the old keywords "attribute" and "varying".
 	# shader_runner will insert a #version directive based on
 	# glsl_version.
-	if self.interpolation_qualifier or self.clipping == 'distance':
+	if (self.vs_interpolation_qualifier or self.clipping == 'distance' or
+	    self.gs_interpolation_qualifier):
 	    self.glsl_version = '1.30'
 	    self.vs_input = 'in'
 	    self.vs_output = 'out'
 	    self.fs_input = 'in'
+	    self.gs_input = 'in'
+	    self.gs_output = 'out'
 	else:
 	    self.glsl_version = '1.10'
 	    self.vs_input = 'attribute'
 	    self.vs_output = 'varying'
 	    self.fs_input = 'varying'
+	    self.gs_input = 'varying in'
+	    self.gs_output = 'varying out'
 
 	# Determine the location of the near and far planes for the
 	# frustum projection.  The triangle fits between z coordinates
@@ -139,6 +168,12 @@ class Test(object):
 	    self.frustum_near = 1.0
 	self.frustum_far = 3.0
 
+	# Flat shading is performed after the geometry shader (if present).
+	if self.gs:
+	    self.interpolation_qualifier = self.gs_interpolation_qualifier
+	else:
+	    self.interpolation_qualifier = self.vs_interpolation_qualifier
+
 	# Determine whether we expect the GL implementation to use
 	# flatshading, non-perspective interpolation, or perspective
 	# interpolation.
@@ -168,6 +203,14 @@ class Test(object):
 	    self.expected_behavior = 'smooth'
 
     def filename(self):
+	if self.gs:
+	    return os.path.join(
+		'spec', 'ARB_geometry_shader4',
+		'execution', 'interpolation',
+		'interpolation-{0}-{1}-{2}-{3}-{4}.shader_test'.format(
+		    self.vs_interpolation_qualifier or 'none',
+		    self.gs_interpolation_qualifier or 'none', self.variable,
+		    self.shade_model, self.clipping or 'none'))
 	return os.path.join(
 	    'spec', 'glsl-{0}'.format(self.glsl_version),
 	    'execution', 'interpolation',
@@ -255,16 +298,30 @@ class Test(object):
 		    yield x2d, y2d, b3d_0, b3d_1, b3d_2, 1.0
 
     def generate(self):
+	test = '# Test generated by:\n'
+	test += '# {0}\n'.format(" ".join(sys.argv))
 	if self.builtin_variable:
-	    test = '# Test proper interpolation of {0}\n'.format(
-		self.vs_variable)
+	    test += '# Test proper interpolation of {0}\n'.format(
+		self.variable)
 	else:
-	    test = '# Test proper interpolation of a non-built-in variable\n'
-	if self.interpolation_qualifier:
-	    test += '# When qualified with {0!r}\n'.format(
-		self.interpolation_qualifier)
+	    test += '# Test proper interpolation of a non-built-in variable\n'
+	if self.gs:
+	    if self.gs_interpolation_qualifier:
+		test += '# When qualified in geometry shader with '
+		test += '{0!r}\n'.format(self.gs_interpolation_qualifier)
+	    else:
+		test += '# When no interpolation qualifier present in '
+		test += 'geometry shader\n'
+	    if self.vs_interpolation_qualifier:
+		test += '# And bogus qualifier {0!r} '.format(
+		    self.vs_interpolation_qualifier)
+		test += 'is present in vertex shader\n'
 	else:
-	    test += '# When no interpolation qualifier present\n'
+	    if self.vs_interpolation_qualifier:
+		test += '# When qualified with {0!r}\n'.format(
+		    self.vs_interpolation_qualifier)
+	    else:
+		test += '# When no interpolation qualifier present\n'
 	test += '# And ShadeModel is {0!r}\n'.format(self.shade_model)
 	if self.clipping == 'fixed':
 	    test += '# And clipping via fixed planes\n'
@@ -276,13 +333,15 @@ class Test(object):
 	    assert self.clipping is None
 	test += '[require]\n'
 	test += 'GLSL >= {0}\n'.format(self.glsl_version)
+	if self.gs:
+	    test += 'GL_ARB_geometry_shader4\n'
 	test += '\n'
 	test += '[vertex shader]\n'
 	test += '{0} vec4 vertex;\n'.format(self.vs_input)
 	test += '{0} vec4 input_data;\n'.format(self.vs_input)
-	if self.interpolation_qualifier or not self.builtin_variable:
+	if self.vs_interpolation_qualifier or not self.builtin_variable:
 	    test += '{0} {1} vec4 {2};'.format(
-		self.interpolation_qualifier or '',
+		self.vs_interpolation_qualifier or '',
 		self.vs_output, self.vs_variable).strip() + '\n'
 	test += 'void main()\n'
 	test += '{\n'
@@ -294,6 +353,37 @@ class Test(object):
 	    test += '  gl_ClipVertex = vertex;\n'
 	test += '}\n'
 	test += '\n'
+	if self.gs:
+	    pass
+	    test += '[geometry shader]\n'
+	    test += '#extension GL_ARB_geometry_shader4: enable\n'
+	    if self.vs_interpolation_qualifier or not self.builtin_variable:
+		test += '{0} {1} vec4 {2}{3}[3];'.format(
+		    self.vs_interpolation_qualifier or '',
+		    self.gs_input, self.vs_variable,
+		    'In' if self.builtin_variable else '').strip() + '\n'
+	    if self.gs_interpolation_qualifier or not self.builtin_variable:
+		test += '{0} {1} vec4 {2};'.format(
+		    self.gs_interpolation_qualifier or '',
+		    self.gs_output, self.gs_variable).strip() + '\n'
+	    test += 'void main()\n'
+	    test += '{\n'
+	    test += '  for (int i = 0; i < 3; i++) {\n'
+	    test += '    gl_Position = gl_PositionIn[i];\n'
+	    test += '    {0} = {0}In[i];\n'.format(self.gs_variable)
+	    if self.clipping == 'distance':
+		test += '    gl_ClipDistance[0] = gl_ClipDistanceIn[i][0];\n'
+	    elif self.clipping == 'vertex':
+		test += '    gl_ClipVertex = gl_ClipVertexIn[i];\n'
+	    test += '    EmitVertex();\n'
+	    test += '  }\n'
+	    test += '}\n'
+	    test += '\n'
+	    test += '[geometry layout]\n'
+	    test += 'input type GL_TRIANGLES\n'
+	    test += 'output type GL_TRIANGLE_STRIP\n'
+	    test += 'vertices out 3\n'
+	    test += '\n'
 	test += '[fragment shader]\n'
 	if self.interpolation_qualifier or not self.builtin_variable:
 	    test += '{0} {1} vec4 {2};'.format(
@@ -339,6 +429,11 @@ def all_tests():
 		for clipping in ['vertex', 'distance', 'fixed', None]:
 		    yield Test(interpolation_qualifier, variable, shade_model,
 			       clipping)
+		    for gs_interpolation_qualifier in ['flat', 'smooth',
+						       'noperspective', None]:
+			yield Test(interpolation_qualifier, variable,
+				   shade_model, clipping,
+				   gs_interpolation_qualifier)
 
 
 def main():
-- 
1.8.1.2



More information about the Piglit mailing list