Hello,

here comes the 2nd of two patches (to be applied in order) for updating
the SGI Impact video driver for the Xorg X server.

with kind regards

peter

(PS: sorry for being that late ;-)

---

This patch enables the use of a virtual screen with XImpact by mmap'ing the
shadow-framebuffer according - within limits - to the requested virtualX/
virtualY values, and by implementing ImpactAdjustFrame().
The virtual resolution is just limited by the available shadow-framebuffer
(DMA-pool) size:
- The kernel mmap's at most 16MB (e.g. 2048x2048 Pixels @ 32bpp) for one
  DMA-pool.
- For Indigo2 this memory had to be restricted to 12MB (e.g. 1772x1772
  Pixels @ 32bpp)


Signed-off-by: peter fuerst <[email protected]>

---

 xorg/driver/xf86-video-impact/src/impact.h        |    1 +
 xorg/driver/xf86-video-impact/src/impact_driver.c |   37 +++++++++++-----
 xorg/driver/xf86-video-impact/src/impact_shadow.c |  115 
+++++++++++++++++++++++++++++++-------------------
 3 files changed, 98 insertions(+), 55 deletions(-)


diff --git a/src/impact.h b/src/impact.h
index ce6b148..97ceca9 100644
--- a/xorg/driver/xf86-video-impact/src/impact.h        Thu Jul 21 03:39:43 2011
+++ b/xorg/driver/xf86-video-impact/src/impact.h        Sun Sep  4 22:35:24 2011
@@ -125,6 +125,7 @@ void ImpactBackupRex(ScrnInfoPtr);
 void ImpactRestoreRex(ScrnInfoPtr);
 void ImpactBackupXmap(ScrnInfoPtr);
 void ImpactRestoreXmap(ScrnInfoPtr);
+void ImpactAdjustFrame(int, int, int, int);

 /* newort_cmap.c */
 static __inline__ unsigned


diff --git a/src/impact_driver.c b/src/impact_driver.c
index cb16b4a..0d11ab6 100644
--- a/xorg/driver/xf86-video-impact/src/impact_driver.c Sun Jul 24 21:37:47 2011
+++ b/xorg/driver/xf86-video-impact/src/impact_driver.c Mon Sep  5 03:36:25 2011
@@ -270,6 +270,7 @@ ImpactProbe(DriverPtr drv, int flags)
                                        pScrn->ScreenInit = ImpactScreenInit;
                                        pScrn->EnterVT = ImpactEnterVT;
                                        pScrn->LeaveVT = ImpactLeaveVT;
+                                       pScrn->AdjustFrame = ImpactAdjustFrame;
                                        pScrn->driverPrivate =
                                                (void*)(busID | 
(long)probedIDs[j].ip<<16);
                                        foundScreen = TRUE;
@@ -401,7 +402,14 @@ ImpactPreInit(ScrnInfoPtr pScrn, int flags)
        xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pImpact->Options);

        /* Set fields in ScreenInfoRec && ImpactRec */
-       pScrn->videoRam = IMPACT_FIXED_W_SCRN * (pScrn->bitsPerPixel >> 3);
+       if (!(i = pScrn->display->virtualX * pScrn->display->virtualY))
+               i = IMPACT_FIXED_W_SCRN * IMPACT_FIXED_H_SCRN;
+       /* ...and round up to full (4k-)pages. */
+       pScrn->videoRam = (i * (pScrn->bitsPerPixel / 8) / 1024 + 3) & ~3;
+
+       /* Hmm, the I2-card hangs with more than 3k DMA-pages... */
+       if (!IMPACTSR(pImpact) && pScrn->videoRam > 3*4096)
+               pScrn->videoRam = 3*4096;

        /* get revisions of REX3, etc. */
        if ( !ImpactMapRegs(pScrn) )
