VirtualBox

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

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

crOpenGL: fix fedora64, use r11 instead of rax

  • 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 34191 2010-11-19 11:04:16Z 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[13];
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>=13)
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] = 0x49; /*movq %r11,imm64*/
356 patch[1] = 0xBB;
357 crMemcpy(&patch[2], &pPatchNode->pSrcStart, 8);
358 patch[10] = 0x41; /*jmp *%r11*/
359 patch[11] = 0xFF;
360 patch[12] = 0xE3;
361# ifndef VBOX_NO_MESA_PATCH_REPORTS
362 crDebug("Adding jmp from mesa %s+%#lx to vbox %s", pFreeNode->psFuncName, pFreeNode->pDstStart-pFreeNode->pSrcStart,
363 pPatchNode->psFuncName);
364# endif
365 vboxApplyPatch(pFreeNode->psFuncName, pFreeNode->pDstStart, &patch[0], 13);
366 /*mark this space as used*/
367 pFreeNode->pDstStart = pFreeNode->pDstStart+13;
368
369 pPatchNode = pPatchNode->pNext;
370 }
371}
372
373static void
374vboxFakeDriFreeList(FAKEDRI_PatchNode *pList)
375{
376 FAKEDRI_PatchNode *pNode;
377
378 while (pList)
379 {
380 pNode=pList;
381 pList=pNode->pNext;
382 crFree(pNode);
383 }
384}
385#endif
386
387#ifdef VBOX_OGL_GLX_USE_CSTUBS
388static void
389# define GLXAPI_ENTRY(Func) vboxPatchMesaExport("glX"#Func, &vbox_glX##Func, NULL);
390vboxPatchMesaExports()
391#else
392static void
393# define GLXAPI_ENTRY(Func) vboxPatchMesaExport("glX"#Func, &vbox_glX##Func, &vbox_glX##Func##_EndProc);
394vboxPatchMesaExports()
395#endif
396{
397 crDebug("Patching mesa glx entries");
398 #include "fakedri_glxfuncsList.h"
399
400#ifdef RT_ARCH_AMD64
401 vboxRepatchMesaExports();
402 vboxFakeDriFreeList(g_pRepatchList);
403 g_pRepatchList = NULL;
404 vboxFakeDriFreeList(g_pFreeList);
405 g_pFreeList = NULL;
406#endif
407}
408#undef GLXAPI_ENTRY
409
410bool vbox_load_sw_dri()
411{
412 const char *libPaths, *p, *next;;
413 char realDriverName[200];
414 void *handle;
415 int len, i;
416
417 /*code from Mesa-7.2/src/glx/x11/dri_common.c:driOpenDriver*/
418
419 libPaths = NULL;
420 if (geteuid() == getuid()) {
421 /* don't allow setuid apps to use LIBGL_DRIVERS_PATH */
422 libPaths = getenv("LIBGL_DRIVERS_PATH");
423 if (!libPaths)
424 libPaths = getenv("LIBGL_DRIVERS_DIR"); /* deprecated */
425 }
426 if (libPaths == NULL)
427 libPaths = DRI_DEFAULT_DRIVER_DIR;
428
429 handle = NULL;
430 for (p = libPaths; *p; p = next)
431 {
432 next = strchr(p, ':');
433 if (next == NULL)
434 {
435 len = strlen(p);
436 next = p + len;
437 }
438 else
439 {
440 len = next - p;
441 next++;
442 }
443
444 snprintf(realDriverName, sizeof realDriverName, "%.*s/%s_dri.so", len, p, "swrast");
445 crDebug("trying %s", realDriverName);
446 handle = dlopen(realDriverName, RTLD_NOW | RTLD_LOCAL);
447 if (handle) break;
448 }
449
450 /*end code*/
451
452 if (handle) gppSwDriExternsion = dlsym(handle, "__driDriverExtensions");
453
454 if (!gppSwDriExternsion)
455 {
456 crDebug("%s doesn't export __driDriverExtensions", realDriverName);
457 return false;
458 }
459 crDebug("loaded %s", realDriverName);
460
461 for (i = 0; gppSwDriExternsion[i]; i++)
462 {
463 if (strcmp(gppSwDriExternsion[i]->name, __DRI_CORE) == 0)
464 gpSwDriCoreExternsion = (__DRIcoreExtension *) gppSwDriExternsion[i];
465 if (strcmp(gppSwDriExternsion[i]->name, __DRI_SWRAST) == 0)
466 gpSwDriSwrastExtension = (__DRIswrastExtension *) gppSwDriExternsion[i];
467 }
468
469 return gpSwDriCoreExternsion && gpSwDriSwrastExtension;
470}
471
472void __attribute__ ((constructor)) vbox_install_into_mesa(void)
473{
474 {
475#ifdef _X_ATTRIBUTE_PRINTF
476 void (*pxf86Msg)(MessageType type, const char *format, ...) _X_ATTRIBUTE_PRINTF(2,3);
477#else
478 void (*pxf86Msg)(MessageType type, const char *format, ...) _printf_attribute(2,3);
479#endif
480
481 pxf86Msg = dlsym(RTLD_DEFAULT, "xf86Msg");
482 if (pxf86Msg)
483 {
484 pxf86Msg(X_INFO, "Next line is added to allow vboxvideo_drv.so to appear as whitelisted driver\n");
485 pxf86Msg(X_INFO, "The file referenced, is *NOT* loaded\n");
486 pxf86Msg(X_INFO, "Loading %s/ati_drv.so\n", DRI_XORG_DRV_DIR);
487
488 /* we're failing to proxy software dri driver calls for certain xservers, so just make sure we're unloaded for now */
489 __driDriverExtensions[0] = NULL;
490 return;
491 }
492 }
493
494 if (!stubInit())
495 {
496 crDebug("vboxdriInitScreen: stubInit failed");
497 return;
498 }
499
500 /* Load swrast_dri.so to proxy dri related calls there. */
501 if (!vbox_load_sw_dri())
502 {
503 crDebug("vboxdriInitScreen: vbox_load_sw_dri failed...going to fail badly");
504 return;
505 }
506
507 /* Handle gl api.
508 * In the end application call would look like this:
509 * app call glFoo->(mesa asm dispatch stub)->cr_glFoo(vbox asm dispatch stub)->SPU Foo function(packspuFoo or alike)
510 * Note, we don't need to install extension functions via _glapi_add_dispatch, because we'd override glXGetProcAddress.
511 */
512 /* We don't support all mesa's functions. Initialize our table to mesa dispatch first*/
513 crMemcpy(&vbox_glapi_table, _glapi_get_dispatch(), sizeof(struct _glapi_table));
514 /* Now install our assembly dispatch entries into table */
515 vboxFillMesaGLAPITable(&vbox_glapi_table);
516 /* Install our dispatch table into mesa */
517 _glapi_set_dispatch(&vbox_glapi_table);
518
519 /* Handle glx api.
520 * In the end application call would look like this:
521 * app call glxFoo->(mesa asm dispatch stub patched with vbox_glXFoo:jmp glxim[Foo's index])->VBOXGLXTAG(glxFoo)
522 */
523 /* Fill structure used by our assembly stubs */
524 vboxFillGLXAPITable(&glxim);
525 /* Now patch functions exported by libGL.so */
526 vboxPatchMesaExports();
527}
528
529/*
530 * @todo we're missing first glx related call from the client application.
531 * Luckily, this doesn't add much problems, except for some cases.
532 */
533
534/* __DRIcoreExtension */
535
536static __DRIscreen *
537vboxdriCreateNewScreen(int screen, int fd, unsigned int sarea_handle,
538 const __DRIextension **extensions, const __DRIconfig ***driverConfigs,
539 void *loaderPrivate)
540{
541 (void) fd;
542 (void) sarea_handle;
543 SWDRI_SAFERET_SWRAST(createNewScreen, screen, extensions, driverConfigs, loaderPrivate);
544}
545
546static void
547vboxdriDestroyScreen(__DRIscreen *screen)
548{
549 SWDRI_SAFECALL_CORE(destroyScreen, screen);
550}
551
552static const __DRIextension **
553vboxdriGetExtensions(__DRIscreen *screen)
554{
555 SWDRI_SAFERET_CORE(getExtensions, screen);
556}
557
558static int
559vboxdriGetConfigAttrib(const __DRIconfig *config,
560 unsigned int attrib,
561 unsigned int *value)
562{
563 SWDRI_SAFERET_CORE(getConfigAttrib, config, attrib, value);
564}
565
566static int
567vboxdriIndexConfigAttrib(const __DRIconfig *config, int index,
568 unsigned int *attrib, unsigned int *value)
569{
570 SWDRI_SAFERET_CORE(indexConfigAttrib, config, index, attrib, value);
571}
572
573static __DRIdrawable *
574vboxdriCreateNewDrawable(__DRIscreen *screen,
575 const __DRIconfig *config,
576 unsigned int drawable_id,
577 unsigned int head,
578 void *loaderPrivate)
579{
580 (void) drawable_id;
581 (void) head;
582 SWDRI_SAFERET_SWRAST(createNewDrawable, screen, config, loaderPrivate);
583}
584
585static void
586vboxdriDestroyDrawable(__DRIdrawable *drawable)
587{
588 SWDRI_SAFECALL_CORE(destroyDrawable, drawable);
589}
590
591static void
592vboxdriSwapBuffers(__DRIdrawable *drawable)
593{
594 SWDRI_SAFECALL_CORE(swapBuffers, drawable);
595}
596
597static __DRIcontext *
598vboxdriCreateNewContext(__DRIscreen *screen,
599 const __DRIconfig *config,
600 __DRIcontext *shared,
601 void *loaderPrivate)
602{
603 SWDRI_SAFERET_CORE(createNewContext, screen, config, shared, loaderPrivate);
604}
605
606static int
607vboxdriCopyContext(__DRIcontext *dest,
608 __DRIcontext *src,
609 unsigned long mask)
610{
611 SWDRI_SAFERET_CORE(copyContext, dest, src, mask);
612}
613
614static void
615vboxdriDestroyContext(__DRIcontext *context)
616{
617 SWDRI_SAFECALL_CORE(destroyContext, context);
618}
619
620static int
621vboxdriBindContext(__DRIcontext *ctx,
622 __DRIdrawable *pdraw,
623 __DRIdrawable *pread)
624{
625 SWDRI_SAFERET_CORE(bindContext, ctx, pdraw, pread);
626}
627
628static int
629vboxdriUnbindContext(__DRIcontext *ctx)
630{
631 SWDRI_SAFERET_CORE(unbindContext, ctx)
632}
633
634/* __DRIlegacyExtension */
635
636static __DRIscreen *
637vboxdriCreateNewScreen_Legacy(int scrn,
638 const __DRIversion *ddx_version,
639 const __DRIversion *dri_version,
640 const __DRIversion *drm_version,
641 const __DRIframebuffer *frame_buffer,
642 drmAddress pSAREA, int fd,
643 const __DRIextension **extensions,
644 const __DRIconfig ***driver_modes,
645 void *loaderPrivate)
646{
647 (void) ddx_version;
648 (void) dri_version;
649 (void) frame_buffer;
650 (void) pSAREA;
651 (void) fd;
652 SWDRI_SAFERET_SWRAST(createNewScreen, scrn, extensions, driver_modes, loaderPrivate);
653}
654
655static __DRIdrawable *
656vboxdriCreateNewDrawable_Legacy(__DRIscreen *psp, const __DRIconfig *config,
657 drm_drawable_t hwDrawable, int renderType,
658 const int *attrs, void *data)
659{
660 (void) hwDrawable;
661 (void) renderType;
662 (void) attrs;
663 (void) data;
664 SWDRI_SAFERET_SWRAST(createNewDrawable, psp, config, data);
665}
666
667static __DRIcontext *
668vboxdriCreateNewContext_Legacy(__DRIscreen *psp, const __DRIconfig *config,
669 int render_type, __DRIcontext *shared,
670 drm_context_t hwContext, void *data)
671{
672 (void) render_type;
673 (void) hwContext;
674 return vboxdriCreateNewContext(psp, config, shared, data);
675}
676
677
678static const __DRIlegacyExtension vboxdriLegacyExtension = {
679 { __DRI_LEGACY, __DRI_LEGACY_VERSION },
680 vboxdriCreateNewScreen_Legacy,
681 vboxdriCreateNewDrawable_Legacy,
682 vboxdriCreateNewContext_Legacy
683};
684
685static const __DRIcoreExtension vboxdriCoreExtension = {
686 { __DRI_CORE, __DRI_CORE_VERSION },
687 vboxdriCreateNewScreen, /* driCreateNewScreen */
688 vboxdriDestroyScreen,
689 vboxdriGetExtensions,
690 vboxdriGetConfigAttrib,
691 vboxdriIndexConfigAttrib,
692 vboxdriCreateNewDrawable, /* driCreateNewDrawable */
693 vboxdriDestroyDrawable,
694 vboxdriSwapBuffers,
695 vboxdriCreateNewContext,
696 vboxdriCopyContext,
697 vboxdriDestroyContext,
698 vboxdriBindContext,
699 vboxdriUnbindContext
700};
701
702/* This structure is used by dri_util from mesa, don't rename it! */
703DECLEXPORT(const __DRIextension *) __driDriverExtensions[] = {
704 &vboxdriLegacyExtension.base,
705 &vboxdriCoreExtension.base,
706 NULL
707};
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