Bug 71199 - [llvmpipe] piglit gl-1.4-polygon-offset regression
Summary: [llvmpipe] piglit gl-1.4-polygon-offset regression
Status: RESOLVED MOVED
Alias: None
Product: Mesa
Classification: Unclassified
Component: Drivers/Gallium/llvmpipe (show other bugs)
Version: git
Hardware: x86-64 (AMD64) Linux (All)
: medium normal
Assignee: mesa-dev
QA Contact:
URL:
Whiteboard:
Keywords: bisected, regression
Depends on:
Blocks: 79039
  Show dependency treegraph
 
Reported: 2013-11-03 21:31 UTC by Vinson Lee
Modified: 2019-09-18 18:31 UTC (History)
4 users (show)

See Also:
i915 platform:
i915 features:


Attachments

Description Vinson Lee 2013-11-03 21:31:47 UTC
mesa: fa8b1514d31d1ffb3d9e2a208ac7d1bd774754b2 (master)

$ ./bin/glean -t polygonOffset --quick
polygonOffset:  FAIL rgba8, db, z24, s8, accrgba16, win+pmap, id 33
	Actual MRD is too small (may cause incorrect results)

	Ideal  MRD at near plane is 1.19209e-07 (nominally 2 bits)
	Actual MRD at near plane is 5.96046e-08 (nominally 1 bit)
	Ideal  MRD at infinity is 3.06118e-08 (nominally 1 bit)
	Actual MRD at infinity is 5.96046e-08 (nominally 1 bit)


be0b67a1436eb2b899f9874725b2a68eb26f9f3f is the first bad commit
commit be0b67a1436eb2b899f9874725b2a68eb26f9f3f
Author: Matthew McClure <mcclurem@vmware.com>
Date:   Tue Oct 22 15:48:00 2013 -0700

    util,llvmpipe: correctly set the minimum representable depth value
    
    Reviewed-by: Roland Scheidegger <sroland@vmware.com>
    Reviewed-by: Jose Fonseca <jfonseca@vmware.com>

:040000 040000 705fdddb5369a190f9fa393549692d5d05dd5d5b 0e7c6c6eb72429cbdceb2b3b85673b48c25ed5eb M	src
bisect run success
Comment 1 Roland Scheidegger 2013-11-03 22:38:15 UTC
My guess would be the test is invalid.
The "mrd" meaning is very precise both in d3d10 and OpenGl, and we were being sloppy there before - it really should be exactly one bit (for unorm depth formats).
I quickly looked at the test and I don't quite understand what it does to find the ideal mrd. I suspect the math doesn't work out somewhere because the float math is right at the limits of depth buffer precision (24 bit in this case).
Do closed source drivers actually pass this (and if so I wonder what their calculated ideal/actual mrd values are)?
Comment 2 Vinson Lee 2014-03-02 02:46:14 UTC
mesa: fc25956badb8e1932cc19d8c97b4be16e92dfc65 (master)

This llvmpipe regression is still present with latest mesa master 10.2.0-devel.
Comment 3 Vinson Lee 2014-09-15 16:50:56 UTC
mesa: 418da979053d4fec5b4913e0407c5c48eab601e5 (master 10.4.0-devel)

glean polygonOffset regression is still present.
Comment 4 Jose Fonseca 2014-11-24 20:16:48 UTC
This test was renamed, but the issue is still there:

$ ./bin/gl-1.4-polygon-offset -auto
	Actual MRD is too small (may cause incorrect results)
	Ideal  MRD at near plane is 1.192095e-07 (nominally 2 bits)
	Actual MRD at near plane is 5.960464e-08 (nominally 1 bit)
	Ideal  MRD at infinity is 3.061179e-08 (nominally 1 bit)
	Actual MRD at infinity is 5.960464e-08 (nominally 1 bit)

PIGLIT: {"result": "fail" }

