summaryrefslogtreecommitdiffstats
path: root/meta-emenlow/recipes-graphics/libva/libva-0.31.0/322_libva_glx.patch
diff options
context:
space:
mode:
authorNitin A Kamble <nitin.a.kamble@intel.com>2012-09-18 12:16:07 -0700
committerTom Zanussi <tom.zanussi@intel.com>2012-12-03 14:20:44 -0600
commit6eed0090597bfe82603be5ffa9c9f1fd141306f0 (patch)
treee4e16247f8ae3b3ad3a1426f59af2dcf5668e533 /meta-emenlow/recipes-graphics/libva/libva-0.31.0/322_libva_glx.patch
parentb4141a6404fa7d3445d660860b6bf68acec9f114 (diff)
downloadmeta-intel-6eed0090597bfe82603be5ffa9c9f1fd141306f0.tar.gz
emenlow: use emgd instead of psb for graphics driver
Remove all the Poulsbo graphics driver specific meta data files. And configure the BSP to use EMGD instead of psb for graphics stack. Signed-off-by: Nitin A Kamble <nitin.a.kamble@intel.com> Signed-off-by: Tom Zanussi <tom.zanussi@intel.com>
Diffstat (limited to 'meta-emenlow/recipes-graphics/libva/libva-0.31.0/322_libva_glx.patch')
-rw-r--r--meta-emenlow/recipes-graphics/libva/libva-0.31.0/322_libva_glx.patch2024
1 files changed, 0 insertions, 2024 deletions
diff --git a/meta-emenlow/recipes-graphics/libva/libva-0.31.0/322_libva_glx.patch b/meta-emenlow/recipes-graphics/libva/libva-0.31.0/322_libva_glx.patch
deleted file mode 100644
index ccd9ae09..00000000
--- a/meta-emenlow/recipes-graphics/libva/libva-0.31.0/322_libva_glx.patch
+++ /dev/null
@@ -1,2024 +0,0 @@
1commit 8e76000abce070da5f1c902a6290f4ccaa3eccc8
2Author: Gwenole Beauchesne <gbeauchesne@splitted-desktop.com>
3Date: Fri Sep 18 15:51:08 2009 +0000
4
5 Add C++ guards.
6
7commit bf1ae22ef324fbb347f5369e1ba307e847553fe8
8Author: Gwenole Beauchesne <gbeauchesne@splitted-desktop.com>
9Date: Fri Sep 18 15:49:55 2009 +0000
10
11 Fix check for GL extensions.
12
13commit df0953a951d8a2e5e4b0a28a95ae0f1ac735726e
14Author: Gwenole Beauchesne <gbeauchesne@splitted-desktop.com>
15Date: Tue Sep 8 12:25:14 2009 +0000
16
17 Add generic VA/GLX implementation with TFP and FBO.
18
19commit f640b1cf9eab4e5d478239b608ed0d8b68f6c5f6
20Author: Gwenole Beauchesne <gbeauchesne@splitted-desktop.com>
21Date: Tue Sep 8 12:15:35 2009 +0000
22
23 Move GLX VTable to a new file.
24
25commit 70d9cb6d1aa2fc2dde6646f3b692433e0d93d431
26Author: Gwenole Beauchesne <gbeauchesne@splitted-desktop.com>
27Date: Fri Aug 28 11:15:51 2009 +0000
28
29 Add OpenGL extensions (v3).
30
31diff --git a/src/glx/Makefile.am b/src/glx/Makefile.am
32new file mode 100644
33index 0000000..7783d8c
34--- /dev/null
35+++ b/src/glx/Makefile.am
36@@ -0,0 +1,41 @@
37+# Copyright (C) 2009 Splitted-Desktop Systems. All Rights Reserved.
38+#
39+# Permission is hereby granted, free of charge, to any person obtaining a
40+# copy of this software and associated documentation files (the
41+# "Software"), to deal in the Software without restriction, including
42+# without limitation the rights to use, copy, modify, merge, publish,
43+# distribute, sub license, and/or sell copies of the Software, and to
44+# permit persons to whom the Software is furnished to do so, subject to
45+# the following conditions:
46+#
47+# The above copyright notice and this permission notice (including the
48+# next paragraph) shall be included in all copies or substantial portions
49+# of the Software.
50+#
51+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
52+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
53+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
54+# IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
55+# ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
56+# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
57+# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
58+
59+AM_CFLAGS = -DLINUX -DIN_LIBVA -I$(top_srcdir)/src -I$(top_srcdir)/src/x11
60+
61+source_c = \
62+ va_glx.c \
63+ va_glx_impl.c
64+
65+source_h = \
66+ va_glx.h \
67+ va_backend_glx.h
68+
69+source_h_priv = \
70+ va_glx_impl.h \
71+ va_glx_private.h
72+
73+noinst_LTLIBRARIES = libva_glx.la
74+libva_glxincludedir = ${includedir}/va
75+libva_glxinclude_HEADERS = $(source_h)
76+libva_glx_la_SOURCES = $(source_c)
77+noinst_HEADERS = $(source_h_priv)
78diff --git a/src/glx/va_backend_glx.h b/src/glx/va_backend_glx.h
79new file mode 100644
80index 0000000..3885d30
81--- /dev/null
82+++ b/src/glx/va_backend_glx.h
83@@ -0,0 +1,87 @@
84+/*
85+ * Copyright (C) 2009 Splitted-Desktop Systems. All Rights Reserved.
86+ *
87+ * Permission is hereby granted, free of charge, to any person obtaining a
88+ * copy of this software and associated documentation files (the
89+ * "Software"), to deal in the Software without restriction, including
90+ * without limitation the rights to use, copy, modify, merge, publish,
91+ * distribute, sub license, and/or sell copies of the Software, and to
92+ * permit persons to whom the Software is furnished to do so, subject to
93+ * the following conditions:
94+ *
95+ * The above copyright notice and this permission notice (including the
96+ * next paragraph) shall be included in all copies or substantial portions
97+ * of the Software.
98+ *
99+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
100+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
101+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
102+ * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
103+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
104+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
105+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
106+ */
107+
108+#ifndef VA_BACKEND_GLX_H
109+#define VA_BACKEND_GLX_H
110+
111+struct VADriverContext;
112+
113+struct VADriverVTableGLX {
114+ /* Optional: create a surface used for display to OpenGL */
115+ VAStatus (*vaCreateSurfaceGLX)(
116+ struct VADriverContext *ctx,
117+ unsigned int gl_target,
118+ unsigned int gl_texture,
119+ void **gl_surface
120+ );
121+
122+ /* Optional: destroy a VA/GLX surface */
123+ VAStatus (*vaDestroySurfaceGLX)(
124+ struct VADriverContext *ctx,
125+ void *gl_surface
126+ );
127+
128+ /* Optional: associate a VA surface to a VA/GLX surface */
129+ VAStatus (*vaAssociateSurfaceGLX)(
130+ struct VADriverContext *ctx,
131+ void *gl_surface,
132+ VASurfaceID surface,
133+ unsigned int flags
134+ );
135+
136+ /* Optional: deassociate a VA surface from a VA/GLX surface */
137+ VAStatus (*vaDeassociateSurfaceGLX)(
138+ struct VADriverContext *ctx,
139+ void *gl_surface
140+ );
141+
142+ /* Optional: synchronize a VA/GLX surface */
143+ VAStatus (*vaSyncSurfaceGLX)(
144+ struct VADriverContext *ctx,
145+ void *gl_surface
146+ );
147+
148+ /* Optional: prepare VA/GLX surface for rendering */
149+ VAStatus (*vaBeginRenderSurfaceGLX)(
150+ struct VADriverContext *ctx,
151+ void *gl_surface
152+ );
153+
154+ /* Optional: notify the server that the VA/GLX surface is no
155+ longer used for rendering */
156+ VAStatus (*vaEndRenderSurfaceGLX)(
157+ struct VADriverContext *ctx,
158+ void *gl_surface
159+ );
160+
161+ /* Optional: copy a VA surface to a VA/GLX surface */
162+ VAStatus (*vaCopySurfaceGLX)(
163+ struct VADriverContext *ctx,
164+ void *gl_surface,
165+ VASurfaceID surface,
166+ unsigned int flags
167+ );
168+};
169+
170+#endif /* VA_BACKEND_GLX_H */
171diff --git a/src/glx/va_glx.c b/src/glx/va_glx.c
172new file mode 100644
173index 0000000..f6ec2c3
174--- /dev/null
175+++ b/src/glx/va_glx.c
176@@ -0,0 +1,295 @@
177+/*
178+ * Copyright (C) 2009 Splitted-Desktop Systems. All Rights Reserved.
179+ *
180+ * Permission is hereby granted, free of charge, to any person obtaining a
181+ * copy of this software and associated documentation files (the
182+ * "Software"), to deal in the Software without restriction, including
183+ * without limitation the rights to use, copy, modify, merge, publish,
184+ * distribute, sub license, and/or sell copies of the Software, and to
185+ * permit persons to whom the Software is furnished to do so, subject to
186+ * the following conditions:
187+ *
188+ * The above copyright notice and this permission notice (including the
189+ * next paragraph) shall be included in all copies or substantial portions
190+ * of the Software.
191+ *
192+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
193+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
194+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
195+ * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
196+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
197+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
198+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
199+ */
200+
201+#include "va_glx_private.h"
202+#include "va_glx_impl.h"
203+
204+#define INIT_CONTEXT(ctx, dpy) do { \
205+ if (!vaDisplayIsValid(dpy)) \
206+ return VA_STATUS_ERROR_INVALID_DISPLAY; \
207+ \
208+ ctx = ((VADisplayContextP)(dpy))->pDriverContext; \
209+ if (!(ctx)) \
210+ return VA_STATUS_ERROR_INVALID_DISPLAY; \
211+ \
212+ VAStatus status = va_glx_init_context(ctx); \
213+ if (status != VA_STATUS_SUCCESS) \
214+ return status; \
215+ } while (0)
216+
217+#define INIT_SURFACE(surface, surface_arg) do { \
218+ surface = (VASurfaceGLXP)(surface_arg); \
219+ if (!vaSurfaceIsValid(surface)) \
220+ return VA_STATUS_ERROR_INVALID_SURFACE; \
221+ } while (0)
222+
223+#define INVOKE(ctx, func, args) do { \
224+ VADriverVTableGLXP vtable; \
225+ vtable = &VA_DRIVER_CONTEXT_GLX(ctx)->vtable; \
226+ if (!vtable->va##func##GLX) \
227+ return VA_STATUS_ERROR_UNIMPLEMENTED; \
228+ status = vtable->va##func##GLX args; \
229+ } while (0)
230+
231+// Check VADisplay is valid
232+static inline int vaDisplayIsValid(VADisplay dpy)
233+{
234+ VADisplayContextP pDisplayContext = (VADisplayContextP)dpy;
235+
236+ return (pDisplayContext &&
237+ pDisplayContext->vaIsValid &&
238+ pDisplayContext->vaIsValid(pDisplayContext));
239+}
240+
241+// Check VASurfaceGLX is valid
242+static inline int vaSurfaceIsValid(VASurfaceGLXP pSurfaceGLX)
243+{
244+ return pSurfaceGLX && pSurfaceGLX->magic == VA_SURFACE_GLX_MAGIC;
245+}
246+
247+// Destroy VA/GLX display context
248+static void va_DisplayContextDestroy(VADisplayContextP pDisplayContext)
249+{
250+ VADisplayContextGLXP pDisplayContextGLX;
251+ VADriverContextP pDriverContext;
252+ VADriverContextGLXP pDriverContextGLX;
253+
254+ if (!pDisplayContext)
255+ return;
256+
257+ pDriverContext = pDisplayContext->pDriverContext;
258+ pDriverContextGLX = pDriverContext->glx;
259+ if (pDriverContextGLX) {
260+ free(pDriverContextGLX);
261+ pDriverContext->glx = NULL;
262+ }
263+
264+ pDisplayContextGLX = pDisplayContext->opaque;
265+ if (pDisplayContextGLX) {
266+ if (pDisplayContextGLX->vaDestroy)
267+ pDisplayContextGLX->vaDestroy(pDisplayContext);
268+ free(pDisplayContextGLX);
269+ pDisplayContext->opaque = NULL;
270+ }
271+}
272+
273+// Return a suitable VADisplay for VA API
274+VADisplay vaGetDisplayGLX(Display *native_dpy)
275+{
276+ VADisplay dpy = NULL;
277+ VADisplayContextP pDisplayContext = NULL;
278+ VADisplayContextGLXP pDisplayContextGLX = NULL;
279+ VADriverContextP pDriverContext;
280+ VADriverContextGLXP pDriverContextGLX = NULL;
281+
282+ dpy = vaGetDisplay(native_dpy);
283+ if (!dpy)
284+ return NULL;
285+ pDisplayContext = (VADisplayContextP)dpy;
286+ pDriverContext = pDisplayContext->pDriverContext;
287+
288+ pDisplayContextGLX = calloc(1, sizeof(*pDisplayContextGLX));
289+ if (!pDisplayContextGLX)
290+ goto error;
291+
292+ pDriverContextGLX = calloc(1, sizeof(*pDriverContextGLX));
293+ if (!pDriverContextGLX)
294+ goto error;
295+
296+ pDisplayContextGLX->vaDestroy = pDisplayContext->vaDestroy;
297+ pDisplayContext->vaDestroy = va_DisplayContextDestroy;
298+ pDisplayContext->opaque = pDisplayContextGLX;
299+ pDriverContext->glx = pDriverContextGLX;
300+ return dpy;
301+
302+error:
303+ free(pDriverContextGLX);
304+ free(pDisplayContextGLX);
305+ pDisplayContext->vaDestroy(pDisplayContext);
306+ return NULL;
307+}
308+
309+// Create a surface used for display to OpenGL
310+VAStatus vaCreateSurfaceGLX(
311+ VADisplay dpy,
312+ GLenum target,
313+ GLuint texture,
314+ void **gl_surface
315+)
316+{
317+ VADriverContextP ctx;
318+ VASurfaceGLXP pSurfaceGLX;
319+ VAStatus status;
320+
321+ /* Make sure it is a valid GL texture object */
322+ if (!glIsTexture(texture))
323+ return VA_STATUS_ERROR_INVALID_PARAMETER;
324+
325+ INIT_CONTEXT(ctx, dpy);
326+
327+ pSurfaceGLX = va_glx_create_surface(ctx, target, texture);
328+ if (!pSurfaceGLX)
329+ return VA_STATUS_ERROR_ALLOCATION_FAILED;
330+
331+ INVOKE(ctx, CreateSurface, (ctx, target, texture, &pSurfaceGLX->priv));
332+
333+ if (status != VA_STATUS_SUCCESS)
334+ va_glx_destroy_surface(ctx, &pSurfaceGLX);
335+
336+ *gl_surface = pSurfaceGLX;
337+ return status;
338+}
339+
340+// Destroy a VA/GLX surface
341+VAStatus vaDestroySurfaceGLX(
342+ VADisplay dpy,
343+ void *gl_surface
344+)
345+{
346+ VADriverContextP ctx;
347+ VASurfaceGLXP pSurfaceGLX;
348+ VAStatus status;
349+
350+ INIT_CONTEXT(ctx, dpy);
351+ INIT_SURFACE(pSurfaceGLX, gl_surface);
352+
353+ INVOKE(ctx, DestroySurface, (ctx, pSurfaceGLX));
354+
355+ free(pSurfaceGLX);
356+ return status;
357+}
358+
359+// Associate a VA surface to a VA/GLX surface
360+VAStatus vaAssociateSurfaceGLX(
361+ VADisplay dpy,
362+ void *gl_surface,
363+ VASurfaceID surface,
364+ unsigned int flags
365+)
366+{
367+ VADriverContextP ctx;
368+ VASurfaceGLXP pSurfaceGLX;
369+ VAStatus status;
370+
371+ INIT_CONTEXT(ctx, dpy);
372+ INIT_SURFACE(pSurfaceGLX, gl_surface);
373+
374+ INVOKE(ctx, AssociateSurface, (ctx, pSurfaceGLX, surface, flags));
375+
376+ if (status == VA_STATUS_SUCCESS)
377+ pSurfaceGLX->surface = surface;
378+
379+ return status;
380+}
381+
382+// Deassociate a VA surface from a VA/GLX surface
383+VAStatus vaDeassociateSurfaceGLX(
384+ VADisplay dpy,
385+ void *gl_surface
386+)
387+{
388+ VADriverContextP ctx;
389+ VASurfaceGLXP pSurfaceGLX;
390+ VAStatus status;
391+
392+ INIT_CONTEXT(ctx, dpy);
393+ INIT_SURFACE(pSurfaceGLX, gl_surface);
394+
395+ INVOKE(ctx, DeassociateSurface, (ctx, pSurfaceGLX));
396+
397+ if (status == VA_STATUS_SUCCESS)
398+ pSurfaceGLX->surface = VA_INVALID_SURFACE;
399+
400+ return status;
401+}
402+
403+// Synchronize a VA/GLX surface
404+VAStatus vaSyncSurfaceGLX(
405+ VADisplay dpy,
406+ void *gl_surface
407+)
408+{
409+ VADriverContextP ctx;
410+ VASurfaceGLXP pSurfaceGLX;
411+ VAStatus status;
412+
413+ INIT_CONTEXT(ctx, dpy);
414+ INIT_SURFACE(pSurfaceGLX, gl_surface);
415+
416+ INVOKE(ctx, SyncSurface, (ctx, pSurfaceGLX));
417+ return status;
418+}
419+
420+// Prepare VA/GLX surface for rendering
421+VAStatus vaBeginRenderSurfaceGLX(
422+ VADisplay dpy,
423+ void *gl_surface
424+)
425+{
426+ VADriverContextP ctx;
427+ VASurfaceGLXP pSurfaceGLX;
428+ VAStatus status;
429+
430+ INIT_CONTEXT(ctx, dpy);
431+ INIT_SURFACE(pSurfaceGLX, gl_surface);
432+
433+ INVOKE(ctx, BeginRenderSurface, (ctx, pSurfaceGLX));
434+ return status;
435+}
436+
437+// Notify the server that the VA/GLX surface is no longer used for rendering
438+VAStatus vaEndRenderSurfaceGLX(
439+ VADisplay dpy,
440+ void *gl_surface
441+)
442+{
443+ VADriverContextP ctx;
444+ VASurfaceGLXP pSurfaceGLX;
445+ VAStatus status;
446+
447+ INIT_CONTEXT(ctx, dpy);
448+ INIT_SURFACE(pSurfaceGLX, gl_surface);
449+
450+ INVOKE(ctx, EndRenderSurface, (ctx, pSurfaceGLX));
451+ return status;
452+}
453+
454+// Copy a VA surface to a VA/GLX surface
455+VAStatus vaCopySurfaceGLX(
456+ VADisplay dpy,
457+ void *gl_surface,
458+ VASurfaceID surface,
459+ unsigned int flags
460+)
461+{
462+ VADriverContextP ctx;
463+ VASurfaceGLXP pSurfaceGLX;
464+ VAStatus status;
465+
466+ INIT_CONTEXT(ctx, dpy);
467+ INIT_SURFACE(pSurfaceGLX, gl_surface);
468+
469+ INVOKE(ctx, CopySurface, (ctx, pSurfaceGLX, surface, flags));
470+ return status;
471+}
472diff --git a/src/glx/va_glx.h b/src/glx/va_glx.h
473new file mode 100644
474index 0000000..183ef3a
475--- /dev/null
476+++ b/src/glx/va_glx.h
477@@ -0,0 +1,217 @@
478+/*
479+ * Copyright (C) 2009 Splitted-Desktop Systems. All Rights Reserved.
480+ *
481+ * Permission is hereby granted, free of charge, to any person obtaining a
482+ * copy of this software and associated documentation files (the
483+ * "Software"), to deal in the Software without restriction, including
484+ * without limitation the rights to use, copy, modify, merge, publish,
485+ * distribute, sub license, and/or sell copies of the Software, and to
486+ * permit persons to whom the Software is furnished to do so, subject to
487+ * the following conditions:
488+ *
489+ * The above copyright notice and this permission notice (including the
490+ * next paragraph) shall be included in all copies or substantial portions
491+ * of the Software.
492+ *
493+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
494+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
495+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
496+ * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
497+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
498+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
499+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
500+ */
501+
502+#ifndef VA_GLX_H
503+#define VA_GLX_H
504+
505+#ifdef IN_LIBVA
506+#include "va.h"
507+#else
508+#include <va/va.h>
509+#endif
510+#include <GL/glx.h>
511+
512+#ifdef __cplusplus
513+extern "C" {
514+#endif
515+
516+/**
517+ * Return a suitable VADisplay for VA API
518+ *
519+ * @param[in] dpy the X11 display
520+ * @return a VADisplay
521+ */
522+VADisplay vaGetDisplayGLX(
523+ Display *dpy
524+);
525+
526+/**
527+ * Create a surface used for display to OpenGL
528+ *
529+ * The application shall maintain the live GLX context itself.
530+ * Implementations are free to use glXGetCurrentContext() and
531+ * glXGetCurrentDrawable() functions for internal purposes.
532+ *
533+ * @param[in] dpy the VA display
534+ * @param[in] target the GL target to which the texture needs to be bound
535+ * @param[in] texture the GL texture
536+ * @param[out] gl_surface the VA/GLX surface
537+ * @return VA_STATUS_SUCCESS if successful
538+ */
539+VAStatus vaCreateSurfaceGLX(
540+ VADisplay dpy,
541+ GLenum target,
542+ GLuint texture,
543+ void **gl_surface
544+);
545+
546+/**
547+ * Destroy a VA/GLX surface
548+ *
549+ * The application shall maintain the live GLX context itself.
550+ * Implementations are free to use glXGetCurrentContext() and
551+ * glXGetCurrentDrawable() functions for internal purposes.
552+ *
553+ * @param[in] dpy the VA display
554+ * @param[in] gl_surface the VA surface
555+ * @return VA_STATUS_SUCCESS if successful
556+ */
557+VAStatus vaDestroySurfaceGLX(
558+ VADisplay dpy,
559+ void *gl_surface
560+);
561+
562+/**
563+ * Associate a VA surface to a VA/GLX surface
564+ *
565+ * The association is live until vaDeassociateSurfaceGLX(),
566+ * vaCopySurfaceGLX() or the next call to vaBeginPicture() with the
567+ * specificed VA surface.
568+ *
569+ * The application shall maintain the live GLX context itself.
570+ * Implementations are free to use glXGetCurrentContext() and
571+ * glXGetCurrentDrawable() functions for internal purposes.
572+ *
573+ * @param[in] dpy the VA display
574+ * @param[in] gl_surface the VA/GLX surface
575+ * @param[in] surface the VA surface
576+ * @param[in] flags the PutSurface flags
577+ * @return VA_STATUS_SUCCESS if successful
578+ */
579+VAStatus vaAssociateSurfaceGLX(
580+ VADisplay dpy,
581+ void *gl_surface,
582+ VASurfaceID surface,
583+ unsigned int flags
584+);
585+
586+/**
587+ * Deassociate a VA surface from a VA/GLX surface
588+ *
589+ * The application shall maintain the live GLX context itself.
590+ * Implementations are free to use glXGetCurrentContext() and
591+ * glXGetCurrentDrawable() functions for internal purposes.
592+ *
593+ * @param[in] dpy the VA display
594+ * @param[in] gl_surface the VA surface
595+ * @return VA_STATUS_SUCCESS if successful
596+ */
597+VAStatus vaDeassociateSurfaceGLX(
598+ VADisplay dpy,
599+ void *gl_surface
600+);
601+
602+/**
603+ * Synchronize a VA/GLX surface
604+ *
605+ * This function blocks until all pending operations on the VA/GLX
606+ * surface have been completed.
607+ *
608+ * The application shall maintain the live GLX context itself.
609+ * Implementations are free to use glXGetCurrentContext() and
610+ * glXGetCurrentDrawable() functions for internal purposes.
611+ *
612+ * @param[in] dpy the VA display
613+ * @param[in] gl_surface the VA surface
614+ * @return VA_STATUS_SUCCESS if successful
615+ */
616+VAStatus vaSyncSurfaceGLX(
617+ VADisplay dpy,
618+ void *gl_surface
619+);
620+
621+/**
622+ * Prepare VA/GLX surface for rendering
623+ *
624+ * This function performs an implicit vaSyncSurfaceGLX().
625+ *
626+ * Implementations using the GLX texture-from-pixmap extension will
627+ * generally call glXBindTexImage() here.
628+ *
629+ * The application shall maintain the live GLX context itself.
630+ * Implementations are free to use glXGetCurrentContext() and
631+ * glXGetCurrentDrawable() functions for internal purposes.
632+ *
633+ * @param[in] dpy the VA display
634+ * @param[in] gl_surface the VA surface
635+ * @return VA_STATUS_SUCCESS if successful
636+ */
637+VAStatus vaBeginRenderSurfaceGLX(
638+ VADisplay dpy,
639+ void *gl_surface
640+);
641+
642+/**
643+ * Notify the server that the VA/GLX surface is no longer used for
644+ * rendering
645+ *
646+ * Implementations using the GLX texture-from-pixmap extension will
647+ * generally call glXReleaseTexImage() here.
648+ *
649+ * The application shall maintain the live GLX context itself.
650+ * Implementations are free to use glXGetCurrentContext() and
651+ * glXGetCurrentDrawable() functions for internal purposes.
652+ *
653+ * @param[in] dpy the VA display
654+ * @param[in] gl_surface the VA surface
655+ * @return VA_STATUS_SUCCESS if successful
656+ */
657+VAStatus vaEndRenderSurfaceGLX(
658+ VADisplay dpy,
659+ void *gl_surface
660+);
661+
662+/**
663+ * Copy a VA surface to a VA/GLX surface
664+ *
665+ * This function kills any association that was previously made with
666+ * vaAssociateSurfaceGLX() and will not return until the copy is
667+ * completed.
668+ *
669+ * Upon successful return, the underlying GL texture will contain the
670+ * complete pixels and no call to vaBeginRenderSurfaceGLX() or
671+ * vaEndRenderSurfaceGLX() is required.
672+ *
673+ * The application shall maintain the live GLX context itself.
674+ * Implementations are free to use glXGetCurrentContext() and
675+ * glXGetCurrentDrawable() functions for internal purposes.
676+ *
677+ * @param[in] dpy the VA display
678+ * @param[in] gl_surface the VA/GLX destination surface
679+ * @param[in] surface the VA source surface
680+ * @param[in] flags the PutSurface flags
681+ * @return VA_STATUS_SUCCESS if successful
682+ */
683+VAStatus vaCopySurfaceGLX(
684+ VADisplay dpy,
685+ void *gl_surface,
686+ VASurfaceID surface,
687+ unsigned int flags
688+);
689+
690+#ifdef __cplusplus
691+}
692+#endif
693+
694+#endif /* VA_GLX_H */
695diff --git a/src/glx/va_glx_impl.c b/src/glx/va_glx_impl.c
696new file mode 100644
697index 0000000..d4f9c1d
698--- /dev/null
699+++ b/src/glx/va_glx_impl.c
700@@ -0,0 +1,1168 @@
701+/*
702+ * Copyright (C) 2009 Splitted-Desktop Systems. All Rights Reserved.
703+ *
704+ * Permission is hereby granted, free of charge, to any person obtaining a
705+ * copy of this software and associated documentation files (the
706+ * "Software"), to deal in the Software without restriction, including
707+ * without limitation the rights to use, copy, modify, merge, publish,
708+ * distribute, sub license, and/or sell copies of the Software, and to
709+ * permit persons to whom the Software is furnished to do so, subject to
710+ * the following conditions:
711+ *
712+ * The above copyright notice and this permission notice (including the
713+ * next paragraph) shall be included in all copies or substantial portions
714+ * of the Software.
715+ *
716+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
717+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
718+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
719+ * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
720+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
721+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
722+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
723+ */
724+
725+#define _GNU_SOURCE 1
726+#include "va_glx_private.h"
727+#include "va_glx_impl.h"
728+#include <stdio.h>
729+#include <stdarg.h>
730+#include <string.h>
731+#include <assert.h>
732+#include <dlfcn.h>
733+
734+static void va_glx_error_message(const char *format, ...)
735+{
736+ va_list args;
737+ va_start(args, format);
738+ fprintf(stderr, "[%s] ", PACKAGE_NAME);
739+ vfprintf(stderr, format, args);
740+ va_end(args);
741+}
742+
743+// X error trap
744+static int x11_error_code = 0;
745+static int (*old_error_handler)(Display *, XErrorEvent *);
746+
747+static int error_handler(Display *dpy, XErrorEvent *error)
748+{
749+ x11_error_code = error->error_code;
750+ return 0;
751+}
752+
753+static void x11_trap_errors(void)
754+{
755+ x11_error_code = 0;
756+ old_error_handler = XSetErrorHandler(error_handler);
757+}
758+
759+static int x11_untrap_errors(void)
760+{
761+ XSetErrorHandler(old_error_handler);
762+ return x11_error_code;
763+}
764+
765+// Returns a string representation of an OpenGL error
766+static const char *gl_get_error_string(GLenum error)
767+{
768+ static const struct {
769+ GLenum val;
770+ const char *str;
771+ }
772+ gl_errors[] = {
773+ { GL_NO_ERROR, "no error" },
774+ { GL_INVALID_ENUM, "invalid enumerant" },
775+ { GL_INVALID_VALUE, "invalid value" },
776+ { GL_INVALID_OPERATION, "invalid operation" },
777+ { GL_STACK_OVERFLOW, "stack overflow" },
778+ { GL_STACK_UNDERFLOW, "stack underflow" },
779+ { GL_OUT_OF_MEMORY, "out of memory" },
780+#ifdef GL_INVALID_FRAMEBUFFER_OPERATION_EXT
781+ { GL_INVALID_FRAMEBUFFER_OPERATION_EXT, "invalid framebuffer operation" },
782+#endif
783+ { ~0, NULL }
784+ };
785+
786+ int i;
787+ for (i = 0; gl_errors[i].str; i++) {
788+ if (gl_errors[i].val == error)
789+ return gl_errors[i].str;
790+ }
791+ return "unknown";
792+}
793+
794+static inline int gl_do_check_error(int report)
795+{
796+ GLenum error;
797+ int is_error = 0;
798+ while ((error = glGetError()) != GL_NO_ERROR) {
799+ if (report)
800+ va_glx_error_message("glError: %s caught\n",
801+ gl_get_error_string(error));
802+ is_error = 1;
803+ }
804+ return is_error;
805+}
806+
807+static inline void gl_purge_errors(void)
808+{
809+ gl_do_check_error(0);
810+}
811+
812+static inline int gl_check_error(void)
813+{
814+ return gl_do_check_error(1);
815+}
816+
817+// glGetFloatv() wrapper
818+static int gl_get_current_color(float color[4])
819+{
820+ gl_purge_errors();
821+ glGetFloatv(GL_CURRENT_COLOR, color);
822+ if (gl_check_error())
823+ return -1;
824+ return 0;
825+}
826+
827+// glGetIntegerv() wrapper
828+static int gl_get_param(GLenum param, unsigned int *pval)
829+{
830+ GLint val;
831+
832+ gl_purge_errors();
833+ glGetIntegerv(param, &val);
834+ if (gl_check_error())
835+ return -1;
836+ if (pval)
837+ *pval = val;
838+ return 0;
839+}
840+
841+// glGetTexLevelParameteriv() wrapper
842+static int gl_get_texture_param(GLenum param, unsigned int *pval)
843+{
844+ GLint val;
845+
846+ gl_purge_errors();
847+ glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, param, &val);
848+ if (gl_check_error())
849+ return -1;
850+ if (pval)
851+ *pval = val;
852+ return 0;
853+}
854+
855+// Returns the OpenGL VTable
856+static inline VAOpenGLVTableP gl_get_vtable(VADriverContextP ctx)
857+{
858+ return &VA_DRIVER_CONTEXT_GLX(ctx)->gl_vtable;
859+}
860+
861+// Lookup for a GLX function
862+typedef void (*GLFuncPtr)(void);
863+typedef GLFuncPtr (*GLXGetProcAddressProc)(const char *);
864+
865+static GLFuncPtr get_proc_address_default(const char *name)
866+{
867+ return NULL;
868+}
869+
870+static GLXGetProcAddressProc get_proc_address_func(void)
871+{
872+ GLXGetProcAddressProc get_proc_func;
873+
874+ dlerror();
875+ get_proc_func = (GLXGetProcAddressProc)
876+ dlsym(RTLD_DEFAULT, "glXGetProcAddress");
877+ if (dlerror() == NULL)
878+ return get_proc_func;
879+
880+ get_proc_func = (GLXGetProcAddressProc)
881+ dlsym(RTLD_DEFAULT, "glXGetProcAddressARB");
882+ if (dlerror() == NULL)
883+ return get_proc_func;
884+
885+ return get_proc_address_default;
886+}
887+
888+static inline GLFuncPtr get_proc_address(const char *name)
889+{
890+ static GLXGetProcAddressProc get_proc_func = NULL;
891+ if (get_proc_func == NULL)
892+ get_proc_func = get_proc_address_func();
893+ return get_proc_func(name);
894+}
895+
896+// Check for GLX extensions (TFP, FBO)
897+static int check_extension(const char *name, const char *ext)
898+{
899+ const char *end;
900+ int name_len, n;
901+
902+ if (name == NULL || ext == NULL)
903+ return 0;
904+
905+ end = ext + strlen(ext);
906+ name_len = strlen(name);
907+ while (ext < end) {
908+ n = strcspn(ext, " ");
909+ if (n == name_len && strncmp(name, ext, n) == 0)
910+ return 1;
911+ ext += (n + 1);
912+ }
913+ return 0;
914+}
915+
916+static int check_tfp_extensions(VADriverContextP ctx)
917+{
918+ const char *gl_extensions;
919+ const char *glx_extensions;
920+
921+ gl_extensions = (const char *)glGetString(GL_EXTENSIONS);
922+ if (!check_extension("GL_ARB_texture_non_power_of_two", gl_extensions))
923+ return 0;
924+
925+ glx_extensions = glXQueryExtensionsString(ctx->x11_dpy, ctx->x11_screen);
926+ if (!check_extension("GLX_EXT_texture_from_pixmap", glx_extensions))
927+ return 0;
928+ return 1;
929+}
930+
931+static int check_fbo_extensions(VADriverContextP ctx)
932+{
933+ const char *gl_extensions;
934+
935+ gl_extensions = (const char *)glGetString(GL_EXTENSIONS);
936+ if (!check_extension("GL_ARB_framebuffer_object", gl_extensions))
937+ return 0;
938+ if (!check_extension("GL_EXT_framebuffer_object", gl_extensions))
939+ return 0;
940+ return 1;
941+}
942+
943+// Load GLX extensions
944+static int load_tfp_extensions(VADriverContextP ctx)
945+{
946+ VAOpenGLVTableP pOpenGLVTable = gl_get_vtable(ctx);
947+
948+ pOpenGLVTable->glx_bind_tex_image = (PFNGLXBINDTEXIMAGEEXTPROC)
949+ get_proc_address("glXBindTexImageEXT");
950+ if (pOpenGLVTable->glx_bind_tex_image == NULL)
951+ return 0;
952+ pOpenGLVTable->glx_release_tex_image = (PFNGLXRELEASETEXIMAGEEXTPROC)
953+ get_proc_address("glXReleaseTexImageEXT");
954+ if (pOpenGLVTable->glx_release_tex_image == NULL)
955+ return 0;
956+ return 1;
957+}
958+
959+static int load_fbo_extensions(VADriverContextP ctx)
960+{
961+ VAOpenGLVTableP pOpenGLVTable = gl_get_vtable(ctx);
962+
963+ pOpenGLVTable->gl_gen_framebuffers = (PFNGLGENFRAMEBUFFERSEXTPROC)
964+ get_proc_address("glGenFramebuffersEXT");
965+ if (pOpenGLVTable->gl_gen_framebuffers == NULL)
966+ return 0;
967+ pOpenGLVTable->gl_delete_framebuffers = (PFNGLDELETEFRAMEBUFFERSEXTPROC)
968+ get_proc_address("glDeleteFramebuffersEXT");
969+ if (pOpenGLVTable->gl_delete_framebuffers == NULL)
970+ return 0;
971+ pOpenGLVTable->gl_bind_framebuffer = (PFNGLBINDFRAMEBUFFEREXTPROC)
972+ get_proc_address("glBindFramebufferEXT");
973+ if (pOpenGLVTable->gl_bind_framebuffer == NULL)
974+ return 0;
975+ pOpenGLVTable->gl_gen_renderbuffers = (PFNGLGENRENDERBUFFERSEXTPROC)
976+ get_proc_address("glGenRenderbuffersEXT");
977+ if (pOpenGLVTable->gl_gen_renderbuffers == NULL)
978+ return 0;
979+ pOpenGLVTable->gl_delete_renderbuffers = (PFNGLDELETERENDERBUFFERSEXTPROC)
980+ get_proc_address("glDeleteRenderbuffersEXT");
981+ if (pOpenGLVTable->gl_delete_renderbuffers == NULL)
982+ return 0;
983+ pOpenGLVTable->gl_bind_renderbuffer = (PFNGLBINDRENDERBUFFEREXTPROC)
984+ get_proc_address("glBindRenderbufferEXT");
985+ if (pOpenGLVTable->gl_bind_renderbuffer == NULL)
986+ return 0;
987+ pOpenGLVTable->gl_renderbuffer_storage = (PFNGLRENDERBUFFERSTORAGEEXTPROC)
988+ get_proc_address("glRenderbufferStorageEXT");
989+ if (pOpenGLVTable->gl_renderbuffer_storage == NULL)
990+ return 0;
991+ pOpenGLVTable->gl_framebuffer_renderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)
992+ get_proc_address("glFramebufferRenderbufferEXT");
993+ if (pOpenGLVTable->gl_framebuffer_renderbuffer == NULL)
994+ return 0;
995+ pOpenGLVTable->gl_framebuffer_texture_2d = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)
996+ get_proc_address("glFramebufferTexture2DEXT");
997+ if (pOpenGLVTable->gl_framebuffer_texture_2d == NULL)
998+ return 0;
999+ pOpenGLVTable->gl_check_framebuffer_status = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)
1000+ get_proc_address("glCheckFramebufferStatusEXT");
1001+ if (pOpenGLVTable->gl_check_framebuffer_status == NULL)
1002+ return 0;
1003+ return 1;
1004+}
1005+
1006+
1007+/* ========================================================================= */
1008+/* === VA/GLX helpers === */
1009+/* ========================================================================= */
1010+
1011+// OpenGL texture state
1012+typedef struct OpenGLTextureState *OpenGLTextureStateP;
1013+
1014+struct OpenGLTextureState {
1015+ int was_enabled;
1016+ int was_bound;
1017+ GLenum target;
1018+ GLuint old_texture;
1019+};
1020+
1021+// Bind texture, preserve previous texture state
1022+static int bind_texture(OpenGLTextureStateP ts, GLenum target, GLuint texture)
1023+{
1024+ ts->target = target;
1025+ ts->old_texture = 0;
1026+ ts->was_bound = 0;
1027+ ts->was_enabled = glIsEnabled(target);
1028+ if (!ts->was_enabled)
1029+ glEnable(target);
1030+
1031+ GLenum texture_binding;
1032+ switch (target) {
1033+ case GL_TEXTURE_1D:
1034+ texture_binding = GL_TEXTURE_BINDING_1D;
1035+ break;
1036+ case GL_TEXTURE_2D:
1037+ texture_binding = GL_TEXTURE_BINDING_2D;
1038+ break;
1039+ case GL_TEXTURE_3D:
1040+ texture_binding = GL_TEXTURE_BINDING_3D;
1041+ break;
1042+ case GL_TEXTURE_RECTANGLE_ARB:
1043+ texture_binding = GL_TEXTURE_BINDING_RECTANGLE_ARB;
1044+ break;
1045+ default:
1046+ assert(!target);
1047+ return -1;
1048+ }
1049+
1050+ if (ts->was_enabled && gl_get_param(texture_binding, &ts->old_texture) < 0)
1051+ return -1;
1052+
1053+ ts->was_bound = texture == ts->old_texture;
1054+ if (!ts->was_bound) {
1055+ gl_purge_errors();
1056+ glBindTexture(target, texture);
1057+ if (gl_check_error())
1058+ return -1;
1059+ }
1060+ return 0;
1061+}
1062+
1063+// Unbind texture, restore previous texture state
1064+static void unbind_texture(OpenGLTextureStateP ts)
1065+{
1066+ if (!ts->was_bound && ts->old_texture)
1067+ glBindTexture(ts->target, ts->old_texture);
1068+ if (!ts->was_enabled)
1069+ glDisable(ts->target);
1070+}
1071+
1072+// Create Pixmaps for GLX texture-from-pixmap extension
1073+static int create_tfp_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX)
1074+{
1075+ const unsigned int width = pSurfaceGLX->width;
1076+ const unsigned int height = pSurfaceGLX->height;
1077+ Pixmap pixmap = None;
1078+ GLXFBConfig *fbconfig = NULL;
1079+ GLXPixmap glx_pixmap = None;
1080+ Window root_window;
1081+ XWindowAttributes wattr;
1082+ int *attrib;
1083+ int n_fbconfig_attribs, x, y, status;
1084+ unsigned int border_width, depth, dummy;
1085+
1086+ root_window = RootWindow(ctx->x11_dpy, ctx->x11_screen);
1087+ XGetWindowAttributes(ctx->x11_dpy, root_window, &wattr);
1088+ pixmap = XCreatePixmap(ctx->x11_dpy, root_window,
1089+ width, height, wattr.depth);
1090+ if (!pixmap)
1091+ return -1;
1092+ pSurfaceGLX->pixmap = pixmap;
1093+
1094+ x11_trap_errors();
1095+ status = XGetGeometry(ctx->x11_dpy,
1096+ (Drawable)pixmap,
1097+ &root_window,
1098+ &x,
1099+ &y,
1100+ &dummy,
1101+ &dummy,
1102+ &border_width,
1103+ &depth);
1104+ if (x11_untrap_errors() != 0 || status == 0)
1105+ return -1;
1106+ if (depth != 24 && depth != 32)
1107+ return -1;
1108+
1109+ int fbconfig_attribs[32] = {
1110+ GLX_DRAWABLE_TYPE, GLX_PIXMAP_BIT,
1111+ GLX_DOUBLEBUFFER, GL_TRUE,
1112+ GLX_RENDER_TYPE, GLX_RGBA_BIT,
1113+ GLX_X_RENDERABLE, GL_TRUE,
1114+ GLX_Y_INVERTED_EXT, GL_TRUE,
1115+ GLX_RED_SIZE, 8,
1116+ GLX_GREEN_SIZE, 8,
1117+ GLX_BLUE_SIZE, 8,
1118+ GL_NONE,
1119+ };
1120+ for (attrib = fbconfig_attribs; *attrib != GL_NONE; attrib += 2)
1121+ ;
1122+ *attrib++ = GLX_DEPTH_SIZE; *attrib++ = depth;
1123+ if (depth == 32) {
1124+ *attrib++ = GLX_ALPHA_SIZE; *attrib++ = 8;
1125+ *attrib++ = GLX_BIND_TO_TEXTURE_RGBA_EXT; *attrib++ = GL_TRUE;
1126+ }
1127+ else {
1128+ *attrib++ = GLX_BIND_TO_TEXTURE_RGB_EXT; *attrib++ = GL_TRUE;
1129+ }
1130+ *attrib++ = GL_NONE;
1131+
1132+ fbconfig = glXChooseFBConfig(ctx->x11_dpy, ctx->x11_screen, fbconfig_attribs, &n_fbconfig_attribs);
1133+ if (fbconfig == NULL)
1134+ return -1;
1135+
1136+ int pixmap_attribs[10] = {
1137+ GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT,
1138+ GLX_MIPMAP_TEXTURE_EXT, GL_FALSE,
1139+ GL_NONE,
1140+ };
1141+ for (attrib = pixmap_attribs; *attrib != GL_NONE; attrib += 2)
1142+ ;
1143+ *attrib++ = GLX_TEXTURE_FORMAT_EXT;
1144+ if (depth == 32)
1145+ *attrib++ = GLX_TEXTURE_FORMAT_RGBA_EXT;
1146+ else
1147+ *attrib++ = GLX_TEXTURE_FORMAT_RGB_EXT;
1148+ *attrib++ = GL_NONE;
1149+
1150+ x11_trap_errors();
1151+ glx_pixmap = glXCreatePixmap(ctx->x11_dpy,
1152+ fbconfig[0],
1153+ pixmap,
1154+ pixmap_attribs);
1155+ free(fbconfig);
1156+ if (x11_untrap_errors() != 0)
1157+ return -1;
1158+ pSurfaceGLX->glx_pixmap = glx_pixmap;
1159+ return 0;
1160+}
1161+
1162+// Destroy Pixmaps used for TFP
1163+static void destroy_tfp_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX)
1164+{
1165+ if (pSurfaceGLX->glx_pixmap) {
1166+ glXDestroyPixmap(ctx->x11_dpy, pSurfaceGLX->glx_pixmap);
1167+ pSurfaceGLX->glx_pixmap = None;
1168+ }
1169+
1170+ if (pSurfaceGLX->pixmap) {
1171+ XFreePixmap(ctx->x11_dpy, pSurfaceGLX->pixmap);
1172+ pSurfaceGLX->pixmap = None;
1173+ }
1174+}
1175+
1176+// Bind GLX Pixmap to texture
1177+static int bind_pixmap(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX)
1178+{
1179+ VAOpenGLVTableP pOpenGLVTable = gl_get_vtable(ctx);
1180+
1181+ if (pSurfaceGLX->is_bound)
1182+ return 0;
1183+
1184+ x11_trap_errors();
1185+ pOpenGLVTable->glx_bind_tex_image(ctx->x11_dpy, pSurfaceGLX->glx_pixmap,
1186+ GLX_FRONT_LEFT_EXT, NULL);
1187+ XSync(ctx->x11_dpy, False);
1188+ if (x11_untrap_errors() != 0) {
1189+ va_glx_error_message("failed to bind pixmap\n");
1190+ return -1;
1191+ }
1192+
1193+ pSurfaceGLX->is_bound = 1;
1194+ return 0;
1195+}
1196+
1197+// Release GLX Pixmap from texture
1198+static int unbind_pixmap(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX)
1199+{
1200+ VAOpenGLVTableP pOpenGLVTable = gl_get_vtable(ctx);
1201+
1202+ if (!pSurfaceGLX->is_bound)
1203+ return 0;
1204+
1205+ x11_trap_errors();
1206+ pOpenGLVTable->glx_release_tex_image(ctx->x11_dpy, pSurfaceGLX->glx_pixmap,
1207+ GLX_FRONT_LEFT_EXT);
1208+ XSync(ctx->x11_dpy, False);
1209+ if (x11_untrap_errors() != 0) {
1210+ va_glx_error_message("failed to release pixmap\n");
1211+ return -1;
1212+ }
1213+
1214+ pSurfaceGLX->is_bound = 0;
1215+ return 0;
1216+}
1217+
1218+// Render GLX Pixmap to texture
1219+static void render_pixmap(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX)
1220+{
1221+ const unsigned int w = pSurfaceGLX->width;
1222+ const unsigned int h = pSurfaceGLX->height;
1223+ float old_color[4];
1224+
1225+ gl_get_current_color(old_color);
1226+ glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
1227+ glBegin(GL_QUADS);
1228+ {
1229+ glTexCoord2f(0.0f, 0.0f); glVertex2i(0, 0);
1230+ glTexCoord2f(0.0f, 1.0f); glVertex2i(0, h);
1231+ glTexCoord2f(1.0f, 1.0f); glVertex2i(w, h);
1232+ glTexCoord2f(1.0f, 0.0f); glVertex2i(w, 0);
1233+ }
1234+ glEnd();
1235+ glColor4fv(old_color);
1236+}
1237+
1238+// Create offscreen surface
1239+static int create_fbo_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX)
1240+{
1241+ VAOpenGLVTableP pOpenGLVTable = gl_get_vtable(ctx);
1242+ const GLenum texture = pSurfaceGLX->texture;
1243+ const unsigned int texture_width = pSurfaceGLX->width;
1244+ const unsigned int texture_height = pSurfaceGLX->height;
1245+ GLuint fbo, fbo_buffer, fbo_texture;
1246+ GLenum status;
1247+
1248+ glGenTextures(1, &fbo_texture);
1249+ glBindTexture(GL_TEXTURE_2D, fbo_texture);
1250+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1251+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1252+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1253+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1254+ glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
1255+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture_width, texture_height, 0,
1256+ GL_BGRA, GL_UNSIGNED_BYTE, NULL);
1257+
1258+ pOpenGLVTable->gl_gen_framebuffers(1, &fbo);
1259+ pOpenGLVTable->gl_bind_framebuffer(GL_FRAMEBUFFER_EXT, fbo);
1260+ pOpenGLVTable->gl_gen_renderbuffers(1, &fbo_buffer);
1261+ pOpenGLVTable->gl_bind_renderbuffer(GL_RENDERBUFFER_EXT, fbo_buffer);
1262+
1263+ glBindTexture(GL_TEXTURE_2D, texture);
1264+ pOpenGLVTable->gl_framebuffer_texture_2d(GL_FRAMEBUFFER_EXT,
1265+ GL_COLOR_ATTACHMENT0_EXT,
1266+ GL_TEXTURE_2D, texture, 0);
1267+
1268+ status = pOpenGLVTable->gl_check_framebuffer_status(GL_DRAW_FRAMEBUFFER_EXT);
1269+ pOpenGLVTable->gl_bind_framebuffer(GL_FRAMEBUFFER_EXT, 0);
1270+ if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
1271+ return -1;
1272+
1273+ pSurfaceGLX->fbo = fbo;
1274+ pSurfaceGLX->fbo_buffer = fbo_buffer;
1275+ pSurfaceGLX->fbo_texture = fbo_texture;
1276+ return 0;
1277+}
1278+
1279+// Destroy offscreen surface
1280+static void destroy_fbo_surface(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX)
1281+{
1282+ VAOpenGLVTableP pOpenGLVTable = gl_get_vtable(ctx);
1283+
1284+ if (pSurfaceGLX->fbo_texture) {
1285+ glDeleteTextures(1, &pSurfaceGLX->fbo_texture);
1286+ pSurfaceGLX->fbo_texture = 0;
1287+ }
1288+
1289+ if (pSurfaceGLX->fbo_buffer) {
1290+ pOpenGLVTable->gl_delete_renderbuffers(1, &pSurfaceGLX->fbo_buffer);
1291+ pSurfaceGLX->fbo_buffer = 0;
1292+ }
1293+
1294+ if (pSurfaceGLX->fbo) {
1295+ pOpenGLVTable->gl_delete_framebuffers(1, &pSurfaceGLX->fbo);
1296+ pSurfaceGLX->fbo = 0;
1297+ }
1298+}
1299+
1300+// Setup matrices to match the FBO texture dimensions
1301+static void fbo_enter(VADriverContextP ctx, VASurfaceGLXP pSurfaceGLX)
1302+{
1303+ VAOpenGLVTableP pOpenGLVTable = gl_get_vtable(ctx);
1304+ const unsigned int width = pSurfaceGLX->width;
1305+ const unsigned int height = pSurfaceGLX->height;
1306+
1307+ pOpenGLVTable->gl_bind_framebuffer(GL_FRAMEBUFFER_EXT, pSurfaceGLX->fbo);
1308+ glPushAttrib(GL_VIEWPORT_BIT);
1309+ glMatrixMode(GL_PROJECTION);
1310+ glPushMatrix();
1311+ glLoadIdentity();
1312+ glMatrixMode(GL_MODELVIEW);
1313+ glPushMatrix();
1314+ glLoadIdentity();
1315+ glViewport(0, 0, width, height);
1316+ glTranslatef(-1.0f, -1.0f, 0.0f);
1317+ glScalef(2.0f / width, 2.0f / height, 1.0f);
1318+
1319+ glBindTexture(GL_TEXTURE_2D, pSurfaceGLX->fbo_texture);
1320+}
1321+
1322+// Restore original OpenGL matrices
1323+static void fbo_leave(VADriverContextP ctx)
1324+{
1325+ VAOpenGLVTableP pOpenGLVTable = gl_get_vtable(ctx);
1326+
1327+ glPopAttrib();
1328+ glMatrixMode(GL_PROJECTION);
1329+ glPopMatrix();
1330+ glMatrixMode(GL_MODELVIEW);
1331+ glPopMatrix();
1332+ pOpenGLVTable->gl_bind_framebuffer(GL_FRAMEBUFFER_EXT, 0);
1333+}
1334+
1335+// Create VA/GLX surface
1336+VASurfaceGLXP
1337+va_glx_create_surface(VADriverContextP ctx, GLenum target, GLuint texture)
1338+{
1339+ VADriverContextGLXP pDriverContextGLX = VA_DRIVER_CONTEXT_GLX(ctx);
1340+ VASurfaceGLXP pSurfaceGLX;
1341+ unsigned int internal_format, border_width, width, height;
1342+ int is_error = 1;
1343+
1344+ /* Make sure binding succeeds, if texture was not already bound */
1345+ struct OpenGLTextureState ts;
1346+ if (bind_texture(&ts, target, texture) < 0)
1347+ goto end;
1348+
1349+ pSurfaceGLX = malloc(sizeof(*pSurfaceGLX));
1350+ if (!pSurfaceGLX)
1351+ goto end;
1352+
1353+ pSurfaceGLX->magic = VA_SURFACE_GLX_MAGIC;
1354+ pSurfaceGLX->target = target;
1355+ pSurfaceGLX->texture = texture;
1356+ pSurfaceGLX->surface = VA_INVALID_SURFACE;
1357+ pSurfaceGLX->is_bound = 0;
1358+ pSurfaceGLX->pixmap = None;
1359+ pSurfaceGLX->glx_pixmap = None;
1360+ pSurfaceGLX->fbo = 0;
1361+ pSurfaceGLX->fbo_buffer = 0;
1362+ pSurfaceGLX->fbo_texture = 0;
1363+ pSurfaceGLX->priv = NULL;
1364+
1365+ /* XXX: we don't support other textures than RGBA */
1366+ if (gl_get_texture_param(GL_TEXTURE_INTERNAL_FORMAT, &internal_format) < 0)
1367+ goto end;
1368+ if (internal_format != GL_RGBA)
1369+ goto end;
1370+
1371+ /* Check texture dimensions */
1372+ if (gl_get_texture_param(GL_TEXTURE_BORDER, &border_width) < 0)
1373+ goto end;
1374+ if (gl_get_texture_param(GL_TEXTURE_WIDTH, &width) < 0)
1375+ goto end;
1376+ if (gl_get_texture_param(GL_TEXTURE_HEIGHT, &height) < 0)
1377+ goto end;
1378+
1379+ width -= 2 * border_width;
1380+ height -= 2 * border_width;
1381+ if (width == 0 || height == 0)
1382+ goto end;
1383+
1384+ pSurfaceGLX->width = width;
1385+ pSurfaceGLX->height = height;
1386+
1387+ /* Create Pixmaps for TFP */
1388+ if (pDriverContextGLX->use_tfp) {
1389+ if (create_tfp_surface(ctx, pSurfaceGLX) < 0)
1390+ goto end;
1391+ }
1392+
1393+ /* Create Pixmaps for FBO */
1394+ if (pDriverContextGLX->use_fbo) {
1395+ if (create_fbo_surface(ctx, pSurfaceGLX) < 0)
1396+ goto end;
1397+ }
1398+
1399+ is_error = 0;
1400+end:
1401+ if (is_error && pSurfaceGLX)
1402+ va_glx_destroy_surface(ctx, &pSurfaceGLX);
1403+
1404+ unbind_texture(&ts);
1405+ return pSurfaceGLX;
1406+}
1407+
1408+// Destroy VA/GLX surface
1409+void va_glx_destroy_surface(VADriverContextP ctx, VASurfaceGLXP *ppSurfaceGLX)
1410+{
1411+ VASurfaceGLXP pSurfaceGLX = *ppSurfaceGLX;
1412+
1413+ unbind_pixmap(ctx, pSurfaceGLX);
1414+ destroy_fbo_surface(ctx, pSurfaceGLX);
1415+ destroy_tfp_surface(ctx, pSurfaceGLX);
1416+
1417+ free(pSurfaceGLX);
1418+ *ppSurfaceGLX = NULL;
1419+}
1420+
1421+
1422+/* ========================================================================= */
1423+/* === VA/GLX implementation from the driver (fordward calls) === */
1424+/* ========================================================================= */
1425+
1426+#define INVOKE(ctx, func, args) do { \
1427+ VADriverVTableGLXP vtable = &(ctx)->vtable.glx; \
1428+ if (!vtable->va##func##GLX) \
1429+ return VA_STATUS_ERROR_UNIMPLEMENTED; \
1430+ \
1431+ VAStatus status = vtable->va##func##GLX args; \
1432+ if (status != VA_STATUS_SUCCESS) \
1433+ return status; \
1434+ } while (0)
1435+
1436+static VAStatus
1437+vaCreateSurfaceGLX_impl_driver(
1438+ VADriverContextP ctx,
1439+ GLenum target,
1440+ GLuint texture,
1441+ void **gl_surface
1442+)
1443+{
1444+ INVOKE(ctx, CreateSurface, (ctx, target, texture, gl_surface));
1445+ return VA_STATUS_SUCCESS;
1446+}
1447+
1448+static VAStatus
1449+vaDestroySurfaceGLX_impl_driver(VADriverContextP ctx, void *gl_surface)
1450+{
1451+ VASurfaceGLXP pSurfaceGLX = gl_surface;
1452+
1453+ INVOKE(ctx, DestroySurface, (ctx, pSurfaceGLX->priv));
1454+ return VA_STATUS_SUCCESS;
1455+}
1456+
1457+static VAStatus
1458+vaAssociateSurfaceGLX_impl_driver(
1459+ VADriverContextP ctx,
1460+ void *gl_surface,
1461+ VASurfaceID surface,
1462+ unsigned int flags
1463+)
1464+{
1465+ VASurfaceGLXP pSurfaceGLX = gl_surface;
1466+
1467+ INVOKE(ctx, AssociateSurface, (ctx, pSurfaceGLX->priv, surface, flags));
1468+ return VA_STATUS_SUCCESS;
1469+}
1470+
1471+static VAStatus
1472+vaDeassociateSurfaceGLX_impl_driver(VADriverContextP ctx, void *gl_surface)
1473+{
1474+ VASurfaceGLXP pSurfaceGLX = gl_surface;
1475+
1476+ INVOKE(ctx, DeassociateSurface, (ctx, pSurfaceGLX->priv));
1477+ return VA_STATUS_SUCCESS;
1478+}
1479+
1480+static VAStatus
1481+vaSyncSurfaceGLX_impl_driver(VADriverContextP ctx, void *gl_surface)
1482+{
1483+ VASurfaceGLXP pSurfaceGLX = gl_surface;
1484+
1485+ INVOKE(ctx, SyncSurface, (ctx, pSurfaceGLX->priv));
1486+ return VA_STATUS_SUCCESS;
1487+}
1488+
1489+static VAStatus
1490+vaBeginRenderSurfaceGLX_impl_driver(VADriverContextP ctx, void *gl_surface)
1491+{
1492+ VASurfaceGLXP pSurfaceGLX = gl_surface;
1493+
1494+ INVOKE(ctx, BeginRenderSurface, (ctx, pSurfaceGLX->priv));
1495+ return VA_STATUS_SUCCESS;
1496+}
1497+
1498+static VAStatus
1499+vaEndRenderSurfaceGLX_impl_driver(VADriverContextP ctx, void *gl_surface)
1500+{
1501+ VASurfaceGLXP pSurfaceGLX = gl_surface;
1502+
1503+ INVOKE(ctx, EndRenderSurface, (ctx, pSurfaceGLX->priv));
1504+ return VA_STATUS_SUCCESS;
1505+}
1506+
1507+static VAStatus
1508+vaCopySurfaceGLX_impl_driver(
1509+ VADriverContextP ctx,
1510+ void *gl_surface,
1511+ VASurfaceID surface,
1512+ unsigned int flags
1513+)
1514+{
1515+ VASurfaceGLXP pSurfaceGLX = gl_surface;
1516+
1517+ INVOKE(ctx, CopySurface, (ctx, pSurfaceGLX->priv, surface, flags));
1518+ return VA_STATUS_SUCCESS;
1519+}
1520+
1521+#undef INVOKE
1522+
1523+
1524+/* ========================================================================= */
1525+/* === VA/GLX implementation from libVA (generic and suboptimal path) === */
1526+/* ========================================================================= */
1527+
1528+static VAStatus
1529+vaCreateSurfaceGLX_impl_libva(
1530+ VADriverContextP ctx,
1531+ GLenum target,
1532+ GLuint texture,
1533+ void **gl_surface
1534+)
1535+{
1536+ VADriverContextGLXP pDriverContextGLX = VA_DRIVER_CONTEXT_GLX(ctx);
1537+
1538+ if (!pDriverContextGLX->use_tfp)
1539+ return VA_STATUS_ERROR_UNIMPLEMENTED;
1540+
1541+ *gl_surface = NULL;
1542+ return VA_STATUS_SUCCESS;
1543+}
1544+
1545+static VAStatus
1546+vaDestroySurfaceGLX_impl_libva(VADriverContextP ctx, void *gl_surface)
1547+{
1548+ VADriverContextGLXP pDriverContextGLX = VA_DRIVER_CONTEXT_GLX(ctx);
1549+
1550+ if (!pDriverContextGLX->use_tfp)
1551+ return VA_STATUS_ERROR_UNIMPLEMENTED;
1552+
1553+ return VA_STATUS_SUCCESS;
1554+}
1555+
1556+static VAStatus
1557+vaAssociateSurfaceGLX_impl_libva(
1558+ VADriverContextP ctx,
1559+ void *gl_surface,
1560+ VASurfaceID surface,
1561+ unsigned int flags
1562+)
1563+{
1564+ VADriverContextGLXP pDriverContextGLX = VA_DRIVER_CONTEXT_GLX(ctx);
1565+ VADriverVTableGLXP vtable = &pDriverContextGLX->vtable;
1566+ VASurfaceGLXP pSurfaceGLX = gl_surface;
1567+ VAStatus status;
1568+
1569+ if (!pDriverContextGLX->use_tfp)
1570+ return VA_STATUS_ERROR_UNIMPLEMENTED;
1571+
1572+ /* XXX: only support VA_FRAME_PICTURE */
1573+ if (flags != VA_FRAME_PICTURE)
1574+ return VA_STATUS_ERROR_FLAG_NOT_SUPPORTED;
1575+
1576+ /* XXX: optimise case where we are associating the same VA surface
1577+ as before an no changed occurred to it */
1578+ status = vtable->vaDeassociateSurfaceGLX(ctx, gl_surface);
1579+ if (status != VA_STATUS_SUCCESS)
1580+ return status;
1581+
1582+ x11_trap_errors();
1583+ status = ctx->vtable.vaPutSurface(ctx,
1584+ surface,
1585+ pSurfaceGLX->pixmap,
1586+ 0, 0,
1587+ pSurfaceGLX->width,
1588+ pSurfaceGLX->height,
1589+ 0, 0,
1590+ pSurfaceGLX->width,
1591+ pSurfaceGLX->height,
1592+ NULL, 0,
1593+ flags);
1594+ XSync(ctx->x11_dpy, False);
1595+ if (x11_untrap_errors() != 0)
1596+ return VA_STATUS_ERROR_OPERATION_FAILED;
1597+ if (status != VA_STATUS_SUCCESS)
1598+ return status;
1599+
1600+ pSurfaceGLX->surface = surface;
1601+ return VA_STATUS_SUCCESS;
1602+}
1603+
1604+static VAStatus
1605+vaDeassociateSurfaceGLX_impl_libva(VADriverContextP ctx, void *gl_surface)
1606+{
1607+ VADriverContextGLXP pDriverContextGLX = VA_DRIVER_CONTEXT_GLX(ctx);
1608+ VASurfaceGLXP pSurfaceGLX = gl_surface;
1609+
1610+ if (!pDriverContextGLX->use_tfp)
1611+ return VA_STATUS_ERROR_UNIMPLEMENTED;
1612+
1613+ if (unbind_pixmap(ctx, pSurfaceGLX) < 0)
1614+ return VA_STATUS_ERROR_OPERATION_FAILED;
1615+
1616+ pSurfaceGLX->surface = VA_INVALID_SURFACE;
1617+ return VA_STATUS_SUCCESS;
1618+}
1619+
1620+static VAStatus
1621+vaSyncSurfaceGLX_impl_libva(VADriverContextP ctx, void *gl_surface)
1622+{
1623+ VADriverContextGLXP pDriverContextGLX = VA_DRIVER_CONTEXT_GLX(ctx);
1624+ VASurfaceGLXP pSurfaceGLX = gl_surface;
1625+
1626+ if (!pDriverContextGLX->use_tfp)
1627+ return VA_STATUS_ERROR_UNIMPLEMENTED;
1628+
1629+ if (pSurfaceGLX->surface == VA_INVALID_SURFACE)
1630+ return VA_STATUS_ERROR_INVALID_SURFACE;
1631+
1632+ return ctx->vtable.vaSyncSurface(ctx, pSurfaceGLX->surface);
1633+}
1634+
1635+static VAStatus
1636+vaBeginRenderSurfaceGLX_impl_libva(VADriverContextP ctx, void *gl_surface)
1637+{
1638+ VADriverContextGLXP pDriverContextGLX = VA_DRIVER_CONTEXT_GLX(ctx);
1639+ VASurfaceGLXP pSurfaceGLX = gl_surface;
1640+ VAStatus status;
1641+
1642+ if (!pDriverContextGLX->use_tfp)
1643+ return VA_STATUS_ERROR_UNIMPLEMENTED;
1644+
1645+ status = vaSyncSurfaceGLX_impl_libva(ctx, gl_surface);
1646+ if (status != VA_STATUS_SUCCESS)
1647+ return status;
1648+
1649+ if (bind_pixmap(ctx, pSurfaceGLX) < 0)
1650+ return VA_STATUS_ERROR_OPERATION_FAILED;
1651+
1652+ return VA_STATUS_SUCCESS;
1653+}
1654+
1655+static VAStatus
1656+vaEndRenderSurfaceGLX_impl_libva(VADriverContextP ctx, void *gl_surface)
1657+{
1658+ VADriverContextGLXP pDriverContextGLX = VA_DRIVER_CONTEXT_GLX(ctx);
1659+ VASurfaceGLXP pSurfaceGLX = gl_surface;
1660+ VAStatus status;
1661+
1662+ if (!pDriverContextGLX->use_tfp)
1663+ return VA_STATUS_ERROR_UNIMPLEMENTED;
1664+
1665+ if (unbind_pixmap(ctx, pSurfaceGLX) < 0)
1666+ return VA_STATUS_ERROR_OPERATION_FAILED;
1667+
1668+ return VA_STATUS_SUCCESS;
1669+}
1670+
1671+static VAStatus
1672+vaCopySurfaceGLX_impl_libva(
1673+ VADriverContextP ctx,
1674+ void *gl_surface,
1675+ VASurfaceID surface,
1676+ unsigned int flags
1677+)
1678+{
1679+ VADriverContextGLXP pDriverContextGLX = VA_DRIVER_CONTEXT_GLX(ctx);
1680+ VADriverVTableGLXP vtable = &pDriverContextGLX->vtable;
1681+ VASurfaceGLXP pSurfaceGLX = gl_surface;
1682+ VAStatus status;
1683+
1684+ if (!pDriverContextGLX->use_fbo)
1685+ return VA_STATUS_ERROR_UNIMPLEMENTED;
1686+
1687+ /* XXX: only support VA_FRAME_PICTURE */
1688+ if (flags != VA_FRAME_PICTURE)
1689+ return VA_STATUS_ERROR_FLAG_NOT_SUPPORTED;
1690+
1691+ /* Associate VA surface */
1692+ status = vtable->vaAssociateSurfaceGLX(ctx, gl_surface, surface, flags);
1693+ if (status != VA_STATUS_SUCCESS)
1694+ return status;
1695+
1696+ /* Make sure binding succeeds, if texture was not already bound */
1697+ struct OpenGLTextureState ts;
1698+ if (bind_texture(&ts, pSurfaceGLX->target, pSurfaceGLX->texture) < 0)
1699+ return VA_STATUS_ERROR_OPERATION_FAILED;
1700+
1701+ /* Render to FBO */
1702+ fbo_enter(ctx, pSurfaceGLX);
1703+ status = vtable->vaBeginRenderSurfaceGLX(ctx, gl_surface);
1704+ if (status == VA_STATUS_SUCCESS) {
1705+ render_pixmap(ctx, pSurfaceGLX);
1706+ status = vtable->vaEndRenderSurfaceGLX(ctx, gl_surface);
1707+ }
1708+ fbo_leave(ctx);
1709+ unbind_texture(&ts);
1710+ if (status != VA_STATUS_SUCCESS)
1711+ return status;
1712+
1713+ return vtable->vaDeassociateSurfaceGLX(ctx, gl_surface);
1714+}
1715+
1716+
1717+/* ========================================================================= */
1718+/* === VA/GLX bind functions implementation with vaCopySurfaceGLX() === */
1719+/* ========================================================================= */
1720+
1721+static VAStatus
1722+vaAssociateSurfaceGLX_impl_bind(
1723+ VADriverContextP ctx,
1724+ void *gl_surface,
1725+ VASurfaceID surface,
1726+ unsigned int flags
1727+)
1728+{
1729+ VADriverContextGLXP pDriverContextGLX = VA_DRIVER_CONTEXT_GLX(ctx);
1730+ VADriverVTableGLXP vtable = &pDriverContextGLX->vtable;
1731+ VASurfaceGLXP pSurfaceGLX = gl_surface;
1732+ VAStatus status;
1733+
1734+ if (!pDriverContextGLX->has_copy)
1735+ return VA_STATUS_ERROR_UNIMPLEMENTED;
1736+
1737+ status = vtable->vaCopySurfaceGLX(ctx, gl_surface, surface, flags);
1738+ if (status != VA_STATUS_SUCCESS)
1739+ return status;
1740+
1741+ pSurfaceGLX->surface = surface;
1742+ return VA_STATUS_SUCCESS;
1743+}
1744+
1745+static VAStatus
1746+vaDeassociateSurfaceGLX_impl_bind(VADriverContextP ctx, void *gl_surface)
1747+{
1748+ VADriverContextGLXP pDriverContextGLX = VA_DRIVER_CONTEXT_GLX(ctx);
1749+ VASurfaceGLXP pSurfaceGLX = gl_surface;
1750+
1751+ if (!pDriverContextGLX->has_copy)
1752+ return VA_STATUS_ERROR_UNIMPLEMENTED;
1753+
1754+ pSurfaceGLX->surface = VA_INVALID_SURFACE;
1755+ return VA_STATUS_SUCCESS;
1756+}
1757+
1758+static VAStatus
1759+vaBeginRenderSurfaceGLX_impl_bind(VADriverContextP ctx, void *gl_surface)
1760+{
1761+ /* Surface is already copied into the texture, in vaAssociateSurfaceGLX() */
1762+ return VA_STATUS_SUCCESS;
1763+}
1764+
1765+static VAStatus
1766+vaEndRenderSurfaceGLX_impl_bind(VADriverContextP ctx, void *gl_surface)
1767+{
1768+ return VA_STATUS_SUCCESS;
1769+}
1770+
1771+
1772+/* ========================================================================= */
1773+/* === Private VA/GLX vtable initialization === */
1774+/* ========================================================================= */
1775+
1776+// Initialize GLX driver context
1777+VAStatus va_glx_init_context(VADriverContextP ctx)
1778+{
1779+ VADriverContextGLXP glx_ctx = VA_DRIVER_CONTEXT_GLX(ctx);
1780+ VADriverVTableGLXP vtable = &glx_ctx->vtable;
1781+ int needs_tfp = 0, needs_fbo = 0;
1782+
1783+ if (glx_ctx->is_initialized)
1784+ return VA_STATUS_SUCCESS;
1785+
1786+ glx_ctx->has_copy = ctx->vtable.glx.vaCopySurfaceGLX != NULL;
1787+ glx_ctx->has_bind = (ctx->vtable.glx.vaAssociateSurfaceGLX != NULL &&
1788+ ctx->vtable.glx.vaBeginRenderSurfaceGLX != NULL &&
1789+ ctx->vtable.glx.vaEndRenderSurfaceGLX != NULL &&
1790+ ctx->vtable.glx.vaDeassociateSurfaceGLX != NULL);
1791+
1792+ switch ((((unsigned int)glx_ctx->has_bind) << 1) | glx_ctx->has_copy) {
1793+ case 0:
1794+ /* Full implementation in libVA */
1795+ needs_tfp = 1;
1796+ needs_fbo = 1;
1797+ vtable->vaCreateSurfaceGLX = vaCreateSurfaceGLX_impl_libva;
1798+ vtable->vaDestroySurfaceGLX = vaDestroySurfaceGLX_impl_libva;
1799+ vtable->vaAssociateSurfaceGLX = vaAssociateSurfaceGLX_impl_libva;
1800+ vtable->vaDeassociateSurfaceGLX = vaDeassociateSurfaceGLX_impl_libva;
1801+ vtable->vaBeginRenderSurfaceGLX = vaBeginRenderSurfaceGLX_impl_libva;
1802+ vtable->vaEndRenderSurfaceGLX = vaEndRenderSurfaceGLX_impl_libva;
1803+ vtable->vaSyncSurfaceGLX = vaSyncSurfaceGLX_impl_libva;
1804+ vtable->vaCopySurfaceGLX = vaCopySurfaceGLX_impl_libva;
1805+ break;
1806+ case 1:
1807+ /* Add bind functions based on vaCopySurfaceGLX() */
1808+ /* XXX: override vaSyncSurfaceGLX()? */
1809+ vtable->vaCreateSurfaceGLX = vaCreateSurfaceGLX_impl_driver;
1810+ vtable->vaDestroySurfaceGLX = vaDestroySurfaceGLX_impl_driver;
1811+ vtable->vaAssociateSurfaceGLX = vaAssociateSurfaceGLX_impl_bind;
1812+ vtable->vaDeassociateSurfaceGLX = vaDeassociateSurfaceGLX_impl_bind;
1813+ vtable->vaBeginRenderSurfaceGLX = vaBeginRenderSurfaceGLX_impl_bind;
1814+ vtable->vaEndRenderSurfaceGLX = vaEndRenderSurfaceGLX_impl_bind;
1815+ vtable->vaSyncSurfaceGLX = vaSyncSurfaceGLX_impl_driver;
1816+ vtable->vaCopySurfaceGLX = vaCopySurfaceGLX_impl_driver;
1817+ break;
1818+ case 2:
1819+ /* Add copy function based on vaBeginRenderSurfaceGLX() et al. */
1820+ needs_fbo = 1;
1821+ vtable->vaCreateSurfaceGLX = vaCreateSurfaceGLX_impl_driver;
1822+ vtable->vaDestroySurfaceGLX = vaDestroySurfaceGLX_impl_driver;
1823+ vtable->vaAssociateSurfaceGLX = vaAssociateSurfaceGLX_impl_driver;
1824+ vtable->vaDeassociateSurfaceGLX = vaDeassociateSurfaceGLX_impl_driver;
1825+ vtable->vaBeginRenderSurfaceGLX = vaBeginRenderSurfaceGLX_impl_driver;
1826+ vtable->vaEndRenderSurfaceGLX = vaEndRenderSurfaceGLX_impl_driver;
1827+ vtable->vaSyncSurfaceGLX = vaSyncSurfaceGLX_impl_driver;
1828+ vtable->vaCopySurfaceGLX = vaCopySurfaceGLX_impl_libva;
1829+ break;
1830+ case 3:
1831+ /* Keep driver bind & copy functions */
1832+ vtable->vaCreateSurfaceGLX = vaCreateSurfaceGLX_impl_driver;
1833+ vtable->vaDestroySurfaceGLX = vaDestroySurfaceGLX_impl_driver;
1834+ vtable->vaAssociateSurfaceGLX = vaAssociateSurfaceGLX_impl_driver;
1835+ vtable->vaDeassociateSurfaceGLX = vaDeassociateSurfaceGLX_impl_driver;
1836+ vtable->vaBeginRenderSurfaceGLX = vaBeginRenderSurfaceGLX_impl_driver;
1837+ vtable->vaEndRenderSurfaceGLX = vaEndRenderSurfaceGLX_impl_driver;
1838+ vtable->vaSyncSurfaceGLX = vaSyncSurfaceGLX_impl_driver;
1839+ vtable->vaCopySurfaceGLX = vaCopySurfaceGLX_impl_driver;
1840+ break;
1841+ default:
1842+ /* Fatal error: this cannot happen */
1843+ assert(0);
1844+ return VA_STATUS_ERROR_UNKNOWN;
1845+ }
1846+
1847+ glx_ctx->has_tfp = 0;
1848+ glx_ctx->use_tfp = 0;
1849+ glx_ctx->has_fbo = 0;
1850+ glx_ctx->use_fbo = 0;
1851+
1852+ if (needs_tfp) {
1853+ glx_ctx->has_tfp = check_tfp_extensions(ctx);
1854+ if (!glx_ctx->has_tfp || !load_tfp_extensions(ctx))
1855+ return VA_STATUS_ERROR_UNIMPLEMENTED;
1856+ glx_ctx->use_tfp = 1;
1857+ }
1858+
1859+ if (needs_fbo) {
1860+ glx_ctx->has_fbo = check_fbo_extensions(ctx);
1861+ if (!glx_ctx->has_fbo || !load_fbo_extensions(ctx))
1862+ return VA_STATUS_ERROR_UNIMPLEMENTED;
1863+ glx_ctx->use_fbo = 1;
1864+ }
1865+
1866+ glx_ctx->is_initialized = 1;
1867+ return VA_STATUS_SUCCESS;
1868+}
1869diff --git a/src/glx/va_glx_impl.h b/src/glx/va_glx_impl.h
1870new file mode 100644
1871index 0000000..977bfcc
1872--- /dev/null
1873+++ b/src/glx/va_glx_impl.h
1874@@ -0,0 +1,46 @@
1875+/*
1876+ * Copyright (C) 2009 Splitted-Desktop Systems. All Rights Reserved.
1877+ *
1878+ * Permission is hereby granted, free of charge, to any person obtaining a
1879+ * copy of this software and associated documentation files (the
1880+ * "Software"), to deal in the Software without restriction, including
1881+ * without limitation the rights to use, copy, modify, merge, publish,
1882+ * distribute, sub license, and/or sell copies of the Software, and to
1883+ * permit persons to whom the Software is furnished to do so, subject to
1884+ * the following conditions:
1885+ *
1886+ * The above copyright notice and this permission notice (including the
1887+ * next paragraph) shall be included in all copies or substantial portions
1888+ * of the Software.
1889+ *
1890+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
1891+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1892+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
1893+ * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
1894+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
1895+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
1896+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1897+ */
1898+
1899+#ifndef VA_GLX_IMPL_H
1900+#define VA_GLX_IMPL_H
1901+
1902+/**
1903+ * Initialize GLX driver context
1904+ *
1905+ * @param[in] ctx the VA driver context
1906+ * @return VA_STATUS_SUCCESS if successful
1907+ */
1908+VAStatus va_glx_init_context(VADriverContextP ctx)
1909+ ATTRIBUTE_HIDDEN;
1910+
1911+/** Create VA/GLX surface */
1912+VASurfaceGLXP
1913+va_glx_create_surface(VADriverContextP ctx, GLenum target, GLuint texture)
1914+ ATTRIBUTE_HIDDEN;
1915+
1916+/** Destroy VA/GLX surface */
1917+void va_glx_destroy_surface(VADriverContextP ctx, VASurfaceGLXP *pSurfaceGLX)
1918+ ATTRIBUTE_HIDDEN;
1919+
1920+#endif /* VA_GLX_IMPL_H */
1921diff --git a/src/glx/va_glx_private.h b/src/glx/va_glx_private.h
1922new file mode 100644
1923index 0000000..8658ad3
1924--- /dev/null
1925+++ b/src/glx/va_glx_private.h
1926@@ -0,0 +1,98 @@
1927+/*
1928+ * Copyright (C) 2009 Splitted-Desktop Systems. All Rights Reserved.
1929+ *
1930+ * Permission is hereby granted, free of charge, to any person obtaining a
1931+ * copy of this software and associated documentation files (the
1932+ * "Software"), to deal in the Software without restriction, including
1933+ * without limitation the rights to use, copy, modify, merge, publish,
1934+ * distribute, sub license, and/or sell copies of the Software, and to
1935+ * permit persons to whom the Software is furnished to do so, subject to
1936+ * the following conditions:
1937+ *
1938+ * The above copyright notice and this permission notice (including the
1939+ * next paragraph) shall be included in all copies or substantial portions
1940+ * of the Software.
1941+ *
1942+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
1943+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
1944+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
1945+ * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
1946+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
1947+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
1948+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
1949+ */
1950+
1951+#ifndef VA_GLX_PRIVATE_H
1952+#define VA_GLX_PRIVATE_H
1953+
1954+#include "config.h"
1955+#include "va.h"
1956+#include "va_backend.h"
1957+#include "va_x11.h"
1958+#include "va_glx.h"
1959+
1960+#if GLX_GLXEXT_VERSION < 18
1961+typedef void (*PFNGLXBINDTEXIMAGEEXTPROC)(Display *, GLXDrawable, int, const int *);
1962+typedef void (*PFNGLXRELEASETEXIMAGEEXTPROC)(Display *, GLXDrawable, int);
1963+#endif
1964+
1965+typedef struct VAOpenGLVTable *VAOpenGLVTableP;
1966+
1967+struct VAOpenGLVTable {
1968+ PFNGLXBINDTEXIMAGEEXTPROC glx_bind_tex_image;
1969+ PFNGLXRELEASETEXIMAGEEXTPROC glx_release_tex_image;
1970+ PFNGLGENFRAMEBUFFERSEXTPROC gl_gen_framebuffers;
1971+ PFNGLDELETEFRAMEBUFFERSEXTPROC gl_delete_framebuffers;
1972+ PFNGLBINDFRAMEBUFFEREXTPROC gl_bind_framebuffer;
1973+ PFNGLGENRENDERBUFFERSEXTPROC gl_gen_renderbuffers;
1974+ PFNGLDELETERENDERBUFFERSEXTPROC gl_delete_renderbuffers;
1975+ PFNGLBINDRENDERBUFFEREXTPROC gl_bind_renderbuffer;
1976+ PFNGLRENDERBUFFERSTORAGEEXTPROC gl_renderbuffer_storage;
1977+ PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC gl_framebuffer_renderbuffer;
1978+ PFNGLFRAMEBUFFERTEXTURE2DEXTPROC gl_framebuffer_texture_2d;
1979+ PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC gl_check_framebuffer_status;
1980+};
1981+
1982+typedef struct VADisplayContextGLX *VADisplayContextGLXP;
1983+typedef struct VADriverContextGLX *VADriverContextGLXP;
1984+typedef struct VASurfaceGLX *VASurfaceGLXP;
1985+typedef struct VADriverVTableGLX *VADriverVTableGLXP;
1986+
1987+struct VADisplayContextGLX {
1988+ void (*vaDestroy)(VADisplayContextP ctx);
1989+};
1990+
1991+#define VA_DRIVER_CONTEXT_GLX(ctx) ((VADriverContextGLXP)((ctx)->glx))
1992+
1993+struct VADriverContextGLX {
1994+ struct VADriverVTableGLX vtable;
1995+ struct VAOpenGLVTable gl_vtable;
1996+ unsigned int is_initialized : 1;
1997+ unsigned int has_copy : 1;
1998+ unsigned int has_bind : 1;
1999+ unsigned int has_tfp : 1;
2000+ unsigned int has_fbo : 1;
2001+ unsigned int use_tfp : 1;
2002+ unsigned int use_fbo : 1;
2003+};
2004+
2005+/** Unique VASurfaceGLX identifier */
2006+#define VA_SURFACE_GLX_MAGIC VA_FOURCC('V','A','G','L')
2007+
2008+struct VASurfaceGLX {
2009+ uint32_t magic; ///< Magic number identifying a VASurfaceGLX
2010+ GLenum target; ///< GL target to which the texture is bound
2011+ GLuint texture; ///< GL texture
2012+ VASurfaceID surface; ///< Associated VA surface
2013+ unsigned int width;
2014+ unsigned int height;
2015+ int is_bound;
2016+ Pixmap pixmap;
2017+ GLXPixmap glx_pixmap;
2018+ GLuint fbo;
2019+ GLuint fbo_buffer;
2020+ GLuint fbo_texture;
2021+ void *priv; ///< Private VA/GLX surface data from driver
2022+};
2023+
2024+#endif /* VA_GLX_PRIVATE_H */