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)
48 #include "nv_include.h"
56 const int NVCopyROP[16] =
60 0x44, /* GXandReverse */
62 0x22, /* GXandInverted */
69 0xDD, /* GXorReverse */
70 0x33, /* GXcopyInverted */
71 0xBB, /* GXorInverted */
77 NVSetPattern(ScrnInfoPtr pScrn, CARD32 clr0, CARD32 clr1,
78 CARD32 pat0, CARD32 pat1)
80 NVPtr pNv = NVPTR(pScrn);
82 NVDmaStart(pNv, NvImagePattern, PATTERN_COLOR_0, 4);
83 NVDmaNext (pNv, clr0);
84 NVDmaNext (pNv, clr1);
85 NVDmaNext (pNv, pat0);
86 NVDmaNext (pNv, pat1);
90 NVSetROP(ScrnInfoPtr pScrn, CARD32 alu, CARD32 planemask)
92 NVPtr pNv = NVPTR(pScrn);
93 int rop = NVCopyROP[alu] & 0xf0;
95 if (planemask != ~0) {
96 NVSetPattern(pScrn, 0, planemask, ~0, ~0);
97 if (pNv->currentRop != (alu + 32)) {
98 NVDmaStart(pNv, NvRop, ROP_SET, 1);
99 NVDmaNext (pNv, rop | 0x0a);
100 pNv->currentRop = alu + 32;
103 if (pNv->currentRop != alu) {
104 if(pNv->currentRop >= 16)
105 NVSetPattern(pScrn, ~0, ~0, ~0, ~0);
106 NVDmaStart(pNv, NvRop, ROP_SET, 1);
107 NVDmaNext (pNv, rop | (rop >> 4));
108 pNv->currentRop = alu;
112 static void setM2MFDirection(ScrnInfoPtr pScrn, int dir)
114 NVPtr pNv = NVPTR(pScrn);
116 if (pNv->M2MFDirection != dir) {
118 NVDmaStart(pNv, NvMemFormat, MEMFORMAT_DMA_OBJECT_IN, 2);
119 NVDmaNext (pNv, dir ? NvDmaTT : NvDmaFB);
120 NVDmaNext (pNv, dir ? NvDmaFB : NvDmaTT);
121 pNv->M2MFDirection = dir;
125 static CARD32 rectFormat(DrawablePtr pDrawable)
127 switch(pDrawable->bitsPerPixel) {
130 return RECT_FORMAT_DEPTH24;
133 return RECT_FORMAT_DEPTH16;
136 return RECT_FORMAT_DEPTH8;
141 /* EXA acceleration hooks */
142 static void NVExaWaitMarker(ScreenPtr pScreen, int marker)
144 NVSync(xf86Screens[pScreen->myNum]);
147 static Bool NVExaPrepareSolid(PixmapPtr pPixmap,
152 ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
153 NVPtr pNv = NVPTR(pScrn);
156 planemask |= ~0 << pPixmap->drawable.bitsPerPixel;
157 if (planemask != ~0 || alu != GXcopy) {
158 if (pPixmap->drawable.bitsPerPixel == 32)
160 NVDmaStart(pNv, NvRectangle, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1);
161 NVDmaNext (pNv, 1 /* ROP_AND */);
162 NVSetROP(pScrn, alu, planemask);
164 NVDmaStart(pNv, NvRectangle, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1);
165 NVDmaNext (pNv, 3 /* SRCCOPY */);
168 if (!NVAccelGetCtxSurf2DFormatFromPixmap(pPixmap, &fmt))
171 /* When SURFACE_FORMAT_A8R8G8B8 is used with GDI_RECTANGLE_TEXT, the
172 * alpha channel gets forced to 0xFF for some reason. We're using
173 * SURFACE_FORMAT_Y32 as a workaround
175 if (fmt == SURFACE_FORMAT_A8R8G8B8)
178 if (!NVAccelSetCtxSurf2D(pPixmap, pPixmap, fmt))
181 NVDmaStart(pNv, NvRectangle, RECT_FORMAT, 1);
182 NVDmaNext (pNv, rectFormat(&pPixmap->drawable));
183 NVDmaStart(pNv, NvRectangle, RECT_SOLID_COLOR, 1);
186 pNv->DMAKickoffCallback = NVDmaKickoffCallback;
190 static void NVExaSolid (PixmapPtr pPixmap, int x1, int y1, int x2, int y2)
192 ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
193 NVPtr pNv = NVPTR(pScrn);
197 NVDmaStart(pNv, NvRectangle, RECT_SOLID_RECTS(0), 2);
198 NVDmaNext (pNv, (x1 << 16) | y1);
199 NVDmaNext (pNv, (width << 16) | height);
201 if((width * height) >= 512)
205 static void NVExaDoneSolid (PixmapPtr pPixmap)
209 static Bool NVExaPrepareCopy(PixmapPtr pSrcPixmap,
210 PixmapPtr pDstPixmap,
216 ScrnInfoPtr pScrn = xf86Screens[pSrcPixmap->drawable.pScreen->myNum];
217 NVPtr pNv = NVPTR(pScrn);
220 if (pSrcPixmap->drawable.bitsPerPixel !=
221 pDstPixmap->drawable.bitsPerPixel)
224 planemask |= ~0 << pDstPixmap->drawable.bitsPerPixel;
225 if (planemask != ~0 || alu != GXcopy) {
226 if (pDstPixmap->drawable.bitsPerPixel == 32)
228 NVDmaStart(pNv, NvImageBlit, NV_IMAGE_BLIT_OPERATION, 1);
229 NVDmaNext (pNv, 1 /* ROP_AND */);
230 NVSetROP(pScrn, alu, planemask);
232 NVDmaStart(pNv, NvImageBlit, NV_IMAGE_BLIT_OPERATION, 1);
233 NVDmaNext (pNv, 3 /* SRCCOPY */);
236 if (!NVAccelGetCtxSurf2DFormatFromPixmap(pDstPixmap, &fmt))
238 if (!NVAccelSetCtxSurf2D(pSrcPixmap, pDstPixmap, fmt))
241 pNv->DMAKickoffCallback = NVDmaKickoffCallback;
245 static void NVExaCopy(PixmapPtr pDstPixmap,
253 ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
254 NVPtr pNv = NVPTR(pScrn);
256 /* Now check whether we have the same values for srcY and dstY and
257 whether the used chipset is buggy. Currently we flag all of G70
258 cards as buggy, which is probably much to broad. KoalaBR
259 16 is an abritrary threshold. It should define the maximum number
260 of lines between dstY and srcY If the number of lines is below
261 we guess, that the bug won't trigger...
263 if ( ((abs(srcY - dstY)< 16)||(abs(srcX-dstX)<16)) &&
264 ((((pNv->Chipset & 0xfff0) == CHIPSET_G70) ||
265 ((pNv->Chipset & 0xfff0) == CHIPSET_G71) ||
266 ((pNv->Chipset & 0xfff0) == CHIPSET_G72) ||
267 ((pNv->Chipset & 0xfff0) == CHIPSET_G73) ||
268 ((pNv->Chipset & 0xfff0) == CHIPSET_C512))) )
270 int dx=abs(srcX - dstX),dy=abs(srcY - dstY);
271 // Ok, let's do it manually unless someone comes up with a better idea
272 // 1. If dstY and srcY are really the same, do a copy rowwise
275 NVDEBUG("ExaCopy: Lines identical:\n");
283 for (i = 0; i < width; i++) {
284 NVDmaStart(pNv, NvImageBlit, BLIT_POINT_SRC, 3);
285 NVDmaNext (pNv, (srcY << 16) | (srcX+xpos));
286 NVDmaNext (pNv, (dstY << 16) | (dstX+xpos));
287 NVDmaNext (pNv, (height << 16) | 1);
291 // 2. Otherwise we will try a line by line copy in the hope to avoid
294 NVDEBUG("ExaCopy: Lines nearly the same srcY=%d, dstY=%d:\n", srcY, dstY);
302 for (i = 0; i < height; i++) {
303 NVDmaStart(pNv, NvImageBlit, BLIT_POINT_SRC, 3);
304 NVDmaNext (pNv, ((srcY+ypos) << 16) | srcX);
305 NVDmaNext (pNv, ((dstY+ypos) << 16) | dstX);
306 NVDmaNext (pNv, (1 << 16) | width);
311 NVDEBUG("ExaCopy: Using default path\n");
312 NVDmaStart(pNv, NvImageBlit, BLIT_POINT_SRC, 3);
313 NVDmaNext (pNv, (srcY << 16) | srcX);
314 NVDmaNext (pNv, (dstY << 16) | dstX);
315 NVDmaNext (pNv, (height << 16) | width);
318 if((width * height) >= 512)
322 static void NVExaDoneCopy (PixmapPtr pDstPixmap) {}
324 static inline Bool NVAccelMemcpyRect(char *dst, const char *src, int height,
325 int dst_pitch, int src_pitch, int line_len)
327 if ((src_pitch == line_len) && (src_pitch == dst_pitch)) {
328 memcpy(dst, src, line_len*height);
331 memcpy(dst, src, line_len);
341 NVAccelDownloadM2MF(ScrnInfoPtr pScrn, char *dst, uint64_t src_offset,
342 int dst_pitch, int src_pitch,
343 int line_len, int line_count)
345 NVPtr pNv = NVPTR(pScrn);
347 setM2MFDirection(pScrn, 0);
350 char *src = pNv->GARTScratch->map;
353 if (line_count * line_len <= pNv->GARTScratch->size) {
356 lc = pNv->GARTScratch->size / line_len;
365 if (pNv->Architecture >= NV_ARCH_50) {
366 NVDmaStart(pNv, NvMemFormat, 0x200, 1);
368 NVDmaStart(pNv, NvMemFormat, 0x21c, 1);
370 /* probably high-order bits of address */
371 NVDmaStart(pNv, NvMemFormat, 0x238, 2);
376 NVDmaStart(pNv, NvMemFormat,
377 NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8);
378 NVDmaNext (pNv, (uint32_t)src_offset);
379 NVDmaNext (pNv, (uint32_t)pNv->GARTScratch->offset);
380 NVDmaNext (pNv, src_pitch);
381 NVDmaNext (pNv, line_len);
382 NVDmaNext (pNv, line_len);
384 NVDmaNext (pNv, (1<<8)|1);
387 NVNotifierReset(pScrn, pNv->Notifier0);
388 NVDmaStart(pNv, NvMemFormat,
389 NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1);
391 NVDmaStart(pNv, NvMemFormat, 0x100, 1);
394 if (!NVNotifierWaitStatus(pScrn, pNv->Notifier0, 0, 2000))
397 if (dst_pitch == line_len) {
398 memcpy(dst, src, dst_pitch * lc);
399 dst += dst_pitch * lc;
401 for (i = 0; i < lc; i++) {
402 memcpy(dst, src, line_len);
409 src_offset += lc * src_pitch;
415 static Bool NVDownloadFromScreen(PixmapPtr pSrc,
418 char *dst, int dst_pitch)
420 ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum];
421 NVPtr pNv = NVPTR(pScrn);
422 int src_offset, src_pitch, cpp, offset;
425 src_offset = NVAccelGetPixmapOffset(pSrc);
426 src_pitch = exaGetPixmapPitch(pSrc);
427 cpp = pSrc->drawable.bitsPerPixel >> 3;
428 offset = (y * src_pitch) + (x * cpp);
430 if (pNv->GARTScratch) {
431 if (NVAccelDownloadM2MF(pScrn, dst,
433 dst_pitch, src_pitch, w * cpp, h))
437 src = (char *) src_offset + offset;
438 exaWaitSync(pSrc->drawable.pScreen);
439 if (NVAccelMemcpyRect(dst, src, h, dst_pitch, src_pitch, w*cpp))
446 NVAccelUploadIFC(ScrnInfoPtr pScrn, const char *src, int src_pitch,
447 PixmapPtr pDst, int fmt, int x, int y, int w, int h, int cpp)
449 NVPtr pNv = NVPTR(pScrn);
450 int line_len = w * cpp;
453 if (pNv->Architecture >= NV_ARCH_50)
460 case 2: ifc_fmt = 1; break;
461 case 4: ifc_fmt = 4; break;
466 NVAccelSetCtxSurf2D(pDst, pDst, fmt);
468 /* Pad out input width to cover both COLORA() and COLORB() */
469 iw = (line_len + 7) & ~7;
470 id = iw / 4; /* line push size */
473 /* Don't support lines longer than max push size yet.. */
477 NVDmaStart(pNv, NvClipRectangle, CLIP_POINT, 2);
478 NVDmaNext (pNv, 0x0);
479 NVDmaNext (pNv, 0x7FFF7FFF);
481 NVDmaStart(pNv, NvImageFromCpu, NV05_IMAGE_FROM_CPU_OPERATION, 2);
482 NVDmaNext (pNv, 0x3 /* SRCCOPY */);
483 NVDmaNext (pNv, ifc_fmt);
484 NVDmaStart(pNv, NvImageFromCpu, NV05_IMAGE_FROM_CPU_POINT, 3);
485 NVDmaNext (pNv, (y << 16) | x); /* dst point */
486 NVDmaNext (pNv, (h << 16) | w); /* width/height out */
487 NVDmaNext (pNv, (h << 16) | iw); /* width/height in */
492 NVDmaStart(pNv, NvImageFromCpu,
493 NV10_IMAGE_FROM_CPU_HLINE, id);
494 dst = (char *)pNv->dmaBase + (pNv->dmaCurrent << 2);
495 memcpy(dst, src, line_len);
496 pNv->dmaCurrent += id;
505 NVAccelUploadM2MF(ScrnInfoPtr pScrn, uint64_t dst_offset, const char *src,
506 int dst_pitch, int src_pitch,
507 int line_len, int line_count)
509 NVPtr pNv = NVPTR(pScrn);
511 setM2MFDirection(pScrn, 1);
514 char *dst = pNv->GARTScratch->map;
517 /* Determine max amount of data we can DMA at once */
518 if (line_count * line_len <= pNv->GARTScratch->size) {
521 lc = pNv->GARTScratch->size / line_len;
531 if (src_pitch == line_len) {
532 memcpy(dst, src, src_pitch * lc);
533 src += src_pitch * lc;
535 for (i = 0; i < lc; i++) {
536 memcpy(dst, src, line_len);
542 if (pNv->Architecture >= NV_ARCH_50) {
543 NVDmaStart(pNv, NvMemFormat, 0x200, 1);
545 NVDmaStart(pNv, NvMemFormat, 0x21c, 1);
547 /* probably high-order bits of address */
548 NVDmaStart(pNv, NvMemFormat, 0x238, 2);
554 NVDmaStart(pNv, NvMemFormat,
555 NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8);
556 NVDmaNext (pNv, (uint32_t)pNv->GARTScratch->offset);
557 NVDmaNext (pNv, (uint32_t)dst_offset);
558 NVDmaNext (pNv, line_len);
559 NVDmaNext (pNv, dst_pitch);
560 NVDmaNext (pNv, line_len);
562 NVDmaNext (pNv, (1<<8)|1);
565 NVNotifierReset(pScrn, pNv->Notifier0);
566 NVDmaStart(pNv, NvMemFormat,
567 NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1);
569 NVDmaStart(pNv, NvMemFormat, 0x100, 1);
572 if (!NVNotifierWaitStatus(pScrn, pNv->Notifier0, 0, 2000))
575 dst_offset += lc * dst_pitch;
582 static Bool NVUploadToScreen(PixmapPtr pDst,
583 int x, int y, int w, int h,
584 char *src, int src_pitch)
586 ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
587 NVPtr pNv = NVPTR(pScrn);
588 int dst_offset, dst_pitch, cpp;
591 dst_offset = NVAccelGetPixmapOffset(pDst);
592 dst_pitch = exaGetPixmapPitch(pDst);
593 cpp = pDst->drawable.bitsPerPixel >> 3;
595 /* try hostdata transfer */
596 if (pNv->Architecture < NV_ARCH_50 && w*h*cpp<16*1024) /* heuristic */
600 if (NVAccelGetCtxSurf2DFormatFromPixmap(pDst, &fmt)) {
601 if (NVAccelUploadIFC(pScrn, src, src_pitch, pDst, fmt,
603 exaMarkSync(pDst->drawable.pScreen);
609 /* try gart-based transfer */
610 if (pNv->GARTScratch) {
611 dst_offset += (y * dst_pitch) + (x * cpp);
612 if (NVAccelUploadM2MF(pScrn, dst_offset, src, dst_pitch,
613 src_pitch, w * cpp, h))
617 /* fallback to memcpy-based transfer */
618 dst = (char *) dst_offset + (y * dst_pitch) + (x * cpp);
619 exaWaitSync(pDst->drawable.pScreen);
620 if (NVAccelMemcpyRect(dst, src, h, dst_pitch, src_pitch, w*cpp))
627 static Bool NVCheckComposite(int op,
628 PicturePtr pSrcPicture,
629 PicturePtr pMaskPicture,
630 PicturePtr pDstPicture)
634 /* PictOpOver doesn't work correctly. The HW command assumes
635 * non premuliplied alpha
639 else if (op != PictOpOver && op != PictOpSrc)
641 else if (!pSrcPicture->pDrawable)
643 else if (pSrcPicture->transform || pSrcPicture->repeat)
645 else if (pSrcPicture->alphaMap || pDstPicture->alphaMap)
647 else if (pSrcPicture->format != PICT_a8r8g8b8 &&
648 pSrcPicture->format != PICT_x8r8g8b8 &&
649 pSrcPicture->format != PICT_r5g6b5)
651 else if (pDstPicture->format != PICT_a8r8g8b8 &&
652 pDstPicture->format != PICT_x8r8g8b8 &&
653 pDstPicture->format != PICT_r5g6b5)
659 static CARD32 src_size, src_pitch, src_offset;
661 static Bool NVPrepareComposite(int op,
662 PicturePtr pSrcPicture,
663 PicturePtr pMaskPicture,
664 PicturePtr pDstPicture,
669 ScrnInfoPtr pScrn = xf86Screens[pSrcPicture->pDrawable->pScreen->myNum];
670 NVPtr pNv = NVPTR(pScrn);
671 int srcFormat, dstFormat;
673 if (pSrcPicture->format == PICT_a8r8g8b8)
674 srcFormat = STRETCH_BLIT_FORMAT_A8R8G8B8;
675 else if (pSrcPicture->format == PICT_x8r8g8b8)
676 srcFormat = STRETCH_BLIT_FORMAT_X8R8G8B8;
677 else if (pSrcPicture->format == PICT_r5g6b5)
678 srcFormat = STRETCH_BLIT_FORMAT_DEPTH16;
682 if (!NVAccelGetCtxSurf2DFormatFromPicture(pDstPicture, &dstFormat))
684 if (!NVAccelSetCtxSurf2D(pDst, pDst, dstFormat))
687 NVDmaStart(pNv, NvScaledImage, STRETCH_BLIT_FORMAT, 2);
688 NVDmaNext (pNv, srcFormat);
689 NVDmaNext (pNv, (op == PictOpSrc) ? STRETCH_BLIT_OPERATION_COPY : STRETCH_BLIT_OPERATION_BLEND);
691 src_size = ((pSrcPicture->pDrawable->width+3)&~3) |
692 (pSrcPicture->pDrawable->height << 16);
693 src_pitch = exaGetPixmapPitch(pSrc)
694 | (STRETCH_BLIT_SRC_FORMAT_ORIGIN_CORNER << 16)
695 | (STRETCH_BLIT_SRC_FORMAT_FILTER_POINT_SAMPLE << 24);
696 src_offset = NVAccelGetPixmapOffset(pSrc);
701 static void NVComposite(PixmapPtr pDst,
711 ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
712 NVPtr pNv = NVPTR(pScrn);
714 NVDmaStart(pNv, NvScaledImage, STRETCH_BLIT_CLIP_POINT, 6);
715 NVDmaNext (pNv, dstX | (dstY << 16));
716 NVDmaNext (pNv, width | (height << 16));
717 NVDmaNext (pNv, dstX | (dstY << 16));
718 NVDmaNext (pNv, width | (height << 16));
719 NVDmaNext (pNv, 1<<20);
720 NVDmaNext (pNv, 1<<20);
722 NVDmaStart(pNv, NvScaledImage, STRETCH_BLIT_SRC_SIZE, 4);
723 NVDmaNext (pNv, src_size);
724 NVDmaNext (pNv, src_pitch);
725 NVDmaNext (pNv, src_offset);
726 NVDmaNext (pNv, srcX | (srcY<<16));
731 static void NVDoneComposite (PixmapPtr pDst)
733 ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
734 NVPtr pNv = NVPTR(pScrn);
737 if (pNv->CurrentLayout.depth == 8)
738 format = SURFACE_FORMAT_Y8;
739 else if (pNv->CurrentLayout.depth == 16)
740 format = SURFACE_FORMAT_R5G6B5;
742 format = SURFACE_FORMAT_X8R8G8B8;
744 NVDmaStart(pNv, NvContextSurfaces, SURFACE_FORMAT, 1);
745 NVDmaNext (pNv, format);
747 exaMarkSync(pDst->drawable.pScreen);
750 Bool NVExaInit(ScreenPtr pScreen)
752 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
753 NVPtr pNv = NVPTR(pScrn);
755 if(!(pNv->EXADriverPtr = (ExaDriverPtr) xnfcalloc(sizeof(ExaDriverRec), 1))) {
760 pNv->EXADriverPtr->exa_major = EXA_VERSION_MAJOR;
761 pNv->EXADriverPtr->exa_minor = EXA_VERSION_MINOR;
763 pNv->EXADriverPtr->memoryBase = pNv->FB->map;
764 pNv->EXADriverPtr->offScreenBase =
765 pScrn->virtualX * pScrn->virtualY*(pScrn->bitsPerPixel/8);
766 pNv->EXADriverPtr->memorySize = pNv->FB->size;
767 pNv->EXADriverPtr->pixmapOffsetAlign = 256;
768 pNv->EXADriverPtr->pixmapPitchAlign = 64;
769 pNv->EXADriverPtr->flags = EXA_OFFSCREEN_PIXMAPS;
770 pNv->EXADriverPtr->maxX = 32768;
771 pNv->EXADriverPtr->maxY = 32768;
773 pNv->EXADriverPtr->WaitMarker = NVExaWaitMarker;
775 /* Install default hooks */
776 pNv->EXADriverPtr->DownloadFromScreen = NVDownloadFromScreen;
777 pNv->EXADriverPtr->UploadToScreen = NVUploadToScreen;
779 if (pNv->Architecture < NV_ARCH_50) {
780 pNv->EXADriverPtr->PrepareCopy = NVExaPrepareCopy;
781 pNv->EXADriverPtr->Copy = NVExaCopy;
782 pNv->EXADriverPtr->DoneCopy = NVExaDoneCopy;
784 pNv->EXADriverPtr->PrepareSolid = NVExaPrepareSolid;
785 pNv->EXADriverPtr->Solid = NVExaSolid;
786 pNv->EXADriverPtr->DoneSolid = NVExaDoneSolid;
788 pNv->EXADriverPtr->PrepareCopy = NV50EXAPrepareCopy;
789 pNv->EXADriverPtr->Copy = NV50EXACopy;
790 pNv->EXADriverPtr->DoneCopy = NV50EXADoneCopy;
792 pNv->EXADriverPtr->PrepareSolid = NV50EXAPrepareSolid;
793 pNv->EXADriverPtr->Solid = NV50EXASolid;
794 pNv->EXADriverPtr->DoneSolid = NV50EXADoneSolid;
797 switch (pNv->Architecture) {
798 #if defined(ENABLE_NV30EXA)
802 pNv->EXADriverPtr->CheckComposite = NV30EXACheckComposite;
803 pNv->EXADriverPtr->PrepareComposite = NV30EXAPrepareComposite;
804 pNv->EXADriverPtr->Composite = NV30EXAComposite;
805 pNv->EXADriverPtr->DoneComposite = NV30EXADoneComposite;
809 #if (X_BYTE_ORDER == X_LITTLE_ENDIAN) && defined(ENABLE_NV30EXA)
811 pNv->EXADriverPtr->CheckComposite = NV40EXACheckComposite;
812 pNv->EXADriverPtr->PrepareComposite = NV40EXAPrepareComposite;
813 pNv->EXADriverPtr->Composite = NV40EXAComposite;
814 pNv->EXADriverPtr->DoneComposite = NV40EXADoneComposite;
820 if (!pNv->BlendingPossible)
822 pNv->EXADriverPtr->CheckComposite = NVCheckComposite;
823 pNv->EXADriverPtr->PrepareComposite = NVPrepareComposite;
824 pNv->EXADriverPtr->Composite = NVComposite;
825 pNv->EXADriverPtr->DoneComposite = NVDoneComposite;
829 return exaDriverInit(pScreen, pNv->EXADriverPtr);