예제 #1
0
파일: box.c 프로젝트: antrik/libggi
int GGI_m2164w_fillscreen(struct ggi_visual *vis)
{
	struct m2164w_priv *priv = M2164W_PRIV(vis);
	volatile uint8_t *mmioaddr = FBDEV_PRIV(vis)->mmioaddr;
	int virtx = LIBGGI_VIRTX(vis);
	int virty = LIBGGI_VIRTY(vis);
	int yadd = vis->w_frame_num * LIBGGI_VIRTY(vis);

	mga_gcupdate(mmioaddr, priv, LIBGGI_MODE(vis),
		     LIBGGI_GC(vis), LIBGGI_VIRTX(vis), yadd);

	if (priv->dwgctl != priv->drawboxcmd) {
		mga_waitfifo(mmioaddr, 3);
		mga_setdwgctl(mmioaddr, priv, priv->drawboxcmd);
	} else {
		mga_waitfifo(mmioaddr, 2);
	}
	mga_out32(mmioaddr, (unsigned)RS16(virtx) << 16, FXBNDRY);
	mga_out32(mmioaddr, (unsigned)(RS16(yadd) << 16) | RS16(virty + yadd),
		  YDSTLEN | EXECUTE);

	vis->accelactive = 1;

	return 0;
}
예제 #2
0
파일: line.c 프로젝트: Nekrofage/DoomRPi
int GGI_m2164w_drawline(ggi_visual *vis, int x, int y, int x2, int y2)
{
	struct m2164w_priv *priv = M2164W_PRIV(vis);
	volatile uint8_t *mmioaddr = FBDEV_PRIV(vis)->mmioaddr;
	int yadd = vis->w_frame_num * LIBGGI_VIRTY(vis);
	uint32_t dwgctl;

	if (yadd) {
		y += yadd;
		y2 += yadd;
	}

	dwgctl = OP_AUTOLINE_CLOSE | SOLID | SHFTZERO | BOP_COPY |
		BLTMOD_BFCOL;

	mga_gcupdate(mmioaddr, priv, LIBGGI_MODE(vis), LIBGGI_GC(vis),
		     LIBGGI_VIRTX(vis), yadd);

	if (priv->dwgctl != dwgctl) {
		mga_waitfifo(mmioaddr, 3);
		mga_setdwgctl(mmioaddr, priv, dwgctl);
	} else {
		mga_waitfifo(mmioaddr, 2);
	}
	mga_out32(mmioaddr, (unsigned)RS16(x) | (RS16(y) << 16), XYSTRT);
	mga_out32(mmioaddr, (unsigned)RS16(x2) | (RS16(y2) << 16),
		  XYEND | EXECUTE);

	vis->accelactive = 1;

	return 0;
}
예제 #3
0
파일: color.c 프로젝트: Nekrofage/DoomRPi
/* This could be moved to default/color as a stub.  It isn't fbdev-local. */
int GGI_fbdev_getgammamap(ggi_visual *vis, int start, int len, 
			  ggi_color *colormap)
{
	ggi_fbdev_priv *priv;
	int i;

	priv = FBDEV_PRIV(vis);
	if (colormap == NULL) return GGI_EARGINVAL;
	if (vis->gamma == NULL) return GGI_ENOMATCH; /* wrong GT if not hooked */
	if (vis->gamma->map == NULL) return GGI_EARGINVAL;
	if (start < 0 || start >= vis->gamma->len) return GGI_ENOSPACE;
	if (len > (vis->gamma->len - start)) return GGI_ENOSPACE;

	i = 0;
	do {
		if ((start + i) < vis->gamma->maxread_r)
			colormap[i].r = vis->gamma->map[start + i].r;
		if ((start + i) < vis->gamma->maxread_g)
			colormap[i].g = vis->gamma->map[start + i].g;
		if ((start + i) < vis->gamma->maxread_b)
			colormap[i].b = vis->gamma->map[start + i].b;
	} while (i++ < len);

	return 0;
}
예제 #4
0
파일: color.c 프로젝트: Nekrofage/DoomRPi
/* Free palette/gamma entries.  Called before changing modes. */
void GGI_fbdev_color_free(ggi_visual *vis)
{
	ggi_fbdev_priv *priv = FBDEV_PRIV(vis);

	/* Unhook the entry points */
	LIBGGI_PAL(vis)->setPalette = NULL;
	LIBGGI_PAL(vis)->getPrivSize = NULL;
	vis->opcolor->getpalvec = NULL; /* ##### */
	vis->opcolor->setgammamap = NULL;
	vis->opcolor->getgammamap = NULL;

	/* Free the convenience array */
	free (LIBGGI_PAL(vis)->priv);
	LIBGGI_PAL(vis)->priv = NULL;
	
	/* 
	 * Clean up any pointers that could be problematic if left set.
	 * Technically they should be taken care of below, but why not...
	 */
	priv->reds = priv->greens = priv->blues = NULL;
	vis->gamma = NULL;

	/* Free the storage area for the palettes. */
	priv->gamma.map = priv->orig_cmap = NULL;
	free (LIBGGI_PAL(vis)->clut.data);
	LIBGGI_PAL(vis)->clut.data = NULL;
}
예제 #5
0
파일: box.c 프로젝트: antrik/libggi
int GGI_m2164w_drawbox(struct ggi_visual *vis, int x, int y, int w, int h)
{
	if (w > 0 && h > 0) {	/* 0 width is not OK! */
		struct m2164w_priv *priv = M2164W_PRIV(vis);
		volatile uint8_t *mmioaddr = FBDEV_PRIV(vis)->mmioaddr;
		int yadd = vis->w_frame_num * LIBGGI_VIRTY(vis);

		y += yadd;

		mga_gcupdate(mmioaddr, priv, LIBGGI_MODE(vis), LIBGGI_GC(vis),
			     LIBGGI_VIRTX(vis), yadd);

		if (priv->dwgctl != priv->drawboxcmd) {
			mga_waitfifo(mmioaddr, 3);
			mga_setdwgctl(mmioaddr, priv, priv->drawboxcmd);
		} else {
			mga_waitfifo(mmioaddr, 2);
		}
		mga_out32(mmioaddr, (unsigned)(RS16(x + w) << 16) | RS16(x),
			  FXBNDRY);
		mga_out32(mmioaddr, (unsigned)(RS16(y) << 16) | RS16(h),
			  YDSTLEN | EXECUTE);

		vis->accelactive = 1;
	}

	return 0;
}
예제 #6
0
파일: hline.c 프로젝트: Nekrofage/DoomRPi
int GGI_mga_g400_drawhline(ggi_visual *vis, int x, int y, int w)
{
	struct mga_g400_priv *priv = MGA_G400_PRIV(vis);
	volatile uint8_t *mmioaddr = FBDEV_PRIV(vis)->mmioaddr;
	int yadd = vis->w_frame_num * LIBGGI_VIRTY(vis);
	uint32_t dwgctl;

	y += yadd;
	y = RS16(y) << 16;

	dwgctl = OP_AUTOLINE_CLOSE | SOLID | SHFTZERO | BOP_COPY |
		BLTMOD_BFCOL;

	mga_gcupdate(mmioaddr, priv, LIBGGI_MODE(vis), LIBGGI_GC(vis),
		     LIBGGI_VIRTX(vis), yadd);

	if (priv->dwgctl != dwgctl) {
		mga_waitfifo(mmioaddr, 3);
		mga_setdwgctl(mmioaddr, priv, dwgctl);
	} else {
		mga_waitfifo(mmioaddr, 2);
	}
	/* y has been shifted above */
	mga_out32(mmioaddr, (unsigned)RS16(x) | y, XYSTRT);
	mga_out32(mmioaddr, (unsigned)RS16(x + w-1) | y, XYEND | EXECUTE);

	vis->accelactive = 1;

	return 0;
}
예제 #7
0
파일: hline.c 프로젝트: antrik/libggi
int GGI_3dlabs_pm2_drawhline(struct ggi_visual *vis, int x, int y, int w)
{
    struct _3dlabs_pm2_priv *priv = PM2_PRIV(vis);
    volatile uint8_t *mmioaddr = FBDEV_PRIV(vis)->mmioaddr;
    int yadd = vis->w_frame_num * LIBGGI_VIRTY(vis);

    DPRINT_DRAW("drawhline(%p, %i,%i, %i) entered\n",
                vis, x,y, w);

    y += yadd;

    pm2_gcupdate(mmioaddr, priv, LIBGGI_MODE(vis), LIBGGI_GC(vis),
                 yadd);

    pm2_waitfifo(mmioaddr, 6);
    pm2_out32(mmioaddr, x << 16, PM2R_START_X_DOM);
    pm2_out32(mmioaddr, y << 16, PM2R_START_Y);

    /* Horizontal */
    pm2_out32(mmioaddr, 1 << 16, PM2R_D_X_DOM);
    pm2_out32(mmioaddr, 0 << 16, PM2R_D_Y);

    pm2_out32(mmioaddr, w, PM2R_COUNT);
    pm2_out32(mmioaddr, PM2F_RENDER_LINE
              | PM2F_RENDER_XPOSITIVE | PM2F_RENDER_YPOSITIVE,
              PM2R_RENDER);

    vis->accelactive = 1;

    return 0;
}
예제 #8
0
파일: visual.c 프로젝트: Nekrofage/DoomRPi
static int
m2164w_idleaccel(ggi_visual *vis)
{
	DPRINT_DRAW("m2164w_idleaccel(%p) called \n", vis);

	mga_waitidle(FBDEV_PRIV(vis)->mmioaddr);
	
	vis->accelactive = 0;

	return 0;
}
예제 #9
0
파일: visual.c 프로젝트: Nekrofage/DoomRPi
static int do_cleanup(ggi_visual *vis)
{
	ggi_fbdev_priv *fbdevpriv = FBDEV_PRIV(vis);
	struct m2164w_priv *priv = NULL;
	int i;

	DPRINT_MISC("mga-2164w: Starting cleanup\n");

	if (fbdevpriv != NULL) {
		priv = M2164W_PRIV(vis);
	}

	/* We may be called more than once due to the LibGG cleanup stuff */
	if (priv == NULL) return 0;

	/* Restore OPMODE and terminate any pending DMA operations
	   Manual says we should write to byte 0 to terminate DMA sequence,
	   but it doesn't say whether a 8 bit access is required, or if any
	   access will do. We play it safe here... */
	mga_out8(fbdevpriv->mmioaddr, priv->origopmode & 0xff, OPMODE);
	mga_out16(fbdevpriv->mmioaddr, priv->origopmode, OPMODE);
	mga_waitidle(fbdevpriv->mmioaddr);

	munmap((void*)fbdevpriv->mmioaddr, fbdevpriv->orig_fix.mmio_len);
	DPRINT_MISC("mga-2164w: Unmapped MMIO\n");

	/* Free DB resource structures */
	for (i = LIBGGI_APPLIST(vis)->num-1; i >= 0; i--) {
		if (LIBGGI_APPBUFS(vis)[i]->resource) {
			free(LIBGGI_APPBUFS(vis)[i]->resource);
			LIBGGI_APPBUFS(vis)[i]->resource = NULL;
		}
	}

	free(priv);
	FBDEV_PRIV(vis)->accelpriv = NULL;

	ggUnregisterCleanup((ggcleanup_func *)do_cleanup, vis);

	return 0;
}
예제 #10
0
static int GGIopen(ggi_visual *vis, struct ggi_dlhandle *dlh,
		   const char *args, void *argptr, uint32_t *dlret)
{
  struct fbdev_directfb_global *globals;

  globals = argptr;
  globals->dfb_config_ptr =    &dfb_config;
  globals->dfb_fbdev_ptr  =    &dfb_fbdev;
  ggi_fbdev_dfb_framebuffer_base = FBDEV_PRIV(vis)->fb_ptr;

  return 0;
}
예제 #11
0
파일: color.c 프로젝트: Nekrofage/DoomRPi
/* In fbdev the gamma uses the same interface as the palette.
 * Therefore, no simultaneous use of 8-bit LUT and gamma.
 *
 * Since this is the case we reuse some of the priv/vis palette members.
 *
 */
