1 #include "nv_include.h"
3 #define _XF86DRI_SERVER_
5 #include "GL/glxtokens.h"
9 #include "nv_dripriv.h"
12 static Bool NVCreateContext(ScreenPtr pScreen, VisualPtr visual,
13 drm_context_t hwContext, void *pVisualConfigPriv,
14 DRIContextType contextStore)
20 static void NVDestroyContext(ScreenPtr pScreen, drm_context_t hwContext,
21 DRIContextType contextStore)
26 static void NVDRISwapContext(ScreenPtr pScreen, DRISyncType syncType,
27 DRIContextType oldContextType,
29 DRIContextType newContextType,
32 /* we really should do something here */
36 static void NVDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 indx)
41 static void NVDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg,
42 RegionPtr prgnSrc, CARD32 indx)
47 static void NVDRITransitionTo2d(ScreenPtr pScreen)
52 static void NVDRITransitionTo3d(ScreenPtr pScreen)
57 static void NVDRITransitionSingleToMulti3d(ScreenPtr pScreen)
62 static void NVDRITransitionMultiToSingle3d(ScreenPtr pScreen)
67 static Bool NVDRIInitVisualConfigs(ScreenPtr pScreen)
69 ScrnInfoPtr pScrn=xf86Screens[pScreen->myNum];
70 __GLXvisualConfig* pConfigs = NULL;
71 NVConfigPrivPtr pNVConfigs = NULL;
72 NVConfigPrivPtr* pNVConfigPtrs = NULL;
73 int db,depth,alpha,stencil;
74 int depths[]={24,16,0};
81 num_configs=2*3*((pScrn->depth==24)?2:1)*2; /* db*depth*alpha*stencil */
82 if (!(pConfigs=(__GLXvisualConfig*)xcalloc(sizeof(__GLXvisualConfig),num_configs)))
84 if (!(pNVConfigs=(NVConfigPrivPtr)xcalloc(sizeof(NVConfigPrivRec), num_configs))) {
88 if (!(pNVConfigPtrs=(NVConfigPrivPtr *)xcalloc(sizeof(NVConfigPrivPtr),num_configs))) {
96 for(depth=0;depth<3;depth++)
97 for(alpha=0;alpha<((pScrn->depth==24)?2:1);alpha++)
98 for(stencil=0;stencil<2;stencil++)
100 pConfigs[i].vid = (VisualID)(-1);
101 pConfigs[i].class = -1;
102 pConfigs[i].rgba = TRUE;
103 if (pScrn->depth==16)
105 pConfigs[i].redSize = 5;
106 pConfigs[i].greenSize = 6;
107 pConfigs[i].blueSize = 5;
108 pConfigs[i].alphaSize = 0;
109 pConfigs[i].redMask = 0x0000F800;
110 pConfigs[i].greenMask = 0x000007E0;
111 pConfigs[i].blueMask = 0x0000001F;
112 pConfigs[i].alphaMask = 0x00000000;
114 pConfigs[i].redSize = 8;
115 pConfigs[i].greenSize = 8;
116 pConfigs[i].blueSize = 8;
117 pConfigs[i].redMask = 0x00FF0000;
118 pConfigs[i].greenMask = 0x0000FF00;
119 pConfigs[i].blueMask = 0x000000FF;
121 pConfigs[i].alphaSize = 8;
122 pConfigs[i].alphaMask = 0xFF000000;
124 pConfigs[i].alphaSize = 0;
125 pConfigs[i].alphaMask = 0x00000000;
129 pConfigs[i].accumRedSize = 0;
130 pConfigs[i].accumGreenSize = 0;
131 pConfigs[i].accumBlueSize = 0;
132 pConfigs[i].accumAlphaSize = 0;
134 pConfigs[i].doubleBuffer = TRUE;
136 pConfigs[i].doubleBuffer = FALSE;
137 pConfigs[i].stereo = FALSE;
138 pConfigs[i].bufferSize = pScrn->depth;
139 if (depths[depth] == 24 && stencil) {
140 pConfigs[i].depthSize = depths[depth];
141 pConfigs[i].stencilSize = 8;
143 pConfigs[i].depthSize = depths[depth];
144 pConfigs[i].stencilSize = 0;
146 pConfigs[i].auxBuffers = 0;
147 pConfigs[i].level = 0;
148 pConfigs[i].visualRating = GLX_NONE;
149 pConfigs[i].transparentPixel = GLX_NONE;
150 pConfigs[i].transparentRed = 0;
151 pConfigs[i].transparentGreen = 0;
152 pConfigs[i].transparentBlue = 0;
153 pConfigs[i].transparentAlpha = 0;
154 pConfigs[i].transparentIndex = 0;
159 xf86DrvMsg(pScreen->myNum, X_ERROR, "[dri] no DRI at %d bpp ",pScrn->depth);
162 GlxSetVisualConfigs(num_configs, pConfigs, (void**)pNVConfigPtrs);
166 Bool NVDRIGetVersion(ScrnInfoPtr pScrn)
168 NVPtr pNv = NVPTR(pScrn);
176 ret = LoadSubModule(pScrn->module, "dri", NULL, NULL, NULL,
177 NULL, &errmaj, &errmin);
179 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
180 "error %d\n", errmaj);
181 LoaderErrorMsg(pScrn->name, "dri", errmaj, errmin);
184 if (!ret && errmaj != LDR_ONCEONLY)
188 xf86LoaderReqSymLists(drmSymbols, NULL);
189 xf86LoaderReqSymLists(driSymbols, NULL);
190 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Loaded DRI module\n");
192 busId = DRICreatePCIBusID(pNv->PciInfo);
194 fd = drmOpen("nouveau", busId);
197 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
198 "[dri] Failed to open the DRM\n");
202 /* Check the lib version */
203 if (xf86LoaderCheckSymbol("drmGetLibVersion"))
204 pNv->pLibDRMVersion = drmGetLibVersion(0);
205 if (pNv->pLibDRMVersion == NULL) {
206 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
207 "NVDRIGetVersion failed because libDRM is really "
208 "way to old to even get a version number out of it.\n"
209 "[dri] Disabling DRI.\n");
213 pNv->pKernelDRMVersion = drmGetVersion(fd);
215 if (pNv->pKernelDRMVersion == NULL) {
216 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
217 "failed to get DRM version\n");
221 /* temporary lock step versioning */
222 #if NOUVEAU_DRM_HEADER_PATCHLEVEL != 10
223 #error nouveau_drm.h does not match expected patchlevel, update libdrm.
225 if (pNv->pKernelDRMVersion->version_patchlevel !=
226 NOUVEAU_DRM_HEADER_PATCHLEVEL) {
227 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
228 "wrong DRM version\n");
235 Bool NVDRICheckModules(ScrnInfoPtr pScrn)
237 if (!xf86LoaderCheckSymbol("GlxSetVisualConfigs")) {
238 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
239 "[dri] GlxSetVisualConfigs not found.\n");
240 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
241 " NVIDIA's glx present, or glx not loaded.\n");
248 Bool NVDRIScreenInit(ScrnInfoPtr pScrn)
251 NOUVEAUDRIPtr pNOUVEAUDRI;
252 NVPtr pNv = NVPTR(pScrn);
254 pScreen = screenInfo.screens[pScrn->scrnIndex];
258 if (!NVDRICheckModules(pScrn))
261 drm_page_size = getpagesize();
262 if (!(pDRIInfo = DRICreateInfoRec())) return FALSE;
264 pNv->pDRIInfo = pDRIInfo;
265 pDRIInfo->drmDriverName = "nouveau";
266 pDRIInfo->clientDriverName = "nouveau";
267 pDRIInfo->busIdString = DRICreatePCIBusID(pNv->PciInfo);
269 pDRIInfo->ddxDriverMajorVersion = NV_MAJOR_VERSION;
270 pDRIInfo->ddxDriverMinorVersion = NV_MINOR_VERSION;
271 pDRIInfo->ddxDriverPatchVersion = NV_PATCHLEVEL;
274 * We set the FB to be in the higher half of VRAM. If we don't, any
275 * VRAM allocations before the FB is mapped will change that map
277 * We should detect when the DRM decides to change the FB area
278 * but we currently don't know how to.
280 pDRIInfo->frameBufferSize = pNv->VRAMPhysicalSize / 2;
281 pDRIInfo->frameBufferPhysicalAddress = (void *)pNv->VRAMPhysical +
282 pDRIInfo->frameBufferSize;
283 pDRIInfo->frameBufferStride = pScrn->displayWidth * pScrn->bitsPerPixel/8;
285 pDRIInfo->ddxDrawableTableEntry = 1;
286 pDRIInfo->maxDrawableTableEntry = 1;
288 if (!(pNOUVEAUDRI = (NOUVEAUDRIPtr)xcalloc(sizeof(NOUVEAUDRIRec), 1))) {
289 DRIDestroyInfoRec(pDRIInfo);
290 pNv->pDRIInfo = NULL;
293 pDRIInfo->devPrivate = pNOUVEAUDRI;
294 pDRIInfo->devPrivateSize = sizeof(NOUVEAUDRIRec);
295 pDRIInfo->contextSize = sizeof(NVDRIContextRec);
296 pDRIInfo->SAREASize = (drm_page_size > SAREA_MAX) ? drm_page_size : SAREA_MAX;
298 pDRIInfo->CreateContext = NVCreateContext;
299 pDRIInfo->DestroyContext = NVDestroyContext;
300 pDRIInfo->SwapContext = NVDRISwapContext;
301 pDRIInfo->InitBuffers = NVDRIInitBuffers;
302 pDRIInfo->MoveBuffers = NVDRIMoveBuffers;
303 pDRIInfo->bufferRequests = DRI_ALL_WINDOWS;
304 pDRIInfo->TransitionTo2d = NVDRITransitionTo2d;
305 pDRIInfo->TransitionTo3d = NVDRITransitionTo3d;
306 pDRIInfo->TransitionSingleToMulti3D = NVDRITransitionSingleToMulti3d;
307 pDRIInfo->TransitionMultiToSingle3D = NVDRITransitionMultiToSingle3d;
309 pDRIInfo->createDummyCtx = FALSE;
310 pDRIInfo->createDummyCtxPriv = FALSE;
312 if (!DRIScreenInit(pScreen, pDRIInfo, &drm_fd)) {
313 xf86DrvMsg(pScreen->myNum, X_ERROR,
314 "[dri] DRIScreenInit failed. Disabling DRI.\n");
315 xfree(pDRIInfo->devPrivate);
316 pDRIInfo->devPrivate = NULL;
317 DRIDestroyInfoRec(pDRIInfo);
322 if (!NVDRIInitVisualConfigs(pScreen)) {
323 xf86DrvMsg(pScreen->myNum, X_ERROR,
324 "[dri] NVDRIInitVisualConfigs failed. Disabling DRI.\n");
325 xfree(pDRIInfo->devPrivate);
326 pDRIInfo->devPrivate = NULL;
327 DRIDestroyInfoRec(pDRIInfo);
332 if (nouveau_device_open_existing(&pNv->dev, 0, drm_fd, 0)) {
333 xf86DrvMsg(pScreen->myNum, X_ERROR, "Error creating device\n");
334 xfree(pDRIInfo->devPrivate);
335 pDRIInfo->devPrivate = NULL;
336 DRIDestroyInfoRec(pDRIInfo);
344 Bool NVDRIFinishScreenInit(ScrnInfoPtr pScrn)
346 ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
347 NVPtr pNv = NVPTR(pScrn);
348 NOUVEAUDRIPtr pNOUVEAUDRI;
350 if (!DRIFinishScreenInit(pScreen)) {
354 pNOUVEAUDRI = (NOUVEAUDRIPtr)pNv->pDRIInfo->devPrivate;
356 pNOUVEAUDRI->device_id = pNv->Chipset;
358 pNOUVEAUDRI->width = pScrn->virtualX;
359 pNOUVEAUDRI->height = pScrn->virtualY;
360 pNOUVEAUDRI->depth = pScrn->depth;
361 pNOUVEAUDRI->bpp = pScrn->bitsPerPixel;
363 pNOUVEAUDRI->front_offset = pNv->FB->offset;
364 pNOUVEAUDRI->front_pitch = pScrn->virtualX;
365 /* back/depth buffers will likely be allocated on a per-drawable
366 * basis, but these may be useful if we want to support shared back
367 * buffers at some point.
369 pNOUVEAUDRI->back_offset = 0;
370 pNOUVEAUDRI->back_pitch = 0;
371 pNOUVEAUDRI->depth_offset = 0;
372 pNOUVEAUDRI->depth_pitch = 0;