1 /***************************************************************************\
3 |* Copyright 2003 NVIDIA, Corporation. All rights reserved. *|
5 |* NOTICE TO USER: The source code is copyrighted under U.S. and *|
6 |* international laws. Users and possessors of this source code are *|
7 |* hereby granted a nonexclusive, royalty-free copyright license to *|
8 |* use this code in individual and commercial software. *|
10 |* Any use of this source code must include, in the user documenta- *|
11 |* tion and internal comments to the code, notices to the end user *|
14 |* Copyright 2003 NVIDIA, Corporation. All rights reserved. *|
16 |* NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY *|
17 |* OF THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" *|
18 |* WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORPOR- *|
19 |* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *|
20 |* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *|
21 |* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *|
22 |* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *|
23 |* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *|
24 |* SULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION *|
25 |* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF *|
26 |* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE. *|
28 |* U.S. Government End Users. This source code is a "commercial *|
29 |* item," as that term is defined at 48 C.F.R. 2.101 (OCT 1995), *|
30 |* consisting of "commercial computer software" and "commercial *|
31 |* computer software documentation," as such terms are used in *|
32 |* 48 C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Govern- *|
33 |* ment only as a commercial end item. Consistent with 48 C.F.R. *|
34 |* 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), *|
35 |* all U.S. Government End Users acquire the source code with only *|
36 |* those rights set forth herein. *|
38 \***************************************************************************/
41 Exa Modifications (c) Lars Knoll (lars@trolltech.com)
44 #include "nv_include.h"
52 const int NVCopyROP[16] =
56 0x44, /* GXandReverse */
58 0x22, /* GXandInverted */
65 0xDD, /* GXorReverse */
66 0x33, /* GXcopyInverted */
67 0xBB, /* GXorInverted */
73 NVSetPattern(ScrnInfoPtr pScrn, CARD32 clr0, CARD32 clr1,
74 CARD32 pat0, CARD32 pat1)
76 NVPtr pNv = NVPTR(pScrn);
78 BEGIN_RING(NvImagePattern, NV04_IMAGE_PATTERN_MONOCHROME_COLOR0, 4);
86 NVSetROP(ScrnInfoPtr pScrn, CARD32 alu, CARD32 planemask)
88 NVPtr pNv = NVPTR(pScrn);
89 int rop = NVCopyROP[alu] & 0xf0;
91 if (planemask != ~0) {
92 NVSetPattern(pScrn, 0, planemask, ~0, ~0);
93 if (pNv->currentRop != (alu + 32)) {
94 BEGIN_RING(NvRop, NV03_CONTEXT_ROP_ROP, 1);
95 OUT_RING (rop | 0x0a);
96 pNv->currentRop = alu + 32;
99 if (pNv->currentRop != alu) {
100 if(pNv->currentRop >= 16)
101 NVSetPattern(pScrn, ~0, ~0, ~0, ~0);
102 BEGIN_RING(NvRop, NV03_CONTEXT_ROP_ROP, 1);
103 OUT_RING (rop | (rop >> 4));
104 pNv->currentRop = alu;
108 static CARD32 rectFormat(DrawablePtr pDrawable)
110 switch(pDrawable->bitsPerPixel) {
113 return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8;
116 return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A16R5G6B5;
119 return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8;
124 /* EXA acceleration hooks */
125 static void NVExaWaitMarker(ScreenPtr pScreen, int marker)
127 NVSync(xf86Screens[pScreen->myNum]);
130 static Bool NVExaPrepareSolid(PixmapPtr pPixmap,
135 ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
136 NVPtr pNv = NVPTR(pScrn);
137 unsigned int fmt, pitch;
139 planemask |= ~0 << pPixmap->drawable.bitsPerPixel;
140 if (planemask != ~0 || alu != GXcopy) {
141 if (pPixmap->drawable.bitsPerPixel == 32)
143 BEGIN_RING(NvRectangle, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1);
144 OUT_RING (1); /* ROP_AND */
145 NVSetROP(pScrn, alu, planemask);
147 BEGIN_RING(NvRectangle, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1);
148 OUT_RING (3); /* SRCCOPY */
151 if (!NVAccelGetCtxSurf2DFormatFromPixmap(pPixmap, (int*)&fmt))
153 pitch = exaGetPixmapPitch(pPixmap);
155 /* When SURFACE_FORMAT_A8R8G8B8 is used with GDI_RECTANGLE_TEXT, the
156 * alpha channel gets forced to 0xFF for some reason. We're using
157 * SURFACE_FORMAT_Y32 as a workaround
159 if (fmt == NV04_CONTEXT_SURFACES_2D_FORMAT_A8R8G8B8)
160 fmt = NV04_CONTEXT_SURFACES_2D_FORMAT_Y32;
162 BEGIN_RING(NvContextSurfaces, NV04_CONTEXT_SURFACES_2D_FORMAT, 4);
164 OUT_RING ((pitch << 16) | pitch);
165 OUT_PIXMAPl(pPixmap, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
166 OUT_PIXMAPl(pPixmap, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
168 BEGIN_RING(NvRectangle, NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT, 1);
169 OUT_RING (rectFormat(&pPixmap->drawable));
170 BEGIN_RING(NvRectangle, NV04_GDI_RECTANGLE_TEXT_COLOR1_A, 1);
176 static void NVExaSolid (PixmapPtr pPixmap, int x1, int y1, int x2, int y2)
178 ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
179 NVPtr pNv = NVPTR(pScrn);
183 BEGIN_RING(NvRectangle,
184 NV04_GDI_RECTANGLE_TEXT_UNCLIPPED_RECTANGLE_POINT(0), 2);
185 OUT_RING ((x1 << 16) | y1);
186 OUT_RING ((width << 16) | height);
188 if((width * height) >= 512)
192 static void NVExaDoneSolid (PixmapPtr pPixmap)
196 static Bool NVExaPrepareCopy(PixmapPtr pSrcPixmap,
197 PixmapPtr pDstPixmap,
203 ScrnInfoPtr pScrn = xf86Screens[pSrcPixmap->drawable.pScreen->myNum];
204 NVPtr pNv = NVPTR(pScrn);
207 if (pSrcPixmap->drawable.bitsPerPixel !=
208 pDstPixmap->drawable.bitsPerPixel)
211 planemask |= ~0 << pDstPixmap->drawable.bitsPerPixel;
212 if (planemask != ~0 || alu != GXcopy) {
213 if (pDstPixmap->drawable.bitsPerPixel == 32)
215 BEGIN_RING(NvImageBlit, NV_IMAGE_BLIT_OPERATION, 1);
216 OUT_RING (1); /* ROP_AND */
217 NVSetROP(pScrn, alu, planemask);
219 BEGIN_RING(NvImageBlit, NV_IMAGE_BLIT_OPERATION, 1);
220 OUT_RING (3); /* SRCCOPY */
223 if (!NVAccelGetCtxSurf2DFormatFromPixmap(pDstPixmap, &fmt))
226 BEGIN_RING(NvContextSurfaces, NV04_CONTEXT_SURFACES_2D_FORMAT, 4);
228 OUT_RING ((exaGetPixmapPitch(pDstPixmap) << 16) |
229 (exaGetPixmapPitch(pSrcPixmap)));
230 OUT_PIXMAPl(pSrcPixmap, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
231 OUT_PIXMAPl(pDstPixmap, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
236 static void NVExaCopy(PixmapPtr pDstPixmap,
244 ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
245 NVPtr pNv = NVPTR(pScrn);
247 /* We want to catch people who have this bug, to find a decent fix */
249 /* Now check whether we have the same values for srcY and dstY and
250 whether the used chipset is buggy. Currently we flag all of G70
251 cards as buggy, which is probably much to broad. KoalaBR
252 16 is an abritrary threshold. It should define the maximum number
253 of lines between dstY and srcY If the number of lines is below
254 we guess, that the bug won't trigger...
256 if ( ((abs(srcY - dstY)< 16)||(abs(srcX-dstX)<16)) &&
257 ((((pNv->Chipset & 0xfff0) == CHIPSET_G70) ||
258 ((pNv->Chipset & 0xfff0) == CHIPSET_G71) ||
259 ((pNv->Chipset & 0xfff0) == CHIPSET_G72) ||
260 ((pNv->Chipset & 0xfff0) == CHIPSET_G73) ||
261 ((pNv->Chipset & 0xfff0) == CHIPSET_C512))) )
263 int dx=abs(srcX - dstX),dy=abs(srcY - dstY);
264 // Ok, let's do it manually unless someone comes up with a better idea
265 // 1. If dstY and srcY are really the same, do a copy rowwise
268 NVDEBUG("ExaCopy: Lines identical:\n");
276 for (i = 0; i < width; i++) {
277 BEGIN_RING(NvImageBlit,
278 NV_IMAGE_BLIT_POINT_IN, 3);
279 OUT_RING ((srcY << 16) | (srcX+xpos));
280 OUT_RING ((dstY << 16) | (dstX+xpos));
281 OUT_RING ((height << 16) | 1);
285 // 2. Otherwise we will try a line by line copy in the hope to avoid
288 NVDEBUG("ExaCopy: Lines nearly the same srcY=%d, dstY=%d:\n", srcY, dstY);
296 for (i = 0; i < height; i++) {
297 BEGIN_RING(NvImageBlit,
298 NV_IMAGE_BLIT_POINT_IN, 3);
299 OUT_RING (((srcY+ypos) << 16) | srcX);
300 OUT_RING (((dstY+ypos) << 16) | dstX);
301 OUT_RING ((1 << 16) | width);
306 NVDEBUG("ExaCopy: Using default path\n");
307 BEGIN_RING(NvImageBlit, NV_IMAGE_BLIT_POINT_IN, 3);
308 OUT_RING ((srcY << 16) | srcX);
309 OUT_RING ((dstY << 16) | dstX);
310 OUT_RING ((height << 16) | width);
314 NVDEBUG("ExaCopy: Using default path\n");
315 BEGIN_RING(NvImageBlit, NV_IMAGE_BLIT_POINT_IN, 3);
316 OUT_RING ((srcY << 16) | srcX);
317 OUT_RING ((dstY << 16) | dstX);
318 OUT_RING ((height << 16) | width);
320 if((width * height) >= 512)
324 static void NVExaDoneCopy (PixmapPtr pDstPixmap) {}
326 static inline Bool NVAccelMemcpyRect(char *dst, const char *src, int height,
327 int dst_pitch, int src_pitch, int line_len)
329 if ((src_pitch == line_len) && (src_pitch == dst_pitch)) {
330 memcpy(dst, src, line_len*height);
333 memcpy(dst, src, line_len);
343 NVAccelDownloadM2MF(ScrnInfoPtr pScrn, char *dst, PixmapPtr pspix,
344 uint32_t src_offset, int dst_pitch, int src_pitch,
345 int line_len, int line_count)
347 NVPtr pNv = NVPTR(pScrn);
349 BEGIN_RING(NvMemFormat, 0x184, 2);
350 OUT_PIXMAPo(pspix, NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
351 OUT_RELOCo(pNv->GART, NOUVEAU_BO_GART | NOUVEAU_BO_WR);
354 char *src = pNv->GART->map;
357 if (line_count * line_len <= pNv->GART->size) {
360 lc = pNv->GART->size / line_len;
369 if (pNv->Architecture >= NV_ARCH_50) {
370 BEGIN_RING(NvMemFormat, 0x200, 1);
372 BEGIN_RING(NvMemFormat, 0x21c, 1);
374 /* probably high-order bits of address */
375 BEGIN_RING(NvMemFormat, 0x238, 2);
376 OUT_PIXMAPh(pspix, src_offset, NOUVEAU_BO_GART |
377 NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
378 OUT_RELOCh(pNv->GART, 0, NOUVEAU_BO_GART |
382 BEGIN_RING(NvMemFormat,
383 NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8);
384 OUT_PIXMAPl(pspix, src_offset, NOUVEAU_BO_GART |
385 NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
386 OUT_RELOCl(pNv->GART, 0, NOUVEAU_BO_GART | NOUVEAU_BO_WR);
387 OUT_RING (src_pitch);
394 nouveau_notifier_reset(pNv->notify0, 0);
395 BEGIN_RING(NvMemFormat, NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1);
397 BEGIN_RING(NvMemFormat, 0x100, 1);
400 if (nouveau_notifier_wait_status(pNv->notify0, 0, 0,
404 if (dst_pitch == line_len) {
405 memcpy(dst, src, dst_pitch * lc);
406 dst += dst_pitch * lc;
408 for (i = 0; i < lc; i++) {
409 memcpy(dst, src, line_len);
416 src_offset += lc * src_pitch;
423 NVExaPixmapMap(PixmapPtr pPix)
425 ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum];
426 NVPtr pNv = NVPTR(pScrn);
429 map = pNv->FB->map + exaGetPixmapOffset(pPix);
433 static Bool NVDownloadFromScreen(PixmapPtr pSrc,
436 char *dst, int dst_pitch)
438 ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum];
439 NVPtr pNv = NVPTR(pScrn);
440 int src_pitch, cpp, offset;
443 src_pitch = exaGetPixmapPitch(pSrc);
444 cpp = pSrc->drawable.bitsPerPixel >> 3;
445 offset = (y * src_pitch) + (x * cpp);
448 if (NVAccelDownloadM2MF(pScrn, dst, pSrc, offset,
449 dst_pitch, src_pitch, w * cpp, h))
453 src = NVExaPixmapMap(pSrc) + offset;
454 exaWaitSync(pSrc->drawable.pScreen);
455 if (NVAccelMemcpyRect(dst, src, h, dst_pitch, src_pitch, w*cpp))
462 NVAccelUploadIFC(ScrnInfoPtr pScrn, const char *src, int src_pitch,
463 PixmapPtr pDst, int x, int y, int w, int h, int cpp)
465 NVPtr pNv = NVPTR(pScrn);
466 int line_len = w * cpp;
467 int iw, id, surf_fmt, ifc_fmt;
469 if (pNv->Architecture >= NV_ARCH_50)
476 case 2: ifc_fmt = 1; break;
477 case 4: ifc_fmt = 4; break;
482 if (!NVAccelGetCtxSurf2DFormatFromPixmap(pDst, &surf_fmt))
485 BEGIN_RING(NvContextSurfaces, NV04_CONTEXT_SURFACES_2D_FORMAT, 4);
487 OUT_RING ((exaGetPixmapPitch(pDst) << 16) | exaGetPixmapPitch(pDst));
488 OUT_PIXMAPl(pDst, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
489 OUT_PIXMAPl(pDst, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
491 /* Pad out input width to cover both COLORA() and COLORB() */
492 iw = (line_len + 7) & ~7;
493 id = iw / 4; /* line push size */
496 /* Don't support lines longer than max push size yet.. */
500 BEGIN_RING(NvClipRectangle, NV01_CONTEXT_CLIP_RECTANGLE_POINT, 2);
502 OUT_RING (0x7FFF7FFF);
504 BEGIN_RING(NvImageFromCpu, NV01_IMAGE_FROM_CPU_OPERATION, 2);
505 OUT_RING (NV01_IMAGE_FROM_CPU_OPERATION_SRCCOPY);
507 BEGIN_RING(NvImageFromCpu, NV01_IMAGE_FROM_CPU_POINT, 3);
508 OUT_RING ((y << 16) | x); /* dst point */
509 OUT_RING ((h << 16) | w); /* width/height out */
510 OUT_RING ((h << 16) | iw); /* width/height in */
514 BEGIN_RING(NvImageFromCpu, NV01_IMAGE_FROM_CPU_COLOR(0), id);
524 NVAccelUploadM2MF(ScrnInfoPtr pScrn, PixmapPtr pdpix, uint32_t dst_offset,
525 const char *src, int dst_pitch, int src_pitch,
526 int line_len, int line_count)
528 NVPtr pNv = NVPTR(pScrn);
530 BEGIN_RING(NvMemFormat, 0x184, 2);
531 OUT_RELOCo(pNv->GART, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
532 OUT_PIXMAPo(pdpix, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_WR);
535 char *dst = pNv->GART->map;
538 /* Determine max amount of data we can DMA at once */
539 if (line_count * line_len <= pNv->GART->size) {
542 lc = pNv->GART->size / line_len;
552 if (src_pitch == line_len) {
553 memcpy(dst, src, src_pitch * lc);
554 src += src_pitch * lc;
556 for (i = 0; i < lc; i++) {
557 memcpy(dst, src, line_len);
563 if (pNv->Architecture >= NV_ARCH_50) {
564 BEGIN_RING(NvMemFormat, 0x200, 1);
566 BEGIN_RING(NvMemFormat, 0x21c, 1);
568 /* probably high-order bits of address */
569 BEGIN_RING(NvMemFormat, 0x238, 2);
570 OUT_RELOCh(pNv->GART, 0, NOUVEAU_BO_GART |
572 OUT_PIXMAPh(pdpix, 0, NOUVEAU_BO_VRAM |
573 NOUVEAU_BO_GART | NOUVEAU_BO_WR);
577 BEGIN_RING(NvMemFormat,
578 NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8);
579 OUT_RELOCl(pNv->GART, 0, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
580 OUT_PIXMAPl(pdpix, dst_offset, NOUVEAU_BO_VRAM |
581 NOUVEAU_BO_GART | NOUVEAU_BO_WR);
583 OUT_RING (dst_pitch);
589 nouveau_notifier_reset(pNv->notify0, 0);
590 BEGIN_RING(NvMemFormat, NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1);
592 BEGIN_RING(NvMemFormat, 0x100, 1);
595 if (nouveau_notifier_wait_status(pNv->notify0, 0, 0, 2000))
598 dst_offset += lc * dst_pitch;
605 static Bool NVUploadToScreen(PixmapPtr pDst,
606 int x, int y, int w, int h,
607 char *src, int src_pitch)
609 ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
610 NVPtr pNv = NVPTR(pScrn);
614 dst_pitch = exaGetPixmapPitch(pDst);
615 cpp = pDst->drawable.bitsPerPixel >> 3;
617 /* try hostdata transfer */
618 if (pNv->Architecture < NV_ARCH_50 && w*h*cpp<16*1024) /* heuristic */
620 if (NVAccelUploadIFC(pScrn, src, src_pitch, pDst,
622 exaMarkSync(pDst->drawable.pScreen);
627 /* try gart-based transfer */
629 if (NVAccelUploadM2MF(pScrn, pDst, (y * dst_pitch) + (x * cpp),
630 src, dst_pitch, src_pitch, w * cpp, h))
634 /* fallback to memcpy-based transfer */
635 dst = NVExaPixmapMap(pDst) + (y * dst_pitch) + (x * cpp);
636 exaWaitSync(pDst->drawable.pScreen);
637 if (NVAccelMemcpyRect(dst, src, h, dst_pitch, src_pitch, w*cpp))
643 #ifdef NOUVEAU_EXA_PIXMAPS
645 NVExaPrepareAccess(PixmapPtr pPix, int index)
647 ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum];
648 NVPtr pNv = NVPTR(pScrn);
649 struct nouveau_pixmap *nvpix;
652 nvpix = exaGetPixmapDriverPrivate(pPix);
653 if (!nvpix || !nvpix->bo)
656 /*XXX: ho hum.. sync if needed */
661 if (nouveau_bo_map(nvpix->bo, NOUVEAU_BO_RDWR))
663 pPix->devPrivate.ptr = nvpix->bo->map;
664 nvpix->mapped = TRUE;
669 NVExaFinishAccess(PixmapPtr pPix, int index)
671 ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum];
672 NVPtr pNv = NVPTR(pScrn);
673 struct nouveau_pixmap *nvpix;
676 nvpix = exaGetPixmapDriverPrivate(pPix);
677 if (!nvpix || !nvpix->bo || !nvpix->mapped)
680 nouveau_bo_unmap(nvpix->bo);
681 pPix->devPrivate.ptr = NULL;
682 nvpix->mapped = FALSE;
686 NVExaPixmapIsOffscreen(PixmapPtr pPix)
688 ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum];
689 NVPtr pNv = NVPTR(pScrn);
690 struct nouveau_pixmap *nvpix;
693 nvpix = exaGetPixmapDriverPrivate(pPix);
694 if (!nvpix || !nvpix->bo)
701 NVExaCreatePixmap(ScreenPtr pScreen, int size, int align)
703 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
704 NVPtr pNv = NVPTR(pScrn);
705 struct nouveau_pixmap *nvpix;
707 nvpix = xcalloc(1, sizeof(struct nouveau_pixmap));
712 if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM, 0, size,
723 NVExaDestroyPixmap(ScreenPtr pScreen, void *driverPriv)
725 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
726 NVPtr pNv = NVPTR(pScrn);
727 struct nouveau_pixmap *nvpix = driverPriv;
732 /*XXX: only if pending relocs reference this buffer..*/
735 nouveau_bo_del(&nvpix->bo);
740 NVExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth,
741 int bitsPerPixel, int devKind, pointer pPixData)
743 ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
744 NVPtr pNv = NVPTR(pScrn);
745 struct nouveau_pixmap *nvpix;
747 if (pPixData == pNv->FB->map) {
748 nvpix = exaGetPixmapDriverPrivate(pPixmap);
752 if (nouveau_bo_ref(pNv->dev, pNv->FB->handle, &nvpix->bo))
755 miModifyPixmapHeader(pPixmap, width, height, depth,
756 bitsPerPixel, devKind, NULL);
765 NVExaInit(ScreenPtr pScreen)
767 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
768 NVPtr pNv = NVPTR(pScrn);
770 if(!(pNv->EXADriverPtr = (ExaDriverPtr) xnfcalloc(sizeof(ExaDriverRec), 1))) {
775 pNv->EXADriverPtr->exa_major = EXA_VERSION_MAJOR;
776 pNv->EXADriverPtr->exa_minor = EXA_VERSION_MINOR;
778 #ifdef NOUVEAU_EXA_PIXMAPS
779 if (NOUVEAU_EXA_PIXMAPS) {
780 pNv->EXADriverPtr->flags = EXA_OFFSCREEN_PIXMAPS |
782 pNv->EXADriverPtr->PrepareAccess = NVExaPrepareAccess;
783 pNv->EXADriverPtr->FinishAccess = NVExaFinishAccess;
784 pNv->EXADriverPtr->PixmapIsOffscreen = NVExaPixmapIsOffscreen;
785 pNv->EXADriverPtr->CreatePixmap = NVExaCreatePixmap;
786 pNv->EXADriverPtr->DestroyPixmap = NVExaDestroyPixmap;
787 pNv->EXADriverPtr->ModifyPixmapHeader = NVExaModifyPixmapHeader;
791 pNv->EXADriverPtr->flags = EXA_OFFSCREEN_PIXMAPS;
792 pNv->EXADriverPtr->memoryBase = pNv->FB->map;
793 pNv->EXADriverPtr->offScreenBase =
794 pScrn->virtualX * pScrn->virtualY *
795 (pScrn->bitsPerPixel / 8);
796 pNv->EXADriverPtr->memorySize = pNv->FB->size;
798 pNv->EXADriverPtr->pixmapOffsetAlign = 256;
799 pNv->EXADriverPtr->pixmapPitchAlign = 64;
800 pNv->EXADriverPtr->maxX = 32768;
801 pNv->EXADriverPtr->maxY = 32768;
803 pNv->EXADriverPtr->WaitMarker = NVExaWaitMarker;
805 /* Install default hooks */
806 pNv->EXADriverPtr->DownloadFromScreen = NVDownloadFromScreen;
807 pNv->EXADriverPtr->UploadToScreen = NVUploadToScreen;
809 if (pNv->Architecture < NV_ARCH_50) {
810 pNv->EXADriverPtr->PrepareCopy = NVExaPrepareCopy;
811 pNv->EXADriverPtr->Copy = NVExaCopy;
812 pNv->EXADriverPtr->DoneCopy = NVExaDoneCopy;
814 pNv->EXADriverPtr->PrepareSolid = NVExaPrepareSolid;
815 pNv->EXADriverPtr->Solid = NVExaSolid;
816 pNv->EXADriverPtr->DoneSolid = NVExaDoneSolid;
818 pNv->EXADriverPtr->PrepareCopy = NV50EXAPrepareCopy;
819 pNv->EXADriverPtr->Copy = NV50EXACopy;
820 pNv->EXADriverPtr->DoneCopy = NV50EXADoneCopy;
822 pNv->EXADriverPtr->PrepareSolid = NV50EXAPrepareSolid;
823 pNv->EXADriverPtr->Solid = NV50EXASolid;
824 pNv->EXADriverPtr->DoneSolid = NV50EXADoneSolid;
827 switch (pNv->Architecture) {
831 pNv->EXADriverPtr->CheckComposite = NV10CheckComposite;
832 pNv->EXADriverPtr->PrepareComposite = NV10PrepareComposite;
833 pNv->EXADriverPtr->Composite = NV10Composite;
834 pNv->EXADriverPtr->DoneComposite = NV10DoneComposite;
837 pNv->EXADriverPtr->CheckComposite = NV30EXACheckComposite;
838 pNv->EXADriverPtr->PrepareComposite = NV30EXAPrepareComposite;
839 pNv->EXADriverPtr->Composite = NV30EXAComposite;
840 pNv->EXADriverPtr->DoneComposite = NV30EXADoneComposite;
843 pNv->EXADriverPtr->CheckComposite = NV40EXACheckComposite;
844 pNv->EXADriverPtr->PrepareComposite = NV40EXAPrepareComposite;
845 pNv->EXADriverPtr->Composite = NV40EXAComposite;
846 pNv->EXADriverPtr->DoneComposite = NV40EXADoneComposite;
854 return exaDriverInit(pScreen, pNv->EXADriverPtr);