[Piglit] [PATCH 1/2] arb_shader_bit_encoding: Add test generator.

Matt Turner mattst88 at gmail.com
Mon Aug 12 12:31:31 PDT 2013


Generates fragment and vertex shader execution tests for the built-in
functions floatBitsToInt(), floatBitsToUint(), intBitsToFloat(), and
uintBitsToFloat().

Functions are tested under
	GLSL 1.30 + ARB_shader_bit_encoding (uses uint, must be 1.30)
	GLSL 1.50 + ARB_gpu_shader5 (requires 1.50)
	GLSL 4.00

Reviewed-by: Ian Romanick <ian.d.romanick at intel.com> [v1]

v2: Do not test subnormal values, since some hardware flushes them to
    zero. Fix value of smallest normalized value.
---
 generated_tests/CMakeLists.txt                   |   4 +
 generated_tests/gen_shader_bit_encoding_tests.py | 227 +++++++++++++++++++++++
 2 files changed, 231 insertions(+)
 create mode 100644 generated_tests/gen_shader_bit_encoding_tests.py

diff --git a/generated_tests/CMakeLists.txt b/generated_tests/CMakeLists.txt
index db3734f..8c0bc02 100644
--- a/generated_tests/CMakeLists.txt
+++ b/generated_tests/CMakeLists.txt
@@ -40,6 +40,9 @@ piglit_make_generated_tests(
 	texture_query_lod_tests.list
 	gen_texture_query_lod_tests.py)
 piglit_make_generated_tests(
+	shader_bit_encoding_tests.list
+	gen_shader_bit_encoding_tests.py)
+piglit_make_generated_tests(
 	uniform-initializer_tests.list
 	gen_uniform_initializer_tests.py
 	uniform-initializer-templates/fs-initializer.template
@@ -65,4 +68,5 @@ add_custom_target(gen-tests ALL
 		interpolation_tests.list
 		non-lvalue_tests.list
 		texture_query_lod_tests.list
+		shader_bit_encoding_tests.list
 		uniform-initializer_tests.list)
diff --git a/generated_tests/gen_shader_bit_encoding_tests.py b/generated_tests/gen_shader_bit_encoding_tests.py
new file mode 100644
index 0000000..2378161
--- /dev/null
+++ b/generated_tests/gen_shader_bit_encoding_tests.py
@@ -0,0 +1,227 @@
+#!/usr/bin/env python2
+# coding=utf-8
+#
+# Copyright © 2013 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 struct
+import os
+import os.path
+from mako.template import Template
+from textwrap import dedent
+
+def floatBitsToInt(f):
+    return struct.unpack('i', struct.pack('f', f))[0]
+
+def floatBitsToUint(f):
+    return struct.unpack('I', struct.pack('f', f))[0]
+
+def intBitsToFloat(i):
+    return struct.unpack('f', struct.pack('i', i))[0]
+
+def uintBitsToFloat(u):
+    return struct.unpack('f', struct.pack('I', u))[0]
+
+def passthrough(f):
+    return f
+
+def vec4(f):
+    return [f, f, f, f]
+
+test_data = {
+    # Interesting floating-point inputs
+    'mixed':                        (2.0, 9.5, -4.5, -25.0),
+    '0.0':                          vec4( 0.0), # int 0
+    '-0.0':                         vec4(-0.0), # INT_MIN
+    '1.0':                          vec4( 1.0),
+    '-1.0':                         vec4(-1.0),
+    'normalized smallest':          vec4( 1.1754944e-38),
+    'normalized smallest negative': vec4(-1.1754944e-38),
+    'normalized largest':           vec4( 3.4028235e+38),
+    'normalized largest negative':  vec4(-3.4028235e+38)
+
+    # Don't test +inf or -inf, since we don't have a way to pass them via
+    # shader_runner [test] sections. Don't test NaN, since it has many
+    # representations. Don't test subnormal values, since hardware might
+    # flush them to zero.
+}
+
+# in_func: Function to convert floating-point data in test_data (above) into
+#          input (given) data to pass the shader.
+# out_func: Function to convert floating-point data in test_data (above) into
+#           output (expected) data to pass the shader.
+
+funcs = {
+    'floatBitsToInt': {
+        'in_func':  passthrough,
+        'out_func': floatBitsToInt,
+        'input':    'vec4',
+        'output':   'ivec4'
+    },
+    'floatBitsToUint': {
+        'in_func':  passthrough,
+        'out_func': floatBitsToUint,
+        'input':    'vec4',
+        'output':   'uvec4'
+    },
+    'intBitsToFloat': {
+        'in_func':  floatBitsToInt,
+        'out_func': intBitsToFloat,
+        'input':    'ivec4',
+        'output':   'vec4'
+    },
+    'uintBitsToFloat': {
+        'in_func':  floatBitsToUint,
+        'out_func': uintBitsToFloat,
+        'input':    'uvec4',
+        'output':   'vec4'
+    }
+}
+
+requirements = {
+    'ARB_shader_bit_encoding': {
+        'version': '1.30',
+        'extension': 'GL_ARB_shader_bit_encoding'
+    },
+    'ARB_gpu_shader5': {
+        'version': '1.50',
+        'extension': 'GL_ARB_gpu_shader5'
+    },
+    'glsl-4.00': {
+        'version': '4.00',
+        'extension': ''
+    }
+}
+
+template = Template(dedent("""\
+    [require]
+    GLSL >= ${version}
+    % for extension in extensions:
+    ${extension}
+    % endfor
+
+    [vertex shader]
+    % if execution_stage == 'vs':
+    % for extension in extensions:
+    #extension ${extension}: enable
+    % endfor
+
+    uniform ${input_type} given;
+    uniform ${output_type} expected;
+    out vec4 color;
+    % endif
+
+    in vec4 vertex;
+
+    void main() {
+        gl_Position = vertex;
+
+        % if execution_stage == 'vs':
+        color = vec4(0.0, 1.0, 0.0, 1.0);
+
+        if (expected.x != ${func}(given.x))
+                color.r = 1.0;
+        if (expected.xy != ${func}(given.xy))
+                color.r = 1.0;
+        if (expected.xyz != ${func}(given.xyz))
+                color.r = 1.0;
+        if (expected != ${func}(given))
+                color.r = 1.0;
+        % endif
+    }
+
+    [fragment shader]
+    % if execution_stage == 'fs':
+    % for extension in extensions:
+    #extension ${extension}: enable
+    % endfor
+
+    uniform ${input_type} given;
+    uniform ${output_type} expected;
+    % else:
+    in vec4 color;
+    % endif
+
+    out vec4 frag_color;
+
+    void main() {
+        % if execution_stage == 'fs':
+        frag_color = vec4(0.0, 1.0, 0.0, 1.0);
+
+        if (expected.x != ${func}(given.x))
+                frag_color.r = 1.0;
+        if (expected.xy != ${func}(given.xy))
+                frag_color.r = 1.0;
+        if (expected.xyz != ${func}(given.xyz))
+                frag_color.r = 1.0;
+        if (expected != ${func}(given))
+                frag_color.r = 1.0;
+        % else:
+        frag_color = color;
+        % endif
+    }
+
+    [test]
+    % for name, data in sorted(test_data.iteritems()):
+
+    # ${name}
+    uniform ${input_type} given ${' '.join(str(in_func(d)) for d in data)}
+    uniform ${output_type} expected ${' '.join(str(out_func(d)) for d in data)}
+    draw rect -1 -1 2 2
+    probe all rgba 0.0 1.0 0.0 1.0
+    % endfor
+"""))
+
+for api, requirement in requirements.iteritems():
+    version = requirement['version']
+    extensions = [requirement['extension']] if requirement['extension'] else []
+
+    for func, attrib in funcs.iteritems():
+        in_func = attrib['in_func']
+        out_func = attrib['out_func']
+        input_type = attrib['input']
+        output_type = attrib['output']
+
+        for execution_stage in ('vs', 'fs'):
+            file_extension = 'frag' if execution_stage == 'fs' else 'vert'
+            filename = os.path.join('spec',
+                                    api,
+                                    'execution',
+                                    'built-in-functions',
+                                    "{0}-{1}.shader_test".format(execution_stage,
+                                                                 func))
+            print filename
+
+            dirname = os.path.dirname(filename)
+            if not os.path.exists(dirname):
+                os.makedirs(dirname)
+
+            f = open(filename, 'w')
+            f.write(template.render(version=version,
+                                    extensions=extensions,
+                                    execution_stage=execution_stage,
+                                    func=func,
+                                    in_func=in_func,
+                                    out_func=out_func,
+                                    input_type=input_type,
+                                    output_type=output_type,
+                                    test_data=test_data))
+            f.close()
-- 
1.8.3.2



More information about the Piglit mailing list