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
23 #include "nv_include.h"
26 NVAccelInitDmaNotifier0(ScrnInfoPtr pScrn)
28 NVPtr pNv = NVPTR(pScrn);
31 if (nouveau_notifier_alloc(pNv->chan, NvDmaNotifier0, 1,
39 /* FLAGS_ROP_AND, DmaFB, DmaFB, 0 */
41 NVAccelInitContextSurfaces(ScrnInfoPtr pScrn)
43 NVPtr pNv = NVPTR(pScrn);
44 struct nouveau_channel *chan = pNv->chan;
45 struct nouveau_grobj *surf2d;
48 class = (pNv->Architecture >= NV_10) ? NV10_CONTEXT_SURFACES_2D :
49 NV04_CONTEXT_SURFACES_2D;
51 if (!pNv->NvContextSurfaces) {
52 if (nouveau_grobj_alloc(chan, NvContextSurfaces, class,
53 &pNv->NvContextSurfaces))
56 surf2d = pNv->NvContextSurfaces;
58 BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_DMA_NOTIFY, 1);
59 OUT_RING (chan, chan->nullobj->handle);
60 BEGIN_RING(chan, surf2d,
61 NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2);
62 OUT_RING (chan, pNv->chan->vram->handle);
63 OUT_RING (chan, pNv->chan->vram->handle);
68 /* FLAGS_ROP_AND, DmaFB, DmaFB, 0 */
70 NVAccelInitContextBeta1(ScrnInfoPtr pScrn)
72 NVPtr pNv = NVPTR(pScrn);
73 struct nouveau_channel *chan = pNv->chan;
74 struct nouveau_grobj *beta1;
76 if (!pNv->NvContextBeta1) {
77 if (nouveau_grobj_alloc(chan, NvContextBeta1, 0x12,
78 &pNv->NvContextBeta1))
81 beta1 = pNv->NvContextBeta1;
83 BEGIN_RING(chan, beta1, 0x300, 1); /*alpha factor*/
84 OUT_RING (chan, 0xff << 23);
91 NVAccelInitContextBeta4(ScrnInfoPtr pScrn)
93 NVPtr pNv = NVPTR(pScrn);
94 struct nouveau_channel *chan = pNv->chan;
95 struct nouveau_grobj *beta4;
97 if (!pNv->NvContextBeta4) {
98 if (nouveau_grobj_alloc(chan, NvContextBeta4, 0x72,
99 &pNv->NvContextBeta4))
102 beta4 = pNv->NvContextBeta4;
104 BEGIN_RING(chan, beta4, 0x300, 1); /*RGBA factor*/
105 OUT_RING (chan, 0xffff0000);
110 NVAccelGetCtxSurf2DFormatFromPixmap(PixmapPtr pPix, int *fmt_ret)
112 switch (pPix->drawable.bitsPerPixel) {
114 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_A8R8G8B8;
117 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_X8R8G8B8_Z8R8G8B8;
120 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_R5G6B5;
123 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_Y8;
133 NVAccelGetCtxSurf2DFormatFromPicture(PicturePtr pPict, int *fmt_ret)
135 switch (pPict->format) {
137 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_A8R8G8B8;
140 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_X8R8G8B8_Z8R8G8B8;
143 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_R5G6B5;
146 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_Y8;
155 /* A copy of exaGetOffscreenPixmap(), since it's private. */
157 NVGetDrawablePixmap(DrawablePtr pDraw)
159 if (pDraw->type == DRAWABLE_WINDOW)
160 return pDraw->pScreen->GetWindowPixmap ((WindowPtr) pDraw);
162 return (PixmapPtr) pDraw;
166 NVAccelInitImagePattern(ScrnInfoPtr pScrn)
168 NVPtr pNv = NVPTR(pScrn);
169 struct nouveau_channel *chan = pNv->chan;
170 struct nouveau_grobj *patt;
172 if (!pNv->NvImagePattern) {
173 if (nouveau_grobj_alloc(chan, NvImagePattern,
175 &pNv->NvImagePattern))
178 patt = pNv->NvImagePattern;
180 BEGIN_RING(chan, patt, NV04_IMAGE_PATTERN_DMA_NOTIFY, 1);
181 OUT_RING (chan, chan->nullobj->handle);
182 BEGIN_RING(chan, patt, NV04_IMAGE_PATTERN_MONOCHROME_FORMAT, 3);
183 #if X_BYTE_ORDER == X_BIG_ENDIAN
184 OUT_RING (chan, NV04_IMAGE_PATTERN_MONOCHROME_FORMAT_LE);
186 OUT_RING (chan, NV04_IMAGE_PATTERN_MONOCHROME_FORMAT_CGA6);
188 OUT_RING (chan, NV04_IMAGE_PATTERN_MONOCHROME_SHAPE_8X8);
189 OUT_RING (chan, NV04_IMAGE_PATTERN_PATTERN_SELECT_MONO);
195 NVAccelInitRasterOp(ScrnInfoPtr pScrn)
197 NVPtr pNv = NVPTR(pScrn);
198 struct nouveau_channel *chan = pNv->chan;
199 struct nouveau_grobj *rop;
202 if (nouveau_grobj_alloc(chan, NvRop, NV03_CONTEXT_ROP,
208 BEGIN_RING(chan, rop, NV03_CONTEXT_ROP_DMA_NOTIFY, 1);
209 OUT_RING (chan, chan->nullobj->handle);
211 pNv->currentRop = ~0;
216 NVAccelInitRectangle(ScrnInfoPtr pScrn)
218 NVPtr pNv = NVPTR(pScrn);
219 struct nouveau_channel *chan = pNv->chan;
220 struct nouveau_grobj *rect;
222 if (!pNv->NvRectangle) {
223 if (nouveau_grobj_alloc(chan, NvRectangle,
224 NV04_GDI_RECTANGLE_TEXT,
228 rect = pNv->NvRectangle;
230 BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_DMA_NOTIFY, 1);
231 OUT_RING (chan, pNv->notify0->handle);
232 BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_DMA_FONTS, 1);
233 OUT_RING (chan, chan->nullobj->handle);
234 BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_SURFACE, 1);
235 OUT_RING (chan, pNv->NvContextSurfaces->handle);
236 BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_ROP, 1);
237 OUT_RING (chan, pNv->NvRop->handle);
238 BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_PATTERN, 1);
239 OUT_RING (chan, pNv->NvImagePattern->handle);
240 BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1);
241 OUT_RING (chan, NV04_GDI_RECTANGLE_TEXT_OPERATION_ROP_AND);
242 BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT, 1);
243 /* XXX why putting 1 like renouveau dump, swap the text */
244 #if 1 || X_BYTE_ORDER == X_BIG_ENDIAN
245 OUT_RING (chan, NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT_LE);
247 OUT_RING (chan, NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT_CGA6);
254 NVAccelInitImageBlit(ScrnInfoPtr pScrn)
256 NVPtr pNv = NVPTR(pScrn);
257 struct nouveau_channel *chan = pNv->chan;
258 struct nouveau_grobj *blit;
261 class = (pNv->WaitVSyncPossible) ? NV12_IMAGE_BLIT : NV04_IMAGE_BLIT;
263 if (!pNv->NvImageBlit) {
264 if (nouveau_grobj_alloc(chan, NvImageBlit, class,
268 blit = pNv->NvImageBlit;
270 BEGIN_RING(chan, blit, NV04_IMAGE_BLIT_DMA_NOTIFY, 1);
271 OUT_RING (chan, pNv->notify0->handle);
272 BEGIN_RING(chan, blit, NV04_IMAGE_BLIT_COLOR_KEY, 1);
273 OUT_RING (chan, chan->nullobj->handle);
274 BEGIN_RING(chan, blit, NV04_IMAGE_BLIT_SURFACE, 1);
275 OUT_RING (chan, pNv->NvContextSurfaces->handle);
276 BEGIN_RING(chan, blit, NV04_IMAGE_BLIT_CLIP_RECTANGLE, 3);
277 OUT_RING (chan, chan->nullobj->handle);
278 OUT_RING (chan, pNv->NvImagePattern->handle);
279 OUT_RING (chan, pNv->NvRop->handle);
280 BEGIN_RING(chan, blit, NV04_IMAGE_BLIT_OPERATION, 1);
281 OUT_RING (chan, NV04_IMAGE_BLIT_OPERATION_ROP_AND);
283 if (pNv->WaitVSyncPossible) {
284 BEGIN_RING(chan, blit, 0x0120, 3);
294 NVAccelInitScaledImage(ScrnInfoPtr pScrn)
296 NVPtr pNv = NVPTR(pScrn);
297 struct nouveau_channel *chan = pNv->chan;
298 struct nouveau_grobj *sifm;
301 switch (pNv->Architecture) {
303 class = NV04_SCALED_IMAGE_FROM_MEMORY;
308 class = NV10_SCALED_IMAGE_FROM_MEMORY;
312 class = NV10_SCALED_IMAGE_FROM_MEMORY | 0x3000;
316 if (!pNv->NvScaledImage) {
317 if (nouveau_grobj_alloc(chan, NvScaledImage, class,
318 &pNv->NvScaledImage))
321 sifm = pNv->NvScaledImage;
323 BEGIN_RING(chan, sifm,
324 NV04_SCALED_IMAGE_FROM_MEMORY_DMA_NOTIFY, 7);
325 OUT_RING (chan, pNv->notify0->handle);
326 OUT_RING (chan, pNv->chan->vram->handle);
327 OUT_RING (chan, chan->nullobj->handle);
328 OUT_RING (chan, chan->nullobj->handle);
329 OUT_RING (chan, pNv->NvContextBeta1->handle);
330 OUT_RING (chan, pNv->NvContextBeta4->handle);
331 OUT_RING (chan, pNv->NvContextSurfaces->handle);
332 if (pNv->Architecture>=NV_ARCH_10) {
333 BEGIN_RING(chan, sifm,
334 NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION, 1);
335 OUT_RING (chan, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION_DITHER);
337 BEGIN_RING(chan, sifm, NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION, 1);
338 OUT_RING (chan, NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY);
344 NVAccelInitClipRectangle(ScrnInfoPtr pScrn)
346 NVPtr pNv = NVPTR(pScrn);
347 struct nouveau_channel *chan = pNv->chan;
348 struct nouveau_grobj *clip;
350 if (!pNv->NvClipRectangle) {
351 if (nouveau_grobj_alloc(pNv->chan, NvClipRectangle,
352 NV01_CONTEXT_CLIP_RECTANGLE,
353 &pNv->NvClipRectangle))
356 clip = pNv->NvClipRectangle;
358 BEGIN_RING(chan, clip, NV01_CONTEXT_CLIP_RECTANGLE_DMA_NOTIFY, 1);
359 OUT_RING (chan, chan->nullobj->handle);
364 /* FLAGS_NONE, NvDmaFB, NvDmaAGP, NvDmaNotifier0 */
366 NVAccelInitMemFormat(ScrnInfoPtr pScrn)
368 NVPtr pNv = NVPTR(pScrn);
369 struct nouveau_channel *chan = pNv->chan;
370 struct nouveau_grobj *m2mf;
373 if (pNv->Architecture < NV_ARCH_50)
374 class = NV04_MEMORY_TO_MEMORY_FORMAT;
376 class = NV50_MEMORY_TO_MEMORY_FORMAT;
378 if (!pNv->NvMemFormat) {
379 if (nouveau_grobj_alloc(chan, NvMemFormat, class,
383 m2mf = pNv->NvMemFormat;
385 BEGIN_RING(chan, m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1);
386 OUT_RING (chan, pNv->notify0->handle);
387 BEGIN_RING(chan, m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_IN, 2);
388 OUT_RING (chan, chan->vram->handle);
389 OUT_RING (chan, chan->vram->handle);
395 NVAccelInitImageFromCpu(ScrnInfoPtr pScrn)
397 NVPtr pNv = NVPTR(pScrn);
398 struct nouveau_channel *chan = pNv->chan;
399 struct nouveau_grobj *ifc;
402 switch (pNv->Architecture) {
404 class = NV04_IMAGE_FROM_CPU;
411 class = NV10_IMAGE_FROM_CPU;
415 if (!pNv->NvImageFromCpu) {
416 if (nouveau_grobj_alloc(chan, NvImageFromCpu, class,
417 &pNv->NvImageFromCpu))
420 ifc = pNv->NvImageFromCpu;
422 BEGIN_RING(chan, ifc, NV01_IMAGE_FROM_CPU_DMA_NOTIFY, 1);
423 OUT_RING (chan, pNv->notify0->handle);
424 BEGIN_RING(chan, ifc, NV01_IMAGE_FROM_CPU_CLIP_RECTANGLE, 1);
425 OUT_RING (chan, chan->nullobj->handle);
426 BEGIN_RING(chan, ifc, NV01_IMAGE_FROM_CPU_PATTERN, 1);
427 OUT_RING (chan, chan->nullobj->handle);
428 BEGIN_RING(chan, ifc, NV01_IMAGE_FROM_CPU_ROP, 1);
429 OUT_RING (chan, chan->nullobj->handle);
430 if (pNv->Architecture >= NV_ARCH_10) {
431 BEGIN_RING(chan, ifc, NV01_IMAGE_FROM_CPU_BETA1, 1);
432 OUT_RING (chan, chan->nullobj->handle);
433 BEGIN_RING(chan, ifc, NV05_IMAGE_FROM_CPU_BETA4, 1);
434 OUT_RING (chan, chan->nullobj->handle);
436 BEGIN_RING(chan, ifc, NV05_IMAGE_FROM_CPU_SURFACE, 1);
437 OUT_RING (chan, pNv->NvContextSurfaces->handle);
438 BEGIN_RING(chan, ifc, NV01_IMAGE_FROM_CPU_OPERATION, 1);
439 OUT_RING (chan, NV01_IMAGE_FROM_CPU_OPERATION_SRCCOPY);
445 NVAccelInit2D_NV50(ScrnInfoPtr pScrn)
447 NVPtr pNv = NVPTR(pScrn);
448 struct nouveau_channel *chan = pNv->chan;
449 struct nouveau_grobj *eng2d;
452 if (nouveau_grobj_alloc(chan, Nv2D, 0x502d, &pNv->Nv2D))
457 BEGIN_RING(chan, eng2d, 0x180, 3);
458 OUT_RING (chan, pNv->notify0->handle);
459 OUT_RING (chan, pNv->chan->vram->handle);
460 OUT_RING (chan, pNv->chan->vram->handle);
462 /* Magics from nv, no clue what they do, but at least some
463 * of them are needed to avoid crashes.
465 BEGIN_RING(chan, eng2d, 0x260, 1);
467 BEGIN_RING(chan, eng2d, 0x290, 1);
469 BEGIN_RING(chan, eng2d, 0x29c, 1);
471 BEGIN_RING(chan, eng2d, 0x58c, 1);
472 OUT_RING (chan, 0x111);
474 pNv->currentRop = 0xfffffffa;
478 #define INIT_CONTEXT_OBJECT(name) do { \
479 ret = NVAccelInit##name(pScrn); \
481 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, \
482 "Failed to initialise context object: "#name \
489 NVAccelCommonInit(ScrnInfoPtr pScrn)
491 NVPtr pNv = NVPTR(pScrn);
493 if(pNv->NoAccel) return TRUE;
495 /* General engine objects */
496 INIT_CONTEXT_OBJECT(DmaNotifier0);
499 if (pNv->Architecture < NV_ARCH_50) {
500 INIT_CONTEXT_OBJECT(ContextSurfaces);
501 INIT_CONTEXT_OBJECT(ContextBeta1);
502 INIT_CONTEXT_OBJECT(ContextBeta4);
503 INIT_CONTEXT_OBJECT(ImagePattern);
504 INIT_CONTEXT_OBJECT(RasterOp);
505 INIT_CONTEXT_OBJECT(Rectangle);
506 INIT_CONTEXT_OBJECT(ImageBlit);
507 INIT_CONTEXT_OBJECT(ScaledImage);
508 INIT_CONTEXT_OBJECT(ClipRectangle);
509 INIT_CONTEXT_OBJECT(ImageFromCpu);
511 INIT_CONTEXT_OBJECT(2D_NV50);
513 INIT_CONTEXT_OBJECT(MemFormat);
516 switch (pNv->Architecture) {
518 INIT_CONTEXT_OBJECT(NV50TCL);
521 INIT_CONTEXT_OBJECT(NV40TCL);
524 INIT_CONTEXT_OBJECT(NV30TCL);
528 INIT_CONTEXT_OBJECT(NV10TCL);
537 void NVAccelFree(NVPtr pNv)
542 nouveau_notifier_free(&pNv->notify0);
543 if (pNv->Architecture < NV_ARCH_50) {
544 nouveau_grobj_free(&pNv->NvContextSurfaces);
545 nouveau_grobj_free(&pNv->NvContextBeta1);
546 nouveau_grobj_free(&pNv->NvContextBeta4);
547 nouveau_grobj_free(&pNv->NvImagePattern);
548 nouveau_grobj_free(&pNv->NvRop);
549 nouveau_grobj_free(&pNv->NvRectangle);
550 nouveau_grobj_free(&pNv->NvImageBlit);
551 nouveau_grobj_free(&pNv->NvScaledImage);
552 nouveau_grobj_free(&pNv->NvClipRectangle);
553 nouveau_grobj_free(&pNv->NvImageFromCpu);
555 nouveau_grobj_free(&pNv->Nv2D);
556 nouveau_grobj_free(&pNv->NvMemFormat);
558 nouveau_grobj_free(&pNv->Nv3D);
560 if (pNv->tesla_scratch)
561 nouveau_bo_ref(NULL, &pNv->tesla_scratch);
563 nouveau_bo_ref(NULL, &pNv->shader_mem);