http://bugs.winehq.org/show_bug.cgi?id=58662
Bug ID: 58662 Summary: 16-bit bitmap rendering Product: Wine Version: 10.14 Hardware: x86-64 OS: Linux Status: UNCONFIRMED Severity: normal Priority: P2 Component: opengl Assignee: wine-bugs@winehq.org Reporter: zowie+wine@vandillen.io Distribution: ---
Created attachment 79243 --> http://bugs.winehq.org/attachment.cgi?id=79243 Glitchy 16-bit render of Civilization 3. Without OpenGL Civ 3 does not have visible glitches.
I've added a new test earlier today for 16-bit bitmap rendering with wGL [1]. In conclusion, it's pretty broken. The solution to this problem isn't trivial, so I'm opening this issue for discussion.
On Windows, when wglChoosePixelFormat is called with the flag `PFD_DRAW_TO_BITMAP` and `cColorBits = 16`, you'll be given a pixel format with r5g5b5a1 (except that the alpha bit is somewhat quirky). This gives you a software rendered OpenGL context for OpenGL 1.1 [2].
On Wine, asking for a 16-bit pixel format gets you nothing, because all 16-bit pixel formats with the DRAW_TO_BITMAP are required to have an alpha bit in Wine and none of the pixel formats on my Nvidia driver actually have an alpha bit (there's only r5g6b5 and r16). The alpha bit requirement was introduced recently in MR !8392 [3]. It's worth noting that not getting a pixel format — although it's wrong — actually works pretty well for Civilization 3 (see “relevant software” section).
Removing the check for an alpha bit, Wine will be able to find a 16 bit pixel format again, but you'll get unusably bad renders (screenshots in the attachments).
Some observations on the screenshots: - You can see alternating vertical black/blue and orange/white/yellow lines every horizontal pixel. - Blue pixels appear in the black lines, but they're rare. I only see blue pixels in the text in the SimGolf screenshot. - The render buffer doesn't seem to be getting cleared (pretty apparent in Civilization 3: the old squares were sticking around) - Zooming in, you can see that there aren't only vertical lines, but also horizontal lines (see zoomed-in screenshot).
My theory is that there's two problems: - Wine is probably putting 32-bit-per-pixel renders into the 16-bit-per-pixel bitmaps. This explains the vertical & horizontal lines. I'm guessing there's also some memory corruption as a consequence: It's presumably overwriting twice as much bitmap memory as it should. - The right pixel format just doesn't exist. The format r5g5b5a1 is not something that is actually implemented on hardware (at least not anymore), it's just a quirky Windows software renderer thing.
The second point is a bit troublesome because I don't see any easy workarounds. The most obvious solution is to make an OpenGL 1.1 software renderer of our own. Alternatively, it might be possible to simulate the behaviour by using a 32-bits-per-pixel OpenGL context. Whenever glFinish is called, we could download the render to a "secret" Wine-internal bitmap that's also 32 bpp and then overwrite the 16 bpp bitmap based on the pixels of the 32 bpp bitmap. I'm not sure how reliable that is.
Looking at the OpenGL 1.1 reference [4], I think making an OpenGL 1.1 software renderer could be a fun project, but the other solution definitely seems like less effort. I've only been involved in Wine for seven days though, so I'll defer the decision to senior maintainers.
[1] https://gitlab.winehq.org/wine/wine/-/merge_requests/8888 [2] https://www.khronos.org/opengl/wiki/Platform_specifics:_Windows#PFD_DRAW_TO_... [3] https://gitlab.winehq.org/wine/wine/-/merge_requests/8392 [4] https://www.talisman.org/opengl-1.1/Reference.html
---
Relevant software (screenshots in attachments) - Sid Meier's SimGolf (demo: https://archive.org/details/Simgolfdemo) In SimGolf, a 16-bit DRAW_TO_BITMAP OpenGL context seems to be used for drawing the terrain. Currently, the terrain renders as black. - Sid Meier's Civilization 3 In Civilization 3, it seems that 16-bit bitmap rendering is used to draw an outline for the movement range of a selected unit (that's just a guess. It draws a square when a unit is selected but I haven't seen it without glitches). It's notable that Civilization 3 currently works fine. Because wglChoosePixelFormat doesn't find a 16-bit pixel format, the `null_gl` implementation is being used right now. That works out pretty well because the movement range outline isn't something you miss when you don't know it's supposed to be there.
---
Relevant bugs: Sid Meier's SimGolf does not render properly | https://bugs.winehq.org/show_bug.cgi?id=50876 Civilization III Complete shows black terrain (Wine compiled with OSMesa support) | https://bugs.winehq.org/show_bug.cgi?id=41930
http://bugs.winehq.org/show_bug.cgi?id=58662
--- Comment #1 from Zowie zowie+wine@vandillen.io --- Created attachment 79244 --> http://bugs.winehq.org/attachment.cgi?id=79244 SimGolf demo in 16-bit.
http://bugs.winehq.org/show_bug.cgi?id=58662
--- Comment #2 from Zowie zowie+wine@vandillen.io --- Created attachment 79245 --> http://bugs.winehq.org/attachment.cgi?id=79245 Without OpenGL (current Wine master), SimGolf demo has black ground
http://bugs.winehq.org/show_bug.cgi?id=58662
--- Comment #3 from Zowie zowie+wine@vandillen.io --- Created attachment 79246 --> http://bugs.winehq.org/attachment.cgi?id=79246 Zooming in on Civ 3 screenshot, you can see vertical and horizontal lines
http://bugs.winehq.org/show_bug.cgi?id=58662
Rémi Bernon rbernon@codeweavers.com changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |rbernon@codeweavers.com
--- Comment #4 from Rémi Bernon rbernon@codeweavers.com --- Yeah I think faking the pixel format and fixing up when uploading/downloading the pixels seems the easiest approach here. You can have a look at `flush_memory_dc` in dlls/win32u/opengl.c which is where this is being done with memory DCs.
http://bugs.winehq.org/show_bug.cgi?id=58662
--- Comment #5 from Zowie zowie+wine@vandillen.io --- Alright, I'll get working on that solution.