Created attachment 117772 [details]
screenshot with bad and expected rendering
Textures are blocky in Crusader Kings 2, on my Broadwell GT2. My guess is the texture filtering isn't working properly (or maybe antialiasing, dunno).
Attached is a screenshot of rendering with i965 and compared to expected rendering (obtained with radeonsi driver).
apitrace here: http://pavel.ondracka.cz/ck2.trace
GPU: Mesa DRI Intel(R) HD Graphics 5500 (Broadwell GT2)
xf86-video-intel: 18e484502727f2e2e16138a3de5b6727f3879a2b (dri3 + sna)
I think this is still a problem -- it's kind of hard to tell on a hidpi screen.
(In reply to Matt Turner from comment #1)
> I think this is still a problem -- it's kind of hard to tell on a hidpi
Yes, definitely still a problem.
We are working on this bug at StreamComputing. It occurs on i965 driver and llvmpipe (using the recent Mesa version from git, Skylake and Ivy Bridge).
Tested hardware: Intel(R) HD Graphics 530 (Skylake GT2)
Mesa version: Mesa 17.1.0-devel (git-a2db9f9) (Yes, old, but we did this when it was the newest commit.)
We confirmed error on:
* Mesa DRI Intel(R) HD Graphics 530 (Skylake GT2) (Intel DRI)
* Gallium 0.4 on llvmpipe (LLVM 3.8, 256 bits)
It looks ok on NVIDIA drivers.
We found when rendered image stops looking OK:
In frame 940 up to the call 2255268 (including) image looks ok, starting with next call - it looks "blocky". It seemed that program 163 does something bad.
We think that it's a bug in the shader code (vertex shader 165, program 163).
Commenting out VertexOut.uv += vHalfPixelOffset_Axis.xy; (line 405) in vertex shader 165 (program 163) in call 1848358, fixes the problem. Setting the offset to 0 also works.
In our opinion, this offset (vHalfPixelOffset) should be 0.0 in OpenGL, and it's probably a legacy workaround for D3D9.
Comparing to OpenGL and D3D10+, D3D9 has a different behaviour:
https://msdn.microsoft.com/en-us/library/cc308049(VS.85).aspx (the note in the beginning)
In this case we have 1 triangle with coordinates:
[3, -1], [-1, -1], [-1, 3]
VertexOut.uv = ( VertexIn.position + 1.0f ) * 0.5f; will give us texture coordinates:
[2, 0], [0, 0], [0, 2]
After clipping this triangle by a viewport we will get a full-screen rectangle:
[-1, -1], [1, 1] - positions of its corners in screen space
[0, 0], [1, 1] - uv
In OpenGL every fragment will already have texture coordinates perfectly mapped to centers of texels (0.5, 1.5, 2.5 and so on).
Adding the vHalfPixelOffset will return values right between texels (i.e. on their borders), and considering that there is a small precision loss, the values will be, for example, 1.0, 1.99999, 2.0, 3.00001, 4.0, 4.9999.
GL_NEAREST is a simple flooring operation (because it returns the nearest texel using its center), so in the example above the texels will be 1, 1, 2, 3, 4, 4.
Radeon on Mesa has no visible artefacts but all resulting pixels are moved by one for x and y (comparing to the source texture). Maybe it returns something like 1.0001, 2.00001, 3.0001... (i.e. always equal to or a bit more than an integer), we are not sure. We did not checke how Radeon on Catalyst works.
Stream HPC Team
Thanks for the analysis, I'm not sure if you already reported this to the developers, but I created a thread about this on the game forum, we shall see if there is any response.