[Libva] [RFC] OpenGL API extension (v3)
Gwenole Beauchesne
gbeauchesne at splitted-desktop.com
Wed Sep 23 01:22:10 PDT 2009
Hi Jonathan,
On Tue, 22 Sep 2009, Bian, Jonathan wrote:
> I didn't see follow-ups to the following thread when catching up on
> emails after coming back from vacation ...
Sorry, I was busy implementing and testing the thing. ;-)
> I am thinking along similar lines as Austin on this proposal. If we can
> have the app pass the GLX context at VA init time, then perhaps only a
> new vaPutSurface interface is needed for the purpose of getting the VA
> surface into a GL texture, without having to add a number of new
> functions.
Actually, this was the way (v1) of the API operated:
1) One function to tell we are in GLX mode: vaGetDisplayGLX()
2) One function to transfer VA surface to GL texture:
vaCopySurfaceToTexture()
This worked for my small hwdecode-demos. However, while integrating into
real-world applications (e.g. MPlayer), this exposed several problems.
1) GLX context is generally tied to a window. So, propagating this context
to vaGetDisplay() is not a good option. A vaInitializeGLX() seemed a
better location, especially to let the VA driver initialize extra VTable
hooks, but it's not really convenient either from a user point of view.
For instance, MPlayer is creating/destroying the GLX context whenever the
video is changed. vaInitialize()'ing there, or changing the VADisplay, is
not a good approach, IMHO. So, at this stage, it became apparent I needed
a new function to tell "hey, we use GLX, here is the GLX context".
Next, I came to think about the actual storage of the GLX context.
- A pointer to the GLXContext? If GLXContext is changed, libVA
automatically knows about the change. However, if GLXContext is destroyed,
and user does not set it to GL_NONE or whatever, libVA would not have any
chance to know about it. Well, we have the same problem as with the X11
display anyway, so this probably bearable and documentable. e.g. GLX
context shall be live from X to Y.
- A copy of the GLXContext? If GLXContext is changed, libVA wouldn't know
about the changes since it had a previous copy. We then tend to an
explicit API to notify the GLXContext.
Finally, I decided that we may just delegate this to the user and let
libVA assume to operate under the currently live GLXContext. This works
with current implementations.
2) Some implementations (like NVIDIA) are limited to the GLX
texture-from-pixmap extension. They have no means to directly transfer the
VA surface to a GL texture. If I want a VA surface to be transferred to a
GL texture, I can only use an FBO. Extra work that I don't want users to
support.
BTW, TFP works by binding/releasing the GLX pixmap whenever we need to
render a texture where that pixmap is attached to. So, in order to avoid
FBO, I wanted to see whether there would be any performance gain by adding
bind/release functions directly at the VA level and have this usage
scenario:
vaBindSurface
// gl operations to render
vaReleaseSurface
It turns out the gain is really minimal but that was on an NVIDIA 8600GT
discrete card. Around 3 points gain (e.g. 13% -> 10% CPU time).
BTW, it would be interesting to know performance on a Moorestown platform.
If using MPlayer, you can try the following:
$ ./mplayer -vo vaapi:gl -va vaapi -fs /path/to/some/1080p/video
$ ./mplayer -vo vaapi:gl:bind -va vaapi -fs /path/to/some/1080p/video
Would a bind/unbind approach be faster than an FBO approach on Moorestown?
You can privately tell me that. In the meantime, I will try again to get a
platform.
Why Associate/Deassociate functions? This was a convenience to avoid
repeating GL texture target, id and probably GLX context too in function
arguments. So, it became apparent a dedicated VA/GLX surface would be
useful to hold that information.
3) I only care about transferring the VA surface to a GL texture as my
needs are for Clutter. I also want a user to do minimal work. So, I'd
really want to keep only the "transfer VA surface to GL texture" API and
possibly drop the bind/unbind stuff, unless it's really necessary
performance-wise e.g. on Moorestown and Poulsbo.
4) I wanted a generic VA/GLX implementation within libVA for drivers only
supporting vaPutSurface(Pixmap,...). So, this point was IMHO a stronger
reason to have a dedicated VA/GLX surface. Otherwise, that would have
tended to some awful machinery to my taste. And also because there is no
means to attach "user" information to an existing VA surface.
In summary, I would like:
(a) Less pain for the users. i.e. don't have him duplicate TFP(+FBO)
machinery in his code. Move that directly into libVA for the generic
implementation.
(b) A single "Copy VA surface to GL texture" API. This will remove the
need for associate, deassociate, bind, release functions. Unless this is
really necessary to keep those for other implementations for performance.
With the (b) condition, we would only keep: vaGetDisplayGLX(),
vaCreateSurfaceGLX(), vaDestroySurfaceGLX(), vaCopySurfaceGLX(). This has
the advantage that vaCreateSurfaceGLX() could also be the API to receive
the GLX context.
5) I want to keep the existing functions and control flow as is. That is,
I would like to avoid the need to call an extra function in-between just
to pass some GLX info/context to the VA driver. The reason is e.g. for
FFmpeg, I want to move more stuff to it so that a user only has to:
- dpy = vaGetDisplay{X11,GLX,whatever}()
- av_create_hwaccel_context(avctx, dpy);
- vaPutSurface()/vaCopySurfaceToTexture() when it needs to
- av_destroy_hwaccel_context(avctx);
i.e. vaCreateContext(), vaCreateConfig(), vaCreateSurfaces() and all those
things (display-independent) are to be moved to FFmpeg itself. This would
terribly ease FFmpeg-based applications enabling to VA API.
Regards,
Gwenole.
More information about the Libva
mailing list