Discussing paths forward for OpenGL mappings on Wow64

Derek Lesho <[email protected]>
Newsgroups gmane.comp.emulators.wine.devel
Message-ID <[email protected]>
Hi everyone,

I'm creating this thread to start a discussion about how we want to 
complete GL support on Wow64, in the hopes that, if we want a MESA 
extension for this, we can get it to them sooner rather than later.

The core of the problem is same that we faced for Vulkan: namely that 
host visible mappings from graphics APIs may be located above 32-bit 
memory, in which case we can't pass them to the application as is. In 
the current implementation that Rémi wrote a few years ago, we use a 
temporary buffer for glMapBuffer, and manually have to copy the data 
from it back to the real mapping on glUnmapBuffer.

This solution works for most applications, but is slower than direct 
writes, and doesn't allow use of the GL_MAP_PERSISTENT_BIT glMapBuffer 
flag, where the application doesn't have to unmap the memory before 
usage by the API. Because of this problem, we can't support GL versions 
 >= 4.4 in this path, which admittedly isn't a huge problem considering 
wined3d now supports Vulkan, but does rule out some native GL apps/games 
from running on the new path. I'll go over a few potential solutions:

- "Just Use Zink": this idea has been floated for a while, and would be 
to use a PE build of Zink, the MESA gallium driver on top of Vulkan, 
which would then automatically make use of our VK_EXT_map_memory_placed 
integration in winevulkan and bypass the problem. Rémi has a branch with 
a draft solution for this [1] The advantage of approach is that it 
doesn't require any more extensions to any more APIs, but the 
disadvantage is that Wine would have to worry about keeping a separate 
version of Mesa up to date and support for building the required c++ 
components of mesa to its build system, as can be seen in the commits.

- GL extension with placed memory allocation callback: In this case, 
Wine provides a map and unmap callback for the GL implementation to use 
in creating the pages it needs for GPU-mappings. In comparison to the PE 
Zink solution, we can continue to use system libraries, and maintain 
fast buffer IO, as long as the glMapBuffer implementation returns the 
mapped ptr directly. The main downside for this solution is of course 
the introduction of a new extension to the mostly dormant GL API, but 
here it would be possible to just use a VK_EXT_map_memory leveraging 
Zink like in the first solution, only this time on the Unix side.

For this solution I've created a draft: Wine MR [2] Mesa Branch with 
Zink implementation [3]

- glMapBuffer extension which we send our placed allocation: The idea 
here is that slightly extended glMapBuffer could be sent a flag to use 
Wine mapping, avoiding callbacks and targeting the problem where it 
manifests for Wine (when we get an address out of 32-bit space). This 
was briefly discussed on the LGD discord server, but it won't work well, 
due to the fact that a GL buffer is usually only a suballocation of a 
memory mapping, and often has already been assigned to another pool of 
memory by the time glMapMemory is called. Mesa would have to add a 
considerable sized implementation setting up custom-allocator pools, and 
be able to move buffers between them to implement this.

- glBufferStorage extension to ease Mesa implementation: The next 
logical conclusion based on the problems of the last solution is that 
the Mesa implementation should get the information about any custom 
allocation at buffer creation time. The closest equivalent to this is 
the glBufferStorage entry, where we could create a new type of memory 
that we would ask the implementation to put the buffer in. For this 
solution we'd either have to implement custom memory allocator or 
introduce more API entries in order to allow the driver to convey to the 
application what size mappings it prefers. This would be very unwieldy, 
and wouldn't solve speed up the slow buffer copies for legacy buffers 
which don't use ARB_buffer_storage.

- finally, going off the last possibility, if we're willing to create 
our own buffer allocator (we probably shouldn't, as the driver probably 
knows best), we could use the already existing EXT_external_objects 
extensions to import Vulkan memory objects, from which our allocator 
would allocate slices for the buffers. In glMapBuffer we would then 
return the Vulkan placed memory mapping.

If I got anything wrong or overlooked anything, please let me know. If 
we decide on a solution that involves mesa, I would gladly then include 
the mesa-dev list to see if they have opinions for/against any of the 
proposals.

Thanks,
Derek

1: https://gitlab.winehq.org/rbernon/wine/-/tree/wip/just-use-zink

2: https://gitlab.winehq.org/wine/wine/-/merge_requests/6663

3: https://gitlab.freedesktop.org/Guy1524/mesa/-/commits/placed_allocation
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.