support anti-aliased fonts in 8 bit
while there, fix pm2fb_bitblt() packed mode, for real this time TODO: - use packed mode when uploading glyphs - let the hardware do the alpha blending if possible - mode setting
This commit is contained in:
parent
550571fe00
commit
12a603e5e8
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: pm2fb.c,v 1.16 2012/09/05 23:19:13 macallan Exp $ */
|
||||
/* $NetBSD: pm2fb.c,v 1.17 2012/09/12 12:07:04 macallan Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Michael Lorenz
|
||||
|
@ -31,7 +31,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: pm2fb.c,v 1.16 2012/09/05 23:19:13 macallan Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: pm2fb.c,v 1.17 2012/09/12 12:07:04 macallan Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -55,6 +55,7 @@ __KERNEL_RCSID(0, "$NetBSD: pm2fb.c,v 1.16 2012/09/05 23:19:13 macallan Exp $");
|
|||
#include <dev/wsfont/wsfont.h>
|
||||
#include <dev/rasops/rasops.h>
|
||||
#include <dev/wscons/wsdisplay_vconsvar.h>
|
||||
#include <dev/wscons/wsdisplay_glyphcachevar.h>
|
||||
#include <dev/pci/wsdisplay_pci.h>
|
||||
|
||||
#include <dev/i2c/i2cvar.h>
|
||||
|
@ -104,6 +105,7 @@ struct pm2fb_softc {
|
|||
uint8_t sc_edid_data[128];
|
||||
struct edid_info sc_ei;
|
||||
struct videomode *sc_videomode;
|
||||
glyphcache sc_gc;
|
||||
};
|
||||
|
||||
static int pm2fb_match(device_t, cfdata_t, void *);
|
||||
|
@ -129,11 +131,11 @@ static void pm2fb_init(struct pm2fb_softc *);
|
|||
static void pm2fb_flush_engine(struct pm2fb_softc *);
|
||||
static void pm2fb_rectfill(struct pm2fb_softc *, int, int, int, int,
|
||||
uint32_t);
|
||||
static void pm2fb_bitblt(struct pm2fb_softc *, int, int, int, int, int,
|
||||
int, int);
|
||||
static void pm2fb_bitblt(void *, int, int, int, int, int, int, int);
|
||||
|
||||
static void pm2fb_cursor(void *, int, int, int);
|
||||
static void pm2fb_putchar(void *, int, int, u_int, long);
|
||||
static void pm2fb_putchar_aa(void *, int, int, u_int, long);
|
||||
static void pm2fb_copycols(void *, int, int, int, int);
|
||||
static void pm2fb_erasecols(void *, int, int, int, long);
|
||||
static void pm2fb_copyrows(void *, int, int, int);
|
||||
|
@ -222,7 +224,10 @@ pm2fb_match(device_t parent, cfdata_t match, void *aux)
|
|||
if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_3DLABS)
|
||||
return 0;
|
||||
|
||||
/* only cards tested on so far - likely need a list */
|
||||
/*
|
||||
* only card tested on so far is a TechSource Raptor GFX 8P
|
||||
* Sun PGX32, which happens to be a Permedia 2v
|
||||
*/
|
||||
if ((PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_3DLABS_PERMEDIA2) ||
|
||||
(PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_3DLABS_PERMEDIA2V))
|
||||
return 100;
|
||||
|
@ -323,6 +328,18 @@ pm2fb_attach(device_t parent, device_t self, void *aux)
|
|||
|
||||
ri = &sc->sc_console_screen.scr_ri;
|
||||
|
||||
sc->sc_gc.gc_bitblt = pm2fb_bitblt;
|
||||
sc->sc_gc.gc_blitcookie = sc;
|
||||
sc->sc_gc.gc_rop = 3;
|
||||
|
||||
#ifdef PM2FB_DEBUG
|
||||
/*
|
||||
* leave some room at the bottom of the screen for various blitter
|
||||
* tests and in order to make the glyph cache visible
|
||||
*/
|
||||
sc->sc_height -= 200;
|
||||
#endif
|
||||
|
||||
if (is_console) {
|
||||
vcons_init_screen(&sc->vd, &sc->sc_console_screen, 1,
|
||||
&defattr);
|
||||
|
@ -334,12 +351,25 @@ pm2fb_attach(device_t parent, device_t self, void *aux)
|
|||
sc->sc_defaultscreen_descr.capabilities = ri->ri_caps;
|
||||
sc->sc_defaultscreen_descr.nrows = ri->ri_rows;
|
||||
sc->sc_defaultscreen_descr.ncols = ri->ri_cols;
|
||||
/* XXX use actual memory size instead of assuming 8MB */
|
||||
glyphcache_init(&sc->sc_gc, sc->sc_height + 5,
|
||||
(0x800000 / sc->sc_stride) - sc->sc_height - 5,
|
||||
sc->sc_width,
|
||||
ri->ri_font->fontwidth,
|
||||
ri->ri_font->fontheight,
|
||||
defattr);
|
||||
wsdisplay_cnattach(&sc->sc_defaultscreen_descr, ri, 0, 0,
|
||||
defattr);
|
||||
vcons_replay_msgbuf(&sc->sc_console_screen);
|
||||
} else {
|
||||
if (sc->sc_console_screen.scr_ri.ri_rows == 0) {
|
||||
/* do some minimal setup to avoid weirdnesses later */
|
||||
glyphcache_init(&sc->sc_gc, sc->sc_height + 5,
|
||||
(0x800000 / sc->sc_stride) - sc->sc_height - 5,
|
||||
sc->sc_width,
|
||||
ri->ri_font->fontwidth,
|
||||
ri->ri_font->fontheight,
|
||||
defattr);
|
||||
vcons_init_screen(&sc->vd, &sc->sc_console_screen, 1,
|
||||
&defattr);
|
||||
}
|
||||
|
@ -360,7 +390,25 @@ pm2fb_attach(device_t parent, device_t self, void *aux)
|
|||
aa.accessops = &pm2fb_accessops;
|
||||
aa.accesscookie = &sc->vd;
|
||||
|
||||
config_found(sc->sc_dev, &aa, wsemuldisplaydevprint);
|
||||
config_found(sc->sc_dev, &aa, wsemuldisplaydevprint);
|
||||
|
||||
#ifdef PM2FB_DEBUG
|
||||
/*
|
||||
* draw a pattern to check if pm2fb_bitblt() gets the alignment stuff
|
||||
* right
|
||||
*/
|
||||
pm2fb_rectfill(sc, 0, sc->sc_height, sc->sc_width, 200, 0xffffffff);
|
||||
pm2fb_rectfill(sc, 0, sc->sc_height, 300, 10, 0);
|
||||
pm2fb_rectfill(sc, 10, sc->sc_height, 200, 10, 0xe0e0e0e0);
|
||||
for (i = 1; i < 20; i++) {
|
||||
pm2fb_bitblt(sc, 0, sc->sc_height,
|
||||
i, sc->sc_height + 10 * i,
|
||||
300, 10, 3);
|
||||
pm2fb_bitblt(sc, i, sc->sc_height,
|
||||
400, sc->sc_height + 10 * i,
|
||||
300, 10, 3);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -414,7 +462,9 @@ pm2fb_ioctl(void *v, void *vs, u_long cmd, void *data, int flag,
|
|||
if (new_mode != sc->sc_mode) {
|
||||
sc->sc_mode = new_mode;
|
||||
if(new_mode == WSDISPLAYIO_MODE_EMUL) {
|
||||
pm2fb_init(sc);
|
||||
pm2fb_restore_palette(sc);
|
||||
glyphcache_wipe(&sc->sc_gc);
|
||||
vcons_redraw_screen(ms);
|
||||
} else
|
||||
pm2fb_flush_engine(sc);
|
||||
|
@ -497,7 +547,7 @@ pm2fb_init_screen(void *cookie, struct vcons_screen *scr,
|
|||
ri->ri_stride = sc->sc_stride;
|
||||
ri->ri_flg = RI_CENTER;
|
||||
if (sc->sc_depth == 8)
|
||||
ri->ri_flg |= RI_8BIT_IS_RGB /*| RI_ENABLE_ALPHA*/;
|
||||
ri->ri_flg |= RI_8BIT_IS_RGB | RI_ENABLE_ALPHA;
|
||||
|
||||
rasops_init(ri, 0, 0);
|
||||
ri->ri_caps = WSSCREEN_WSCOLORS;
|
||||
|
@ -511,7 +561,10 @@ pm2fb_init_screen(void *cookie, struct vcons_screen *scr,
|
|||
ri->ri_ops.cursor = pm2fb_cursor;
|
||||
ri->ri_ops.eraserows = pm2fb_eraserows;
|
||||
ri->ri_ops.erasecols = pm2fb_erasecols;
|
||||
ri->ri_ops.putchar = pm2fb_putchar;
|
||||
if (FONT_IS_ALPHA(ri->ri_font)) {
|
||||
ri->ri_ops.putchar = pm2fb_putchar_aa;
|
||||
} else
|
||||
ri->ri_ops.putchar = pm2fb_putchar;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -694,6 +747,13 @@ pm2fb_init(struct pm2fb_softc *sc)
|
|||
bus_space_write_4(sc->sc_memt, sc->sc_regh, PM2_RE_SCISSOR_MINYX, 0);
|
||||
bus_space_write_4(sc->sc_memt, sc->sc_regh, PM2_RE_SCISSOR_MAXYX,
|
||||
0x0fff0fff);
|
||||
/*
|
||||
* another scissor we need to disable in order to blit into off-screen
|
||||
* memory
|
||||
*/
|
||||
bus_space_write_4(sc->sc_memt, sc->sc_regh, PM2_RE_SCREENSIZE,
|
||||
0x0fff0fff);
|
||||
|
||||
switch(sc->sc_depth) {
|
||||
case 8:
|
||||
bus_space_write_4(sc->sc_memt, sc->sc_regh,
|
||||
|
@ -709,7 +769,8 @@ pm2fb_init(struct pm2fb_softc *sc)
|
|||
break;
|
||||
}
|
||||
pm2fb_flush_engine(sc);
|
||||
DPRINTF("pixel size: %08x\n", bus_space_read_4(sc->sc_memt, sc->sc_regh, PM2_RE_PIXEL_SIZE));
|
||||
DPRINTF("pixel size: %08x\n",
|
||||
bus_space_read_4(sc->sc_memt, sc->sc_regh, PM2_RE_PIXEL_SIZE));
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -733,11 +794,12 @@ pm2fb_rectfill(struct pm2fb_softc *sc, int x, int y, int wi, int he,
|
|||
}
|
||||
|
||||
static void
|
||||
pm2fb_bitblt(struct pm2fb_softc *sc, int xs, int ys, int xd, int yd,
|
||||
pm2fb_bitblt(void *cookie, int xs, int ys, int xd, int yd,
|
||||
int wi, int he, int rop)
|
||||
{
|
||||
struct pm2fb_softc *sc = cookie;
|
||||
uint32_t dir = 0;
|
||||
int rxs, rxd, rwi;
|
||||
int rxs, rxd, rwi, rxdelta;
|
||||
|
||||
if (yd <= ys) {
|
||||
dir |= PM2RE_INC_Y;
|
||||
|
@ -771,12 +833,14 @@ pm2fb_bitblt(struct pm2fb_softc *sc, int xs, int ys, int xd, int yd,
|
|||
}
|
||||
rxs = xs >> 2;
|
||||
rxd = xd >> 2;
|
||||
rwi = wi >> 2;
|
||||
rwi = (wi + 7) >> 2;
|
||||
rxdelta = (xs & 0xffc) - (xd & 0xffc);
|
||||
/* adjust for non-aligned x */
|
||||
adjust = (xs & 3) - (xd & 3);
|
||||
adjust = ((xd & 3) - (xs & 3));
|
||||
bus_space_write_4(sc->sc_memt, sc->sc_regh,
|
||||
PM2_RE_PACKEDDATA_LIMIT,
|
||||
(xd << 16) | (xd + wi) | (adjust << 29));
|
||||
|
||||
} else {
|
||||
/* we're in 16 or 32bit mode */
|
||||
if (rop == 3) {
|
||||
|
@ -794,13 +858,14 @@ pm2fb_bitblt(struct pm2fb_softc *sc, int xs, int ys, int xd, int yd,
|
|||
rxs = xs;
|
||||
rxd = xd;
|
||||
rwi = wi;
|
||||
rxdelta = xs - xd;
|
||||
}
|
||||
bus_space_write_4(sc->sc_memt, sc->sc_regh, PM2_RE_RECT_START,
|
||||
(yd << 16) | rxd);
|
||||
bus_space_write_4(sc->sc_memt, sc->sc_regh, PM2_RE_RECT_SIZE,
|
||||
(he << 16) | rwi);
|
||||
bus_space_write_4(sc->sc_memt, sc->sc_regh, PM2_RE_SOURCE_DELTA,
|
||||
(((ys - yd) & 0xfff) << 16) | ((rxs - rxd) & 0xfff));
|
||||
(((ys - yd) & 0xfff) << 16) | (rxdelta & 0xfff));
|
||||
bus_space_write_4(sc->sc_memt, sc->sc_regh, PM2_RE_RENDER,
|
||||
PM2RE_RECTANGLE | dir);
|
||||
}
|
||||
|
@ -933,6 +998,138 @@ pm2fb_putchar(void *cookie, int row, int col, u_int c, long attr)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
pm2fb_putchar_aa(void *cookie, int row, int col, u_int c, long attr)
|
||||
{
|
||||
struct rasops_info *ri = cookie;
|
||||
struct wsdisplay_font *font = PICK_FONT(ri, c);
|
||||
struct vcons_screen *scr = ri->ri_hw;
|
||||
struct pm2fb_softc *sc = scr->scr_cookie;
|
||||
uint32_t bg, /*latch = 0,*/ bg8, fg8, pixel;
|
||||
int i, x, y, wi, he, r, g, b, aval;
|
||||
int r1, g1, b1, r0, g0, b0, fgo, bgo;
|
||||
uint8_t *data8;
|
||||
int rv = GC_NOPE, cnt = 0;
|
||||
|
||||
if (sc->sc_mode != WSDISPLAYIO_MODE_EMUL)
|
||||
return;
|
||||
|
||||
if (!CHAR_IN_FONT(c, font))
|
||||
return;
|
||||
|
||||
wi = font->fontwidth;
|
||||
he = font->fontheight;
|
||||
|
||||
bg = ri->ri_devcmap[(attr >> 16) & 0xf];
|
||||
x = ri->ri_xorigin + col * wi;
|
||||
y = ri->ri_yorigin + row * he;
|
||||
if (c == 0x20) {
|
||||
pm2fb_rectfill(sc, x, y, wi, he, bg);
|
||||
return;
|
||||
}
|
||||
|
||||
rv = glyphcache_try(&sc->sc_gc, c, x, y, attr);
|
||||
if (rv == GC_OK)
|
||||
return;
|
||||
|
||||
data8 = WSFONT_GLYPH(c, font);
|
||||
|
||||
pm2fb_wait(sc, 5);
|
||||
#if 0
|
||||
/*
|
||||
* TODO:
|
||||
* - use packed mode here as well, instead of writing each pixel separately
|
||||
* - support 32bit colour
|
||||
* - see if we can trick the chip into doing the alpha blending for us
|
||||
*/
|
||||
x = x >> 2;
|
||||
wi = (wi + 3) >> 2;
|
||||
#endif
|
||||
bus_space_write_4(sc->sc_memt, sc->sc_regh, PM2_RE_MODE, 0);
|
||||
bus_space_write_4(sc->sc_memt, sc->sc_regh, PM2_RE_CONFIG,
|
||||
PM2RECFG_WRITE_EN /*| PM2RECFG_PACKED*/);
|
||||
bus_space_write_4(sc->sc_memt, sc->sc_regh,
|
||||
PM2_RE_RECT_START, (y << 16) | x);
|
||||
bus_space_write_4(sc->sc_memt, sc->sc_regh,
|
||||
PM2_RE_RECT_SIZE, (he << 16) | wi);
|
||||
bus_space_write_4(sc->sc_memt, sc->sc_regh,
|
||||
PM2_RE_RENDER,
|
||||
PM2RE_RECTANGLE | PM2RE_SYNC_ON_HOST |
|
||||
PM2RE_INC_X | PM2RE_INC_Y);
|
||||
/*
|
||||
* we need the RGB colours here, so get offsets into rasops_cmap
|
||||
*/
|
||||
fgo = ((attr >> 24) & 0xf) * 3;
|
||||
bgo = ((attr >> 16) & 0xf) * 3;
|
||||
|
||||
r0 = rasops_cmap[bgo];
|
||||
r1 = rasops_cmap[fgo];
|
||||
g0 = rasops_cmap[bgo + 1];
|
||||
g1 = rasops_cmap[fgo + 1];
|
||||
b0 = rasops_cmap[bgo + 2];
|
||||
b1 = rasops_cmap[fgo + 2];
|
||||
#define R3G3B2(r, g, b) ((r & 0xe0) | ((g >> 3) & 0x1c) | (b >> 6))
|
||||
bg8 = R3G3B2(r0, g0, b0);
|
||||
fg8 = R3G3B2(r1, g1, b1);
|
||||
|
||||
pm2fb_wait(sc, 200);
|
||||
|
||||
for (i = 0; i < ri->ri_fontscale; i++) {
|
||||
aval = *data8;
|
||||
if (aval == 0) {
|
||||
pixel = bg8;
|
||||
} else if (aval == 255) {
|
||||
pixel = fg8;
|
||||
} else {
|
||||
r = aval * r1 + (255 - aval) * r0;
|
||||
g = aval * g1 + (255 - aval) * g0;
|
||||
b = aval * b1 + (255 - aval) * b0;
|
||||
pixel = ((r & 0xe000) >> 8) |
|
||||
((g & 0xe000) >> 11) |
|
||||
((b & 0xc000) >> 14);
|
||||
}
|
||||
#if 0
|
||||
latch = (latch << 8) | pixel;
|
||||
/* write in 32bit chunks */
|
||||
if ((i & 3) == 3) {
|
||||
bus_space_write_stream_4(sc->sc_memt, sc->sc_regh,
|
||||
PM2_RE_DATA, latch);
|
||||
/*
|
||||
* not strictly necessary, old data should be shifted
|
||||
* out
|
||||
*/
|
||||
latch = 0;
|
||||
cnt++;
|
||||
if (cnt > 190) {
|
||||
pm2fb_wait(sc, 200);
|
||||
cnt = 0;
|
||||
}
|
||||
}
|
||||
#else
|
||||
bus_space_write_4(sc->sc_memt, sc->sc_regh,
|
||||
PM2_RE_COLOUR, pixel);
|
||||
|
||||
if (cnt > 190) {
|
||||
pm2fb_wait(sc, 200);
|
||||
cnt = 0;
|
||||
}
|
||||
#endif
|
||||
data8++;
|
||||
}
|
||||
#if 0
|
||||
/* if we have pixels left in latch write them out */
|
||||
if ((i & 3) != 0) {
|
||||
latch = latch << ((4 - (i & 3)) << 3);
|
||||
bus_space_write_stream_4(sc->sc_memt, sc->sc_regh,
|
||||
PM2_RE_DATA, latch);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (rv == GC_ADD) {
|
||||
glyphcache_add(&sc->sc_gc, c, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
pm2fb_copycols(void *cookie, int row, int srccol, int dstcol, int ncols)
|
||||
{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: pm2reg.h,v 1.7 2012/09/05 01:32:01 macallan Exp $ */
|
||||
/* $NetBSD: pm2reg.h,v 1.8 2012/09/12 12:07:04 macallan Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Michael Lorenz
|
||||
|
@ -322,6 +322,8 @@
|
|||
#define PM2_RE_STENCIL_MODE 0x00008988
|
||||
#define PM2_RE_ROP_MODE 0x00008828
|
||||
#define PM2_RE_PACKEDDATA_LIMIT 0x00008150
|
||||
#define PM2_RE_DATA 0x00008aa0 /* pixel data */
|
||||
#define PM2_RE_SOURCEDATA 0x00008aa8 /* raw data */
|
||||
|
||||
|
||||
#endif /* PM2_REG_H */
|
||||
|
|
Loading…
Reference in New Issue