(In reply to Roland Scheidegger from comment #1)
> My guess would be the test is invalid.
> The "mrd" meaning is very precise both in d3d10 and OpenGl, and we were
> being sloppy there before - it really should be exactly one bit (for unorm
> depth formats).
> I quickly looked at the test and I don't quite understand what it does to
> find the ideal mrd. I suspect the math doesn't work out somewhere because
> the float math is right at the limits of depth buffer precision (24 bit in
> this case).

Yes, I also don't understand why the requirement of 2 bits. 

> Do closed source drivers actually pass this (and if so I wonder what their
> calculated ideal/actual mrd values are)?

Yes, they do somehow:

$ glxinfo | grep '^OpenGL \(vendor\|renderer\) string:'
OpenGL vendor string: NVIDIA Corporation
OpenGL renderer string: Quadro K1000M/PCIe/SSE2
$ ./bin/gl-1.4-polygon-offset -auto
	Ideal  MRD at near plane is 1.192089e-07 (nominally 2 bits)
	Actual MRD at near plane is 1.192093e-07 (nominally 2 bits)
	Ideal  MRD at infinity is 1.499423e-08 (nominally 0 bits)
	Actual MRD at infinity is 1.192093e-07 (nominally 2 bits)

PIGLIT: {"result": "pass" }
Comment 5 Roland Scheidegger 2014-11-24 21:42:56 UTC
(In reply to José Fonseca from comment #4)
> This test was renamed, but the issue is still there:
> 
> $ ./bin/gl-1.4-polygon-offset -auto
> 	Actual MRD is too small (may cause incorrect results)
> 	Ideal  MRD at near plane is 1.192095e-07 (nominally 2 bits)
> 	Actual MRD at near plane is 5.960464e-08 (nominally 1 bit)
> 	Ideal  MRD at infinity is 3.061179e-08 (nominally 1 bit)
> 	Actual MRD at infinity is 5.960464e-08 (nominally 1 bit)
> 

> Yes, they do somehow:
> 
> $ glxinfo | grep '^OpenGL \(vendor\|renderer\) string:'
> OpenGL vendor string: NVIDIA Corporation
> OpenGL renderer string: Quadro K1000M/PCIe/SSE2
> $ ./bin/gl-1.4-polygon-offset -auto
> 	Ideal  MRD at near plane is 1.192089e-07 (nominally 2 bits)
> 	Actual MRD at near plane is 1.192093e-07 (nominally 2 bits)
> 	Ideal  MRD at infinity is 1.499423e-08 (nominally 0 bits)
> 	Actual MRD at infinity is 1.192093e-07 (nominally 2 bits)
> 
> PIGLIT: {"result": "pass" }

Interestingly even the ideal MRD is different, suggesting differences in basic vertex transform math, or different rounding when converting to unorm z?
This test is too weird for me...
Comment 6 Laura Ekstrand 2014-11-24 23:47:11 UTC
I recently ported this test from Glean to Piglit, and I took another look at it just now.  From my understanding, I think the logic of the test is correct, but perhaps you are correct that the implementation is touchy because of numerical precision issues.

I found that the terms "ideal" and "actual" may be confusing for the purposes of this discussion.  "Actual" is the implementation-specific definition of one unit used in the driver's PolygonOffset.  This is discussed in the OpenGL 4.5 core spec (Oct. 30, 2014) in section 14.6.5.  It's supposed to be derived from the depth buffer precision, but I suppose after looking at the spec that it's not always guaranteed to be.

"Ideal" is found by experimentation and depends on the whole OpenGL experience; driver, hardware, depth buffer, etc.  The original authors of this test are doing a complicated set of binary searches to converge on a numerical solution.  There may be some numerical instability here.

The output of the test shown above indicates that the llvmpipe driver is providing a near plane actual mrd that is about half of what its OpenGL context can actually provide ("ideal" mrd).  In other words, one unit of offset in a call to glPolygonOffset will not provide enough separation to say, draw a decal on top of a plane wing without some stitching (plane wing showing through).  A user would have to use a value of two.

I may be missing something here.
Comment 7 Roland Scheidegger 2014-11-25 02:20:05 UTC
(In reply to Laura Ekstrand from comment #6)
> I recently ported this test from Glean to Piglit, and I took another look at
> it just now.  From my understanding, I think the logic of the test is
> correct, but perhaps you are correct that the implementation is touchy
> because of numerical precision issues.
> 
> I found that the terms "ideal" and "actual" may be confusing for the
> purposes of this discussion.  "Actual" is the implementation-specific
> definition of one unit used in the driver's PolygonOffset.  This is
> discussed in the OpenGL 4.5 core spec (Oct. 30, 2014) in section 14.6.5. 
> It's supposed to be derived from the depth buffer precision, but I suppose
> after looking at the spec that it's not always guaranteed to be.
> 
> "Ideal" is found by experimentation and depends on the whole OpenGL
> experience; driver, hardware, depth buffer, etc.  The original authors of
> this test are doing a complicated set of binary searches to converge on a
> numerical solution.  There may be some numerical instability here.
> 
> The output of the test shown above indicates that the llvmpipe driver is
> providing a near plane actual mrd that is about half of what its OpenGL
> context can actually provide ("ideal" mrd).  In other words, one unit of
> offset in a call to glPolygonOffset will not provide enough separation to
> say, draw a decal on top of a plane wing without some stitching (plane wing
> showing through).  A user would have to use a value of two.
> 
> I may be missing something here.

I think for some reason the "Ideal MRD" values aren't quite what we'd expect them to be. The Actual MRD value (both for near and far) in llvmpipe is 2^-24 - which you'd think is just right for a 24 bit z buffer (and indeed the test shows this as nominally 1 bit). Nvidia apparently gives 2^-23, so "losing" one bit.
But the more important question is why values with such a difference would not resolve to different z values. Apparently, the test figured out a difference of 2^-23 is required at the near plane and I just can't see why that would be (it is the same for nvidia too). It just seems like somehow the math isn't accurate enough. Or maybe this is due to OpenGL's clip space (which is different to d3d10) so some small inaccuracies creep in. In any case since nvidia apparently uses 2 bits as mrd this doesn't look like it's fixable. I guess this would only really be a problem with 24bit z buffers, but in any case we can't change llvmpipe to use different mrd values (d3d10 won't like it), though if this is only a problem with GL clip space we could perhaps adjust it depending on that (which is also controllable in GL with ARB_clip_control).
Comment 8 Jose Fonseca 2014-11-25 08:34:23 UTC
Yes, I suspect that ideal MRD at near plane may never go below 2, because of the the "near_1_far_infinity" perspective transformation applied.

We could experiment whether an orthogonal transformation would allow to tease out
an ideal MRD of 1.


Another solution would be to compute the minimum MRD, not from this complex procedure, but from the glGetIntegerv(GL_DEPTH_BITS).
Comment 9 Vinson Lee 2015-06-14 03:41:04 UTC
mesa: 4d35eef326e49cc8da50879d30a1c5088d4775e1 (master 10.7.0-devel)

This regression is still present on llvmpipe.
Comment 10 Jose Fonseca 2015-06-16 14:09:48 UTC
On me Mesa DRI Intel(R) Haswell Mobile I actually get the reverse problem:

$ ./bin/gl-1.4-polygon-offset -auto
	Actual MRD is too large (may waste depth-buffer range)

	Ideal  MRD at near plane is 5.960283e-08 (nominally 1 bit)
	Actual MRD at near plane is 1.192093e-07 (nominally 2 bits)
	Ideal  MRD at infinity is 4.353401e-08 (nominally 1 bit)
	Actual MRD at infinity is 1.192093e-07 (nominally 2 bits)

PIGLIT: {"result": "fail" }

So the test itself doesn't seem to be limited to 1 bit as I considered.

Still no idea on how to fix it.  I'm reluctant just to bump MRD on llvmpipe, as I'm afraid it will cause problems with different state trackers.

It's not a huge deal neither.

In short, I'm afraid there's little chance for a fix any time soon..
Comment 11 GitLab Migration User 2019-09-18 18:31:30 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to freedesktop.org's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.freedesktop.org/mesa/mesa/issues/230.


Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.