1 #include "nv_include.h"
3 #define _XF86DRI_SERVER_
5 #include "GL/glxtokens.h"
9 #include "nv_dripriv.h"
12 Bool NVDRMSetParam(NVPtr pNv, unsigned int param, unsigned int value)
14 struct drm_nouveau_setparam setparam;
17 setparam.param = param;
18 setparam.value = value;
19 ret = drmCommandWriteRead(pNv->drm_fd, DRM_NOUVEAU_SETPARAM, &setparam,
26 unsigned int NVDRMGetParam(NVPtr pNv, unsigned int param)
28 struct drm_nouveau_getparam getparam;
30 getparam.param = param;
31 drmCommandWriteRead(pNv->drm_fd, DRM_NOUVEAU_GETPARAM, &getparam, sizeof(getparam));
33 return getparam.value;
36 static Bool NVCreateContext(ScreenPtr pScreen, VisualPtr visual,
37 drm_context_t hwContext, void *pVisualConfigPriv,
38 DRIContextType contextStore)
44 static void NVDestroyContext(ScreenPtr pScreen, drm_context_t hwContext,
45 DRIContextType contextStore)
50 static void NVDRISwapContext(ScreenPtr pScreen, DRISyncType syncType,
51 DRIContextType oldContextType,
53 DRIContextType newContextType,
56 /* we really should do something here */
60 static void NVDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 indx)
65 static void NVDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg,
66 RegionPtr prgnSrc, CARD32 indx)
71 static void NVDRITransitionTo2d(ScreenPtr pScreen)
76 static void NVDRITransitionTo3d(ScreenPtr pScreen)
81 static void NVDRITransitionSingleToMulti3d(ScreenPtr pScreen)
86 static void NVDRITransitionMultiToSingle3d(ScreenPtr pScreen)
91 static Bool NVDRIInitVisualConfigs(ScreenPtr pScreen)
93 ScrnInfoPtr pScrn=xf86Screens[pScreen->myNum];
94 __GLXvisualConfig* pConfigs = NULL;
95 NVConfigPrivPtr pNVConfigs = NULL;
96 NVConfigPrivPtr* pNVConfigPtrs = NULL;
97 int db,depth,alpha,stencil;
98 int depths[]={24,16,0};
105 xf86DrvMsg(pScreen->myNum, X_ERROR, "[dri] no DRI at %d bpp ",pScrn->depth);
109 num_configs=2*3*((pScrn->depth==24)?2:1)*2; /* db*depth*alpha*stencil */
110 if (!(pConfigs=(__GLXvisualConfig*)xcalloc(sizeof(__GLXvisualConfig),num_configs)))
112 if (!(pNVConfigs=(NVConfigPrivPtr)xcalloc(sizeof(NVConfigPrivRec), num_configs))) {
116 if (!(pNVConfigPtrs=(NVConfigPrivPtr *)xcalloc(sizeof(NVConfigPrivPtr),num_configs))) {
124 for(depth=0;depth<3;depth++)
125 for(alpha=0;alpha<((pScrn->depth==24)?2:1);alpha++)
126 for(stencil=0;stencil<2;stencil++)
128 pConfigs[i].vid = (VisualID)(-1);
129 pConfigs[i].class = -1;
130 pConfigs[i].rgba = TRUE;
131 if (pScrn->depth==16)
133 pConfigs[i].redSize = 5;
134 pConfigs[i].greenSize = 6;
135 pConfigs[i].blueSize = 5;
136 pConfigs[i].alphaSize = 0;
137 pConfigs[i].redMask = 0x0000F800;
138 pConfigs[i].greenMask = 0x000007E0;
139 pConfigs[i].blueMask = 0x0000001F;
140 pConfigs[i].alphaMask = 0x00000000;
142 pConfigs[i].redSize = 8;
143 pConfigs[i].greenSize = 8;
144 pConfigs[i].blueSize = 8;
145 pConfigs[i].redMask = 0x00FF0000;
146 pConfigs[i].greenMask = 0x0000FF00;
147 pConfigs[i].blueMask = 0x000000FF;
149 pConfigs[i].alphaSize = 8;
150 pConfigs[i].alphaMask = 0xFF000000;
152 pConfigs[i].alphaSize = 0;
153 pConfigs[i].alphaMask = 0x00000000;
157 pConfigs[i].accumRedSize = 0;
158 pConfigs[i].accumGreenSize = 0;
159 pConfigs[i].accumBlueSize = 0;
160 pConfigs[i].accumAlphaSize = 0;
162 pConfigs[i].doubleBuffer = TRUE;
164 pConfigs[i].doubleBuffer = FALSE;
165 pConfigs[i].stereo = FALSE;
166 pConfigs[i].bufferSize = pScrn->depth;
167 if (depths[depth] == 24 && stencil) {
168 pConfigs[i].depthSize = depths[depth];
169 pConfigs[i].stencilSize = 8;
171 pConfigs[i].depthSize = depths[depth];
172 pConfigs[i].stencilSize = 0;
174 pConfigs[i].auxBuffers = 0;
175 pConfigs[i].level = 0;
176 pConfigs[i].visualRating = GLX_NONE;
177 pConfigs[i].transparentPixel = GLX_NONE;
178 pConfigs[i].transparentRed = 0;
179 pConfigs[i].transparentGreen = 0;
180 pConfigs[i].transparentBlue = 0;
181 pConfigs[i].transparentAlpha = 0;
182 pConfigs[i].transparentIndex = 0;
187 GlxSetVisualConfigs(num_configs, pConfigs, (void**)pNVConfigPtrs);
191 Bool NVDRIGetVersion(ScrnInfoPtr pScrn)
193 NVPtr pNv = NVPTR(pScrn);
201 ret = LoadSubModule(pScrn->module, "dri", NULL, NULL, NULL,
202 NULL, &errmaj, &errmin);
204 xf86DrvMsg(pScrn->scrnIndex, X_INFO,
205 "error %d\n", errmaj);
206 LoaderErrorMsg(pScrn->name, "dri", errmaj, errmin);
209 if (!ret && errmaj != LDR_ONCEONLY)
213 xf86LoaderReqSymLists(drmSymbols, NULL);
214 xf86LoaderReqSymLists(driSymbols, NULL);
215 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Loaded DRI module\n");
217 busId = DRICreatePCIBusID(pNv->PciInfo);
219 fd = drmOpen("nouveau", busId);
222 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
223 "[dri] Failed to open the DRM\n");
227 /* Check the lib version */
228 if (xf86LoaderCheckSymbol("drmGetLibVersion"))
229 pNv->pLibDRMVersion = drmGetLibVersion(0);
230 if (pNv->pLibDRMVersion == NULL) {
231 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
232 "NVDRIGetVersion failed because libDRM is really "
233 "way to old to even get a version number out of it.\n"
234 "[dri] Disabling DRI.\n");
238 pNv->pKernelDRMVersion = drmGetVersion(fd);
240 if (pNv->pKernelDRMVersion == NULL) {
241 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
242 "failed to get DRM version\n");
246 /* temporary lock step versioning */
247 #if NOUVEAU_DRM_HEADER_PATCHLEVEL != 10
248 #error nouveau_drm.h doesn\'t match expected patchlevel, update libdrm.
250 if (pNv->pKernelDRMVersion->version_patchlevel !=
251 NOUVEAU_DRM_HEADER_PATCHLEVEL) {
252 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
253 "wrong DRM version\n");
260 Bool NVDRICheckModules(ScrnInfoPtr pScrn)
262 if (!xf86LoaderCheckSymbol("GlxSetVisualConfigs")) {
263 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
264 "[dri] GlxSetVisualConfigs not found.\n");
265 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
266 " NVIDIA's glx present, or glx not loaded.\n");
273 Bool NVDRIScreenInit(ScrnInfoPtr pScrn)
276 NOUVEAUDRIPtr pNOUVEAUDRI;
277 NVPtr pNv = NVPTR(pScrn);
279 pScreen = screenInfo.screens[pScrn->scrnIndex];
282 if (!NVDRICheckModules(pScrn))
285 drm_page_size = getpagesize();
286 if (!(pDRIInfo = DRICreateInfoRec())) return FALSE;
288 pNv->pDRIInfo = pDRIInfo;
289 pDRIInfo->drmDriverName = "nouveau";
290 pDRIInfo->clientDriverName = "nouveau";
291 pDRIInfo->busIdString = DRICreatePCIBusID(pNv->PciInfo);
293 pDRIInfo->ddxDriverMajorVersion = NV_MAJOR_VERSION;
294 pDRIInfo->ddxDriverMinorVersion = NV_MINOR_VERSION;
295 pDRIInfo->ddxDriverPatchVersion = NV_PATCHLEVEL;
298 * We set the FB to be in the higher half of VRAM. If we don't, any
299 * VRAM allocations before the FB is mapped will change that map
301 * We should detect when the DRM decides to change the FB area
302 * but we currently don't know how to.
304 pDRIInfo->frameBufferSize = pNv->VRAMPhysicalSize / 2;
305 pDRIInfo->frameBufferPhysicalAddress = (void *)pNv->VRAMPhysical +
306 pDRIInfo->frameBufferSize;
307 pDRIInfo->frameBufferStride = pScrn->displayWidth * pScrn->bitsPerPixel/8;
309 pDRIInfo->ddxDrawableTableEntry = 1;
310 pDRIInfo->maxDrawableTableEntry = 1;
312 if (!(pNOUVEAUDRI = (NOUVEAUDRIPtr)xcalloc(sizeof(NOUVEAUDRIRec), 1))) {
313 DRIDestroyInfoRec(pDRIInfo);
314 pNv->pDRIInfo = NULL;
317 pDRIInfo->devPrivate = pNOUVEAUDRI;
318 pDRIInfo->devPrivateSize = sizeof(NOUVEAUDRIRec);
319 pDRIInfo->contextSize = sizeof(NVDRIContextRec);
320 pDRIInfo->SAREASize = (drm_page_size > SAREA_MAX) ? drm_page_size : SAREA_MAX;
322 pDRIInfo->CreateContext = NVCreateContext;
323 pDRIInfo->DestroyContext = NVDestroyContext;
324 pDRIInfo->SwapContext = NVDRISwapContext;
325 pDRIInfo->InitBuffers = NVDRIInitBuffers;
326 pDRIInfo->MoveBuffers = NVDRIMoveBuffers;
327 pDRIInfo->bufferRequests = DRI_ALL_WINDOWS;
328 pDRIInfo->TransitionTo2d = NVDRITransitionTo2d;
329 pDRIInfo->TransitionTo3d = NVDRITransitionTo3d;
330 pDRIInfo->TransitionSingleToMulti3D = NVDRITransitionSingleToMulti3d;
331 pDRIInfo->TransitionMultiToSingle3D = NVDRITransitionMultiToSingle3d;
333 pDRIInfo->createDummyCtx = FALSE;
334 pDRIInfo->createDummyCtxPriv = FALSE;
336 if (!DRIScreenInit(pScreen, pDRIInfo, &pNv->drm_fd)) {
337 xf86DrvMsg(pScreen->myNum, X_ERROR,
338 "[dri] DRIScreenInit failed. Disabling DRI.\n");
339 xfree(pDRIInfo->devPrivate);
340 pDRIInfo->devPrivate = NULL;
341 DRIDestroyInfoRec(pDRIInfo);
345 if (!NVDRIInitVisualConfigs(pScreen)) {
346 xf86DrvMsg(pScreen->myNum, X_ERROR,
347 "[dri] NVDRIInitVisualConfigs failed. Disabling DRI.\n");
348 xfree(pDRIInfo->devPrivate);
349 pDRIInfo->devPrivate = NULL;
350 DRIDestroyInfoRec(pDRIInfo);
358 Bool NVDRIFinishScreenInit(ScrnInfoPtr pScrn)
360 ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
361 NVPtr pNv = NVPTR(pScrn);
362 NOUVEAUDRIPtr pNOUVEAUDRI;
364 if (!DRIFinishScreenInit(pScreen)) {
368 pNOUVEAUDRI = (NOUVEAUDRIPtr)pNv->pDRIInfo->devPrivate;
370 pNOUVEAUDRI->device_id = pNv->Chipset;
372 pNOUVEAUDRI->width = pScrn->virtualX;
373 pNOUVEAUDRI->height = pScrn->virtualY;
374 pNOUVEAUDRI->depth = pScrn->depth;
375 pNOUVEAUDRI->bpp = pScrn->bitsPerPixel;
377 pNOUVEAUDRI->front_offset = pNv->FB->offset;
378 pNOUVEAUDRI->front_pitch = pScrn->virtualX;
379 /* back/depth buffers will likely be allocated on a per-drawable
380 * basis, but these may be useful if we want to support shared back
381 * buffers at some point.
383 pNOUVEAUDRI->back_offset = 0;
384 pNOUVEAUDRI->back_pitch = 0;
385 pNOUVEAUDRI->depth_offset = 0;
386 pNOUVEAUDRI->depth_pitch = 0;