VirtualBox

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

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

crOpenGL: fix for 64bit linuxes

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 21.1 KB
Line 
1/* $Id: fakedri_drv.c 34177 2010-11-18 15:12:24Z 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
176static void
177vboxPatchMesaExport(const char* psFuncName, const void *pStart, const void *pEnd)
178{
179 Dl_info dlip;
180 DRI_ELFSYM* sym=0;
181 int rv;
182 void *alPatch;
183 void *pMesaEntry;
184 char patch[5];
185 void *shift;
186
187#ifndef VBOX_NO_MESA_PATCH_REPORTS
188 crDebug("\nvboxPatchMesaExport: %s", psFuncName);
189#endif
190
191 pMesaEntry = dlsym(RTLD_DEFAULT, psFuncName);
192
193 if (!pMesaEntry)
194 {
195 crDebug("%s not defined in current scope, are we being loaded by mesa's libGL.so?", psFuncName);
196 return;
197 }
198
199 rv = dladdr1(pMesaEntry, &dlip, (void**)&sym, RTLD_DL_SYMENT);
200 if (!rv || !sym)
201 {
202 crError("Failed to get size for %p(%s)", pMesaEntry, psFuncName);
203 return;
204 }
205
206#if VBOX_OGL_GLX_USE_CSTUBS
207 {
208 Dl_info dlip1;
209 DRI_ELFSYM* sym1=0;
210 int rv;
211
212 rv = dladdr1(pStart, &dlip1, (void**)&sym1, RTLD_DL_SYMENT);
213 if (!rv || !sym1)
214 {
215 crError("Failed to get size for %p", pStart);
216 return;
217 }
218
219 pEnd = pStart + sym1->st_size;
220# ifndef VBOX_NO_MESA_PATCH_REPORTS
221 crDebug("VBox Entry: %p, start: %p(%s:%s), size: %li", pStart, dlip1.dli_saddr, dlip1.dli_fname, dlip1.dli_sname, sym1->st_size);
222# endif
223 }
224#endif
225
226#ifndef VBOX_NO_MESA_PATCH_REPORTS
227 crDebug("Mesa Entry: %p, start: %p(%s:%s), size: %li", pMesaEntry, dlip.dli_saddr, dlip.dli_fname, dlip.dli_sname, sym->st_size);
228 crDebug("Vbox code: start: %p, end %p, size: %li", pStart, pEnd, pEnd-pStart);
229#endif
230
231#ifndef VBOX_OGL_GLX_USE_CSTUBS
232 if (sym->st_size<(pEnd-pStart))
233#endif
234 {
235 /* Try to insert 5 bytes jmp/jmpq to our stub code */
236
237 if (sym->st_size<5)
238 {
239 if (crStrcmp(psFuncName, "glXCreateGLXPixmapMESA"))
240 {
241 crError("Can't patch size too small.(%s)", psFuncName);
242 }
243 return;
244 }
245
246 shift = (void*)((intptr_t)pStart-((intptr_t)dlip.dli_saddr+5));
247#ifndef VBOX_NO_MESA_PATCH_REPORTS
248 crDebug("Inserting jmp[q] with shift %p instead", shift);
249#endif
250
251#ifdef RT_ARCH_AMD64
252 {
253 int64_t offset = (intptr_t)shift;
254
255 if (offset>INT32_MAX || offset<INT32_MIN)
256 {
257 FAKEDRI_PatchNode *pNode;
258# ifndef VBOX_NO_MESA_PATCH_REPORTS
259 crDebug("Can't patch offset is too big. Pushing for 2nd pass(%s)", psFuncName);
260# endif
261 /*Add patch node to repatch with chain jmps in 2nd pass*/
262 pNode = (FAKEDRI_PatchNode *)crAlloc(sizeof(FAKEDRI_PatchNode));
263 if (!pNode)
264 {
265 crError("Not enough memory.");
266 return;
267 }
268 pNode->psFuncName = psFuncName;
269 pNode->pDstStart = dlip.dli_saddr;
270 pNode->pDstEnd = dlip.dli_saddr+sym->st_size;
271 pNode->pSrcStart = pStart;
272 pNode->pSrcEnd = pEnd;
273 pNode->pNext = g_pRepatchList;
274 g_pRepatchList = pNode;
275 return;
276 }
277 }
278#endif
279
280 patch[0] = 0xE9;
281 crMemcpy(&patch[1], &shift, 4);
282#ifndef VBOX_NO_MESA_PATCH_REPORTS
283 crDebug("Patch: E9 %x", *((int*)&patch[1]));
284#endif
285 pStart = &patch[0];
286 pEnd = &patch[5];
287 }
288
289 vboxApplyPatch(psFuncName, dlip.dli_saddr, pStart, pEnd-pStart);
290
291#ifdef RT_ARCH_AMD64
292 /*Add rest of mesa function body to free list*/
293 if (sym->st_size-(pEnd-pStart)>=5)
294 {
295 FAKEDRI_PatchNode *pNode = (FAKEDRI_PatchNode *)crAlloc(sizeof(FAKEDRI_PatchNode));
296 if (pNode)
297 {
298 pNode->psFuncName = psFuncName;
299 pNode->pDstStart = dlip.dli_saddr+(pEnd-pStart);
300 pNode->pDstEnd = dlip.dli_saddr+sym->st_size;
301 pNode->pSrcStart = dlip.dli_saddr;
302 pNode->pSrcEnd = NULL;
303 pNode->pNext = g_pFreeList;
304 g_pFreeList = pNode;
305 }
306 }
307#endif
308}
309
310#ifdef RT_ARCH_AMD64
311static void
312vboxRepatchMesaExports(void)
313{
314 FAKEDRI_PatchNode *pFreeNode, *pPatchNode;
315 int64_t offset;
316 char patch[12];
317
318 pPatchNode = g_pRepatchList;
319 while (pPatchNode)
320 {
321# ifndef VBOX_NO_MESA_PATCH_REPORTS
322 crDebug("\nvboxRepatchMesaExports %s", pPatchNode->psFuncName);
323# endif
324 /*find free place in mesa functions, to place 64bit jump to our stub code*/
325 pFreeNode = g_pFreeList;
326 while (pFreeNode)
327 {
328 if (pFreeNode->pDstEnd-pFreeNode->pDstStart>=12)
329 {
330 offset = ((intptr_t)pFreeNode->pDstStart-((intptr_t)pPatchNode->pDstStart+5));
331 if (offset<=INT32_MAX && offset>=INT32_MIN)
332 {
333 break;
334 }
335 }
336 pFreeNode=pFreeNode->pNext;
337 }
338
339 if (!pFreeNode)
340 {
341 crError("Failed to find free space, to place repatch for %s.", pPatchNode->psFuncName);
342 return;
343 }
344
345 /*add 32bit rel jmp, from mesa orginal function to free space in other mesa function*/
346 patch[0] = 0xE9;
347 crMemcpy(&patch[1], &offset, 4);
348# ifndef VBOX_NO_MESA_PATCH_REPORTS
349 crDebug("Adding jmp from mesa %s to mesa %s+%#lx", pPatchNode->psFuncName, pFreeNode->psFuncName,
350 pFreeNode->pDstStart-pFreeNode->pSrcStart);
351# endif
352 vboxApplyPatch(pPatchNode->psFuncName, pPatchNode->pDstStart, &patch[0], 5);
353
354 /*add 64bit abs jmp, from free space to our stub code*/
355 patch[0] = 0x48; /*movq %rax,imm64*/
356 patch[1] = 0xB8;
357 crMemcpy(&patch[2], &pPatchNode->pSrcStart, 8);
358 patch[10] = 0xFF; /*jmp *%rax*/
359 patch[11] = 0xE0;
360# ifndef VBOX_NO_MESA_PATCH_REPORTS
361 crDebug("Adding jmp from mesa %s+%#lx to vbox %s", pFreeNode->psFuncName, pFreeNode->pDstStart-pFreeNode->pSrcStart,
362 pPatchNode->psFuncName);
363# endif
364 vboxApplyPatch(pFreeNode->psFuncName, pFreeNode->pDstStart, &patch[0], 12);
365 /*mark this space as used*/
366 pFreeNode->pDstStart = pFreeNode->pDstStart+12;
367
368 pPatchNode = pPatchNode->pNext;
369 }
370}
371
372static void
373vboxFakeDriFreeList(FAKEDRI_PatchNode *pList)
374{
375 FAKEDRI_PatchNode *pNode;
376
377 while (pList)
378 {
379 pNode=pList;
380 pList=pNode->pNext;
381 crFree(pNode);
382 }
383}
384#endif
385
386#ifdef VBOX_OGL_GLX_USE_CSTUBS
387static void
388# define GLXAPI_ENTRY(Func) vboxPatchMesaExport("glX"#Func, &vbox_glX##Func, NULL);
389vboxPatchMesaExports()
390#else
391static void
392# define GLXAPI_ENTRY(Func) vboxPatchMesaExport("glX"#Func, &vbox_glX##Func, &vbox_glX##Func##_EndProc);
393vboxPatchMesaExports()
394#endif
395{
396 crDebug("Patching mesa glx entries");
397 #include "fakedri_glxfuncsList.h"
398
399#ifdef RT_ARCH_AMD64
400 vboxRepatchMesaExports();
401 vboxFakeDriFreeList(g_pRepatchList);
402 g_pRepatchList = NULL;
403 vboxFakeDriFreeList(g_pFreeList);
404 g_pFreeList = NULL;
405#endif
406}
407#undef GLXAPI_ENTRY
408
409bool vbox_load_sw_dri()
410{
411 const char *libPaths, *p, *next;;
412 char realDriverName[200];
413 void *handle;
414 int len, i;
415
416 /*code from Mesa-7.2/src/glx/x11/dri_common.c:driOpenDriver*/
417
418 libPaths = NULL;
419 if (geteuid() == getuid()) {
420 /* don't allow setuid apps to use LIBGL_DRIVERS_PATH */
421 libPaths = getenv("LIBGL_DRIVERS_PATH");
422 if (!libPaths)
423 libPaths = getenv("LIBGL_DRIVERS_DIR"); /* deprecated */
424 }
425 if (libPaths == NULL)
426 libPaths = DRI_DEFAULT_DRIVER_DIR;
427
428 handle = NULL;
429 for (p = libPaths; *p; p = next)
430 {
431 next = strchr(p, ':');
432 if (next == NULL)
433 {
434 len = strlen(p);
435 next = p + len;
436 }
437 else
438 {
439 len = next - p;
440 next++;
441 }
442
443 snprintf(realDriverName, sizeof realDriverName, "%.*s/%s_dri.so", len, p, "swrast");
444 crDebug("trying %s", realDriverName);
445 handle = dlopen(realDriverName, RTLD_NOW | RTLD_LOCAL);
446 if (handle) break;
447 }
448
449 /*end code*/
450
451 if (handle) gppSwDriExternsion = dlsym(handle, "__driDriverExtensions");
452
453 if (!gppSwDriExternsion)
454 {
455 crDebug("%s doesn't export __driDriverExtensions", realDriverName);
456 return false;
457 }
458 crDebug("loaded %s", realDriverName);
459
460 for (i = 0; gppSwDriExternsion[i]; i++)
461 {
462 if (strcmp(gppSwDriExternsion[i]->name, __DRI_CORE) == 0)
463 gpSwDriCoreExternsion = (__DRIcoreExtension *) gppSwDriExternsion[i];
464 if (strcmp(gppSwDriExternsion[i]->name, __DRI_SWRAST) == 0)
465 gpSwDriSwrastExtension = (__DRIswrastExtension *) gppSwDriExternsion[i];
466 }
467
468 return gpSwDriCoreExternsion && gpSwDriSwrastExtension;
469}
470
471void __attribute__ ((constructor)) vbox_install_into_mesa(void)
472{
473 {
474#ifdef _X_ATTRIBUTE_PRINTF
475 void (*pxf86Msg)(MessageType type, const char *format, ...) _X_ATTRIBUTE_PRINTF(2,3);
476#else
477 void (*pxf86Msg)(MessageType type, const char *format, ...) _printf_attribute(2,3);
478#endif
479
480 pxf86Msg = dlsym(RTLD_DEFAULT, "xf86Msg");
481 if (pxf86Msg)
482 {
483 pxf86Msg(X_INFO, "Next line is added to allow vboxvideo_drv.so to appear as whitelisted driver\n");
484 pxf86Msg(X_INFO, "The file referenced, is *NOT* loaded\n");
485 pxf86Msg(X_INFO, "Loading %s/ati_drv.so\n", DRI_XORG_DRV_DIR);
486
487 /* we're failing to proxy software dri driver calls for certain xservers, so just make sure we're unloaded for now */
488 __driDriverExtensions[0] = NULL;
489 return;
490 }
491 }
492
493 if (!stubInit())
494 {
495 crDebug("vboxdriInitScreen: stubInit failed");
496 return;
497 }
498
499 /* Load swrast_dri.so to proxy dri related calls there. */
500 if (!vbox_load_sw_dri())
501 {
502 crDebug("vboxdriInitScreen: vbox_load_sw_dri failed...going to fail badly");
503 return;
504 }
505
506 /* Handle gl api.
507 * In the end application call would look like this:
508 * app call glFoo->(mesa asm dispatch stub)->cr_glFoo(vbox asm dispatch stub)->SPU Foo function(packspuFoo or alike)
509 * Note, we don't need to install extension functions via _glapi_add_dispatch, because we'd override glXGetProcAddress.
510 */
511 /* We don't support all mesa's functions. Initialize our table to mesa dispatch first*/
512 crMemcpy(&vbox_glapi_table, _glapi_get_dispatch(), sizeof(struct _glapi_table));
513 /* Now install our assembly dispatch entries into table */
514 vboxFillMesaGLAPITable(&vbox_glapi_table);
515 /* Install our dispatch table into mesa */
516 _glapi_set_dispatch(&vbox_glapi_table);
517
518 /* Handle glx api.
519 * In the end application call would look like this:
520 * app call glxFoo->(mesa asm dispatch stub patched with vbox_glXFoo:jmp glxim[Foo's index])->VBOXGLXTAG(glxFoo)
521 */
522 /* Fill structure used by our assembly stubs */
523 vboxFillGLXAPITable(&glxim);
524 /* Now patch functions exported by libGL.so */
525 vboxPatchMesaExports();
526}
527
528/*
529 * @todo we're missing first glx related call from the client application.
530 * Luckily, this doesn't add much problems, except for some cases.
531 */
532
533/* __DRIcoreExtension */
534
535static __DRIscreen *
536vboxdriCreateNewScreen(int screen, int fd, unsigned int sarea_handle,
537 const __DRIextension **extensions, const __DRIconfig ***driverConfigs,
538 void *loaderPrivate)
539{
540 (void) fd;
541 (void) sarea_handle;
542 SWDRI_SAFERET_SWRAST(createNewScreen, screen, extensions, driverConfigs, loaderPrivate);
543}
544
545static void
546vboxdriDestroyScreen(__DRIscreen *screen)
547{
548 SWDRI_SAFECALL_CORE(destroyScreen, screen);
549}
550
551static const __DRIextension **
552vboxdriGetExtensions(__DRIscreen *screen)
553{
554 SWDRI_SAFERET_CORE(getExtensions, screen);
555}
556
557static int
558vboxdriGetConfigAttrib(const __DRIconfig *config,
559 unsigned int attrib,
560 unsigned int *value)
561{
562 SWDRI_SAFERET_CORE(getConfigAttrib, config, attrib, value);
563}
564
565static int
566vboxdriIndexConfigAttrib(const __DRIconfig *config, int index,
567 unsigned int *attrib, unsigned int *value)
568{
569 SWDRI_SAFERET_CORE(indexConfigAttrib, config, index, attrib, value);
570}
571
572static __DRIdrawable *
573vboxdriCreateNewDrawable(__DRIscreen *screen,
574 const __DRIconfig *config,
575 unsigned int drawable_id,
576 unsigned int head,
577 void *loaderPrivate)
578{
579 (void) drawable_id;
580 (void) head;
581 SWDRI_SAFERET_SWRAST(createNewDrawable, screen, config, loaderPrivate);
582}
583
584static void
585vboxdriDestroyDrawable(__DRIdrawable *drawable)
586{
587 SWDRI_SAFECALL_CORE(destroyDrawable, drawable);
588}
589
590static void
591vboxdriSwapBuffers(__DRIdrawable *drawable)
592{
593 SWDRI_SAFECALL_CORE(swapBuffers, drawable);
594}
595
596static __DRIcontext *
597vboxdriCreateNewContext(__DRIscreen *screen,
598 const __DRIconfig *config,
599 __DRIcontext *shared,
600 void *loaderPrivate)
601{
602 SWDRI_SAFERET_CORE(createNewContext, screen, config, shared, loaderPrivate);
603}
604
605static int
606vboxdriCopyContext(__DRIcontext *dest,
607 __DRIcontext *src,
608 unsigned long mask)
609{
610 SWDRI_SAFERET_CORE(copyContext, dest, src, mask);
611}
612
613static void
614vboxdriDestroyContext(__DRIcontext *context)
615{
616 SWDRI_SAFECALL_CORE(destroyContext, context);
617}
618
619static int
620vboxdriBindContext(__DRIcontext *ctx,
621 __DRIdrawable *pdraw,
622 __DRIdrawable *pread)
623{
624 SWDRI_SAFERET_CORE(bindContext, ctx, pdraw, pread);
625}
626
627static int
628vboxdriUnbindContext(__DRIcontext *ctx)
629{
630 SWDRI_SAFERET_CORE(unbindContext, ctx)
631}
632
633/* __DRIlegacyExtension */
634
635static __DRIscreen *
636vboxdriCreateNewScreen_Legacy(int scrn,
637 const __DRIversion *ddx_version,
638 const __DRIversion *dri_version,
639 const __DRIversion *drm_version,
640 const __DRIframebuffer *frame_buffer,
641 drmAddress pSAREA, int fd,
642 const __DRIextension **extensions,
643 const __DRIconfig ***driver_modes,
644 void *loaderPrivate)
645{
646 (void) ddx_version;
647 (void) dri_version;
648 (void) frame_buffer;
649 (void) pSAREA;
650 (void) fd;
651 SWDRI_SAFERET_SWRAST(createNewScreen, scrn, extensions, driver_modes, loaderPrivate);
652}
653
654static __DRIdrawable *
655vboxdriCreateNewDrawable_Legacy(__DRIscreen *psp, const __DRIconfig *config,
656 drm_drawable_t hwDrawable, int renderType,
657 const int *attrs, void *data)
658{
659 (void) hwDrawable;
660 (void) renderType;
661 (void) attrs;
662 (void) data;
663 SWDRI_SAFERET_SWRAST(createNewDrawable, psp, config, data);
664}
665
666static __DRIcontext *
667vboxdriCreateNewContext_Legacy(__DRIscreen *psp, const __DRIconfig *config,
668 int render_type, __DRIcontext *shared,
669 drm_context_t hwContext, void *data)
670{
671 (void) render_type;
672 (void) hwContext;
673 return vboxdriCreateNewContext(psp, config, shared, data);
674}
675
676
677static const __DRIlegacyExtension vboxdriLegacyExtension = {
678 { __DRI_LEGACY, __DRI_LEGACY_VERSION },
679 vboxdriCreateNewScreen_Legacy,
680 vboxdriCreateNewDrawable_Legacy,
681 vboxdriCreateNewContext_Legacy
682};
683
684static const __DRIcoreExtension vboxdriCoreExtension = {
685 { __DRI_CORE, __DRI_CORE_VERSION },
686 vboxdriCreateNewScreen, /* driCreateNewScreen */
687 vboxdriDestroyScreen,
688 vboxdriGetExtensions,
689 vboxdriGetConfigAttrib,
690 vboxdriIndexConfigAttrib,
691 vboxdriCreateNewDrawable, /* driCreateNewDrawable */
692 vboxdriDestroyDrawable,
693 vboxdriSwapBuffers,
694 vboxdriCreateNewContext,
695 vboxdriCopyContext,
696 vboxdriDestroyContext,
697 vboxdriBindContext,
698 vboxdriUnbindContext
699};
700
701/* This structure is used by dri_util from mesa, don't rename it! */
702DECLEXPORT(const __DRIextension *) __driDriverExtensions[] = {
703 &vboxdriLegacyExtension.base,
704 &vboxdriCoreExtension.base,
705 NULL
706};
Note: See TracBrowser for help on using the repository browser.

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