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"
31
const int NVCopyROP[16] =
35
0x44, /* GXandReverse */
37
0x22, /* GXandInverted */
44
0xDD, /* GXorReverse */
45
0x33, /* GXcopyInverted */
46
0xBB, /* GXorInverted */
52
NVSetPattern(ScrnInfoPtr pScrn, CARD32 clr0, CARD32 clr1,
53
CARD32 pat0, CARD32 pat1)
55
NVPtr pNv = NVPTR(pScrn);
57
BEGIN_RING(NvImagePattern, NV04_IMAGE_PATTERN_MONOCHROME_COLOR0, 4);
65
NVSetROP(ScrnInfoPtr pScrn, CARD32 alu, CARD32 planemask)
67
NVPtr pNv = NVPTR(pScrn);
68
int rop = NVCopyROP[alu] & 0xf0;
70
if (planemask != ~0) {
71
NVSetPattern(pScrn, 0, planemask, ~0, ~0);
72
if (pNv->currentRop != (alu + 32)) {
73
BEGIN_RING(NvRop, NV03_CONTEXT_ROP_ROP, 1);
74
OUT_RING (rop | 0x0a);
75
pNv->currentRop = alu + 32;
78
if (pNv->currentRop != alu) {
79
if(pNv->currentRop >= 16)
80
NVSetPattern(pScrn, ~0, ~0, ~0, ~0);
81
BEGIN_RING(NvRop, NV03_CONTEXT_ROP_ROP, 1);
82
OUT_RING (rop | (rop >> 4));
83
pNv->currentRop = alu;
87
static CARD32 rectFormat(DrawablePtr pDrawable)
89
switch(pDrawable->bitsPerPixel) {
92
return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8;
95
return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A16R5G6B5;
98
return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8;
103
/* EXA acceleration hooks */
104
static void NVExaWaitMarker(ScreenPtr pScreen, int marker)
106
NVSync(xf86Screens[pScreen->myNum]);
109
static Bool NVExaPrepareSolid(PixmapPtr pPixmap,
114
ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
115
NVPtr pNv = NVPTR(pScrn);
116
unsigned int fmt, pitch;
118
planemask |= ~0 << pPixmap->drawable.bitsPerPixel;
119
if (planemask != ~0 || alu != GXcopy) {
120
if (pPixmap->drawable.bitsPerPixel == 32)
122
BEGIN_RING(NvRectangle, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1);
123
OUT_RING (1); /* ROP_AND */
124
NVSetROP(pScrn, alu, planemask);
126
BEGIN_RING(NvRectangle, NV04_GDI_RECTANGLE_TEXT_OPERATION, 1);
127
OUT_RING (3); /* SRCCOPY */
130
if (!NVAccelGetCtxSurf2DFormatFromPixmap(pPixmap, (int*)&fmt))
132
pitch = exaGetPixmapPitch(pPixmap);
134
/* When SURFACE_FORMAT_A8R8G8B8 is used with GDI_RECTANGLE_TEXT, the
135
* alpha channel gets forced to 0xFF for some reason. We're using
136
* SURFACE_FORMAT_Y32 as a workaround
138
if (fmt == NV04_CONTEXT_SURFACES_2D_FORMAT_A8R8G8B8)
139
fmt = NV04_CONTEXT_SURFACES_2D_FORMAT_Y32;
141
BEGIN_RING(NvContextSurfaces, NV04_CONTEXT_SURFACES_2D_FORMAT, 4);
143
OUT_RING ((pitch << 16) | pitch);
144
OUT_PIXMAPl(pPixmap, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
145
OUT_PIXMAPl(pPixmap, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
147
BEGIN_RING(NvRectangle, NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT, 1);
148
OUT_RING (rectFormat(&pPixmap->drawable));
149
BEGIN_RING(NvRectangle, NV04_GDI_RECTANGLE_TEXT_COLOR1_A, 1);
155
static void NVExaSolid (PixmapPtr pPixmap, int x1, int y1, int x2, int y2)
157
ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
158
NVPtr pNv = NVPTR(pScrn);
162
BEGIN_RING(NvRectangle,
163
NV04_GDI_RECTANGLE_TEXT_UNCLIPPED_RECTANGLE_POINT(0), 2);
164
OUT_RING ((x1 << 16) | y1);
165
OUT_RING ((width << 16) | height);
167
if((width * height) >= 512)
171
static void NVExaDoneSolid (PixmapPtr pPixmap)
175
static Bool NVExaPrepareCopy(PixmapPtr pSrcPixmap,
176
PixmapPtr pDstPixmap,
182
ScrnInfoPtr pScrn = xf86Screens[pSrcPixmap->drawable.pScreen->myNum];
183
NVPtr pNv = NVPTR(pScrn);
186
if (pSrcPixmap->drawable.bitsPerPixel !=
187
pDstPixmap->drawable.bitsPerPixel)
190
planemask |= ~0 << pDstPixmap->drawable.bitsPerPixel;
191
if (planemask != ~0 || alu != GXcopy) {
192
if (pDstPixmap->drawable.bitsPerPixel == 32)
194
BEGIN_RING(NvImageBlit, NV04_IMAGE_BLIT_OPERATION, 1);
195
OUT_RING (1); /* ROP_AND */
196
NVSetROP(pScrn, alu, planemask);
198
BEGIN_RING(NvImageBlit, NV04_IMAGE_BLIT_OPERATION, 1);
199
OUT_RING (3); /* SRCCOPY */
202
if (!NVAccelGetCtxSurf2DFormatFromPixmap(pDstPixmap, &fmt))
205
BEGIN_RING(NvContextSurfaces, NV04_CONTEXT_SURFACES_2D_FORMAT, 4);
207
OUT_RING ((exaGetPixmapPitch(pDstPixmap) << 16) |
208
(exaGetPixmapPitch(pSrcPixmap)));
209
OUT_PIXMAPl(pSrcPixmap, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
210
OUT_PIXMAPl(pDstPixmap, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
215
static void NVExaCopy(PixmapPtr pDstPixmap,
223
ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
224
NVPtr pNv = NVPTR(pScrn);
226
/* We want to catch people who have this bug, to find a decent fix */
228
/* Now check whether we have the same values for srcY and dstY and
229
whether the used chipset is buggy. Currently we flag all of G70
230
cards as buggy, which is probably much to broad. KoalaBR
231
16 is an abritrary threshold. It should define the maximum number
232
of lines between dstY and srcY If the number of lines is below
233
we guess, that the bug won't trigger...
235
if ( ((abs(srcY - dstY)< 16)||(abs(srcX-dstX)<16)) &&
236
((((pNv->Chipset & 0xfff0) == CHIPSET_G70) ||
237
((pNv->Chipset & 0xfff0) == CHIPSET_G71) ||
238
((pNv->Chipset & 0xfff0) == CHIPSET_G72) ||
239
((pNv->Chipset & 0xfff0) == CHIPSET_G73) ||
240
((pNv->Chipset & 0xfff0) == CHIPSET_C512))) )
242
int dx=abs(srcX - dstX),dy=abs(srcY - dstY);
243
// Ok, let's do it manually unless someone comes up with a better idea
244
// 1. If dstY and srcY are really the same, do a copy rowwise
247
NVDEBUG("ExaCopy: Lines identical:\n");
255
for (i = 0; i < width; i++) {
256
BEGIN_RING(NvImageBlit,
257
NV_IMAGE_BLIT_POINT_IN, 3);
258
OUT_RING ((srcY << 16) | (srcX+xpos));
259
OUT_RING ((dstY << 16) | (dstX+xpos));
260
OUT_RING ((height << 16) | 1);
264
// 2. Otherwise we will try a line by line copy in the hope to avoid
267
NVDEBUG("ExaCopy: Lines nearly the same srcY=%d, dstY=%d:\n", srcY, dstY);
275
for (i = 0; i < height; i++) {
276
BEGIN_RING(NvImageBlit,
277
NV_IMAGE_BLIT_POINT_IN, 3);
278
OUT_RING (((srcY+ypos) << 16) | srcX);
279
OUT_RING (((dstY+ypos) << 16) | dstX);
280
OUT_RING ((1 << 16) | width);
285
NVDEBUG("ExaCopy: Using default path\n");
286
BEGIN_RING(NvImageBlit, NV_IMAGE_BLIT_POINT_IN, 3);
287
OUT_RING ((srcY << 16) | srcX);
288
OUT_RING ((dstY << 16) | dstX);
289
OUT_RING ((height << 16) | width);
293
NVDEBUG("ExaCopy: Using default path\n");
294
BEGIN_RING(NvImageBlit, NV01_IMAGE_BLIT_POINT_IN, 3);
295
OUT_RING ((srcY << 16) | srcX);
296
OUT_RING ((dstY << 16) | dstX);
297
OUT_RING ((height << 16) | width);
299
if((width * height) >= 512)
303
static void NVExaDoneCopy (PixmapPtr pDstPixmap) {}
305
static inline Bool NVAccelMemcpyRect(char *dst, const char *src, int height,
306
int dst_pitch, int src_pitch, int line_len)
308
if ((src_pitch == line_len) && (src_pitch == dst_pitch)) {
309
memcpy(dst, src, line_len*height);
312
memcpy(dst, src, line_len);
322
NVAccelDownloadM2MF(ScrnInfoPtr pScrn, char *dst, PixmapPtr pspix,
323
uint32_t src_offset, int dst_pitch, int src_pitch,
324
int line_len, int line_count)
326
NVPtr pNv = NVPTR(pScrn);
328
BEGIN_RING(NvMemFormat, 0x184, 2);
329
OUT_PIXMAPo(pspix, NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
330
OUT_RELOCo(pNv->GART, NOUVEAU_BO_GART | NOUVEAU_BO_WR);
333
char *src = pNv->GART->map;
336
if (line_count * line_len <= pNv->GART->size) {
339
lc = pNv->GART->size / line_len;
348
if (pNv->Architecture >= NV_ARCH_50) {
349
BEGIN_RING(NvMemFormat, 0x200, 1);
351
BEGIN_RING(NvMemFormat, 0x21c, 1);
353
/* probably high-order bits of address */
354
BEGIN_RING(NvMemFormat, 0x238, 2);
355
OUT_PIXMAPh(pspix, src_offset, NOUVEAU_BO_GART |
356
NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
357
OUT_RELOCh(pNv->GART, 0, NOUVEAU_BO_GART |
361
BEGIN_RING(NvMemFormat,
362
NV04_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8);
363
OUT_PIXMAPl(pspix, src_offset, NOUVEAU_BO_GART |
364
NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
365
OUT_RELOCl(pNv->GART, 0, NOUVEAU_BO_GART | NOUVEAU_BO_WR);
366
OUT_RING (src_pitch);
373
nouveau_notifier_reset(pNv->notify0, 0);
374
BEGIN_RING(NvMemFormat, NV04_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1);
376
BEGIN_RING(NvMemFormat, 0x100, 1);
379
if (nouveau_notifier_wait_status(pNv->notify0, 0, 0,
383
if (dst_pitch == line_len) {
384
memcpy(dst, src, dst_pitch * lc);
385
dst += dst_pitch * lc;
387
for (i = 0; i < lc; i++) {
388
memcpy(dst, src, line_len);
395
src_offset += lc * src_pitch;
402
NVExaPixmapMap(PixmapPtr pPix)
405
#if NOUVEAU_EXA_PIXMAPS
406
struct nouveau_pixmap *nvpix;
408
nvpix = exaGetPixmapDriverPrivate(pPix);
409
if (!nvpix || !nvpix->bo)
412
map = nvpix->bo->map;
414
ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum];
415
NVPtr pNv = NVPTR(pScrn);
416
map = pNv->FB->map + exaGetPixmapOffset(pPix);
417
#endif /* NOUVEAU_EXA_PIXMAPS */
421
static Bool NVDownloadFromScreen(PixmapPtr pSrc,
424
char *dst, int dst_pitch)
426
ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum];
427
NVPtr pNv = NVPTR(pScrn);
428
int src_pitch, cpp, offset;
431
src_pitch = exaGetPixmapPitch(pSrc);
432
cpp = pSrc->drawable.bitsPerPixel >> 3;
433
offset = (y * src_pitch) + (x * cpp);
436
if (NVAccelDownloadM2MF(pScrn, dst, pSrc, offset,
437
dst_pitch, src_pitch, w * cpp, h))
441
src = NVExaPixmapMap(pSrc);
445
exaWaitSync(pSrc->drawable.pScreen);
446
if (NVAccelMemcpyRect(dst, src, h, dst_pitch, src_pitch, w*cpp))
453
NVAccelUploadIFC(ScrnInfoPtr pScrn, const char *src, int src_pitch,
454
PixmapPtr pDst, int x, int y, int w, int h, int cpp)
456
NVPtr pNv = NVPTR(pScrn);
457
int line_len = w * cpp;
458
int iw, id, surf_fmt, ifc_fmt;
461
if (pNv->Architecture >= NV_ARCH_50)
468
case 2: ifc_fmt = 1; break;
469
case 4: ifc_fmt = 4; break;
474
if (!NVAccelGetCtxSurf2DFormatFromPixmap(pDst, &surf_fmt))
477
BEGIN_RING(NvContextSurfaces, NV04_CONTEXT_SURFACES_2D_FORMAT, 4);
479
OUT_RING ((exaGetPixmapPitch(pDst) << 16) | exaGetPixmapPitch(pDst));
480
OUT_PIXMAPl(pDst, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
481
OUT_PIXMAPl(pDst, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
483
/* Pad out input width to cover both COLORA() and COLORB() */
484
iw = (line_len + 7) & ~7;
485
padbytes = iw - line_len;
486
id = iw / 4; /* line push size */
489
/* Don't support lines longer than max push size yet.. */
493
BEGIN_RING(NvClipRectangle, NV01_CONTEXT_CLIP_RECTANGLE_POINT, 2);
495
OUT_RING (0x7FFF7FFF);
497
BEGIN_RING(NvImageFromCpu, NV01_IMAGE_FROM_CPU_OPERATION, 2);
498
OUT_RING (NV01_IMAGE_FROM_CPU_OPERATION_SRCCOPY);
500
BEGIN_RING(NvImageFromCpu, NV01_IMAGE_FROM_CPU_POINT, 3);
501
OUT_RING ((y << 16) | x); /* dst point */
502
OUT_RING ((h << 16) | w); /* width/height out */
503
OUT_RING ((h << 16) | iw); /* width/height in */
509
BEGIN_RING(NvImageFromCpu, NV01_IMAGE_FROM_CPU_COLOR(0), id);
516
int aux = (padbytes + 7) >> 2;
517
BEGIN_RING(NvImageFromCpu, NV01_IMAGE_FROM_CPU_COLOR(0), id);
518
OUT_RINGp (src, id - aux);
519
memcpy(padding, src + (id - aux) * 4, padbytes);
520
OUT_RINGp (padding, aux);
527
NVAccelUploadM2MF(ScrnInfoPtr pScrn, PixmapPtr pdpix, uint32_t dst_offset,
528
const char *src, int dst_pitch, int src_pitch,
529
int line_len, int line_count)
531
NVPtr pNv = NVPTR(pScrn);
533
BEGIN_RING(NvMemFormat, 0x184, 2);
534
OUT_RELOCo(pNv->GART, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
535
OUT_PIXMAPo(pdpix, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_WR);
538
char *dst = pNv->GART->map;
541
/* Determine max amount of data we can DMA at once */
542
if (line_count * line_len <= pNv->GART->size) {
545
lc = pNv->GART->size / line_len;
555
if (src_pitch == line_len) {
556
memcpy(dst, src, src_pitch * lc);
557
src += src_pitch * lc;
559
for (i = 0; i < lc; i++) {
560
memcpy(dst, src, line_len);
566
if (pNv->Architecture >= NV_ARCH_50) {
567
BEGIN_RING(NvMemFormat, 0x200, 1);
569
BEGIN_RING(NvMemFormat, 0x21c, 1);
571
/* probably high-order bits of address */
572
BEGIN_RING(NvMemFormat, 0x238, 2);
573
OUT_RELOCh(pNv->GART, 0, NOUVEAU_BO_GART |
575
OUT_PIXMAPh(pdpix, 0, NOUVEAU_BO_VRAM |
576
NOUVEAU_BO_GART | NOUVEAU_BO_WR);
580
BEGIN_RING(NvMemFormat,
581
NV04_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8);
582
OUT_RELOCl(pNv->GART, 0, NOUVEAU_BO_GART | NOUVEAU_BO_RD);
583
OUT_PIXMAPl(pdpix, dst_offset, NOUVEAU_BO_VRAM |
584
NOUVEAU_BO_GART | NOUVEAU_BO_WR);
586
OUT_RING (dst_pitch);
592
nouveau_notifier_reset(pNv->notify0, 0);
593
BEGIN_RING(NvMemFormat, NV04_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1);
595
BEGIN_RING(NvMemFormat, 0x100, 1);
598
if (nouveau_notifier_wait_status(pNv->notify0, 0, 0, 2000))
601
dst_offset += lc * dst_pitch;
608
static Bool NVUploadToScreen(PixmapPtr pDst,
609
int x, int y, int w, int h,
610
char *src, int src_pitch)
612
ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
613
NVPtr pNv = NVPTR(pScrn);
617
dst_pitch = exaGetPixmapPitch(pDst);
618
cpp = pDst->drawable.bitsPerPixel >> 3;
620
/* try hostdata transfer */
621
if (w * h * cpp < 16*1024) /* heuristic */
623
if (pNv->Architecture < NV_ARCH_50) {
624
if (NVAccelUploadIFC(pScrn, src, src_pitch, pDst,
626
exaMarkSync(pDst->drawable.pScreen);
630
if (NV50EXAUploadSIFC(pScrn, src, src_pitch, pDst,
632
exaMarkSync(pDst->drawable.pScreen);
638
/* try gart-based transfer */
640
if (NVAccelUploadM2MF(pScrn, pDst, (y * dst_pitch) + (x * cpp),
641
src, dst_pitch, src_pitch, w * cpp, h))
645
/* fallback to memcpy-based transfer */
646
dst = NVExaPixmapMap(pDst);
649
dst += (y * dst_pitch) + (x * cpp);
650
exaWaitSync(pDst->drawable.pScreen);
651
if (NVAccelMemcpyRect(dst, src, h, dst_pitch, src_pitch, w*cpp))
657
#if NOUVEAU_EXA_PIXMAPS
659
NVExaPrepareAccess(PixmapPtr pPix, int index)
661
ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum];
662
NVPtr pNv = NVPTR(pScrn);
663
struct nouveau_pixmap *nvpix;
666
nvpix = exaGetPixmapDriverPrivate(pPix);
667
if (!nvpix || !nvpix->bo)
670
/*XXX: ho hum.. sync if needed */
675
if (nouveau_bo_map(nvpix->bo, NOUVEAU_BO_RDWR))
677
pPix->devPrivate.ptr = nvpix->bo->map;
678
nvpix->mapped = TRUE;
683
NVExaFinishAccess(PixmapPtr pPix, int index)
685
ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum];
686
NVPtr pNv = NVPTR(pScrn);
687
struct nouveau_pixmap *nvpix;
690
nvpix = exaGetPixmapDriverPrivate(pPix);
691
if (!nvpix || !nvpix->bo || !nvpix->mapped)
694
nouveau_bo_unmap(nvpix->bo);
695
pPix->devPrivate.ptr = NULL;
696
nvpix->mapped = FALSE;
700
NVExaPixmapIsOffscreen(PixmapPtr pPix)
702
ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum];
703
NVPtr pNv = NVPTR(pScrn);
704
struct nouveau_pixmap *nvpix;
707
nvpix = exaGetPixmapDriverPrivate(pPix);
708
if (!nvpix || !nvpix->bo)
715
NVExaCreatePixmap(ScreenPtr pScreen, int size, int align)
717
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
718
NVPtr pNv = NVPTR(pScrn);
719
struct nouveau_pixmap *nvpix;
721
nvpix = xcalloc(1, sizeof(struct nouveau_pixmap));
726
if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM, 0, size,
737
NVExaDestroyPixmap(ScreenPtr pScreen, void *driverPriv)
739
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
740
NVPtr pNv = NVPTR(pScrn);
741
struct nouveau_pixmap *nvpix = driverPriv;
746
/*XXX: only if pending relocs reference this buffer..*/
749
nouveau_bo_del(&nvpix->bo);
754
NVExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height, int depth,
755
int bitsPerPixel, int devKind, pointer pPixData)
757
ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
758
NVPtr pNv = NVPTR(pScrn);
759
struct nouveau_pixmap *nvpix;
761
if (pPixData == pNv->FB->map) {
762
nvpix = exaGetPixmapDriverPrivate(pPixmap);
766
if (nouveau_bo_ref(pNv->dev, pNv->FB->handle, &nvpix->bo))
769
miModifyPixmapHeader(pPixmap, width, height, depth,
770
bitsPerPixel, devKind, NULL);
778
#if !NOUVEAU_EXA_PIXMAPS
780
nouveau_exa_pixmap_is_offscreen(PixmapPtr pPixmap)
782
ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
783
NVPtr pNv = NVPTR(pScrn);
784
void *addr = (void *)pPixmap->devPrivate.ptr;
786
if (addr >= pNv->FB->map && addr < (pNv->FB->map + pNv->FB->size))
789
if (pNv->shadow[0] && (addr >= pNv->shadow[0]->map && addr < (pNv->shadow[0]->map + pNv->shadow[0]->size)))
792
if (pNv->shadow[1] && (addr >= pNv->shadow[1]->map && addr < (pNv->shadow[1]->map + pNv->shadow[1]->size)))
797
#endif /* !NOUVEAU_EXA_PIXMAPS */
800
NVExaPixmapIsOnscreen(PixmapPtr pPixmap)
802
ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
803
NVPtr pNv = NVPTR(pScrn);
805
#if NOUVEAU_EXA_PIXMAPS
806
struct nouveau_pixmap *nvpix;
807
nvpix = exaGetPixmapDriverPrivate(pPixmap);
809
if (nvpix && nvpix->bo == pNv->FB)
813
unsigned long offset = exaGetPixmapOffset(pPixmap);
815
if (offset < pNv->EXADriverPtr->offScreenBase)
817
#endif /* NOUVEAU_EXA_PIXMAPS */
823
NVExaInit(ScreenPtr pScreen)
825
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
826
NVPtr pNv = NVPTR(pScrn);
828
if(!(pNv->EXADriverPtr = (ExaDriverPtr) xnfcalloc(sizeof(ExaDriverRec), 1))) {
833
pNv->EXADriverPtr->exa_major = EXA_VERSION_MAJOR;
834
pNv->EXADriverPtr->exa_minor = EXA_VERSION_MINOR;
836
#if NOUVEAU_EXA_PIXMAPS
837
if (NOUVEAU_EXA_PIXMAPS) {
838
pNv->EXADriverPtr->flags = EXA_OFFSCREEN_PIXMAPS |
840
pNv->EXADriverPtr->PrepareAccess = NVExaPrepareAccess;
841
pNv->EXADriverPtr->FinishAccess = NVExaFinishAccess;
842
pNv->EXADriverPtr->PixmapIsOffscreen = NVExaPixmapIsOffscreen;
843
pNv->EXADriverPtr->CreatePixmap = NVExaCreatePixmap;
844
pNv->EXADriverPtr->DestroyPixmap = NVExaDestroyPixmap;
845
pNv->EXADriverPtr->ModifyPixmapHeader = NVExaModifyPixmapHeader;
849
pNv->EXADriverPtr->flags = EXA_OFFSCREEN_PIXMAPS;
850
pNv->EXADriverPtr->memoryBase = pNv->FB->map;
851
pNv->EXADriverPtr->offScreenBase =
852
NOUVEAU_ALIGN(pScrn->virtualX, 64) * NOUVEAU_ALIGN(pScrn->virtualY,64) *
853
(pScrn->bitsPerPixel / 8);
854
pNv->EXADriverPtr->memorySize = pNv->FB->size;
855
#if EXA_VERSION_MINOR >= 2
856
pNv->EXADriverPtr->PixmapIsOffscreen = nouveau_exa_pixmap_is_offscreen;
859
pNv->EXADriverPtr->pixmapOffsetAlign = 256;
860
pNv->EXADriverPtr->pixmapPitchAlign = 64;
862
if (pNv->Architecture >= NV_ARCH_50) {
863
pNv->EXADriverPtr->maxX = 8192;
864
pNv->EXADriverPtr->maxY = 8192;
866
if (pNv->Architecture >= NV_ARCH_20) {
867
pNv->EXADriverPtr->maxX = 4096;
868
pNv->EXADriverPtr->maxY = 4096;
870
pNv->EXADriverPtr->maxX = 2048;
871
pNv->EXADriverPtr->maxY = 2048;
874
pNv->EXADriverPtr->WaitMarker = NVExaWaitMarker;
876
/* Install default hooks */
877
pNv->EXADriverPtr->DownloadFromScreen = NVDownloadFromScreen;
878
pNv->EXADriverPtr->UploadToScreen = NVUploadToScreen;
880
if (pNv->Architecture < NV_ARCH_50) {
881
pNv->EXADriverPtr->PrepareCopy = NVExaPrepareCopy;
882
pNv->EXADriverPtr->Copy = NVExaCopy;
883
pNv->EXADriverPtr->DoneCopy = NVExaDoneCopy;
885
pNv->EXADriverPtr->PrepareSolid = NVExaPrepareSolid;
886
pNv->EXADriverPtr->Solid = NVExaSolid;
887
pNv->EXADriverPtr->DoneSolid = NVExaDoneSolid;
889
pNv->EXADriverPtr->PrepareCopy = NV50EXAPrepareCopy;
890
pNv->EXADriverPtr->Copy = NV50EXACopy;
891
pNv->EXADriverPtr->DoneCopy = NV50EXADoneCopy;
893
pNv->EXADriverPtr->PrepareSolid = NV50EXAPrepareSolid;
894
pNv->EXADriverPtr->Solid = NV50EXASolid;
895
pNv->EXADriverPtr->DoneSolid = NV50EXADoneSolid;
898
switch (pNv->Architecture) {
902
pNv->EXADriverPtr->CheckComposite = NV10CheckComposite;
903
pNv->EXADriverPtr->PrepareComposite = NV10PrepareComposite;
904
pNv->EXADriverPtr->Composite = NV10Composite;
905
pNv->EXADriverPtr->DoneComposite = NV10DoneComposite;
908
pNv->EXADriverPtr->CheckComposite = NV30EXACheckComposite;
909
pNv->EXADriverPtr->PrepareComposite = NV30EXAPrepareComposite;
910
pNv->EXADriverPtr->Composite = NV30EXAComposite;
911
pNv->EXADriverPtr->DoneComposite = NV30EXADoneComposite;
914
pNv->EXADriverPtr->CheckComposite = NV40EXACheckComposite;
915
pNv->EXADriverPtr->PrepareComposite = NV40EXAPrepareComposite;
916
pNv->EXADriverPtr->Composite = NV40EXAComposite;
917
pNv->EXADriverPtr->DoneComposite = NV40EXADoneComposite;
925
if (!exaDriverInit(pScreen, pNv->EXADriverPtr))
928
/* EXA init catches this, but only for xserver >= 1.4 */
929
if (pNv->VRAMPhysicalSize / 2 < NOUVEAU_ALIGN(pScrn->virtualX, 64) * NOUVEAU_ALIGN(pScrn->virtualY, 64) * (pScrn->bitsPerPixel >> 3)) {
930
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "The virtual screen size's resolution is too big for the video RAM framebuffer at this colour depth.\n");