[Piglit] [PATCH] Test accuracy of dFdx and dFdy functions.

Ian Romanick idr at freedesktop.org
Mon Sep 30 16:46:30 PDT 2013


On 09/28/2013 03:24 PM, Paul Berry wrote:
> On 27 September 2013 14:18, Ian Romanick <idr at freedesktop.org
> <mailto:idr at freedesktop.org>> wrote:
> 
>     On 09/20/2013 10:15 AM, Paul Berry wrote:
>     > Mesa/i965 currently (as of commit 1cc3b90) has an inaccurate
>     > implementation of dFdy() which produces the same results for every
>     > pixel in an aligned 2x2 block.  This piglit test exposes the
>     > inaccuracy.
> 
>     Two questions:
> 
>      - How did you come up with the error metric values?
> 
>      - Why are the different?
> 
> 
> Oops, I was experimenting with the tests while I was debugging and I
> forgot to restore the original error metrics.  I intended for both error
> metrics to be 1.0e-3.

That makes sense.

> There's a huge amount of leeway for choosing the error metric, though,
> since the i965 driver is currently so bad--it has an error of 1.0 for
> dFdy.  With my RFC patch "i965/fs: Improve accuracy of dFdy()." applied,
> the error is 0.0 for both dFdy and dFdx (the test does computations
> based on window coordinates, which are always exactly representable as
> floats on i965, so no numerical errors occur).  So I don't particularly
> care what error bound we use; I just pulled 1.0e-3 out of the air.
> 
> Note: based on a conversation we had on Thursday, it sounded like you
> were going to recommend to Chia-I that we go ahead and use his
> less-accurate dFdx formula as the default, but switch back to the
> accurate version if GL_FRAGMENT_SHADER_DERIVATIVE_HINT is set to
> GL_NICEST or a driconf variable is set.  (I haven't seen that email
> yet--did you forget or are you still weighing options?)  If we decide to
> go ahead with that plan, then I should probably modify these tests so
> that they set GL_FRAGMENT_SHADER_DERIVATIVE_HINT to GL_NICEST.

I just haven't sent it yet. :)

Setting GL_FRAGMENT_SHADER_DERIVATIVE_HINT to GL_NICEST in this test
isn't a terrible idea.  That may cause some other drivers to use the
high quality derivative mode (from DX) that calculates dFdx as
(value[x+1].x - value[x-1].x)/2 instead of value[x].x - value[x+1].x.

>     > ---
>     >  .../execution/fs-dfdx-accuracy.shader_test         | 35
>     ++++++++++++++++++++++
>     >  .../execution/fs-dfdy-accuracy.shader_test         | 35
>     ++++++++++++++++++++++
>     >  2 files changed, 70 insertions(+)
>     >  create mode 100644
>     tests/spec/glsl-1.10/execution/fs-dfdx-accuracy.shader_test
>     >  create mode 100644
>     tests/spec/glsl-1.10/execution/fs-dfdy-accuracy.shader_test
>     >
>     > diff --git
>     a/tests/spec/glsl-1.10/execution/fs-dfdx-accuracy.shader_test
>     b/tests/spec/glsl-1.10/execution/fs-dfdx-accuracy.shader_test
>     > new file mode 100644
>     > index 0000000..b8d471c
>     > --- /dev/null
>     > +++ b/tests/spec/glsl-1.10/execution/fs-dfdx-accuracy.shader_test
>     > @@ -0,0 +1,35 @@
>     > +# The spec allows considerable leeway in how dFdx() is calculated,
>     > +# however the expected implementation is via forward or backward
>     > +# differencing.  (Implementations are permitted, for instance, to use
>     > +# forward differencing for some pixels and backward differencing for
>     > +# other pixels).
>     > +#
>     > +# This test computes dFdx(x*y), which should exactly equal y at every
>     > +# pixel, regardless of whether forward or backward differencing is
>     > +# used.
>     > +
>     > +[require]
>     > +GLSL >= 1.10
>     > +
>     > +[vertex shader]
>     > +void main()
>     > +{
>     > +     gl_Position = gl_Vertex;
>     > +}
>     > +
>     > +[fragment shader]
>     > +void main()
>     > +{
>     > +     float x = gl_FragCoord.x;
>     > +     float y = gl_FragCoord.y;
>     > +     float xy = x * y;
>     > +     float dxydx = dFdx(xy);
>     > +     if (distance(dxydx, y) > 1.0e-3)
>     > +             gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
>     > +     else
>     > +             gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
>     > +}
>     > +
>     > +[test]
>     > +draw rect -1 -1 2 2
>     > +probe all rgba 0.0 1.0 0.0 1.0
>     > diff --git
>     a/tests/spec/glsl-1.10/execution/fs-dfdy-accuracy.shader_test
>     b/tests/spec/glsl-1.10/execution/fs-dfdy-accuracy.shader_test
>     > new file mode 100644
>     > index 0000000..5c02680
>     > --- /dev/null
>     > +++ b/tests/spec/glsl-1.10/execution/fs-dfdy-accuracy.shader_test
>     > @@ -0,0 +1,35 @@
>     > +# The spec allows considerable leeway in how dFdy() is calculated,
>     > +# however the expected implementation is via forward or backward
>     > +# differencing.  (Implementations are permitted, for instance, to use
>     > +# forward differencing for some pixels and backward differencing for
>     > +# other pixels).
>     > +#
>     > +# This test computes dFdy(x*y), which should exactly equal x at every
>     > +# pixel, regardless of whether forward or backward differencing is
>     > +# used.
>     > +
>     > +[require]
>     > +GLSL >= 1.10
>     > +
>     > +[vertex shader]
>     > +void main()
>     > +{
>     > +     gl_Position = gl_Vertex;
>     > +}
>     > +
>     > +[fragment shader]
>     > +void main()
>     > +{
>     > +     float x = gl_FragCoord.x;
>     > +     float y = gl_FragCoord.y;
>     > +     float xy = x * y;
>     > +     float dxydy = dFdy(xy);
>     > +     if (distance(dxydy, x) > 1.0e-1)
>     > +             gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
>     > +     else
>     > +             gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
>     > +}
>     > +
>     > +[test]
>     > +draw rect -1 -1 2 2
>     > +probe all rgba 0.0 1.0 0.0 1.0
>     >



More information about the Piglit mailing list