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 NVAccelInitNullObject(ScrnInfoPtr pScrn)
28 NVPtr pNv = NVPTR(pScrn);
31 if (nouveau_grobj_alloc(pNv->chan, NvNullObject, NV01_NULL,
40 NVAccelInitDmaNotifier0(ScrnInfoPtr pScrn)
42 NVPtr pNv = NVPTR(pScrn);
45 if (nouveau_notifier_alloc(pNv->chan, NvDmaNotifier0, 1,
53 /* FLAGS_ROP_AND, DmaFB, DmaFB, 0 */
55 NVAccelInitContextSurfaces(ScrnInfoPtr pScrn)
57 NVPtr pNv = NVPTR(pScrn);
58 struct nouveau_channel *chan = pNv->chan;
59 struct nouveau_grobj *surf2d;
62 class = (pNv->Architecture >= NV_10) ? NV10_CONTEXT_SURFACES_2D :
63 NV04_CONTEXT_SURFACES_2D;
65 if (!pNv->NvContextSurfaces) {
66 if (nouveau_grobj_alloc(chan, NvContextSurfaces, class,
67 &pNv->NvContextSurfaces))
70 surf2d = pNv->NvContextSurfaces;
72 BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_DMA_NOTIFY, 1);
73 OUT_RING (chan, pNv->NvNull->handle);
74 BEGIN_RING(chan, surf2d,
75 NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2);
76 OUT_RING (chan, pNv->chan->vram->handle);
77 OUT_RING (chan, pNv->chan->vram->handle);
82 /* FLAGS_ROP_AND, DmaFB, DmaFB, 0 */
84 NVAccelInitContextBeta1(ScrnInfoPtr pScrn)
86 NVPtr pNv = NVPTR(pScrn);
87 struct nouveau_channel *chan = pNv->chan;
88 struct nouveau_grobj *beta1;
90 if (!pNv->NvContextBeta1) {
91 if (nouveau_grobj_alloc(chan, NvContextBeta1, 0x12,
92 &pNv->NvContextBeta1))
95 beta1 = pNv->NvContextBeta1;
97 BEGIN_RING(chan, beta1, 0x300, 1); /*alpha factor*/
98 OUT_RING (chan, 0xff << 23);
105 NVAccelInitContextBeta4(ScrnInfoPtr pScrn)
107 NVPtr pNv = NVPTR(pScrn);
108 struct nouveau_channel *chan = pNv->chan;
109 struct nouveau_grobj *beta4;
111 if (!pNv->NvContextBeta4) {
112 if (nouveau_grobj_alloc(chan, NvContextBeta4, 0x72,
113 &pNv->NvContextBeta4))
116 beta4 = pNv->NvContextBeta4;
118 BEGIN_RING(chan, beta4, 0x300, 1); /*RGBA factor*/
119 OUT_RING (chan, 0xffff0000);
124 NVAccelGetCtxSurf2DFormatFromPixmap(PixmapPtr pPix, int *fmt_ret)
126 switch (pPix->drawable.bitsPerPixel) {
128 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_A8R8G8B8;
131 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_X8R8G8B8_Z8R8G8B8;
134 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_R5G6B5;
137 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_Y8;
147 NVAccelGetCtxSurf2DFormatFromPicture(PicturePtr pPict, int *fmt_ret)
149 switch (pPict->format) {
151 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_A8R8G8B8;
154 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_X8R8G8B8_Z8R8G8B8;
157 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_R5G6B5;
160 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_Y8;
169 /* A copy of exaGetOffscreenPixmap(), since it's private. */
171 NVGetDrawablePixmap(DrawablePtr pDraw)
173 if (pDraw->type == DRAWABLE_WINDOW)
174 return pDraw->pScreen->GetWindowPixmap ((WindowPtr) pDraw);
176 return (PixmapPtr) pDraw;
180 NVAccelInitImagePattern(ScrnInfoPtr pScrn)
182 NVPtr pNv = NVPTR(pScrn);
183 struct nouveau_channel *chan = pNv->chan;
184 struct nouveau_grobj *patt;
186 if (!pNv->NvImagePattern) {
187 if (nouveau_grobj_alloc(chan, NvImagePattern,
189 &pNv->NvImagePattern))
192 patt = pNv->NvImagePattern;
194 BEGIN_RING(chan, patt, NV04_IMAGE_PATTERN_DMA_NOTIFY, 1);
195 OUT_RING (chan, pNv->NvNull->handle);
196 BEGIN_RING(chan, patt, NV04_IMAGE_PATTERN_MONOCHROME_FORMAT, 3);
197 #if X_BYTE_ORDER == X_BIG_ENDIAN
198 OUT_RING (chan, NV04_IMAGE_PATTERN_MONOCHROME_FORMAT_LE);
200 OUT_RING (chan, NV04_IMAGE_PATTERN_MONOCHROME_FORMAT_CGA6);
202 OUT_RING (chan, NV04_IMAGE_PATTERN_MONOCHROME_SHAPE_8X8);
203 OUT_RING (chan, NV04_IMAGE_PATTERN_PATTERN_SELECT_MONO);
209 NVAccelInitRasterOp(ScrnInfoPtr pScrn)
211 NVPtr pNv = NVPTR(pScrn);
212 struct nouveau_channel *chan = pNv->chan;
213 struct nouveau_grobj *rop;
216 if (nouveau_grobj_alloc(chan, NvRop, NV03_CONTEXT_ROP,
222 BEGIN_RING(chan, rop, NV03_CONTEXT_ROP_DMA_NOTIFY, 1);
223 OUT_RING (chan, pNv->NvNull->handle);
225 pNv->currentRop = ~0;
230 NVAccelInitRectangle(ScrnInfoPtr pScrn)
232 NVPtr pNv = NVPTR(pScrn);
233 struct nouveau_channel *chan = pNv->chan;
234 struct nouveau_grobj *rect;
236 if (!pNv->NvRectangle) {
237 if (nouveau_grobj_alloc(chan, NvRectangle,
238 NV04_GDI_RECTANGLE_TEXT,
242 rect = pNv->NvRectangle;
244 BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_DMA_NOTIFY, 1);
245 OUT_RING (chan, pNv->notify0->handle);
246 BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_DMA_FONTS, 1);
247 OUT_RING (chan, pNv->NvNull->handle);
248 BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_SURFACE, 1);
249 OUT_RING (chan, pNv->NvContextSurfaces->handle);
250 BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_ROP, 1);
251 OUT_RING (chan, pNv->NvRop->handle);
252 BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_PATTERN, 1);
253 OUT_RING (chan, pNv->NvImagePattern->handle);
254 BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1);
255 OUT_RING (chan, NV04_GDI_RECTANGLE_TEXT_OPERATION_ROP_AND);
256 BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT, 1);
257 /* XXX why putting 1 like renouveau dump, swap the text */
258 #if 1 || X_BYTE_ORDER == X_BIG_ENDIAN
259 OUT_RING (chan, NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT_LE);
261 OUT_RING (chan, NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT_CGA6);
268 NVAccelInitImageBlit(ScrnInfoPtr pScrn)
270 NVPtr pNv = NVPTR(pScrn);
271 struct nouveau_channel *chan = pNv->chan;
272 struct nouveau_grobj *blit;
275 class = (pNv->WaitVSyncPossible) ? NV12_IMAGE_BLIT : NV04_IMAGE_BLIT;
277 if (!pNv->NvImageBlit) {
278 if (nouveau_grobj_alloc(chan, NvImageBlit, class,
282 blit = pNv->NvImageBlit;
284 BEGIN_RING(chan, blit, NV04_IMAGE_BLIT_DMA_NOTIFY, 1);
285 OUT_RING (chan, pNv->notify0->handle);
286 BEGIN_RING(chan, blit, NV04_IMAGE_BLIT_COLOR_KEY, 1);
287 OUT_RING (chan, pNv->NvNull->handle);
288 BEGIN_RING(chan, blit, NV04_IMAGE_BLIT_SURFACE, 1);
289 OUT_RING (chan, pNv->NvContextSurfaces->handle);
290 BEGIN_RING(chan, blit, NV04_IMAGE_BLIT_CLIP_RECTANGLE, 3);
291 OUT_RING (chan, pNv->NvNull->handle);
292 OUT_RING (chan, pNv->NvImagePattern->handle);
293 OUT_RING (chan, pNv->NvRop->handle);
294 BEGIN_RING(chan, blit, NV04_IMAGE_BLIT_OPERATION, 1);
295 OUT_RING (chan, NV04_IMAGE_BLIT_OPERATION_ROP_AND);
297 if (pNv->WaitVSyncPossible) {
298 BEGIN_RING(chan, blit, 0x0120, 3);
308 NVAccelInitScaledImage(ScrnInfoPtr pScrn)
310 NVPtr pNv = NVPTR(pScrn);
311 struct nouveau_channel *chan = pNv->chan;
312 struct nouveau_grobj *sifm;
315 switch (pNv->Architecture) {
317 class = NV04_SCALED_IMAGE_FROM_MEMORY;
322 class = NV10_SCALED_IMAGE_FROM_MEMORY;
326 class = NV10_SCALED_IMAGE_FROM_MEMORY | 0x3000;
330 if (!pNv->NvScaledImage) {
331 if (nouveau_grobj_alloc(chan, NvScaledImage, class,
332 &pNv->NvScaledImage))
335 sifm = pNv->NvScaledImage;
337 BEGIN_RING(chan, sifm,
338 NV04_SCALED_IMAGE_FROM_MEMORY_DMA_NOTIFY, 7);
339 OUT_RING (chan, pNv->notify0->handle);
340 OUT_RING (chan, pNv->chan->vram->handle);
341 OUT_RING (chan, pNv->NvNull->handle);
342 OUT_RING (chan, pNv->NvNull->handle);
343 OUT_RING (chan, pNv->NvContextBeta1->handle);
344 OUT_RING (chan, pNv->NvContextBeta4->handle);
345 OUT_RING (chan, pNv->NvContextSurfaces->handle);
346 if (pNv->Architecture>=NV_ARCH_10) {
347 BEGIN_RING(chan, sifm,
348 NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION, 1);
349 OUT_RING (chan, NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION_DITHER);
351 BEGIN_RING(chan, sifm, NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION, 1);
352 OUT_RING (chan, NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY);
358 NVAccelInitClipRectangle(ScrnInfoPtr pScrn)
360 NVPtr pNv = NVPTR(pScrn);
361 struct nouveau_channel *chan = pNv->chan;
362 struct nouveau_grobj *clip;
364 if (!pNv->NvClipRectangle) {
365 if (nouveau_grobj_alloc(pNv->chan, NvClipRectangle,
366 NV01_CONTEXT_CLIP_RECTANGLE,
367 &pNv->NvClipRectangle))
370 clip = pNv->NvClipRectangle;
372 BEGIN_RING(chan, clip, NV01_CONTEXT_CLIP_RECTANGLE_DMA_NOTIFY, 1);
373 OUT_RING (chan, pNv->NvNull->handle);
378 /* FLAGS_NONE, NvDmaFB, NvDmaAGP, NvDmaNotifier0 */
380 NVAccelInitMemFormat(ScrnInfoPtr pScrn)
382 NVPtr pNv = NVPTR(pScrn);
383 struct nouveau_channel *chan = pNv->chan;
384 struct nouveau_grobj *m2mf;
387 if (pNv->Architecture < NV_ARCH_50)
388 class = NV04_MEMORY_TO_MEMORY_FORMAT;
390 class = NV50_MEMORY_TO_MEMORY_FORMAT;
392 if (!pNv->NvMemFormat) {
393 if (nouveau_grobj_alloc(chan, NvMemFormat, class,
397 m2mf = pNv->NvMemFormat;
399 BEGIN_RING(chan, m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1);
400 OUT_RING (chan, pNv->notify0->handle);
401 BEGIN_RING(chan, m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_IN, 2);
402 OUT_RING (chan, chan->vram->handle);
403 OUT_RING (chan, chan->vram->handle);
409 NVAccelInitImageFromCpu(ScrnInfoPtr pScrn)
411 NVPtr pNv = NVPTR(pScrn);
412 struct nouveau_channel *chan = pNv->chan;
413 struct nouveau_grobj *ifc;
416 switch (pNv->Architecture) {
418 class = NV04_IMAGE_FROM_CPU;
425 class = NV10_IMAGE_FROM_CPU;
429 if (!pNv->NvImageFromCpu) {
430 if (nouveau_grobj_alloc(chan, NvImageFromCpu, class,
431 &pNv->NvImageFromCpu))
434 ifc = pNv->NvImageFromCpu;
436 BEGIN_RING(chan, ifc, NV01_IMAGE_FROM_CPU_DMA_NOTIFY, 1);
437 OUT_RING (chan, pNv->notify0->handle);
438 BEGIN_RING(chan, ifc, NV01_IMAGE_FROM_CPU_CLIP_RECTANGLE, 1);
439 OUT_RING (chan, pNv->NvNull->handle);
440 BEGIN_RING(chan, ifc, NV01_IMAGE_FROM_CPU_PATTERN, 1);
441 OUT_RING (chan, pNv->NvNull->handle);
442 BEGIN_RING(chan, ifc, NV01_IMAGE_FROM_CPU_ROP, 1);
443 OUT_RING (chan, pNv->NvNull->handle);
444 if (pNv->Architecture >= NV_ARCH_10) {
445 BEGIN_RING(chan, ifc, NV01_IMAGE_FROM_CPU_BETA1, 1);
446 OUT_RING (chan, pNv->NvNull->handle);
447 BEGIN_RING(chan, ifc, NV05_IMAGE_FROM_CPU_BETA4, 1);
448 OUT_RING (chan, pNv->NvNull->handle);
450 BEGIN_RING(chan, ifc, NV05_IMAGE_FROM_CPU_SURFACE, 1);
451 OUT_RING (chan, pNv->NvContextSurfaces->handle);
452 BEGIN_RING(chan, ifc, NV01_IMAGE_FROM_CPU_OPERATION, 1);
453 OUT_RING (chan, NV01_IMAGE_FROM_CPU_OPERATION_SRCCOPY);
459 NVAccelInit2D_NV50(ScrnInfoPtr pScrn)
461 NVPtr pNv = NVPTR(pScrn);
462 struct nouveau_channel *chan = pNv->chan;
463 struct nouveau_grobj *eng2d;
466 if (nouveau_grobj_alloc(chan, Nv2D, 0x502d, &pNv->Nv2D))
471 BEGIN_RING(chan, eng2d, 0x180, 3);
472 OUT_RING (chan, pNv->notify0->handle);
473 OUT_RING (chan, pNv->chan->vram->handle);
474 OUT_RING (chan, pNv->chan->vram->handle);
476 /* Magics from nv, no clue what they do, but at least some
477 * of them are needed to avoid crashes.
479 BEGIN_RING(chan, eng2d, 0x260, 1);
481 BEGIN_RING(chan, eng2d, 0x290, 1);
483 BEGIN_RING(chan, eng2d, 0x29c, 1);
485 BEGIN_RING(chan, eng2d, 0x58c, 1);
486 OUT_RING (chan, 0x111);
488 pNv->currentRop = 0xfffffffa;
492 #define INIT_CONTEXT_OBJECT(name) do { \
493 ret = NVAccelInit##name(pScrn); \
495 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, \
496 "Failed to initialise context object: "#name \
503 NVAccelCommonInit(ScrnInfoPtr pScrn)
505 NVPtr pNv = NVPTR(pScrn);
507 if(pNv->NoAccel) return TRUE;
509 /* General engine objects */
510 INIT_CONTEXT_OBJECT(NullObject);
511 INIT_CONTEXT_OBJECT(DmaNotifier0);
514 if (pNv->Architecture < NV_ARCH_50) {
515 INIT_CONTEXT_OBJECT(ContextSurfaces);
516 INIT_CONTEXT_OBJECT(ContextBeta1);
517 INIT_CONTEXT_OBJECT(ContextBeta4);
518 INIT_CONTEXT_OBJECT(ImagePattern);
519 INIT_CONTEXT_OBJECT(RasterOp);
520 INIT_CONTEXT_OBJECT(Rectangle);
521 INIT_CONTEXT_OBJECT(ImageBlit);
522 INIT_CONTEXT_OBJECT(ScaledImage);
523 INIT_CONTEXT_OBJECT(ClipRectangle);
524 INIT_CONTEXT_OBJECT(ImageFromCpu);
526 INIT_CONTEXT_OBJECT(2D_NV50);
528 INIT_CONTEXT_OBJECT(MemFormat);
531 switch (pNv->Architecture) {
533 INIT_CONTEXT_OBJECT(NV50TCL);
536 INIT_CONTEXT_OBJECT(NV40TCL);
539 INIT_CONTEXT_OBJECT(NV30TCL);
543 INIT_CONTEXT_OBJECT(NV10TCL);
552 void NVAccelFree(NVPtr pNv)
554 if (pNv->tesla_scratch)
555 nouveau_bo_del(&pNv->tesla_scratch);
557 nouveau_bo_del(&pNv->shader_mem);