1 | /** @file $Id: vboxvideo_dri2.c$
|
---|
2 | *
|
---|
3 | * VirtualBox X11 Additions graphics driver, DRI2 support
|
---|
4 | */
|
---|
5 |
|
---|
6 | /*
|
---|
7 | * Copyright (C) 2006-2013 Oracle Corporation
|
---|
8 | *
|
---|
9 | * This file is part of VirtualBox Open Source Edition (OSE), as
|
---|
10 | * available from http://www.virtualbox.org. This file is free software;
|
---|
11 | * you can redistribute it and/or modify it under the terms of the GNU
|
---|
12 | * General Public License (GPL) as published by the Free Software
|
---|
13 | * Foundation, in version 2 as it comes in the "COPYING" file of the
|
---|
14 | * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
|
---|
15 | * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
|
---|
16 | */
|
---|
17 |
|
---|
18 | #include "vboxvideo.h"
|
---|
19 | #include <xf86drm.h>
|
---|
20 | #include <drm.h>
|
---|
21 | #include <dri2.h>
|
---|
22 | #include <fcntl.h>
|
---|
23 | #include <unistd.h>
|
---|
24 |
|
---|
25 | static void VBOXDRICopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
|
---|
26 | DRI2BufferPtr pDest, DRI2BufferPtr pSrc)
|
---|
27 | {
|
---|
28 | }
|
---|
29 |
|
---|
30 | static DRI2Buffer2Ptr VBOXDRICreateBuffer(DrawablePtr pDraw,
|
---|
31 | unsigned int cAttachment,
|
---|
32 | unsigned int cFormat)
|
---|
33 | {
|
---|
34 | return calloc(1, sizeof(DRI2Buffer2Rec));
|
---|
35 | }
|
---|
36 |
|
---|
37 | static void VBOXDRIDestroyBuffer(DrawablePtr pDraw, DRI2Buffer2Ptr pBuffer)
|
---|
38 | {
|
---|
39 | free(pBuffer);
|
---|
40 | }
|
---|
41 |
|
---|
42 | /* We need to pass a constant path string to the screen initialisation function.
|
---|
43 | * The format is hard-coded in "drmOpen" in libdrm, and libdrm contains a
|
---|
44 | * comment to say that open should be done manually in future and not using
|
---|
45 | * "drmOpen", so we will do it manually but also hard-coding the format. The
|
---|
46 | * maximum minor number (15) is also hard-coded. */
|
---|
47 | #define PATH(minor) "/dev/dri/card" #minor
|
---|
48 | const char *devicePaths[] =
|
---|
49 | {
|
---|
50 | PATH(0), PATH(1), PATH(2), PATH(3), PATH(4), PATH(5), PATH(6), PATH(7),
|
---|
51 | PATH(8), PATH(9), PATH(10), PATH(11), PATH(12), PATH(13), PATH(14), PATH(15)
|
---|
52 | };
|
---|
53 | #undef PATH
|
---|
54 |
|
---|
55 | /** As long as we are using our fake DRI driver inside of Mesa, we only want
|
---|
56 | * to implement the minimum here to make Mesa load it. */
|
---|
57 | Bool VBOXDRIScreenInit(ScrnInfoPtr pScrn, ScreenPtr pScreen, VBOXPtr pVBox)
|
---|
58 | {
|
---|
59 | DRI2InfoRec DRI2Info;
|
---|
60 | unsigned i;
|
---|
61 |
|
---|
62 | memset(&DRI2Info, 0, sizeof(DRI2Info));
|
---|
63 | pVBox->drmFD = -1;
|
---|
64 | for (i = 0; i < RT_ELEMENTS(devicePaths); ++i)
|
---|
65 | {
|
---|
66 | int fd = open(devicePaths[i], O_RDWR);
|
---|
67 | if (fd >= 0)
|
---|
68 | {
|
---|
69 | drmVersionPtr pVersion = drmGetVersion(fd);
|
---|
70 | if ( pVersion
|
---|
71 | && pVersion->name_len
|
---|
72 | && !strcmp(pVersion->name, VBOX_DRM_DRIVER_NAME)
|
---|
73 | && drmSetMaster(fd) == 0)
|
---|
74 | {
|
---|
75 | TRACE_LOG("Opened drm device %s\n", devicePaths[i]);
|
---|
76 | DRI2Info.deviceName = devicePaths[i];
|
---|
77 | /* Keep the driver open and hope that the path won't change. */
|
---|
78 | pVBox->drmFD = fd;
|
---|
79 | drmFreeVersion(pVersion);
|
---|
80 | break;
|
---|
81 | }
|
---|
82 | close(fd);
|
---|
83 | drmFreeVersion(pVersion);
|
---|
84 | }
|
---|
85 | }
|
---|
86 | if (!DRI2Info.deviceName)
|
---|
87 | return FALSE;
|
---|
88 | DRI2Info.version = 3;
|
---|
89 | DRI2Info.fd = pVBox->drmFD;
|
---|
90 | DRI2Info.driverName = VBOX_DRI_DRIVER_NAME;
|
---|
91 | DRI2Info.CopyRegion = VBOXDRICopyRegion;
|
---|
92 | DRI2Info.Wait = NULL;
|
---|
93 | DRI2Info.CreateBuffer = VBOXDRICreateBuffer;
|
---|
94 | DRI2Info.DestroyBuffer = VBOXDRIDestroyBuffer;
|
---|
95 | return DRI2ScreenInit(pScreen, &DRI2Info);
|
---|
96 | }
|
---|
97 |
|
---|
98 | void VBOXDRICloseScreen(ScreenPtr pScreen, VBOXPtr pVBox)
|
---|
99 | {
|
---|
100 | DRI2CloseScreen(pScreen);
|
---|
101 | if (pVBox->drmFD >= 0)
|
---|
102 | close(pVBox->drmFD);
|
---|
103 | }
|
---|