summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Skeggs <skeggsb@gmail.com>2007-07-09 16:20:31 +1000
committerBen Skeggs <skeggsb@gmail.com>2007-07-09 16:20:31 +1000
commite6a16710033d189aa5d6b2e3b4a75f2dd9d05a5d (patch)
treea7f826331d620442aed6dc4eb07514ecc82553d1
parent3f4aa20f4f4dd3c1a306e87aafe030bb3c926688 (diff)
parente182cff4f72f2e8403d94898c55cbca6e6349ba0 (diff)
Merge branch 'nv50-branch' into upstream-nv50-branch
Conflicts: src/Makefile.am src/nv_hw.c src/nv_proto.h
-rw-r--r--src/Makefile.am1
-rw-r--r--src/nv50_display.c2
-rw-r--r--src/nv50_exa.c254
-rw-r--r--src/nv_accel_common.c83
-rw-r--r--src/nv_dma.c82
-rw-r--r--src/nv_dma.h4
-rw-r--r--src/nv_driver.c6
-rw-r--r--src/nv_exa.c186
-rw-r--r--src/nv_proto.h13
-rw-r--r--src/nv_type.h4
-rw-r--r--src/nv_xaa.c2
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 */