[RFC] Server side glvnd

Adam Jackson ajax at redhat.com
Tue Jul 18 15:43:32 UTC 2017


I've been thinking about how to get multiple GL stacks to coexist
within the server, along the lines of libglvnd on the client side. This
is a bit of a brain dump, the intrepid can find some work in progress
along these lines here:

https://cgit.freedesktop.org/~ajax/xserver/log/?h=glxfe

The basic approach I've been taking is: how little does the GLX
provider's dispatch code need to be modified?

For QueryVersion, we can just return 1.4. For the ClientInfo requests,
we have to dispatch them to every backend. For every other request, we
need to inspect some key element of the request and use that to map to
a backend. There are only three kinds of objects for this purpose:
screen numbers (sigh), XIDs, and context tags. The screen mapping is
straightforward. For XIDs we can set up a mapping on creation:
GLXCreateWindow is dispatched to a backend (by screen number), on
success we create a shadow resource with the same XID whose value
points to the backend that created it.

Tags are uglier because tags are ugly [1]. The code I currently have
for this simply treats tags as XIDs because in Xorg's GLX they are. But
tags are assigned by the backend, not the client: they're in the reply
to MakeCurrent. So the backend's MakeCurrent hook will need to be
different from a non-glvnded version, allocating the tag from the
frontend.

The other quirk with MakeCurrent is, when switching between contexts on
different backends, one must first detach the old context and then
attach the new. But that's two backend calls, and MakeCurrent as a
protocol request wants to emit a reply, and libGL is absolutely not
prepared to hear two replies to a single request. So the backend vtable
probably also needs a LoseCurrent hook. (I tried to hide this detail in
the frontend via ReplyCallback, and I was not very pleased with myself
afterwards.)

SwapBuffers has to dispatch based on the drawable, not the context tag,
because the tag may be None. Thanks SGI.

GLX requests with opcode >= 101 are "single" requests corresponding to
GL API calls that don't fit in a Render request; they are dispatched
relative to a context tag, so the backend vfunc can simply be int
(*Single)(ClientPtr client). Requests from 1 to 35 are GLX API calls,
and have a mostly static dispatch setup. The exceptions are
VendorPrivate and VendorPrivateWithReply. For these I imagine the
backend will register a list of { vop, object, offset, error } tuples
for each request it supports.

VendorPrivate requests are also tricky because, being GLX API, they can
also create and destroy objects. The shadow resource trick (above)
makes destruction lifetime simple, but the frontend will need to expose
methods to allow e.g. glXCreateGLXPbufferSGIX to register its XID. (In
principle GLX extensions could also create named objects on which one
should dispatch that are not XIDs. I'm not aware of any extensions like
that at the moment, and I kind of want not to support anyone making
that mistake.)

In principle, the above is enough in a Zaphod Xorg configuration to
have heterogeneous GLX providers on different ScreenRecs. It would also
make it easy, in a single ScreenRec case, to determine the GLX provider
based on the DDX driver in use (e.g., I updated my kernel but not my
NVIDIA driver, nouveau wants Xorg's GLX not NVIDIA's). For homogeneous
Xinerama-enabled GLX this should not lose any functionality, since the
backend can simply be the same for all objects.

Open questions:

- What more is needed for Prime setups? For direct contexts, I don't
think much. For indirect contexts presumably you'd want a way to
communicate the desired GPU when you create the GLX drawable and have
that determine the screen you dispatch to.

- What more is needed for Xinerama+GLX with the open driver stack? We
have some flexibility here, GLX_EXT_glvnd lets us name whatever client-
side library we want, so we can ask for a new Mesa target that knows
how to be multi-GPU aware.

- What more is needed for credible GLX on non-xfree86 servers, in
particular Xwayland? I think, if the pig is given enough thrust, it
would be possible to build accelerated GLX atop just about arbitrary
EGL stacks; in that sense it'd be cool if Xwayland could do reasonable
amounts of GLX accel with the stock backend. But I don't think that's
going to get feature or performance parity with xfree86 on its own, if
nothing else the open stack doesn't have stereo support.

- What else am I missing?

[1] - The GLX spec describes context tags as _not_ being the same as
the context XID, with the explanation that the context may be destroyed
but still be current to a client. Yes, and? You can prevent the client
from reusing the XID by simply not freeing it, the client is going to
ask XC-MISC for free IDs when it needs to start reusing them. I _think_
this is because GLX 1.0 predates XC-MISC, but 1994 was a long time ago
so maybe we can assume it's there now.

- ajax


More information about the xorg-devel mailing list