diff options
-rw-r--r-- | src/Makefile.am | 1 | ||||
-rw-r--r-- | src/nv50_display.c | 2 | ||||
-rw-r--r-- | src/nv50_exa.c | 254 | ||||
-rw-r--r-- | src/nv_accel_common.c | 83 | ||||
-rw-r--r-- | src/nv_dma.c | 82 | ||||
-rw-r--r-- | src/nv_dma.h | 4 | ||||
-rw-r--r-- | src/nv_driver.c | 6 | ||||
-rw-r--r-- | src/nv_exa.c | 186 | ||||
-rw-r--r-- | src/nv_proto.h | 13 | ||||
-rw-r--r-- | src/nv_type.h | 4 | ||||
-rw-r--r-- | src/nv_xaa.c | 2 |
11 files changed, 507 insertions, 130 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index f88c3f8..d2dc5b5 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -60,6 +60,7 @@ nouveau_drv_la_SOURCES = \ nv50_cursor.c \ nv50_dac.c \ nv50_display.c \ + nv50_exa.c \ nv50_output.c \ nv50_sor.c diff --git a/src/nv50_display.c b/src/nv50_display.c index 3eeb283..394c924 100644 --- a/src/nv50_display.c +++ b/src/nv50_display.c @@ -399,7 +399,7 @@ NV50CrtcBlankScreen(xf86CrtcPtr crtc, Bool blank) if(pNv->_Chipset != 0x50) C(0x0000089C + headOff, 0); } else { - C(0x00000860 + headOff, 0); + C(0x00000860 + headOff, pNv->FB->offset >> 8); C(0x00000864 + headOff, 0); pNv->REGS[0x00610380/4] = 0; /*XXX: in "nv" this is total vram size. our RamAmountKBytes is clamped diff --git a/src/nv50_exa.c b/src/nv50_exa.c new file mode 100644 index 0000000..6536715 --- /dev/null +++ b/src/nv50_exa.c @@ -0,0 +1,254 @@ +#include "nv_include.h" + +#define NV50_2D_NOP 0x00000100 +#define NV50_2D_UNK110 0x00000110 +#define NV50_2D_DST_FORMAT 0x00000200 +#define NV50_2D_SRC_FORMAT 0x00000230 +#define NV50_2D_SRC_FORMAT_8BPP 0x000000f3 +#define NV50_2D_SRC_FORMAT_15BPP 0x000000f8 +#define NV50_2D_SRC_FORMAT_16BPP 0x000000e8 +#define NV50_2D_SRC_FORMAT_24BPP 0x000000e6 +#define NV50_2D_SRC_FORMAT_32BPP 0x000000cf +#define NV50_2D_CLIP_X 0x00000280 +#define NV50_2D_SET_OPERATION 0x000002ac +#define NV50_2D_SET_OPERATION_ROP_AND 0x00000001 +#define NV50_2D_SET_OPERATION_SRCCOPY 0x00000003 +#define NV50_2D_RASTER_OP 0x000002a0 +#define NV50_2D_PATTERN_FORMAT 0x000002e8 +#define NV50_2D_PATTERN_COLOR_0 0x000002f0 +#define NV50_2D_RECT_UNK580 0x00000580 +#define NV50_2D_RECT_FORMAT 0x00000584 +#define NV50_2D_RECT_X1 0x00000600 +#define NV50_2D_BLIT_DST_X 0x000008b0 + +#define NV50EXA_LOCALS(p) \ + ScrnInfoPtr pScrn = xf86Screens[(p)->drawable.pScreen->myNum]; \ + NVPtr pNv = NVPTR(pScrn); \ + (void)pNv + +static Bool +NV50EXA2DSurfaceFormat(PixmapPtr pPix, uint32_t *fmt) +{ + NV50EXA_LOCALS(pPix); + + switch (pPix->drawable.depth) { + case 8 : *fmt = NV50_2D_SRC_FORMAT_8BPP; break; + case 15: *fmt = NV50_2D_SRC_FORMAT_15BPP; break; + case 16: *fmt = NV50_2D_SRC_FORMAT_16BPP; break; + case 24: *fmt = NV50_2D_SRC_FORMAT_24BPP; break; + case 32: *fmt = NV50_2D_SRC_FORMAT_32BPP; break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Unknown surface format for bpp=%d\n", + pPix->drawable.depth); + return FALSE; + } + + return TRUE; +} + +static Bool +NV50EXAAcquireSurface2D(PixmapPtr pPix, int is_src) +{ + NV50EXA_LOCALS(pPix); + int mthd = is_src ? NV50_2D_SRC_FORMAT : NV50_2D_DST_FORMAT; + uint32_t fmt; + + if (!NV50EXA2DSurfaceFormat(pPix, &fmt)) + return FALSE; + + NVDmaStart(pNv, NvSub2D, mthd, 2); + NVDmaNext (pNv, fmt); + NVDmaNext (pNv, 1); + + NVDmaStart(pNv, NvSub2D, mthd + 0x14, 5); + NVDmaNext (pNv, (uint32_t)exaGetPixmapPitch(pPix)); + NVDmaNext (pNv, pPix->drawable.width); + NVDmaNext (pNv, pPix->drawable.height); + NVDmaNext (pNv, 0); + NVDmaNext (pNv, NVAccelGetPixmapOffset(pPix)); + + if (is_src == 0) { + NVDmaStart(pNv, NvSub2D, NV50_2D_CLIP_X, 4); + NVDmaNext (pNv, 0); + NVDmaNext (pNv, 0); + NVDmaNext (pNv, pPix->drawable.width); + NVDmaNext (pNv, pPix->drawable.height); + } + + return TRUE; +} + +static Bool +NV50EXAAcquireSurfaces(PixmapPtr pdPix) +{ + NV50EXA_LOCALS(pdPix); + + return TRUE; +} + +static void +NV50EXAReleaseSurfaces(PixmapPtr pdPix) +{ + NV50EXA_LOCALS(pdPix); + + NVDmaStart(pNv, NvSub2D, NV50_2D_NOP, 1); + NVDmaNext (pNv, 0); + NVDmaKickoff(pNv); +} + +static void +NV50EXASetPattern(PixmapPtr pdPix, int col0, int col1, int pat0, int pat1) +{ + NV50EXA_LOCALS(pdPix); + + NVDmaStart(pNv, NvSub2D, NV50_2D_PATTERN_COLOR_0, 4); + NVDmaNext (pNv, col0); + NVDmaNext (pNv, col1); + NVDmaNext (pNv, pat0); + NVDmaNext (pNv, pat1); +} + +extern const int NVCopyROP[16]; +static void +NV50EXASetROP(PixmapPtr pdPix, int alu, Pixel planemask) +{ + NV50EXA_LOCALS(pdPix); + int rop = NVCopyROP[alu]; + + NVDmaStart(pNv, NvSub2D, NV50_2D_SET_OPERATION, 1); + if(alu == GXcopy && planemask == ~0) { + NVDmaNext (pNv, NV50_2D_SET_OPERATION_SRCCOPY); + return; + } else { + NVDmaNext (pNv, NV50_2D_SET_OPERATION_ROP_AND); + } + + NVDmaStart(pNv, NvSub2D, NV50_2D_PATTERN_FORMAT, 1); + switch (pdPix->drawable.depth) { + case 8: NVDmaNext(pNv, 3); break; + case 15: NVDmaNext(pNv, 1); break; + case 16: NVDmaNext(pNv, 0); break; + case 24: + case 32: + default: + NVDmaNext(pNv, 2); + break; + } + + if(planemask != ~0) { + NV50EXASetPattern(pdPix, 0, planemask, ~0, ~0); + rop = (rop & 0xf0) | 0x0a; + } else + if((pNv->currentRop & 0x0f) == 0x0a) { + NV50EXASetPattern(pdPix, ~0, ~0, ~0, ~0); + } + + if (pNv->currentRop != rop) { + NVDmaStart(pNv, NvSub2D, NV50_2D_RASTER_OP, 1); + NVDmaNext (pNv, rop); + pNv->currentRop = rop; + } +} + +Bool +NV50EXAPrepareSolid(PixmapPtr pdPix, int alu, Pixel planemask, Pixel fg) +{ + NV50EXA_LOCALS(pdPix); + uint32_t fmt; + + if(pdPix->drawable.depth > 24) + return FALSE; + if (!NV50EXA2DSurfaceFormat(pdPix, &fmt)) + return FALSE; + + if (!NV50EXAAcquireSurface2D(pdPix, 0)) + return FALSE; + if (!NV50EXAAcquireSurfaces(pdPix)) + return FALSE; + NV50EXASetROP(pdPix, alu, planemask); + + NVDmaStart(pNv, NvSub2D, NV50_2D_RECT_UNK580, 3); + NVDmaNext (pNv, 4); + NVDmaNext (pNv, fmt); + NVDmaNext (pNv, fg); + + return TRUE; +} + +void +NV50EXASolid(PixmapPtr pdPix, int x1, int y1, int x2, int y2) +{ + NV50EXA_LOCALS(pdPix); + + NVDmaStart(pNv, NvSub2D, NV50_2D_RECT_X1, 4); + NVDmaNext (pNv, x1); + NVDmaNext (pNv, y1); + NVDmaNext (pNv, x2); + NVDmaNext (pNv, y2); + + if((x2 - x1) * (y2 - y1) >= 512) + NVDmaKickoff(pNv); +} + +void +NV50EXADoneSolid(PixmapPtr pdPix) +{ + NV50EXA_LOCALS(pdPix); + + NV50EXAReleaseSurfaces(pdPix); +} + +Bool +NV50EXAPrepareCopy(PixmapPtr psPix, PixmapPtr pdPix, int dx, int dy, + int alu, Pixel planemask) +{ + NV50EXA_LOCALS(pdPix); + + if (!NV50EXAAcquireSurface2D(psPix, 1)) + return FALSE; + if (!NV50EXAAcquireSurface2D(pdPix, 0)) + return FALSE; + if (!NV50EXAAcquireSurfaces(pdPix)) + return FALSE; + NV50EXASetROP(pdPix, alu, planemask); + + return TRUE; +} + +void +NV50EXACopy(PixmapPtr pdPix, int srcX , int srcY, + int dstX , int dstY, + int width, int height) +{ + NV50EXA_LOCALS(pdPix); + + NVDmaStart(pNv, NvSub2D, NV50_2D_UNK110, 1); + NVDmaNext (pNv, 0); + NVDmaStart(pNv, NvSub2D, NV50_2D_BLIT_DST_X, 12); + NVDmaNext (pNv, dstX); + NVDmaNext (pNv, dstY); + NVDmaNext (pNv, width); + NVDmaNext (pNv, height); + NVDmaNext (pNv, 0); + NVDmaNext (pNv, 1); + NVDmaNext (pNv, 0); + NVDmaNext (pNv, 1); + NVDmaNext (pNv, 0); + NVDmaNext (pNv, srcX); + NVDmaNext (pNv, 0); + NVDmaNext (pNv, srcY); + + if(width * height >= 512) + NVDmaKickoff(pNv); +} + +void +NV50EXADoneCopy(PixmapPtr pdPix) +{ + NV50EXA_LOCALS(pdPix); + + NV50EXAReleaseSurfaces(pdPix); +} + + diff --git a/src/nv_accel_common.c b/src/nv_accel_common.c index 2b9b09e..640dac6 100644 --- a/src/nv_accel_common.c +++ b/src/nv_accel_common.c @@ -16,6 +16,21 @@ NVAccelInitNullObject(ScrnInfoPtr pScrn) return TRUE; } +static Bool +NVAccelInitNull3D(ScrnInfoPtr pScrn) +{ + NVPtr pNv = NVPTR(pScrn); + static int have_object = FALSE; + + if (!have_object) { + if (!NVDmaCreateContextObject(pNv, Nv3D, 0x30)) + return FALSE; + have_object = TRUE; + } + + return TRUE; +} + uint32_t NVAccelGetPixmapOffset(PixmapPtr pPix) { @@ -374,7 +389,10 @@ NVAccelInitMemFormat(ScrnInfoPtr pScrn) static int have_object = FALSE; uint32_t class; - class = NV_MEMORY_TO_MEMORY_FORMAT; + if (pNv->Architecture < NV_ARCH_50) + class = NV_MEMORY_TO_MEMORY_FORMAT; + else + class = NV_MEMORY_TO_MEMORY_FORMAT | 0x5000; if (!have_object) { if (!NVDmaCreateContextObject(pNv, NvMemFormat, class)) @@ -395,6 +413,41 @@ NVAccelInitMemFormat(ScrnInfoPtr pScrn) return TRUE; } +static Bool +NVAccelInit2D_NV50(ScrnInfoPtr pScrn) +{ + NVPtr pNv = NVPTR(pScrn); + static int have_object = FALSE; + + if (!have_object) { + if (!NVDmaCreateContextObject(pNv, Nv2D, 0x502d)) + return FALSE; + have_object = TRUE; + } + + NVDmaSetObjectOnSubchannel(pNv, NvSub2D, Nv2D); + + NVDmaStart(pNv, NvSub2D, 0x180, 3); + NVDmaNext (pNv, NvDmaNotifier0); + NVDmaNext (pNv, NvDmaFB); + NVDmaNext (pNv, NvDmaFB); + + /* Magics from nv, no clue what they do, but at least some + * of them are needed to avoid crashes. + */ + NVDmaStart(pNv, NvSub2D, 0x260, 1); + NVDmaNext (pNv, 1); + NVDmaStart(pNv, NvSub2D, 0x290, 1); + NVDmaNext (pNv, 1); + NVDmaStart(pNv, NvSub2D, 0x29c, 1); + NVDmaNext (pNv, 0); + NVDmaStart(pNv, NvSub2D, 0x58c, 1); + NVDmaNext (pNv, 0x111); + + pNv->currentRop = 0xfffffffa; + return TRUE; +} + #define INIT_CONTEXT_OBJECT(name) do { \ ret = NVAccelInit##name(pScrn); \ if (!ret) { \ @@ -414,26 +467,28 @@ NVAccelCommonInit(ScrnInfoPtr pScrn) INIT_CONTEXT_OBJECT(NullObject); INIT_CONTEXT_OBJECT(DmaNotifier0); - INIT_CONTEXT_OBJECT(ContextSurfaces); - INIT_CONTEXT_OBJECT(ImagePattern); - INIT_CONTEXT_OBJECT(RasterOp); - INIT_CONTEXT_OBJECT(Rectangle); - INIT_CONTEXT_OBJECT(ImageBlit); - INIT_CONTEXT_OBJECT(ScaledImage); - - /* XAA-only */ - INIT_CONTEXT_OBJECT(ClipRectangle); - INIT_CONTEXT_OBJECT(SolidLine); - - /* EXA-only */ + /* 2D engine */ + if (pNv->Architecture < NV_ARCH_50) { + INIT_CONTEXT_OBJECT(ContextSurfaces); + INIT_CONTEXT_OBJECT(ImagePattern); + INIT_CONTEXT_OBJECT(RasterOp); + INIT_CONTEXT_OBJECT(Rectangle); + INIT_CONTEXT_OBJECT(ImageBlit); + INIT_CONTEXT_OBJECT(ScaledImage); + INIT_CONTEXT_OBJECT(ClipRectangle); + INIT_CONTEXT_OBJECT(SolidLine); + } else { + INIT_CONTEXT_OBJECT(2D_NV50); + } INIT_CONTEXT_OBJECT(MemFormat); - /* 3D init */ + /* 3D engine */ switch (pNv->Architecture) { case NV_ARCH_40: INIT_CONTEXT_OBJECT(NV40TCL); break; default: + INIT_CONTEXT_OBJECT(Null3D); break; } diff --git a/src/nv_dma.c b/src/nv_dma.c index de9566f..ca5e122 100644 --- a/src/nv_dma.c +++ b/src/nv_dma.c @@ -23,6 +23,33 @@ void NVDmaKickoffCallback(NVPtr pNv) */ #define SKIPS 8 +static void NVDumpLockupInfo(NVPtr pNv) +{ + int i,start; + start=READ_GET(pNv)-20; + if (start<0) start=0; + xf86DrvMsg(0, X_INFO, "Fifo dump (lockup 0x%04x,0x%04x):\n",READ_GET(pNv),pNv->dmaPut); + for(i=start;i<pNv->dmaPut+10;i++) + xf86DrvMsg(0, X_INFO, "[0x%04x] 0x%08x\n", i, pNv->dmaBase[i]); + xf86DrvMsg(0, X_INFO, "End of fifo dump\n"); +} + +static void +NVLockedUp(ScrnInfoPtr pScrn) +{ + NVPtr pNv = NVPTR(pScrn); + + /* avoid re-entering FatalError on shutdown */ + if (pNv->LockedUp) + return; + pNv->LockedUp = TRUE; + + NVDumpLockupInfo(pNv); + + FatalError("DMA queue hang: dmaPut=%x, current=%x, status=%x\n", + pNv->dmaPut, READ_GET(pNv), pNv->PGRAPH[NV_PGRAPH_STATUS/4]); +} + void NVDmaWait (ScrnInfoPtr pScrn, int size) { NVPtr pNv = NVPTR(pScrn); @@ -44,7 +71,7 @@ void NVDmaWait (ScrnInfoPtr pScrn, int size) WRITE_PUT(pNv, SKIPS + 1); do { if (GetTimeInMillis() - t_start > 2000) - NVSync(pScrn); + NVLockedUp(pScrn); dmaGet = READ_GET(pNv); } while(dmaGet <= SKIPS); } @@ -52,45 +79,20 @@ void NVDmaWait (ScrnInfoPtr pScrn, int size) pNv->dmaCurrent = pNv->dmaPut = SKIPS; pNv->dmaFree = dmaGet - (SKIPS + 1); } - } else + } else { pNv->dmaFree = dmaGet - pNv->dmaCurrent - 1; + } if (GetTimeInMillis() - t_start > 2000) - NVSync(pScrn); + NVLockedUp(pScrn); } } -static void NVDumpLockupInfo(NVPtr pNv) -{ - int i,start; - start=READ_GET(pNv)-20; - if (start<0) start=0; - xf86DrvMsg(0, X_INFO, "Fifo dump (lockup 0x%04x,0x%04x):\n",READ_GET(pNv),pNv->dmaPut); - for(i=start;i<pNv->dmaPut+10;i++) - xf86DrvMsg(0, X_INFO, "[0x%04x] 0x%08x\n", i, pNv->dmaBase[i]); - xf86DrvMsg(0, X_INFO, "End of fifo dump\n"); -} - -static void -NVLockedUp(ScrnInfoPtr pScrn) -{ - NVPtr pNv = NVPTR(pScrn); - - /* avoid re-entering FatalError on shutdown */ - if (pNv->LockedUp) - return; - pNv->LockedUp = TRUE; - - NVDumpLockupInfo(pNv); - - FatalError("DMA queue hang: dmaPut=%x, current=%x, status=%x\n", - pNv->dmaPut, READ_GET(pNv), pNv->PGRAPH[NV_PGRAPH_STATUS/4]); -} - void NVSync(ScrnInfoPtr pScrn) { NVPtr pNv = NVPTR(pScrn); int t_start, timeout = 2000; + int subc; if(pNv->NoAccel) return; @@ -108,10 +110,11 @@ void NVSync(ScrnInfoPtr pScrn) } /* Wait for channel to go completely idle */ + subc = (pNv->Architecture >= NV_ARCH_50) ? NvSub2D : NvSubImageBlit; NVNotifierReset(pScrn, pNv->Notifier0); - NVDmaStart(pNv, NvSubImageBlit, 0x104, 1); + NVDmaStart(pNv, subc, 0x104, 1); NVDmaNext (pNv, 0); - NVDmaStart(pNv, NvSubImageBlit, 0x100, 1); + NVDmaStart(pNv, subc, 0x100, 1); NVDmaNext (pNv, 0); NVDmaKickoff(pNv); if (!NVNotifierWaitStatus(pScrn, pNv->Notifier0, 0, timeout)) @@ -128,8 +131,9 @@ void NVResetGraphics(ScrnInfoPtr pScrn) pitch = pNv->CurrentLayout.displayWidth * (pNv->CurrentLayout.bitsPerPixel >> 3); +#if 0 pNv->dmaPut = pNv->dmaCurrent = READ_GET(pNv); - pNv->dmaMax = (pNv->fifo.cmdbuf_size >> 2) - 1; + pNv->dmaMax = (pNv->fifo.cmdbuf_size >> 2) - 2; pNv->dmaFree = pNv->dmaMax - pNv->dmaCurrent; /* assert there's enough room for the skips */ @@ -140,9 +144,13 @@ void NVResetGraphics(ScrnInfoPtr pScrn) pNv->dmaBase[i]=0; } pNv->dmaFree -= SKIPS; +#endif NVAccelCommonInit(pScrn); + if (pNv->Architecture >= NV_ARCH_50) + return; + /* EXA + XAA + Xv */ NVDmaSetObjectOnSubchannel(pNv, NvSubContextSurfaces, NvContextSurfaces); NVDmaSetObjectOnSubchannel(pNv, NvSubRectangle , NvRectangle ); @@ -154,10 +162,6 @@ void NVResetGraphics(ScrnInfoPtr pScrn) if (pNv->useEXA) { if (pNv->AGPScratch) NVDmaSetObjectOnSubchannel(pNv, NvSubMemFormat, NvMemFormat); - if (pNv->use3D) { - NVDmaSetObjectOnSubchannel(pNv, NvSub3D, Nv3D); - pNv->Reset3D(pNv); - } } else if (!pNv->useEXA) { NVDmaSetObjectOnSubchannel(pNv, NvSubClipRectangle, NvClipRectangle); NVDmaSetObjectOnSubchannel(pNv, NvSubSolidLine, NvSolidLine); @@ -308,8 +312,8 @@ Bool NVInitDma(ScrnInfoPtr pScrn) xf86DrvMsg(pScrn->scrnIndex, X_INFO, " DMA base PUT : 0x%08x\n", pNv->fifo.put_base); - pNv->dmaPut = pNv->dmaCurrent = READ_GET(pNv); - pNv->dmaMax = (pNv->fifo.cmdbuf_size >> 2) - 1; + pNv->dmaPut = pNv->dmaCurrent = 0; + pNv->dmaMax = (pNv->fifo.cmdbuf_size >> 2) - 2; pNv->dmaFree = pNv->dmaMax - pNv->dmaCurrent; for (i=0; i<SKIPS; i++) diff --git a/src/nv_dma.h b/src/nv_dma.h index 16be1fd..19e1bb3 100644 --- a/src/nv_dma.h +++ b/src/nv_dma.h @@ -66,6 +66,7 @@ enum DMAObjects { NvScaledImage = 0x80000017, NvMemFormat = 0x80000018, Nv3D = 0x80000019, + Nv2D = 0x80000020, NvDmaFB = 0xD8000001, NvDmaTT = 0xD8000002, NvDmaNotifier0 = 0xD8000003 @@ -73,6 +74,7 @@ enum DMAObjects { enum DMASubchannel { /* EXA + XAA + Xv */ + NvSub2D = 0, NvSubContextSurfaces = 0, NvSubRectangle = 1, NvSubScaledImage = 2, @@ -103,7 +105,7 @@ enum DMASubchannel { } while(0) #define NVDmaStart(pNv, subchannel, tag, size) do { \ - if((pNv)->dmaFree <= (size)) \ + if((pNv)->dmaFree <= (size)) \ NVDmaWait(pScrn, size); \ NVDEBUG("NVDmaStart: subc=%d, cmd=%x, num=%d\n", (subchannel), (tag), (size)); \ NVDmaNext(pNv, ((size) << 18) | ((subchannel) << 13) | (tag)); \ diff --git a/src/nv_driver.c b/src/nv_driver.c index e8ec8c6..183f2f1 100644 --- a/src/nv_driver.c +++ b/src/nv_driver.c @@ -1005,7 +1005,6 @@ NVCloseScreen(int scrnIndex, ScreenPtr pScreen) NVPtr pNv = NVPTR(pScrn); if (pScrn->vtSema) { - ErrorF("*************\n"); if (pNv->Architecture == NV_ARCH_50) { NV50ReleaseDisplay(pScrn); } else { @@ -1441,10 +1440,6 @@ NVPreInit(ScrnInfoPtr pScrn, int flags) pNv->NoAccel = TRUE; xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Acceleration disabled\n"); - } else if (pNv->Architecture == NV_ARCH_50) { - pNv->NoAccel = TRUE; - xf86DrvMsg(pScrn->scrnIndex, X_WARNING, - "NV50 detected, acceleration not currently supported\n"); } if (xf86ReturnOptValBool(pNv->Options, OPTION_SHADOW_FB, FALSE)) { @@ -2015,7 +2010,6 @@ NV50LoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices, unsigned short red, green, blue, unused; } *lut = (void *) pNv->CLUT->map; - ErrorF("NV50LoadPalette\n"); switch (pScrn->depth) { case 15: for (i = 0; i < numColors; i++) { diff --git a/src/nv_exa.c b/src/nv_exa.c index 7e5c929..6380971 100644 --- a/src/nv_exa.c +++ b/src/nv_exa.c @@ -260,62 +260,108 @@ static void NVExaCopy(PixmapPtr pDstPixmap, static void NVExaDoneCopy (PixmapPtr pDstPixmap) {} -static Bool NVDownloadFromScreen(PixmapPtr pSrc, - int x, int y, - int w, int h, - char *dst, int dst_pitch) +Bool NVAccelMemcpyRect(char *dst, const char *src, int height, + int dst_pitch, int src_pitch, int line_len) { - ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum]; - NVPtr pNv = NVPTR(pScrn); - CARD32 offset_in, pitch_in, max_lines, line_length; - Bool ret = TRUE; + if ((src_pitch == line_len) && (src_pitch == dst_pitch)) { + memcpy(dst, src, line_len*height); + } else { + while (height--) { + memcpy(dst, src, line_len); + src += src_pitch; + dst += dst_pitch; + } + } - pitch_in = exaGetPixmapPitch(pSrc); - offset_in = NVAccelGetPixmapOffset(pSrc); - offset_in += y*pitch_in; - offset_in += x * (pSrc->drawable.bitsPerPixel >> 3); - max_lines = 65536/dst_pitch + 1; - line_length = w * (pSrc->drawable.bitsPerPixel >> 3); + return TRUE; +} + +Bool +NVAccelDownloadM2MF(ScrnInfoPtr pScrn, char *dst, uint64_t src_offset, + int dst_pitch, int src_pitch, + int line_len, int line_count) +{ + NVPtr pNv = NVPTR(pScrn); setM2MFDirection(pScrn, 0); - NVDEBUG("NVDownloadFromScreen: x=%d, y=%d, w=%d, h=%d\n", x, y, w, h); - NVDEBUG(" pitch_in=%x dst_pitch=%x offset_in=%x", - pitch_in, dst_pitch, offset_in); - while (h > 0) { - int nlines = h > max_lines ? max_lines : h; - NVDEBUG(" max_lines=%d, h=%d\n", max_lines, h); + while (line_count) { + char *src = pNv->AGPScratch->map; + int lc, i; + + if (line_count * line_len <= pNv->AGPScratch->size) { + lc = line_count; + } else { + lc = pNv->AGPScratch->size / line_len; + if (lc > line_count) + lc = line_count; + } + /*XXX: and hw limitations? */ - /* reset the notification object */ NVNotifierReset(pScrn, pNv->Notifier0); - NVDmaStart(pNv, NvSubMemFormat, MEMFORMAT_NOTIFY, 1); + NVDmaStart(pNv, NvSubMemFormat, + NV_MEMORY_TO_MEMORY_FORMAT_NOTIFY, 1); NVDmaNext (pNv, 0); - NVDmaStart(pNv, NvSubMemFormat, MEMFORMAT_OFFSET_IN, 8); - NVDmaNext (pNv, offset_in); + NVDmaStart(pNv, NvSubMemFormat, + NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8); + NVDmaNext (pNv, (uint32_t)src_offset); NVDmaNext (pNv, (uint32_t)pNv->AGPScratch->offset); - NVDmaNext (pNv, pitch_in); - NVDmaNext (pNv, dst_pitch); - NVDmaNext (pNv, line_length); - NVDmaNext (pNv, nlines); - NVDmaNext (pNv, 0x101); + NVDmaNext (pNv, src_pitch); + NVDmaNext (pNv, line_len); + NVDmaNext (pNv, line_len); + NVDmaNext (pNv, lc); + NVDmaNext (pNv, (1<<8)|1); NVDmaNext (pNv, 0); NVDmaKickoff(pNv); - if (!NVNotifierWaitStatus(pScrn, pNv->Notifier0, 0, 2000)) { - ret = FALSE; - goto error; + if (!NVNotifierWaitStatus(pScrn, pNv->Notifier0, 0, 0)) + return FALSE; + + if (dst_pitch == line_len) { + memcpy(dst, src, dst_pitch * lc); + dst += dst_pitch * lc; + } else { + for (i = 0; i < lc; i++) { + memcpy(dst, src, line_len); + src += line_len; + dst += dst_pitch; + } } - memcpy(dst, pNv->AGPScratch->map, nlines*dst_pitch); - h -= nlines; - offset_in += nlines*pitch_in; - dst += nlines*dst_pitch; + line_count -= lc; } -error: - exaMarkSync(pSrc->drawable.pScreen); - return ret; + return TRUE; +} + +static Bool NVDownloadFromScreen(PixmapPtr pSrc, + int x, int y, + int w, int h, + char *dst, int dst_pitch) +{ + ScrnInfoPtr pScrn = xf86Screens[pSrc->drawable.pScreen->myNum]; + NVPtr pNv = NVPTR(pScrn); + int src_pitch, cpp, offset; + const char *src; + + src_pitch = exaGetPixmapPitch(pSrc); + cpp = pSrc->drawable.bitsPerPixel >> 3; + offset = (y * src_pitch) + (x * cpp); + + if (pNv->AGPScratch) { + if (NVAccelDownloadM2MF(pScrn, dst, + NVAccelGetPixmapOffset(pSrc) + offset, + dst_pitch, src_pitch, w * cpp, h)) + return TRUE; + } + + src = pSrc->devPrivate.ptr + offset; + exaWaitSync(pSrc->drawable.pScreen); + if (NVAccelMemcpyRect(dst, src, h, dst_pitch, src_pitch, w*cpp)) + return TRUE; + + return FALSE; } Bool @@ -344,6 +390,7 @@ NVAccelUploadM2MF(ScrnInfoPtr pScrn, uint64_t dst_offset, const char *src, /* Upload to GART */ if (src_pitch == line_len) { memcpy(dst, src, src_pitch * lc); + src += src_pitch * lc; } else { for (i = 0; i < lc; i++) { memcpy(dst, src, line_len); @@ -384,21 +431,27 @@ static Bool NVUploadToScreen(PixmapPtr pDst, char *src, int src_pitch) { ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum]; - int dst_offset, dst_pitch, bpp; - Bool ret; + NVPtr pNv = NVPTR(pScrn); + int dst_offset, dst_pitch, cpp; + char *dst; dst_offset = NVAccelGetPixmapOffset(pDst); dst_pitch = exaGetPixmapPitch(pDst); - bpp = pDst->drawable.bitsPerPixel >> 3; + cpp = pDst->drawable.bitsPerPixel >> 3; - if (1) { - dst_offset += (y * dst_pitch) + (x * bpp); - ret = NVAccelUploadM2MF(pScrn, dst_offset, src, - dst_pitch, src_pitch, - w * bpp, h); + if (pNv->AGPScratch) { + dst_offset += (y * dst_pitch) + (x * cpp); + if (NVAccelUploadM2MF(pScrn, dst_offset, src, dst_pitch, + src_pitch, w * cpp, h)) + return TRUE; } - exaMarkSync(pDst->drawable.pScreen); - return ret; + + dst = pDst->devPrivate.ptr + (y * dst_pitch) + (x * cpp); + exaWaitSync(pDst->drawable.pScreen); + if (NVAccelMemcpyRect(dst, src, h, dst_pitch, src_pitch, w*cpp)) + return TRUE; + + return FALSE; } @@ -552,18 +605,26 @@ Bool NVExaInit(ScreenPtr pScreen) pNv->EXADriverPtr->WaitMarker = NVExaWaitMarker; /* Install default hooks */ - if (pNv->AGPScratch) { - pNv->EXADriverPtr->DownloadFromScreen = NVDownloadFromScreen; - pNv->EXADriverPtr->UploadToScreen = NVUploadToScreen; - } + pNv->EXADriverPtr->DownloadFromScreen = NVDownloadFromScreen; + pNv->EXADriverPtr->UploadToScreen = NVUploadToScreen; - pNv->EXADriverPtr->PrepareCopy = NVExaPrepareCopy; - pNv->EXADriverPtr->Copy = NVExaCopy; - pNv->EXADriverPtr->DoneCopy = NVExaDoneCopy; + if (pNv->Architecture < NV_ARCH_50) { + pNv->EXADriverPtr->PrepareCopy = NVExaPrepareCopy; + pNv->EXADriverPtr->Copy = NVExaCopy; + pNv->EXADriverPtr->DoneCopy = NVExaDoneCopy; - pNv->EXADriverPtr->PrepareSolid = NVExaPrepareSolid; - pNv->EXADriverPtr->Solid = NVExaSolid; - pNv->EXADriverPtr->DoneSolid = NVExaDoneSolid; + pNv->EXADriverPtr->PrepareSolid = NVExaPrepareSolid; + pNv->EXADriverPtr->Solid = NVExaSolid; + pNv->EXADriverPtr->DoneSolid = NVExaDoneSolid; + } else { + pNv->EXADriverPtr->PrepareCopy = NV50EXAPrepareCopy; + pNv->EXADriverPtr->Copy = NV50EXACopy; + pNv->EXADriverPtr->DoneCopy = NV50EXADoneCopy; + + pNv->EXADriverPtr->PrepareSolid = NV50EXAPrepareSolid; + pNv->EXADriverPtr->Solid = NV50EXASolid; + pNv->EXADriverPtr->DoneSolid = NV50EXADoneSolid; + } switch (pNv->Architecture) { case NV_ARCH_40: @@ -572,6 +633,8 @@ Bool NVExaInit(ScreenPtr pScreen) pNv->EXADriverPtr->Composite = NV30EXAComposite; pNv->EXADriverPtr->DoneComposite = NV30EXADoneComposite; break; + case NV_ARCH_50: + break; default: if (!pNv->BlendingPossible) break; @@ -582,11 +645,6 @@ Bool NVExaInit(ScreenPtr pScreen) break; } - /* If we're going to try and use 3D, let the card-specific function - * override whatever hooks it wants. - */ - if (pNv->use3D) pNv->InitEXA3D(pNv); - return exaDriverInit(pScreen, pNv->EXADriverPtr); } diff --git a/src/nv_proto.h b/src/nv_proto.h index d1075b2..6e50bd5 100644 --- a/src/nv_proto.h +++ b/src/nv_proto.h @@ -132,5 +132,18 @@ Bool NV30EXAPrepareComposite(int, PicturePtr, PicturePtr, PicturePtr, void NV30EXAComposite(PixmapPtr, int, int, int, int, int, int, int, int); void NV30EXADoneComposite(PixmapPtr); +/* in nv50_exa.c */ +Bool NV50EXAPrepareSolid(PixmapPtr, int, Pixel, Pixel); +void NV50EXASolid(PixmapPtr, int, int, int, int); +void NV50EXADoneSolid(PixmapPtr); +Bool NV50EXAPrepareCopy(PixmapPtr, PixmapPtr, int, int, int, Pixel); +void NV50EXACopy(PixmapPtr, int, int, int, int, int, int); +void NV50EXADoneCopy(PixmapPtr); +Bool NV50EXACheckComposite(int, PicturePtr, PicturePtr, PicturePtr); +Bool NV50EXAPrepareComposite(int, PicturePtr, PicturePtr, PicturePtr, + PixmapPtr, PixmapPtr, PixmapPtr); +void NV50EXAComposite(PixmapPtr, int, int, int, int, int, int, int, int); +void NV50EXADoneComposite(PixmapPtr); + #endif /* __NV_PROTO_H__ */ diff --git a/src/nv_type.h b/src/nv_type.h index 9515bb0..73a326f 100644 --- a/src/nv_type.h +++ b/src/nv_type.h @@ -295,10 +295,6 @@ typedef struct _NVRec { CARD32 dmaMax; CARD32 *dmaBase; - Bool use3D; - void (*Reset3D)(NVPtr pNv); - void (*InitEXA3D)(NVPtr pNv); - CARD32 currentRop; int M2MFDirection; diff --git a/src/nv_xaa.c b/src/nv_xaa.c index 9c32910..a79efc6 100644 --- a/src/nv_xaa.c +++ b/src/nv_xaa.c @@ -45,7 +45,7 @@ #include "nv_dma.h" #include "nvreg.h" -static const int NVCopyROP[16] = +const int NVCopyROP[16] = { 0x00, /* GXclear */ 0x88, /* GXand */ |