Helping Wine use 64 bit Mesa OGL drivers for 32-bit Windows applications

2024-10-18 Thread Derek Lesho

Hey everyone 👋,

I'm Derek from the Wine project, and wanted to start a discussion with 
y'all about potentially extending the Mesa OGL drivers to help us with a 
functionality gap we're facing.


Problem Space:

In the last few years Wine's support for running 32-bit windows apps in 
a 64-bit host environment (wow64) has almost reached feature completion, 
but there remains a pain point with OpenGL applications: Namely that 
Wine can't return a 64-bit GL implementation's buffer mappings to a 32 
bit application when the address is outside of the 32-bit range.


Currently, we have a workaround that will copy any changes to the 
mapping back to the host upon glBufferUnmap, but this of course is slow 
when the implementation directly returns mapped memory, and doesn't work 
for GL_PERSISTENT_BIT, where directly mapped memory is required.


A few years ago we also faced this problem with Vulkan's, which was 
solved through the VK_EXT_map_memory_placed extension Faith drafted, 
allowing us to use our Wine-internal allocator to provide the pages the 
driver maps to. I'm now wondering if an GL equivalent would also be seen 
as feasible amongst the devs here.


Proposed solution:

As the GL backend handles host mapping in its own code, only giving 
suballocations from its mappings back to the App, the problem is a 
little bit less straight forward in comparison to our Vulkan solution: 
If we just allowed the application to set its own placed mapping when 
calling glMapBuffer, the driver might then have to handle moving buffers 
out of already mapped ranges, and would lose control over its own memory 
management schemes.


Therefore, I propose a GL extension that allows the GL client to provide 
a mapping and unmapping callback to the implementation, to be used 
whenever the driver needs to perform such operations. This way the 
driver remains in full control of its memory management affairs, and the 
amount of work for an implementation as well as potential for bugs is 
kept minimal. I've written a draft implementation in Zink using 
map_memory_placed [1] and a corresponding Wine MR utilizing it [2], and 
would be curious to hear your thoughts. I don't have experience in the 
Mesa codebase, so I apologize if the branch is a tad messy.


In theory, the only requirement from drivers from the extension would be 
that glMapBuffer always return a pointer from within a page allocated 
through the provided callbacks, so that it can be guaranteed to be 
positioned within the required address space. Wine would then use it's 
existing workaround for other types of buffers, but as Mesa seems to 
often return directly mapped buffers in other cases as well, Wine could 
also avoid the slowdown that comes with copying in these cases as well.


Why not use Zink?:

There's also a proposal to use a 32-bit PE build of Zink in Wine 
bypassing the need for an extension; I brought this to discussion in 
this Wine-Devel thread last week [3], which has some arguments against 
this approach.



If any of you have thoughts, concerns, or questions about this potential 
approach, please let me know, thanks!


1: https://gitlab.freedesktop.org/Guy1524/mesa/-/commits/placed_allocation

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

3: https://marc.info/?t=17288326032&r=1&w=2



Re: Helping Wine use 64 bit Mesa OGL drivers for 32-bit Windows applications

2024-10-18 Thread Faith Ekstrand
The timing here isn't great, unfortunately. I'd love to contribute more to
the discussion but I'm going on leave starting next week until mid-Febuary
so I won't be able to participate much until then. I'll try to leave a few
thoughts, though.

On Fri, Oct 18, 2024 at 5:10 PM Derek Lesho  wrote:

