[Piglit] [PATCH] glsl-1.10: Verify pre- and post-inc/dec cannot be l-values

Ian Romanick idr at freedesktop.org
Mon Jan 9 12:21:37 PST 2012


From: Ian Romanick <ian.d.romanick at intel.com>

These generators create two kinds of tests.  The first verifies that
pre- and post-increment/decrement operations cannot be assignment
targets.  These look like:

uniform float u;
varying vec4 v;

void main()
{
    float t = u;

    ++t = float(v.x);
    gl_FragColor = vec4(t, v.yzw);
}

The second kind of test verifies that pre- and
post-increment/decrement operations cannot be used for function 'out'
parameters.  These look like:

uniform ivec4 u;
attribute vec4 v;

void f(out ivec4 p)
{
    p = ivec4(v);
}

void main()
{
    ivec4 t = u;

    f(t--);
    gl_Position = vec4(t);
}

Function 'inout' parameters are not explicitly tested.

A test is generated for both vertex and fragment targets for each
int and float vector or scalar datatype.  Matrix types and GLSL 1.30
unsigned types are not tested.

Signed-off-by: Ian Romanick <ian.d.romanick at intel.com>
---
 generated_tests/CMakeLists.txt          |    6 +-
 generated_tests/gen_non-lvalue_tests.py |  162 +++++++++++++++++++++++++++++++
 2 files changed, 167 insertions(+), 1 deletions(-)
 create mode 100644 generated_tests/gen_non-lvalue_tests.py

diff --git a/generated_tests/CMakeLists.txt b/generated_tests/CMakeLists.txt
index ea6072b..1b52775 100644
--- a/generated_tests/CMakeLists.txt
+++ b/generated_tests/CMakeLists.txt
@@ -30,10 +30,14 @@ piglit_make_generated_tests(
 piglit_make_generated_tests(
 	interpolation_tests.list
 	gen_interpolation_tests.py)
+piglit_make_generated_tests(
+	non-lvalue_tests.list
+	gen_non-lvalue_tests.py)
 
 # Add a "gen-tests" target that can be used to generate all the
 # tests without doing any other compilation.
 add_custom_target(gen-tests ALL
 	DEPENDS builtin_uniform_tests.list
 		constant_array_size_tests.list
-		interpolation_tests.list)
+		interpolation_tests.list
+		non-lvalue_tests.list)
diff --git a/generated_tests/gen_non-lvalue_tests.py b/generated_tests/gen_non-lvalue_tests.py
new file mode 100644
index 0000000..9d7687d
--- /dev/null
+++ b/generated_tests/gen_non-lvalue_tests.py
@@ -0,0 +1,162 @@
+# coding=utf-8
+#
+# Copyright © 2012 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.
+
+import os
+
+
+class Test(object):
+    def __init__(self, type_name, op, usage, shader_target):
+        self.type_name = type_name
+        self.op = op
+        self.usage = usage
+        self.shader_target = shader_target
+
+    def filename(self):
+        if self.op == "++t":
+            name_base = "preincrement"
+        elif self.op == "--t":
+            name_base = "predecrement"
+        elif self.op == "t++":
+            name_base = "postincrement"
+        elif self.op == "t--":
+            name_base = "postdecrement"
+
+        return os.path.join('spec',
+                            'glsl-1.10',
+                            'compiler',
+                            'expressions',
+                            '{0}-{1}-non-lvalue-for-{2}.{3}'.format(
+                                name_base, self.type_name, self.usage,
+                                self.shader_target))
+
+    def generate(self):
+        if self.usage == 'assignment':
+            test = """/* [config]
+ * expect_result: fail
+ * glsl_version: 1.10
+ * [end config]
+ *
+ * Page 32 (page 38 of the PDF) of the GLSL 1.10 spec says:
+ *
+ *     "Variables that are built-in types, entire structures, structure
+ *     fields, l-values with the field selector ( . ) applied to select
+ *     components or swizzles without repeated fields, and l-values
+ *     dereferenced with the array subscript operator ( [ ] ) are all
+ *     l-values. Other binary or unary expressions, non-dereferenced arrays,
+ *     function names, swizzles with repeated fields, and constants cannot be
+ *     l-values.  The ternary operator (?:) is also not allowed as an
+ *     l-value."
+ */
+uniform {0} u;
+{5} vec4 v;
+
+void main()
+{{
+    {0} t = u;
+
+    {1} = {0}(v{2});
+    {3} = {4};
+}}
+"""
+        else:
+            test = """/* [config]
+ * expect_result: fail
+ * glsl_version: 1.10
+ * [end config]
+ *
+ * Page 32 (page 38 of the PDF) of the GLSL 1.10 spec says:
+ *
+ *     "Variables that are built-in types, entire structures, structure
+ *     fields, l-values with the field selector ( . ) applied to select
+ *     components or swizzles without repeated fields, and l-values
+ *     dereferenced with the array subscript operator ( [ ] ) are all
+ *     l-values. Other binary or unary expressions, non-dereferenced arrays,
+ *     function names, swizzles with repeated fields, and constants cannot be
+ *     l-values.  The ternary operator (?:) is also not allowed as an
+ *     l-value."
+ */
+uniform {0} u;
+{5} vec4 v;
+
+void f(out {0} p)
+{{
+    p = {0}(v{2});
+}}
+
+void main()
+{{
+    {0} t = u;
+
+    f({1});
+    {3} = {4};
+}}
+"""
+        if '2' in self.type_name:
+            var_as_vec4 = 'vec4(t.xyxy)'
+            components = '.xy'
+        elif '3' in self.type_name:
+            var_as_vec4 = 'vec4(t.xyzx)'
+            components = '.xyz'
+        elif '4' in self.type_name:
+            var_as_vec4 = 'vec4(t)'
+            components = ''
+        else:
+            var_as_vec4 = 'vec4(t)'
+            components = '.x'
+
+        if self.shader_target == 'vert':
+            dest = "gl_Position"
+            mode = 'attribute'
+        else:
+            mode = 'varying'
+            dest = "gl_FragColor"
+
+        test = test.format(self.type_name, self.op, components,
+                           dest,
+                           var_as_vec4,
+                           mode)
+
+        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)
+
+
+def all_tests():
+    for type_name in ['float', 'vec2',  'vec3',  'vec4',
+                 'int',   'ivec2', 'ivec3', 'ivec4']:
+        for op in ["++t", "--t", "t++", "t--"]:
+            for usage in ['assignment', 'out-parameter']:
+                          for shader_target in ['vert', 'frag']:
+                              yield Test(type_name, op, usage, shader_target)
+
+def main():
+    for test in all_tests():
+	test.generate()
+	print test.filename()
+
+
+if __name__ == '__main__':
+    main()
-- 
1.7.6.4



More information about the Piglit mailing list