[Piglit] [PATCH 1/9] generated_tests: combine gen_{tcs, tes}_input_tests

Dylan Baker baker.dylan.c at gmail.com
Wed Oct 7 14:26:13 PDT 2015


These two generators share a lot of boilerplate, and all of the
interesting logic is contained in the Test class. A little simple
renaming and the generators can be combined, reducing the amount of
boilerplate needed.

Signed-off-by: Dylan Baker <dylanx.c.baker at intel.com>
---
 generated_tests/CMakeLists.txt                     |  10 +-
 generated_tests/gen_tcs_input_tests.py             | 308 ---------------------
 ..._tes_input_tests.py => gen_tess_input_tests.py} | 289 +++++++++++++++++--
 3 files changed, 275 insertions(+), 332 deletions(-)
 delete mode 100644 generated_tests/gen_tcs_input_tests.py
 rename generated_tests/{gen_tes_input_tests.py => gen_tess_input_tests.py} (53%)

diff --git a/generated_tests/CMakeLists.txt b/generated_tests/CMakeLists.txt
index 0dc617b..dbfd5c8 100644
--- a/generated_tests/CMakeLists.txt
+++ b/generated_tests/CMakeLists.txt
@@ -43,11 +43,8 @@ piglit_make_generated_tests(
 	templates/gen_const_builtin_equal_tests/template.shader_test.mako
 	)
 piglit_make_generated_tests(
-	tes_input_tests.list
-	gen_tes_input_tests.py)
-piglit_make_generated_tests(
-	tcs_input_tests.list
-	gen_tcs_input_tests.py)
+	tess_input_tests.list
+	gen_tess_input_tests.py)
 piglit_make_generated_tests(
 	interpolation_tests.list
 	gen_interpolation_tests.py
@@ -162,8 +159,7 @@ add_custom_target(gen-gl-tests
 			constant_array_size_tests.list
 			const_builtin_equal_tests.list
 			builtin_packing_tests.list
-			tcs_input_tests.list
-			tes_input_tests.list
+			tess_input_tests.list
 			interpolation_tests.list
 			non-lvalue_tests.list
 			texture_query_lod_tests.list
diff --git a/generated_tests/gen_tcs_input_tests.py b/generated_tests/gen_tcs_input_tests.py
deleted file mode 100644
index 01e938c..0000000
--- a/generated_tests/gen_tcs_input_tests.py
+++ /dev/null
@@ -1,308 +0,0 @@
[truncated because gmail sucks]

diff --git a/generated_tests/gen_tes_input_tests.py b/generated_tests/gen_tess_input_tests.py
similarity index 53%
rename from generated_tests/gen_tes_input_tests.py
rename to generated_tests/gen_tess_input_tests.py
index d443f7f..bb23f8d 100644
--- a/generated_tests/gen_tes_input_tests.py
+++ b/generated_tests/gen_tess_input_tests.py
@@ -2,6 +2,7 @@
 # coding=utf-8
 #
 # Copyright © 2014 The Piglit Project
+# Copyright © 2015 Intel Corporation
 #
 # Permission is hereby granted, free of charge, to any person obtaining a
 # copy of this software and associated documentation files (the "Software"),
@@ -22,21 +23,9 @@
 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 # DEALINGS IN THE SOFTWARE.
 
-"""Test passing variables from the tessellation control shader to the
-tessellation evaluation shader.
+"""Generate tests for tessellation input stages.
 
-For every combination of varying type as scalar and as two element array and
-per-vertex or per-patch varying create a test that that passes said variable
-between the tessellation shader stages.
-
-Copy a uniform value to the varying in the tessellation control shader and
-compare the varying to the same uniform in the tessellation evaluation
-shader.
-If the values are equal draw the screen green, red otherwise.
-
-Draw for tessellated quads. Each should cover one quarter of the screen.
-
-This script outputs, to stdout, the name of each file it generates.
+Currently test for VS -> TCS and TCS -> TES are generated.
 
 """
 
@@ -49,7 +38,271 @@ import textwrap
 from six.moves import range
 
 
-class Test(object):
+class TcsTest(object):
+    """Test passing variables from the vertex shader to the tessellation
+    control shader.
+
+    For every varying type create one tests that passes a scalar of that type
+    and one test that passes a two element array. Copy an uniform value to the
+    varying in the vertex shader and compare the varying to the same uniform in
+    the tessellation control shader. If the values are equal draw the screen
+    green, red otherwise.
+
+    Draw four tessellated quads. Each should cover one quarter of the screen.
+
+    """
+    def __init__(self, type_name, array, name):
+        """Creates a test.
+
+        type_name -- varying type to test (e.g.: vec4, mat3x2, int, ...)
+        array -- number of array elements to test, None for no array
+        name -- name of the variable to test
+
+        """
+        self.var_name = name or 'var'
+
+        if self.var_name == 'gl_Position':
+            self.var_type = 'vec4'
+            self.var_array = None
+        elif self.var_name == 'gl_PointSize':
+            self.var_type = 'float'
+            self.var_array = None
+        elif self.var_name == 'gl_ClipDistance':
+            self.var_type = 'float'
+            self.var_array = 8
+        else:
+            self.var_type = type_name
+            self.var_array = array
+
+        if self.built_in:
+            self.interface_name = 'gl_PerVertex'
+            self.interface_vs_instance = ''
+            self.interface_tcs_instance = 'gl_in'
+        else:
+            self.interface_name = 'v2tc_interface'
+            self.interface_vs_instance = ''
+            self.interface_tcs_instance = 'v2tc'
+
+        if self.var_array:
+            self.var_type_full = self.var_type + '[{0}]'.format(self.var_array)
+        else:
+            self.var_type_full = self.var_type
+
+    @property
+    def built_in(self):
+        return self.var_name.startswith('gl_')
+
+    @property
+    def vs_var_ref(self):
+        return '.' + self.var_name if self.interface_vs_instance else self.var_name
+
+    @property
+    def tcs_var_ref(self):
+        return '.' + self.var_name if self.interface_tcs_instance else self.var_name
+
+    @property
+    def uniform_string(self):
+        """Returns string for loading uniform data by the shader_runner."""
+        data = self.test_data()
+        uniforms = ''
+        if self.var_array:
+            for i in range(12):
+                for j in range(self.var_array):
+                    uniforms += 'uniform {0} reference[{1}].v[{2}] {3}\n'.format(
+                        self.var_type, i, j, data[i*j])
+        else:
+            for i in range(12):
+                uniforms += 'uniform {0} reference[{1}].v {2}\n'.format(
+                    self.var_type,
+                    i,
+                    data[i])
+
+        #strip last newline
+        return uniforms[:-1]
+
+    def components(self):
+        """Returns the number of scalar components of the used data type."""
+        n = 1
+
+        if self.var_type.startswith('mat'):
+            if 'x' in self.var_type:
+                n *= int(self.var_type[-1])
+                n *= int(self.var_type[-3])
+            else:
+                n *= int(self.var_type[-1])
+                n *= int(self.var_type[-1])
+        elif 'vec' in self.var_type:
+            n *= int(self.var_type[-1])
+
+        return n
+
+    def test_data(self):
+        """Returns random but deterministic data as a list of strings.
+
+        n strings are returned containing c random values, each.
+        Where n is the number of vertices times the array length and
+        c is the number of components in the tested scalar data type.
+        """
+        random.seed(17)
+
+        if self.var_array:
+            n = self.var_array * 12
+        else:
+            n = 12
+
+        if self.var_type.startswith('i'):
+            rand = lambda: random.randint(-0x80000000, 0x7fffffff)
+        elif self.var_type.startswith('u'):
+            rand = lambda: random.randint(0, 0xffffffff)
+        else:
+            rand = lambda: ((-1 + 2 * random.randint(0, 1)) *
+                            random.randint(0, 2**23-1) *
+                            2.0**(random.randint(-126, 127)))
+
+        c = self.components()
+
+        ret = []
+        for _ in range(n):
+            ret.append(" ".join(str(rand()) for _ in range(c)))
+
+        return ret
+
+    def filename(self):
+        """Returns the file name (including path) for the test."""
+        if self.built_in:
+            name = self.var_name
+        elif self.var_array:
+            name = self.var_type + '_{0}'.format(self.var_array)
+        else:
+            name = self.var_type
+        return os.path.join('spec',
+                            'arb_tessellation_shader',
+                            'execution',
+                            'tcs-input',
+                            'tcs-input-{0}.shader_test'.format(name))
+
+    def generate(self):
+        """Generates and writes the test to disc."""
+        test = textwrap.dedent("""\
+            # Test generated by:
+            # {generator_command}
+            # Test tessellation control shader inputs
+            [require]
+            GLSL >= 1.50
+            GL_ARB_tessellation_shader
+
+            [vertex shader]
+            uniform struct S0 {{
+                    {self.var_type_full} v;
+            }} reference[12];
+
+            out {self.interface_name} {{
+                    {self.var_type_full} {self.var_name};
+            }} {self.interface_vs_instance};
+
+            void main()
+            {{
+                    {self.interface_vs_instance}{self.vs_var_ref} = reference[gl_VertexID].v;
+            }}
+
+            [tessellation control shader]
+            #extension GL_ARB_tessellation_shader : require
+            layout(vertices = 3) out;
+
+            uniform struct S0 {{
+                    {self.var_type_full} v;
+            }} reference[12];
+
+            in {self.interface_name} {{
+                    {self.var_type_full} {self.var_name};
+            }} {self.interface_tcs_instance}[];
+
+            out int pass[];
+
+            void main()
+            {{
+                    const int vertices_in = 3;
+                    int local_pass = 1;
+                    for (int i = 0; i < vertices_in; ++i) {{
+                            int vertex_ID = gl_PrimitiveID * vertices_in + i;
+                            if ({self.interface_tcs_instance}[i]{self.tcs_var_ref} != reference[vertex_ID].v)
+                                    local_pass = 0;
+                    }}
+                    pass[gl_InvocationID] = local_pass;
+                    gl_TessLevelOuter = float[4](1.0, 1.0, 1.0, 1.0);
+                    gl_TessLevelInner = float[2](1.0, 1.0);
+            }}
+
+            [tessellation evaluation shader]
+            #extension GL_ARB_tessellation_shader : require
+            layout(quads) in;
+
+            in int pass[];
+
+            out vec4 vert_color;
+
+            void main()
+            {{
+                    const vec4 red = vec4(1, 0, 0, 1);
+                    const vec4 green = vec4(0, 1, 0, 1);
+                    vec2[3] position = vec2[3](
+                            vec2(float(gl_PrimitiveID / 2) - 1.0, float(gl_PrimitiveID % 2) - 1.0),
+                            vec2(float(gl_PrimitiveID / 2) - 0.0, float(gl_PrimitiveID % 2) - 1.0),
+                            vec2(float(gl_PrimitiveID / 2) - 1.0, float(gl_PrimitiveID % 2) - 0.0)
+                    );
+                    gl_Position = vec4(position[0]
+                                + (position[1] - position[0]) * gl_TessCoord[0]
+                                + (position[2] - position[0]) * gl_TessCoord[1], 0.0, 1.0);
+                    vert_color = green;
+                    if (pass[0] == 0 || pass[1] == 0 || pass[2] == 0) {{
+                            vert_color = red;
+                    }}
+            }}
+
+            [fragment shader]
+
+            in vec4 vert_color;
+
+            out vec4 frag_color;
+
+            void main()
+            {{
+                    frag_color = vert_color;
+            }}
+
+            [test]
+            {self.uniform_string}
+            draw arrays GL_PATCHES 0 12
+            relative probe rgb (0.25, 0.25) (0.0, 1.0, 0.0)
+            relative probe rgb (0.75, 0.25) (0.0, 1.0, 0.0)
+            relative probe rgb (0.25, 0.75) (0.0, 1.0, 0.0)
+            relative probe rgb (0.75, 0.75) (0.0, 1.0, 0.0)
+            """)
+
+        test = test.format(self=self, generator_command=" ".join(sys.argv))
+
+        filename = self.filename()
+        dirname = os.path.dirname(filename)
+        if not os.path.exists(dirname):
+            os.makedirs(dirname)
+        with open(filename, 'w') as f:
+            f.write(test)
+
+
+class TesTest(object):
+    """Test passing variables from the tessellation control shader to the
+    tessellation evaluation shader.
+
+    For every combination of varying type as scalar and as two element array
+    and per-vertex or per-patch varying create a test that that passes said
+    variable between the tessellation shader stages.  Copy a uniform value to
+    the varying in the tessellation control shader and compare the varying to
+    the same uniform in the tessellation evaluation shader. If the values are
+    equal draw the screen green, red otherwise.
+
+    Draw four tessellated quads. Each should cover one quarter of the screen.
+
+    """
     def __init__(self, type_name, array, patch_in, name):
         """Creates a test.
 
@@ -323,9 +576,11 @@ def all_tests():
                       'uint', 'uvec2', 'uvec3', 'uvec4']:
         for array in [None, 2]:
             for patch_in in [True, False]:
-                yield Test(type_name, array, patch_in, name=None)
+                yield TesTest(type_name, array, patch_in, name=None)
+            yield TcsTest(type_name, array, name=None)
     for var in ['gl_Position', 'gl_PointSize', 'gl_ClipDistance']:
-        yield Test(type_name=None, array=None, patch_in=False, name=var)
+        yield TesTest(type_name=None, array=None, patch_in=False, name=var)
+        yield TcsTest(type_name=None, array=None, name=var)
 
 
 def main():
-- 
2.6.1



More information about the Piglit mailing list