[Piglit] [PATCH] tex-miplevel-selection: Fix textureProj failures due to precision errors

Iago Toral itoral at igalia.com
Thu Mar 12 00:38:22 PDT 2015


On Wed, 2015-03-11 at 12:52 -0400, Ilia Mirkin wrote:
> On Wed, Mar 11, 2015 at 9:59 AM, Ilia Mirkin <imirkin at alum.mit.edu> wrote:
> > On Wed, Mar 11, 2015 at 3:56 AM, Iago Toral Quiroga <itoral at igalia.com> wrote:
> >> The textureProj tests multiply expected texture coordinates by the projector
> >> in advance so that when the driver does the division we obtain the same
> >> coordinates. However, the division can lead to small rounding errors that
> >> can affect the selected layer and fail the tests. This is currently happening
> >> on Intel hardware for all projector tests involving 3D textures.
> >>
> >> When we test a 3D texture for texture level 0 we have 32 layers, which
> >> means that each layer takes 1/32 = 0.03125 space in the [0, 1] texture
> >> coordinate space. The test uses 0.5 for the Z coordinate, which is exactly
> >> the boundary between layers 15 and 16 (16 * 0.03125 = 0.5). Because we
> >> first multiply 0.5 by the projector in CPU and then we divide the coordinate
> >> by the driver in the GPU, the result may be subject to rounding/precision
> >> errors and if the result of this operation is even slighly smaller than 0.5
> >> the hardware will select layer 15 instead of layer 16, leading to the
> >> test failures we currently see, at least on Intel hardware, for all piglit
> >> tests that involve textureProj with 3D textures.
> >>
> >> The patch prevents this rounding from affecting the result of the test by
> >> using 0.51 as the target texture coordinates instead of 0.5. Because 0.51
> >> is 0.01 into layer 16, we are giving a small room for rounding/precision
> >> errors that won't lead the hardware to select a different layer.
> >>
> >> This fixes all projector tests on Intel hardware:
> >> bin/tex-miplevel-selection *ProjGradARB 3D -fbo -auto
> >> bin/tex-miplevel-selection *ProjLod 3D -fbo -auto
> >> bin/tex-miplevel-selection textureProj 3D -fbo -auto
> >> bin/tex-miplevel-selection textureProjGrad 3D -fbo -auto
> >> bin/tex-miplevel-selection textureProjGradOffset 3D -fbo -auto
> >> bin/tex-miplevel-selection textureProjOffset 3D -fbo -auto
> >> bin/tex-miplevel-selection "textureProj(bias)" 3D -fbo -auto
> >> bin/tex-miplevel-selection "textureProjOffset(bias)" 3D -fbo -auto
> >
> > Neat! This also fixes the (apparently lower-precision) "p" modifier on
> > the sample instruction on a3xx -- previously we just assumed it
> > couldn't be used with 3D textures, and worked around it by doing the
> > projection by hand (in 32-bit fp land). I guess sam.p does it in fp16
> > land?
> 
> Although the question is... is this loss of precision OK? Probably is
> for lowp in gles, but what about highp or desktop gl?
> 
> Iago, what happens if you do the projection "by hand" in a lowering
> pass, do those tests start passing then?

Actually, this is what is already happening, the Intel driver (and
possibly others) are lowering the projector and making the division by
hand (see do_lower_texture_projection).

> Does the spec have anything
> clever to say on the matter?

There is no specific mention about precision in textureProj, but chapter
Range And Precision of the Desktop GLSL lang spec says:

"a/b or 1/b are required to have a precision of 2.5 ULP for b in the
range [2^-126, 2^126]"

That said, I think this is not a precision problem, but a direct result
of the fact that we are doing 1 / p with p = 7 which gives a result with
an infinite number of decimal places, so we are always going to lose
some precision, and even if that loss is < 2.5 ULP that will inevitably
lead to a result that will always be < 0.5, which then will inevitably
lead to selecting the wrong layer.

This is what is happening with bc:

scale=100
> 1/7
0.142857142857142857...
> (0.5 * 7) * (1 / 7) 
.4999999999999999999999999999999999999999999999999999999999999999999\
999999999999999999999999999999998

No matter how good our precision is, there is always going to be some
loss, and any loss we have will lead to a result < 0.5 and selecting the
wring layer.

If we avoid  doing 1/p first, then we should be fine:

(0.5 * 7) / 7
.5000000000000000000000000000000000000000000000000000000000000000000\
000000000000000000000000000000000

So I think what is happening here is within expectations. We could
probably avoid the problem by not doing 1 / p separately, but the truth
is that there is nothing wrong with doing 1 / p really, it is just that
the way that the test is setup won't allow for even the slightest
precision error.

Iago



More information about the Piglit mailing list