2 * Copyright 2003 NVIDIA, Corporation
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"
32 NVSetPattern(ScrnInfoPtr pScrn, CARD32 clr0, CARD32 clr1,
33 CARD32 pat0, CARD32 pat1)
35 NVPtr pNv = NVPTR(pScrn);
36 struct nouveau_channel *chan = pNv->chan;
37 struct nouveau_grobj *patt = pNv->NvImagePattern;
39 BEGIN_RING(chan, patt, NV04_IMAGE_PATTERN_MONOCHROME_COLOR0, 4);
40 OUT_RING (chan, clr0);
41 OUT_RING (chan, clr1);
42 OUT_RING (chan, pat0);
43 OUT_RING (chan, pat1);
47 NVSetROP(ScrnInfoPtr pScrn, CARD32 alu, CARD32 planemask)
49 NVPtr pNv = NVPTR(pScrn);
50 struct nouveau_channel *chan = pNv->chan;
51 struct nouveau_grobj *rop = pNv->NvRop;
53 if (planemask != ~0) {
54 NVSetPattern(pScrn, 0, planemask, ~0, ~0);
55 if (pNv->currentRop != (alu + 32)) {
56 BEGIN_RING(chan, rop, NV03_CONTEXT_ROP_ROP, 1);
57 OUT_RING (chan, NVROP[alu].copy_planemask);
58 pNv->currentRop = alu + 32;
61 if (pNv->currentRop != alu) {
62 if(pNv->currentRop >= 16)
63 NVSetPattern(pScrn, ~0, ~0, ~0, ~0);
64 BEGIN_RING(chan, rop, NV03_CONTEXT_ROP_ROP, 1);
65 OUT_RING (chan, NVROP[alu].copy);
66 pNv->currentRop = alu;
70 /* EXA acceleration hooks */
72 NVExaMarkSync(ScreenPtr pScreen)
78 NVExaWaitMarker(ScreenPtr pScreen, int marker)
80 /* Nothing required - synchronisation for CPU acess to buffers will
81 * be handled as required when buffers are mapped.
85 static unsigned rect_colour = 0;
87 static Bool NVExaPrepareSolid(PixmapPtr pPixmap,
92 ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
93 NVPtr pNv = NVPTR(pScrn);
94 struct nouveau_channel *chan = pNv->chan;
95 struct nouveau_grobj *surf2d = pNv->NvContextSurfaces;
96 struct nouveau_grobj *rect = pNv->NvRectangle;
97 struct nouveau_pixmap *dst = nouveau_pixmap(pPixmap);
98 unsigned int fmt, pitch, color;
100 planemask |= ~0 << pPixmap->drawable.bitsPerPixel;
101 if (planemask != ~0 || alu != GXcopy) {
102 if (pPixmap->drawable.bitsPerPixel == 32)
104 BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1);
105 OUT_RING (chan, 1); /* ROP_AND */
106 NVSetROP(pScrn, alu, planemask);
108 BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1);
109 OUT_RING (chan, 3); /* SRCCOPY */
112 if (!NVAccelGetCtxSurf2DFormatFromPixmap(pPixmap, (int*)&fmt))
114 pitch = exaGetPixmapPitch(pPixmap);
116 if (pPixmap->drawable.bitsPerPixel == 16) {
117 /* convert to 32bpp */
118 uint32_t r = (fg&0x1F) * 255 / 31;
119 uint32_t g = ((fg&0x7E0) >> 5) * 255 / 63;
120 uint32_t b = ((fg&0xF100) >> 11) * 255 / 31;
121 color = b<<16 | g<<8 | r;
125 /* When SURFACE_FORMAT_A8R8G8B8 is used with GDI_RECTANGLE_TEXT, the
126 * alpha channel gets forced to 0xFF for some reason. We're using
127 * SURFACE_FORMAT_Y32 as a workaround
129 if (fmt == NV04_CONTEXT_SURFACES_2D_FORMAT_A8R8G8B8)
130 fmt = NV04_CONTEXT_SURFACES_2D_FORMAT_Y32;
132 BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_FORMAT, 4);
133 OUT_RING (chan, fmt);
134 OUT_RING (chan, (pitch << 16) | pitch);
135 OUT_RELOCl(chan, dst->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
136 OUT_RELOCl(chan, dst->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
142 static void NVExaSolid (PixmapPtr pPixmap, int x1, int y1, int x2, int y2)
144 ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
145 NVPtr pNv = NVPTR(pScrn);
146 struct nouveau_channel *chan = pNv->chan;
147 struct nouveau_grobj *rect = pNv->NvRectangle;
151 if (chan->pushbuf->remaining < 10)
154 BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT, 1);
155 OUT_RING (chan, NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8);
156 BEGIN_RING(chan, rect, NV04_GDI_RECTANGLE_TEXT_COLOR1_A, 1);
157 OUT_RING (chan, rect_colour);
159 BEGIN_RING(chan, rect,
160 NV04_GDI_RECTANGLE_TEXT_UNCLIPPED_RECTANGLE_POINT(0), 2);
161 OUT_RING (chan, (x1 << 16) | y1);
162 OUT_RING (chan, (width << 16) | height);
164 if((width * height) >= 512)
168 static void NVExaDoneSolid (PixmapPtr pPixmap)
172 static Bool NVExaPrepareCopy(PixmapPtr pSrcPixmap,
173 PixmapPtr pDstPixmap,
179 ScrnInfoPtr pScrn = xf86Screens[pSrcPixmap->drawable.pScreen->myNum];
180 NVPtr pNv = NVPTR(pScrn);
181 struct nouveau_channel *chan = pNv->chan;
182 struct nouveau_grobj *surf2d = pNv->NvContextSurfaces;
183 struct nouveau_grobj *blit = pNv->NvImageBlit;
184 struct nouveau_pixmap *src = nouveau_pixmap(pSrcPixmap);
185 struct nouveau_pixmap *dst = nouveau_pixmap(pDstPixmap);
188 if (pSrcPixmap->drawable.bitsPerPixel !=
189 pDstPixmap->drawable.bitsPerPixel)
192 planemask |= ~0 << pDstPixmap->drawable.bitsPerPixel;
193 if (planemask != ~0 || alu != GXcopy) {
194 if (pDstPixmap->drawable.bitsPerPixel == 32)
196 BEGIN_RING(chan, blit, NV04_IMAGE_BLIT_OPERATION, 1);
197 OUT_RING (chan, 1); /* ROP_AND */
198 NVSetROP(pScrn, alu, planemask);
200 BEGIN_RING(chan, blit, NV04_IMAGE_BLIT_OPERATION, 1);
201 OUT_RING (chan, 3); /* SRCCOPY */
204 if (!NVAccelGetCtxSurf2DFormatFromPixmap(pDstPixmap, &fmt))
207 BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_FORMAT, 4);
208 OUT_RING (chan, fmt);
209 OUT_RING (chan, (exaGetPixmapPitch(pDstPixmap) << 16) |
210 (exaGetPixmapPitch(pSrcPixmap)));
211 OUT_RELOCl(chan, src->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
212 OUT_RELOCl(chan, dst->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
217 static void NVExaCopy(PixmapPtr pDstPixmap,
225 ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
226 NVPtr pNv = NVPTR(pScrn);
227 struct nouveau_channel *chan = pNv->chan;
228 struct nouveau_grobj *blit = pNv->NvImageBlit;
230 BEGIN_RING(chan, blit, NV01_IMAGE_BLIT_POINT_IN, 3);
231 OUT_RING (chan, (srcY << 16) | srcX);
232 OUT_RING (chan, (dstY << 16) | dstX);
233 OUT_RING (chan, (height << 16) | width);
235 if((width * height) >= 512)
239 static void NVExaDoneCopy (PixmapPtr pDstPixmap) {}
241 static inline Bool NVAccelMemcpyRect(char *dst, const char *src, int height,
242 int dst_pitch, int src_pitch, int line_len)
244 if ((src_pitch == line_len) && (src_pitch == dst_pitch)) {
245 memcpy(dst, src, line_len*height);
248 memcpy(dst, src, line_len);
258 NVAccelDownloadM2MF(PixmapPtr pspix, int x, int y, int w, int h,
259 char *dst, unsigned dst_pitch)
261 ScrnInfoPtr pScrn = xf86Screens[pspix->drawable.pScreen->myNum];
262 NVPtr pNv = NVPTR(pScrn);
263 struct nouveau_channel *chan = pNv->chan;
264 struct nouveau_grobj *m2mf = pNv->NvMemFormat;
265 unsigned cpp = pspix->drawable.bitsPerPixel / 8;
266 unsigned line_len = w * cpp;
267 unsigned src_pitch = 0, src_offset = 0, linear = 0;
268 struct nouveau_pixmap *nvpix = nouveau_pixmap(pspix);
270 BEGIN_RING(chan, m2mf, 0x184, 2);
271 OUT_RELOCo(chan, nvpix->bo,
272 NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
273 OUT_RELOCo(chan, pNv->GART, NOUVEAU_BO_GART | NOUVEAU_BO_WR);
275 if (!nvpix->bo->tiled) {
277 src_pitch = exaGetPixmapPitch(pspix);
278 src_offset = (y * src_pitch) + (x * cpp);
281 if (pNv->Architecture >= NV_ARCH_50) {
283 BEGIN_RING(chan, m2mf, 0x0200, 1);
286 BEGIN_RING(chan, m2mf, 0x0200, 6);
289 OUT_RING (chan, pspix->drawable.width * cpp);
290 OUT_RING (chan, pspix->drawable.height);
295 BEGIN_RING(chan, m2mf, 0x021c, 1);
302 if (h * line_len <= pNv->GART->size) {
305 line_count = pNv->GART->size / line_len;
311 if (line_count > 2047)
314 if (pNv->Architecture >= NV_ARCH_50) {
316 BEGIN_RING(chan, m2mf, 0x0218, 1);
317 OUT_RING (chan, (y << 16) | (x * cpp));
320 BEGIN_RING(chan, m2mf, 0x238, 2);
321 OUT_RELOCh(chan, nvpix->bo, src_offset,
322 NOUVEAU_BO_GART | NOUVEAU_BO_VRAM |
324 OUT_RELOCh(chan, pNv->GART, 0, NOUVEAU_BO_GART |
328 BEGIN_RING(chan, m2mf,
329 NV04_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8);
330 OUT_RELOCl(chan, nvpix->bo, src_offset, NOUVEAU_BO_GART |
331 NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
332 OUT_RELOCl(chan, pNv->GART, 0, NOUVEAU_BO_GART | NOUVEAU_BO_WR);
333 OUT_RING (chan, src_pitch);
334 OUT_RING (chan, line_len);
335 OUT_RING (chan, line_len);
336 OUT_RING (chan, line_count);
337 OUT_RING (chan, (1<<8)|1);
340 nouveau_bo_map(pNv->GART, NOUVEAU_BO_RD);
341 if (dst_pitch == line_len) {
342 memcpy(dst, pNv->GART->map, dst_pitch * line_count);
343 dst += dst_pitch * line_count;
345 const void *src = pNv->GART->map;
347 for (i = 0; i < line_count; i++) {
348 memcpy(dst, src, line_len);
353 nouveau_bo_unmap(pNv->GART);
356 src_offset += line_count * src_pitch;
365 NVExaPixmapMap(PixmapPtr pPix)
367 struct nouveau_pixmap *nvpix = nouveau_pixmap(pPix);
369 if (!nvpix || !nvpix->bo)
372 nouveau_bo_map(nvpix->bo, NOUVEAU_BO_RDWR);
373 return nvpix->bo->map;
377 NVExaPixmapUnmap(PixmapPtr pPix)
379 struct nouveau_pixmap *nvpix = nouveau_pixmap(pPix);
381 if (!nvpix || !nvpix->bo)
384 nouveau_bo_unmap(nvpix->bo);
387 static Bool NVDownloadFromScreen(PixmapPtr pSrc,
390 char *dst, int dst_pitch)
392 ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum];
393 NVPtr pNv = NVPTR(pScrn);
394 int src_pitch, cpp, offset;
397 src_pitch = exaGetPixmapPitch(pSrc);
398 cpp = pSrc->drawable.bitsPerPixel >> 3;
399 offset = (y * src_pitch) + (x * cpp);
402 if (NVAccelDownloadM2MF(pSrc, x, y, w, h, dst, dst_pitch))
406 src = NVExaPixmapMap(pSrc);
410 exaWaitSync(pSrc->drawable.pScreen);
411 if (NVAccelMemcpyRect(dst, src, h, dst_pitch, src_pitch, w*cpp)) {
412 NVExaPixmapUnmap(pSrc);
415 NVExaPixmapUnmap(pSrc);
421 NVAccelUploadIFC(ScrnInfoPtr pScrn, const char *src, int src_pitch,
422 PixmapPtr pDst, int x, int y, int w, int h, int cpp)
424 NVPtr pNv = NVPTR(pScrn);
425 struct nouveau_channel *chan = pNv->chan;
426 struct nouveau_grobj *surf2d = pNv->NvContextSurfaces;
427 struct nouveau_grobj *clip = pNv->NvClipRectangle;
428 struct nouveau_grobj *ifc = pNv->NvImageFromCpu;
429 struct nouveau_pixmap *dst = nouveau_pixmap(pDst);
430 int line_len = w * cpp;
431 int iw, id, surf_fmt, ifc_fmt;
434 if (pNv->Architecture >= NV_ARCH_50)
444 case 2: ifc_fmt = 1; break;
445 case 4: ifc_fmt = 4; break;
450 if (!NVAccelGetCtxSurf2DFormatFromPixmap(pDst, &surf_fmt))
453 BEGIN_RING(chan, surf2d, NV04_CONTEXT_SURFACES_2D_FORMAT, 4);
454 OUT_RING (chan, surf_fmt);
455 OUT_RING (chan, (exaGetPixmapPitch(pDst) << 16) | exaGetPixmapPitch(pDst));
456 OUT_RELOCl(chan, dst->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
457 OUT_RELOCl(chan, dst->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
459 /* Pad out input width to cover both COLORA() and COLORB() */
460 iw = (line_len + 7) & ~7;
461 padbytes = iw - line_len;
462 id = iw / 4; /* line push size */
465 /* Don't support lines longer than max push size yet.. */
469 BEGIN_RING(chan, clip, NV01_CONTEXT_CLIP_RECTANGLE_POINT, 2);
470 OUT_RING (chan, 0x0);
471 OUT_RING (chan, 0x7FFF7FFF);
473 BEGIN_RING(chan, ifc, NV01_IMAGE_FROM_CPU_OPERATION, 2);
474 OUT_RING (chan, NV01_IMAGE_FROM_CPU_OPERATION_SRCCOPY);
475 OUT_RING (chan, ifc_fmt);
481 RING_SPACE(chan, 5 + id);
482 BEGIN_RING(chan, ifc, NV01_IMAGE_FROM_CPU_POINT, 3);
483 OUT_RING (chan, (y++ << 16) | x); /* dst point */
484 OUT_RING (chan, (1 << 16) | w); /* width/height out */
485 OUT_RING (chan, (1 << 16) | iw); /* width/height in */
486 BEGIN_RING(chan, ifc, NV01_IMAGE_FROM_CPU_COLOR(0), id);
487 OUT_RINGp (chan, src, id);
493 int aux = (padbytes + 7) >> 2;
494 RING_SPACE(chan, 5 + id + 1);
495 BEGIN_RING(chan, ifc, NV01_IMAGE_FROM_CPU_POINT, 3);
496 OUT_RING (chan, (y++ << 16) | x); /* dst point */
497 OUT_RING (chan, (1 << 16) | w); /* width/height out */
498 OUT_RING (chan, (1 << 16) | iw); /* width/height in */
499 BEGIN_RING(chan, ifc, NV01_IMAGE_FROM_CPU_COLOR(0), id);
500 OUT_RINGp (chan, src, id - aux);
501 memcpy(padding, src + (id - aux) * 4, padbytes);
502 OUT_RINGp (chan, padding, aux);
509 NVAccelUploadM2MF(PixmapPtr pdpix, int x, int y, int w, int h,
510 const char *src, int src_pitch)
512 ScrnInfoPtr pScrn = xf86Screens[pdpix->drawable.pScreen->myNum];
513 NVPtr pNv = NVPTR(pScrn);
514 struct nouveau_channel *chan = pNv->chan;
515 struct nouveau_grobj *m2mf = pNv->NvMemFormat;
516 unsigned cpp = pdpix->drawable.bitsPerPixel / 8;
517 unsigned line_len = w * cpp;
518 unsigned dst_pitch = 0, dst_offset = 0, linear = 0;
519 struct nouveau_pixmap *nvpix = nouveau_pixmap(pdpix);
521 if (!nvpix || !nvpix->bo)
524 BEGIN_RING(chan, m2mf, 0x184, 2);
525 OUT_RELOCo(chan, pNv->GART, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
526 OUT_RELOCo(chan, nvpix->bo,
527 NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_WR);
529 if (!nvpix->bo->tiled) {
531 dst_pitch = exaGetPixmapPitch(pdpix);
532 dst_offset = (y * dst_pitch) + (x * cpp);
535 if (pNv->Architecture >= NV_ARCH_50) {
536 BEGIN_RING(chan, m2mf, 0x0200, 1);
540 BEGIN_RING(chan, m2mf, 0x021c, 1);
543 BEGIN_RING(chan, m2mf, 0x021c, 6);
546 OUT_RING (chan, pdpix->drawable.width * cpp);
547 OUT_RING (chan, pdpix->drawable.height);
556 /* Determine max amount of data we can DMA at once */
557 if (h * line_len <= pNv->GART->size) {
560 line_count = pNv->GART->size / line_len;
566 if (line_count > 2047)
570 nouveau_bo_map(pNv->GART, NOUVEAU_BO_WR);
571 if (src_pitch == line_len) {
572 memcpy(pNv->GART->map, src, src_pitch * line_count);
573 src += src_pitch * line_count;
575 void *dst = pNv->GART->map;
577 for (i = 0; i < line_count; i++) {
578 memcpy(dst, src, line_len);
583 nouveau_bo_unmap(pNv->GART);
585 if (pNv->Architecture >= NV_ARCH_50) {
587 BEGIN_RING(chan, m2mf, 0x0234, 1);
588 OUT_RING (chan, (y << 16) | (x * cpp));
591 BEGIN_RING(chan, m2mf, 0x0238, 2);
592 OUT_RELOCh(chan, pNv->GART, 0, NOUVEAU_BO_GART |
594 OUT_RELOCh(chan, nvpix->bo, dst_offset,
595 NOUVEAU_BO_VRAM | NOUVEAU_BO_GART |
600 BEGIN_RING(chan, m2mf,
601 NV04_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8);
602 OUT_RELOCl(chan, pNv->GART, 0, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
603 OUT_RELOCl(chan, nvpix->bo, dst_offset, NOUVEAU_BO_VRAM |
604 NOUVEAU_BO_GART | NOUVEAU_BO_WR);
605 OUT_RING (chan, line_len);
606 OUT_RING (chan, dst_pitch);
607 OUT_RING (chan, line_len);
608 OUT_RING (chan, line_count);
609 OUT_RING (chan, (1<<8)|1);
613 dst_offset += line_count * dst_pitch;
621 static Bool NVUploadToScreen(PixmapPtr pDst,
622 int x, int y, int w, int h,
623 char *src, int src_pitch)
625 ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
626 NVPtr pNv = NVPTR(pScrn);
630 dst_pitch = exaGetPixmapPitch(pDst);
631 cpp = pDst->drawable.bitsPerPixel >> 3;
633 /* try hostdata transfer */
634 if (w * h * cpp < 16*1024) /* heuristic */
636 if (pNv->Architecture < NV_ARCH_50) {
637 if (NVAccelUploadIFC(pScrn, src, src_pitch, pDst,
639 exaMarkSync(pDst->drawable.pScreen);
643 if (NV50EXAUploadSIFC(src, src_pitch, pDst,
645 exaMarkSync(pDst->drawable.pScreen);
651 /* try gart-based transfer */
653 if (NVAccelUploadM2MF(pDst, x, y, w, h, src, src_pitch)) {
654 exaMarkSync(pDst->drawable.pScreen);
659 /* fallback to memcpy-based transfer */
660 dst = NVExaPixmapMap(pDst);
663 dst += (y * dst_pitch) + (x * cpp);
664 exaWaitSync(pDst->drawable.pScreen);
665 if (NVAccelMemcpyRect(dst, src, h, dst_pitch, src_pitch, w*cpp)) {
666 NVExaPixmapUnmap(pDst);
669 NVExaPixmapUnmap(pDst);
675 NVExaPrepareAccess(PixmapPtr pPix, int index)
677 ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum];
678 NVPtr pNv = NVPTR(pScrn);
679 struct nouveau_pixmap *nvpix;
682 nvpix = exaGetPixmapDriverPrivate(pPix);
683 if (!nvpix || !nvpix->bo)
686 if (!nvpix->bo->map) {
687 if (nouveau_bo_map(nvpix->bo, NOUVEAU_BO_RDWR))
691 pPix->devPrivate.ptr = nvpix->bo->map;
696 NVExaFinishAccess(PixmapPtr pPix, int index)
698 ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum];
699 NVPtr pNv = NVPTR(pScrn);
700 struct nouveau_pixmap *nvpix;
703 nvpix = exaGetPixmapDriverPrivate(pPix);
704 if (!nvpix || !nvpix->bo)
707 nouveau_bo_unmap(nvpix->bo);
708 pPix->devPrivate.ptr = NULL;
712 NVExaPixmapIsOffscreen(PixmapPtr pPix)
714 ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum];
715 NVPtr pNv = NVPTR(pScrn);
716 struct nouveau_pixmap *nvpix;
719 nvpix = exaGetPixmapDriverPrivate(pPix);
720 if (!nvpix || !nvpix->bo)
727 NVExaCreatePixmap(ScreenPtr pScreen, int size, int align)
729 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
730 NVPtr pNv = NVPTR(pScrn);
731 struct nouveau_pixmap *nvpix;
733 nvpix = xcalloc(1, sizeof(struct nouveau_pixmap));
738 uint32_t flags = NOUVEAU_BO_VRAM;
740 if (pNv->Architecture >= NV_ARCH_50)
741 flags |= NOUVEAU_BO_TILED;
743 if (nouveau_bo_new(pNv->dev, flags, 0, size,
754 NVExaDestroyPixmap(ScreenPtr pScreen, void *driverPriv)
756 struct nouveau_pixmap *nvpix = driverPriv;
761 nouveau_bo_ref(NULL, &nvpix->bo);
766 NVExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth,
767 int bitsPerPixel, int devKind, pointer pPixData)
769 ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
770 NVPtr pNv = NVPTR(pScrn);
771 struct nouveau_pixmap *nvpix;
773 if (pPixData == pNv->FBMap) {
774 nvpix = exaGetPixmapDriverPrivate(pPixmap);
778 if (nouveau_bo_ref(pNv->FB, &nvpix->bo))
781 miModifyPixmapHeader(pPixmap, width, height, depth,
782 bitsPerPixel, devKind, NULL);
790 NVExaPixmapIsOnscreen(PixmapPtr pPixmap)
792 ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
793 NVPtr pNv = NVPTR(pScrn);
794 struct nouveau_pixmap *nvpix;
796 nvpix = exaGetPixmapDriverPrivate(pPixmap);
797 if (nvpix && nvpix->bo == pNv->FB)
804 NVExaInit(ScreenPtr pScreen)
806 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
807 NVPtr pNv = NVPTR(pScrn);
809 pNv->EXADriverPtr = exaDriverAlloc();
810 if (!pNv->EXADriverPtr) {
815 pNv->EXADriverPtr->exa_major = EXA_VERSION_MAJOR;
816 pNv->EXADriverPtr->exa_minor = EXA_VERSION_MINOR;
817 pNv->EXADriverPtr->flags = EXA_OFFSCREEN_PIXMAPS | EXA_HANDLES_PIXMAPS;
819 pNv->EXADriverPtr->pixmapOffsetAlign = 256;
820 pNv->EXADriverPtr->pixmapPitchAlign = 64;
822 pNv->EXADriverPtr->PrepareAccess = NVExaPrepareAccess;
823 pNv->EXADriverPtr->FinishAccess = NVExaFinishAccess;
824 pNv->EXADriverPtr->PixmapIsOffscreen = NVExaPixmapIsOffscreen;
825 pNv->EXADriverPtr->CreatePixmap = NVExaCreatePixmap;
826 pNv->EXADriverPtr->DestroyPixmap = NVExaDestroyPixmap;
827 pNv->EXADriverPtr->ModifyPixmapHeader = NVExaModifyPixmapHeader;
829 if (pNv->Architecture >= NV_ARCH_50) {
830 pNv->EXADriverPtr->maxX = 8192;
831 pNv->EXADriverPtr->maxY = 8192;
833 if (pNv->Architecture >= NV_ARCH_20) {
834 pNv->EXADriverPtr->maxX = 4096;
835 pNv->EXADriverPtr->maxY = 4096;
837 pNv->EXADriverPtr->maxX = 2048;
838 pNv->EXADriverPtr->maxY = 2048;
841 pNv->EXADriverPtr->MarkSync = NVExaMarkSync;
842 pNv->EXADriverPtr->WaitMarker = NVExaWaitMarker;
844 /* Install default hooks */
845 pNv->EXADriverPtr->DownloadFromScreen = NVDownloadFromScreen;
846 pNv->EXADriverPtr->UploadToScreen = NVUploadToScreen;
848 if (pNv->Architecture < NV_ARCH_50) {
849 pNv->EXADriverPtr->PrepareCopy = NVExaPrepareCopy;
850 pNv->EXADriverPtr->Copy = NVExaCopy;
851 pNv->EXADriverPtr->DoneCopy = NVExaDoneCopy;
853 pNv->EXADriverPtr->PrepareSolid = NVExaPrepareSolid;
854 pNv->EXADriverPtr->Solid = NVExaSolid;
855 pNv->EXADriverPtr->DoneSolid = NVExaDoneSolid;
857 pNv->EXADriverPtr->PrepareCopy = NV50EXAPrepareCopy;
858 pNv->EXADriverPtr->Copy = NV50EXACopy;
859 pNv->EXADriverPtr->DoneCopy = NV50EXADoneCopy;
861 pNv->EXADriverPtr->PrepareSolid = NV50EXAPrepareSolid;
862 pNv->EXADriverPtr->Solid = NV50EXASolid;
863 pNv->EXADriverPtr->DoneSolid = NV50EXADoneSolid;
866 switch (pNv->Architecture) {
869 pNv->EXADriverPtr->CheckComposite = NV10CheckComposite;
870 pNv->EXADriverPtr->PrepareComposite = NV10PrepareComposite;
871 pNv->EXADriverPtr->Composite = NV10Composite;
872 pNv->EXADriverPtr->DoneComposite = NV10DoneComposite;
875 pNv->EXADriverPtr->CheckComposite = NV30EXACheckComposite;
876 pNv->EXADriverPtr->PrepareComposite = NV30EXAPrepareComposite;
877 pNv->EXADriverPtr->Composite = NV30EXAComposite;
878 pNv->EXADriverPtr->DoneComposite = NV30EXADoneComposite;
881 pNv->EXADriverPtr->CheckComposite = NV40EXACheckComposite;
882 pNv->EXADriverPtr->PrepareComposite = NV40EXAPrepareComposite;
883 pNv->EXADriverPtr->Composite = NV40EXAComposite;
884 pNv->EXADriverPtr->DoneComposite = NV40EXADoneComposite;
887 pNv->EXADriverPtr->CheckComposite = NV50EXACheckComposite;
888 pNv->EXADriverPtr->PrepareComposite = NV50EXAPrepareComposite;
889 pNv->EXADriverPtr->Composite = NV50EXAComposite;
890 pNv->EXADriverPtr->DoneComposite = NV50EXADoneComposite;
896 if (!exaDriverInit(pScreen, pNv->EXADriverPtr))