Module Name: xsrc
Committed By: macallan
Date: Thu Jul 12 21:19:55 UTC 2018
Modified Files:
xsrc/external/mit/xf86-video-nv/dist/src: nv_driver.c nv_proto.h
nv_type.h nv_xaa.c
Added Files:
xsrc/external/mit/xf86-video-nv/dist/src: nv_exa.c
Log Message:
add mostly working EXA support
tested on a GeForce 6800 Ultra in a G5
still produces occasional artifacts but good enough to run a bunch of xterms
and gtk2 applications
To generate a diff of this commit:
cvs rdiff -u -r1.9 -r1.10 \
xsrc/external/mit/xf86-video-nv/dist/src/nv_driver.c
cvs rdiff -u -r0 -r1.1 xsrc/external/mit/xf86-video-nv/dist/src/nv_exa.c
cvs rdiff -u -r1.1.1.3 -r1.2 \
xsrc/external/mit/xf86-video-nv/dist/src/nv_proto.h
cvs rdiff -u -r1.1.1.4 -r1.2 \
xsrc/external/mit/xf86-video-nv/dist/src/nv_type.h
cvs rdiff -u -r1.1.1.2 -r1.2 \
xsrc/external/mit/xf86-video-nv/dist/src/nv_xaa.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: xsrc/external/mit/xf86-video-nv/dist/src/nv_driver.c
diff -u xsrc/external/mit/xf86-video-nv/dist/src/nv_driver.c:1.9 xsrc/external/mit/xf86-video-nv/dist/src/nv_driver.c:1.10
--- xsrc/external/mit/xf86-video-nv/dist/src/nv_driver.c:1.9 Sun Mar 5 01:57:26 2017
+++ xsrc/external/mit/xf86-video-nv/dist/src/nv_driver.c Thu Jul 12 21:19:54 2018
@@ -2058,11 +2058,22 @@ NVPreInit(ScrnInfoPtr pScrn, int flags)
/* Load XAA if needed */
if (!pNv->NoAccel) {
+ pNv->UseEXA = 1;
+#ifdef HAVE_XAA_H
if (!xf86LoadSubModule(pScrn, "xaa")) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Falling back to shadwwfb\n");
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Falling back to shadowfb\n");
pNv->NoAccel = 1;
pNv->ShadowFB = 1;
+ } else
+ pNv->UseEXA = 0;
+#else
+ if (!xf86LoadSubModule(pScrn, "exa")) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Falling back to shadowfb\n");
+ pNv->NoAccel = 1;
+ pNv->UseEXA = 0;
+ pNv->ShadowFB = 1;
}
+#endif
}
/* Load ramdac if needed */
@@ -2591,6 +2602,7 @@ NVScreenInit(SCREEN_INIT_ARGS_DECL)
if(offscreenHeight > 32767)
offscreenHeight = 32767;
+#ifdef HAVE_XAA_H
AvailFBArea.x1 = 0;
AvailFBArea.y1 = 0;
AvailFBArea.x2 = pScrn->displayWidth;
@@ -2599,7 +2611,10 @@ NVScreenInit(SCREEN_INIT_ARGS_DECL)
if (!pNv->NoAccel)
NVAccelInit(pScreen);
-
+#endif
+ if ((!pNv->NoAccel) && (pNv->UseEXA == 1))
+ NvInitExa(pScreen);
+
xf86SetBackingStore(pScreen);
xf86SetSilkenMouse(pScreen);
Index: xsrc/external/mit/xf86-video-nv/dist/src/nv_proto.h
diff -u xsrc/external/mit/xf86-video-nv/dist/src/nv_proto.h:1.1.1.3 xsrc/external/mit/xf86-video-nv/dist/src/nv_proto.h:1.2
--- xsrc/external/mit/xf86-video-nv/dist/src/nv_proto.h:1.1.1.3 Sun Mar 5 01:55:42 2017
+++ xsrc/external/mit/xf86-video-nv/dist/src/nv_proto.h Thu Jul 12 21:19:54 2018
@@ -34,8 +34,13 @@ Bool NVAccelInit(ScreenPtr pScreen);
void NVSync(ScrnInfoPtr pScrn);
void NVResetGraphics(ScrnInfoPtr pScrn);
void NVDmaKickoff(NVPtr pNv);
+void NVDMAKickoffCallback(ScrnInfoPtr pScrn);
void NVDmaWait(NVPtr pNv, int size);
void NVWaitVSync(NVPtr pNv);
+void NVSetRopSolid(ScrnInfoPtr pScrn, CARD32 rop, CARD32 planemask);
+
+/* in nv_exa.c */
+Bool NvInitExa(ScreenPtr pScreen);
/* in nv_dga.c */
Bool NVDGAInit(ScreenPtr pScreen);
Index: xsrc/external/mit/xf86-video-nv/dist/src/nv_type.h
diff -u xsrc/external/mit/xf86-video-nv/dist/src/nv_type.h:1.1.1.4 xsrc/external/mit/xf86-video-nv/dist/src/nv_type.h:1.2
--- xsrc/external/mit/xf86-video-nv/dist/src/nv_type.h:1.1.1.4 Sun Mar 5 01:55:42 2017
+++ xsrc/external/mit/xf86-video-nv/dist/src/nv_type.h Thu Jul 12 21:19:54 2018
@@ -5,6 +5,7 @@
#include "vgaHW.h"
#include "xf86Cursor.h"
#include "xf86int10.h"
+#include "exa.h"
#define NV_ARCH_04 0x04
#define NV_ARCH_10 0x10
@@ -128,6 +129,7 @@ typedef struct {
#ifdef HAVE_XAA_H
XAAInfoRecPtr AccelInfoRec;
#endif
+ ExaDriverPtr pExa;
xf86CursorInfoPtr CursorInfoRec;
DGAModePtr DGAModes;
int numDGAModes;
Index: xsrc/external/mit/xf86-video-nv/dist/src/nv_xaa.c
diff -u xsrc/external/mit/xf86-video-nv/dist/src/nv_xaa.c:1.1.1.2 xsrc/external/mit/xf86-video-nv/dist/src/nv_xaa.c:1.2
--- xsrc/external/mit/xf86-video-nv/dist/src/nv_xaa.c:1.1.1.2 Sun Jun 2 08:24:14 2013
+++ xsrc/external/mit/xf86-video-nv/dist/src/nv_xaa.c Thu Jul 12 21:19:54 2018
@@ -106,7 +106,7 @@ NVDmaKickoff(NVPtr pNv)
You can't jump to the location of your put offset. We write put
at the jump offset + SKIPS dwords with noop padding in between
to solve this problem */
-#define SKIPS 8
+#define SKIPS 16
void
NVDmaWait (
@@ -176,7 +176,7 @@ NVSetPattern(
NVDmaNext (pNv, pat1);
}
-static void
+void
NVSetRopSolid(ScrnInfoPtr pScrn, CARD32 rop, CARD32 planemask)
{
NVPtr pNv = NVPTR(pScrn);
@@ -282,16 +282,30 @@ void NVResetGraphics(ScrnInfoPtr pScrn)
void NVSync(ScrnInfoPtr pScrn)
{
NVPtr pNv = NVPTR(pScrn);
-
+ int bail = 10000000;
+
if(pNv->DMAKickoffCallback)
(*pNv->DMAKickoffCallback)(pScrn);
- while(READ_GET(pNv) != pNv->dmaPut);
-
- while(pNv->PGRAPH[0x0700/4]);
+ while((READ_GET(pNv) != pNv->dmaPut) && (bail > 0)) bail--;
+ if (bail == 0) {
+ xf86Msg(X_ERROR, "DMA drain timeout\n");
+ goto crap;
+ }
+
+ bail = 10000000;
+ while((pNv->PGRAPH[0x0700/4]) && (bail > 0)) bail--;
+ if (bail == 0) {
+ xf86Msg(X_ERROR, "engine stalled\n");
+ goto crap;
+ }
+ return;
+
+crap:
+ NVResetGraphics(pScrn);
}
-static void
+ void
NVDMAKickoffCallback (ScrnInfoPtr pScrn)
{
NVPtr pNv = NVPTR(pScrn);
Added files:
Index: xsrc/external/mit/xf86-video-nv/dist/src/nv_exa.c
diff -u /dev/null xsrc/external/mit/xf86-video-nv/dist/src/nv_exa.c:1.1
--- /dev/null Thu Jul 12 21:19:55 2018
+++ xsrc/external/mit/xf86-video-nv/dist/src/nv_exa.c Thu Jul 12 21:19:54 2018
@@ -0,0 +1,334 @@
+/*
+ * crude EXA support for geforce chips
+ *
+ * Copyright (C) 2018 Michael Lorenz
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * MICHAEL LORENZ BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/* $NetBSD: nv_exa.c,v 1.1 2018/07/12 21:19:54 macallan Exp $ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "nv_include.h"
+#include "miline.h"
+#include "nv_dma.h"
+#include "exa.h"
+
+//#define DEBUG
+
+#ifdef DEBUG
+#define ENTER xf86Msg(X_ERROR, "%s\n", __func__)
+#define LEAVE xf86Msg(X_ERROR, "%s done\n", __func__)
+#else
+#define ENTER
+#define LEAVE
+#endif
+
+static void
+NvWaitMarker(ScreenPtr pScreen, int Marker)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+
+ ENTER;
+ NVSync(pScrn);
+ LEAVE;
+}
+
+static Bool
+NvPrepareCopy
+(
+ PixmapPtr pSrcPixmap,
+ PixmapPtr pDstPixmap,
+ int xdir,
+ int ydir,
+ int rop,
+ Pixel planemask
+)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
+ NVPtr pNv = NVPTR(pScrn);
+ int srcpitch, srcoff, dstpitch, dstoff;
+
+ ENTER;
+ if (pSrcPixmap->drawable.bitsPerPixel != 32)
+ xf86Msg(X_ERROR, "%s %d bpp\n", __func__, pSrcPixmap->drawable.bitsPerPixel);
+ planemask |= ~0 << pNv->CurrentLayout.depth;
+ NVSetRopSolid(pScrn, rop, planemask);
+ pNv->DMAKickoffCallback = NVDMAKickoffCallback;
+ dstpitch = exaGetPixmapPitch(pDstPixmap);
+ dstoff = exaGetPixmapOffset(pDstPixmap);
+ srcpitch = exaGetPixmapPitch(pSrcPixmap);
+ srcoff = exaGetPixmapOffset(pSrcPixmap);
+
+ NVDmaStart(pNv, SURFACE_PITCH, 3);
+ NVDmaNext (pNv, srcpitch | (dstpitch << 16));
+ NVDmaNext (pNv, srcoff);
+ NVDmaNext (pNv, dstoff);
+
+ LEAVE;
+ return TRUE;
+}
+
+static void
+NvCopy
+(
+ PixmapPtr pDstPixmap,
+ int srcX,
+ int srcY,
+ int dstX,
+ int dstY,
+ int w,
+ int h
+)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
+ NVPtr pNv = NVPTR(pScrn);
+
+ NVDmaStart(pNv, BLIT_POINT_SRC, 3);
+ NVDmaNext (pNv, (srcY << 16) | srcX);
+ NVDmaNext (pNv, (dstY << 16) | dstX);
+ NVDmaNext (pNv, (h << 16) | w);
+
+ if((w * h) >= 512)
+ NVDmaKickoff(pNv);
+
+ LEAVE;
+}
+
+static void
+NvDoneCopy(PixmapPtr pDstPixmap)
+{
+ ENTER;
+ LEAVE;
+}
+
+static Bool
+NvPrepareSolid(
+ PixmapPtr pPixmap,
+ int rop,
+ Pixel planemask,
+ Pixel color)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
+ NVPtr pNv = NVPTR(pScrn);
+ int pitch, off;
+
+ ENTER;
+ if (pPixmap->drawable.bitsPerPixel != 32)
+ xf86Msg(X_ERROR, "%s %d bpp\n", __func__, pPixmap->drawable.bitsPerPixel);
+ planemask |= ~0 << pNv->CurrentLayout.depth;
+
+
+ pitch = exaGetPixmapPitch(pPixmap);
+ off = exaGetPixmapOffset(pPixmap);
+
+ NVDmaStart(pNv, SURFACE_PITCH, 3);
+ NVDmaNext (pNv, pitch | (pitch << 16));
+ NVDmaNext (pNv, off);
+ NVDmaNext (pNv, off);
+
+ NVSetRopSolid(pScrn, rop, planemask);
+ pNv->DMAKickoffCallback = NVDMAKickoffCallback;
+ NVDmaStart(pNv, RECT_SOLID_COLOR, 1);
+ NVDmaNext (pNv, color);
+
+ LEAVE;
+ return TRUE;
+}
+
+static void
+NvSolid(
+ PixmapPtr pPixmap,
+ int x1,
+ int y1,
+ int x2,
+ int y2)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
+ NVPtr pNv = NVPTR(pScrn);
+ int w = x2 - x1, h = y2 - y1;
+
+ ENTER;
+ NVDmaStart(pNv, RECT_SOLID_RECTS(0), 2);
+ NVDmaNext (pNv, (x1 << 16) | y1);
+ NVDmaNext (pNv, (w << 16) | h);
+
+ if((w * h) >= 512)
+ NVDmaKickoff(pNv);
+
+ LEAVE;
+}
+
+/*
+ * Memcpy-based UTS.
+ */
+static Bool
+NvUploadToScreen(PixmapPtr pDst, int x, int y, int w, int h,
+ char *src, int src_pitch)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
+ NVPtr pNv = NVPTR(pScrn);
+ unsigned char *dst = pNv->FbStart + exaGetPixmapOffset(pDst);
+ int dst_pitch = exaGetPixmapPitch(pDst);
+
+ int bpp = pDst->drawable.bitsPerPixel;
+ int cpp = (bpp + 7) >> 3;
+ int wBytes = w * cpp;
+
+ ENTER;
+ dst += (x * cpp) + (y * dst_pitch);
+
+ NVSync(pScrn);
+
+ while (h--) {
+ memcpy(dst, src, wBytes);
+ src += src_pitch;
+ dst += dst_pitch;
+ }
+ _NV_FENCE()
+ LEAVE;
+ return TRUE;
+}
+
+/*
+ * Memcpy-based DFS.
+ */
+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);
+ unsigned char *src = pNv->FbStart + exaGetPixmapOffset(pSrc);
+ int src_pitch = exaGetPixmapPitch(pSrc);
+
+ int bpp = pSrc->drawable.bitsPerPixel;
+ int cpp = (bpp + 7) >> 3;
+ int wBytes = w * cpp;
+
+ ENTER;
+ src += (x * cpp) + (y * src_pitch);
+
+ NVSync(pScrn);
+
+ while (h--) {
+ memcpy(dst, src, wBytes);
+ src += src_pitch;
+ dst += dst_pitch;
+ }
+ LEAVE;
+ return TRUE;
+}
+
+#ifdef __arm__
+static Bool
+NvPrepareAccess(PixmapPtr pPix, int index)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pPix->drawable.pScreen->myNum];
+ NVPtr pNv = NVPTR(pScrn);
+
+ IgsWaitReady(fPtr);
+ return TRUE;
+}
+
+static void
+NvFinishAccess(PixmapPtr pPix, int index)
+{
+}
+#endif
+
+Bool
+NvInitExa(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ NVPtr pNv = NVPTR(pScrn);
+ ExaDriverPtr pExa;
+ int surfaceFormat, rectFormat;
+
+ pExa = exaDriverAlloc();
+ if (!pExa)
+ return FALSE;
+
+ pNv->pExa = pExa;
+
+ NVResetGraphics(pScrn);
+
+ pExa->exa_major = EXA_VERSION_MAJOR;
+ pExa->exa_minor = EXA_VERSION_MINOR;
+
+ pExa->memoryBase = pNv->FbStart;
+ pExa->memorySize = pNv->ScratchBufferStart & (~63);
+ pExa->offScreenBase = pScrn->virtualY *
+ pScrn->displayWidth * pScrn->bitsPerPixel >> 3;
+ pExa->pixmapOffsetAlign = 64;
+ pExa->pixmapPitchAlign = 64;
+
+ pExa->flags = EXA_OFFSCREEN_PIXMAPS |
+ EXA_SUPPORTS_OFFSCREEN_OVERLAPS |
+ EXA_MIXED_PIXMAPS;
+
+ pExa->maxX = 8192;
+ pExa->maxY = 8192;
+
+ pExa->WaitMarker = NvWaitMarker;
+ pExa->PrepareSolid = NvPrepareSolid;
+ pExa->Solid = NvSolid;
+ pExa->DoneSolid = NvDoneCopy;
+ pExa->PrepareCopy = NvPrepareCopy;
+ pExa->Copy = NvCopy;
+ pExa->DoneCopy = NvDoneCopy;
+
+ switch(pNv->CurrentLayout.depth) {
+ case 24:
+ surfaceFormat = SURFACE_FORMAT_DEPTH24;
+ rectFormat = RECT_FORMAT_DEPTH24;
+ break;
+ case 16:
+ case 15:
+ surfaceFormat = SURFACE_FORMAT_DEPTH16;
+ rectFormat = RECT_FORMAT_DEPTH16;
+ break;
+ default:
+ surfaceFormat = SURFACE_FORMAT_DEPTH8;
+ rectFormat = RECT_FORMAT_DEPTH8;
+ break;
+ }
+ NVDmaStart(pNv, SURFACE_FORMAT, 1);
+ NVDmaNext (pNv, surfaceFormat);
+ NVDmaStart(pNv, RECT_FORMAT, 1);
+ NVDmaNext (pNv, rectFormat);
+
+ pNv->currentRop = ~0; /* set to something invalid */
+ NVSetRopSolid(pScrn, GXcopy, ~0);
+
+ NVDmaKickoff(pNv);
+
+ /* EXA hits more optimized paths when it does not have to fallback
+ * because of missing UTS/DFS, hook memcpy-based UTS/DFS.
+ */
+ pExa->UploadToScreen = NvUploadToScreen;
+ pExa->DownloadFromScreen = NvDownloadFromScreen;
+#ifdef __arm__
+ pExa->PrepareAccess = IgsPrepareAccess;
+ pExa->FinishAccess = IgsFinishAccess;
+#endif
+ return exaDriverInit(pScreen, pExa);
+}