2
* Copyright 2006 Stephane Marchesin
3
* Copyright 2006 Ben Skeggs
5
* Permission is hereby granted, free of charge, to any person obtaining a
6
* copy of this software and associated documentation files (the "Software"),
7
* to deal in the Software without restriction, including without limitation
8
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
9
* and/or sell copies of the Software, and to permit persons to whom the
10
* Software is furnished to do so, subject to the following conditions:
12
* The above copyright notice and this permission notice shall be included in
13
* all copies or substantial portions of the Software.
15
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18
* THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
20
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
#include "nv_include.h"
26
#define _XF86DRI_SERVER_
27
#include "GL/glxint.h"
28
#include "GL/glxtokens.h"
32
#include "nv_dripriv.h"
35
static Bool NVCreateContext(ScreenPtr pScreen, VisualPtr visual,
36
drm_context_t hwContext, void *pVisualConfigPriv,
37
DRIContextType contextStore)
43
static void NVDestroyContext(ScreenPtr pScreen, drm_context_t hwContext,
44
DRIContextType contextStore)
49
static void NVDRISwapContext(ScreenPtr pScreen, DRISyncType syncType,
50
DRIContextType oldContextType,
52
DRIContextType newContextType,
55
/* we really should do something here */
59
static void NVDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 indx)
64
static void NVDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg,
65
RegionPtr prgnSrc, CARD32 indx)
70
static void NVDRITransitionTo2d(ScreenPtr pScreen)
75
static void NVDRITransitionTo3d(ScreenPtr pScreen)
80
static void NVDRITransitionSingleToMulti3d(ScreenPtr pScreen)
85
static void NVDRITransitionMultiToSingle3d(ScreenPtr pScreen)
90
static Bool NVDRIInitVisualConfigs(ScreenPtr pScreen)
92
ScrnInfoPtr pScrn=xf86Screens[pScreen->myNum];
93
__GLXvisualConfig* pConfigs = NULL;
94
NVConfigPrivPtr pNVConfigs = NULL;
95
NVConfigPrivPtr* pNVConfigPtrs = NULL;
96
int db,depth,alpha,stencil;
97
int depths[]={24,16,0};
104
num_configs=2*3*((pScrn->depth==24)?2:1)*2; /* db*depth*alpha*stencil */
105
if (!(pConfigs=(__GLXvisualConfig*)xcalloc(sizeof(__GLXvisualConfig),num_configs)))
107
if (!(pNVConfigs=(NVConfigPrivPtr)xcalloc(sizeof(NVConfigPrivRec), num_configs))) {
111
if (!(pNVConfigPtrs=(NVConfigPrivPtr *)xcalloc(sizeof(NVConfigPrivPtr),num_configs))) {
119
for(depth=0;depth<3;depth++)
120
for(alpha=0;alpha<((pScrn->depth==24)?2:1);alpha++)
121
for(stencil=0;stencil<2;stencil++)
123
pConfigs[i].vid = (VisualID)(-1);
124
pConfigs[i].class = -1;
125
pConfigs[i].rgba = TRUE;
126
if (pScrn->depth==16)
128
pConfigs[i].redSize = 5;
129
pConfigs[i].greenSize = 6;
130
pConfigs[i].blueSize = 5;
131
pConfigs[i].alphaSize = 0;
132
pConfigs[i].redMask = 0x0000F800;
133
pConfigs[i].greenMask = 0x000007E0;
134
pConfigs[i].blueMask = 0x0000001F;
135
pConfigs[i].alphaMask = 0x00000000;
137
pConfigs[i].redSize = 8;
138
pConfigs[i].greenSize = 8;
139
pConfigs[i].blueSize = 8;
140
pConfigs[i].redMask = 0x00FF0000;
141
pConfigs[i].greenMask = 0x0000FF00;
142
pConfigs[i].blueMask = 0x000000FF;
144
pConfigs[i].alphaSize = 8;
145
pConfigs[i].alphaMask = 0xFF000000;
147
pConfigs[i].alphaSize = 0;
148
pConfigs[i].alphaMask = 0x00000000;
152
pConfigs[i].accumRedSize = 0;
153
pConfigs[i].accumGreenSize = 0;
154
pConfigs[i].accumBlueSize = 0;
155
pConfigs[i].accumAlphaSize = 0;
157
pConfigs[i].doubleBuffer = TRUE;
159
pConfigs[i].doubleBuffer = FALSE;
160
pConfigs[i].stereo = FALSE;
161
pConfigs[i].bufferSize = pScrn->depth;
162
if (depths[depth] == 24 && stencil) {
163
pConfigs[i].depthSize = depths[depth];
164
pConfigs[i].stencilSize = 8;
166
pConfigs[i].depthSize = depths[depth];
167
pConfigs[i].stencilSize = 0;
169
pConfigs[i].auxBuffers = 0;
170
pConfigs[i].level = 0;
171
pConfigs[i].visualRating = GLX_NONE;
172
pConfigs[i].transparentPixel = GLX_NONE;
173
pConfigs[i].transparentRed = 0;
174
pConfigs[i].transparentGreen = 0;
175
pConfigs[i].transparentBlue = 0;
176
pConfigs[i].transparentAlpha = 0;
177
pConfigs[i].transparentIndex = 0;
182
xf86DrvMsg(pScreen->myNum, X_ERROR, "[dri] no DRI at %d bpp ",pScrn->depth);
185
GlxSetVisualConfigs(num_configs, pConfigs, (void**)pNVConfigPtrs);
189
Bool NVDRIGetVersion(ScrnInfoPtr pScrn)
191
NVPtr pNv = NVPTR(pScrn);
195
ret = LoadSubModule(pScrn->module, "dri", NULL, NULL, NULL,
196
NULL, &errmaj, &errmin);
198
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
199
"error %d\n", errmaj);
200
LoaderErrorMsg(pScrn->name, "dri", errmaj, errmin);
203
if (!ret && errmaj != LDR_ONCEONLY)
206
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Loaded DRI module\n");
208
/* Check the lib version */
209
if (xf86LoaderCheckSymbol("drmGetLibVersion"))
210
pNv->pLibDRMVersion = drmGetLibVersion(0);
211
if (pNv->pLibDRMVersion == NULL) {
212
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
213
"NVDRIGetVersion failed because libDRM is really "
214
"way to old to even get a version number out of it.\n"
215
"[dri] Disabling DRI.\n");
222
Bool NVDRICheckModules(ScrnInfoPtr pScrn)
224
if (!xf86LoaderCheckSymbol("GlxSetVisualConfigs")) {
225
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
226
"[dri] GlxSetVisualConfigs not found.\n");
227
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
228
" NVIDIA's glx present, or glx not loaded.\n");
235
Bool NVDRIScreenInit(ScrnInfoPtr pScrn)
238
NOUVEAUDRIPtr pNOUVEAUDRI;
239
NVPtr pNv = NVPTR(pScrn);
241
pScreen = screenInfo.screens[pScrn->scrnIndex];
244
if (!NVDRICheckModules(pScrn))
247
drm_page_size = getpagesize();
248
if (!(pDRIInfo = DRICreateInfoRec())) return FALSE;
250
pDRIInfo->drmDriverName = "nouveau";
251
pDRIInfo->clientDriverName = "nouveau";
252
pDRIInfo->busIdString = DRICreatePCIBusID(pNv->PciInfo);
254
pDRIInfo->ddxDriverMajorVersion = NV_MAJOR_VERSION;
255
pDRIInfo->ddxDriverMinorVersion = NV_MINOR_VERSION;
256
pDRIInfo->ddxDriverPatchVersion = NV_PATCHLEVEL;
258
pDRIInfo->frameBufferSize = getpagesize();
259
pDRIInfo->frameBufferPhysicalAddress = (void *)pNv->VRAMPhysical;
260
pDRIInfo->frameBufferStride = pScrn->displayWidth * pScrn->bitsPerPixel/8;
262
pDRIInfo->ddxDrawableTableEntry = 1;
263
pDRIInfo->maxDrawableTableEntry = 1;
265
if (!(pNOUVEAUDRI = (NOUVEAUDRIPtr)xcalloc(sizeof(NOUVEAUDRIRec), 1))) {
266
DRIDestroyInfoRec(pDRIInfo);
269
pDRIInfo->devPrivate = pNOUVEAUDRI;
270
pDRIInfo->devPrivateSize = sizeof(NOUVEAUDRIRec);
271
pDRIInfo->contextSize = sizeof(NVDRIContextRec);
272
pDRIInfo->SAREASize = (drm_page_size > SAREA_MAX) ? drm_page_size : SAREA_MAX;
274
pDRIInfo->CreateContext = NVCreateContext;
275
pDRIInfo->DestroyContext = NVDestroyContext;
276
pDRIInfo->SwapContext = NVDRISwapContext;
277
pDRIInfo->InitBuffers = NVDRIInitBuffers;
278
pDRIInfo->MoveBuffers = NVDRIMoveBuffers;
279
pDRIInfo->bufferRequests = DRI_ALL_WINDOWS;
280
pDRIInfo->TransitionTo2d = NVDRITransitionTo2d;
281
pDRIInfo->TransitionTo3d = NVDRITransitionTo3d;
282
pDRIInfo->TransitionSingleToMulti3D = NVDRITransitionSingleToMulti3d;
283
pDRIInfo->TransitionMultiToSingle3D = NVDRITransitionMultiToSingle3d;
285
pDRIInfo->createDummyCtx = FALSE;
286
pDRIInfo->createDummyCtxPriv = FALSE;
288
pDRIInfo->keepFDOpen = TRUE;
290
if (!DRIScreenInit(pScreen, pDRIInfo, &nouveau_device(pNv->dev)->fd)) {
291
xf86DrvMsg(pScreen->myNum, X_ERROR,
292
"[dri] DRIScreenInit failed. Disabling DRI.\n");
293
xfree(pDRIInfo->devPrivate);
294
pDRIInfo->devPrivate = NULL;
295
DRIDestroyInfoRec(pDRIInfo);
299
if (!NVDRIInitVisualConfigs(pScreen)) {
300
xf86DrvMsg(pScreen->myNum, X_ERROR,
301
"[dri] NVDRIInitVisualConfigs failed."
302
" Disabling DRI.\n");
303
DRICloseScreen(pScreen);
304
xfree(pDRIInfo->devPrivate);
305
pDRIInfo->devPrivate = NULL;
306
DRIDestroyInfoRec(pDRIInfo);
310
pNv->pDRIInfo = pDRIInfo;
314
Bool NVDRIFinishScreenInit(ScrnInfoPtr pScrn, bool update)
316
ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
317
NVPtr pNv = NVPTR(pScrn);
318
NOUVEAUDRIPtr pNOUVEAUDRI;
325
if (!DRIFinishScreenInit(pScreen))
329
pNOUVEAUDRI = (NOUVEAUDRIPtr)pNv->pDRIInfo->devPrivate;
331
pNOUVEAUDRI->device_id = pNv->Chipset;
333
pNOUVEAUDRI->width = pScrn->virtualX;
334
pNOUVEAUDRI->height = pScrn->virtualY;
335
pNOUVEAUDRI->depth = pScrn->depth;
336
pNOUVEAUDRI->bpp = pScrn->bitsPerPixel;
338
ret = nouveau_bo_handle_get(pNv->scanout, &pNOUVEAUDRI->front_offset);
340
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
341
"[dri] unable to reference front buffer: %d\n", ret);
344
pNOUVEAUDRI->front_pitch = pScrn->displayWidth;
345
/* back/depth buffers will likely be allocated on a per-drawable
346
* basis, but these may be useful if we want to support shared back
347
* buffers at some point.
349
pNOUVEAUDRI->back_offset = 0;
350
pNOUVEAUDRI->back_pitch = 0;
351
pNOUVEAUDRI->depth_offset = 0;
352
pNOUVEAUDRI->depth_pitch = 0;
357
void NVDRICloseScreen(ScrnInfoPtr pScrn)
359
ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
360
NVPtr pNv = NVPTR(pScrn);
365
DRICloseScreen(pScreen);
368
if (pNv->pDRIInfo->devPrivate) {
369
xfree(pNv->pDRIInfo->devPrivate);
370
pNv->pDRIInfo->devPrivate = NULL;
372
DRIDestroyInfoRec(pNv->pDRIInfo);
373
pNv->pDRIInfo = NULL;