diff options
author | Matt Turner <mattst88@gmail.com> | 2013-08-06 18:11:18 -0700 |
---|---|---|
committer | Matt Turner <mattst88@gmail.com> | 2013-08-16 13:20:54 -0700 |
commit | f7eabdf8cda7cb4bf5e8fa5fd25c16f52afa14bc (patch) | |
tree | f425101d0ae08e61d2d803c0049244789f5f982b /generated_tests | |
parent | 41490df54906b2920c75cd345b64a7d46cb69b1d (diff) |
arb_shader_bit_encoding: Add test generator.
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@intel.com> [v1]
v2: Do not test subnormal values, since some hardware flushes them to
zero. Fix value of smallest normalized value.
Diffstat (limited to 'generated_tests')
-rw-r--r-- | generated_tests/CMakeLists.txt | 4 | ||||
-rw-r--r-- | generated_tests/gen_shader_bit_encoding_tests.py | 234 |
2 files changed, 238 insertions, 0 deletions
diff --git a/generated_tests/CMakeLists.txt b/generated_tests/CMakeLists.txt index 6ac5a9c27..a0ba4b1bb 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 @@ -69,4 +72,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 000000000..a666a5cdb --- /dev/null +++ b/generated_tests/gen_shader_bit_encoding_tests.py @@ -0,0 +1,234 @@ +#!/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 + } + + [vertex data] + vertex/float/2 + -1.0 -1.0 + 1.0 -1.0 + 1.0 1.0 + -1.0 1.0 + + [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 arrays GL_TRIANGLE_FAN 0 4 + 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() |