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"
47 #if (EXA_VERSION_MAJOR < 2)
48 #error You need EXA >=2.0.0
56 static CARD32 getPitch(DrawablePtr pDrawable)
58 return (pDrawable->width*(pDrawable->bitsPerPixel >> 3) + 63) & ~63;
61 static CARD32 getOffset(NVPtr pNv, DrawablePtr pDrawable)
66 if (pDrawable->type == DRAWABLE_WINDOW) {
67 offset = pNv->FB->offset - pNv->VRAMPhysical;
69 pPixmap = (PixmapPtr)pDrawable;
70 offset = (CARD32)((unsigned long)pPixmap->devPrivate.ptr - (unsigned long)pNv->FB->map);
71 offset += pNv->FB->offset - pNv->VRAMPhysical;
77 static CARD32 surfaceFormat(DrawablePtr pDrawable)
79 switch(pDrawable->bitsPerPixel) {
82 return SURFACE_FORMAT_X8R8G8B8;
85 return SURFACE_FORMAT_R5G6B5;
88 return SURFACE_FORMAT_Y8;
93 static CARD32 rectFormat(DrawablePtr pDrawable)
95 switch(pDrawable->bitsPerPixel) {
98 return RECT_FORMAT_DEPTH24;
101 return RECT_FORMAT_DEPTH16;
104 return RECT_FORMAT_DEPTH8;
109 /* EXA acceleration hooks */
111 static void NVExaWaitMarker(ScreenPtr pScreen, int marker)
113 NVSync(xf86Screens[pScreen->myNum]);
116 static Bool NVExaPrepareSolid (PixmapPtr pPixmap,
121 ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
122 NVPtr pNv = NVPTR(pScrn);
125 planemask |= ~0 << pNv->CurrentLayout.depth;
127 NVSetRopSolid(pScrn, alu, planemask);
129 NVDmaStart(pNv, NvSubContextSurfaces, SURFACE_FORMAT, 4);
131 NVDmaNext (pNv, surfaceFormat(&pPixmap->drawable));
133 pitch = getPitch(&pPixmap->drawable);
134 NVDmaNext (pNv, (pitch<<16)|pitch);
136 NVDmaNext (pNv, getOffset(pNv, &pPixmap->drawable));
137 NVDmaNext (pNv, getOffset(pNv, &pPixmap->drawable));
139 NVDmaStart(pNv, NvSubRectangle, RECT_FORMAT, 1);
140 NVDmaNext(pNv, rectFormat(&pPixmap->drawable));
141 NVDmaStart(pNv, NvSubRectangle, RECT_SOLID_COLOR, 1);
144 pNv->DMAKickoffCallback = NVDMAKickoffCallback;
149 static void NVExaSolid (PixmapPtr pPixmap, int x1, int y1, int x2, int y2)
151 ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
152 NVPtr pNv = NVPTR(pScrn);
156 NVDmaStart(pNv, NvSubRectangle, RECT_SOLID_RECTS(0), 2);
157 NVDmaNext (pNv, (x1 << 16) | y1);
158 NVDmaNext (pNv, (width << 16) | height);
160 if((width * height) >= 512)
164 static void NVExaDoneSolid (PixmapPtr pPixmap)
168 static Bool NVExaPrepareCopy (PixmapPtr pSrcPixmap,
169 PixmapPtr pDstPixmap,
175 ScrnInfoPtr pScrn = xf86Screens[pSrcPixmap->drawable.pScreen->myNum];
176 NVPtr pNv = NVPTR(pScrn);
177 CARD32 srcPitch, dstPitch;
179 planemask |= ~0 << pNv->CurrentLayout.depth;
181 NVSetRopSolid(pScrn, alu, planemask);
183 dstPitch = getPitch(&pDstPixmap->drawable);
184 srcPitch = getPitch(&pSrcPixmap->drawable);
185 NVDmaStart(pNv, NvSubContextSurfaces, SURFACE_PITCH, 3);
186 NVDmaNext (pNv, (dstPitch<<16)|srcPitch);
187 NVDmaNext (pNv, getOffset(pNv, &pSrcPixmap->drawable));
188 NVDmaNext (pNv, getOffset(pNv, &pDstPixmap->drawable));
190 pNv->DMAKickoffCallback = NVDMAKickoffCallback;
194 static void NVExaCopy (PixmapPtr pDstPixmap,
202 ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
203 NVPtr pNv = NVPTR(pScrn);
205 NVDmaStart(pNv, NvSubImageBlit, BLIT_POINT_SRC, 3);
206 NVDmaNext (pNv, (srcY << 16) | srcX);
207 NVDmaNext (pNv, (dstY << 16) | dstX);
208 NVDmaNext (pNv, (height << 16) | width);
210 if((width * height) >= 512)
214 static void NVExaDoneCopy (PixmapPtr pDstPixmap) {}
216 static Bool NVDownloadFromScreen(PixmapPtr pSrc,
219 char *dst, int dst_pitch)
221 ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum];
222 NVPtr pNv = NVPTR(pScrn);
223 CARD32 offset_in, pitch_in, max_lines, line_length;
226 pitch_in = getPitch(&pSrc->drawable);
227 offset_in = getOffset(pNv, &pSrc->drawable);
228 offset_in += y*pitch_in;
229 offset_in += x * (pSrc->drawable.bitsPerPixel >> 3);
230 max_lines = 65536/dst_pitch + 1;
231 line_length = w * (pSrc->drawable.bitsPerPixel >> 3);
233 NVDmaSetObjectOnSubchannel(pNv, NvSubGraphicsToAGP, NvGraphicsToAGP);
235 NVDEBUG("NVDownloadFromScreen: x=%d, y=%d, w=%d, h=%d\n", x, y, w, h);
236 NVDEBUG(" pitch_in=%x dst_pitch=%x offset_in=%x", pitch_in, dst_pitch, offset_in);
238 NVDEBUG(" max_lines=%d, h=%d\n", max_lines, h);
239 int nlines = h > max_lines ? max_lines : h;
240 /* reset the notification object */
241 memset(pNv->Notifier0, 0xff, 0x100);
242 NVDmaStart(pNv, NvSubGraphicsToAGP, MEMFORMAT_NOTIFY, 1);
244 NVDmaStart(pNv, NvSubGraphicsToAGP, MEMFORMAT_OFFSET_IN, 8);
245 NVDmaNext (pNv, offset_in);
247 NVDmaNext (pNv, pitch_in);
248 NVDmaNext (pNv, dst_pitch);
249 NVDmaNext (pNv, line_length);
250 NVDmaNext (pNv, nlines);
251 NVDmaNext (pNv, 0x101);
254 if (!NVDmaWaitForNotifier(pNv, pNv->Notifier0)) {
259 memcpy(dst, pNv->AGPScratch->map, nlines*dst_pitch);
261 offset_in += nlines*pitch_in;
262 dst += nlines*dst_pitch;
266 NVDmaSetObjectOnSubchannel(pNv, NvSubGraphicsToAGP, NvScaledImage);
267 exaMarkSync(pSrc->drawable.pScreen);
271 static Bool NVUploadToScreen(PixmapPtr pDst,
272 int x, int y, int w, int h,
273 char *src, int src_pitch)
275 ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
276 NVPtr pNv = NVPTR(pScrn);
277 CARD32 offset_out, pitch_out, max_lines, line_length;
282 w = pDst->drawable.width;
283 h = pDst->drawable.height;
286 pitch_out = getPitch(&pDst->drawable);
287 offset_out = getOffset(pNv, &pDst->drawable);
288 offset_out += y*pitch_out;
289 offset_out += x * (pDst->drawable.bitsPerPixel >> 3);
291 max_lines = 65536/src_pitch + 1;
292 line_length = w * (pDst->drawable.bitsPerPixel >> 3);
294 NVDmaSetObjectOnSubchannel(pNv, NvSubGraphicsToAGP, NvAGPToGraphics);
296 NVDEBUG("NVUploadToScreen: x=%d, y=%d, w=%d, h=%d\n", x, y, w, h);
298 NVDEBUG(" max_lines=%d, h=%d\n", max_lines, h);
299 int nlines = h > max_lines ? max_lines : h;
300 /* reset the notification object */
301 memset(pNv->Notifier0, 0xff, 0x100);
302 memcpy(pNv->AGPScratch->map, src, nlines*src_pitch);
303 NVDmaStart(pNv, NvSubGraphicsToAGP, MEMFORMAT_NOTIFY, 1);
305 NVDmaStart(pNv, NvSubGraphicsToAGP, MEMFORMAT_OFFSET_IN, 8);
307 NVDmaNext (pNv, offset_out);
308 NVDmaNext (pNv, src_pitch);
309 NVDmaNext (pNv, pitch_out);
310 NVDmaNext (pNv, line_length);
311 NVDmaNext (pNv, nlines);
312 NVDmaNext (pNv, 0x101);
315 if (!NVDmaWaitForNotifier(pNv, pNv->Notifier0)) {
320 offset_out += nlines*pitch_out;
321 src += nlines*src_pitch;
325 NVDmaSetObjectOnSubchannel(pNv, NvSubGraphicsToAGP, NvScaledImage);
326 exaMarkSync(pDst->drawable.pScreen);
331 static Bool NVCheckComposite (int op,
332 PicturePtr pSrcPicture,
333 PicturePtr pMaskPicture,
334 PicturePtr pDstPicture)
339 /* PictOpOver doesn't work correctly. The HW command assumes non premuliplied alpha */
340 else if (op != PictOpOver && op != PictOpSrc)
342 else if (!pSrcPicture->pDrawable)
344 else if (pSrcPicture->transform || pSrcPicture->repeat)
346 else if (pSrcPicture->alphaMap || pDstPicture->alphaMap)
348 else if (pSrcPicture->format != PICT_a8r8g8b8 &&
349 pSrcPicture->format != PICT_x8r8g8b8 &&
350 pSrcPicture->format != PICT_r5g6b5)
352 else if (pDstPicture->format != PICT_a8r8g8b8 &&
353 pDstPicture->format != PICT_x8r8g8b8 &&
354 pDstPicture->format != PICT_r5g6b5)
359 static CARD32 src_size, src_pitch, src_offset;
361 static Bool NVPrepareComposite (int op,
362 PicturePtr pSrcPicture,
363 PicturePtr pMaskPicture,
364 PicturePtr pDstPicture,
369 ScrnInfoPtr pScrn = xf86Screens[pSrcPicture->pDrawable->pScreen->myNum];
370 NVPtr pNv = NVPTR(pScrn);
372 int srcFormat, dstFormat;
373 if (pSrcPicture->format == PICT_a8r8g8b8)
374 srcFormat = STRETCH_BLIT_FORMAT_A8R8G8B8;
375 else if (pSrcPicture->format == PICT_x8r8g8b8)
376 srcFormat = STRETCH_BLIT_FORMAT_X8R8G8B8;
378 srcFormat = STRETCH_BLIT_FORMAT_DEPTH16;
380 if (pDstPicture->format == PICT_a8r8g8b8)
381 dstFormat = SURFACE_FORMAT_A8R8G8B8;
382 else if (pDstPicture->format == PICT_x8r8g8b8)
383 dstFormat = SURFACE_FORMAT_X8R8G8B8;
385 dstFormat = SURFACE_FORMAT_R5G6B5;
388 NVDmaStart(pNv, NvSubContextSurfaces, SURFACE_FORMAT, 1);
389 NVDmaNext (pNv, dstFormat);
390 NVDmaNext (pNv, getPitch(pSrcPicture->pDrawable)|(getPitch(pDstPicture->pDrawable) << 16));
391 NVDmaNext (pNv, getOffset(pNv, pSrcPicture->pDrawable));
392 NVDmaNext (pNv, getOffset(pNv, pDstPicture->pDrawable));
394 NVDmaStart(pNv, NvSubScaledImage, STRETCH_BLIT_FORMAT, 2);
395 NVDmaNext (pNv, srcFormat);
396 NVDmaNext (pNv, (op == PictOpSrc) ? STRETCH_BLIT_OPERATION_COPY : STRETCH_BLIT_OPERATION_BLEND);
398 src_size = pSrcPicture->pDrawable->width | (pSrcPicture->pDrawable->height << 16);
399 src_pitch = getPitch(pSrcPicture->pDrawable)
400 | (STRETCH_BLIT_SRC_FORMAT_ORIGIN_CORNER << 16)
401 | (STRETCH_BLIT_SRC_FORMAT_FILTER_POINT_SAMPLE << 24);
402 src_offset = getOffset(pNv, pSrcPicture->pDrawable);
406 static void NVComposite (PixmapPtr pDst,
416 ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
417 NVPtr pNv = NVPTR(pScrn);
419 NVDmaStart(pNv, NvSubScaledImage, STRETCH_BLIT_CLIP_POINT, 6);
420 NVDmaNext (pNv, dstX | (dstY << 16));
421 NVDmaNext (pNv, width | (height << 16));
422 NVDmaNext (pNv, dstX | (dstY << 16));
423 NVDmaNext (pNv, width | (height << 16));
424 NVDmaNext (pNv, 1<<20);
425 NVDmaNext (pNv, 1<<20);
427 NVDmaStart(pNv, NvSubScaledImage, STRETCH_BLIT_SRC_SIZE, 4);
428 NVDmaNext (pNv, src_size);
429 NVDmaNext (pNv, src_pitch);
430 NVDmaNext (pNv, src_offset);
431 NVDmaNext (pNv, srcX | (srcY<<16));
436 static void NVDoneComposite (PixmapPtr pDst)
438 ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
439 NVPtr pNv = NVPTR(pScrn);
441 if (pNv->CurrentLayout.depth == 8)
442 format = SURFACE_FORMAT_Y8;
443 else if (pNv->CurrentLayout.depth == 16)
444 format = SURFACE_FORMAT_R5G6B5;
446 format = SURFACE_FORMAT_X8R8G8B8;
447 NVDmaStart(pNv, NvSubContextSurfaces, SURFACE_FORMAT, 1);
448 NVDmaNext (pNv, format);
449 exaMarkSync(pDst->drawable.pScreen);
452 Bool NVExaInit(ScreenPtr pScreen)
454 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
455 NVPtr pNv = NVPTR(pScrn);
457 if(!(pNv->EXADriverPtr = (ExaDriverPtr) xnfcalloc(sizeof(ExaDriverRec), 1))) {
461 pNv->EXADriverPtr->exa_major = EXA_VERSION_MAJOR;
462 pNv->EXADriverPtr->exa_minor = EXA_VERSION_MINOR;
464 pNv->EXADriverPtr->memoryBase = pNv->FB->map;
465 pNv->EXADriverPtr->offScreenBase = pScrn->virtualX*pScrn->virtualY*pScrn->depth;
466 pNv->EXADriverPtr->memorySize = pNv->FB->size;
467 pNv->EXADriverPtr->pixmapOffsetAlign = 256;
468 pNv->EXADriverPtr->pixmapPitchAlign = 64;
469 pNv->EXADriverPtr->flags = EXA_OFFSCREEN_PIXMAPS;
470 pNv->EXADriverPtr->maxX = 32768;
471 pNv->EXADriverPtr->maxY = 32768;
473 pNv->EXADriverPtr->WaitMarker = NVExaWaitMarker;
475 pNv->EXADriverPtr->PrepareCopy = NVExaPrepareCopy;
476 pNv->EXADriverPtr->Copy = NVExaCopy;
477 pNv->EXADriverPtr->DoneCopy = NVExaDoneCopy;
479 pNv->EXADriverPtr->PrepareSolid = NVExaPrepareSolid;
480 pNv->EXADriverPtr->Solid = NVExaSolid;
481 pNv->EXADriverPtr->DoneSolid = NVExaDoneSolid;
483 if (pNv->AGPScratch) {
484 pNv->EXADriverPtr->DownloadFromScreen = NVDownloadFromScreen;
485 pNv->EXADriverPtr->UploadToScreen = NVUploadToScreen;
487 /*darktama: Hard-disabled these for now, I get lockups often when
488 * starting e17 with them enabled.
490 if (0 && pNv->BlendingPossible) {
491 /* install composite hooks */
492 pNv->EXADriverPtr->CheckComposite = NVCheckComposite;
493 pNv->EXADriverPtr->PrepareComposite = NVPrepareComposite;
494 pNv->EXADriverPtr->Composite = NVComposite;
495 pNv->EXADriverPtr->DoneComposite = NVDoneComposite;
498 return exaDriverInit(pScreen, pNv->EXADriverPtr);