diff options
author | Tom Zanussi <tom.zanussi@intel.com> | 2010-12-27 16:32:21 -0600 |
---|---|---|
committer | Tom Zanussi <tom.zanussi@intel.com> | 2010-12-27 16:32:21 -0600 |
commit | af40e14ce335fa689d1a989feba3c02a8c71b7a7 (patch) | |
tree | 90ce1d53eb63627d90ec7f081b680a66c92e8705 /meta-emenlow/recipes-graphics/libva/libva-0.31.0/322_libva_glx.patch | |
parent | ba8b8a99fd1598d0ce2cbaa69e9d16358d1ff5db (diff) | |
download | meta-intel-af40e14ce335fa689d1a989feba3c02a8c71b7a7.tar.gz |
meta-emenlow: move to meta-intel repo from poky repo
This is the meta-emenlow layer, moved from the poky repo in order to
keep all the meta-intel BSPs together.
This version builds against laverne (0.90) - detailed build
instruction can be found in the README file.
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.patch | 2024 |
1 files changed, 2024 insertions, 0 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 new file mode 100644 index 00000000..ccd9ae09 --- /dev/null +++ b/meta-emenlow/recipes-graphics/libva/libva-0.31.0/322_libva_glx.patch | |||
@@ -0,0 +1,2024 @@ | |||
1 | commit 8e76000abce070da5f1c902a6290f4ccaa3eccc8 | ||
2 | Author: Gwenole Beauchesne <gbeauchesne@splitted-desktop.com> | ||
3 | Date: Fri Sep 18 15:51:08 2009 +0000 | ||
4 | |||
5 | Add C++ guards. | ||
6 | |||
7 | commit bf1ae22ef324fbb347f5369e1ba307e847553fe8 | ||
8 | Author: Gwenole Beauchesne <gbeauchesne@splitted-desktop.com> | ||
9 | Date: Fri Sep 18 15:49:55 2009 +0000 | ||
10 | |||
11 | Fix check for GL extensions. | ||
12 | |||
13 | commit df0953a951d8a2e5e4b0a28a95ae0f1ac735726e | ||
14 | Author: Gwenole Beauchesne <gbeauchesne@splitted-desktop.com> | ||
15 | Date: Tue Sep 8 12:25:14 2009 +0000 | ||
16 | |||
17 | Add generic VA/GLX implementation with TFP and FBO. | ||
18 | |||
19 | commit f640b1cf9eab4e5d478239b608ed0d8b68f6c5f6 | ||
20 | Author: Gwenole Beauchesne <gbeauchesne@splitted-desktop.com> | ||
21 | Date: Tue Sep 8 12:15:35 2009 +0000 | ||
22 | |||
23 | Move GLX VTable to a new file. | ||
24 | |||
25 | commit 70d9cb6d1aa2fc2dde6646f3b692433e0d93d431 | ||
26 | Author: Gwenole Beauchesne <gbeauchesne@splitted-desktop.com> | ||
27 | Date: Fri Aug 28 11:15:51 2009 +0000 | ||
28 | |||
29 | Add OpenGL extensions (v3). | ||
30 | |||
31 | diff --git a/src/glx/Makefile.am b/src/glx/Makefile.am | ||
32 | new file mode 100644 | ||
33 | index 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) | ||
78 | diff --git a/src/glx/va_backend_glx.h b/src/glx/va_backend_glx.h | ||
79 | new file mode 100644 | ||
80 | index 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 */ | ||
171 | diff --git a/src/glx/va_glx.c b/src/glx/va_glx.c | ||
172 | new file mode 100644 | ||
173 | index 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 | +} | ||
472 | diff --git a/src/glx/va_glx.h b/src/glx/va_glx.h | ||
473 | new file mode 100644 | ||
474 | index 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 */ | ||
695 | diff --git a/src/glx/va_glx_impl.c b/src/glx/va_glx_impl.c | ||
696 | new file mode 100644 | ||
697 | index 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 | +} | ||
1869 | diff --git a/src/glx/va_glx_impl.h b/src/glx/va_glx_impl.h | ||
1870 | new file mode 100644 | ||
1871 | index 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 */ | ||
1921 | diff --git a/src/glx/va_glx_private.h b/src/glx/va_glx_private.h | ||
1922 | new file mode 100644 | ||
1923 | index 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 */ | ||