~ubuntu-branches/ubuntu/karmic/xserver-xorg-video-nouveau/karmic

« back to all changes in this revision

Viewing changes to src/nv_dri.c

  • Committer: Bazaar Package Importer
  • Author(s): Chris Lamb
  • Date: 2008-07-06 20:26:53 UTC
  • Revision ID: james.westby@ubuntu.com-20080706202653-e99oiii765j3a0qn
Tags: upstream-0.0.10~git+20080706+b1f3169
ImportĀ upstreamĀ versionĀ 0.0.10~git+20080706+b1f3169

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright 2006 Stephane Marchesin
 
3
 * Copyright 2006 Ben Skeggs
 
4
 *
 
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:
 
11
 *
 
12
 * The above copyright notice and this permission notice shall be included in
 
13
 * all copies or substantial portions of the Software.
 
14
 *
 
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
 
21
 * SOFTWARE.
 
22
 */
 
23
 
 
24
#include "nv_include.h"
 
25
 
 
26
#define _XF86DRI_SERVER_
 
27
#include "GL/glxint.h"
 
28
#include "GL/glxtokens.h"
 
29
#include "sarea.h"
 
30
#include "xf86drm.h"
 
31
#include "dri.h"
 
32
#include "nv_dripriv.h"
 
33
#include "nv_dri.h"
 
34
#include "drmmode_display.h"
 
35
 
 
36
static Bool NVCreateContext(ScreenPtr pScreen, VisualPtr visual,
 
37
                drm_context_t hwContext, void *pVisualConfigPriv,
 
38
                DRIContextType contextStore)
 
39
{
 
40
        return TRUE;
 
41
}
 
42
 
 
43
 
 
44
static void NVDestroyContext(ScreenPtr pScreen, drm_context_t hwContext,
 
45
                DRIContextType contextStore)
 
46
{
 
47
        return;
 
48
}
 
49
 
 
50
static void NVDRISwapContext(ScreenPtr pScreen, DRISyncType syncType,
 
51
                DRIContextType oldContextType,
 
52
                void *oldContext,
 
53
                DRIContextType newContextType,
 
54
                void *newContext)
 
55
{
 
56
        /* we really should do something here */
 
57
        return;
 
58
}
 
59
 
 
60
static void NVDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 indx)
 
61
{   
 
62
        return;
 
63
}
 
64
 
 
65
static void NVDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg,
 
66
                RegionPtr prgnSrc, CARD32 indx)
 
67
{
 
68
        return;
 
69
}       
 
70
 
 
71
static void NVDRITransitionTo2d(ScreenPtr pScreen)
 
72
{
 
73
        return;
 
74
}
 
75
 
 
76
static void NVDRITransitionTo3d(ScreenPtr pScreen)
 
77
{
 
78
        return;
 
79
}
 
80
 
 
81
static void NVDRITransitionSingleToMulti3d(ScreenPtr pScreen)
 
82
{           
 
83
        return;
 
84
}           
 
85
        
 
86
static void NVDRITransitionMultiToSingle3d(ScreenPtr pScreen)
 
87
{       
 
88
        return;
 
89
}
 
90
 
 
91
static Bool NVDRIInitVisualConfigs(ScreenPtr pScreen)
 
92
{
 
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};
 
99
        int num_configs,i;
 
100
 
 
101
        switch(pScrn->depth)
 
