On Thu, 12 Aug 2021 at 18:56, Stefan Dösinger stefan@codeweavers.com wrote:
Am Dienstag, 10. August 2021, 17:18:31 EAT schrieb Henri Verbeet:
- We translate by ε to the left, so that a triangle covering the
right half of a pixel from top to bottom exactly through the pixel centre ends up generating a fragment for that pixel, and a triangle covering the left half of that pixel doesn't.
Because we don't know what OpenGL is doing, i.e. it might generate a fragment if the pixel center is on a right edge of a triangle, either due to underspecification or driver bugs?
I was under the impression that GL guarantees a top-left filling rule (pixel is on a top edge OR on a left edge of a triangle -> generate fragment), but on further research the only place that states that (that I could find) is https://docs.microsoft.com/th-th/windows/win32/direct3d9/rasterization-rules , which isn't exactly an authoritative source on GL.
Perhaps Windows imposes additional restrictions on GL, but as far as I'm aware the only thing the GL spec requires in this regard is the following:
Special treatment is given to a fragment whose center lies on a polygon edge. In such a case we require that if two polygons lie on either side of a common edge (with identical endpoints) on which a fragment center lies, then exactly one of the polygons results in the production of the fragment during rasterization.
(From 14.6.1 "Basic Polygon Rasterization" in the 4.6 spec.)
Sadly, while it does match up with with the d3d9 test, it doesn't match up with SPORE nor World of Tanks. World of Tanks wants no nudge everywhere, even the radeon card. SPORE is broken on MacOS regardless of what I try to do, but works on Linux-Radeon either with or without the nudge. I can deliberately break it everywhere by removing the half pixel offset, but that doesn't tell us anything we didn't already know.
So something else must be going on. My suspicions are that it has something to do with shaders vs fixed function or core vs legacy context. It is also possible that the issue is entirely unrelated, at least in World of Tanks.
Are we using shader offsets or ARB_clip_control/viewport offsets in the broken case? I wouldn't be entirely surprised if some drivers don't handle fractional viewport offsets entirely correctly. If possible, it may be worth trying to switch to the shader offset implementation to see if it makes any difference. Is there any multi-sampling or sample shading involved?
Note that I don't personally remember the Spore bug being about the filling convention; I remember the bug, but if you told me it was about the half-pixel offset instead I'd believe you.