static int GGI_fbdev_setgammamap(ggi_visual *vis, int start, int len, 
				 const ggi_color *colormap)
{
	ggi_fbdev_priv *priv;
	struct fb_cmap gam;
	int i;

	priv = FBDEV_PRIV(vis);
	if (colormap == NULL) return GGI_EARGINVAL;
	if (vis->gamma == NULL) return GGI_ENOMATCH; /* Wrong GT if not hooked */
	if (start < 0 || start >= priv->gamma.len) return GGI_ENOSPACE;
	if (len > (priv->gamma.len - start)) return GGI_ENOSPACE;

	gam.start = start;
	gam.len = len;
	gam.red = priv->reds;
	gam.green = priv->greens;
	gam.blue = priv->blues;
	gam.transp = NULL;

	i = 0;
	do {
		if ((start + i) < priv->gamma.maxwrite_r)
			vis->gamma->map[start + i].r = priv->reds[start + i]
			  = colormap[i].r;
		if ((start + i) < priv->gamma.maxwrite_g)
			vis->gamma->map[start + i].g = priv->greens[start + i]
			  = colormap[i].g;
		if ((start + i) < priv->gamma.maxwrite_b)
			vis->gamma->map[start + i].b = priv->blues[start + i]
			  = colormap[i].b;
	} while (i++ < len);

	if (fbdev_doioctl(vis, FBIOPUTCMAP, &gam) < 0) {
		DPRINT_COLOR("display-fbdev: PUTCMAP failed.");
		return -1;
	}
	return 0;
}
예제 #12
0
파일: color.c 프로젝트: Nekrofage/DoomRPi
static int GGI_fbdev_setPalette(ggi_visual *vis, size_t start, size_t size, 
			       const ggi_color *colormap)
{
	ggi_fbdev_priv *priv = FBDEV_PRIV(vis);
	struct fb_cmap cmap;
	
	int len = (int)size;
	
	const ggi_color* src = colormap;
	
	DPRINT_COLOR("display-fbdev: SetPalette(%d,%d)\n", start, size);
	
	memcpy(LIBGGI_PAL(vis)->clut.data+start, colormap, size*sizeof(ggi_color));

	if (!priv->ismapped) return 0;

	cmap.start  = start;
	cmap.len    = size;
	cmap.red    = priv->reds + start;
	cmap.green  = priv->greens + start;
	cmap.blue   = priv->blues + start;
	cmap.transp = NULL;

	for (; len > 0; start++, src++, len--) {
		priv->reds[start]   = src->r;
		priv->greens[start] = src->g;
		priv->blues[start]  = src->b;
	}

	if (fbdev_doioctl(vis, FBIOPUTCMAP, &cmap) < 0) {
		DPRINT_COLOR("display-fbdev: PUTCMAP failed.");
		return -1;
	}

	return 0;
}
예제 #13
0
파일: visual.c 프로젝트: Nekrofage/DoomRPi
static int GGIopen(ggi_visual *vis, struct ggi_dlhandle *dlh,
		   const char *args, void *argptr, uint32_t *dlret)
{
	ggi_fbdev_priv *fbdevpriv = FBDEV_PRIV(vis);
	struct m2164w_priv *priv;
	unsigned long usedmemend;
	size_t fontlen;
	int pixbytes;
	int fd = LIBGGI_FD(vis);
	int i;

	if (GT_SIZE(LIBGGI_GT(vis)) % 8 != 0 ||
	    GT_SIZE(LIBGGI_GT(vis)) > 32 ||
	    GT_SIZE(LIBGGI_GT(vis)) < 8) {
		/* Unsupported mode */
		return GGI_ENOFUNC;
	}
	pixbytes = GT_ByPP(LIBGGI_GT(vis));

	priv = malloc(sizeof(struct m2164w_priv));
	if (priv == NULL) {
		return GGI_ENOMEM;
	}

	fbdevpriv->mmioaddr = mmap(NULL, fbdevpriv->orig_fix.mmio_len,
				   PROT_READ | PROT_WRITE, MAP_SHARED,
				   fd, (signed)fbdevpriv->orig_fix.smem_len);
	if (fbdevpriv->mmioaddr == MAP_FAILED) {
		/* Can't mmap() MMIO region - bail out */
		DPRINT_LIBS("mga-2164w: Unable to map MMIO region: %s\n"
			       "          fd: %d, len: %ld, offset: %ld\n",
			       strerror(errno), fd,
			       fbdevpriv->orig_fix.mmio_len,
			       fbdevpriv->orig_fix.smem_len);
		fbdevpriv->mmioaddr = NULL;
		free(priv);
		return GGI_ENODEVICE;
	}

	DPRINT_MISC("mga-2164w: Mapped MMIO region at %p\n",
		       fbdevpriv->mmioaddr);

	/* Set up DirectBuffers */
	for (i=0; i < LIBGGI_MODE(vis)->frames; i++) {
		ggi_directbuffer *buf = LIBGGI_APPBUFS(vis)[i];
		ggi_resource *res;
		
		res = malloc(sizeof(ggi_resource));
		if (res == NULL) {
			do_cleanup(vis);
			return GGI_ENOMEM;
		}
		buf->resource = res;
		buf->resource->acquire = m2164w_acquire;
		buf->resource->release = m2164w_release;
		buf->resource->self = buf;
		buf->resource->priv = vis;
		buf->resource->count = 0;
		buf->resource->curactype = 0;
	}

	priv->drawboxcmd
		= BOP_COPY | SHFTZERO | SGNZERO | ARZERO | SOLID | OP_TRAP;
	if (pixbytes != 3) {
		switch (fbdevpriv->orig_fix.accel) {	
		case FB_ACCEL_MATROX_MGA2064W:
		case FB_ACCEL_MATROX_MGA1064SG:
		case FB_ACCEL_MATROX_MGA2164W:
		case FB_ACCEL_MATROX_MGA2164W_AGP:
			/* Use block mode */
			priv->drawboxcmd |= ATYPE_BLK;
			break;
		default:
			/* For now - assume SDRAM for other cards */
			break;
		}
	}
	priv->dwgctl = 0;
	priv->oldfgcol = LIBGGI_GC(vis)->fg_color - 1;
	priv->oldbgcol = LIBGGI_GC(vis)->bg_color - 1;
	priv->oldtl.x = -1;
	priv->oldtl.y = -1;
	priv->oldbr.x = -1;
	priv->oldbr.y = -1;
	priv->oldyadd = -1;
	priv->curopmode = priv->origopmode = mga_in16(fbdevpriv->mmioaddr, OPMODE);
	/* Use the 7k Pseudo-DMA window */
	priv->dmaaddr = (void*)fbdevpriv->mmioaddr;
	priv->dma_len = 0x1c00;

	vis->needidleaccel = 1;
	fbdevpriv->idleaccel = m2164w_idleaccel;

	/* Accelerate fonts if possible */
	priv->font = (uint8_t *)(font);
	usedmemend = LIBGGI_MODE(vis)->frames *
		fbdevpriv->fix.line_length * LIBGGI_VIRTY(vis);
	fontlen = 256*8;
	priv->fontoffset = fbdevpriv->orig_fix.smem_len - fontlen;
	priv->fontoffset &= ~127; /* Align */
	DPRINT_MISC("mga-2164w: usedmemend: %ld, fontoffset: %ld\n",
		       usedmemend, priv->fontoffset);
	if (usedmemend <= priv->fontoffset) {
		memcpy((uint8_t*)fbdevpriv->fb_ptr + priv->fontoffset,
		       font, fontlen);
		priv->fontoffset *= 8; /* In bits */
		priv->charadd = FWIDTH*FHEIGHT;
		vis->opdraw->putc = GGI_m2164w_fastputc;
		vis->opdraw->puts = GGI_m2164w_fastputs;
		DPRINT_MISC("mga-2164w: Using fast chars\n");
	} else {
		priv->fontoffset = 0;
		vis->opdraw->putc = GGI_m2164w_putc;
		vis->opdraw->puts = GGI_m2164w_puts;
		DPRINT_MISC("mga-2164w: Using slow chars\n");
	}

	/* Save previous function pointers */
	priv->crossblit = vis->opdraw->crossblit;

	/* Initialize function pointers */
	vis->opdraw->getcharsize= GGI_m2164w_getcharsize;
	vis->opdraw->drawhline = GGI_m2164w_drawhline;
	vis->opdraw->drawvline = GGI_m2164w_drawvline;
	vis->opdraw->drawline = GGI_m2164w_drawline;
	vis->opdraw->drawbox = GGI_m2164w_drawbox;
	vis->opdraw->copybox = GGI_m2164w_copybox;
	vis->opdraw->fillscreen = GGI_m2164w_fillscreen;
	/* The crossblit in linear-* is faster on truecolor modes! */
	if (GT_SCHEME(LIBGGI_GT(vis)) == GT_PALETTE ||
	    GT_SCHEME(LIBGGI_GT(vis)) == GT_STATIC_PALETTE) {
		vis->opdraw->crossblit = GGI_m2164w_crossblit;
	}

	FBDEV_PRIV(vis)->accelpriv = priv;

	/* Register cleanup handler */
	ggRegisterCleanup((ggcleanup_func *)do_cleanup, vis);

	*dlret = GGI_DL_OPDRAW;
	return 0;
}
예제 #14
0
파일: copybox.c 프로젝트: Nekrofage/DoomRPi
int GGI_mga_g400_copybox(ggi_visual *vis, int x, int y, int w, int h,
		       int dstx, int dsty)
{
	struct mga_g400_priv *priv = MGA_G400_PRIV(vis);
	volatile uint8_t *mmioaddr = FBDEV_PRIV(vis)->mmioaddr;
	int virtx = LIBGGI_VIRTX(vis);
	int yadd = vis->w_frame_num * LIBGGI_VIRTY(vis);
	int32_t ar5 = virtx;
	int32_t begin, end;
	uint32_t sgn = 0;
	uint32_t dwgctl;

#define COPY_LEFT	1
#define COPY_UP		4

	dsty += yadd;
	y += vis->r_frame_num*LIBGGI_VIRTY(vis);

	if (dsty > y) {
		sgn |= COPY_UP;
		y += h - 1;
		dsty += h - 1;
		ar5 = - ar5;
	}
	
	begin = end = y * virtx + x;

	w--;
	if (dstx > x) {
		sgn |= COPY_LEFT;
		begin += w;
	} else {
		end += w;
	}

	dwgctl = BLTMOD_BFCOL | BOP_COPY | SHFTZERO | OP_BITBLT
		| (sgn ? 0 : SGNZERO);

	mga_gcupdate(mmioaddr, priv, LIBGGI_MODE(vis),
		     LIBGGI_GC(vis), virtx, yadd);

	if (priv->dwgctl != dwgctl) {
		if (sgn) mga_waitfifo(mmioaddr, 7);
		else mga_waitfifo(mmioaddr, 6);
		mga_setdwgctl(mmioaddr, priv, dwgctl);
	} else {
		if (sgn) mga_waitfifo(mmioaddr, 6);
		else mga_waitfifo(mmioaddr, 5);
	}
	if (sgn) {
		mga_out32(mmioaddr, sgn, SGN);
	}
#if 0
	mga_out32(mmioaddr, RS18(end), AR0);
	mga_out32(mmioaddr, RS24(begin), AR3);
	mga_out32(mmioaddr, RS18(ar5), AR5);
#else
	mga_out32(mmioaddr, RS22(end), AR0);
	mga_out32(mmioaddr, RS24(begin), AR3);
	mga_out32(mmioaddr, RS22(ar5), AR5);
#endif
	mga_out32(mmioaddr, (unsigned)(RS16(dstx + w) << 16) | RS16(dstx),
		  FXBNDRY);
	mga_out32(mmioaddr, (unsigned)(RS16(dsty) << 16) | RS16(h), 
		  YDSTLEN | EXECUTE);

	vis->accelactive = 1;

	return 0;
}
예제 #15
0
static inline void
dbblit_32bpp(ggi_visual *src, int sx, int sy, int w, int h, 
	     ggi_visual *dst, int dx, int dy, uint32_t srcfmt)
{
	struct m2164w_priv *priv = M2164W_PRIV(dst);
	volatile uint8_t *mmioaddr = FBDEV_PRIV(dst)->mmioaddr;
	int yadd = dst->w_frame_num * LIBGGI_VIRTY(dst);
	volatile uint32_t *dstptr;
	uint32_t dwgctl, bltmod = BLTMOD_BU32RGB;
	uint16_t opmode;
	uint8_t *srcptr;
	uint32_t *srcptr32;
	int srcinc;
	int maxpix;

	dstptr = priv->dmaaddr;
	srcinc = LIBGGI_FB_R_STRIDE(src);
	srcptr = (uint8_t*) LIBGGI_CURWRITE(src) + sy*srcinc + sx*4;
	srcinc -= w*4;
	maxpix = priv->dma_len/4;

	dy += yadd;

	switch (srcfmt) {
#if 0 /* This case is the default. */
	case GGI_DB_STD_24a32p8r8g8b8:
		bltmod = BLTMOD_BU32RGB;
		break;
#endif
	case GGI_DB_STD_24a32p8b8g8r8:
		bltmod = BLTMOD_BU32BGR;
		break;
	}

	dwgctl = bltmod | BOP_COPY | SHFTZERO | OP_ILOAD | SGNZERO;
#ifdef GGI_BIG_ENDIAN
	opmode = OPMODE_DMA_BLIT_WRITE | OPMODE_DMA_BE_32BPP;
#else
	opmode = OPMODE_DMA_BLIT_WRITE | OPMODE_DMA_LE;
#endif

	mga_gcupdate(mmioaddr, priv, LIBGGI_MODE(dst), LIBGGI_GC(dst),
		     LIBGGI_VIRTX(dst), yadd);

	if (priv->curopmode != opmode) {
		priv->curopmode = opmode;
		mga_waitidle(mmioaddr);
		mga_out16(mmioaddr, opmode, OPMODE);
	}
	if (priv->dwgctl != dwgctl) {
		mga_waitfifo(mmioaddr, 6);
		mga_setdwgctl(mmioaddr, priv, dwgctl);
	} else {
		mga_waitfifo(mmioaddr, 5);
	}
	mga_out32(mmioaddr, RS18(w-1), AR0);
	mga_out32(mmioaddr, 0, AR3);
	mga_out32(mmioaddr, 0, AR5);
	mga_out32(mmioaddr, (unsigned)(RS16(dx + w - 1) << 16) | RS16(dx), 
		  FXBNDRY);
	mga_out32(mmioaddr, (unsigned)(RS16(dy) << 16) | RS16(h),
		  YDSTLEN | EXECUTE);

	dst->accelactive = 1;

	if (w > maxpix) {
		while (h--) {
			int tmpw = w;

			while (tmpw) {
				int tmpw2 = (tmpw > maxpix ? maxpix : tmpw);

				tmpw -= tmpw2;
				while (tmpw2--) {
					srcptr32 = (uint32_t *)srcptr;
					*(dstptr++) = *(srcptr32++);
					srcptr = (uint8_t *)srcptr32;
				}
				dstptr = priv->dmaaddr;
			}
			srcptr += srcinc;
		}
	} else {
		while (h--) {
			int tmpw = w;

			while (tmpw--) {
				srcptr32 = (uint32_t *)srcptr;
				*(dstptr++) = *(srcptr32++);
				srcptr = (uint8_t *)srcptr32;
			}
			srcptr += srcinc;
			dstptr = priv->dmaaddr;
		}
	}
}
예제 #16
0
파일: color.c 프로젝트: Nekrofage/DoomRPi
void GGI_fbdev_color_setup(ggi_visual *vis)
{
	ggi_fbdev_priv *priv = FBDEV_PRIV(vis);
	struct fb_cmap cmap;
	int len;

	/* We rely on caller to have deallocated old storage */
	priv->orig_cmap = LIBGGI_PAL(vis)->clut.data = priv->gamma.map = NULL; 
	vis->gamma = NULL;
	priv->reds = priv->greens = priv->blues = NULL;
	priv->gamma.maxread_r = priv->gamma.maxread_g = 
	  priv->gamma.maxread_b = priv->gamma.maxread_r = 
	  priv->gamma.maxwrite_g = priv->gamma.maxwrite_b = -1;
	priv->gamma.len = priv->gamma.start = 0;

	if (!priv->var.bits_per_pixel) return;
	if (priv->fix.visual == FB_VISUAL_TRUECOLOR) return; /* No gamma. */

	if (priv->fix.visual == FB_VISUAL_DIRECTCOLOR) {

		DPRINT("display-fbdev: trying gamma.\n");

		priv->gamma.maxwrite_r = priv->gamma.maxread_r = 
			1 << priv->var.red.length;
		priv->gamma.maxwrite_g = priv->gamma.maxread_g = 
			1 << priv->var.green.length;
		priv->gamma.maxwrite_b = priv->gamma.maxread_b = 
			1 << priv->var.blue.length;
		
		len = priv->gamma.maxread_r;
		if (len < priv->gamma.maxread_g) 
			len = priv->gamma.maxread_g;
		if (len < priv->gamma.maxread_b)
			len = priv->gamma.maxread_b;
		priv->gamma.len = len;
		priv->gamma.start = 0;
		
		LIBGGI_PAL(vis)->clut.size = len * 2;
		LIBGGI_PAL(vis)->clut.data = calloc(len * 2 /* orig */, sizeof(ggi_color));
		if (LIBGGI_PAL(vis)->clut.data == NULL) return;
		priv->gamma.map = LIBGGI_PAL(vis)->clut.data;
		/* All of the above is moot until we turn it on like so: */
		vis->gamma = &(priv->gamma);
	} else {

		DPRINT("display-fbdev: trying palette.\n");

		len = 1 << priv->var.bits_per_pixel;
		LIBGGI_PAL(vis)->clut.size = len * 2;
		LIBGGI_PAL(vis)->clut.data = calloc(len * 2 /* orig */, sizeof(ggi_color));
		if (LIBGGI_PAL(vis)->clut.data == NULL) return;
	}

	cmap.start = 0;
	cmap.len   = len;
	cmap.red   = calloc(len * 3, 2);
	if (cmap.red == NULL) goto bail;
	cmap.green = cmap.red + len;
	cmap.blue  = cmap.green + len;
	cmap.transp = NULL;
	
	if (ioctl(LIBGGI_FD(vis), FBIOGETCMAP, &cmap) < 0) {
		DPRINT_COLOR("display-fbdev: GETCMAP failed.\n");
		free(cmap.red);
		goto bail;
	} 

	priv->orig_cmap = LIBGGI_PAL(vis)->clut.data + len;

	if (vis->gamma != NULL) {

		DPRINT_COLOR("display-fbdev: Saved gamma (len=%d/%d/%d).\n",
				priv->gamma.maxread_r, priv->gamma.maxread_g,
				priv->gamma.maxread_b);

		while (len--) {
			if (len < priv->gamma.maxread_r) 
				priv->orig_cmap[len].r = cmap.red[len];
			if (len < priv->gamma.maxread_g) 
				priv->orig_cmap[len].g = cmap.green[len];
			if (len < priv->gamma.maxread_b) 
				priv->orig_cmap[len].b = cmap.blue[len];
		}
		vis->opcolor->getgammamap = GGI_fbdev_getgammamap;
		vis->opcolor->setgammamap = GGI_fbdev_setgammamap;
	}
	else {
		DPRINT_COLOR("display-fbdev: Saved palette (len=%d).\n", 
				len);
		while (len--) {
			priv->orig_cmap[len].r = cmap.red[len];
			priv->orig_cmap[len].g = cmap.green[len];
			priv->orig_cmap[len].b = cmap.blue[len];
		}
		if (priv->fix.visual != FB_VISUAL_STATIC_PSEUDOCOLOR) {
			LIBGGI_PAL(vis)->setPalette  = GGI_fbdev_setPalette;
			LIBGGI_PAL(vis)->getPrivSize =  GGI_fbdev_getPrivSize;
		}
	}

	LIBGGI_PAL(vis)->priv = cmap.red;

	priv->reds = cmap.red;
	priv->greens = cmap.green;
	priv->blues = cmap.blue;
	return;

 bail:
	free(LIBGGI_PAL(vis)->clut.data);
	LIBGGI_PAL(vis)->clut.data = NULL;
	vis->gamma = NULL;
	return;

}
예제 #17
0
파일: hline.c 프로젝트: antrik/libggi
int GGI_3dlabs_pm2_puthline(struct ggi_visual *vis, int x, int y, int w,
                            const void *buf)
{
    struct _3dlabs_pm2_priv *priv = PM2_PRIV(vis);
    volatile uint8_t *mmioaddr = FBDEV_PRIV(vis)->mmioaddr;
    int yadd = vis->w_frame_num * LIBGGI_VIRTY(vis);
    int count;
#if 0
    uint32_t srcwidth;
#endif
    const uint8_t *src;
    const uint32_t *srcp;
    uint32_t *dest;


    /* 0 width not OK */
    if (w == 0) return 0;

    DPRINT_DRAW("puthline(%p, %i,%i, %i, %p) entered\n",
                vis, x, y, w, buf);

    y += yadd;

#if 0
    if (LIBGGI_GT(vis) & GT_SUB_PACKED_GETPUT) {
        srcwidth = GT_ByPPP(w, LIBGGI_GT(vis));
    } else {
        srcwidth = w * GT_ByPP(LIBGGI_GT(vis));
    }
#endif

    pm2_gcupdate(mmioaddr, priv, LIBGGI_MODE(vis), LIBGGI_GC(vis),
                 yadd);

    pm2_waitfifo(mmioaddr, 6);

    /* Setting for Image download from Host */
    pm2_out32(mmioaddr, priv->pprod, PM2R_FB_READ_MODE);
    pm2_out32(mmioaddr, UNIT_ENABLE, PM2R_FB_WRITE_MODE);
    pm2_out32(mmioaddr, UNIT_DISABLE, PM2R_COLOR_DDA_MODE);

    pm2_loadcoord(mmioaddr, x,y, w, 1);
    pm2_out32(mmioaddr,
              PM2F_RENDER_RECTANGLE | PM2F_RENDER_XPOSITIVE
              | PM2F_RENDER_YPOSITIVE | PM2F_RENDER_SYNC_ON_HOST,
              PM2R_RENDER);

    src = (const uint8_t *)buf;
    dest = (uint32_t *)((volatile uint8_t *)
                        (mmioaddr + PM2R_OUT_FIFO + 4));

    count = w;
    srcp = (const uint32_t *)src;
    while (count >= priv->fifosize) {
        pm2_waitfifo(mmioaddr, priv->fifosize);
        /* 0x0155 is the TAG for FBSourceData */
        pm2_out32(mmioaddr,
                  ((priv->fifosize - 2) << 16) | 0x0155,
                  PM2R_OUT_FIFO);

        pm2_move32(dest, srcp, priv->fifosize - 1);

        count -= priv->fifosize - 1;
        srcp += priv->fifosize - 1;
    }
    if (count) {
        pm2_waitfifo(mmioaddr, count + 1);
        pm2_out32(mmioaddr,
                  ((count - 1) << 16) | 0x0155,
                  PM2R_OUT_FIFO);

        pm2_move32(dest, srcp, count);
    }

    /* Re-enable fb readmode when done */
    pm2_waitfifo(mmioaddr, 2);
    pm2_out32(mmioaddr, 0, PM2R_WAIT_FOR_COMPLETION);


    priv->oldfgcol = ~priv->oldfgcol;

    vis->accelactive = 1;

    return 0;
}