[Mesa-dev] [RFC] pipe-loader: abstract GALLIUM_STATIC_TARGETS behind pipe_loader API
Marek Olšák
maraeo at gmail.com
Wed Sep 30 16:37:43 PDT 2015
On Wed, Sep 30, 2015 at 10:43 PM, Rob Clark <robdclark at gmail.com> wrote:
> From: Rob Clark <robclark at freedesktop.org>
>
> Not actually working yet, ie. doesn't even compile yet, but an idea.
>
> Initial motivation was for drm_gralloc/pipe, which is essentially a sort
> of mini state-tracker, that needs to be able to share pipe_screen with
> libGL linked into the same process (to ensure we didn't end up with
> duplicate pipe_resource's, etc). I think same situation happens with
> vdpau+gl interop.
>
> Currently drm_gralloc/pipe (and other state trackers??) statically link
> the winsys code, which completely defeats the purpose magic in the
> winsys code to detect when the same device is opened multiple times and
> return the same pipe_screen (since you end up w/ multiple copies of the
> hashtable in the same process). See for example:
>
> 5bb41d9094b3c9bdf0669fd55418981ed83347e3
> fee0686c21c631d96d6042741267a3c218c23ffc
>
> Rough idea is that we should have something like libgallium.so which
> contains the pipe-loader API, and then optionally (depending on
> GALLIUM_STATIC_TARGETS) all of the gallium pipe drivers. The various
> different state trackers would link against (or dlopen()) libgallium.so
> and use the pipe-loader API to get themselves a pipe_screen (and config
> params, etc). And then you end up with:
>
> +---+
> | l |
> clover --> | i |
> | b |
> mesa-st --> | g |
> | a |--> pipe driver
> vdapau --> | l |
> | l |
> gralloc --> | i |
> | u |
> xa --> | m |
> | |
> +---+
> or:
> +---+-------------+
> | l | |
> clover --> | i | |
> | b | |
> mesa-st --> | g | |
> | a | pipe driver |
> vdapau --> | l | |
> | l | |
> gralloc --> | i | |
> | u | |
> xa --> | m | |
> | | |
> +---+-------------+
>
> depending on GALLIUM_STATIC_TARGETS. Either way, all the state trackers
> in the same process share a single copy of the hashtable in the winsys
> code which allows them to share the same pipe_screen.
>
> I think that ends up being an extra level of library indirection vs
> current state w/ pipe drivers, ie. with mesa dri loader stuff directly
> loading gallium_dri.so which contains all the drivers plus mesa state
> tracker. If this was concerning to someone, what I'd suggest would be
> to, for all the state trackers that already have some sort of loader
> sitting between them and the user, just pull them directly into the
> mega-mega libgallium.so, ie. something like:
>
> +---------+---+-------------+
> | | | |
> | clover | l | |
> | | i | |
> | mesa-st | b | |
> | | g | pipe driver |
> | vdapau | a | |
> | | l | |
> +---------| l | |
> | i | |
> gralloc --> | u | |
> | m | |
> xa --> | | |
> | | |
> +---+-------------+
>
> Anyways, I'm far from an expert in the build architecture of things so
> I might have some facts wrong or be a bit confused. And I'll probably
> regret bringing the subject up. But somehow or another it seems like
> it would be good to (a) clean up all the GALLIUM_STATIC_TARGETS
> ifdeffery spread throughout all the different state trackers, and (b)
> have the pipe driver[*] only exist once per process rather than once per
> state-tracker. Especially for android where each process using GL will
> have both gralloc and mesa-st.. and perhaps even clover/omx/etc.
Radeon and amdgpu already have one pipe_screen per process per fd. It
works like this:
- The GL, VDPAU, OMX etc. libs each ship its own copy of the whole
driver, so we have multiple screens and multiple winsyses.
- All libs export "radeon_drm_winsys_create", which is this function:
struct radeon_winsys *radeon_drm_winsys_create(
int fd, radeon_screen_create_t screen_create);
- The first lib that is loaded registers "radeon_drm_winsys_create",
all other libs loaded later can't override it. Therefore, if any lib
calls radeon_drm_winsys_create, the version from the first loaded lib
is called.
- The first caller passes the screen_create function to
radeon_drm_winsys_create, the screen is created only once for each
input fd in that function along with the winsys. When the winsys is
returned, radeon_winsys::screen is the returned screen.
- Any other call to radeon_drm_winsys_create will return the same
winsys+screen combo for that fd. (it also needs to recognize dup()
fds, etc.)
- Of course, all libs must use the same version of the driver.
- The winsys is reference-counted. pipe_screen::destroy doesn't
destroy itself until the winsys counter drops to 0.
Alternative solution other than the gallium lib:
- use a winsys lib or move the winsys into libdrm
Indeed, libdrm_amdgpu only creates one instance of amdgpu_device per
process per fd.
Marek
More information about the mesa-dev
mailing list