102
        {
 
103
                case 16:
 
104
                case 24:
 
105
                        num_configs=2*3*((pScrn->depth==24)?2:1)*2; /* db*depth*alpha*stencil */
 
106
                        if (!(pConfigs=(__GLXvisualConfig*)xcalloc(sizeof(__GLXvisualConfig),num_configs)))
 
107
                                return FALSE;
 
108
                        if (!(pNVConfigs=(NVConfigPrivPtr)xcalloc(sizeof(NVConfigPrivRec), num_configs))) {
 
109
                                xfree(pConfigs);
 
110
                                return FALSE;
 
111
                        }
 
112
                        if (!(pNVConfigPtrs=(NVConfigPrivPtr *)xcalloc(sizeof(NVConfigPrivPtr),num_configs))) {
 
113
                                xfree(pConfigs);
 
114
                                xfree(pNVConfigs);
 
115
                                return FALSE;
 
116
                        }
 
117
 
 
118
                        i = 0;
 
119
                        for(db=1;db>=0;db--)
 
120
                        for(depth=0;depth<3;depth++)
 
121
                        for(alpha=0;alpha<((pScrn->depth==24)?2:1);alpha++)
 
122
                        for(stencil=0;stencil<2;stencil++)
 
123
                        {
 
124
                                pConfigs[i].vid                = (VisualID)(-1);
 
125
                                pConfigs[i].class              = -1;
 
126
                                pConfigs[i].rgba               = TRUE;
 
127
                                if (pScrn->depth==16)
 
128
                                {                                       
 
129
                                        pConfigs[i].redSize            = 5;
 
130
                                        pConfigs[i].greenSize          = 6;
 
131
                                        pConfigs[i].blueSize           = 5;
 
132
                                        pConfigs[i].alphaSize          = 0;
 
133
                                        pConfigs[i].redMask            = 0x0000F800;
 
134
                                        pConfigs[i].greenMask          = 0x000007E0;
 
135
                                        pConfigs[i].blueMask           = 0x0000001F;
 
136
                                        pConfigs[i].alphaMask          = 0x00000000;
 
137
                                } else {
 
138
                                        pConfigs[i].redSize            = 8;
 
139
                                        pConfigs[i].greenSize          = 8;
 
140
                                        pConfigs[i].blueSize           = 8;
 
141
                                        pConfigs[i].redMask            = 0x00FF0000;
 
142
                                        pConfigs[i].greenMask          = 0x0000FF00;
 
143
                                        pConfigs[i].blueMask           = 0x000000FF;
 
144
                                        if (alpha) {
 
145
                                                pConfigs[i].alphaSize          = 8;
 
146
                                                pConfigs[i].alphaMask          = 0xFF000000;
 
147
                                        } else {
 
148
                                                pConfigs[i].alphaSize          = 0;
 
149
                                                pConfigs[i].alphaMask          = 0x00000000;
 
150
                                        }
 
151
                                }
 
152
 
 
153
                                pConfigs[i].accumRedSize   = 0;
 
154
                                pConfigs[i].accumGreenSize = 0;
 
155
                                pConfigs[i].accumBlueSize  = 0;
 
156
                                pConfigs[i].accumAlphaSize = 0;
 
157
                                if (db)
 
158
                                        pConfigs[i].doubleBuffer   = TRUE;
 
159
                                else
 
160
                                        pConfigs[i].doubleBuffer   = FALSE;
 
161
                                pConfigs[i].stereo             = FALSE;
 
162
                                pConfigs[i].bufferSize         = pScrn->depth;
 
163
                                if (depths[depth] == 24 && stencil) {
 
164
                                        pConfigs[i].depthSize          = depths[depth];
 
165
                                        pConfigs[i].stencilSize        = 8;
 
166
                                } else {
 
167
                                        pConfigs[i].depthSize          = depths[depth];
 
168
                                        pConfigs[i].stencilSize        = 0;
 
169
                                }
 
170
                                pConfigs[i].auxBuffers         = 0;
 
171
                                pConfigs[i].level              = 0;
 
172
                                pConfigs[i].visualRating       = GLX_NONE;
 
173
                                pConfigs[i].transparentPixel   = GLX_NONE;
 
174
                                pConfigs[i].transparentRed     = 0;
 
175
                                pConfigs[i].transparentGreen   = 0;
 
176
                                pConfigs[i].transparentBlue    = 0;
 
177
                                pConfigs[i].transparentAlpha   = 0;
 
178
                                pConfigs[i].transparentIndex   = 0;
 
179
                                i++;
 
180
                        }
 
181
                        break;
 
182
                default:
 
183
                        xf86DrvMsg(pScreen->myNum, X_ERROR, "[dri] no DRI at %d bpp ",pScrn->depth);
 
184
                        return FALSE;
 
185
        }
 
186
        GlxSetVisualConfigs(num_configs, pConfigs, (void**)pNVConfigPtrs);
 
187
        return TRUE;
 
188
}
 
