1
/** @file $Id: vboxvideo_dri.c $
3
* VirtualBox X11 Additions graphics driver, DRI support
7
* Copyright (C) 2006-2007 Oracle Corporation
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
* --------------------------------------------------------------------
18
* This code is based on:
20
* X11 TDFX driver, src/tdfx_dri.c
22
* Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
23
* All Rights Reserved.
25
* Permission is hereby granted, free of charge, to any person obtaining a
26
* copy of this software and associated documentation files (the
27
* "Software"), to deal in the Software without restriction, including
28
* without limitation the rights to use, copy, modify, merge, publish,
29
* distribute, sub license, and/or sell copies of the Software, and to
30
* permit persons to whom the Software is furnished to do so, subject to
31
* the following conditions:
33
* The above copyright notice and this permission notice (including the
34
* next paragraph) shall be included in all copies or substantial portions
37
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
38
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
39
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
40
* IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
41
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
42
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
43
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
46
* Daryll Strauss <daryll@precisioninsight.com>
49
#include "vboxvideo.h"
55
VBOXCreateContext(ScreenPtr pScreen, VisualPtr visual,
56
drm_context_t hwContext, void *pVisualConfigPriv,
57
DRIContextType contextStore);
59
VBOXDestroyContext(ScreenPtr pScreen, drm_context_t hwContext,
60
DRIContextType contextStore);
62
VBOXDRISwapContext(ScreenPtr pScreen, DRISyncType syncType,
63
DRIContextType oldContextType, void *oldContext,
64
DRIContextType newContextType, void *newContext);
66
VBOXDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index);
68
VBOXDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg,
69
RegionPtr prgnSrc, CARD32 index);
71
VBOXDRIOpenFullScreen(ScreenPtr pScreen);
73
VBOXDRICloseFullScreen(ScreenPtr pScreen);
75
VBOXDRITransitionTo2d(ScreenPtr pScreen);
77
VBOXDRITransitionTo3d(ScreenPtr pScreen);
80
VBOXInitVisualConfigs(ScrnInfoPtr pScrn, VBOXPtr pVBox)
84
int cConfigs = 2; /* With and without double buffering */
85
__GLXvisualConfig *pConfigs = NULL;
86
pConfigs = (__GLXvisualConfig*) calloc(sizeof(__GLXvisualConfig),
91
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
92
"Disabling DRI: out of memory.\n");
94
for (int i = 0; rc && i < cConfigs; ++i)
97
pConfigs[i].class = -1;
98
pConfigs[i].rgba = TRUE;
99
if (pScrn->bitsPerPixel == 16)
101
pConfigs[i].redSize = 5;
102
pConfigs[i].greenSize = 6;
103
pConfigs[i].blueSize = 5;
104
pConfigs[i].redMask = 0x0000F800;
105
pConfigs[i].greenMask = 0x000007E0;
106
pConfigs[i].blueMask = 0x0000001F;
108
else if (pScrn->bitsPerPixel == 32)
110
pConfigs[i].redSize = 8;
111
pConfigs[i].greenSize = 8;
112
pConfigs[i].blueSize = 8;
113
pConfigs[i].alphaSize = 8;
114
pConfigs[i].redMask = 0x00ff0000;
115
pConfigs[i].greenMask = 0x0000ff00;
116
pConfigs[i].blueMask = 0x000000ff;
117
pConfigs[i].alphaMask = 0xff000000;
121
pConfigs[i].bufferSize = pScrn->bitsPerPixel;
122
pConfigs[i].visualRating = GLX_NONE;
123
pConfigs[i].transparentPixel = GLX_NONE;
127
pConfigs[0].doubleBuffer = FALSE;
128
pConfigs[1].doubleBuffer = TRUE;
129
pVBox->cVisualConfigs = cConfigs;
130
pVBox->pVisualConfigs = pConfigs;
131
TRACE_LOG("Calling GlxSetVisualConfigs\n");
132
GlxSetVisualConfigs(cConfigs, pConfigs, NULL);
136
TRACE_LOG("returning %s\n", BOOL_STR(rc));
142
VBOXDoWakeupHandler(int screenNum, pointer wakeupData, unsigned long result,
151
VBOXDoBlockHandler(int screenNum, pointer blockData, pointer pTimeout,
158
Bool VBOXDRIScreenInit(int scrnIndex, ScreenPtr pScreen, VBOXPtr pVBox)
160
DRIInfoPtr pDRIInfo = NULL;
162
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
166
if ( pScrn->bitsPerPixel != 16
167
&& pScrn->bitsPerPixel != 32)
169
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
170
"DRI is only available in 16bpp or 32bpp graphics modes.\n");
174
if ( (pScrn->displayWidth == 0)
175
|| (pVBox->pciInfo == NULL)
176
|| (pVBox->base == NULL)
177
|| (pVBox->cbFBMax == 0))
179
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "%s: preconditions failed\n",
180
__PRETTY_FUNCTION__);
183
/* Check that the GLX, DRI, and DRM modules have been loaded by testing for
184
* canonical symbols in each module, the way all existing _dri drivers do.
188
TRACE_LOG("Checking symbols\n");
189
if ( !xf86LoaderCheckSymbol("GlxSetVisualConfigs")
190
|| !xf86LoaderCheckSymbol("drmAvailable")
191
|| !xf86LoaderCheckSymbol("DRIQueryVersion"))
193
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
194
"Disabling DRI due to missing server functionality.\n");
198
/* Check the DRI version */
201
int major, minor, patch;
202
TRACE_LOG("Checking DRI version\n");
203
DRIQueryVersion(&major, &minor, &patch);
204
if (major != DRIINFO_MAJOR_VERSION || minor < DRIINFO_MINOR_VERSION)
206
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
207
"Disabling DRI due to a version mismatch between server and driver. Server version: %d.%d. Driver version: %d.%d\n",
208
major, minor, DRIINFO_MAJOR_VERSION, DRIINFO_MINOR_VERSION);
214
TRACE_LOG("Creating DRIInfoRec\n");
215
pDRIInfo = DRICreateInfoRec();
218
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
219
"Disabling DRI: out of memory.\n");
223
pVBox->pDRIInfo = pDRIInfo;
227
pDRIInfo->CreateContext = VBOXCreateContext;
228
pDRIInfo->DestroyContext = VBOXDestroyContext;
229
pDRIInfo->SwapContext = VBOXDRISwapContext;
230
pDRIInfo->InitBuffers = VBOXDRIInitBuffers;
231
pDRIInfo->MoveBuffers = VBOXDRIMoveBuffers;
232
pDRIInfo->OpenFullScreen = VBOXDRIOpenFullScreen;
233
pDRIInfo->CloseFullScreen = VBOXDRICloseFullScreen;
234
pDRIInfo->TransitionTo2d = VBOXDRITransitionTo2d;
235
pDRIInfo->TransitionTo3d = VBOXDRITransitionTo3d;
237
/* These two are set in DRICreateInfoRec(). */
238
pDRIInfo->wrap.ValidateTree = NULL;
239
pDRIInfo->wrap.PostValidateTree = NULL;
241
pDRIInfo->drmDriverName = VBOX_DRM_DRIVER_NAME;
242
pDRIInfo->clientDriverName = VBOX_DRI_DRIVER_NAME;
244
pDRIInfo->busIdString = DRICreatePCIBusID(pVBox->pciInfo);
246
pDRIInfo->busIdString = alloc(64);
247
sprintf(pDRIInfo->busIdString, "PCI:%d:%d:%d",
248
((pciConfigPtr)pVBox->pciInfo->thisCard)->busnum,
249
((pciConfigPtr)pVBox->pciInfo->thisCard)->devnum,
250
((pciConfigPtr)pVBox->pciInfo->thisCard)->funcnum);
252
pDRIInfo->ddxDriverMajorVersion = VBOX_VIDEO_MAJOR;
253
pDRIInfo->ddxDriverMinorVersion = VBOX_VIDEO_MINOR;
254
pDRIInfo->ddxDriverPatchVersion = 0;
255
pDRIInfo->ddxDrawableTableEntry = VBOX_MAX_DRAWABLES;
256
pDRIInfo->maxDrawableTableEntry = VBOX_MAX_DRAWABLES;
257
pDRIInfo->frameBufferPhysicalAddress = (pointer)pScrn->memPhysBase;
258
pDRIInfo->frameBufferSize = pVBox->cbFBMax;
259
pDRIInfo->frameBufferStride = pScrn->displayWidth
260
* pScrn->bitsPerPixel / 8;
261
pDRIInfo->SAREASize = SAREA_MAX; /* we have no private bits yet. */
262
/* This can't be zero, as the server callocs this size and checks for
264
pDRIInfo->contextSize = 4;
265
pDRIInfo->driverSwapMethod = DRI_HIDE_X_CONTEXT;
266
pDRIInfo->bufferRequests = DRI_ALL_WINDOWS;
267
TRACE_LOG("Calling DRIScreenInit\n");
268
if (!DRIScreenInit(pScreen, pDRIInfo, &pVBox->drmFD))
271
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
272
"DRIScreenInit failed, disabling DRI.\n");
274
if (rc && !VBOXInitVisualConfigs(pScrn, pVBox))
276
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
277
"VBOXInitVisualConfigs failed, disabling DRI.\n");
280
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "visual configurations initialized\n");
282
/* Check the DRM version */
285
drmVersionPtr version = drmGetVersion(pVBox->drmFD);
286
TRACE_LOG("Checking DRM version\n");
289
if (version->version_major != 1 || version->version_minor < 0)
291
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
292
"Bad DRM driver version %d.%d, expected version 1.0. Disabling DRI.\n",
293
version->version_major, version->version_minor);
296
drmFreeVersion(version);
300
/* Clean up on failure. */
304
DRIDestroyInfoRec(pVBox->pDRIInfo);
305
pVBox->pDRIInfo = NULL;
306
if (pVBox->drmFD >= 0)
307
VBOXDRICloseScreen(pScreen, pVBox);
310
TRACE_LOG("returning %s\n", BOOL_STR(rc));
314
void VBOXDRIUpdateStride(ScrnInfoPtr pScrn, VBOXPtr pVBox)
316
DRIInfoPtr pDRIInfo = pVBox->pDRIInfo;
317
pDRIInfo->frameBufferStride = pScrn->displayWidth
318
* pScrn->bitsPerPixel / 8;
322
VBOXDRICloseScreen(ScreenPtr pScreen, VBOXPtr pVBox)
324
DRICloseScreen(pScreen);
325
DRIDestroyInfoRec(pVBox->pDRIInfo);
327
if (pVBox->pVisualConfigs)
328
free(pVBox->pVisualConfigs);
329
pVBox->cVisualConfigs = 0;
330
pVBox->pVisualConfigs = NULL;
334
VBOXCreateContext(ScreenPtr pScreen, VisualPtr visual,
335
drm_context_t hwContext, void *pVisualConfigPriv,
336
DRIContextType contextStore)
342
VBOXDestroyContext(ScreenPtr pScreen, drm_context_t hwContext,
343
DRIContextType contextStore)
348
VBOXDRIFinishScreenInit(ScreenPtr pScreen)
350
return DRIFinishScreenInit(pScreen);
354
VBOXDRISwapContext(ScreenPtr pScreen, DRISyncType syncType,
355
DRIContextType oldContextType, void *oldContext,
356
DRIContextType newContextType, void *newContext)
361
VBOXDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index)
366
VBOXDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg,
367
RegionPtr prgnSrc, CARD32 index)
371
/* Apparently the next two are just legacy. */
373
VBOXDRIOpenFullScreen(ScreenPtr pScreen)
379
VBOXDRICloseFullScreen(ScreenPtr pScreen)
385
VBOXDRITransitionTo2d(ScreenPtr pScreen)
390
VBOXDRITransitionTo3d(ScreenPtr pScreen)