@@ -454,8 +462,8 @@ ImpactPreInit(ScrnInfoPtr pScrn, int flags)
        i = xf86ValidateModes(
                        pScrn, pScrn->monitor->Modes,
                        pScrn->display->modes, clockRanges,
-                       NULL, 256, 2048,
-                       pScrn->bitsPerPixel, 128, 2048,
+                       NULL, IMPACT_FIXED_W_SCRN, 2048,
+                       pScrn->bitsPerPixel, IMPACT_FIXED_H_SCRN, 2048,
                        pScrn->display->virtualX,
                        pScrn->display->virtualY,
                        pScrn->videoRam * 1024,
@@ -811,13 +819,16 @@ ImpactMapRegs(ScrnInfoPtr pScrn)
                ErrorF("ImpactMapRegs: failed to open /dev/fb%d (%s)\n",
                        pImpact->busID , strerror(errno));
        else {
-               size_t size = IMPACTSR(pImpact) ? 0x200000:sizeof(ImpactI2Regs);
+               unsigned size = IMPACTSR(pImpact) ? 
sizeof(ImpactSRRegs):sizeof(ImpactI2Regs);
                pImpact->pImpactRegs =
                        mmap((void*)0, size, PROT_READ|PROT_WRITE,
                                MAP_SHARED, pImpact->devFD, 0);
-               if (MAP_FAILED == pImpact->pImpactRegs) {
+               if (pImpact->pImpactRegs != MAP_FAILED)
+                       ErrorF("ImpactMapRegs: mapped %u B @ %p\n",
+                               size, pImpact->pImpactRegs);
+               else {
                        ErrorF("ImpactMapRegs: Could not mmap card registers"
-                               " (0x%08lx,0x%x) (%s)\n", 0, size, 
strerror(errno));
+                               " (%p,0x%x) (%s)\n", (void*)0, size, 
strerror(errno));
                        pImpact->pImpactRegs = 0;
                }
        }
@@ -837,11 +848,15 @@ ImpactMapShadowFB(ScrnInfoPtr pScrn)
                ErrorF("ImpactMapShadowFB: failed to open fb-dev\n");
        else {
                pImpact->ShadowPtr =
-                       mmap((void*)0, 0x800000, PROT_READ|PROT_WRITE,
+                       mmap((void*)0, 1024*pScrn->videoRam, 
PROT_READ|PROT_WRITE,
                                MAP_SHARED, pImpact->devFD, 
IMPACT_FB_MMAP_OFF(3));
-               if (MAP_FAILED == pImpact->ShadowPtr) {
+               if (pImpact->ShadowPtr != MAP_FAILED)
+                       ErrorF("ImpactMapShadowFB: mapped %ukB @ %p\n",
+                               pScrn->videoRam, pImpact->ShadowPtr);
+               else {
                        ErrorF("ImpactMapShadowFB: Could not mmap shadow buffer"
-                               " (0x%08lx,0x800000) (%s)\n", 
IMPACT_FB_MMAP_OFF(3), strerror(errno));
+                               " (%p,0x%xkB) (%s)\n", 
(void*)IMPACT_FB_MMAP_OFF(3),
+                               pScrn->videoRam, strerror(errno));
                        pImpact->ShadowPtr = 0;
                }
        }
@@ -853,7 +868,7 @@ static void
 ImpactUnmapRegs(ScrnInfoPtr pScrn)
 {
        ImpactPtr pImpact = IMPACTPTR(pScrn);
-       size_t size = IMPACTSR(pImpact) ? 0x200000:sizeof(ImpactI2Regs);
+       unsigned size = IMPACTSR(pImpact) ? 
sizeof(ImpactSRRegs):sizeof(ImpactI2Regs);

        if (pImpact->pImpactRegs)
                munmap( pImpact->pImpactRegs, size );
@@ -867,7 +882,7 @@ ImpactUnmapShadowFB(ScrnInfoPtr pScrn)
        ImpactPtr pImpact = IMPACTPTR(pScrn);

        if (pImpact->ShadowPtr)
-               munmap( pImpact->ShadowPtr, 0x800000 );
+               munmap( pImpact->ShadowPtr, 1024*pScrn->videoRam );
        pImpact->ShadowPtr = 0;
 }



diff --git a/src/impact_shadow.c b/src/impact_shadow.c
index 6bc711e..9aacc4e 100644
--- a/xorg/driver/xf86-video-impact/src/impact_shadow.c Wed Jul 27 21:59:04 2011
+++ b/xorg/driver/xf86-video-impact/src/impact_shadow.c Mon Sep  5 02:11:26 2011
@@ -32,16 +32,15 @@ int ImpactDepth24Flags(void)
  * Common sanity check and adjustment for all ImpactRefreshArea...
  */
 static __inline__ int
-ImpactAdjRefreshBox(const BoxPtr obox, BoxPtr nbox)
+ImpactAdjRefreshBox(BoxPtr box, int x0, int y0)
 {
        /*
         * NB: Box defines [x1,x2[ x [x2,y2[, not [x1,x2] x [x2,y2] !
         */
-       *nbox = *obox;
-       if (nbox->x1 < 0) nbox->x1 = 0;
-       if (nbox->y1 < 0) nbox->y1 = 0;
-       if (IMPACT_FIXED_W_SCRN < nbox->x2) nbox->x2 = IMPACT_FIXED_W_SCRN;
-       if (IMPACT_FIXED_H_SCRN < nbox->y2) nbox->y2 = IMPACT_FIXED_H_SCRN;
+       if (box->x1 < x0) box->x1 = x0;
+       if (box->y1 < y0) box->y1 = y0;
+       if (x0 + IMPACT_FIXED_W_SCRN < box->x2) box->x2 = x0 + 
IMPACT_FIXED_W_SCRN;
+       if (y0 + IMPACT_FIXED_H_SCRN < box->y2) box->y2 = y0 + 
IMPACT_FIXED_H_SCRN;
        /*
         * We may need to do some adjustment, since
         * 1) the actual number of pixels *must* match the settings
@@ -49,9 +48,9 @@ ImpactAdjRefreshBox(const BoxPtr obox, BoxPtr nbox)
         * 2) we draw pairs of pixels.
         * Otherwise... (try it :))
         */
-       nbox->x1 &= ~1;
-       nbox->x2 = ++nbox->x2 & ~1;
-       return (nbox->x2 <= nbox->x1 || nbox->y2 <= nbox->y1);
+       box->x1 &= ~1;
+       box->x2 = ++box->x2 & ~1;
+       return (box->x2 <= box->x1 || box->y2 <= box->y1);
 }


@@ -59,20 +58,20 @@ ImpactAdjRefreshBox(const BoxPtr obox, BoxPtr nbox)
  * Common per-box-prologue for PIO-version of ImpactRefreshArea*
  */
 static __inline__ int
-ImpactPreRefreshBoxPIO(mgicfifo_t *cfifo, const BoxPtr obox, BoxPtr nbox)
+ImpactPreRefreshBoxPIO(mgicfifo_t *cfifo, BoxPtr box, int x0, int y0)
 {
        int h, w, i;

-       if (ImpactAdjRefreshBox(obox, nbox))
+       if (ImpactAdjRefreshBox(box, x0, y0))
                return 0;

-       w = nbox->x2 - nbox->x1;
-       h = nbox->y2 - nbox->y1;
+       w = box->x2 - box->x1;
+       h = box->y2 - box->y1;

        /* setup PIO to RE */
        impact_cmd_pp1fillmode(cfifo, 0x6300, IMPACT_LO_COPY);
-       impact_cmd_blockxystarti(cfifo, nbox->x1, nbox->y1);
-       impact_cmd_blockxyendi(cfifo, nbox->x2-1, nbox->y2-1);
+       impact_cmd_blockxystarti(cfifo, box->x1-x0, box->y1-y0);
+       impact_cmd_blockxyendi(cfifo, box->x2-x0-1, box->y2-y0-1);
        impact_cmd_fillmode(cfifo, 0x00c00000);
        impact_cmd_xfrmode(cfifo, 0x00080);
        impact_cmd_xfrsize(cfifo, w, h);
@@ -103,8 +102,11 @@ ImpactPostRefreshBoxPIO(mgicfifo_t *cfifo)
  * into 32-bpp values from the current palette in software.
  */
 static void
-ImpactRefreshArea8(ImpactPtr pImpact, mgicfifo_t *cfifo, int num, BoxPtr pbox)
+ImpactRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
 {
+       ImpactPtr pImpact = IMPACTPTR(pScrn);
+       mgicfifo_t *cfifo = IMPACTSR(pImpact) ?
+               &pImpact->pImpactRegs->sr.cfifo:&pImpact->pImpactRegs->i2.cfifo;
        unsigned pal[256];
        int i;

@@ -112,14 +114,15 @@ ImpactRefreshArea8(ImpactPtr pImpact, mgicfifo_t *cfifo, 
int num, BoxPtr pbox)
                pal[i] = ImpactGetPalReg(pImpact, i);

        for (; num--; pbox++) {
-               BoxRec sanebox;
+               BoxRec sanebox = *pbox;
                unsigned char *base;
                int dy;
                TRACEV("ImpactRefreshArea8: %d [%d..%d[x[%d..%d[\n",
                                num, pbox->x1,pbox->x2, pbox->y1,pbox->y2 );

                (*pImpact->WaitCfifoEmpty)(pImpact->pImpactRegs);
-               if (ImpactPreRefreshBoxPIO(cfifo,pbox,&sanebox) <= 0)
+               if (ImpactPreRefreshBoxPIO(cfifo,&sanebox,
+                               pScrn->frameX0, pScrn->frameY0) <= 0)
                        continue;

base = (unsigned char*)pImpact->ShadowPtr @@ -144,23 +147,13 @@ ImpactRefreshArea8(ImpactPtr pImpact, mgicfifo_t *cfifo, int num, BoxPtr pbox)
 void
 ImpactI2RefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
 {
-       if (num > 0)
-       {       ImpactPtr pImpact = IMPACTPTR(pScrn);
-               ImpactRegsPtr pImpactRegs = pImpact->pImpactRegs;
-
-               ImpactRefreshArea8(pImpact, &pImpactRegs->i2.cfifo, num, pbox);
-       }
+       if (num > 0) ImpactRefreshArea8(pScrn, num, pbox);
 }

 void
 ImpactSRRefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
 {
-       if (num > 0)
-       {       ImpactPtr pImpact = IMPACTPTR(pScrn);
-               ImpactRegsPtr pImpactRegs = pImpact->pImpactRegs;
-
-               ImpactRefreshArea8(pImpact, &pImpactRegs->sr.cfifo, num, pbox);
-       }
+       if (num > 0) ImpactRefreshArea8(pScrn, num, pbox);
 }


@@ -247,7 +240,8 @@ ImpactI2FindCflushmode(ImpactPtr pImpact)


 static __inline__ int
-ImpactRefreshBoxDMA(int isSR, mgicfifo_t *cfifo, BoxPtr box, unsigned bpitch)
+ImpactRefreshBoxDMA(int isSR, mgicfifo_t *cfifo, BoxPtr box, unsigned bpitch,
+       int x0, int y0)
 {
        int w = box->x2 - box->x1;
        int h = box->y2 - box->y1;
@@ -262,8 +256,8 @@ ImpactRefreshBoxDMA(int isSR, mgicfifo_t *cfifo, BoxPtr 
box, unsigned bpitch)
        impact_cmd_packedcolor(cfifo, 0);
        impact_cmd_red(cfifo, 0);
        impact_cmd_drbpointers(cfifo, 0xc8240);
-       impact_cmd_blockxystarti(cfifo, box->x1, box->y1);
-       impact_cmd_blockxyendi(cfifo, box->x2-1, box->y2-1);
+       impact_cmd_blockxystarti(cfifo, box->x1-x0, box->y1-y0);
+       impact_cmd_blockxyendi(cfifo, box->x2-x0-1, box->y2-y0-1);
        impact_cmd_fillmode(cfifo, 0x01400000);
        impact_cmd_xfrmode(cfifo, 0x00080);
        impact_cmd_hq_pixelformat(cfifo, 0x600);
@@ -308,19 +302,20 @@ ImpactPostRefreshBoxDMA(mgicfifo_t *cfifo)


 static void
-ImpactRefreshArea32DMA(ImpactPtr pImpact, int num, BoxPtr pbox)
+ImpactRefreshArea32DMA(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
 {
+       ImpactPtr pImpact = IMPACTPTR(pScrn);
        ImpactRegsPtr pImpactRegs = pImpact->pImpactRegs;
        mgicfifo_t *cfifo =
                IMPACTSR(pImpact) ? 
&pImpactRegs->sr.cfifo:&pImpactRegs->i2.cfifo;
        unsigned bpitch = pImpact->ShadowPitch;

        for (; num-- > 0; pbox++) {
-               BoxRec sanebox;
+               BoxRec sanebox = *pbox;
                TRACEV("ImpactRefreshArea32: %d [%d..%d]x[%d..%d]\n",
                        num, pbox->x1,pbox->x2, pbox->y1,pbox->y2);

-               if (ImpactAdjRefreshBox(pbox, &sanebox))
+               if (ImpactAdjRefreshBox(&sanebox, pScrn->frameX0, 
pScrn->frameY0))
                        continue;

                if (pImpact->FlushBoxCache)
@@ -328,7 +323,8 @@ ImpactRefreshArea32DMA(ImpactPtr pImpact, int num, BoxPtr 
pbox)
                                                &sanebox, bpitch);

                (*pImpact->WaitDMAOver)(pImpactRegs);
-               ImpactRefreshBoxDMA(IMPACTSR(pImpact), cfifo, &sanebox, bpitch);
+               ImpactRefreshBoxDMA(IMPACTSR(pImpact), cfifo, &sanebox, bpitch,
+                       pScrn->frameX0, pScrn->frameY0);
                (*pImpact->WaitDMAOver)(pImpactRegs);
                ImpactPostRefreshBoxDMA(cfifo);
        }
@@ -341,22 +337,24 @@ ImpactRefreshArea32DMA(ImpactPtr pImpact, int num, BoxPtr 
pbox)
  * for very small boxes or boxes, no wider than about a dozen pixels.
  */
 static void
-ImpactRefreshArea32PIO(ImpactPtr pImpact, int num, BoxPtr pbox)
+ImpactRefreshArea32PIO(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
 {
+       ImpactPtr pImpact = IMPACTPTR(pScrn);
        ImpactRegsPtr pImpactRegs = pImpact->pImpactRegs;
        mgicfifo_t *cfifo =
                IMPACTSR(pImpact) ? 
&pImpactRegs->sr.cfifo:&pImpactRegs->i2.cfifo;
        unsigned bpitch = pImpact->ShadowPitch;

        for (; num--; pbox++) {
-               BoxRec sanebox;
+               BoxRec sanebox = *pbox;
                unsigned char* base;
                int dy;
                TRACEV("ImpactRefreshArea32 PIO: %d [%d..%d[x[%d..%d[\n",
                                num, pbox->x1,pbox->x2, pbox->y1,pbox->y2 );

                (*pImpact->WaitCfifoEmpty)(pImpactRegs);
-               if (ImpactPreRefreshBoxPIO(cfifo,pbox,&sanebox) <= 0)
+               if (ImpactPreRefreshBoxPIO(cfifo,&sanebox,
+                               pScrn->frameX0, pScrn->frameY0) <= 0)
                        continue;

                base = (unsigned char*)pImpact->ShadowPtr
@@ -406,9 +404,9 @@ ImpactIP28RefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr 
pbox)
                        if (w < lim[h]) pio = 1;
                }
                if (pio)
-                       ImpactRefreshArea32PIO(pImpact, 1, pbox);
+                       ImpactRefreshArea32PIO(pScrn, 1, pbox);
                else
-                       ImpactRefreshArea32DMA(pImpact, 1, pbox);
+                       ImpactRefreshArea32DMA(pScrn, 1, pbox);
        }
 }

@@ -420,13 +418,42 @@ ImpactIP28RefreshArea32(ScrnInfoPtr pScrn, int num, 
BoxPtr pbox)
 void
 ImpactIP22RefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
 {
-       ImpactRefreshArea32DMA(IMPACTPTR(pScrn), num, pbox);
+       ImpactRefreshArea32DMA(pScrn, num, pbox);
 }

 void
 ImpactSRRefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
 {
-       ImpactRefreshArea32DMA(IMPACTPTR(pScrn), num, pbox);
+       ImpactRefreshArea32DMA(pScrn, num, pbox);
+}
+
+void
+ImpactAdjustFrame(int scrnIndex, int x, int y, int flags)
+{
+       static int x0, y0;
+       ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+       ImpactPtr pImpact = IMPACTPTR(pScrn);
+
+       /* Pan by reasonable steps. */
+       pScrn->frameX0 = x &= ~7;
+       pScrn->frameY0 = y &= ~7;
+
+       if (x != x0 || y != y0) {
+               BoxRec all;
+               void (*rf)(ScrnInfoPtr, int, BoxPtr) =
+                       1 == pImpact->Bpp ? 
pImpact->RefreshArea8:pImpact->RefreshArea32;
+               void (*cf)(int,char*,BoxPtr,unsigned) = pImpact->FlushBoxCache;
+
+               x0 = all.x1 = x; all.x2 = x + IMPACT_FIXED_W_SCRN;
+               y0 = all.y1 = y; all.y2 = y + IMPACT_FIXED_H_SCRN;
+
+               /* Since framebuffer is unchanged, avoid cache-flush overhead. 
*/
+               pImpact->FlushBoxCache = 0;
+               /* This takes about 36ms (DMA) to 366ms (PIO) on a IP28/195MHz. 
*/
+               (*rf)(pScrn, 1, &all);
+               pImpact->FlushBoxCache = cf;
+       }
+
 }

 /* eof */

*** eof ***
_______________________________________________
[email protected]: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to