[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