VirtualBox

source: vbox/trunk/src/VBox/Additions/x11/vboxvideo/vboxvideo_dri.c@ 52235

Last change on this file since 52235 was 49696, checked in by vboxsync, 11 years ago

Additions/x11/vboxvideo: fixes for when DRI fails to initialise.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.6 KB
Line 
1/** @file $Id: vboxvideo_dri.c 49696 2013-11-28 09:46:38Z vboxsync $
2 *
3 * VirtualBox X11 Additions graphics driver, DRI 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 * This code is based on:
19 *
20 * X11 TDFX driver, src/tdfx_dri.c
21 *
22 * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
23 * All Rights Reserved.
24 *
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:
32 *
33 * The above copyright notice and this permission notice (including the
34 * next paragraph) shall be included in all copies or substantial portions
35 * of the Software.
36 *
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.
44 *
45 * Authors:
46 * Daryll Strauss <[email protected]>
47 */
48
49#include "xf86.h"
50#include "vboxvideo.h"
51#ifndef PCIACCESS
52# include "xf86Pci.h"
53#endif
54#include <dri.h>
55#include <GL/glxtokens.h>
56#include <GL/glxint.h>
57#include <drm.h>
58
59static Bool
60VBOXCreateContext(ScreenPtr pScreen, VisualPtr visual,
61 drm_context_t hwContext, void *pVisualConfigPriv,
62 DRIContextType contextStore);
63static void
64VBOXDestroyContext(ScreenPtr pScreen, drm_context_t hwContext,
65 DRIContextType contextStore);
66static void
67VBOXDRISwapContext(ScreenPtr pScreen, DRISyncType syncType,
68 DRIContextType oldContextType, void *oldContext,
69 DRIContextType newContextType, void *newContext);
70static void
71VBOXDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index);
72static void
73VBOXDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg,
74 RegionPtr prgnSrc, CARD32 index);
75static Bool
76VBOXDRIOpenFullScreen(ScreenPtr pScreen);
77static Bool
78VBOXDRICloseFullScreen(ScreenPtr pScreen);
79static void
80VBOXDRITransitionTo2d(ScreenPtr pScreen);
81static void
82VBOXDRITransitionTo3d(ScreenPtr pScreen);
83
84static Bool
85VBOXInitVisualConfigs(ScrnInfoPtr pScrn, VBOXPtr pVBox)
86{
87 Bool rc = TRUE;
88 TRACE_ENTRY();
89 int cConfigs = 2; /* With and without double buffering */
90 __GLXvisualConfig *pConfigs = NULL;
91 pConfigs = (__GLXvisualConfig*) calloc(sizeof(__GLXvisualConfig),
92 cConfigs);
93 if (!pConfigs)
94 {
95 rc = FALSE;
96 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
97 "Disabling DRI: out of memory.\n");
98 }
99 for (int i = 0; rc && i < cConfigs; ++i)
100 {
101 pConfigs[i].vid = -1;
102 pConfigs[i].class = -1;
103 pConfigs[i].rgba = TRUE;
104 if (pScrn->bitsPerPixel == 16)
105 {
106 pConfigs[i].redSize = 5;
107 pConfigs[i].greenSize = 6;
108 pConfigs[i].blueSize = 5;
109 pConfigs[i].redMask = 0x0000F800;
110 pConfigs[i].greenMask = 0x000007E0;
111 pConfigs[i].blueMask = 0x0000001F;
112 }
113 else if (pScrn->bitsPerPixel == 32)
114 {
115 pConfigs[i].redSize = 8;
116 pConfigs[i].greenSize = 8;
117 pConfigs[i].blueSize = 8;
118 pConfigs[i].alphaSize = 8;
119 pConfigs[i].redMask = 0x00ff0000;
120 pConfigs[i].greenMask = 0x0000ff00;
121 pConfigs[i].blueMask = 0x000000ff;
122 pConfigs[i].alphaMask = 0xff000000;
123 }
124 else
125 rc = FALSE;
126 pConfigs[i].bufferSize = pScrn->bitsPerPixel;
127 pConfigs[i].visualRating = GLX_NONE;
128 pConfigs[i].transparentPixel = GLX_NONE;
129 }
130 if (rc)
131 {
132 pConfigs[0].doubleBuffer = FALSE;
133 pConfigs[1].doubleBuffer = TRUE;
134 pVBox->cVisualConfigs = cConfigs;
135 pVBox->pVisualConfigs = pConfigs;
136 TRACE_LOG("Calling GlxSetVisualConfigs\n");
137 GlxSetVisualConfigs(cConfigs, pConfigs, NULL);
138 }
139 if (!rc && pConfigs)
140 free(pConfigs);
141 TRACE_LOG("returning %s\n", BOOL_STR(rc));
142 return rc;
143}
144
145#if 0
146static void
147VBOXDoWakeupHandler(int screenNum, pointer wakeupData, unsigned long result,
148 pointer pReadmask)
149{
150
151}
152#endif
153
154#if 0
155static void
156VBOXDoBlockHandler(int screenNum, pointer blockData, pointer pTimeout,
157 pointer pReadmask)
158{
159
160}
161#endif
162
163Bool VBOXDRIScreenInit(ScrnInfoPtr pScrn, ScreenPtr pScreen, VBOXPtr pVBox)
164{
165 DRIInfoPtr pDRIInfo = NULL;
166 Bool rc = TRUE;
167
168 TRACE_ENTRY();
169 pVBox->drmFD = -1;
170 if ( pScrn->bitsPerPixel != 16
171 && pScrn->bitsPerPixel != 32)
172 {
173 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
174 "DRI is only available in 16bpp or 32bpp graphics modes.\n");
175 rc = FALSE;
176 }
177 /* Assertion */
178 if ( (pScrn->displayWidth == 0)
179 || (pVBox->pciInfo == NULL)
180 || (pVBox->base == NULL)
181 || (pVBox->cbFBMax == 0))
182 {
183 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "%s: preconditions failed\n",
184 __PRETTY_FUNCTION__);
185 rc = FALSE;
186 }
187 /* Check that the GLX, DRI, and DRM modules have been loaded by testing for
188 * canonical symbols in each module, the way all existing _dri drivers do.
189 */
190 if (rc)
191 {
192 TRACE_LOG("Checking symbols\n");
193 if ( !xf86LoaderCheckSymbol("GlxSetVisualConfigs")
194 || !xf86LoaderCheckSymbol("drmAvailable")
195 || !xf86LoaderCheckSymbol("DRIQueryVersion"))
196 {
197 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
198 "Disabling DRI due to missing server functionality.\n");
199 rc = FALSE;
200 }
201 }
202 /* Check the DRI version */
203 if (rc)
204 {
205 int major, minor, patch;
206 TRACE_LOG("Checking DRI version\n");
207 DRIQueryVersion(&major, &minor, &patch);
208 if (major != DRIINFO_MAJOR_VERSION || minor < DRIINFO_MINOR_VERSION)
209 {
210 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
211 "Disabling DRI due to a version mismatch between server and driver. Server version: %d.%d. Driver version: %d.%d\n",
212 major, minor, DRIINFO_MAJOR_VERSION, DRIINFO_MINOR_VERSION);
213 rc = FALSE;
214 }
215 }
216 if (rc)
217 {
218 TRACE_LOG("Creating DRIInfoRec\n");
219 pDRIInfo = DRICreateInfoRec();
220 if (!pDRIInfo)
221 {
222 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
223 "Disabling DRI: out of memory.\n");
224 rc = FALSE;
225 }
226 else
227 pVBox->pDRIInfo = pDRIInfo;
228 }
229 if (rc)
230 {
231 pDRIInfo->CreateContext = VBOXCreateContext;
232 pDRIInfo->DestroyContext = VBOXDestroyContext;
233 pDRIInfo->SwapContext = VBOXDRISwapContext;
234 pDRIInfo->InitBuffers = VBOXDRIInitBuffers;
235 pDRIInfo->MoveBuffers = VBOXDRIMoveBuffers;
236 pDRIInfo->OpenFullScreen = VBOXDRIOpenFullScreen;
237 pDRIInfo->CloseFullScreen = VBOXDRICloseFullScreen;
238 pDRIInfo->TransitionTo2d = VBOXDRITransitionTo2d;
239 pDRIInfo->TransitionTo3d = VBOXDRITransitionTo3d;
240
241 /* These two are set in DRICreateInfoRec(). */
242 pDRIInfo->wrap.ValidateTree = NULL;
243 pDRIInfo->wrap.PostValidateTree = NULL;
244
245 pDRIInfo->drmDriverName = VBOX_DRM_DRIVER_NAME;
246 pDRIInfo->clientDriverName = VBOX_DRI_DRIVER_NAME;
247#ifdef PCIACCESS
248 pDRIInfo->busIdString = DRICreatePCIBusID(pVBox->pciInfo);
249#else
250 pDRIInfo->busIdString = alloc(64);
251 sprintf(pDRIInfo->busIdString, "PCI:%d:%d:%d",
252 ((pciConfigPtr)pVBox->pciInfo->thisCard)->busnum,
253 ((pciConfigPtr)pVBox->pciInfo->thisCard)->devnum,
254 ((pciConfigPtr)pVBox->pciInfo->thisCard)->funcnum);
255#endif
256 pDRIInfo->ddxDriverMajorVersion = VBOX_VIDEO_MAJOR;
257 pDRIInfo->ddxDriverMinorVersion = VBOX_VIDEO_MINOR;
258 pDRIInfo->ddxDriverPatchVersion = 0;
259 pDRIInfo->ddxDrawableTableEntry = VBOX_MAX_DRAWABLES;
260 pDRIInfo->maxDrawableTableEntry = VBOX_MAX_DRAWABLES;
261 pDRIInfo->frameBufferPhysicalAddress = (pointer)pScrn->memPhysBase;
262 pDRIInfo->frameBufferSize = pVBox->cbFBMax;
263 pDRIInfo->frameBufferStride = pScrn->displayWidth
264 * pScrn->bitsPerPixel / 8;
265 pDRIInfo->SAREASize = SAREA_MAX; /* we have no private bits yet. */
266 /* This can't be zero, as the server callocs this size and checks for
267 * non-NULL... */
268 pDRIInfo->contextSize = 4;
269 pDRIInfo->driverSwapMethod = DRI_HIDE_X_CONTEXT;
270 pDRIInfo->bufferRequests = DRI_ALL_WINDOWS;
271 TRACE_LOG("Calling DRIScreenInit\n");
272 if (!DRIScreenInit(pScreen, pDRIInfo, &pVBox->drmFD))
273 {
274 rc = FALSE;
275 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
276 "DRIScreenInit failed, disabling DRI.\n");
277 if (pVBox->drmFD)
278 {
279 drmClose(pVBox->drmFD);
280 pVBox->drmFD = -1;
281 }
282 }
283 }
284 if (rc && !VBOXInitVisualConfigs(pScrn, pVBox))
285 {
286 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
287 "VBOXInitVisualConfigs failed, disabling DRI.\n");
288 rc = FALSE;
289 }
290 else
291 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "visual configurations initialized\n");
292
293 /* Check the DRM version */
294 if (rc)
295 {
296 drmVersionPtr version = drmGetVersion(pVBox->drmFD);
297 TRACE_LOG("Checking DRM version\n");
298 if (version)
299 {
300 if (version->version_major != 1 || version->version_minor < 0)
301 {
302 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
303 "Bad DRM driver version %d.%d, expected version 1.0. Disabling DRI.\n",
304 version->version_major, version->version_minor);
305 rc = FALSE;
306 }
307 drmFreeVersion(version);
308 }
309 }
310
311 /* Clean up on failure. */
312 if (!rc)
313 {
314 if (pVBox->drmFD >= 0)
315 VBOXDRICloseScreen(pScreen, pVBox);
316 pVBox->drmFD = -1;
317 if (pVBox->pDRIInfo)
318 DRIDestroyInfoRec(pVBox->pDRIInfo);
319 pVBox->pDRIInfo = NULL;
320 }
321 TRACE_LOG("returning %s\n", BOOL_STR(rc));
322 return rc;
323}
324
325void VBOXDRIUpdateStride(ScrnInfoPtr pScrn, VBOXPtr pVBox)
326{
327 DRIInfoPtr pDRIInfo = pVBox->pDRIInfo;
328 pDRIInfo->frameBufferStride = pScrn->displayWidth
329 * pScrn->bitsPerPixel / 8;
330}
331
332void
333VBOXDRICloseScreen(ScreenPtr pScreen, VBOXPtr pVBox)
334{
335 DRICloseScreen(pScreen);
336 DRIDestroyInfoRec(pVBox->pDRIInfo);
337 pVBox->pDRIInfo=0;
338 if (pVBox->pVisualConfigs)
339 free(pVBox->pVisualConfigs);
340 pVBox->cVisualConfigs = 0;
341 pVBox->pVisualConfigs = NULL;
342}
343
344static Bool
345VBOXCreateContext(ScreenPtr pScreen, VisualPtr visual,
346 drm_context_t hwContext, void *pVisualConfigPriv,
347 DRIContextType contextStore)
348{
349 return TRUE;
350}
351
352static void
353VBOXDestroyContext(ScreenPtr pScreen, drm_context_t hwContext,
354 DRIContextType contextStore)
355{
356}
357
358Bool
359VBOXDRIFinishScreenInit(ScreenPtr pScreen)
360{
361 return DRIFinishScreenInit(pScreen);
362}
363
364static void
365VBOXDRISwapContext(ScreenPtr pScreen, DRISyncType syncType,
366 DRIContextType oldContextType, void *oldContext,
367 DRIContextType newContextType, void *newContext)
368{
369}
370
371static void
372VBOXDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index)
373{
374}
375
376static void
377VBOXDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg,
378 RegionPtr prgnSrc, CARD32 index)
379{
380}
381
382/* Apparently the next two are just legacy. */
383static Bool
384VBOXDRIOpenFullScreen(ScreenPtr pScreen)
385{
386 return TRUE;
387}
388
389static Bool
390VBOXDRICloseFullScreen(ScreenPtr pScreen)
391{
392 return TRUE;
393}
394
395static void
396VBOXDRITransitionTo2d(ScreenPtr pScreen)
397{
398}
399
400static void
401VBOXDRITransitionTo3d(ScreenPtr pScreen)
402{
403}
404
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