189
 
 
190
Bool NVDRIGetVersion(ScrnInfoPtr pScrn)
 
191
{
 
192
        NVPtr pNv = NVPTR(pScrn);
 
193
        char *busId;
 
194
        int fd = 0;
 
195
 
 
196
#ifdef XF86DRM_MODE
 
197
        /* drm already open */
 
198
        if (pNv->drmmode) {
 
199
                drmmode_ptr drmmode = pNv->drmmode;
 
200
                fd = drmmode->fd;
 
201
        }
 
202
#endif
 
203
 
 
204
        {
 
205
                pointer ret;
 
206
                int errmaj, errmin;
 
207
 
 
208
                ret = LoadSubModule(pScrn->module, "dri", NULL, NULL, NULL,
 
209
                                    NULL, &errmaj, &errmin);
 
210
                if (!ret) {
 
211
                        xf86DrvMsg(pScrn->scrnIndex, X_INFO,
 
212
                                        "error %d\n", errmaj);
 
213
                        LoaderErrorMsg(pScrn->name, "dri", errmaj, errmin);
 
214
                }
 
215
 
 
216
                if (!ret && errmaj != LDR_ONCEONLY)
 
217
                        return FALSE;
 
218
        }
 
219
 
 
220
        xf86LoaderReqSymLists(drmSymbols, NULL);
 
221
        xf86LoaderReqSymLists(driSymbols, NULL);
 
222
        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Loaded DRI module\n");
 
223
 
 
224
        if (!fd) {
 
225
                busId = DRICreatePCIBusID(pNv->PciInfo);
 
226
 
 
227
                fd = drmOpen("nouveau", busId);
 
228
                xfree(busId);
 
229
        }
 
230
        if (fd < 0) {
 
231
                xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 
232
                        "[dri] Failed to open the DRM\n");
 
233
                return FALSE;
 
234
        }
 
235
 
 
236
        /* Check the lib version */
 
237
        if (xf86LoaderCheckSymbol("drmGetLibVersion"))
 
238
                pNv->pLibDRMVersion = drmGetLibVersion(0);
 
239
        if (pNv->pLibDRMVersion == NULL) {
 
240
                xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 
241
                "NVDRIGetVersion failed because libDRM is really "
 
242
                "way to old to even get a version number out of it.\n"
 
243
                "[dri] Disabling DRI.\n");
 
244
                return FALSE;
 
245
        }
 
246
 
 
247
        pNv->pKernelDRMVersion = drmGetVersion(fd);
 
248
#ifdef XF86DRM_MODE
 
249
        if (!pNv->drmmode) /* drmmode still needs the file descriptor */
 
250
#endif
 
251
                drmClose(fd);
 
252
 
 
253
        if (pNv->pKernelDRMVersion == NULL) {
 
254
                xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 
255
                        "failed to get DRM version\n");
 
256
                return FALSE;
 
257
        }
 
258
        
 
259
        /* temporary lock step versioning */
 
260
#if NOUVEAU_DRM_HEADER_PATCHLEVEL != 10
 
261
#error nouveau_drm.h does not match expected patchlevel, update libdrm.
 
262
#endif
 
263
        if (pNv->pKernelDRMVersion->version_patchlevel !=
 
264
                        NOUVEAU_DRM_HEADER_PATCHLEVEL) {
 
265
                xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 
266
                        "wrong DRM version\n");
 
267
                return FALSE;
 
268
        }
 
269
 
 
270
        return TRUE;
 
271
}
 
272
 
 
273
Bool NVDRICheckModules(ScrnInfoPtr pScrn)
 
274
{
 
275
        if (!xf86LoaderCheckSymbol("GlxSetVisualConfigs")) {
 
276
                xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 
277
                           "[dri] GlxSetVisualConfigs not found.\n");
 
278
                xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 
279
                           "      NVIDIA's glx present, or glx not loaded.\n");
 
280
                return FALSE;
 
281
        }
 
282
 
 
283
        return TRUE;
 
284
}
 
285
 
 
286
Bool NVDRIScreenInit(ScrnInfoPtr pScrn)
 
