Missed out "DEBUG" part of the name in the define
[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         uint32_t   class;
59
60         class = (pNv->Architecture >= NV_10) ? NV10_CONTEXT_SURFACES_2D :
61                                                NV04_CONTEXT_SURFACES_2D;
62
63         if (!pNv->NvContextSurfaces) {
64                 if (nouveau_grobj_alloc(pNv->chan, NvContextSurfaces, class,
65                                         &pNv->NvContextSurfaces))
66                         return FALSE;
67         }
68
69         BEGIN_RING(NvContextSurfaces, NV04_CONTEXT_SURFACES_2D_DMA_NOTIFY, 1);
70         OUT_RING  (pNv->NvNull->handle);
71         BEGIN_RING(NvContextSurfaces,
72                    NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2);
73         OUT_RING  (pNv->chan->vram->handle);
74         OUT_RING  (pNv->chan->vram->handle);
75
76         return TRUE;
77 }
78
79 /* FLAGS_ROP_AND, DmaFB, DmaFB, 0 */
80 static Bool
81 NVAccelInitContextBeta1(ScrnInfoPtr pScrn)
82 {
83         NVPtr pNv = NVPTR(pScrn);
84         uint32_t   class;
85
86         class = 0x12;
87
88         if (!pNv->NvContextBeta1) {
89                 if (nouveau_grobj_alloc(pNv->chan, NvContextBeta1, class,
90                                         &pNv->NvContextBeta1))
91                         return FALSE;
92         }
93
94         BEGIN_RING(NvContextBeta1, 0x300, 1); /*alpha factor*/
95         OUT_RING  (0xff << 23);
96
97         return TRUE;
98 }
99
100
101 static Bool
102 NVAccelInitContextBeta4(ScrnInfoPtr pScrn)
103 {
104         NVPtr pNv = NVPTR(pScrn);
105         uint32_t   class;
106         
107         class = 0x72;
108
109         if (!pNv->NvContextBeta4) {
110                 if (nouveau_grobj_alloc(pNv->chan, NvContextBeta4, class,
111                                         &pNv->NvContextBeta4))
112                         return FALSE;
113         }
114
115         BEGIN_RING(NvContextBeta4, 0x300, 1); /*RGBA factor*/
116         OUT_RING  (0xffff0000);
117         return TRUE;
118 }
119
120 Bool
121 NVAccelGetCtxSurf2DFormatFromPixmap(PixmapPtr pPix, int *fmt_ret)
122 {
123         switch (pPix->drawable.bitsPerPixel) {
124         case 32:
125                 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_A8R8G8B8;
126                 break;
127         case 24:
128                 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_X8R8G8B8_Z8R8G8B8;
129                 break;
130         case 16:
131                 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_R5G6B5;
132                 break;
133         case 8:
134                 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_Y8;
135                 break;
136         default:
137                 return FALSE;
138         }
139
140         return TRUE;
141 }
142
143 Bool
144 NVAccelGetCtxSurf2DFormatFromPicture(PicturePtr pPict, int *fmt_ret)
145 {
146         switch (pPict->format) {
147         case PICT_a8r8g8b8:
148                 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_A8R8G8B8;
149                 break;
150         case PICT_x8r8g8b8:
151                 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_X8R8G8B8_Z8R8G8B8;
152                 break;
153         case PICT_r5g6b5:
154                 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_R5G6B5;
155                 break;
156         case PICT_a8:
157                 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_Y8;
158                 break;
159         default:
160                 return FALSE;
161         }
162
163         return TRUE;
164 }
165
166 /* A copy of exaGetOffscreenPixmap(), since it's private. */
167 PixmapPtr
168 NVGetDrawablePixmap(DrawablePtr pDraw)
169 {
170         if (pDraw->type == DRAWABLE_WINDOW)
171                 return pDraw->pScreen->GetWindowPixmap ((WindowPtr) pDraw);
172         else
173                 return (PixmapPtr) pDraw;
174 }
175
176 static Bool
177 NVAccelInitImagePattern(ScrnInfoPtr pScrn)
178 {
179         NVPtr pNv = NVPTR(pScrn);
180         uint32_t   class;
181
182         class = NV04_IMAGE_PATTERN;
183
184         if (!pNv->NvImagePattern) {
185                 if (nouveau_grobj_alloc(pNv->chan, NvImagePattern, class,
186                                         &pNv->NvImagePattern))
187                         return FALSE;
188         }
189
190         BEGIN_RING(NvImagePattern, NV04_IMAGE_PATTERN_DMA_NOTIFY, 1);
191         OUT_RING  (pNv->NvNull->handle);
192         BEGIN_RING(NvImagePattern, NV04_IMAGE_PATTERN_MONOCHROME_FORMAT, 3);
193 #if X_BYTE_ORDER == X_BIG_ENDIAN
194         OUT_RING  (NV04_IMAGE_PATTERN_MONOCHROME_FORMAT_LE);
195 #else
196         OUT_RING  (NV04_IMAGE_PATTERN_MONOCHROME_FORMAT_CGA6);
197 #endif
198         OUT_RING  (NV04_IMAGE_PATTERN_MONOCHROME_SHAPE_8X8);
199         OUT_RING  (NV04_IMAGE_PATTERN_PATTERN_SELECT_MONO);
200
201         return TRUE;
202 }
203
204 static Bool
205 NVAccelInitRasterOp(ScrnInfoPtr pScrn)
206 {
207         NVPtr pNv = NVPTR(pScrn);
208         uint32_t   class;
209
210         class = NV03_CONTEXT_ROP;
211
212         if (!pNv->NvRop) {
213                 if (nouveau_grobj_alloc(pNv->chan, NvRop, class,
214                                         &pNv->NvRop))
215                         return FALSE;
216         }
217
218         BEGIN_RING(NvRop, NV03_CONTEXT_ROP_DMA_NOTIFY, 1);
219         OUT_RING  (pNv->NvNull->handle);
220
221         pNv->currentRop = ~0;
222         return TRUE;
223 }
224
225 static Bool
226 NVAccelInitRectangle(ScrnInfoPtr pScrn)
227 {
228         NVPtr pNv = NVPTR(pScrn);
229         uint32_t   class;
230
231         class = NV04_GDI_RECTANGLE_TEXT;
232
233         if (!pNv->NvRectangle) {
234                 if (nouveau_grobj_alloc(pNv->chan, NvRectangle, class,
235                                         &pNv->NvRectangle))
236                         return FALSE;
237         }
238
239         BEGIN_RING(NvRectangle, NV04_GDI_RECTANGLE_TEXT_DMA_NOTIFY, 1);
240         OUT_RING  (pNv->notify0->handle);
241         BEGIN_RING(NvRectangle, NV04_GDI_RECTANGLE_TEXT_DMA_FONTS, 1);
242         OUT_RING  (pNv->NvNull->handle);
243         BEGIN_RING(NvRectangle, NV04_GDI_RECTANGLE_TEXT_SURFACE, 1);
244         OUT_RING  (pNv->NvContextSurfaces->handle);
245         BEGIN_RING(NvRectangle, NV04_GDI_RECTANGLE_TEXT_ROP, 1);
246         OUT_RING  (pNv->NvRop->handle);
247         BEGIN_RING(NvRectangle, NV04_GDI_RECTANGLE_TEXT_PATTERN, 1);
248         OUT_RING  (pNv->NvImagePattern->handle);
249         BEGIN_RING(NvRectangle, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1);
250         OUT_RING  (NV04_GDI_RECTANGLE_TEXT_OPERATION_ROP_AND);
251         BEGIN_RING(NvRectangle, NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT, 1);
252         /* XXX why putting 1 like renouveau dump, swap the text */
253 #if 1 || X_BYTE_ORDER == X_BIG_ENDIAN
254         OUT_RING  (NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT_LE);
255 #else
256         OUT_RING  (NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT_CGA6);
257 #endif
258
259         return TRUE;
260 }
261
262 static Bool
263 NVAccelInitImageBlit(ScrnInfoPtr pScrn)
264 {
265         NVPtr pNv = NVPTR(pScrn);
266         uint32_t   class;
267
268         class = (pNv->WaitVSyncPossible) ? NV12_IMAGE_BLIT : NV04_IMAGE_BLIT;
269
270         if (!pNv->NvImageBlit) {
271                 if (nouveau_grobj_alloc(pNv->chan, NvImageBlit, class,
272                                         &pNv->NvImageBlit))
273                         return FALSE;
274         }
275
276         BEGIN_RING(NvImageBlit, NV04_IMAGE_BLIT_DMA_NOTIFY, 1);
277         OUT_RING  (pNv->notify0->handle);
278         BEGIN_RING(NvImageBlit, NV04_IMAGE_BLIT_COLOR_KEY, 1);
279         OUT_RING  (pNv->NvNull->handle);
280         BEGIN_RING(NvImageBlit, NV04_IMAGE_BLIT_SURFACE, 1);
281         OUT_RING  (pNv->NvContextSurfaces->handle);
282         BEGIN_RING(NvImageBlit, NV04_IMAGE_BLIT_CLIP_RECTANGLE, 3);
283         OUT_RING  (pNv->NvNull->handle);
284         OUT_RING  (pNv->NvImagePattern->handle);
285         OUT_RING  (pNv->NvRop->handle);
286         BEGIN_RING(NvImageBlit, NV04_IMAGE_BLIT_OPERATION, 1);
287         OUT_RING  (NV04_IMAGE_BLIT_OPERATION_ROP_AND);
288
289         if (pNv->WaitVSyncPossible) {
290                 BEGIN_RING(NvImageBlit, 0x0120, 3);
291                 OUT_RING  (0);
292                 OUT_RING  (1);
293                 OUT_RING  (2);
294         }
295
296         return TRUE;
297 }
298
299 static Bool
300 NVAccelInitScaledImage(ScrnInfoPtr pScrn)
301 {
302         NVPtr pNv = NVPTR(pScrn);
303         uint32_t   class;
304
305         switch (pNv->Architecture) {
306         case NV_ARCH_04:
307                 class = NV04_SCALED_IMAGE_FROM_MEMORY;
308                 break;
309         case NV_ARCH_10:
310         case NV_ARCH_20:
311         case NV_ARCH_30:
312                 class = NV10_SCALED_IMAGE_FROM_MEMORY;
313                 break;
314         case NV_ARCH_40:
315         default:
316                 class = NV10_SCALED_IMAGE_FROM_MEMORY | 0x3000;
317                 break;
318         }
319
320         if (!pNv->NvScaledImage) {
321                 if (nouveau_grobj_alloc(pNv->chan, NvScaledImage, class,
322                                         &pNv->NvScaledImage))
323                         return FALSE;
324         }
325
326         BEGIN_RING(NvScaledImage,
327                         NV04_SCALED_IMAGE_FROM_MEMORY_DMA_NOTIFY, 7);
328         OUT_RING  (pNv->notify0->handle);
329         OUT_RING  (pNv->chan->vram->handle);
330         OUT_RING  (pNv->NvNull->handle);
331         OUT_RING  (pNv->NvNull->handle);
332         OUT_RING  (pNv->NvContextBeta1->handle);
333         OUT_RING  (pNv->NvContextBeta4->handle);
334         OUT_RING  (pNv->NvContextSurfaces->handle);
335         if (pNv->Architecture>=NV_ARCH_10) {
336         BEGIN_RING(NvScaledImage,
337                    NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION, 1);
338         OUT_RING  (NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION_DITHER);
339         }
340         BEGIN_RING(NvScaledImage, NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION, 1);
341         OUT_RING  (NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY);
342
343         return TRUE;
344 }
345
346 static Bool
347 NVAccelInitClipRectangle(ScrnInfoPtr pScrn)
348 {
349         NVPtr pNv = NVPTR(pScrn);
350         int class = NV01_CONTEXT_CLIP_RECTANGLE;
351
352         if (!pNv->NvClipRectangle) {
353                 if (nouveau_grobj_alloc(pNv->chan, NvClipRectangle, class,
354                                         &pNv->NvClipRectangle))
355                         return FALSE;
356         }
357
358         BEGIN_RING(NvClipRectangle, NV01_CONTEXT_CLIP_RECTANGLE_DMA_NOTIFY, 1);
359         OUT_RING  (pNv->NvNull->handle);
360
361         return TRUE;
362 }
363
364 /* FLAGS_NONE, NvDmaFB, NvDmaAGP, NvDmaNotifier0 */
365 static Bool
366 NVAccelInitMemFormat(ScrnInfoPtr pScrn)
367 {
368         NVPtr pNv = NVPTR(pScrn);
369         uint32_t   class;
370
371         if (pNv->Architecture < NV_ARCH_50)
372                 class = NV04_MEMORY_TO_MEMORY_FORMAT;
373         else
374                 class = NV50_MEMORY_TO_MEMORY_FORMAT;
375
376         if (!pNv->NvMemFormat) {
377                 if (nouveau_grobj_alloc(pNv->chan, NvMemFormat, class,
378                                         &pNv->NvMemFormat))
379                         return FALSE;
380         }
381
382         BEGIN_RING(NvMemFormat, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1);
383         OUT_RING  (pNv->notify0->handle);
384         BEGIN_RING(NvMemFormat, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_IN, 2);
385         OUT_RING  (pNv->chan->vram->handle);
386         OUT_RING  (pNv->chan->vram->handle);
387
388         return TRUE;
389 }
390
391 static Bool
392 NVAccelInitImageFromCpu(ScrnInfoPtr pScrn)
393 {
394         NVPtr pNv = NVPTR(pScrn);
395         uint32_t   class;
396
397         switch (pNv->Architecture) {
398         case NV_ARCH_04:
399                 class = NV04_IMAGE_FROM_CPU;
400                 break;
401         case NV_ARCH_10:
402         case NV_ARCH_20:
403         case NV_ARCH_30:
404         case NV_ARCH_40:
405         default:
406                 class = NV10_IMAGE_FROM_CPU;
407                 break;
408         }
409
410         if (!pNv->NvImageFromCpu) {
411                 if (nouveau_grobj_alloc(pNv->chan, NvImageFromCpu, class,
412                                         &pNv->NvImageFromCpu))
413                         return FALSE;
414         }
415
416         BEGIN_RING(NvImageFromCpu, NV01_IMAGE_FROM_CPU_DMA_NOTIFY, 1);
417         OUT_RING  (pNv->notify0->handle);
418         BEGIN_RING(NvImageFromCpu, NV01_IMAGE_FROM_CPU_CLIP_RECTANGLE, 1);
419         OUT_RING  (pNv->NvNull->handle);
420         BEGIN_RING(NvImageFromCpu, NV01_IMAGE_FROM_CPU_PATTERN, 1);
421         OUT_RING  (pNv->NvNull->handle);
422         BEGIN_RING(NvImageFromCpu, NV01_IMAGE_FROM_CPU_ROP, 1);
423         OUT_RING  (pNv->NvNull->handle);
424         if (pNv->Architecture >= NV_ARCH_10)
425         {
426                 BEGIN_RING(NvImageFromCpu, NV01_IMAGE_FROM_CPU_BETA1, 1);
427                 OUT_RING  (pNv->NvNull->handle);
428                 BEGIN_RING(NvImageFromCpu, NV05_IMAGE_FROM_CPU_BETA4, 1);
429                 OUT_RING  (pNv->NvNull->handle);
430         }
431         BEGIN_RING(NvImageFromCpu, NV05_IMAGE_FROM_CPU_SURFACE, 1);
432         OUT_RING  (pNv->NvContextSurfaces->handle);
433         BEGIN_RING(NvImageFromCpu, NV01_IMAGE_FROM_CPU_OPERATION, 1);
434         OUT_RING  (NV01_IMAGE_FROM_CPU_OPERATION_SRCCOPY);
435         return TRUE;
436 }
437
438 static Bool
439 NVAccelInit2D_NV50(ScrnInfoPtr pScrn)
440 {
441         NVPtr pNv = NVPTR(pScrn);
442
443         if (!pNv->Nv2D) {
444                 if (nouveau_grobj_alloc(pNv->chan, Nv2D, 0x502d,
445                                         &pNv->Nv2D))
446                         return FALSE;
447         }
448
449         BEGIN_RING(Nv2D, 0x180, 3);
450         OUT_RING  (pNv->notify0->handle);
451         OUT_RING  (pNv->chan->vram->handle);
452         OUT_RING  (pNv->chan->vram->handle);
453
454         /* Magics from nv, no clue what they do, but at least some
455          * of them are needed to avoid crashes.
456          */
457         BEGIN_RING(Nv2D, 0x260, 1);
458         OUT_RING  (1);
459         BEGIN_RING(Nv2D, 0x290, 1);
460         OUT_RING  (1);
461         BEGIN_RING(Nv2D, 0x29c, 1);
462         OUT_RING  (0);
463         BEGIN_RING(Nv2D, 0x58c, 1);
464         OUT_RING  (0x111);
465
466         pNv->currentRop = 0xfffffffa;
467         return TRUE;
468 }
469
470 #define INIT_CONTEXT_OBJECT(name) do {                                        \
471         ret = NVAccelInit##name(pScrn);                                       \
472         if (!ret) {                                                           \
473                 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,                         \
474                            "Failed to initialise context object: "#name       \
475                            " (%d)\n", ret);                                   \
476                 return FALSE;                                                 \
477         }                                                                     \
478 } while(0)
479
480 Bool
481 NVAccelCommonInit(ScrnInfoPtr pScrn)
482 {
483         NVPtr pNv = NVPTR(pScrn);
484         Bool ret;
485         if(pNv->NoAccel) return TRUE;
486
487         /* General engine objects */
488         INIT_CONTEXT_OBJECT(NullObject);
489         INIT_CONTEXT_OBJECT(DmaNotifier0);
490
491         /* 2D engine */
492         if (pNv->Architecture < NV_ARCH_50) {
493                 INIT_CONTEXT_OBJECT(ContextSurfaces);
494                 INIT_CONTEXT_OBJECT(ContextBeta1);
495                 INIT_CONTEXT_OBJECT(ContextBeta4);
496                 INIT_CONTEXT_OBJECT(ImagePattern);
497                 INIT_CONTEXT_OBJECT(RasterOp);
498                 INIT_CONTEXT_OBJECT(Rectangle);
499                 INIT_CONTEXT_OBJECT(ImageBlit);
500                 INIT_CONTEXT_OBJECT(ScaledImage);
501                 INIT_CONTEXT_OBJECT(ClipRectangle);
502                 INIT_CONTEXT_OBJECT(ImageFromCpu);
503         } else {
504                 INIT_CONTEXT_OBJECT(2D_NV50);
505         }
506         INIT_CONTEXT_OBJECT(MemFormat);
507
508         /* 3D init */
509         switch (pNv->Architecture) {
510         case NV_ARCH_40:
511                 INIT_CONTEXT_OBJECT(NV40TCL);
512                 break;
513         case NV_ARCH_30:
514                 INIT_CONTEXT_OBJECT(NV30TCL);
515                 break;
516         case NV_ARCH_20:
517         case NV_ARCH_10:
518                 INIT_CONTEXT_OBJECT(NV10TCL);
519                 break;
520         default:
521                 break;
522         }
523
524         return TRUE;
525 }
526