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 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 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: fmt = 1; break;
461 case 4: fmt = 4; break;
466 /* Pad out input width to cover both COLORA() and COLORB() */
467 iw = (line_len + 7) & ~7;
468 id = iw / 4; /* line push size */
471 /* Don't support lines longer than max push size yet.. */
475 NVDmaStart(pNv, NvClipRectangle, CLIP_POINT, 2);
476 NVDmaNext (pNv, 0x0);
477 NVDmaNext (pNv, 0x7FFF7FFF);
479 NVDmaStart(pNv, NvImageFromCpu, NV05_IMAGE_FROM_CPU_OPERATION, 2);
480 NVDmaNext (pNv, 0x3 /* SRCCOPY */);
481 NVDmaNext (pNv, fmt);
482 NVDmaStart(pNv, NvImageFromCpu, NV05_IMAGE_FROM_CPU_POINT, 3);
483 NVDmaNext (pNv, (y << 16) | x); /* dst point */
484 NVDmaNext (pNv, (h << 16) | w); /* width/height out */
485 NVDmaNext (pNv, (h << 16) | iw); /* width/height in */
490 NVDmaStart(pNv, NvImageFromCpu,
491 NV10_IMAGE_FROM_CPU_HLINE, id);
492 dst = (char *)pNv->dmaBase + (pNv->dmaCurrent << 2);
493 memcpy(dst, src, line_len);
494 pNv->dmaCurrent += id;
503 NVAccelUploadM2MF(ScrnInfoPtr pScrn, uint64_t dst_offset, const char *src,
504 int dst_pitch, int src_pitch,
505 int line_len, int line_count)
507 NVPtr pNv = NVPTR(pScrn);
509 setM2MFDirection(pScrn, 1);
512 char *dst = pNv->GARTScratch->map;
515 /* Determine max amount of data we can DMA at once */
516 if (line_count * line_len <= pNv->GARTScratch->size) {
519 lc = pNv->GARTScratch->size / line_len;
529 if (src_pitch == line_len) {
530 memcpy(dst, src, src_pitch * lc);
531 src += src_pitch * lc;
533 for (i = 0; i < lc; i++) {
534 memcpy(dst, src, line_len);
540 if (pNv->Architecture >= NV_ARCH_50) {
541 NVDmaStart(pNv, NvMemFormat, 0x200, 1);
543 NVDmaStart(pNv, NvMemFormat, 0x21c, 1);
545 /* probably high-order bits of address */
546 NVDmaStart(pNv, NvMemFormat, 0x238, 2);
552 NVDmaStart(pNv, NvMemFormat,
553 NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8);
554 NVDmaNext (pNv, (uint32_t)pNv->GARTScratch->offset);
555 NVDmaNext (pNv, (uint32_t)dst_offset);
556 NVDmaNext (pNv, line_len);
557 NVDmaNext (pNv, dst_pitch);
558 NVDmaNext (pNv, line_len);
560 NVDmaNext (pNv, (1<<8)|1);
563 NVNotifierReset(pScrn, pNv->Notifier0);
564 NVDmaStart(pNv, NvMemFormat,
565 NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1);
567 NVDmaStart(pNv, NvMemFormat, 0x100, 1);
570 if (!NVNotifierWaitStatus(pScrn, pNv->Notifier0, 0, 2000))
573 dst_offset += lc * dst_pitch;
580 static Bool NVUploadToScreen(PixmapPtr pDst,
581 int x, int y, int w, int h,
582 char *src, int src_pitch)
584 ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
585 NVPtr pNv = NVPTR(pScrn);
586 int dst_offset, dst_pitch, cpp;
589 dst_offset = NVAccelGetPixmapOffset(pDst);
590 dst_pitch = exaGetPixmapPitch(pDst);
591 cpp = pDst->drawable.bitsPerPixel >> 3;
593 /* try hostdata transfer */
594 if (pNv->Architecture < NV_ARCH_50 && w*h*cpp<16*1024) /* heuristic */
598 if (NVAccelGetCtxSurf2DFormatFromPixmap(pDst, &fmt)) {
599 NVAccelSetCtxSurf2D(pDst, pDst, fmt);
600 if (NVAccelUploadIFC(pScrn, src, src_pitch,
602 exaMarkSync(pDst->drawable.pScreen);
608 /* try gart-based transfer */
609 if (pNv->GARTScratch) {
610 dst_offset += (y * dst_pitch) + (x * cpp);
611 if (NVAccelUploadM2MF(pScrn, dst_offset, src, dst_pitch,
612 src_pitch, w * cpp, h))
616 /* fallback to memcpy-based transfer */
617 dst = (char *) dst_offset + (y * dst_pitch) + (x * cpp);
618 exaWaitSync(pDst->drawable.pScreen);
619 if (NVAccelMemcpyRect(dst, src, h, dst_pitch, src_pitch, w*cpp))
626 static Bool NVCheckComposite(int op,
627 PicturePtr pSrcPicture,
628 PicturePtr pMaskPicture,
629 PicturePtr pDstPicture)
633 /* PictOpOver doesn't work correctly. The HW command assumes
634 * non premuliplied alpha
638 else if (op != PictOpOver && op != PictOpSrc)
640 else if (!pSrcPicture->pDrawable)
642 else if (pSrcPicture->transform || pSrcPicture->repeat)
644 else if (pSrcPicture->alphaMap || pDstPicture->alphaMap)
646 else if (pSrcPicture->format != PICT_a8r8g8b8 &&
647 pSrcPicture->format != PICT_x8r8g8b8 &&
648 pSrcPicture->format != PICT_r5g6b5)
650 else if (pDstPicture->format != PICT_a8r8g8b8 &&
651 pDstPicture->format != PICT_x8r8g8b8 &&
652 pDstPicture->format != PICT_r5g6b5)
658 static CARD32 src_size, src_pitch, src_offset;
660 static Bool NVPrepareComposite(int op,
661 PicturePtr pSrcPicture,
662 PicturePtr pMaskPicture,
663 PicturePtr pDstPicture,
668 ScrnInfoPtr pScrn = xf86Screens[pSrcPicture->pDrawable->pScreen->myNum];
669 NVPtr pNv = NVPTR(pScrn);
670 int srcFormat, dstFormat;
672 if (pSrcPicture->format == PICT_a8r8g8b8)
673 srcFormat = STRETCH_BLIT_FORMAT_A8R8G8B8;
674 else if (pSrcPicture->format == PICT_x8r8g8b8)
675 srcFormat = STRETCH_BLIT_FORMAT_X8R8G8B8;
676 else if (pSrcPicture->format == PICT_r5g6b5)
677 srcFormat = STRETCH_BLIT_FORMAT_DEPTH16;
681 if (!NVAccelGetCtxSurf2DFormatFromPicture(pDstPicture, &dstFormat))
683 if (!NVAccelSetCtxSurf2D(pDst, pDst, dstFormat))
686 NVDmaStart(pNv, NvScaledImage, STRETCH_BLIT_FORMAT, 2);
687 NVDmaNext (pNv, srcFormat);
688 NVDmaNext (pNv, (op == PictOpSrc) ? STRETCH_BLIT_OPERATION_COPY : STRETCH_BLIT_OPERATION_BLEND);
690 src_size = ((pSrcPicture->pDrawable->width+3)&~3) |
691 (pSrcPicture->pDrawable->height << 16);
692 src_pitch = exaGetPixmapPitch(pSrc)
693 | (STRETCH_BLIT_SRC_FORMAT_ORIGIN_CORNER << 16)
694 | (STRETCH_BLIT_SRC_FORMAT_FILTER_POINT_SAMPLE << 24);
695 src_offset = NVAccelGetPixmapOffset(pSrc);
700 static void NVComposite(PixmapPtr pDst,
710 ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
711 NVPtr pNv = NVPTR(pScrn);
713 NVDmaStart(pNv, NvScaledImage, STRETCH_BLIT_CLIP_POINT, 6);
714 NVDmaNext (pNv, dstX | (dstY << 16));
715 NVDmaNext (pNv, width | (height << 16));
716 NVDmaNext (pNv, dstX | (dstY << 16));
717 NVDmaNext (pNv, width | (height << 16));
718 NVDmaNext (pNv, 1<<20);
719 NVDmaNext (pNv, 1<<20);
721 NVDmaStart(pNv, NvScaledImage, STRETCH_BLIT_SRC_SIZE, 4);
722 NVDmaNext (pNv, src_size);
723 NVDmaNext (pNv, src_pitch);
724 NVDmaNext (pNv, src_offset);
725 NVDmaNext (pNv, srcX | (srcY<<16));
730 static void NVDoneComposite (PixmapPtr pDst)
732 ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
733 NVPtr pNv = NVPTR(pScrn);
736 if (pNv->CurrentLayout.depth == 8)
737 format = SURFACE_FORMAT_Y8;
738 else if (pNv->CurrentLayout.depth == 16)
739 format = SURFACE_FORMAT_R5G6B5;
741 format = SURFACE_FORMAT_X8R8G8B8;
743 NVDmaStart(pNv, NvContextSurfaces, SURFACE_FORMAT, 1);
744 NVDmaNext (pNv, format);
746 exaMarkSync(pDst->drawable.pScreen);
749 Bool NVExaInit(ScreenPtr pScreen)
751 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
752 NVPtr pNv = NVPTR(pScrn);
754 if(!(pNv->EXADriverPtr = (ExaDriverPtr) xnfcalloc(sizeof(ExaDriverRec), 1))) {
759 pNv->EXADriverPtr->exa_major = EXA_VERSION_MAJOR;
760 pNv->EXADriverPtr->exa_minor = EXA_VERSION_MINOR;
762 pNv->EXADriverPtr->memoryBase = pNv->FB->map;
763 pNv->EXADriverPtr->offScreenBase =
764 pScrn->virtualX * pScrn->virtualY*(pScrn->bitsPerPixel/8);
765 pNv->EXADriverPtr->memorySize = pNv->FB->size;
766 pNv->EXADriverPtr->pixmapOffsetAlign = 256;
767 pNv->EXADriverPtr->pixmapPitchAlign = 64;
768 pNv->EXADriverPtr->flags = EXA_OFFSCREEN_PIXMAPS;
769 pNv->EXADriverPtr->maxX = 32768;
770 pNv->EXADriverPtr->maxY = 32768;
772 pNv->EXADriverPtr->WaitMarker = NVExaWaitMarker;
774 /* Install default hooks */
775 pNv->EXADriverPtr->DownloadFromScreen = NVDownloadFromScreen;
776 pNv->EXADriverPtr->UploadToScreen = NVUploadToScreen;
778 if (pNv->Architecture < NV_ARCH_50) {
779 pNv->EXADriverPtr->PrepareCopy = NVExaPrepareCopy;
780 pNv->EXADriverPtr->Copy = NVExaCopy;
781 pNv->EXADriverPtr->DoneCopy = NVExaDoneCopy;
783 pNv->EXADriverPtr->PrepareSolid = NVExaPrepareSolid;
784 pNv->EXADriverPtr->Solid = NVExaSolid;
785 pNv->EXADriverPtr->DoneSolid = NVExaDoneSolid;
787 pNv->EXADriverPtr->PrepareCopy = NV50EXAPrepareCopy;
788 pNv->EXADriverPtr->Copy = NV50EXACopy;
789 pNv->EXADriverPtr->DoneCopy = NV50EXADoneCopy;
791 pNv->EXADriverPtr->PrepareSolid = NV50EXAPrepareSolid;
792 pNv->EXADriverPtr->Solid = NV50EXASolid;
793 pNv->EXADriverPtr->DoneSolid = NV50EXADoneSolid;
796 switch (pNv->Architecture) {
797 #if defined(ENABLE_NV30EXA)
801 pNv->EXADriverPtr->CheckComposite = NV30EXACheckComposite;
802 pNv->EXADriverPtr->PrepareComposite = NV30EXAPrepareComposite;
803 pNv->EXADriverPtr->Composite = NV30EXAComposite;
804 pNv->EXADriverPtr->DoneComposite = NV30EXADoneComposite;
808 #if (X_BYTE_ORDER == X_LITTLE_ENDIAN) && defined(ENABLE_NV30EXA)
810 pNv->EXADriverPtr->CheckComposite = NV40EXACheckComposite;
811 pNv->EXADriverPtr->PrepareComposite = NV40EXAPrepareComposite;
812 pNv->EXADriverPtr->Composite = NV40EXAComposite;
813 pNv->EXADriverPtr->DoneComposite = NV40EXADoneComposite;
819 if (!pNv->BlendingPossible)
821 pNv->EXADriverPtr->CheckComposite = NVCheckComposite;
822 pNv->EXADriverPtr->PrepareComposite = NVPrepareComposite;
823 pNv->EXADriverPtr->Composite = NVComposite;
824 pNv->EXADriverPtr->DoneComposite = NVDoneComposite;
828 return exaDriverInit(pScreen, pNv->EXADriverPtr);