[Piglit] [PATCH 0/1] Add comprehensive tests of builtin functions with uniform input.
Ian Romanick
idr at freedesktop.org
Sat Jul 23 01:45:38 PDT 2011
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
On 07/22/2011 02:00 PM, Paul Berry wrote:
> Executive summary:
> - Comprehensively tests built-in GLSL 1.10 and 1.20 functions.
> - Tests are auto-generated at piglit build time.
> - Auto-generation code is organized so that in the future, we can
> easily add more built-in functions to be tested, and more contexts
> in which to test them.
> - Adds two dependencies to piglit: Python 2.7 and numpy.
> - All tests pass on nVidia's proprietary Linux driver, one failure on
> Mesa with Intel i965.
Wow. This is pretty cool.
I'm sure I'll have more comments next week, but there was one thing
below that jumped out at me...
> The following patch adds 462 tests to piglit, which comprehensively
> test the behavior of GLSL built-in functions on vertex and fragment
> shaders. The test vectors are auto-generated in Python, by using the
> numpy library to simulate the behavior of the built-in functions on a
> variety of inputs, and then producing shader_runner tests to verify
> the expected behavior. The numpy library includes support for typical
> vector and matrix operations such as dot products and outer
> products--this allowed complex built-in functions such as refract() to
> be simulated using straightforward Python code, so that we can have
> high confidence in the correctness of the test vectors.
>
> Since built-in functions tend to be added in each new version of GLSL,
> I've incorporated the auto-generation of tests into the Piglit build
> process, so that we can easily add tests of more built-ins in the
> future. You can generate the tests using "make gen-tests" from the
> root of the piglit tree (after configuring using cmake).
>
> The auto-generation code depends on Python 2.7 (for the argparse
> library) and on the numpy library. Both of these are standard, mature
> packages (Python 2.7 was released a year ago, and numpy has been
> around since 1995). So I'm hoping it won't be a problem adding these
> as dependencies, especially since Piglit is used principally by
> developers testing cutting-edge drivers. We could, in principle,
> relax the Python 2.7 requirement to 2.6 by using optparse instead of
> argparse, but I'm hoping not to have to do so because optparse is
> deprecated as of Python 2.7. I've updated the README to reflect these
> dependencies, and added code to CMakeLists.txt to check for them at
> configure time.
>
> The set of built-ins currently tested covers all of GLSL 1.10 and GLSL
> 1.20, with the exception of ftransform(), texture lookup functions,
> local differencing functions (dFdx(), dFdy(), and fwidth()), and noise
> functions. Some of these functions were already fairly well-tested in
> Piglit; others were lightly tested if at all. Sometime in the next
> few months I plan to expand these tests to cover GLSL 1.30.
>
> Since GL implementations may contain different code paths to support
> each built-in function in different contexts, I've separated the test
> generation into two files: a back-end, builtin_function.py, which
> generates the test vectors themselves, and a front-end,
> gen_builtin_uniform_tests.py, which creates shader_runner tests to
> test the built-ins on uniform inputs to vertex and fragment shaders.
> The principal export of builtin_function.py is a single dictionary,
> test_suite, which contains a complete set of test vectors for all
> built-in functions. This should allow us to add front-ends for
> testing the built-in functions in different contexts, without having
> to revisit the trickier back-end code. In the next week or two I plan
> to add a second front-end to test the behavior of built-in functions
> on constant values, as part of some planned work on Mesa's
> constant-folding code.
>
> I've validated these tests using nVidia's proprietary Linux driver and
> using Mesa with an Intel i965 chipset. The nVidia driver passes all
> tests. Mesa passes all tests but one, which I'll be submitting a fix
> for shortly.
>
> I realize this is a lot of tricky Python code to dump into an
> otherwise straightforward project. Ordinarily I would just check in
> the generated tests for easier review. But in this case, I think that
> we are going to get enough advantage out of extending these tests in
> the future (both by adding more built-ins and by adding more
> front-ends to test them in different contexts) that it's worth
> autogenerating the tests at Piglit compile time.
>
> As an aid in review, the complete list of functions tested may be
> found by looking at lines beginning in "f(" in
> generated_tests/builtin_function.py. Here is an example:
>
> f('mod', 2, '1.10', lambda x, y: x-y*np.floor(x/y), [1], [np.linspace(-1.9, 1.9, 4), np.linspace(-2.0, 2.0, 4)])
>
> The meanings of f()'s arguments are explained in its definition; there
> are a few variants of f() for testing different types of built-ins.
> For this example, the arguments represent:
>
> - The name of the function
> - The number of arguments it takes
> - The version of GLSL in which it was introduced
> - The function's Python equivalent (this is typically either a
> built-in function in numpy or a straightforward transliteration of a
> formula in the GLSL spec).
> - If the function has an equivalent form in which some arguments are
> vectors and some arguments are scalars, a list of the indices of
> which arguments are scalars. So in the case of "mod", this means
> that in addition to mod(genType x, genType y), there is a form
> mod(genType x, float y).
> - A list of possible input values to test. np.linspace(x, y, n) is a
> numpy function that generates a list of n linearly spaced values
> from x to y. So in the case of mod, the test vectors will exercise
> the cartesian product of 4 possible x values from -1.9 to 1.9, and 4
> possible y values from -2.0 to 2.0.
>
> One of the areas in which I'm most interested in receiving review is
> in whether I have chosen an appropiate set of input values for testing
> each function.
>
> Here is an example of a test created by gen_builtin_uniform_tests.py.
> This example is vs-smoothstep-float-float-vec4.shader_test. Note that
> the filename contains the types of the arguments, so this test
> exercises the function smoothstep(float, float, vec4). I've tried to
> make the generated test as straightforward as possible, so that when
> failures occur it will be easy to understand what has failed.
>
> [require]
> GLSL >= 1.10
>
> [vertex shader]
> varying vec4 color;
> uniform float arg0;
> uniform float arg1;
> uniform vec4 arg2;
>
> void main()
> {
> gl_Position = gl_Vertex;
> vec4 result = smoothstep(arg0, arg1, arg2);
> result -= -0.5;
> result *= 0.5;
> color = vec4(result);
> }
>
> [fragment shader]
> varying vec4 color;
>
> void main()
> {
> gl_FragColor = color;
> }
>
> [test]
> uniform float arg0 -1.9
> uniform float arg1 -0.633333333333
> uniform vec4 arg2 -2.0 -0.666666666667 0.666666666667 2.0
> draw rect -1 -1 2 2
> probe rgba 0 0 0.25 0.748979443068 0.75 0.75
Checks like this are a big problem for shaders. With 8-bit color
outputs, checks that require any precision are doomed. As you noticed,
you can only validate answers on the range [0,1]. Moreover, you can
only verify that the calculated answer is within 1/255 of correct.
That's just not good enough for most things.
Most of the time you want to check that a calculation is correct within
a certain tolerance. In those cases, you should do exactly that in the
shader. Some of the non-constant indexing tests that I wrote do this.
In one of the cases, vs-varying-mat4-wr.shader_test, I want to check
that a matrix passed to fragment shader has a varying had correct
values. I checked that by doing a calculation with that matrix and
verifying the correctness of that result:
void main()
{
gl_FragColor = (abs(distance(dst_matrix * v, expect)) < 1e-6)
? vec4(0.0, 1.0, 0.0, 1.0) : vec4(1.0, 0.0, 0.0, 1.0);
}
Of course, this assumes that abs() and distance() work correctly. :)
> uniform float arg0 -1.9
> uniform float arg1 0.633333333333
> uniform vec4 arg2 -2.0 -0.666666666667 0.666666666667 2.0
> draw rect -1 -1 2 2
> probe rgba 1 0 0.25 0.490133856976 0.75 0.75
> uniform float arg0 -1.9
> uniform float arg1 1.9
> uniform vec4 arg2 -2.0 -0.666666666667 0.666666666667 2.0
> draw rect -1 -1 2 2
> probe rgba 2 0 0.25 0.373820824761 0.626179175239 0.75
> uniform float arg0 -0.633333333333
> uniform float arg1 0.633333333333
> uniform vec4 arg2 -2.0 -0.666666666667 0.666666666667 2.0
> draw rect -1 -1 2 2
> probe rgba 3 0 0.25 0.25 0.75 0.75
> uniform float arg0 -0.633333333333
> uniform float arg1 1.9
> uniform vec4 arg2 -2.0 -0.666666666667 0.666666666667 2.0
> draw rect -1 -1 2 2
> probe rgba 4 0 0.25 0.25 0.509866143024 0.75
> uniform float arg0 0.633333333333
> uniform float arg1 1.9
> uniform vec4 arg2 -2.0 -0.666666666667 0.666666666667 2.0
> draw rect -1 -1 2 2
> probe rgba 5 0 0.25 0.25 0.251020556932 0.75
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/
iEYEARECAAYFAk4qijIACgkQX1gOwKyEAw+fyQCghwXcwTjjaLmgcEkQrUdBjvxc
2RgAnRdRXidJmvDrsz7DUI0WaisFk8tP
=ojD2
-----END PGP SIGNATURE-----
More information about the Piglit
mailing list