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; }
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; }
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; }
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; }
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; }
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; }