VERY EXPERIMENTAL now EXA waits for sync before its operations - this removed the...
[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,
11                                                    0x30))
12                         return FALSE;
13                 have_object = TRUE;
14         }
15
16         return TRUE;
17 }
18
19 uint32_t
20 NVAccelGetPixmapOffset(PixmapPtr pPix)
21 {
22         ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum];
23         NVPtr pNv = NVPTR(pScrn);
24         CARD32 offset;
25
26         if (pPix->drawable.type == DRAWABLE_WINDOW) {
27                 offset = pNv->FB->offset;
28         } else {
29                 offset  = (uint32_t)((unsigned long)pPix->devPrivate.ptr -
30                                 (unsigned long)pNv->FB->map);
31                 offset += pNv->FB->offset;
32         }
33
34         return offset;
35 }
36
37 static Bool
38 NVAccelInitDmaNotifier0(ScrnInfoPtr pScrn)
39 {
40         NVPtr pNv = NVPTR(pScrn);
41         static int have_object = FALSE;
42
43         if (!have_object) {
44                 pNv->Notifier0 = NVNotifierAlloc(pScrn, NvDmaNotifier0);
45                 if (!pNv->Notifier0)
46                         return FALSE;
47                 have_object = TRUE;
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         static int have_object = FALSE;
59         uint32_t   class;
60
61         class = (pNv->Architecture >= NV_10) ? NV10_CONTEXT_SURFACES_2D :
62                                                NV04_SURFACE;
63
64         if (!have_object) {
65                 if (!NVDmaCreateContextObject(pNv, NvContextSurfaces, class))
66                         return FALSE;
67                 have_object = TRUE;
68         }
69
70         NVDmaSetObjectOnSubchannel(pNv, NvSubContextSurfaces,
71                                         NvContextSurfaces);
72         NVDmaStart(pNv, NvSubContextSurfaces, NV04_SURFACE_DMA_NOTIFY, 1);
73         NVDmaNext (pNv, NvNullObject);
74         NVDmaStart(pNv, NvSubContextSurfaces, NV04_SURFACE_DMA_IMAGE_SOURCE, 2);
75         NVDmaNext (pNv, NvDmaFB);
76         NVDmaNext (pNv, NvDmaFB);
77
78         return TRUE;
79 }
80
81 Bool
82 NVAccelGetCtxSurf2DFormatFromPixmap(PixmapPtr pPix, int *fmt_ret)
83 {
84         switch (pPix->drawable.bitsPerPixel) {
85         case 32:
86                 *fmt_ret = SURFACE_FORMAT_A8R8G8B8;
87                 break;
88         case 24:
89                 *fmt_ret = SURFACE_FORMAT_X8R8G8B8;
90                 break;
91         case 16:
92                 *fmt_ret = SURFACE_FORMAT_R5G6B5;
93                 break;
94         case 8:
95                 *fmt_ret = SURFACE_FORMAT_Y8;
96                 break;
97         default:
98                 return FALSE;
99         }
100
101         return TRUE;
102 }
103
104 Bool
105 NVAccelGetCtxSurf2DFormatFromPicture(PicturePtr pPict, int *fmt_ret)
106 {
107         switch (pPict->format) {
108         case PICT_a8r8g8b8:
109                 *fmt_ret = SURFACE_FORMAT_A8R8G8B8;
110                 break;
111         case PICT_x8r8g8b8:
112                 *fmt_ret = SURFACE_FORMAT_X8R8G8B8;
113                 break;
114         case PICT_r5g6b5:
115                 *fmt_ret = SURFACE_FORMAT_R5G6B5;
116                 break;
117         case PICT_a8:
118                 *fmt_ret = SURFACE_FORMAT_Y8;
119                 break;
120         default:
121                 return FALSE;
122         }
123
124         return TRUE;
125 }
126
127 Bool
128 NVAccelSetCtxSurf2D(PixmapPtr psPix, PixmapPtr pdPix, int format)
129 {
130         ScrnInfoPtr pScrn = xf86Screens[psPix->drawable.pScreen->myNum];
131         NVPtr pNv = NVPTR(pScrn);
132
133         NVDmaStart(pNv, NvSubContextSurfaces, SURFACE_FORMAT, 4);
134         NVDmaNext (pNv, format);
135         NVDmaNext (pNv, ((uint32_t)exaGetPixmapPitch(pdPix) << 16) |
136                          (uint32_t)exaGetPixmapPitch(psPix));
137         NVDmaNext (pNv, NVAccelGetPixmapOffset(psPix));
138         NVDmaNext (pNv, NVAccelGetPixmapOffset(pdPix));
139
140         return TRUE;
141 }
142
143 /* FLAGS_ROP_AND|FLAGS_MONO, 0, 0, 0 */
144 static Bool
145 NVAccelInitImagePattern(ScrnInfoPtr pScrn)
146 {
147         NVPtr pNv = NVPTR(pScrn);
148         static int have_object = FALSE;
149         uint32_t   class;
150
151         class = NV04_IMAGE_PATTERN;
152
153         if (!have_object) {
154                 if (!NVDmaCreateContextObject(pNv, NvImagePattern, class))
155                         return FALSE;
156                 have_object = TRUE;
157         }
158
159         NVDmaSetObjectOnSubchannel(pNv, NvSubImagePattern,
160                                         NvImagePattern);
161         NVDmaStart(pNv, NvSubImagePattern,
162                         0x180, /*NV04_IMAGE_PATTERN_SET_DMA_NOTIFY*/ 1);
163         NVDmaNext (pNv, NvNullObject);
164         NVDmaStart(pNv, NvSubImagePattern, NV04_IMAGE_PATTERN_MONO_FORMAT, 3);
165 #if X_BYTE_ORDER == X_BIG_ENDIAN
166         NVDmaNext (pNv, 2 /* NV04_IMAGE_PATTERN_BIGENDIAN/LE_M1 */);
167 #else
168         NVDmaNext (pNv, 1 /* NV04_IMAGE_PATTERN_LOWENDIAN/CGA6_M1 */);
169 #endif
170         NVDmaNext (pNv, 0 /* NV04_IMAGE_PATTERN_MONOCHROME_SHAPE_8X8 */);
171         NVDmaNext (pNv, 1 /* NV04_IMAGE_PATTERN_SELECT_MONOCHROME */);
172
173         return TRUE;
174 }
175
176 /* FLAGS_ROP_AND, 0, 0, 0 */
177 static Bool
178 NVAccelInitRasterOp(ScrnInfoPtr pScrn)
179 {
180         NVPtr pNv = NVPTR(pScrn);
181         static int have_object = FALSE;
182         uint32_t   class;
183
184         class = NV03_PRIMITIVE_RASTER_OP;
185
186         if (!have_object) {
187                 if (!NVDmaCreateContextObject(pNv, NvRop, class))
188                         return FALSE;
189                 have_object = TRUE;
190         }
191
192         NVDmaSetObjectOnSubchannel(pNv, NvSubRop, NvRop);
193         NVDmaStart(pNv, NvSubRop, NV03_PRIMITIVE_RASTER_OP_DMA_NOTIFY, 1);
194         NVDmaNext (pNv, NvNullObject);
195
196         return TRUE;
197 }
198
199 /* FLAGS_ROP_AND | FLAGS_MONO, 0, 0, 0 */
200 static Bool
201 NVAccelInitRectangle(ScrnInfoPtr pScrn)
202 {
203         NVPtr pNv = NVPTR(pScrn);
204         static int have_object = FALSE;
205         uint32_t   class;
206
207         class = NV04_GDI_RECTANGLE_TEXT;
208
209         if (!have_object) {
210                 if (!NVDmaCreateContextObject(pNv, NvRectangle, class))
211                         return FALSE;
212                 have_object = TRUE;
213         }
214
215         NVDmaSetObjectOnSubchannel(pNv, NvSubRectangle, NvRectangle);
216         NVDmaStart(pNv, NvSubRectangle,
217                         NV04_GDI_RECTANGLE_TEXT_SET_DMA_NOTIFY, 1);
218         NVDmaNext (pNv, NvDmaNotifier0);
219         NVDmaStart(pNv, NvSubRectangle,
220                         0x184 /*NV04_GDI_RECTANGLE_TEXT_SET_DMA_FONTS*/, 1);
221         NVDmaNext (pNv, NvNullObject);
222         NVDmaStart(pNv, NvSubRectangle, NV04_GDI_RECTANGLE_TEXT_SURFACE, 1);
223         NVDmaNext (pNv, NvContextSurfaces);
224         NVDmaStart(pNv, NvSubRectangle, NV04_GDI_RECTANGLE_TEXT_ROP5, 1);
225         NVDmaNext (pNv, NvRop);
226         NVDmaStart(pNv, NvSubRectangle, NV04_GDI_RECTANGLE_TEXT_PATTERN, 1);
227         NVDmaNext (pNv, NvImagePattern);
228         NVDmaStart(pNv, NvSubRectangle, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1);
229         NVDmaNext (pNv, 1 /* ROP_AND */);
230
231         return TRUE;
232 }
233
234 /* FLAGS_ROP_AND, DmaFB, DmaFB, 0 */
235 static Bool
236 NVAccelInitImageBlit(ScrnInfoPtr pScrn)
237 {
238         NVPtr pNv = NVPTR(pScrn);
239         static int have_object = FALSE;
240         uint32_t   class;
241
242         class = (pNv->WaitVSyncPossible) ? NV10_IMAGE_BLIT : NV_IMAGE_BLIT;
243
244         if (!have_object) {
245                 if (!NVDmaCreateContextObject(pNv, NvImageBlit, class))
246                         return FALSE;
247                 have_object = TRUE;
248         }
249
250         NVDmaSetObjectOnSubchannel(pNv, NvSubImageBlit, NvImageBlit);
251         NVDmaStart(pNv, NvSubImageBlit, NV_IMAGE_BLIT_DMA_NOTIFY, 1);
252         NVDmaNext (pNv, NvDmaNotifier0);
253         NVDmaStart(pNv, NvSubImageBlit, NV_IMAGE_BLIT_COLOR_KEY, 1);
254         NVDmaNext (pNv, NvNullObject);
255         NVDmaStart(pNv, NvSubImageBlit, NV_IMAGE_BLIT_SURFACE, 1);
256         NVDmaNext (pNv, NvContextSurfaces);
257         NVDmaStart(pNv, NvSubImageBlit, NV_IMAGE_BLIT_CLIP_RECTANGLE, 3);
258         NVDmaNext (pNv, NvNullObject);
259         NVDmaNext (pNv, NvImagePattern);
260         NVDmaNext (pNv, NvRop);
261         NVDmaStart(pNv, NvSubImageBlit, NV_IMAGE_BLIT_OPERATION, 1);
262         NVDmaNext (pNv, 1 /* NV_IMAGE_BLIT_OPERATION_ROP_AND */);
263
264         return TRUE;
265 }
266
267 /* FLAGS_SRCCOPY, DmaFB, DmaFB, 0 */
268 static Bool
269 NVAccelInitScaledImage(ScrnInfoPtr pScrn)
270 {
271         NVPtr pNv = NVPTR(pScrn);
272         static int have_object = FALSE;
273         uint32_t   class;
274
275         switch (pNv->Architecture) {
276         case NV_ARCH_04:
277                 class = NV04_SCALED_IMAGE_FROM_MEMORY;
278                 break;
279         case NV_ARCH_10:
280         case NV_ARCH_20:
281         case NV_ARCH_30:
282                 class = NV10_SCALED_IMAGE_FROM_MEMORY;
283                 break;
284         case NV_ARCH_40:
285         default:
286                 class = NV10_SCALED_IMAGE_FROM_MEMORY | 0x3000;
287                 break;
288         }
289
290         if (!have_object) {
291                 if (!NVDmaCreateContextObject(pNv, NvScaledImage, class))
292                         return FALSE;
293                 have_object = TRUE;
294         }
295
296         NVDmaSetObjectOnSubchannel(pNv, NvSubScaledImage, NvScaledImage);
297         NVDmaStart(pNv, NvSubScaledImage,
298                         NV04_SCALED_IMAGE_FROM_MEMORY_DMA_NOTIFY, 1);
299         NVDmaNext (pNv, NvDmaNotifier0);
300         NVDmaStart(pNv, NvSubScaledImage,
301                         NV04_SCALED_IMAGE_FROM_MEMORY_DMA_IMAGE, 1);
302         NVDmaNext (pNv, NvDmaFB); /* source object */
303         NVDmaStart(pNv, NvSubScaledImage,
304                         NV04_SCALED_IMAGE_FROM_MEMORY_SURFACE, 1);
305         NVDmaNext (pNv, NvContextSurfaces);
306         NVDmaStart(pNv, NvSubScaledImage, 0x188, 1); /* PATTERN */
307         NVDmaNext (pNv, NvNullObject);
308         NVDmaStart(pNv, NvSubScaledImage, 0x18c, 1); /* ROP */
309         NVDmaNext (pNv, NvNullObject);
310         NVDmaStart(pNv, NvSubScaledImage, 0x190, 1); /* BETA1 */
311         NVDmaNext (pNv, NvNullObject);
312         NVDmaStart(pNv, NvSubScaledImage, 0x194, 1); /* BETA4 */
313         NVDmaNext (pNv, NvNullObject);
314         NVDmaStart(pNv, NvSubScaledImage,
315                         NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION, 1);
316         NVDmaNext (pNv, 3 /* SRCCOPY */);
317
318         return TRUE;
319 }
320
321 /* FLAGS_NONE, 0, 0, 0 */
322 static Bool
323 NVAccelInitClipRectangle(ScrnInfoPtr pScrn)
324 {
325         NVPtr pNv = NVPTR(pScrn);
326         static int have_object = FALSE;
327         int class = NV01_CONTEXT_CLIP_RECTANGLE;
328
329         if (!have_object) {
330                 if (!NVDmaCreateContextObject(pNv, NvClipRectangle, class))
331                         return FALSE;
332                 have_object = TRUE;
333         }
334
335         NVDmaSetObjectOnSubchannel(pNv, NvSubClipRectangle, NvClipRectangle);
336         NVDmaStart(pNv, NvSubClipRectangle, 0x180, 1); /* DMA_NOTIFY */
337         NVDmaNext (pNv, NvNullObject);
338
339         return TRUE;
340 }
341
342 /* FLAGS_ROP_AND | FLAGS_CLIP_ENABLE, 0, 0, 0 */
343 static Bool
344 NVAccelInitSolidLine(ScrnInfoPtr pScrn)
345 {
346         NVPtr pNv = NVPTR(pScrn);
347         static int have_object = FALSE;
348         int class = NV04_SOLID_LINE;
349
350         if (!have_object) {
351                 if (!NVDmaCreateContextObject(pNv, NvSolidLine, class))
352                         return FALSE;
353                 have_object = TRUE;
354         }
355
356         NVDmaSetObjectOnSubchannel(pNv, NvSubSolidLine, NvSolidLine);
357         NVDmaStart(pNv, NvSubSolidLine, NV04_SOLID_LINE_CLIP_RECTANGLE, 3);
358         NVDmaNext (pNv, NvClipRectangle);
359         NVDmaNext (pNv, NvImagePattern);
360         NVDmaNext (pNv, NvRop);
361         NVDmaStart(pNv, NvSubSolidLine, NV04_SOLID_LINE_SURFACE, 1);
362         NVDmaNext (pNv, NvContextSurfaces);
363         NVDmaStart(pNv, NvSubSolidLine, NV04_SOLID_LINE_OPERATION, 1);
364         NVDmaNext (pNv, 1); /* ROP_AND */
365
366         return TRUE;
367 }
368
369 /* FLAGS_NONE, NvDmaFB, NvDmaAGP, NvDmaNotifier0 */
370 static Bool
371 NVAccelInitMemFormat(ScrnInfoPtr pScrn)
372 {
373         NVPtr pNv = NVPTR(pScrn);
374         static int have_object = FALSE;
375         uint32_t   class;
376
377         class = NV_MEMORY_TO_MEMORY_FORMAT;
378
379         if (!have_object) {
380                 if (!NVDmaCreateContextObject(pNv, NvMemFormat, class))
381                                 return FALSE;
382                 have_object = TRUE;
383         }
384
385         NVDmaSetObjectOnSubchannel(pNv, NvSubMemFormat, NvMemFormat);
386         NVDmaStart(pNv, NvSubMemFormat,
387                         NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1);
388         NVDmaNext (pNv, NvDmaNotifier0);
389         NVDmaStart(pNv, NvSubMemFormat,
390                         NV_MEMORY_TO_MEMORY_FORMAT_OBJECT_IN, 2);
391         NVDmaNext (pNv, NvDmaFB);
392         NVDmaNext (pNv, NvDmaFB);
393
394         pNv->M2MFDirection = -1;
395         return TRUE;
396 }
397
398 #define INIT_CONTEXT_OBJECT(name) do {                                        \
399         ret = NVAccelInit##name(pScrn);                                       \
400         if (!ret) {                                                           \
401                 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,                         \
402                            "Failed to initialise context object: "#name       \
403                            " (%d)\n", ret);                                   \
404                 return FALSE;                                                 \
405         }                                                                     \
406 } while(0)
407
408 Bool
409 NVAccelCommonInit(ScrnInfoPtr pScrn)
410 {
411         NVPtr pNv = NVPTR(pScrn);
412         Bool ret;
413         if(pNv->NoAccel) return TRUE;
414
415         INIT_CONTEXT_OBJECT(NullObject);
416         INIT_CONTEXT_OBJECT(DmaNotifier0);
417
418         INIT_CONTEXT_OBJECT(ContextSurfaces);
419         INIT_CONTEXT_OBJECT(ImagePattern);
420         INIT_CONTEXT_OBJECT(RasterOp);
421         INIT_CONTEXT_OBJECT(Rectangle);
422         INIT_CONTEXT_OBJECT(ImageBlit);
423         INIT_CONTEXT_OBJECT(ScaledImage);
424
425         /* XAA-only */
426         INIT_CONTEXT_OBJECT(ClipRectangle);
427         INIT_CONTEXT_OBJECT(SolidLine);
428
429         /* EXA-only */
430         INIT_CONTEXT_OBJECT(MemFormat);
431
432         /* 3D init */
433         switch (pNv->Architecture) {
434         case NV_ARCH_40:
435                 INIT_CONTEXT_OBJECT(NV40TCL);
436                 break;
437         default:
438                 break;
439         }
440
441         return TRUE;
442 }
443