Hint added.
[AROS.git] / workbench / hidds / nouveau / xf86-video-nouveau / nv_accel_common.c
blob2ab52bb2adf0e40f550a97f518b593af5324c4c9
1 /*
2 * Copyright 2007 Ben Skeggs
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:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
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.
23 #include "nv_include.h"
24 #include "nv04_pushbuf.h"
25 #if defined(__AROS__)
26 #include <aros/debug.h>
27 #endif
29 #if !defined(__AROS__)
30 Bool
31 nouveau_allocate_surface(ScrnInfoPtr scrn, int width, int height, int bpp,
32 int usage_hint, int *pitch, struct nouveau_bo **bo)
34 NVPtr pNv = NVPTR(scrn);
35 Bool scanout = (usage_hint & NOUVEAU_CREATE_PIXMAP_SCANOUT);
36 Bool tiled = (usage_hint & NOUVEAU_CREATE_PIXMAP_TILED);
37 int tile_mode = 0, tile_flags = 0;
38 int flags = NOUVEAU_BO_MAP | (bpp >= 8 ? NOUVEAU_BO_VRAM : 0);
39 int cpp = bpp / 8, ret;
41 if (pNv->Architecture >= NV_ARCH_50) {
42 if (scanout) {
43 if (pNv->tiled_scanout) {
44 tiled = TRUE;
45 *pitch = NOUVEAU_ALIGN(width * cpp, 64);
46 } else {
47 *pitch = NOUVEAU_ALIGN(width * cpp, 256);
49 } else {
50 if (bpp >= 8)
51 tiled = TRUE;
52 *pitch = NOUVEAU_ALIGN(width * cpp, 64);
54 } else {
55 if (scanout && pNv->tiled_scanout)
56 tiled = TRUE;
57 *pitch = NOUVEAU_ALIGN(width * cpp, 64);
60 if (tiled) {
61 if (pNv->Architecture >= NV_ARCH_C0) {
62 if (height > 64)
63 tile_mode = 0x40;
64 else if (height > 32)
65 tile_mode = 0x30;
66 else if (height > 16)
67 tile_mode = 0x20;
68 else if (height > 8)
69 tile_mode = 0x10;
70 else
71 tile_mode = 0x00;
73 if (usage_hint & NOUVEAU_CREATE_PIXMAP_ZETA)
74 tile_flags = 0x1100; /* S8Z24 */
75 else
76 tile_flags = 0xfe00;
78 height = NOUVEAU_ALIGN(
79 height, NVC0_TILE_HEIGHT(tile_mode));
80 } else if (pNv->Architecture >= NV_ARCH_50) {
81 if (height > 32)
82 tile_mode = 4;
83 else if (height > 16)
84 tile_mode = 3;
85 else if (height > 8)
86 tile_mode = 2;
87 else if (height > 4)
88 tile_mode = 1;
89 else
90 tile_mode = 0;
92 if (usage_hint & NOUVEAU_CREATE_PIXMAP_ZETA)
93 tile_flags = 0x22800;
94 else if (usage_hint & NOUVEAU_CREATE_PIXMAP_SCANOUT)
95 tile_flags = (bpp == 16 ? 0x7000 : 0x7a00);
96 else
97 tile_flags = 0x7000;
99 height = NOUVEAU_ALIGN(height, 1 << (tile_mode + 2));
100 } else {
101 int pitch_align = max(
102 pNv->dev->chipset >= 0x40 ? 1024 : 256,
103 round_down_pow2(*pitch / 4));
105 tile_mode = *pitch =
106 NOUVEAU_ALIGN(*pitch, pitch_align);
110 if (bpp == 32)
111 tile_flags |= NOUVEAU_BO_TILE_32BPP;
112 else if (bpp == 16)
113 tile_flags |= NOUVEAU_BO_TILE_16BPP;
115 if (usage_hint & NOUVEAU_CREATE_PIXMAP_ZETA)
116 tile_flags |= NOUVEAU_BO_TILE_ZETA;
118 if (usage_hint & NOUVEAU_CREATE_PIXMAP_SCANOUT)
119 tile_flags |= NOUVEAU_BO_TILE_SCANOUT;
121 ret = nouveau_bo_new_tile(pNv->dev, flags, 0, *pitch * height,
122 tile_mode, tile_flags, bo);
123 if (ret)
124 return FALSE;
126 return TRUE;
129 void
130 NV11SyncToVBlank(PixmapPtr ppix, BoxPtr box)
132 ScrnInfoPtr pScrn = xf86Screens[ppix->drawable.pScreen->myNum];
133 NVPtr pNv = NVPTR(pScrn);
134 struct nouveau_channel *chan = pNv->chan;
135 struct nouveau_grobj *blit = pNv->NvImageBlit;
136 int crtcs;
138 if (!nouveau_exa_pixmap_is_onscreen(ppix))
139 return;
141 crtcs = nv_window_belongs_to_crtc(pScrn, box->x1, box->y1,
142 box->x2 - box->x1,
143 box->y2 - box->y1);
144 if (!crtcs)
145 return;
147 BEGIN_RING(chan, blit, 0x0000012C, 1);
148 OUT_RING (chan, 0);
149 BEGIN_RING(chan, blit, 0x00000134, 1);
150 OUT_RING (chan, ffs(crtcs) - 1);
151 BEGIN_RING(chan, blit, 0x00000100, 1);
152 OUT_RING (chan, 0);
153 BEGIN_RING(chan, blit, 0x00000130, 1);
154 OUT_RING (chan, 0);
156 #endif
158 static Bool
159 NVAccelInitDmaNotifier0(ScrnInfoPtr pScrn)
161 NVPtr pNv = NVPTR(pScrn);
163 if (!pNv->notify0) {
164 if (nouveau_notifier_alloc(pNv->chan, NvDmaNotifier0, 1,
165 &pNv->notify0))
166 return FALSE;
169 return TRUE;
172 /* FLAGS_ROP_AND, DmaFB, DmaFB, 0 */
173 static Bool
174 NVAccelInitContextSurfaces(ScrnInfoPtr pScrn)
176 NVPtr pNv = NVPTR(pScrn);
177 struct nouveau_channel *chan = pNv->chan;
178 struct nouveau_grobj *surf2d;
179 uint32_t class;
181 class = (pNv->Architecture >= NV_ARCH_10) ? NV10_CONTEXT_SURFACES_2D :
182 NV04_CONTEXT_SURFACES_2D;
184 if (!pNv->NvContextSurfaces) {
185 if (nouveau_grobj_alloc(chan, NvContextSurfaces, class,
186 &pNv->NvContextSurfaces))
187 return FALSE;
189 surf2d = pNv->NvContextSurfaces;
191 BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_DMA_NOTIFY, 1);
192 OUT_RING (chan, chan->nullobj->handle);
193 BEGIN_RING(chan, surf2d,
194 NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2);
195 OUT_RING (chan, pNv->chan->vram->handle);
196 OUT_RING (chan, pNv->chan->vram->handle);
198 return TRUE;
201 #if !defined(__AROS__)
202 /* FLAGS_ROP_AND, DmaFB, DmaFB, 0 */
203 static Bool
204 NVAccelInitContextBeta1(ScrnInfoPtr pScrn)
206 NVPtr pNv = NVPTR(pScrn);
207 struct nouveau_channel *chan = pNv->chan;
208 struct nouveau_grobj *beta1;
210 if (!pNv->NvContextBeta1) {
211 if (nouveau_grobj_alloc(chan, NvContextBeta1, 0x12,
212 &pNv->NvContextBeta1))
213 return FALSE;
215 beta1 = pNv->NvContextBeta1;
217 BEGIN_RING(chan, beta1, 0x300, 1); /*alpha factor*/
218 OUT_RING (chan, 0xff << 23);
220 return TRUE;
224 static Bool
225 NVAccelInitContextBeta4(ScrnInfoPtr pScrn)
227 NVPtr pNv = NVPTR(pScrn);
228 struct nouveau_channel *chan = pNv->chan;
229 struct nouveau_grobj *beta4;
231 if (!pNv->NvContextBeta4) {
232 if (nouveau_grobj_alloc(chan, NvContextBeta4, 0x72,
233 &pNv->NvContextBeta4))
234 return FALSE;
236 beta4 = pNv->NvContextBeta4;
238 BEGIN_RING(chan, beta4, 0x300, 1); /*RGBA factor*/
239 OUT_RING (chan, 0xffff0000);
240 return TRUE;
242 #endif
244 Bool
245 NVAccelGetCtxSurf2DFormatFromPixmap(PixmapPtr pPix, int *fmt_ret)
247 #if !defined(__AROS__)
248 switch (pPix->drawable.bitsPerPixel) {
249 #else
250 switch (pPix->depth) {
251 #endif
252 case 32:
253 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_A8R8G8B8;
254 break;
255 case 24:
256 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_X8R8G8B8_Z8R8G8B8;
257 break;
258 case 16:
259 #if !defined(__AROS__)
260 if (pPix->drawable.depth == 16)
261 #else
262 if (pPix->depth == 16)
263 #endif
264 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_R5G6B5;
265 else
266 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_X1R5G5B5_Z1R5G5B5;
267 break;
268 case 8:
269 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_Y8;
270 break;
271 default:
272 return FALSE;
275 return TRUE;
278 #if !defined(__AROS__)
279 Bool
280 NVAccelGetCtxSurf2DFormatFromPicture(PicturePtr pPict, int *fmt_ret)
282 switch (pPict->format) {
283 case PICT_a8r8g8b8:
284 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_A8R8G8B8;
285 break;
286 case PICT_x8r8g8b8:
287 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_X8R8G8B8_Z8R8G8B8;
288 break;
289 case PICT_r5g6b5:
290 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_R5G6B5;
291 break;
292 case PICT_a8:
293 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_Y8;
294 break;
295 default:
296 return FALSE;
299 return TRUE;
302 /* A copy of exaGetOffscreenPixmap(), since it's private. */
303 PixmapPtr
304 NVGetDrawablePixmap(DrawablePtr pDraw)
306 if (pDraw->type == DRAWABLE_WINDOW)
307 return pDraw->pScreen->GetWindowPixmap ((WindowPtr) pDraw);
308 else
309 return (PixmapPtr) pDraw;
311 #endif
313 static Bool
314 NVAccelInitImagePattern(ScrnInfoPtr pScrn)
316 NVPtr pNv = NVPTR(pScrn);
317 struct nouveau_channel *chan = pNv->chan;
318 struct nouveau_grobj *patt;
320 if (!pNv->NvImagePattern) {
321 if (nouveau_grobj_alloc(chan, NvImagePattern,
322 NV04_IMAGE_PATTERN,
323 &pNv->NvImagePattern))
324 return FALSE;
326 patt = pNv->NvImagePattern;
328 BEGIN_RING(chan, patt, NV04_IMAGE_PATTERN_DMA_NOTIFY, 1);
329 OUT_RING (chan, chan->nullobj->handle);
330 BEGIN_RING(chan, patt, NV04_IMAGE_PATTERN_MONOCHROME_FORMAT, 3);
331 #if X_BYTE_ORDER == X_BIG_ENDIAN
332 OUT_RING (chan, NV04_IMAGE_PATTERN_MONOCHROME_FORMAT_LE);
333 #else
334 OUT_RING (chan, NV04_IMAGE_PATTERN_MONOCHROME_FORMAT_CGA6);
335 #endif
336 OUT_RING (chan, NV04_IMAGE_PATTERN_MONOCHROME_SHAPE_8X8);
337 OUT_RING (chan, NV04_IMAGE_PATTERN_PATTERN_SELECT_MONO);
339 return TRUE;
342 static Bool
343 NVAccelInitRasterOp(ScrnInfoPtr pScrn)
345 NVPtr pNv = NVPTR(pScrn);
346 struct nouveau_channel *chan = pNv->chan;
347 struct nouveau_grobj *rop;
349 if (!pNv->NvRop) {
350 if (nouveau_grobj_alloc(chan, NvRop, NV03_CONTEXT_ROP,
351 &pNv->NvRop))
352 return FALSE;
354 rop = pNv->NvRop;
356 BEGIN_RING(chan, rop, NV03_CONTEXT_ROP_DMA_NOTIFY, 1);
357 OUT_RING (chan, chan->nullobj->handle);
359 // pNv->currentRop = ~0;
360 return TRUE;
363 static Bool
364 NVAccelInitRectangle(ScrnInfoPtr pScrn)
366 NVPtr pNv = NVPTR(pScrn);
367 struct nouveau_channel *chan = pNv->chan;
368 struct nouveau_grobj *rect;
370 if (!pNv->NvRectangle) {
371 if (nouveau_grobj_alloc(chan, NvRectangle,
372 NV04_GDI_RECTANGLE_TEXT,
373 &pNv->NvRectangle))
374 return FALSE;
376 rect = pNv->NvRectangle;
378 BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_DMA_NOTIFY, 1);
379 OUT_RING (chan, pNv->notify0->handle);
380 BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_DMA_FONTS, 1);
381 OUT_RING (chan, chan->nullobj->handle);
382 BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_SURFACE, 1);
383 OUT_RING (chan, pNv->NvContextSurfaces->handle);
384 BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_ROP, 1);
385 OUT_RING (chan, pNv->NvRop->handle);
386 BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_PATTERN, 1);
387 OUT_RING (chan, pNv->NvImagePattern->handle);
388 BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1);
389 OUT_RING (chan, NV04_GDI_RECTANGLE_TEXT_OPERATION_ROP_AND);
390 BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT, 1);
391 /* XXX why putting 1 like renouveau dump, swap the text */
392 #if 1 || X_BYTE_ORDER == X_BIG_ENDIAN
393 OUT_RING (chan, NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT_LE);
394 #else
395 OUT_RING (chan, NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT_CGA6);
396 #endif
398 return TRUE;
401 static Bool
402 NVAccelInitImageBlit(ScrnInfoPtr pScrn)
404 NVPtr pNv = NVPTR(pScrn);
405 struct nouveau_channel *chan = pNv->chan;
406 struct nouveau_grobj *blit;
407 uint32_t class;
409 class = (pNv->dev->chipset >= 0x11) ? NV12_IMAGE_BLIT : NV04_IMAGE_BLIT;
411 if (!pNv->NvImageBlit) {
412 if (nouveau_grobj_alloc(chan, NvImageBlit, class,
413 &pNv->NvImageBlit))
414 return FALSE;
416 blit = pNv->NvImageBlit;
418 BEGIN_RING(chan, blit, NV01_IMAGE_BLIT_DMA_NOTIFY, 1);
419 OUT_RING (chan, pNv->notify0->handle);
420 BEGIN_RING(chan, blit, NV01_IMAGE_BLIT_COLOR_KEY, 1);
421 OUT_RING (chan, chan->nullobj->handle);
422 BEGIN_RING(chan, blit, NV04_IMAGE_BLIT_SURFACE, 1);
423 OUT_RING (chan, pNv->NvContextSurfaces->handle);
424 BEGIN_RING(chan, blit, NV01_IMAGE_BLIT_CLIP_RECTANGLE, 3);
425 OUT_RING (chan, chan->nullobj->handle);
426 OUT_RING (chan, pNv->NvImagePattern->handle);
427 OUT_RING (chan, pNv->NvRop->handle);
428 BEGIN_RING(chan, blit, NV01_IMAGE_BLIT_OPERATION, 1);
429 OUT_RING (chan, NV01_IMAGE_BLIT_OPERATION_ROP_AND);
431 if (blit->grclass == NV12_IMAGE_BLIT) {
432 BEGIN_RING(chan, blit, 0x0120, 3);
433 OUT_RING (chan, 0);
434 OUT_RING (chan, 1);
435 OUT_RING (chan, 2);
438 return TRUE;
441 #if !defined(__AROS__)
442 static Bool
443 NVAccelInitScaledImage(ScrnInfoPtr pScrn)
445 NVPtr pNv = NVPTR(pScrn);
446 struct nouveau_channel *chan = pNv->chan;
447 struct nouveau_grobj *sifm;
448 uint32_t class;
450 switch (pNv->Architecture) {
451 case NV_ARCH_04:
452 class = NV04_SCALED_IMAGE_FROM_MEMORY;
453 break;
454 case NV_ARCH_10:
455 case NV_ARCH_20:
456 case NV_ARCH_30:
457 class = NV10_SCALED_IMAGE_FROM_MEMORY;
458 break;
459 case NV_ARCH_40:
460 default:
461 class = NV10_SCALED_IMAGE_FROM_MEMORY | 0x3000;
462 break;
465 if (!pNv->NvScaledImage) {
466 if (nouveau_grobj_alloc(chan, NvScaledImage, class,
467 &pNv->NvScaledImage))
468 return FALSE;
470 sifm = pNv->NvScaledImage;
472 BEGIN_RING(chan, sifm,
473 NV03_SCALED_IMAGE_FROM_MEMORY_DMA_NOTIFY, 7);
474 OUT_RING (chan, pNv->notify0->handle);
475 OUT_RING (chan, pNv->chan->vram->handle);
476 OUT_RING (chan, chan->nullobj->handle);
477 OUT_RING (chan, chan->nullobj->handle);
478 OUT_RING (chan, pNv->NvContextBeta1->handle);
479 OUT_RING (chan, pNv->NvContextBeta4->handle);
480 OUT_RING (chan, pNv->NvContextSurfaces->handle);
481 if (pNv->Architecture>=NV_ARCH_10) {
482 BEGIN_RING(chan, sifm,
483 NV05_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION, 1);
484 OUT_RING (chan, NV05_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION_DITHER);
486 BEGIN_RING(chan, sifm, NV03_SCALED_IMAGE_FROM_MEMORY_OPERATION, 1);
487 OUT_RING (chan, NV03_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY);
489 return TRUE;
492 static Bool
493 NVAccelInitClipRectangle(ScrnInfoPtr pScrn)
495 NVPtr pNv = NVPTR(pScrn);
496 struct nouveau_channel *chan = pNv->chan;
497 struct nouveau_grobj *clip;
499 if (!pNv->NvClipRectangle) {
500 if (nouveau_grobj_alloc(pNv->chan, NvClipRectangle,
501 NV01_CONTEXT_CLIP_RECTANGLE,
502 &pNv->NvClipRectangle))
503 return FALSE;
505 clip = pNv->NvClipRectangle;
507 BEGIN_RING(chan, clip, NV01_CONTEXT_CLIP_RECTANGLE_DMA_NOTIFY, 1);
508 OUT_RING (chan, chan->nullobj->handle);
510 return TRUE;
512 #endif
514 /* FLAGS_NONE, NvDmaFB, NvDmaAGP, NvDmaNotifier0 */
515 static Bool
516 NVAccelInitMemFormat(ScrnInfoPtr pScrn)
518 NVPtr pNv = NVPTR(pScrn);
519 struct nouveau_channel *chan = pNv->chan;
520 struct nouveau_grobj *m2mf;
521 uint32_t class;
523 if (pNv->Architecture < NV_ARCH_50)
524 class = NV04_MEMORY_TO_MEMORY_FORMAT;
525 else
526 class = NV50_MEMORY_TO_MEMORY_FORMAT;
528 if (!pNv->NvMemFormat) {
529 if (nouveau_grobj_alloc(chan, NvMemFormat, class,
530 &pNv->NvMemFormat))
531 return FALSE;
533 m2mf = pNv->NvMemFormat;
535 BEGIN_RING(chan, m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1);
536 OUT_RING (chan, pNv->notify0->handle);
537 BEGIN_RING(chan, m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_IN, 2);
538 OUT_RING (chan, chan->vram->handle);
539 OUT_RING (chan, chan->vram->handle);
541 return TRUE;
544 #if !defined(__AROS__)
545 static Bool
546 NVAccelInitImageFromCpu(ScrnInfoPtr pScrn)
548 NVPtr pNv = NVPTR(pScrn);
549 struct nouveau_channel *chan = pNv->chan;
550 struct nouveau_grobj *ifc;
551 uint32_t class;
553 switch (pNv->Architecture) {
554 case NV_ARCH_04:
555 class = NV04_IMAGE_FROM_CPU;
556 break;
557 case NV_ARCH_10:
558 case NV_ARCH_20:
559 case NV_ARCH_30:
560 case NV_ARCH_40:
561 default:
562 class = NV10_IMAGE_FROM_CPU;
563 break;
566 if (!pNv->NvImageFromCpu) {
567 if (nouveau_grobj_alloc(chan, NvImageFromCpu, class,
568 &pNv->NvImageFromCpu))
569 return FALSE;
571 ifc = pNv->NvImageFromCpu;
573 BEGIN_RING(chan, ifc, NV01_IMAGE_FROM_CPU_DMA_NOTIFY, 1);
574 OUT_RING (chan, pNv->notify0->handle);
575 BEGIN_RING(chan, ifc, NV01_IMAGE_FROM_CPU_CLIP_RECTANGLE, 1);
576 OUT_RING (chan, chan->nullobj->handle);
577 BEGIN_RING(chan, ifc, NV01_IMAGE_FROM_CPU_PATTERN, 1);
578 OUT_RING (chan, chan->nullobj->handle);
579 BEGIN_RING(chan, ifc, NV01_IMAGE_FROM_CPU_ROP, 1);
580 OUT_RING (chan, chan->nullobj->handle);
581 if (pNv->Architecture >= NV_ARCH_10) {
582 BEGIN_RING(chan, ifc, NV01_IMAGE_FROM_CPU_BETA1, 1);
583 OUT_RING (chan, chan->nullobj->handle);
584 BEGIN_RING(chan, ifc, NV04_IMAGE_FROM_CPU_BETA4, 1);
585 OUT_RING (chan, chan->nullobj->handle);
587 BEGIN_RING(chan, ifc, NV04_IMAGE_FROM_CPU_SURFACE, 1);
588 OUT_RING (chan, pNv->NvContextSurfaces->handle);
589 BEGIN_RING(chan, ifc, NV01_IMAGE_FROM_CPU_OPERATION, 1);
590 OUT_RING (chan, NV01_IMAGE_FROM_CPU_OPERATION_SRCCOPY);
592 return TRUE;
594 #endif
596 static Bool
597 NVAccelInit2D_NV50(ScrnInfoPtr pScrn)
599 NVPtr pNv = NVPTR(pScrn);
600 struct nouveau_channel *chan = pNv->chan;
601 struct nouveau_grobj *eng2d;
603 if (!pNv->Nv2D) {
604 if (nouveau_grobj_alloc(chan, Nv2D, NV50_2D, &pNv->Nv2D))
605 return FALSE;
607 eng2d = pNv->Nv2D;
609 BEGIN_RING(chan, eng2d, NV50_2D_DMA_NOTIFY, 3);
610 OUT_RING (chan, pNv->notify0->handle);
611 OUT_RING (chan, pNv->chan->vram->handle);
612 OUT_RING (chan, pNv->chan->vram->handle);
614 /* Magics from nv, no clue what they do, but at least some
615 * of them are needed to avoid crashes.
617 BEGIN_RING(chan, eng2d, 0x260, 1);
618 OUT_RING (chan, 1);
619 BEGIN_RING(chan, eng2d, NV50_2D_CLIP_ENABLE, 1);
620 OUT_RING (chan, 1);
621 BEGIN_RING(chan, eng2d, NV50_2D_COLOR_KEY_ENABLE, 1);
622 OUT_RING (chan, 0);
623 BEGIN_RING(chan, eng2d, 0x58c, 1);
624 OUT_RING (chan, 0x111);
626 // pNv->currentRop = 0xfffffffa;
627 return TRUE;
630 #if !defined(__AROS__)
631 #define INIT_CONTEXT_OBJECT(name) do { \
632 ret = NVAccelInit##name(pScrn); \
633 if (!ret) { \
634 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, \
635 "Failed to initialise context object: "#name \
636 " (%d)\n", ret); \
637 return FALSE; \
639 } while(0)
640 #else
641 #define INIT_CONTEXT_OBJECT(name) do { \
642 ret = NVAccelInit##name(pScrn); \
643 if (!ret) { \
644 bug("[nouveau] Failed to initialise context object: "#name \
645 " (%d)\n", ret); \
646 return FALSE; \
648 } while(0)
649 #endif
651 Bool
652 NVAccelCommonInit(ScrnInfoPtr pScrn)
654 NVPtr pNv = NVPTR(pScrn);
655 Bool ret;
657 #if !defined(__AROS__)
658 if (pNv->NoAccel)
659 return TRUE;
660 #endif
662 /* General engine objects */
663 if (pNv->Architecture < NV_ARCH_C0)
664 INIT_CONTEXT_OBJECT(DmaNotifier0);
666 /* 2D engine */
667 if (pNv->Architecture < NV_ARCH_50) {
668 INIT_CONTEXT_OBJECT(ContextSurfaces);
669 #if !defined(__AROS__)
670 INIT_CONTEXT_OBJECT(ContextBeta1);
671 INIT_CONTEXT_OBJECT(ContextBeta4);
672 #endif
673 INIT_CONTEXT_OBJECT(ImagePattern);
674 INIT_CONTEXT_OBJECT(RasterOp);
675 INIT_CONTEXT_OBJECT(Rectangle);
676 INIT_CONTEXT_OBJECT(ImageBlit);
677 #if !defined(__AROS__)
678 INIT_CONTEXT_OBJECT(ScaledImage);
679 INIT_CONTEXT_OBJECT(ClipRectangle);
680 INIT_CONTEXT_OBJECT(ImageFromCpu);
681 #endif
682 } else
683 if (pNv->Architecture < NV_ARCH_C0) {
684 INIT_CONTEXT_OBJECT(2D_NV50);
685 } else {
686 INIT_CONTEXT_OBJECT(2D_NVC0);
689 if (pNv->Architecture < NV_ARCH_C0)
690 INIT_CONTEXT_OBJECT(MemFormat);
691 else
692 INIT_CONTEXT_OBJECT(M2MF_NVC0);
694 /* 3D init */
695 switch (pNv->Architecture) {
696 case NV_ARCH_C0:
697 INIT_CONTEXT_OBJECT(3D_NVC0);
698 break;
699 case NV_ARCH_50:
700 INIT_CONTEXT_OBJECT(NV50TCL);
701 break;
702 case NV_ARCH_40:
703 INIT_CONTEXT_OBJECT(NV40TCL);
704 break;
705 case NV_ARCH_30:
706 INIT_CONTEXT_OBJECT(NV30TCL);
707 break;
708 case NV_ARCH_20:
709 case NV_ARCH_10:
710 INIT_CONTEXT_OBJECT(NV10TCL);
711 break;
712 default:
713 break;
716 return TRUE;
719 void NVAccelFree(ScrnInfoPtr pScrn)
721 NVPtr pNv = NVPTR(pScrn);
723 #if !defined(__AROS__)
724 if (pNv->NoAccel)
725 return;
726 #endif
728 nouveau_notifier_free(&pNv->notify0);
729 nouveau_notifier_free(&pNv->vblank_sem);
731 nouveau_grobj_free(&pNv->NvContextSurfaces);
732 #if !defined(__AROS__)
733 nouveau_grobj_free(&pNv->NvContextBeta1);
734 nouveau_grobj_free(&pNv->NvContextBeta4);
735 #endif
736 nouveau_grobj_free(&pNv->NvImagePattern);
737 nouveau_grobj_free(&pNv->NvRop);
738 nouveau_grobj_free(&pNv->NvRectangle);
739 nouveau_grobj_free(&pNv->NvImageBlit);
740 #if !defined(__AROS__)
741 nouveau_grobj_free(&pNv->NvScaledImage);
742 nouveau_grobj_free(&pNv->NvClipRectangle);
743 nouveau_grobj_free(&pNv->NvImageFromCpu);
744 #endif
745 nouveau_grobj_free(&pNv->Nv2D);
746 nouveau_grobj_free(&pNv->NvMemFormat);
747 nouveau_grobj_free(&pNv->NvSW);
748 nouveau_grobj_free(&pNv->Nv3D);
750 nouveau_bo_ref(NULL, &pNv->tesla_scratch);
751 nouveau_bo_ref(NULL, &pNv->shader_mem);
755 /* AROS CODE */
757 BOOL HIDDNouveauAccelCommonInit(struct CardData * carddata)
759 return NVAccelCommonInit(carddata);
762 VOID HIDDNouveauAccelFree(struct CardData * carddata)
764 NVAccelFree(carddata);