VirtualBox

source: vbox/trunk/src/VBox/Additions/common/crOpenGL/fakedri_drv.c@ 34198

Last change on this file since 34198 was 34198, checked in by vboxsync, 14 years ago

crOpenGL: add debug message and use define for patch size

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 21.5 KB
Line 
1/* $Id: fakedri_drv.c 34198 2010-11-19 13:46:47Z vboxsync $ */
2
3/** @file
4 * VBox OpenGL DRI driver functions
5 */
6
7/*
8 * Copyright (C) 2009 Oracle Corporation
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 */
18
19#define _GNU_SOURCE 1
20
21#include "cr_error.h"
22#include "cr_gl.h"
23#include "cr_mem.h"
24#include "stub.h"
25#include "fakedri_drv.h"
26#include "dri_glx.h"
27#include "iprt/mem.h"
28#include "iprt/err.h"
29#include <dlfcn.h>
30#include <elf.h>
31#include <unistd.h>
32#include "xf86.h"
33
34#define VBOX_NO_MESA_PATCH_REPORTS
35
36//#define DEBUG_DRI_CALLS
37
38//@todo this could be different...
39#ifdef RT_ARCH_AMD64
40# define DRI_DEFAULT_DRIVER_DIR "/usr/lib64/dri:/usr/lib/dri"
41# define DRI_XORG_DRV_DIR "/usr/lib/xorg/modules/drivers/"
42#else
43# define DRI_DEFAULT_DRIVER_DIR "/usr/lib/dri"
44# define DRI_XORG_DRV_DIR "/usr/lib/xorg/modules/drivers/"
45#endif
46
47#ifdef DEBUG_DRI_CALLS
48 #define SWDRI_SHOWNAME(pext, func) \
49 crDebug("SWDRI: sc %s->%s", #pext, #func)
50#else
51 #define SWDRI_SHOWNAME(pext, func)
52#endif
53
54#define SWDRI_SAFECALL(pext, func, ...) \
55 SWDRI_SHOWNAME(pext, func); \
56 if (pext && pext->func){ \
57 (*pext->func)(__VA_ARGS__); \
58 } else { \
59 crDebug("swcore_call NULL for "#func); \
60 }
61
62#define SWDRI_SAFERET(pext, func, ...) \
63 SWDRI_SHOWNAME(pext, func); \
64 if (pext && pext->func){ \
65 return (*pext->func)(__VA_ARGS__); \
66 } else { \
67 crDebug("swcore_call NULL for "#func); \
68 return 0; \
69 }
70
71#define SWDRI_SAFERET_CORE(func, ...) SWDRI_SAFERET(gpSwDriCoreExternsion, func, __VA_ARGS__)
72#define SWDRI_SAFECALL_CORE(func, ...) SWDRI_SAFECALL(gpSwDriCoreExternsion, func, __VA_ARGS__)
73#define SWDRI_SAFERET_SWRAST(func, ...) SWDRI_SAFERET(gpSwDriSwrastExtension, func, __VA_ARGS__)
74#define SWDRI_SAFECALL_SWRAST(func, ...) SWDRI_SAFECALL(gpSwDriSwrastExtension, func, __VA_ARGS__)
75
76#ifndef PAGESIZE
77#define PAGESIZE 4096
78#endif
79
80#ifdef RT_ARCH_AMD64
81# define DRI_ELFSYM Elf64_Sym
82#else
83# define DRI_ELFSYM Elf32_Sym
84#endif
85
86#ifdef RT_ARCH_AMD64
87typedef struct _FAKEDRI_PatchNode
88{
89 const char* psFuncName;
90 void *pDstStart, *pDstEnd;
91 const void *pSrcStart, *pSrcEnd;
92
93 struct _FAKEDRI_PatchNode *pNext;
94} FAKEDRI_PatchNode;
95static FAKEDRI_PatchNode *g_pFreeList=NULL, *g_pRepatchList=NULL;
96#endif
97
98static struct _glapi_table vbox_glapi_table;
99fakedri_glxapi_table glxim;
100
101static const __DRIextension **gppSwDriExternsion = NULL;
102static const __DRIcoreExtension *gpSwDriCoreExternsion = NULL;
103static const __DRIswrastExtension *gpSwDriSwrastExtension = NULL;
104
105extern const __DRIextension * __driDriverExtensions[];
106
107#define GLAPI_ENTRY(Func) pGLTable->Func = cr_gl##Func;
108static void
109vboxFillMesaGLAPITable(struct _glapi_table *pGLTable)
110{
111 #include "fakedri_glfuncsList.h"
112
113 pGLTable->SampleMaskSGIS = cr_glSampleMaskEXT;
114 pGLTable->SamplePatternSGIS = cr_glSamplePatternEXT;
115 pGLTable->WindowPos2dMESA = cr_glWindowPos2d;
116 pGLTable->WindowPos2dvMESA = cr_glWindowPos2dv;
117 pGLTable->WindowPos2fMESA = cr_glWindowPos2f;
118 pGLTable->WindowPos2fvMESA = cr_glWindowPos2fv;
119 pGLTable->WindowPos2iMESA = cr_glWindowPos2i;
120 pGLTable->WindowPos2ivMESA = cr_glWindowPos2iv;
121 pGLTable->WindowPos2sMESA = cr_glWindowPos2s;
122 pGLTable->WindowPos2svMESA = cr_glWindowPos2sv;
123 pGLTable->WindowPos3dMESA = cr_glWindowPos3d;
124 pGLTable->WindowPos3dvMESA = cr_glWindowPos3dv;
125 pGLTable->WindowPos3fMESA = cr_glWindowPos3f;
126 pGLTable->WindowPos3fvMESA = cr_glWindowPos3fv;
127 pGLTable->WindowPos3iMESA = cr_glWindowPos3i;
128 pGLTable->WindowPos3ivMESA = cr_glWindowPos3iv;
129 pGLTable->WindowPos3sMESA = cr_glWindowPos3s;
130 pGLTable->WindowPos3svMESA = cr_glWindowPos3sv;
131};
132#undef GLAPI_ENTRY
133
134#define GLXAPI_ENTRY(Func) pGLXTable->Func = VBOXGLXTAG(glX##Func);
135static void
136vboxFillGLXAPITable(fakedri_glxapi_table *pGLXTable)
137{
138 #include "fakedri_glxfuncsList.h"
139}
140#undef GLXAPI_ENTRY
141
142static void
143vboxApplyPatch(const char* psFuncName, void *pDst, const void *pSrc, unsigned long size)
144{
145 void *alPatch;
146 int rv;
147
148 /* Get aligned start address we're going to patch*/
149 alPatch = (void*) ((uintptr_t)pDst & ~(uintptr_t)(PAGESIZE-1));
150
151#ifndef VBOX_NO_MESA_PATCH_REPORTS
152 crDebug("MProtecting: %p, %li", alPatch, pDst-alPatch+size);
153#endif
154
155 /* Get write access to mesa functions */
156 rv = RTMemProtect(alPatch, pDst-alPatch+size, RTMEM_PROT_READ|RTMEM_PROT_WRITE|RTMEM_PROT_EXEC);
157 if (RT_FAILURE(rv))
158 {
159 crError("mprotect failed with %x (%s)", rv, psFuncName);
160 }
161
162#ifndef VBOX_NO_MESA_PATCH_REPORTS
163 crDebug("Writing %li bytes to %p from %p", size, pDst, pSrc);
164#endif
165
166 crMemcpy(pDst, pSrc, size);
167
168 /*@todo Restore the protection, probably have to check what was it before us...*/
169 rv = RTMemProtect(alPatch, pDst-alPatch+size, RTMEM_PROT_READ|RTMEM_PROT_EXEC);
170 if (RT_FAILURE(rv))
171 {
172 crError("mprotect2 failed with %x (%s)", rv, psFuncName);
173 }
174}
175
176#ifdef RT_ARCH_AMD64
177# define FAKEDRI_JMP64_PATCH_SIZE 13
178#endif
179
180static void
181vboxPatchMesaExport(const char* psFuncName, const void *pStart, const void *pEnd)
182{
183 Dl_info dlip;
184 DRI_ELFSYM* sym=0;
185 int rv;
186 void *alPatch;
187 void *pMesaEntry;
188 char patch[5];
189 void *shift;
190
191#ifndef VBOX_NO_MESA_PATCH_REPORTS
192 crDebug("\nvboxPatchMesaExport: %s", psFuncName);
193#endif
194
195 pMesaEntry = dlsym(RTLD_DEFAULT, psFuncName);
196
197 if (!pMesaEntry)
198 {
199 crDebug("%s not defined in current scope, are we being loaded by mesa's libGL.so?", psFuncName);
200 return;
201 }
202
203 rv = dladdr1(pMesaEntry, &dlip, (void**)&sym, RTLD_DL_SYMENT);
204 if (!rv || !sym)
205 {
206 crError("Failed to get size for %p(%s)", pMesaEntry, psFuncName);
207 return;
208 }
209
210#if VBOX_OGL_GLX_USE_CSTUBS
211 {
212 Dl_info dlip1;
213 DRI_ELFSYM* sym1=0;
214 int rv;
215
216 rv = dladdr1(pStart, &dlip1, (void**)&sym1, RTLD_DL_SYMENT);
217 if (!rv || !sym1)
218 {
219 crError("Failed to get size for %p", pStart);
220 return;
221 }
222
223 pEnd = pStart + sym1->st_size;
224# ifndef VBOX_NO_MESA_PATCH_REPORTS
225 crDebug("VBox Entry: %p, start: %p(%s:%s), size: %li", pStart, dlip1.dli_saddr, dlip1.dli_fname, dlip1.dli_sname, sym1->st_size);
226# endif
227 }
228#endif
229
230#ifndef VBOX_NO_MESA_PATCH_REPORTS
231 crDebug("Mesa Entry: %p, start: %p(%s:%s), size: %li", pMesaEntry, dlip.dli_saddr, dlip.dli_fname, dlip.dli_sname, sym->st_size);
232 crDebug("Vbox code: start: %p, end %p, size: %li", pStart, pEnd, pEnd-pStart);
233#endif
234
235#ifndef VBOX_OGL_GLX_USE_CSTUBS
236 if (sym->st_size<(pEnd-pStart))
237#endif
238 {
239 /* Try to insert 5 bytes jmp/jmpq to our stub code */
240
241 if (sym->st_size<5)
242 {
243 if (crStrcmp(psFuncName, "glXCreateGLXPixmapMESA"))
244 {
245 crError("Can't patch size too small.(%s)", psFuncName);
246 }
247 return;
248 }
249
250 shift = (void*)((intptr_t)pStart-((intptr_t)dlip.dli_saddr+5));
251#ifndef VBOX_NO_MESA_PATCH_REPORTS
252 crDebug("Inserting jmp[q] with shift %p instead", shift);
253#endif
254
255#ifdef RT_ARCH_AMD64
256 {
257 int64_t offset = (intptr_t)shift;
258
259 if (offset>INT32_MAX || offset<INT32_MIN)
260 {
261 FAKEDRI_PatchNode *pNode;
262# ifndef VBOX_NO_MESA_PATCH_REPORTS
263 crDebug("Can't patch offset is too big. Pushing for 2nd pass(%s)", psFuncName);
264# endif
265 /*Add patch node to repatch with chain jmps in 2nd pass*/
266 pNode = (FAKEDRI_PatchNode *)crAlloc(sizeof(FAKEDRI_PatchNode));
267 if (!pNode)
268 {
269 crError("Not enough memory.");
270 return;
271 }
272 pNode->psFuncName = psFuncName;
273 pNode->pDstStart = dlip.dli_saddr;
274 pNode->pDstEnd = dlip.dli_saddr+sym->st_size;
275 pNode->pSrcStart = pStart;
276 pNode->pSrcEnd = pEnd;
277 pNode->pNext = g_pRepatchList;
278 g_pRepatchList = pNode;
279 return;
280 }
281 }
282#endif
283
284 patch[0] = 0xE9;
285 crMemcpy(&patch[1], &shift, 4);
286#ifndef VBOX_NO_MESA_PATCH_REPORTS
287 crDebug("Patch: E9 %x", *((int*)&patch[1]));
288#endif
289 pStart = &patch[0];
290 pEnd = &patch[5];
291 }
292
293 vboxApplyPatch(psFuncName, dlip.dli_saddr, pStart, pEnd-pStart);
294
295#ifdef RT_ARCH_AMD64
296 /*Add rest of mesa function body to free list*/
297 if (sym->st_size-(pEnd-pStart)>=FAKEDRI_JMP64_PATCH_SIZE)
298 {
299 FAKEDRI_PatchNode *pNode = (FAKEDRI_PatchNode *)crAlloc(sizeof(FAKEDRI_PatchNode));
300 if (pNode)
301 {
302 pNode->psFuncName = psFuncName;
303 pNode->pDstStart = dlip.dli_saddr+(pEnd-pStart);
304 pNode->pDstEnd = dlip.dli_saddr+sym->st_size;
305 pNode->pSrcStart = dlip.dli_saddr;
306 pNode->pSrcEnd = NULL;
307 pNode->pNext = g_pFreeList;
308 g_pFreeList = pNode;
309# ifndef VBOX_NO_MESA_PATCH_REPORTS
310 crDebug("Added free node %s, func start=%p, free start=%p, size=%#lx",
311 psFuncName, pNode->pSrcStart, pNode->pDstStart, pNode->pDstEnd-pNode->pDstStart);
312# endif
313 }
314 }
315#endif
316}
317
318#ifdef RT_ARCH_AMD64
319static void
320vboxRepatchMesaExports(void)
321{
322 FAKEDRI_PatchNode *pFreeNode, *pPatchNode;
323 int64_t offset;
324 char patch[FAKEDRI_JMP64_PATCH_SIZE];
325
326 pPatchNode = g_pRepatchList;
327 while (pPatchNode)
328 {
329# ifndef VBOX_NO_MESA_PATCH_REPORTS
330 crDebug("\nvboxRepatchMesaExports %s", pPatchNode->psFuncName);
331# endif
332 /*find free place in mesa functions, to place 64bit jump to our stub code*/
333 pFreeNode = g_pFreeList;
334 while (pFreeNode)
335 {
336 if (pFreeNode->pDstEnd-pFreeNode->pDstStart>=FAKEDRI_JMP64_PATCH_SIZE)
337 {
338 offset = ((intptr_t)pFreeNode->pDstStart-((intptr_t)pPatchNode->pDstStart+5));
339 if (offset<=INT32_MAX && offset>=INT32_MIN)
340 {
341 break;
342 }
343 }
344 pFreeNode=pFreeNode->pNext;
345 }
346
347 if (!pFreeNode)
348 {
349 crError("Failed to find free space, to place repatch for %s.", pPatchNode->psFuncName);
350 return;
351 }
352
353 /*add 32bit rel jmp, from mesa orginal function to free space in other mesa function*/
354 patch[0] = 0xE9;
355 crMemcpy(&patch[1], &offset, 4);
356# ifndef VBOX_NO_MESA_PATCH_REPORTS
357 crDebug("Adding jmp from mesa %s to mesa %s+%#lx", pPatchNode->psFuncName, pFreeNode->psFuncName,
358 pFreeNode->pDstStart-pFreeNode->pSrcStart);
359# endif
360 vboxApplyPatch(pPatchNode->psFuncName, pPatchNode->pDstStart, &patch[0], 5);
361
362 /*add 64bit abs jmp, from free space to our stub code*/
363 patch[0] = 0x49; /*movq %r11,imm64*/
364 patch[1] = 0xBB;
365 crMemcpy(&patch[2], &pPatchNode->pSrcStart, 8);
366 patch[10] = 0x41; /*jmp *%r11*/
367 patch[11] = 0xFF;
368 patch[12] = 0xE3;
369# ifndef VBOX_NO_MESA_PATCH_REPORTS
370 crDebug("Adding jmp from mesa %s+%#lx to vbox %s", pFreeNode->psFuncName, pFreeNode->pDstStart-pFreeNode->pSrcStart,
371 pPatchNode->psFuncName);
372# endif
373 vboxApplyPatch(pFreeNode->psFuncName, pFreeNode->pDstStart, &patch[0], FAKEDRI_JMP64_PATCH_SIZE);
374 /*mark this space as used*/
375 pFreeNode->pDstStart = pFreeNode->pDstStart+FAKEDRI_JMP64_PATCH_SIZE;
376
377 pPatchNode = pPatchNode->pNext;
378 }
379}
380
381static void
382vboxFakeDriFreeList(FAKEDRI_PatchNode *pList)
383{
384 FAKEDRI_PatchNode *pNode;
385
386 while (pList)
387 {
388 pNode=pList;
389 pList=pNode->pNext;
390 crFree(pNode);
391 }
392}
393#endif
394
395#ifdef VBOX_OGL_GLX_USE_CSTUBS
396static void
397# define GLXAPI_ENTRY(Func) vboxPatchMesaExport("glX"#Func, &vbox_glX##Func, NULL);
398vboxPatchMesaExports()
399#else
400static void
401# define GLXAPI_ENTRY(Func) vboxPatchMesaExport("glX"#Func, &vbox_glX##Func, &vbox_glX##Func##_EndProc);
402vboxPatchMesaExports()
403#endif
404{
405 crDebug("Patching mesa glx entries");
406 #include "fakedri_glxfuncsList.h"
407
408#ifdef RT_ARCH_AMD64
409 vboxRepatchMesaExports();
410 vboxFakeDriFreeList(g_pRepatchList);
411 g_pRepatchList = NULL;
412 vboxFakeDriFreeList(g_pFreeList);
413 g_pFreeList = NULL;
414#endif
415}
416#undef GLXAPI_ENTRY
417
418bool vbox_load_sw_dri()
419{
420 const char *libPaths, *p, *next;;
421 char realDriverName[200];
422 void *handle;
423 int len, i;
424
425 /*code from Mesa-7.2/src/glx/x11/dri_common.c:driOpenDriver*/
426
427 libPaths = NULL;
428 if (geteuid() == getuid()) {
429 /* don't allow setuid apps to use LIBGL_DRIVERS_PATH */
430 libPaths = getenv("LIBGL_DRIVERS_PATH");
431 if (!libPaths)
432 libPaths = getenv("LIBGL_DRIVERS_DIR"); /* deprecated */
433 }
434 if (libPaths == NULL)
435 libPaths = DRI_DEFAULT_DRIVER_DIR;
436
437 handle = NULL;
438 for (p = libPaths; *p; p = next)
439 {
440 next = strchr(p, ':');
441 if (next == NULL)
442 {
443 len = strlen(p);
444 next = p + len;
445 }
446 else
447 {
448 len = next - p;
449 next++;
450 }
451
452 snprintf(realDriverName, sizeof realDriverName, "%.*s/%s_dri.so", len, p, "swrast");
453 crDebug("trying %s", realDriverName);
454 handle = dlopen(realDriverName, RTLD_NOW | RTLD_LOCAL);
455 if (handle) break;
456 }
457
458 /*end code*/
459
460 if (handle) gppSwDriExternsion = dlsym(handle, "__driDriverExtensions");
461
462 if (!gppSwDriExternsion)
463 {
464 crDebug("%s doesn't export __driDriverExtensions", realDriverName);
465 return false;
466 }
467 crDebug("loaded %s", realDriverName);
468
469 for (i = 0; gppSwDriExternsion[i]; i++)
470 {
471 if (strcmp(gppSwDriExternsion[i]->name, __DRI_CORE) == 0)
472 gpSwDriCoreExternsion = (__DRIcoreExtension *) gppSwDriExternsion[i];
473 if (strcmp(gppSwDriExternsion[i]->name, __DRI_SWRAST) == 0)
474 gpSwDriSwrastExtension = (__DRIswrastExtension *) gppSwDriExternsion[i];
475 }
476
477 return gpSwDriCoreExternsion && gpSwDriSwrastExtension;
478}
479
480void __attribute__ ((constructor)) vbox_install_into_mesa(void)
481{
482 {
483#ifdef _X_ATTRIBUTE_PRINTF
484 void (*pxf86Msg)(MessageType type, const char *format, ...) _X_ATTRIBUTE_PRINTF(2,3);
485#else
486 void (*pxf86Msg)(MessageType type, const char *format, ...) _printf_attribute(2,3);
487#endif
488
489 pxf86Msg = dlsym(RTLD_DEFAULT, "xf86Msg");
490 if (pxf86Msg)
491 {
492 pxf86Msg(X_INFO, "Next line is added to allow vboxvideo_drv.so to appear as whitelisted driver\n");
493 pxf86Msg(X_INFO, "The file referenced, is *NOT* loaded\n");
494 pxf86Msg(X_INFO, "Loading %s/ati_drv.so\n", DRI_XORG_DRV_DIR);
495
496 /* we're failing to proxy software dri driver calls for certain xservers, so just make sure we're unloaded for now */
497 __driDriverExtensions[0] = NULL;
498 return;
499 }
500 }
501
502 if (!stubInit())
503 {
504 crDebug("vboxdriInitScreen: stubInit failed");
505 return;
506 }
507
508 /* Load swrast_dri.so to proxy dri related calls there. */
509 if (!vbox_load_sw_dri())
510 {
511 crDebug("vboxdriInitScreen: vbox_load_sw_dri failed...going to fail badly");
512 return;
513 }
514
515 /* Handle gl api.
516 * In the end application call would look like this:
517 * app call glFoo->(mesa asm dispatch stub)->cr_glFoo(vbox asm dispatch stub)->SPU Foo function(packspuFoo or alike)
518 * Note, we don't need to install extension functions via _glapi_add_dispatch, because we'd override glXGetProcAddress.
519 */
520 /* We don't support all mesa's functions. Initialize our table to mesa dispatch first*/
521 crMemcpy(&vbox_glapi_table, _glapi_get_dispatch(), sizeof(struct _glapi_table));
522 /* Now install our assembly dispatch entries into table */
523 vboxFillMesaGLAPITable(&vbox_glapi_table);
524 /* Install our dispatch table into mesa */
525 _glapi_set_dispatch(&vbox_glapi_table);
526
527 /* Handle glx api.
528 * In the end application call would look like this:
529 * app call glxFoo->(mesa asm dispatch stub patched with vbox_glXFoo:jmp glxim[Foo's index])->VBOXGLXTAG(glxFoo)
530 */
531 /* Fill structure used by our assembly stubs */
532 vboxFillGLXAPITable(&glxim);
533 /* Now patch functions exported by libGL.so */
534 vboxPatchMesaExports();
535}
536
537/*
538 * @todo we're missing first glx related call from the client application.
539 * Luckily, this doesn't add much problems, except for some cases.
540 */
541
542/* __DRIcoreExtension */
543
544static __DRIscreen *
545vboxdriCreateNewScreen(int screen, int fd, unsigned int sarea_handle,
546 const __DRIextension **extensions, const __DRIconfig ***driverConfigs,
547 void *loaderPrivate)
548{
549 (void) fd;
550 (void) sarea_handle;
551 SWDRI_SAFERET_SWRAST(createNewScreen, screen, extensions, driverConfigs, loaderPrivate);
552}
553
554static void
555vboxdriDestroyScreen(__DRIscreen *screen)
556{
557 SWDRI_SAFECALL_CORE(destroyScreen, screen);
558}
559
560static const __DRIextension **
561vboxdriGetExtensions(__DRIscreen *screen)
562{
563 SWDRI_SAFERET_CORE(getExtensions, screen);
564}
565
566static int
567vboxdriGetConfigAttrib(const __DRIconfig *config,
568 unsigned int attrib,
569 unsigned int *value)
570{
571 SWDRI_SAFERET_CORE(getConfigAttrib, config, attrib, value);
572}
573
574static int
575vboxdriIndexConfigAttrib(const __DRIconfig *config, int index,
576 unsigned int *attrib, unsigned int *value)
577{
578 SWDRI_SAFERET_CORE(indexConfigAttrib, config, index, attrib, value);
579}
580
581static __DRIdrawable *
582vboxdriCreateNewDrawable(__DRIscreen *screen,
583 const __DRIconfig *config,
584 unsigned int drawable_id,
585 unsigned int head,
586 void *loaderPrivate)
587{
588 (void) drawable_id;
589 (void) head;
590 SWDRI_SAFERET_SWRAST(createNewDrawable, screen, config, loaderPrivate);
591}
592
593static void
594vboxdriDestroyDrawable(__DRIdrawable *drawable)
595{
596 SWDRI_SAFECALL_CORE(destroyDrawable, drawable);
597}
598
599static void
600vboxdriSwapBuffers(__DRIdrawable *drawable)
601{
602 SWDRI_SAFECALL_CORE(swapBuffers, drawable);
603}
604
605static __DRIcontext *
606vboxdriCreateNewContext(__DRIscreen *screen,
607 const __DRIconfig *config,
608 __DRIcontext *shared,
609 void *loaderPrivate)
610{
611 SWDRI_SAFERET_CORE(createNewContext, screen, config, shared, loaderPrivate);
612}
613
614static int
615vboxdriCopyContext(__DRIcontext *dest,
616 __DRIcontext *src,
617 unsigned long mask)
618{
619 SWDRI_SAFERET_CORE(copyContext, dest, src, mask);
620}
621
622static void
623vboxdriDestroyContext(__DRIcontext *context)
624{
625 SWDRI_SAFECALL_CORE(destroyContext, context);
626}
627
628static int
629vboxdriBindContext(__DRIcontext *ctx,
630 __DRIdrawable *pdraw,
631 __DRIdrawable *pread)
632{
633 SWDRI_SAFERET_CORE(bindContext, ctx, pdraw, pread);
634}
635
636static int
637vboxdriUnbindContext(__DRIcontext *ctx)
638{
639 SWDRI_SAFERET_CORE(unbindContext, ctx)
640}
641
642/* __DRIlegacyExtension */
643
644static __DRIscreen *
645vboxdriCreateNewScreen_Legacy(int scrn,
646 const __DRIversion *ddx_version,
647 const __DRIversion *dri_version,
648 const __DRIversion *drm_version,
649 const __DRIframebuffer *frame_buffer,
650 drmAddress pSAREA, int fd,
651 const __DRIextension **extensions,
652 const __DRIconfig ***driver_modes,
653 void *loaderPrivate)
654{
655 (void) ddx_version;
656 (void) dri_version;
657 (void) frame_buffer;
658 (void) pSAREA;
659 (void) fd;
660 SWDRI_SAFERET_SWRAST(createNewScreen, scrn, extensions, driver_modes, loaderPrivate);
661}
662
663static __DRIdrawable *
664vboxdriCreateNewDrawable_Legacy(__DRIscreen *psp, const __DRIconfig *config,
665 drm_drawable_t hwDrawable, int renderType,
666 const int *attrs, void *data)
667{
668 (void) hwDrawable;
669 (void) renderType;
670 (void) attrs;
671 (void) data;
672 SWDRI_SAFERET_SWRAST(createNewDrawable, psp, config, data);
673}
674
675static __DRIcontext *
676vboxdriCreateNewContext_Legacy(__DRIscreen *psp, const __DRIconfig *config,
677 int render_type, __DRIcontext *shared,
678 drm_context_t hwContext, void *data)
679{
680 (void) render_type;
681 (void) hwContext;
682 return vboxdriCreateNewContext(psp, config, shared, data);
683}
684
685
686static const __DRIlegacyExtension vboxdriLegacyExtension = {
687 { __DRI_LEGACY, __DRI_LEGACY_VERSION },
688 vboxdriCreateNewScreen_Legacy,
689 vboxdriCreateNewDrawable_Legacy,
690 vboxdriCreateNewContext_Legacy
691};
692
693static const __DRIcoreExtension vboxdriCoreExtension = {
694 { __DRI_CORE, __DRI_CORE_VERSION },
695 vboxdriCreateNewScreen, /* driCreateNewScreen */
696 vboxdriDestroyScreen,
697 vboxdriGetExtensions,
698 vboxdriGetConfigAttrib,
699 vboxdriIndexConfigAttrib,
700 vboxdriCreateNewDrawable, /* driCreateNewDrawable */
701 vboxdriDestroyDrawable,
702 vboxdriSwapBuffers,
703 vboxdriCreateNewContext,
704 vboxdriCopyContext,
705 vboxdriDestroyContext,
706 vboxdriBindContext,
707 vboxdriUnbindContext
708};
709
710/* This structure is used by dri_util from mesa, don't rename it! */
711DECLEXPORT(const __DRIextension *) __driDriverExtensions[] = {
712 &vboxdriLegacyExtension.base,
713 &vboxdriCoreExtension.base,
714 NULL
715};
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette