[PATCH 2/2 xf86-video-impact] Virtual screen
peter fuerst
post at pfrst.de
Tue Sep 6 13:47:49 PDT 2011
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 <post at pfrst.de>
---
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 ***
More information about the xorg-devel
mailing list