> Hey everyone 👋,
>
> I'm Derek from the Wine project, and wanted to start a discussion with
> y'all about potentially extending the Mesa OGL drivers to help us with a
> functionality gap we're facing.
>
> Problem Space:
>
> In the last few years Wine's support for running 32-bit windows apps in
> a 64-bit host environment (wow64) has almost reached feature completion,
> but there remains a pain point with OpenGL applications: Namely that
> Wine can't return a 64-bit GL implementation's buffer mappings to a 32
> bit application when the address is outside of the 32-bit range.
>
> Currently, we have a workaround that will copy any changes to the
> mapping back to the host upon glBufferUnmap, but this of course is slow
> when the implementation directly returns mapped memory, and doesn't work
> for GL_PERSISTENT_BIT, where directly mapped memory is required.
>
> A few years ago we also faced this problem with Vulkan's, which was
> solved through the VK_EXT_map_memory_placed extension Faith drafted,
> allowing us to use our Wine-internal allocator to provide the pages the
> driver maps to. I'm now wondering if an GL equivalent would also be seen
> as feasible amongst the devs here.
>
> Proposed solution:
>
> As the GL backend handles host mapping in its own code, only giving
> suballocations from its mappings back to the App, the problem is a
> little bit less straight forward in comparison to our Vulkan solution:
> If we just allowed the application to set its own placed mapping when
> calling glMapBuffer, the driver might then have to handle moving buffers
> out of already mapped ranges, and would lose control over its own memory
> management schemes.
>
> Therefore, I propose a GL extension that allows the GL client to provide
> a mapping and unmapping callback to the implementation, to be used
> whenever the driver needs to perform such operations. This way the
> driver remains in full control of its memory management affairs, and the
> amount of work for an implementation as well as potential for bugs is
> kept minimal. I've written a draft implementation in Zink using
> map_memory_placed [1] and a corresponding Wine MR utilizing it [2], and
> would be curious to hear your thoughts. I don't have experience in the
> Mesa codebase, so I apologize if the branch is a tad messy.
>

It's an interesting approach, to be sure. I don't mean that as a bad or
good thing as I haven't given this enough thought with GL in mind to have a
better, more well thought out plan.

The most obvious issue that jumps out to me is that we really want that
callback to be set before anyone ever maps a buffer that might possibly get
exposed to the client and we want it to never change.  If this were Vulkan,
we'd have you provide it at vkCreateDevice() time.  But this is GL where
everybody loves a big mutable state object. If we do go with callbacks (and
it's still not 100% clear to me what the right choice is), we'd want them
to be somehow set-once and set before any buffers are created.  I'm not
100% sure how you'd spec that or how we'd enforce it.  There may be some
precedent for this somewhere in GL (no_error, maybe?) but I'm not sure.

The other question that comes to mind is when exactly we'd be expected to
use these things. Obviously, we need to do so for any map that may be
exposed to the client.  However, it's not always easy to do that because
you don't know at buffer create time whether or not it will be persistently
mapped.  A driver is likely to have all sorts of internal mappings for
things and, while those can come from one of those ranges, it'll burn more
of that precious 32-bit address space than needed. This gets worse when you
take sub-allocation into account. If we're okay with all buffer mappings
going down the client-request path then it's probably okay. The driver just
might need an extra bit in its buffer cache key.

I'm also sitting here trying to come up with some plan that would let us do
this more like Vulkan and I'm having trouble coming up with one that works.
GL has no concept of "create time". We could theoretically do something
where we flush everything, copy the data to a new placed-mappable buffer
and then continue on but that's gonna suck.

I think that's all that comes to mind immediately. As I said at the top,
I'm happy to talk more in a few months. Best of luck until then!

~Faith



> In theory, the only requirement from drivers from the extension would be
> that glMapBuffer always return a pointer from within a page allocated
> through the provided callbacks, so that it can be guaranteed to be
> positioned within the required address space. Wine would then use it's
> existing workaround for other types o

Re: Mesa is painful to bisect, I hope this can be improved

2024-10-18 Thread Michel Dänzer
On 2024-10-18 01:36, Timur Kristóf wrote:
> 
> It's not clear what your issue is exactly, it seems your problem may be
> that you try to build the entirety of Mesa and replace the version in
> your system that was shipped by your distro? Or that you bisect between
> very old very new versions?

I suspect the latter. To put it differently, the further back one needs to go 
for bisecting, the more likely one is to hit the issues Thomas described. I've 
certainly hit some of them myself.


> My process is having a meson setup configured to build just the driver
> I am interested in debugging and then I compile it and install to a
> local prefix without replacing the Mesa version shipped by my system.
> Then I run the application with that local Mesa version by pointing it
> to the Vulkan ICD of that version or setting the relevant environment
> variables for OpenGL. This works without affecting the rest of the
> system.

FWIW, you might not need to even install for this, "meson devenv" allows 
running apps using the Mesa binaries in a build directory.


> Other than that, I think it's normal and expected that the drivers
> evolve and some options change. Things that were experimental yesterday
> might become default tomorrow; things that were default last week might
> become obsolete or even removed.

As Thomas points out though, such changes potentially cause pain for people who 
need to bisect across them. So such changes shouldn't be done lightly but only 
if the benefits clearly outweigh that pain.


-- 
Earthling Michel Dänzer   \GNOME / Xwayland / Mesa developer
https://redhat.com \   Libre software enthusiast