s/#define ABC ;/#define ABC do { ; } while(0);/
[nouveau] / src / nv_accel_common.c
1 #include "nv_include.h"
2
3 static Bool
4 NVAccelInitNullObject(ScrnInfoPtr pScrn)
5 {
6         NVPtr pNv = NVPTR(pScrn);
7         static int have_object = FALSE;
8
9         if (!have_object) {
10                 if (!NVDmaCreateContextObject(pNv, NvNullObject, NV01_NULL))
11                         return FALSE;
12                 have_object = TRUE;
13         }
14
15         return TRUE;
16 }
17
18 uint32_t
19 NVAccelGetPixmapOffset(PixmapPtr pPix)
20 {
21         ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum];
22         NVPtr pNv = NVPTR(pScrn);
23         unsigned long offset;
24
25         offset = exaGetPixmapOffset(pPix);
26         if (offset >= pNv->FB->size) {
27                 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
28                            "AII, passed bad pixmap: offset 0x%lx\n", offset);
29                 return pNv->FB->offset;
30         }
31         offset += pNv->FB->offset;
32
33         return offset;
34 }
35
36 static Bool
37 NVAccelInitDmaNotifier0(ScrnInfoPtr pScrn)
38 {
39         NVPtr pNv = NVPTR(pScrn);
40         static int have_object = FALSE;
41
42         if (!have_object) {
43                 pNv->Notifier0 = NVNotifierAlloc(pScrn, NvDmaNotifier0);
44                 if (!pNv->Notifier0)
45                         return FALSE;
46                 have_object = TRUE;
47         }
48
49         return TRUE;
50 }
51
52 /* FLAGS_ROP_AND, DmaFB, DmaFB, 0 */
53 static Bool
54 NVAccelInitContextSurfaces(ScrnInfoPtr pScrn)
55 {
56         NVPtr pNv = NVPTR(pScrn);
57         static int have_object = FALSE;
58         uint32_t   class;
59
60         class = (pNv->Architecture >= NV_10) ? NV10_CONTEXT_SURFACES_2D :
61                                                NV04_CONTEXT_SURFACES_2D;
62
63         if (!have_object) {
64                 if (!NVDmaCreateContextObject(pNv, NvContextSurfaces, class))
65                         return FALSE;
66                 have_object = TRUE;
67         }
68
69         BEGIN_RING(NvContextSurfaces, NV04_CONTEXT_SURFACES_2D_DMA_NOTIFY, 1);
70         OUT_RING  (NvNullObject);
71         BEGIN_RING(NvContextSurfaces,
72                    NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2);
73         OUT_RING  (NvDmaFB);
74         OUT_RING  (NvDmaFB);
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         static int have_object = FALSE;
85         uint32_t   class;
86
87         class = 0x12;
88
89         if (!have_object) {
90                 if (!NVDmaCreateContextObject(pNv, NvContextBeta1, class))
91                         return FALSE;
92                 have_object = TRUE;
93         }
94
95         BEGIN_RING(NvContextBeta1, 0x300, 1); /*alpha factor*/
96         OUT_RING  (0xff << 23);
97
98         return TRUE;
99 }
100
101
102 static Bool
103 NVAccelInitContextBeta4(ScrnInfoPtr pScrn)
104 {
105         NVPtr pNv = NVPTR(pScrn);
106         static int have_object = FALSE;
107         uint32_t   class;
108         
109         class = 0x72;
110
111         if (!have_object) {
112                 if (!NVDmaCreateContextObject(pNv, NvContextBeta4, class))
113                         return FALSE;
114                 have_object = TRUE;
115         }
116
117         BEGIN_RING(NvContextBeta4, 0x300, 1); /*RGBA factor*/
118         OUT_RING  (0xffff0000);
119         return TRUE;
120 }
121
122 Bool
123 NVAccelGetCtxSurf2DFormatFromPixmap(PixmapPtr pPix, int *fmt_ret)
124 {
125         switch (pPix->drawable.bitsPerPixel) {
126         case 32:
127                 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_A8R8G8B8;
128                 break;
129         case 24:
130                 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_X8R8G8B8_Z8R8G8B8;
131                 break;
132         case 16:
133                 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_R5G6B5;
134                 break;
135         case 8:
136                 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_Y8;
137                 break;
138         default:
139                 return FALSE;
140         }
141
142         return TRUE;
143 }
144
145 Bool
146 NVAccelGetCtxSurf2DFormatFromPicture(PicturePtr pPict, int *fmt_ret)
147 {
148         switch (pPict->format) {
149         case PICT_a8r8g8b8:
150                 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_A8R8G8B8;
151                 break;
152         case PICT_x8r8g8b8:
153                 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_X8R8G8B8_Z8R8G8B8;
154                 break;
155         case PICT_r5g6b5:
156                 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_R5G6B5;
157                 break;
158         case PICT_a8:
159                 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_Y8;
160                 break;
161         default:
162                 return FALSE;
163         }
164
165         return TRUE;
166 }
167
168 Bool
169 NVAccelSetCtxSurf2D(PixmapPtr psPix, PixmapPtr pdPix, int format)
170 {
171         ScrnInfoPtr pScrn = xf86Screens[psPix->drawable.pScreen->myNum];
172         NVPtr pNv = NVPTR(pScrn);
173
174         BEGIN_RING(NvContextSurfaces, NV04_CONTEXT_SURFACES_2D_FORMAT, 4);
175         OUT_RING  (format);
176         OUT_RING  (((uint32_t)exaGetPixmapPitch(pdPix) << 16) |
177                          (uint32_t)exaGetPixmapPitch(psPix));
178         OUT_RING  (NVAccelGetPixmapOffset(psPix));
179         OUT_RING  (NVAccelGetPixmapOffset(pdPix));
180
181         return TRUE;
182 }
183
184 static Bool
185 NVAccelInitImagePattern(ScrnInfoPtr pScrn)
186 {
187         NVPtr pNv = NVPTR(pScrn);
188         static int have_object = FALSE;
189         uint32_t   class;
190
191         class = NV04_IMAGE_PATTERN;
192
193         if (!have_object) {
194                 if (!NVDmaCreateContextObject(pNv, NvImagePattern, class))
195                         return FALSE;
196                 have_object = TRUE;
197         }
198
199         BEGIN_RING(NvImagePattern, NV04_IMAGE_PATTERN_DMA_NOTIFY, 1);
200         OUT_RING  (NvNullObject);
201         BEGIN_RING(NvImagePattern, NV04_IMAGE_PATTERN_MONOCHROME_FORMAT, 3);
202 #if X_BYTE_ORDER == X_BIG_ENDIAN
203         OUT_RING  (NV04_IMAGE_PATTERN_MONOCHROME_FORMAT_LE);
204 #else
205         OUT_RING  (NV04_IMAGE_PATTERN_MONOCHROME_FORMAT_CGA6);
206 #endif
207         OUT_RING  (NV04_IMAGE_PATTERN_MONOCHROME_SHAPE_8X8);
208         OUT_RING  (NV04_IMAGE_PATTERN_PATTERN_SELECT_MONO);
209
210         return TRUE;
211 }
212
213 static Bool
214 NVAccelInitRasterOp(ScrnInfoPtr pScrn)
215 {
216         NVPtr pNv = NVPTR(pScrn);
217         static int have_object = FALSE;
218         uint32_t   class;
219
220         class = NV03_CONTEXT_ROP;
221
222         if (!have_object) {
223                 if (!NVDmaCreateContextObject(pNv, NvRop, class))
224                         return FALSE;
225                 have_object = TRUE;
226         }
227
228         BEGIN_RING(NvRop, NV03_CONTEXT_ROP_DMA_NOTIFY, 1);
229         OUT_RING  (NvNullObject);
230
231         pNv->currentRop = ~0;
232         return TRUE;
233 }
234
235 static Bool
236 NVAccelInitRectangle(ScrnInfoPtr pScrn)
237 {
238         NVPtr pNv = NVPTR(pScrn);
239         static int have_object = FALSE;
240         uint32_t   class;
241
242         class = NV04_GDI_RECTANGLE_TEXT;
243
244         if (!have_object) {
245                 if (!NVDmaCreateContextObject(pNv, NvRectangle, class))
246                         return FALSE;
247                 have_object = TRUE;
248         }
249
250         BEGIN_RING(NvRectangle, NV04_GDI_RECTANGLE_TEXT_DMA_NOTIFY, 1);
251         OUT_RING  (NvDmaNotifier0);
252         BEGIN_RING(NvRectangle, NV04_GDI_RECTANGLE_TEXT_DMA_FONTS, 1);
253         OUT_RING  (NvNullObject);
254         BEGIN_RING(NvRectangle, NV04_GDI_RECTANGLE_TEXT_SURFACE, 1);
255         OUT_RING  (NvContextSurfaces);
256         BEGIN_RING(NvRectangle, NV04_GDI_RECTANGLE_TEXT_ROP, 1);
257         OUT_RING  (NvRop);
258         BEGIN_RING(NvRectangle, NV04_GDI_RECTANGLE_TEXT_PATTERN, 1);
259         OUT_RING  (NvImagePattern);
260         BEGIN_RING(NvRectangle, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1);
261         OUT_RING  (NV04_GDI_RECTANGLE_TEXT_OPERATION_ROP_AND);
262         BEGIN_RING(NvRectangle, NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT, 1);
263         /* XXX why putting 1 like renouveau dump, swap the text */
264 #if 1 || X_BYTE_ORDER == X_BIG_ENDIAN
265         OUT_RING  (NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT_LE);
266 #else
267         OUT_RING  (NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT_CGA6);
268 #endif
269
270         return TRUE;
271 }
272
273 static Bool
274 NVAccelInitImageBlit(ScrnInfoPtr pScrn)
275 {
276         NVPtr pNv = NVPTR(pScrn);
277         static int have_object = FALSE;
278         uint32_t   class;
279
280         class = (pNv->WaitVSyncPossible) ? NV12_IMAGE_BLIT : NV_IMAGE_BLIT;
281
282         if (!have_object) {
283                 if (!NVDmaCreateContextObject(pNv, NvImageBlit, class))
284                         return FALSE;
285                 have_object = TRUE;
286         }
287
288         BEGIN_RING(NvImageBlit, NV_IMAGE_BLIT_DMA_NOTIFY, 1);
289         OUT_RING  (NvDmaNotifier0);
290         BEGIN_RING(NvImageBlit, NV_IMAGE_BLIT_COLOR_KEY, 1);
291         OUT_RING  (NvNullObject);
292         BEGIN_RING(NvImageBlit, NV_IMAGE_BLIT_SURFACE, 1);
293         OUT_RING  (NvContextSurfaces);
294         BEGIN_RING(NvImageBlit, NV_IMAGE_BLIT_CLIP_RECTANGLE, 3);
295         OUT_RING  (NvNullObject);
296         OUT_RING  (NvImagePattern);
297         OUT_RING  (NvRop);
298         BEGIN_RING(NvImageBlit, NV_IMAGE_BLIT_OPERATION, 1);
299         OUT_RING  (NV_IMAGE_BLIT_OPERATION_ROP_AND);
300
301         if (pNv->WaitVSyncPossible) {
302                 BEGIN_RING(NvImageBlit, 0x0120, 3);
303                 OUT_RING  (0);
304                 OUT_RING  (1);
305                 OUT_RING  (2);
306         }
307
308         return TRUE;
309 }
310
311 static Bool
312 NVAccelInitScaledImage(ScrnInfoPtr pScrn)
313 {
314         NVPtr pNv = NVPTR(pScrn);
315         static int have_object = FALSE;
316         uint32_t   class;
317
318         switch (pNv->Architecture) {
319         case NV_ARCH_04:
320                 class = NV04_SCALED_IMAGE_FROM_MEMORY;
321                 break;
322         case NV_ARCH_10:
323         case NV_ARCH_20:
324         case NV_ARCH_30:
325                 class = NV10_SCALED_IMAGE_FROM_MEMORY;
326                 break;
327         case NV_ARCH_40:
328         default:
329                 class = NV10_SCALED_IMAGE_FROM_MEMORY | 0x3000;
330                 break;
331         }
332
333         if (!have_object) {
334                 if (!NVDmaCreateContextObject(pNv, NvScaledImage, class))
335                         return FALSE;
336                 have_object = TRUE;
337         }
338
339         BEGIN_RING(NvScaledImage,
340                         NV04_SCALED_IMAGE_FROM_MEMORY_DMA_NOTIFY, 7);
341         OUT_RING  (NvDmaNotifier0);
342         OUT_RING  (NvDmaFB);
343         OUT_RING  (NvNullObject);
344         OUT_RING  (NvNullObject);
345         OUT_RING  (NvContextBeta1);
346         OUT_RING  (NvContextBeta4);
347         OUT_RING  (NvContextSurfaces);
348         if (pNv->Architecture>=NV_ARCH_10) {
349         BEGIN_RING(NvScaledImage,
350                    NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION, 1);
351         OUT_RING  (NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION_DITHER);
352         }
353         BEGIN_RING(NvScaledImage, NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION, 1);
354         OUT_RING  (NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY);
355
356         return TRUE;
357 }
358
359 static Bool
360 NVAccelInitClipRectangle(ScrnInfoPtr pScrn)
361 {
362         NVPtr pNv = NVPTR(pScrn);
363         static int have_object = FALSE;
364         int class = NV01_CONTEXT_CLIP_RECTANGLE;
365
366         if (!have_object) {
367                 if (!NVDmaCreateContextObject(pNv, NvClipRectangle, class))
368                         return FALSE;
369                 have_object = TRUE;
370         }
371
372         BEGIN_RING(NvClipRectangle, NV01_CONTEXT_CLIP_RECTANGLE_DMA_NOTIFY, 1);
373         OUT_RING  (NvNullObject);
374
375         return TRUE;
376 }
377
378 static Bool
379 NVAccelInitSolidLine(ScrnInfoPtr pScrn)
380 {
381         NVPtr pNv = NVPTR(pScrn);
382         static int have_object = FALSE;
383         int class = NV04_RENDER_SOLID_LINE;
384
385         if (!have_object) {
386                 if (!NVDmaCreateContextObject(pNv, NvSolidLine, class))
387                         return FALSE;
388                 have_object = TRUE;
389         }
390
391         BEGIN_RING(NvSolidLine, NV01_RENDER_SOLID_LINE_CLIP_RECTANGLE, 3);
392         OUT_RING  (NvClipRectangle);
393         OUT_RING  (NvImagePattern);
394         OUT_RING  (NvRop);
395         BEGIN_RING(NvSolidLine, NV04_RENDER_SOLID_LINE_SURFACE, 1);
396         OUT_RING  (NvContextSurfaces);
397         BEGIN_RING(NvSolidLine, NV01_RENDER_SOLID_LINE_OPERATION, 1);
398         OUT_RING  (NV01_RENDER_SOLID_LINE_OPERATION_ROP_AND);
399
400         return TRUE;
401 }
402
403 /* FLAGS_NONE, NvDmaFB, NvDmaAGP, NvDmaNotifier0 */
404 static Bool
405 NVAccelInitMemFormat(ScrnInfoPtr pScrn)
406 {
407         NVPtr pNv = NVPTR(pScrn);
408         static int have_object = FALSE;
409         uint32_t   class;
410
411         if (pNv->Architecture < NV_ARCH_50)
412                 class = NV_MEMORY_TO_MEMORY_FORMAT;
413         else
414                 class = NV50_MEMORY_TO_MEMORY_FORMAT;
415
416         if (!have_object) {
417                 if (!NVDmaCreateContextObject(pNv, NvMemFormat, class))
418                                 return FALSE;
419                 have_object = TRUE;
420         }
421
422         BEGIN_RING(NvMemFormat, NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1);
423         OUT_RING  (NvDmaNotifier0);
424         BEGIN_RING(NvMemFormat, NV_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_IN, 2);
425         OUT_RING  (NvDmaFB);
426         OUT_RING  (NvDmaFB);
427
428         pNv->M2MFDirection = -1;
429         return TRUE;
430 }
431
432 static Bool
433 NVAccelInitImageFromCpu(ScrnInfoPtr pScrn)
434 {
435         NVPtr pNv = NVPTR(pScrn);
436         static int have_object = FALSE;
437         uint32_t   class;
438
439         switch (pNv->Architecture) {
440         case NV_ARCH_04:
441                 class = NV05_IMAGE_FROM_CPU;
442                 break;
443         case NV_ARCH_10:
444         case NV_ARCH_20:
445         case NV_ARCH_30:
446         case NV_ARCH_40:
447         default:
448                 class = NV10_IMAGE_FROM_CPU;
449                 break;
450         }
451
452         if (!have_object) {
453                 if (!NVDmaCreateContextObject(pNv, NvImageFromCpu, class))
454                         return FALSE;
455                 have_object = TRUE;
456         }
457
458         BEGIN_RING(NvImageFromCpu, NV01_IMAGE_FROM_CPU_DMA_NOTIFY, 1);
459         OUT_RING  (NvDmaNotifier0);
460         BEGIN_RING(NvImageFromCpu, NV01_IMAGE_FROM_CPU_CLIP_RECTANGLE, 1);
461         OUT_RING  (NvNullObject);
462         BEGIN_RING(NvImageFromCpu, NV01_IMAGE_FROM_CPU_PATTERN, 1);
463         OUT_RING  (NvNullObject);
464         BEGIN_RING(NvImageFromCpu, NV01_IMAGE_FROM_CPU_ROP, 1);
465         OUT_RING  (NvNullObject);
466         if (pNv->Architecture >= NV_ARCH_10)
467         {
468                 BEGIN_RING(NvImageFromCpu, NV01_IMAGE_FROM_CPU_BETA1, 1);
469                 OUT_RING  (NvNullObject);
470                 BEGIN_RING(NvImageFromCpu, NV05_IMAGE_FROM_CPU_BETA4, 1);
471                 OUT_RING  (NvNullObject);
472         }
473         BEGIN_RING(NvImageFromCpu, NV05_IMAGE_FROM_CPU_SURFACE, 1);
474         OUT_RING  (NvContextSurfaces);
475         BEGIN_RING(NvImageFromCpu, NV01_IMAGE_FROM_CPU_OPERATION, 1);
476         OUT_RING  (NV01_IMAGE_FROM_CPU_OPERATION_SRCCOPY);
477         return TRUE;
478 }
479
480 static Bool
481 NVAccelInit2D_NV50(ScrnInfoPtr pScrn)
482 {
483         NVPtr pNv = NVPTR(pScrn);
484         static int have_object = FALSE;
485
486         if (!have_object) {
487                 if (!NVDmaCreateContextObject(pNv, Nv2D, 0x502d))
488                                 return FALSE;
489                 have_object = TRUE;
490         }
491
492         BEGIN_RING(Nv2D, 0x180, 3);
493         OUT_RING  (NvDmaNotifier0);
494         OUT_RING  (NvDmaFB);
495         OUT_RING  (NvDmaFB);
496
497         /* Magics from nv, no clue what they do, but at least some
498          * of them are needed to avoid crashes.
499          */
500         BEGIN_RING(Nv2D, 0x260, 1);
501         OUT_RING  (1);
502         BEGIN_RING(Nv2D, 0x290, 1);
503         OUT_RING  (1);
504         BEGIN_RING(Nv2D, 0x29c, 1);
505         OUT_RING  (0);
506         BEGIN_RING(Nv2D, 0x58c, 1);
507         OUT_RING  (0x111);
508
509         pNv->currentRop = 0xfffffffa;
510         return TRUE;
511 }
512
513 #define INIT_CONTEXT_OBJECT(name) do {                                        \
514         ret = NVAccelInit##name(pScrn);                                       \
515         if (!ret) {                                                           \
516                 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,                         \
517                            "Failed to initialise context object: "#name       \
518                            " (%d)\n", ret);                                   \
519                 return FALSE;                                                 \
520         }                                                                     \
521 } while(0)
522
523 Bool
524 NVAccelCommonInit(ScrnInfoPtr pScrn)
525 {
526         NVPtr pNv = NVPTR(pScrn);
527         Bool ret;
528         if(pNv->NoAccel) return TRUE;
529
530         /* General engine objects */
531         INIT_CONTEXT_OBJECT(NullObject);
532         INIT_CONTEXT_OBJECT(DmaNotifier0);
533
534         /* 2D engine */
535         if (pNv->Architecture < NV_ARCH_50) {
536                 INIT_CONTEXT_OBJECT(ContextSurfaces);
537                 INIT_CONTEXT_OBJECT(ContextBeta1);
538                 INIT_CONTEXT_OBJECT(ContextBeta4);
539                 INIT_CONTEXT_OBJECT(ImagePattern);
540                 INIT_CONTEXT_OBJECT(RasterOp);
541                 INIT_CONTEXT_OBJECT(Rectangle);
542                 INIT_CONTEXT_OBJECT(ImageBlit);
543                 INIT_CONTEXT_OBJECT(ScaledImage);
544                 INIT_CONTEXT_OBJECT(ClipRectangle);
545                 INIT_CONTEXT_OBJECT(SolidLine);
546                 INIT_CONTEXT_OBJECT(ImageFromCpu);
547         } else {
548                 INIT_CONTEXT_OBJECT(2D_NV50);
549         }
550         INIT_CONTEXT_OBJECT(MemFormat);
551
552         /* 3D init */
553         switch (pNv->Architecture) {
554         case NV_ARCH_40:
555                 INIT_CONTEXT_OBJECT(NV40TCL);
556                 break;
557         case NV_ARCH_30:
558                 INIT_CONTEXT_OBJECT(NV30TCL);
559                 break;
560         case NV_ARCH_20:
561         case NV_ARCH_10:
562                 INIT_CONTEXT_OBJECT(NV10TCL);
563                 break;
564         default:
565                 break;
566         }
567
568         return TRUE;
569 }
570