Summary: | Incorrect texture filtering when using GL_LINEAR_MIPMAP_LINEAR | ||
---|---|---|---|
Product: | Mesa | Reporter: | peter.fiss |
Component: | Mesa core | Assignee: | mesa-dev |
Status: | RESOLVED NOTOURBUG | QA Contact: | mesa-dev |
Severity: | normal | ||
Priority: | medium | ||
Version: | 11.2 | ||
Hardware: | x86-64 (AMD64) | ||
OS: | Linux (All) | ||
Whiteboard: | |||
i915 platform: | i915 features: | ||
Attachments: |
source code
the issue with GL_CLAMP_TO_EDGE the issue with GL_CLAMP_TO_BORDER How it should look like (nvidia) |
Created attachment 122848 [details]
the issue with GL_CLAMP_TO_EDGE
Created attachment 122849 [details]
the issue with GL_CLAMP_TO_BORDER
Created attachment 122850 [details]
How it should look like (nvidia)
Looking at the fragment shader: // check if in [-1;1] if(any(lessThan ( vec3(1.0), projTexCoords )) || any(greaterThan( vec3(-1.0), projTexCoords ))) return vec3(0.0, 0.0, 0.3); projTexCoords = 0.5 * projTexCoords + vec3(0.5); // transform to [0;1] return texture( u_Texture, projTexCoords.xy ).xyz; texture() is only called conditionally, i.e. within non-uniform control flow, but for mip-mapping it has to implicitly calculate derivatives. Section 8.7 of the GLSL spec explains that this is undefined: "Some texture functions (non-“Lod” and non-“Grad” versions) may require implicit derivatives. Implicit derivatives are undefined within non-uniform control flow [...]." Thanks for pointing out. Moving all ifs to the end of the function indeed fixes the issue. |
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.
Created attachment 122847 [details] source code I had an issue with texture filtering in one of my apps. So I decided to write a minimal sample program, which can reproduce the issue. You can find it in the tar.xz archive attached to this bug report. The program creates a 512x512 texture which is completely white, except for the outermost 8 pixels, which are black. The fragment shader renders the texture as if a light was projecting it from the side (see attached screenshots). The resulting picture is different depending on the graphics driver and glTexParameter settings. If GL_TEXTURE_MIN_FILTER is set to GL_LINEAR or GL_NEAREST, everything looks fine, no matter which driver is used. The resulting picture looks like nvidia.png. However, when using GL_LINEAR_MIPMAP_LINEAR, there is a ~1 pixel wide border around the projected texture. This happens on all tested drivers except the proprietary nvidia driver on Windows. This is actually strong evidence that there's something wrong with my program instead of the drivers, but I really couldn't figure it out and the program is not that complicated. The white border gets smaller when GL_TEXTURE_WRAP_* is set to GL_CLAMP_TO_BORDER instead of GL_CLAMP_TO_EDGE or GL_REPEAT. It's still wrong though. Make sure to view the screenshots unscaled and unfiltered, otherwise you might not see it. Tested platforms: - Intel HD 4000 (Ivy Bridge Mobile) with Mesa 11.2.0-1 on Arch - GeForce GT 640M with Mesa 11.2.0-1 on Arch - Radeon HD 5670 with Mesa 11.1.2-1 on Manjaro - the same 3 GPUs with their proprietary drivers on Windows 7 Since all tested Mesa drivers have the issue, I decided to post this in the mesa core section. I hope this is correct. If you can confirm, that this is a driver bug, I will write bug reports to the closed-source teams of AMD and Intel as well.