Esempio n. 1
0
File: trle.c Progetto: antrik/libggi
int
GGI_vnc_trle(ggi_vnc_client *client, ggi_rect *update)
{
	struct trle_ctx_t *ctx = client->trle_ctx;
	struct ggi_visual *cvis;
	const ggi_directbuffer *db;
	ggi_graphtype gt;
	int bpp;
	int cbpp;
	int count;
	unsigned char *buf;
	unsigned char *header;
	int xtiles, ytiles;
	unsigned char *work;
	int lower = 1;
	int tile_param;
	tile_func *tile;
	int xt, yt;
	int xs, ys;
	int xs_last, ys_last;
	int stride;
	ggi_rect vupdate;
	int d_frame_num;

	DPRINT("trle update %dx%d - %dx%d\n",
		update->tl.x, update->tl.y,
		update->br.x, update->br.y);

	cvis = GGI_vnc_encode_init(client, update, &vupdate, &d_frame_num);

	gt = LIBGGI_GT(cvis);

	bpp = GT_ByPP(gt);
	if (bpp == 4) {
		ggi_pixel mask =
			LIBGGI_PIXFMT(cvis)->red_mask |
			LIBGGI_PIXFMT(cvis)->green_mask |
			LIBGGI_PIXFMT(cvis)->blue_mask;
		if (!(mask & 0xff000000))
			cbpp = 3;
		else if (!(mask & 0xff)) {
			lower = 0;
			cbpp = 3;
		}
		else
			cbpp = 4;
	}
	else
		cbpp = bpp;
	count = ggi_rect_width(&vupdate) * ggi_rect_height(&vupdate);
	xtiles = (ggi_rect_width(&vupdate) + 15) / 16;
	ytiles = (ggi_rect_height(&vupdate) + 15) / 16;
	GGI_vnc_buf_reserve(&client->wbuf, client->wbuf.size + 12
		+ xtiles * ytiles + count * cbpp);
	header = &client->wbuf.buf[client->wbuf.size];
	insert_header(header, &update->tl, &vupdate, 15); /* trle */

	client->wbuf.size += 12;
	work = &client->wbuf.buf[client->wbuf.size];
	buf = work;

	db = ggiDBGetBuffer(cvis->instance.stem, d_frame_num);
	ggiResourceAcquire(db->resource, GGI_ACTYPE_READ);

	if (bpp == 1) {
		tile_param = 0;
		tile = tile_8;
	}
	else if (bpp == 2) {
		tile_param = client->reverse_endian;
		tile = tile_16;
	}
	else if (cbpp == 3 && !client->reverse_endian) {
		tile_param = lower;
		tile = tile_24;
	}
	else if (cbpp == 3) {
		tile_param = lower;
		tile = tile_rev_24;
	}
	else {
		tile_param = client->reverse_endian;
		tile = tile_32;
	}

	stride = LIBGGI_VIRTX(cvis);

	ys_last = ggi_rect_height(&vupdate) & 0xf;
	if (!ys_last)
		ys_last = 16;
	xs_last = ggi_rect_width(&vupdate) & 0xf;
	if (!xs_last)
		xs_last = 16;

	ys = 16;
	for (yt = 0; yt < ytiles; ++yt) {
		if (yt == ytiles - 1)
			ys = ys_last;
		xs = 16;
		for (xt = 0; xt < xtiles; ++xt) {
			if (xt == xtiles - 1)
				xs = xs_last;
			tile(ctx, &buf, (uint8_t *)db->read +
				((vupdate.tl.y + 16 * yt) * stride +
				 vupdate.tl.x + 16 * xt) * bpp,
				xs, ys, stride, tile_param);
		}
	}

	ggiResourceRelease(db->resource);

	client->wbuf.size += buf - work;
	return 1;
}
Esempio n. 2
0
int GGI_kgi_radeon_putvline_3d(ggi_visual *vis, int x, int y, int h, const void *buf)
{
	int wb, w32;
	radeon_context_t *ctx;

	struct {
		cce_type3_header_t h;
		cce_se_se_vtx_fmt_t vfmt;
		cce_se_se_vf_cntl_t vctl;
		/* TODO: this wrongly assumes float is 32 bit everywhere. */
		float v1x, v1y, v1s, v1t; /* v1z; */ 
		float v2x, v2y, v2s, v2t; /* v2z; */ 
		float v3x, v3y, v3s, v3t; /* v3z; */ 
	} packet;
	struct {
		cce_type0_header_t h;
		uint32_t txoffset;
	} offsetpkt;


	ctx = RADEON_CONTEXT(vis);

	wb = GT_ByPP(LIBGGI_GT(vis)) * h;
	w32 = ((wb + 31) / 32) * 32;

	if (ctx->ctx_loaded != RADEON_PUT_CTX) {
		ctx->put_ctx.tex_size.usize = w32 / GT_ByPP(LIBGGI_GT(vis));
		ctx->put_ctx.tex_size.vsize = 1;
		ctx->put_ctx.txpitch.txpitch = (w32/32) - 1;
		RADEON_RESTORE_CTX(vis, RADEON_PUT_CTX);
	} else {
		struct {
			cce_type0_header_t h;
			pp_tex_size_t tex_size;
			pp_txpitch_t txpitch;
		} packet2;

		memset(&packet2, 0, sizeof(packet2));

		packet2.h.base_index = PP_TEX_SIZE_1 >> 2;
		packet2.h.count = 1;
		packet2.tex_size.usize = w32 / GT_ByPP(LIBGGI_GT(vis));
		packet2.tex_size.vsize = 1;
		packet2.txpitch.txpitch = (w32/32) - 1;
		
		RADEON_RESTORE_CTX(vis, RADEON_BASE_CTX);
		RADEON_WRITEPACKET(vis, packet2);
		ctx->ctx_loaded = RADEON_PUT_CTX;
	}

	memset(&packet, 0, sizeof(packet));

	packet.h.it_opcode = CCE_IT_OPCODE_3D_DRAW_IMMD;
	packet.h.count     = 13;
	packet.h.type      = 3;

	packet.vfmt.st0 = 1;
	packet.vfmt.z = 0 /* 1 */;

	packet.vctl.num_vertices = 3;
	packet.vctl.en_maos = 1;
	packet.vctl.fmt_mode = 1;
	packet.vctl.prim_walk = 3;   /* Vertex data follows in packet. */
	packet.vctl.prim_type = 8;   /* Rectangle list */

	packet.v1x = packet.v3x = x;
	packet.v2x = x + 1;
	packet.v1y = packet.v2y = y;
	packet.v3y = y + h;
	packet.v1s = packet.v2s = 0;
        packet.v3s = h;
	packet.v1t = packet.v3t = 1;
	packet.v2t = 0;

	memset(&offsetpkt, 0, sizeof(offsetpkt));
	offsetpkt.h.base_index = PP_TXOFFSET_1 >> 2;

	if ((KGI_PRIV(vis)->swatch_size - ctx->swatch_inuse) < w32) {
		/* idleaccel */
	        ctx->swatch_inuse = 0;
	}

	offsetpkt.txoffset = 
	  (uint32_t)KGI_PRIV(vis)->swatch_gp + ctx->swatch_inuse;

	RADEON_WRITEPACKET(vis, offsetpkt);

	memcpy(KGI_PRIV(vis)->swatch + ctx->swatch_inuse,
	       (char *)buf, wb);
	
	RADEON_WRITEPACKET(vis, packet);

	if (!(LIBGGI_FLAGS(vis) & GGIFLAG_ASYNC)) RADEON_FLUSH(vis);	
	return 0;
}
Esempio n. 3
0
int _ggi_palemu_Open(struct ggi_visual *vis)
{
	int rc;
	ggi_palemu_priv *priv = PALEMU_PRIV(vis);


	DPRINT("display-palemu: Open %dx%d#%dx%d\n", LIBGGI_X(vis), 
		LIBGGI_Y(vis), LIBGGI_VIRTX(vis), LIBGGI_VIRTY(vis));


	/* set the parent mode */
	
	rc = ggiSetMode(priv->parent, &priv->parent_mode);
	if (rc < 0) {
		DPRINT("display-palemu: Couldn't set parent mode.\n");
		return rc;
	}

	DPRINT("display-palemu: parent is %d/%d\n",
		GT_DEPTH(priv->parent_mode.graphtype), 
		GT_SIZE(priv->parent_mode.graphtype));
	

	/* setup tables and choose blitter function */

	switch (GT_ByPP(priv->parent_mode.graphtype)) {

	case 1: priv->do_blit = &blitter_1;
		break;
		
	case 2: priv->do_blit = &blitter_2;
		break;
		
	case 3: priv->do_blit = &blitter_3;
		break;
		
	case 4: priv->do_blit = &blitter_4;
		break;
		
	default:
		DPRINT("Unsupported pixel size '%d'.\n",
			GT_SIZE(priv->parent_mode.graphtype));
		return GGI_ENOMATCH;
	}


	priv->palette = _ggi_malloc(256 * sizeof(ggi_color));
	priv->lookup  = _ggi_malloc(256 * sizeof(ggi_pixel));

	priv->red_gamma = priv->green_gamma = priv->blue_gamma = 1.0;

	
	/* clear the 'dirty region' */

	priv->dirty_tl.x = LIBGGI_VIRTX(vis);
	priv->dirty_tl.y = LIBGGI_VIRTY(vis);
	priv->dirty_br.x = 0;
	priv->dirty_br.y = 0;

	return 0;
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
static int GGIopen(ggi_visual *vis, struct ggi_dlhandle *dlh,
			const char *args, void *argptr, uint32_t *dlret)
{
	ggi_accel_t *accel;
	Gx00_context_t *ctx;

	/* NB: The accel engine is resource 2 (1 is the ILOAD aperture,
	** 0 the framebuffer) */
	if (!(accel = KGI_PRIV(vis)->map_accel(vis, 2, 0,
		GX00_BUFFER_SIZE_ORDER, GX00_BUFFER_NUM, 0)))
		return GGI_ENODEVICE;

	if (!(ctx = (Gx00_context_t*)malloc(sizeof(*ctx))))
		return GGI_ENOMEM;

	/* setup the accel_priv data structures */
	KGI_ACCEL_PRIV(vis) = ctx;
	memset(ctx, 0, sizeof(*ctx));
	ctx->accel = accel;
	ctx->hwgc_mask = 0; /* TODO: Should use -1 instead? */
	/* setup the DMA buffers */
	GX00_INIT(vis);

	/* Initializes the pitch */
	GX00_WRITE_REG(vis, LIBGGI_VIRTX(vis), PITCH);
	/* Initializes the MACCESS fields */
	{
	  uint32_t maccess = MACCESS_ZWIDTH_ZW16; /* NB: no fogging */
	  switch (GT_ByPP(LIBGGI_GT(vis))) {
	  case 1:
	    maccess |= MACCESS_PWIDTH_PW8;
	    break;
	  case 2:
	    maccess |= MACCESS_PWIDTH_PW16;
	    if (LIBGGI_GT(vis) == GT_15BIT)
	      maccess |= MACCESS_DIT555;
	    /* else: GT_16BIT */
	    break;
	  case 4:
	    maccess |= MACCESS_PWIDTH_PW32;
	    break;
	  case 3:
	    maccess |= MACCESS_PWIDTH_PW24;
	    break;
	  default:
	    ggiPanic("Unknown depth size!");
	    break;
	  }
	  /* TODO: check? -- ortalo: maccess |= MACCESS_NODITHER; */
	  GX00_WRITE_REG(vis, maccess, MACCESS);
	}
	/* Initializes the destination origin */
	GX00_WRITE_REG(vis, 0x0, DSTORG);
	/* Initializes the old-style destination origin */
	GX00_WRITE_REG(vis, 0x0, YDSTORG);
	/* Initializes the plane mask */
	GX00_WRITE_REG(vis, 0xFFFFFFFF, PLNWT);
#if 0 /* Maybe not needed? TODO: Check in libggi if clipping is initialized */
	/* Initializes the clipping to max */
	GX00_WRITE_REG(vis, 0 |
		       (((LIBGGI_X(vis) - 1) << CXBNDRY_CXRIGHT_SHIFT)
			& CXBNDRY_CXRIGHT_MASK),
		       CXBNDRY);
	GX00_WRITE_REG(vis, 0, YTOP);
	GX00_WRITE_REG(vis, (LIBGGI_Y(vis) - 1) * LIBGGI_VIRTX(vis),
		       YBOT);
#endif

	vis->opdisplay->idleaccel = GGI_kgi_Gx00_idleaccel;
	vis->opdisplay->flush     = GGI_kgi_Gx00_flush;
	vis->opgc->gcchanged      = GGI_kgi_Gx00_gcchanged;
	vis->opdraw->drawhline_nc = GGI_kgi_Gx00_drawhline_nc;
	vis->opdraw->drawhline    = GGI_kgi_Gx00_drawhline;
	vis->opdraw->drawvline_nc = GGI_kgi_Gx00_drawvline_nc;
	vis->opdraw->drawvline    = GGI_kgi_Gx00_drawvline;
	vis->opdraw->drawbox      = GGI_kgi_Gx00_drawbox;
	vis->opdraw->fillscreen   = GGI_kgi_Gx00_fillscreen;
	vis->opdraw->drawline     = GGI_kgi_Gx00_drawline;
	vis->opdraw->copybox      = GGI_kgi_Gx00_copybox;
	/* bugs on the G400
	*/
	vis->opdraw->getcharsize  = GGI_kgi_Gx00_getcharsize;
	vis->opdraw->putc         = GGI_kgi_Gx00_putc;
	/* The generic puts uses putc, so...
	vis->opdraw->puts         = GGI_kgi_Gx00_puts;
	*/

	vis->needidleaccel = 1;
	vis->accelactive = 0;

	*dlret = GGI_DL_OPDRAW | GGI_DL_OPGC;

	return 0;
}
Esempio n. 6
0
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;
}