287
{
 
288
        DRIInfoPtr     pDRIInfo;
 
289
        NOUVEAUDRIPtr  pNOUVEAUDRI;
 
290
        NVPtr pNv = NVPTR(pScrn);
 
291
        ScreenPtr pScreen;
 
292
        pScreen = screenInfo.screens[pScrn->scrnIndex];
 
293
        int drm_page_size;
 
294
        int drm_fd;
 
295
 
 
296
#ifdef XF86DRM_MODE
 
297
        /* drm already open, reuse it */
 
298
        if (pNv->drmmode) {
 
299
                drmmode_ptr drmmode = pNv->drmmode;
 
300
                drm_fd = drmmode->fd;
 
301
        }
 
302
#endif
 
303
 
 
304
        if (!NVDRICheckModules(pScrn))
 
305
                return FALSE;
 
306
 
 
307
        drm_page_size = getpagesize();
 
308
        if (!(pDRIInfo = DRICreateInfoRec())) return FALSE;
 
309
        
 
310
        pNv->pDRIInfo                        = pDRIInfo;
 
311
        pDRIInfo->drmDriverName              = "nouveau";
 
312
        pDRIInfo->clientDriverName           = "nouveau";
 
313
        pDRIInfo->busIdString                = DRICreatePCIBusID(pNv->PciInfo);
 
314
 
 
315
        pDRIInfo->ddxDriverMajorVersion      = NV_MAJOR_VERSION;
 
316
        pDRIInfo->ddxDriverMinorVersion      = NV_MINOR_VERSION;
 
317
        pDRIInfo->ddxDriverPatchVersion      = NV_PATCHLEVEL;
 
318
 
 
319
        /*
 
320
         * We set the FB to be in the higher half of VRAM. If we don't, any
 
321
         * VRAM allocations before the FB is mapped will change that map
 
322
         * and we fail.
 
323
         * We should detect when the DRM decides to change the FB area
 
324
         * but we currently don't know how to.
 
325
         */
 
326
        pDRIInfo->frameBufferSize            = pNv->VRAMPhysicalSize / 2;
 
327
        pDRIInfo->frameBufferPhysicalAddress = (void *)pNv->VRAMPhysical;
 
328
        pDRIInfo->frameBufferStride          = pScrn->displayWidth * pScrn->bitsPerPixel/8;
 
329
 
 
330
        pDRIInfo->ddxDrawableTableEntry      = 1;
 
331
        pDRIInfo->maxDrawableTableEntry      = 1;
 
332
 
 
333
        if (!(pNOUVEAUDRI = (NOUVEAUDRIPtr)xcalloc(sizeof(NOUVEAUDRIRec), 1))) {
 
334
                DRIDestroyInfoRec(pDRIInfo);
 
335
                pNv->pDRIInfo = NULL;
 
336
                return FALSE;
 
337
        }
 
338
        pDRIInfo->devPrivate                 = pNOUVEAUDRI; 
 
339
        pDRIInfo->devPrivateSize             = sizeof(NOUVEAUDRIRec);
 
340
        pDRIInfo->contextSize                = sizeof(NVDRIContextRec);
 
341
        pDRIInfo->SAREASize                  = (drm_page_size > SAREA_MAX) ? drm_page_size : SAREA_MAX;
 
342
 
 
343
        pDRIInfo->CreateContext              = NVCreateContext;
 
344
        pDRIInfo->DestroyContext             = NVDestroyContext;
 
345
        pDRIInfo->SwapContext                = NVDRISwapContext;
 
346
        pDRIInfo->InitBuffers                = NVDRIInitBuffers;
 
347
        pDRIInfo->MoveBuffers                = NVDRIMoveBuffers;
 
348
        pDRIInfo->bufferRequests             = DRI_ALL_WINDOWS;
 
349
        pDRIInfo->TransitionTo2d             = NVDRITransitionTo2d;
 
350
        pDRIInfo->TransitionTo3d             = NVDRITransitionTo3d;
 
351
        pDRIInfo->TransitionSingleToMulti3D  = NVDRITransitionSingleToMulti3d;
 
352
        pDRIInfo->TransitionMultiToSingle3D  = NVDRITransitionMultiToSingle3d;
 
353
 
 
354
        pDRIInfo->createDummyCtx     = FALSE;
 
355
        pDRIInfo->createDummyCtxPriv = FALSE;
 
356
 
 
357
        if (!DRIScreenInit(pScreen, pDRIInfo, &drm_fd)) {
 
358
                xf86DrvMsg(pScreen->myNum, X_ERROR,
 
359
                                "[dri] DRIScreenInit failed.  Disabling DRI.\n");
 
360
                xfree(pDRIInfo->devPrivate);
 
361
                pDRIInfo->devPrivate = NULL;
 
362
                DRIDestroyInfoRec(pDRIInfo);
 
363
                pDRIInfo = NULL;
 
364
                return FALSE;
 
365
        }
 
366
 
 
367
        if (!NVDRIInitVisualConfigs(pScreen)) {
 
368
                xf86DrvMsg(pScreen->myNum, X_ERROR,
 
369
                                "[dri] NVDRIInitVisualConfigs failed.  Disabling DRI.\n");
 
370
                xfree(pDRIInfo->devPrivate);
 
371
                pDRIInfo->devPrivate = NULL;
 
372
                DRIDestroyInfoRec(pDRIInfo);
 
373
                pDRIInfo = NULL;
 
374
                return FALSE;
 
375
        }
 
376
 
 
377
        /* turn on need_close, so we explictly drmClose() on exit */
 
378
        if (nouveau_device_open_existing(&pNv->dev, 1, drm_fd, 0)) {
 
379
                xf86DrvMsg(pScreen->myNum, X_ERROR, "Error creating device\n");
 
380
                xfree(pDRIInfo->devPrivate);
 
381
                pDRIInfo->devPrivate = NULL;
 
382
                DRIDestroyInfoRec(pDRIInfo);
 
383
                pDRIInfo = NULL;
 
384
                return FALSE;
 
385
        }
 
386
 
 
387
        return TRUE;
 
388
}
 
