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 NVAccelGetPixmapOffset(PixmapPtr pPix)
42 ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum];
43 NVPtr pNv = NVPTR(pScrn);
46 offset = exaGetPixmapOffset(pPix);
47 if (offset >= pNv->FB->size) {
48 xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
49 "AII, passed bad pixmap: offset 0x%lx\n", offset);
50 return pNv->FB->offset;
52 offset += pNv->FB->offset;
58 NVAccelInitDmaNotifier0(ScrnInfoPtr pScrn)
60 NVPtr pNv = NVPTR(pScrn);
63 if (nouveau_notifier_alloc(pNv->chan, NvDmaNotifier0, 1,
71 /* FLAGS_ROP_AND, DmaFB, DmaFB, 0 */
73 NVAccelInitContextSurfaces(ScrnInfoPtr pScrn)
75 NVPtr pNv = NVPTR(pScrn);
78 class = (pNv->Architecture >= NV_10) ? NV10_CONTEXT_SURFACES_2D :
79 NV04_CONTEXT_SURFACES_2D;
81 if (!pNv->NvContextSurfaces) {
82 if (nouveau_grobj_alloc(pNv->chan, NvContextSurfaces, class,
83 &pNv->NvContextSurfaces))
87 BEGIN_RING(NvContextSurfaces, NV04_CONTEXT_SURFACES_2D_DMA_NOTIFY, 1);
88 OUT_RING (NvNullObject);
89 BEGIN_RING(NvContextSurfaces,
90 NV04_CONTEXT_SURFACES_2D_DMA_IMAGE_SOURCE, 2);
97 /* FLAGS_ROP_AND, DmaFB, DmaFB, 0 */
99 NVAccelInitContextBeta1(ScrnInfoPtr pScrn)
101 NVPtr pNv = NVPTR(pScrn);
106 if (!pNv->NvContextBeta1) {
107 if (nouveau_grobj_alloc(pNv->chan, NvContextBeta1, class,
108 &pNv->NvContextBeta1))
112 BEGIN_RING(NvContextBeta1, 0x300, 1); /*alpha factor*/
113 OUT_RING (0xff << 23);
120 NVAccelInitContextBeta4(ScrnInfoPtr pScrn)
122 NVPtr pNv = NVPTR(pScrn);
127 if (!pNv->NvContextBeta4) {
128 if (nouveau_grobj_alloc(pNv->chan, NvContextBeta4, class,
129 &pNv->NvContextBeta4))
133 BEGIN_RING(NvContextBeta4, 0x300, 1); /*RGBA factor*/
134 OUT_RING (0xffff0000);
139 NVAccelGetCtxSurf2DFormatFromPixmap(PixmapPtr pPix, int *fmt_ret)
141 switch (pPix->drawable.bitsPerPixel) {
143 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_A8R8G8B8;
146 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_X8R8G8B8_Z8R8G8B8;
149 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_R5G6B5;
152 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_Y8;
162 NVAccelGetCtxSurf2DFormatFromPicture(PicturePtr pPict, int *fmt_ret)
164 switch (pPict->format) {
166 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_A8R8G8B8;
169 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_X8R8G8B8_Z8R8G8B8;
172 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_R5G6B5;
175 *fmt_ret = NV04_CONTEXT_SURFACES_2D_FORMAT_Y8;
185 NVAccelSetCtxSurf2D(PixmapPtr psPix, PixmapPtr pdPix, int format)
187 ScrnInfoPtr pScrn = xf86Screens[psPix->drawable.pScreen->myNum];
188 NVPtr pNv = NVPTR(pScrn);
190 BEGIN_RING(NvContextSurfaces, NV04_CONTEXT_SURFACES_2D_FORMAT, 4);
192 OUT_RING (((uint32_t)exaGetPixmapPitch(pdPix) << 16) |
193 (uint32_t)exaGetPixmapPitch(psPix));
194 OUT_RING (NVAccelGetPixmapOffset(psPix));
195 OUT_RING (NVAccelGetPixmapOffset(pdPix));
201 NVAccelInitImagePattern(ScrnInfoPtr pScrn)
203 NVPtr pNv = NVPTR(pScrn);
206 class = NV04_IMAGE_PATTERN;
208 if (!pNv->NvImagePattern) {
209 if (nouveau_grobj_alloc(pNv->chan, NvImagePattern, class,
210 &pNv->NvImagePattern))
214 BEGIN_RING(NvImagePattern, NV04_IMAGE_PATTERN_DMA_NOTIFY, 1);
215 OUT_RING (NvNullObject);
216 BEGIN_RING(NvImagePattern, NV04_IMAGE_PATTERN_MONOCHROME_FORMAT, 3);
217 #if X_BYTE_ORDER == X_BIG_ENDIAN
218 OUT_RING (NV04_IMAGE_PATTERN_MONOCHROME_FORMAT_LE);
220 OUT_RING (NV04_IMAGE_PATTERN_MONOCHROME_FORMAT_CGA6);
222 OUT_RING (NV04_IMAGE_PATTERN_MONOCHROME_SHAPE_8X8);
223 OUT_RING (NV04_IMAGE_PATTERN_PATTERN_SELECT_MONO);
229 NVAccelInitRasterOp(ScrnInfoPtr pScrn)
231 NVPtr pNv = NVPTR(pScrn);
234 class = NV03_CONTEXT_ROP;
237 if (nouveau_grobj_alloc(pNv->chan, NvRop, class,
242 BEGIN_RING(NvRop, NV03_CONTEXT_ROP_DMA_NOTIFY, 1);
243 OUT_RING (NvNullObject);
245 pNv->currentRop = ~0;
250 NVAccelInitRectangle(ScrnInfoPtr pScrn)
252 NVPtr pNv = NVPTR(pScrn);
255 class = NV04_GDI_RECTANGLE_TEXT;
257 if (!pNv->NvRectangle) {
258 if (nouveau_grobj_alloc(pNv->chan, NvRectangle, class,
263 BEGIN_RING(NvRectangle, NV04_GDI_RECTANGLE_TEXT_DMA_NOTIFY, 1);
264 OUT_RING (NvDmaNotifier0);
265 BEGIN_RING(NvRectangle, NV04_GDI_RECTANGLE_TEXT_DMA_FONTS, 1);
266 OUT_RING (NvNullObject);
267 BEGIN_RING(NvRectangle, NV04_GDI_RECTANGLE_TEXT_SURFACE, 1);
268 OUT_RING (NvContextSurfaces);
269 BEGIN_RING(NvRectangle, NV04_GDI_RECTANGLE_TEXT_ROP, 1);
271 BEGIN_RING(NvRectangle, NV04_GDI_RECTANGLE_TEXT_PATTERN, 1);
272 OUT_RING (NvImagePattern);
273 BEGIN_RING(NvRectangle, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1);
274 OUT_RING (NV04_GDI_RECTANGLE_TEXT_OPERATION_ROP_AND);
275 BEGIN_RING(NvRectangle, NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT, 1);
276 /* XXX why putting 1 like renouveau dump, swap the text */
277 #if 1 || X_BYTE_ORDER == X_BIG_ENDIAN
278 OUT_RING (NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT_LE);
280 OUT_RING (NV04_GDI_RECTANGLE_TEXT_MONOCHROME_FORMAT_CGA6);
287 NVAccelInitImageBlit(ScrnInfoPtr pScrn)
289 NVPtr pNv = NVPTR(pScrn);
292 class = (pNv->WaitVSyncPossible) ? NV12_IMAGE_BLIT : NV_IMAGE_BLIT;
294 if (!pNv->NvImageBlit) {
295 if (nouveau_grobj_alloc(pNv->chan, NvImageBlit, class,
300 BEGIN_RING(NvImageBlit, NV_IMAGE_BLIT_DMA_NOTIFY, 1);
301 OUT_RING (NvDmaNotifier0);
302 BEGIN_RING(NvImageBlit, NV_IMAGE_BLIT_COLOR_KEY, 1);
303 OUT_RING (NvNullObject);
304 BEGIN_RING(NvImageBlit, NV_IMAGE_BLIT_SURFACE, 1);
305 OUT_RING (NvContextSurfaces);
306 BEGIN_RING(NvImageBlit, NV_IMAGE_BLIT_CLIP_RECTANGLE, 3);
307 OUT_RING (NvNullObject);
308 OUT_RING (NvImagePattern);
310 BEGIN_RING(NvImageBlit, NV_IMAGE_BLIT_OPERATION, 1);
311 OUT_RING (NV_IMAGE_BLIT_OPERATION_ROP_AND);
313 if (pNv->WaitVSyncPossible) {
314 BEGIN_RING(NvImageBlit, 0x0120, 3);
324 NVAccelInitScaledImage(ScrnInfoPtr pScrn)
326 NVPtr pNv = NVPTR(pScrn);
329 switch (pNv->Architecture) {
331 class = NV04_SCALED_IMAGE_FROM_MEMORY;
336 class = NV10_SCALED_IMAGE_FROM_MEMORY;
340 class = NV10_SCALED_IMAGE_FROM_MEMORY | 0x3000;
344 if (!pNv->NvScaledImage) {
345 if (nouveau_grobj_alloc(pNv->chan, NvScaledImage, class,
346 &pNv->NvScaledImage))
350 BEGIN_RING(NvScaledImage,
351 NV04_SCALED_IMAGE_FROM_MEMORY_DMA_NOTIFY, 7);
352 OUT_RING (NvDmaNotifier0);
354 OUT_RING (NvNullObject);
355 OUT_RING (NvNullObject);
356 OUT_RING (NvContextBeta1);
357 OUT_RING (NvContextBeta4);
358 OUT_RING (NvContextSurfaces);
359 if (pNv->Architecture>=NV_ARCH_10) {
360 BEGIN_RING(NvScaledImage,
361 NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION, 1);
362 OUT_RING (NV04_SCALED_IMAGE_FROM_MEMORY_COLOR_CONVERSION_DITHER);
364 BEGIN_RING(NvScaledImage, NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION, 1);
365 OUT_RING (NV04_SCALED_IMAGE_FROM_MEMORY_OPERATION_SRCCOPY);
371 NVAccelInitClipRectangle(ScrnInfoPtr pScrn)
373 NVPtr pNv = NVPTR(pScrn);
374 int class = NV01_CONTEXT_CLIP_RECTANGLE;
376 if (!pNv->NvClipRectangle) {
377 if (nouveau_grobj_alloc(pNv->chan, NvClipRectangle, class,
378 &pNv->NvClipRectangle))
382 BEGIN_RING(NvClipRectangle, NV01_CONTEXT_CLIP_RECTANGLE_DMA_NOTIFY, 1);
383 OUT_RING (NvNullObject);
388 /* FLAGS_NONE, NvDmaFB, NvDmaAGP, NvDmaNotifier0 */
390 NVAccelInitMemFormat(ScrnInfoPtr pScrn)
392 NVPtr pNv = NVPTR(pScrn);
395 if (pNv->Architecture < NV_ARCH_50)
396 class = NV_MEMORY_TO_MEMORY_FORMAT;
398 class = NV50_MEMORY_TO_MEMORY_FORMAT;
400 if (!pNv->NvMemFormat) {
401 if (nouveau_grobj_alloc(pNv->chan, NvMemFormat, class,
406 BEGIN_RING(NvMemFormat, NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1);
407 OUT_RING (NvDmaNotifier0);
408 BEGIN_RING(NvMemFormat, NV_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_IN, 2);
412 pNv->M2MFDirection = -1;
417 NVAccelInitImageFromCpu(ScrnInfoPtr pScrn)
419 NVPtr pNv = NVPTR(pScrn);
422 switch (pNv->Architecture) {
424 class = NV05_IMAGE_FROM_CPU;
431 class = NV10_IMAGE_FROM_CPU;
435 if (!pNv->NvImageFromCpu) {
436 if (nouveau_grobj_alloc(pNv->chan, NvImageFromCpu, class,
437 &pNv->NvImageFromCpu))
441 BEGIN_RING(NvImageFromCpu, NV01_IMAGE_FROM_CPU_DMA_NOTIFY, 1);
442 OUT_RING (NvDmaNotifier0);
443 BEGIN_RING(NvImageFromCpu, NV01_IMAGE_FROM_CPU_CLIP_RECTANGLE, 1);
444 OUT_RING (NvNullObject);
445 BEGIN_RING(NvImageFromCpu, NV01_IMAGE_FROM_CPU_PATTERN, 1);
446 OUT_RING (NvNullObject);
447 BEGIN_RING(NvImageFromCpu, NV01_IMAGE_FROM_CPU_ROP, 1);
448 OUT_RING (NvNullObject);
449 if (pNv->Architecture >= NV_ARCH_10)
451 BEGIN_RING(NvImageFromCpu, NV01_IMAGE_FROM_CPU_BETA1, 1);
452 OUT_RING (NvNullObject);
453 BEGIN_RING(NvImageFromCpu, NV05_IMAGE_FROM_CPU_BETA4, 1);
454 OUT_RING (NvNullObject);
456 BEGIN_RING(NvImageFromCpu, NV05_IMAGE_FROM_CPU_SURFACE, 1);
457 OUT_RING (NvContextSurfaces);
458 BEGIN_RING(NvImageFromCpu, NV01_IMAGE_FROM_CPU_OPERATION, 1);
459 OUT_RING (NV01_IMAGE_FROM_CPU_OPERATION_SRCCOPY);
464 NVAccelInit2D_NV50(ScrnInfoPtr pScrn)
466 NVPtr pNv = NVPTR(pScrn);
469 if (nouveau_grobj_alloc(pNv->chan, Nv2D, 0x502d,
474 BEGIN_RING(Nv2D, 0x180, 3);
475 OUT_RING (NvDmaNotifier0);
479 /* Magics from nv, no clue what they do, but at least some
480 * of them are needed to avoid crashes.
482 BEGIN_RING(Nv2D, 0x260, 1);
484 BEGIN_RING(Nv2D, 0x290, 1);
486 BEGIN_RING(Nv2D, 0x29c, 1);
488 BEGIN_RING(Nv2D, 0x58c, 1);
491 pNv->currentRop = 0xfffffffa;
495 #define INIT_CONTEXT_OBJECT(name) do { \
496 ret = NVAccelInit##name(pScrn); \
498 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, \
499 "Failed to initialise context object: "#name \
506 NVAccelCommonInit(ScrnInfoPtr pScrn)
508 NVPtr pNv = NVPTR(pScrn);
510 if(pNv->NoAccel) return TRUE;
512 /* General engine objects */
513 INIT_CONTEXT_OBJECT(NullObject);
514 INIT_CONTEXT_OBJECT(DmaNotifier0);
517 if (pNv->Architecture < NV_ARCH_50) {
518 INIT_CONTEXT_OBJECT(ContextSurfaces);
519 INIT_CONTEXT_OBJECT(ContextBeta1);
520 INIT_CONTEXT_OBJECT(ContextBeta4);
521 INIT_CONTEXT_OBJECT(ImagePattern);
522 INIT_CONTEXT_OBJECT(RasterOp);
523 INIT_CONTEXT_OBJECT(Rectangle);
524 INIT_CONTEXT_OBJECT(ImageBlit);
525 INIT_CONTEXT_OBJECT(ScaledImage);
526 INIT_CONTEXT_OBJECT(ClipRectangle);
527 INIT_CONTEXT_OBJECT(ImageFromCpu);
529 INIT_CONTEXT_OBJECT(2D_NV50);
531 INIT_CONTEXT_OBJECT(MemFormat);
534 switch (pNv->Architecture) {
536 INIT_CONTEXT_OBJECT(NV40TCL);
539 INIT_CONTEXT_OBJECT(NV30TCL);
543 INIT_CONTEXT_OBJECT(NV10TCL);