Remove all object with mmaps in CloseScreen, so that drmClose actually calls the...
[nouveau] / src / nv_accel_common.c
1 /*
2  * Copyright 2007 Ben Skeggs
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
19  * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20  * SOFTWARE.
21  */
22
23 #include "nv_include.h"
24
25 static Bool
26 NVAccelInitNullObject(ScrnInfoPtr pScrn)
27 {
28         NVPtr pNv = NVPTR(pScrn);
29
30         if (!pNv->NvNull) {
31                 if (nouveau_grobj_alloc(pNv->chan, NvNullObject, NV01_NULL,
32                                         &pNv->NvNull))
33                         return FALSE;
34         }
35
36         return TRUE;
37 }
38
39 static Bool
40 NVAccelInitDmaNotifier0(ScrnInfoPtr pScrn)
41 {
42         NVPtr pNv = NVPTR(pScrn);
43
44         if (!pNv->notify0) {
45                 if (nouveau_notifier_alloc(pNv->chan, NvDmaNotifier0, 1,
46                                            &pNv->notify0))
47                         return FALSE;
48         }
49
50         return TRUE;
51 }
52
53 /* FLAGS_ROP_AND, DmaFB, DmaFB, 0 */
54 static Bool
55 NVAccelInitContextSurfaces(ScrnInfoPtr pScrn)
56 {
57         NVPtr pNv = NVPTR(pScrn);
58         struct nouveau_channel *chan = pNv->chan;
59         struct nouveau_grobj *surf2d;
60         uint32_t class;
61
62         class = (pNv->Architecture >= NV_10) ? NV10_CONTEXT_SURFACES_2D :
63                                                NV04_CONTEXT_SURFACES_2D;
64
65         if (!pNv->NvContextSurfaces) {
66                 if (nouveau_grobj_alloc(chan, NvContextSurfaces, class,
67                                         &pNv->NvContextSurfaces))
68                         return FALSE;
69         }
70         surf2d = pNv->NvContextSurfaces;
71
72         BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_DMA_NOTIFY, 1);
73         OUT_RING  (chan, pNv->NvNull->handle);
74         BEGIN_RING(chan, surf2d,
75                    NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2);
76         OUT_RING  (chan, pNv->chan->vram->handle);
77         OUT_RING  (chan, pNv->chan->vram->handle);
78
79         return TRUE;
80 }
81
82 /* FLAGS_ROP_AND, DmaFB, DmaFB, 0 */
83 static Bool
84 NVAccelInitContextBeta1(ScrnInfoPtr pScrn)
85 {
86         NVPtr pNv = NVPTR(pScrn);
87         struct nouveau_channel *chan = pNv->chan;
88         struct nouveau_grobj *beta1;
89
90         if (!pNv->NvContextBeta1) {
91                 if (nouveau_grobj_alloc(chan, NvContextBeta1, 0x12,
92                                         &pNv->NvContextBeta1))
93                         return FALSE;
94         }
95         beta1 = pNv->NvContextBeta1;
96
97         BEGIN_RING(chan, beta1, 0x300, 1); /*alpha factor*/
98         OUT_RING  (chan, 0xff << 23);
99
100         return TRUE;
101 }
102
103
104 static Bool
105 NVAccelInitContextBeta4(ScrnInfoPtr pScrn)
106 {
107         NVPtr pNv = NVPTR(pScrn);
108         struct nouveau_channel *chan = pNv->chan;
109         struct nouveau_grobj *beta4;
110         
111         if (!pNv->NvContextBeta4) {
112                 if (nouveau_grobj_alloc(chan, NvContextBeta4, 0x72,
113                                         &pNv->NvContextBeta4))
114                         return FALSE;
115         }
116         beta4 = pNv->NvContextBeta4;
117
118         BEGIN_RING(chan, beta4, 0x300, 1); /*RGBA factor*/
119         OUT_RING  (chan, 0xffff0000);
120         return TRUE;
121 }
122
123 Bool
124 NVAccelGetCtxSurf2DFormatFromPixmap(PixmapPtr pPix, int *fmt_ret)
125 {
126         switch (pPix->drawable.bitsPerPixel) {
127         case 32:
128                 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_A8R8G8B8;
129                 break;
130         case 24:
131                 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_X8R8G8B8_Z8R8G8B8;
132                 break;
133         case 16:
134                 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_R5G6B5;
135                 break;
136         case 8:
137                 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_Y8;
138                 break;
139         default:
140                 return FALSE;
141         }
142
143         return TRUE;
144 }
145
146 Bool
147 NVAccelGetCtxSurf2DFormatFromPicture(PicturePtr pPict, int *fmt_ret)
148 {
149         switch (pPict->format) {
150         case PICT_a8r8g8b8:
151                 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_A8R8G8B8;
152                 break;
153         case PICT_x8r8g8b8:
154                 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_X8R8G8B8_Z8R8G8B8;
155                 break;
156         case PICT_r5g6b5:
157                 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_R5G6B5;
158                 break;
159         case PICT_a8:
160                 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_Y8;
161                 break;
162         default:
163                 return FALSE;
164         }
165
166         return TRUE;
167 }
168
169 /* A copy of exaGetOffscreenPixmap(), since it's private. */
170 PixmapPtr
171 NVGetDrawablePixmap(DrawablePtr pDraw)
172 {
173         if (pDraw->type == DRAWABLE_WINDOW)
174                 return pDraw->pScreen->GetWindowPixmap ((WindowPtr) pDraw);
175         else
176                 return (PixmapPtr) pDraw;
177 }
178
179 static Bool
180 NVAccelInitImagePattern(ScrnInfoPtr pScrn)
181 {
182         NVPtr pNv = NVPTR(pScrn);
183         struct nouveau_channel *chan = pNv->chan;
184         struct nouveau_grobj *patt;
185
186         if (!pNv->NvImagePattern) {
187                 if (nouveau_grobj_alloc(chan, NvImagePattern,
188                                         NV04_IMAGE_PATTERN,
189                                         &pNv->NvImagePattern))
190                         return FALSE;
191         }
192         patt = pNv->NvImagePattern;
193
194         BEGIN_RING(chan, patt, NV04_IMAGE_PATTERN_DMA_NOTIFY, 1);
195         OUT_RING  (chan, pNv->NvNull->handle);
196         BEGIN_RING(chan, patt, NV04_IMAGE_PATTERN_MONOCHROME_FORMAT, 3);
197 #if X_BYTE_ORDER == X_BIG_ENDIAN
198         OUT_RING  (chan, NV04_IMAGE_PATTERN_MONOCHROME_FORMAT_LE);
199 #else
200         OUT_RING  (chan, NV04_IMAGE_PATTERN_MONOCHROME_FORMAT_CGA6);
201 #endif
202         OUT_RING  (chan, NV04_IMAGE_PATTERN_MONOCHROME_SHAPE_8X8);
203         OUT_RING  (chan, NV04_IMAGE_PATTERN_PATTERN_SELECT_MONO);
204
205         return TRUE;
206 }
207
208 static Bool
209 NVAccelInitRasterOp(ScrnInfoPtr pScrn)
210 {
211         NVPtr pNv = NVPTR(pScrn);
212         struct nouveau_channel *chan = pNv->chan;
213         struct nouveau_grobj *rop;
214
215         if (!pNv->NvRop) {
216                 if (nouveau_grobj_alloc(chan, NvRop, NV03_CONTEXT_ROP,
217                                         &pNv->NvRop))
218                         return FALSE;
219         }
220         rop = pNv->NvRop;
221
222         BEGIN_RING(chan, rop, NV03_CONTEXT_ROP_DMA_NOTIFY, 1);
223         OUT_RING  (chan, pNv->NvNull->handle);
224
225         pNv->currentRop = ~0;
226         return TRUE;
227 }
228
229 static Bool
230 NVAccelInitRectangle(ScrnInfoPtr pScrn)
231 {
232         NVPtr pNv = NVPTR(pScrn);
233         struct nouveau_channel *chan = pNv->chan;
234         struct nouveau_grobj *rect;
235
236         if (!pNv->NvRectangle) {
237                 if (nouveau_grobj_alloc(chan, NvRectangle,
238                                         NV04_GDI_RECTANGLE_TEXT,
239                                         &pNv->NvRectangle))
240                         return FALSE;
241         }
242         rect = pNv->NvRectangle;
243
244         BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_DMA_NOTIFY, 1);
245         OUT_RING  (chan, pNv->notify0->handle);
246         BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_DMA_FONTS, 1);
247         OUT_RING  (chan, pNv->NvNull->handle);
248         BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_SURFACE, 1);
249         OUT_RING  (chan, pNv->NvContextSurfaces->handle);
250         BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_ROP, 1);
251         OUT_RING  (chan, pNv->NvRop->handle);
252         BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_PATTERN, 1);
253         OUT_RING  (chan, pNv->NvImagePattern->handle);
254         BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1);
255         OUT_RING  (chan, NV04_GDI_RECTANGLE_TEXT_OPERATION_ROP_AND);
256         BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT, 1);
257         /* XXX why putting 1 like renouveau dump, swap the text */
258 #if 1 || X_BYTE_ORDER == X_BIG_ENDIAN
259         OUT_RING  (chan, NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT_LE);
260 #else
261         OUT_RING  (chan, NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT_CGA6);
262 #endif
263
264         return TRUE;
265 }
266
267 static Bool
268 NVAccelInitImageBlit(ScrnInfoPtr pScrn)
269 {
270         NVPtr pNv = NVPTR(pScrn);
271         struct nouveau_channel *chan = pNv->chan;
272         struct nouveau_grobj *blit;
273         uint32_t class;
274
275         class = (pNv->WaitVSyncPossible) ? NV12_IMAGE_BLIT : NV04_IMAGE_BLIT;
276
277         if (!pNv->NvImageBlit) {
278                 if (nouveau_grobj_alloc(chan, NvImageBlit, class,
279                                         &pNv->NvImageBlit))
280                         return FALSE;
281         }
282         blit = pNv->NvImageBlit;
283
284         BEGIN_RING(chan, blit, NV04_IMAGE_BLIT_DMA_NOTIFY, 1);
285         OUT_RING  (chan, pNv->notify0->handle);
286         BEGIN_RING(chan, blit, NV04_IMAGE_BLIT_COLOR_KEY, 1);
287         OUT_RING  (chan, pNv->NvNull->handle);
288         BEGIN_RING(chan, blit, NV04_IMAGE_BLIT_SURFACE, 1);
289         OUT_RING  (chan, pNv->NvContextSurfaces->handle);
290         BEGIN_RING(chan, blit, NV04_IMAGE_BLIT_CLIP_RECTANGLE, 3);
291         OUT_RING  (chan, pNv->NvNull->handle);
292         OUT_RING  (chan, pNv->NvImagePattern->handle);
293         OUT_RING  (chan, pNv->NvRop->handle);
294         BEGIN_RING(chan, blit, NV04_IMAGE_BLIT_OPERATION, 1);
295         OUT_RING  (chan, NV04_IMAGE_BLIT_OPERATION_ROP_AND);
296
297         if (pNv->WaitVSyncPossible) {
298                 BEGIN_RING(chan, blit, 0x0120, 3);
299                 OUT_RING  (chan, 0);
300                 OUT_RING  (chan, 1);
301                 OUT_RING  (chan, 2);
302         }
303
304         return TRUE;
305 }
306
307 static Bool
308 NVAccelInitScaledImage(ScrnInfoPtr pScrn)
309 {
310         NVPtr pNv = NVPTR(pScrn);
311         struct nouveau_channel *chan = pNv->chan;
312         struct nouveau_grobj *sifm;
313         uint32_t class;
314
315         switch (pNv->Architecture) {
316         case NV_ARCH_04:
317                 class = NV04_SCALED_IMAGE_FROM_MEMORY;
318                 break;
319         case NV_ARCH_10:
320         case NV_ARCH_20:
321         case NV_ARCH_30:
322                 class = NV10_SCALED_IMAGE_FROM_MEMORY;
323                 break;
324         case NV_ARCH_40:
325         default:
326                 class = NV10_SCALED_IMAGE_FROM_MEMORY | 0x3000;
327                 break;
328         }
329
330         if (!pNv->NvScaledImage) {
331                 if (nouveau_grobj_alloc(chan, NvScaledImage, class,
332                                         &pNv->NvScaledImage))
333                         return FALSE;
334         }
335         sifm = pNv->NvScaledImage;
336
337         BEGIN_RING(chan, sifm,
338                          NV04_SCALED_IMAGE_FROM_MEMORY_DMA_NOTIFY, 7);
339         OUT_RING  (chan, pNv->notify0->handle);
340         OUT_RING  (chan, pNv->chan->vram->handle);
341         OUT_RING  (chan, pNv->NvNull->handle);
342         OUT_RING  (chan, pNv->NvNull->handle);
343         OUT_RING  (chan, pNv->NvContextBeta1->handle);
344         OUT_RING  (chan, pNv->NvContextBeta4->handle);
345         OUT_RING  (chan, pNv->NvContextSurfaces->handle);
346         if (pNv->Architecture>=NV_ARCH_10) {
347         BEGIN_RING(chan, sifm,
348                          NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION, 1);
349         OUT_RING  (chan, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION_DITHER);
350         }
351         BEGIN_RING(chan, sifm, NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION, 1);
352         OUT_RING  (chan, NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY);
353
354         return TRUE;
355 }
356
357 static Bool
358 NVAccelInitClipRectangle(ScrnInfoPtr pScrn)
359 {
360         NVPtr pNv = NVPTR(pScrn);
361         struct nouveau_channel *chan = pNv->chan;
362         struct nouveau_grobj *clip;
363
364         if (!pNv->NvClipRectangle) {
365                 if (nouveau_grobj_alloc(pNv->chan, NvClipRectangle,
366                                         NV01_CONTEXT_CLIP_RECTANGLE,
367                                         &pNv->NvClipRectangle))
368                         return FALSE;
369         }
370         clip = pNv->NvClipRectangle;
371
372         BEGIN_RING(chan, clip, NV01_CONTEXT_CLIP_RECTANGLE_DMA_NOTIFY, 1);
373         OUT_RING  (chan, pNv->NvNull->handle);
374
375         return TRUE;
376 }
377
378 /* FLAGS_NONE, NvDmaFB, NvDmaAGP, NvDmaNotifier0 */
379 static Bool
380 NVAccelInitMemFormat(ScrnInfoPtr pScrn)
381 {
382         NVPtr pNv = NVPTR(pScrn);
383         struct nouveau_channel *chan = pNv->chan;
384         struct nouveau_grobj *m2mf;
385         uint32_t class;
386
387         if (pNv->Architecture < NV_ARCH_50)
388                 class = NV04_MEMORY_TO_MEMORY_FORMAT;
389         else
390                 class = NV50_MEMORY_TO_MEMORY_FORMAT;
391
392         if (!pNv->NvMemFormat) {
393                 if (nouveau_grobj_alloc(chan, NvMemFormat, class,
394                                         &pNv->NvMemFormat))
395                         return FALSE;
396         }
397         m2mf = pNv->NvMemFormat;
398
399         BEGIN_RING(chan, m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1);
400         OUT_RING  (chan, pNv->notify0->handle);
401         BEGIN_RING(chan, m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_IN, 2);
402         OUT_RING  (chan, chan->vram->handle);
403         OUT_RING  (chan, chan->vram->handle);
404
405         return TRUE;
406 }
407
408 static Bool
409 NVAccelInitImageFromCpu(ScrnInfoPtr pScrn)
410 {
411         NVPtr pNv = NVPTR(pScrn);
412         struct nouveau_channel *chan = pNv->chan;
413         struct nouveau_grobj *ifc;
414         uint32_t class;
415
416         switch (pNv->Architecture) {
417         case NV_ARCH_04:
418                 class = NV04_IMAGE_FROM_CPU;
419                 break;
420         case NV_ARCH_10:
421         case NV_ARCH_20:
422         case NV_ARCH_30:
423         case NV_ARCH_40:
424         default:
425                 class = NV10_IMAGE_FROM_CPU;
426                 break;
427         }
428
429         if (!pNv->NvImageFromCpu) {
430                 if (nouveau_grobj_alloc(chan, NvImageFromCpu, class,
431                                         &pNv->NvImageFromCpu))
432                         return FALSE;
433         }
434         ifc = pNv->NvImageFromCpu;
435
436         BEGIN_RING(chan, ifc, NV01_IMAGE_FROM_CPU_DMA_NOTIFY, 1);
437         OUT_RING  (chan, pNv->notify0->handle);
438         BEGIN_RING(chan, ifc, NV01_IMAGE_FROM_CPU_CLIP_RECTANGLE, 1);
439         OUT_RING  (chan, pNv->NvNull->handle);
440         BEGIN_RING(chan, ifc, NV01_IMAGE_FROM_CPU_PATTERN, 1);
441         OUT_RING  (chan, pNv->NvNull->handle);
442         BEGIN_RING(chan, ifc, NV01_IMAGE_FROM_CPU_ROP, 1);
443         OUT_RING  (chan, pNv->NvNull->handle);
444         if (pNv->Architecture >= NV_ARCH_10) {
445                 BEGIN_RING(chan, ifc, NV01_IMAGE_FROM_CPU_BETA1, 1);
446                 OUT_RING  (chan, pNv->NvNull->handle);
447                 BEGIN_RING(chan, ifc, NV05_IMAGE_FROM_CPU_BETA4, 1);
448                 OUT_RING  (chan, pNv->NvNull->handle);
449         }
450         BEGIN_RING(chan, ifc, NV05_IMAGE_FROM_CPU_SURFACE, 1);
451         OUT_RING  (chan, pNv->NvContextSurfaces->handle);
452         BEGIN_RING(chan, ifc, NV01_IMAGE_FROM_CPU_OPERATION, 1);
453         OUT_RING  (chan, NV01_IMAGE_FROM_CPU_OPERATION_SRCCOPY);
454
455         return TRUE;
456 }
457
458 static Bool
459 NVAccelInit2D_NV50(ScrnInfoPtr pScrn)
460 {
461         NVPtr pNv = NVPTR(pScrn);
462         struct nouveau_channel *chan = pNv->chan;
463         struct nouveau_grobj *eng2d;
464
465         if (!pNv->Nv2D) {
466                 if (nouveau_grobj_alloc(chan, Nv2D, 0x502d, &pNv->Nv2D))
467                         return FALSE;
468         }
469         eng2d = pNv->Nv2D;
470
471         BEGIN_RING(chan, eng2d, 0x180, 3);
472         OUT_RING  (chan, pNv->notify0->handle);
473         OUT_RING  (chan, pNv->chan->vram->handle);
474         OUT_RING  (chan, pNv->chan->vram->handle);
475
476         /* Magics from nv, no clue what they do, but at least some
477          * of them are needed to avoid crashes.
478          */
479         BEGIN_RING(chan, eng2d, 0x260, 1);
480         OUT_RING  (chan, 1);
481         BEGIN_RING(chan, eng2d, 0x290, 1);
482         OUT_RING  (chan, 1);
483         BEGIN_RING(chan, eng2d, 0x29c, 1);
484         OUT_RING  (chan, 0);
485         BEGIN_RING(chan, eng2d, 0x58c, 1);
486         OUT_RING  (chan, 0x111);
487
488         pNv->currentRop = 0xfffffffa;
489         return TRUE;
490 }
491
492 #define INIT_CONTEXT_OBJECT(name) do {                                        \
493         ret = NVAccelInit##name(pScrn);                                       \
494         if (!ret) {                                                           \
495                 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,                         \
496                            "Failed to initialise context object: "#name       \
497                            " (%d)\n", ret);                                   \
498                 return FALSE;                                                 \
499         }                                                                     \
500 } while(0)
501
502 Bool
503 NVAccelCommonInit(ScrnInfoPtr pScrn)
504 {
505         NVPtr pNv = NVPTR(pScrn);
506         Bool ret;
507         if(pNv->NoAccel) return TRUE;
508
509         /* General engine objects */
510         INIT_CONTEXT_OBJECT(NullObject);
511         INIT_CONTEXT_OBJECT(DmaNotifier0);
512
513         /* 2D engine */
514         if (pNv->Architecture < NV_ARCH_50) {
515                 INIT_CONTEXT_OBJECT(ContextSurfaces);
516                 INIT_CONTEXT_OBJECT(ContextBeta1);
517                 INIT_CONTEXT_OBJECT(ContextBeta4);
518                 INIT_CONTEXT_OBJECT(ImagePattern);
519                 INIT_CONTEXT_OBJECT(RasterOp);
520                 INIT_CONTEXT_OBJECT(Rectangle);
521                 INIT_CONTEXT_OBJECT(ImageBlit);
522                 INIT_CONTEXT_OBJECT(ScaledImage);
523                 INIT_CONTEXT_OBJECT(ClipRectangle);
524                 INIT_CONTEXT_OBJECT(ImageFromCpu);
525         } else {
526                 INIT_CONTEXT_OBJECT(2D_NV50);
527         }
528         INIT_CONTEXT_OBJECT(MemFormat);
529
530         /* 3D init */
531         switch (pNv->Architecture) {
532         case NV_ARCH_50:
533                 INIT_CONTEXT_OBJECT(NV50TCL);
534                 break;
535         case NV_ARCH_40:
536                 INIT_CONTEXT_OBJECT(NV40TCL);
537                 break;
538         case NV_ARCH_30:
539                 INIT_CONTEXT_OBJECT(NV30TCL);
540                 break;
541         case NV_ARCH_20:
542         case NV_ARCH_10:
543                 INIT_CONTEXT_OBJECT(NV10TCL);
544                 break;
545         default:
546                 break;
547         }
548
549         return TRUE;
550 }
551
552 void NVAccelFree(NVPtr pNv)
553 {
554         if (pNv->tesla_scratch)
555                 nouveau_bo_del(&pNv->tesla_scratch);
556         if (pNv->shader_mem)
557                 nouveau_bo_del(&pNv->shader_mem);
558 }