389
 
 
390
Bool NVDRIFinishScreenInit(ScrnInfoPtr pScrn)
 
391
{
 
392
        ScreenPtr      pScreen = screenInfo.screens[pScrn->scrnIndex];
 
393
        NVPtr          pNv = NVPTR(pScrn);
 
394
        NOUVEAUDRIPtr  pNOUVEAUDRI;
 
395
 
 
396
        if (!DRIFinishScreenInit(pScreen)) {
 
397
                return FALSE;
 
398
        }
 
399
 
 
400
        pNOUVEAUDRI                     = (NOUVEAUDRIPtr)pNv->pDRIInfo->devPrivate;
 
401
 
 
402
        pNOUVEAUDRI->device_id          = pNv->Chipset;
 
403
 
 
404
        pNOUVEAUDRI->width              = pScrn->virtualX;
 
405
        pNOUVEAUDRI->height             = pScrn->virtualY;
 
406
        pNOUVEAUDRI->depth              = pScrn->depth;
 
407
        pNOUVEAUDRI->bpp                = pScrn->bitsPerPixel;
 
408
 
 
409
        pNOUVEAUDRI->front_offset       = pNv->FB->offset;
 
410
        pNOUVEAUDRI->front_pitch        = pScrn->displayWidth;
 
411
        /* back/depth buffers will likely be allocated on a per-drawable
 
412
         * basis, but these may be useful if we want to support shared back
 
413
         * buffers at some point.
 
414
         */
 
415
        pNOUVEAUDRI->back_offset        = 0;
 
416
        pNOUVEAUDRI->back_pitch         = 0;
 
417
        pNOUVEAUDRI->depth_offset       = 0;
 
418
        pNOUVEAUDRI->depth_pitch        = 0;
 
419
 
 
420
        return TRUE;
 
421
}
 
422
 
 
423
void NVDRICloseScreen(ScrnInfoPtr pScrn)
 
424
{
 
425
        ScreenPtr pScreen = screenInfo.screens[pScrn->scrnIndex];
 
426
        NVPtr pNv = NVPTR(pScrn);
 
427
 
 
428
        DRICloseScreen(pScreen);
 
429
        nouveau_device_close(&pNv->dev);
 
430
}
 
431