xemu
xemu copied to clipboard
Beat Down: Vertical lines and crooked borders in text windows
Title
https://xemu.app/titles/43430015/#Beat-Down-Fists-of-Vengeance
Bug Description
Text windows during gameplay have vertical lines at the bottom and have crooked borders (note the left and right borders of the dialogue window in the screenshot).
Xemu 0.8.67
Expected Behavior
xemu Version
0.8.67
System Information
CPU: Intel(R) Core(TM) i5-9400F CPU @ 2.90GHz OS Platform: Windows OS Version: Windows 8.1 Pro Manufacturer: NVIDIA Corporation GPU Model: GeForce GTX 1050 Ti/PCIe/SSE2 Driver: 4.0.0 NVIDIA 442.59 Shader: 4.00 NVIDIA via Cg compiler
Additional Context
No response
A regression caused by #2183
This regression doesn't occur on Xemu 0.8.71, Linux, Mesa 25.1.1, with neither Intel UHD 770 nor AMD Radeon RX 6600 (also not with the llvmpipe software renderer.)
I inspected rendering of the text window in Renderdoc. The game draws the window border using several small quads around the border using a 64x128 texture atlas with nearest-neighbor sampling. The left edges of the quads have x-coordinates at half-pixel coordinates while the texture coordinates are at exactly integer coordinates (u=0, 32 or 64, and v = 0, 32, 64, 96 or 128). This means texture sampling occurs at exactly half-way between the centers of two neighboring texels. According to OpenGL/Vulkan specs the chosen texel should then be consistently the one on the right. Looking at the screenshot in the bug description it appears that the GeForce GPU nevertheless often chooses the left texel which belongs to the sub-image on the left of the correct one in the texture atlas, which would explain the artifacts. The crooked right border appears as if the chosen texel even changes at the vertical middle of those quads, even though the x-coordinates and texture u-coordinates are constant along the quad's left and right edge (and y and v are constant along top and bottom edges).
Perhaps someone with an NVIDIA GPU can inspect this in Renderdoc, but it could be that some GPUs don't handle texture nearest-neighbor sampling tie-breaking gracefully. If that is the case then subtracting a small number from the x,y coordinates might fix it: https://github.com/xemu-project/xemu/blob/e02e41ccaaceffcad816cfb554dd1195767e952d/hw/xbox/nv2a/pgraph/glsl/vsh.c#L93-L95
Changing this to e.g. return trunc(pos * 16.0f) / 16.0f - 0.004; where in place of 0.004 also other small numbers could be tried. If that fixes it then possibly Xemu might need GPU-specific quirk settings.
Here a renderdoc not sure guest or host don't know why it upside down. downloaded one abaire build seem to break the emulator. all renderdoc are upside down now. Let me know if there anything else you want. Tested your fix above only fixed the issue on vulkan on this issue. Fixed the other issues I metioned on other pr with ms5 and mvc2. matt also has nivida gpu so might be more helpful to find out the problem.
Thanks for testing and renderdoc. (You probably see it upside down in renderdoc, compared to before, because y-coordinates are flipped now to be the same as with Vulkan.) Your renderdoc capture looks fine on my system. I didn't look carefully enough previously, though. On Radeon, borders on the left side are crooked, but other sides are fine. On Intel, all are fine. I reproduced the artifact in a small OpenGL program (gist: https://gist.github.com/coldhex/a154871469780f63d60f4ae80b452772). Here's a zoomed screenshot:
The top rectangle is 32x32 pixels and renders perfectly with Radeon. The height of the bottom rectangle is a little less than 32 pixels. In exact arithmetic the texture u-coordinate at each pixel center is an integer, but Radeon (and I suppose GeForce as well) interpolation has floating-point round-off errors. This is what causes crooked window border in the game since there the border runs through the middle of such a rectangle.
Instead of subtracting something from vertex coordinates a better way to fix this is to add a small offset to texture coordinates in fragment shader similar to what the commented fragment shader code does in the gist. This needs a much smaller offset than for vertices since it's a more direct way to counteract interpolation round-off.
Also effects The Baseball 2002: Battle Ball Park Sengen, Dino crisis 3, Genma Onimusha, Metal Slug 4 and 5