Module Name: src Committed By: macallan Date: Fri Dec 6 11:58:56 UTC 2024
Modified Files: src/sys/arch/hppa/dev: summitfb.c Log Message: add support for alpha fonts and glyph cache, disabled by default since there is guesswork involved also, store bitmap fonts in video memory, mostly to show how to change colours around To generate a diff of this commit: cvs rdiff -u -r1.11 -r1.12 src/sys/arch/hppa/dev/summitfb.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/hppa/dev/summitfb.c diff -u src/sys/arch/hppa/dev/summitfb.c:1.11 src/sys/arch/hppa/dev/summitfb.c:1.12 --- src/sys/arch/hppa/dev/summitfb.c:1.11 Fri Nov 29 14:59:18 2024 +++ src/sys/arch/hppa/dev/summitfb.c Fri Dec 6 11:58:56 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: summitfb.c,v 1.11 2024/11/29 14:59:18 riastradh Exp $ */ +/* $NetBSD: summitfb.c,v 1.12 2024/12/06 11:58:56 macallan Exp $ */ /* $OpenBSD: sti_pci.c,v 1.7 2009/02/06 22:51:04 miod Exp $ */ @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: summitfb.c,v 1.11 2024/11/29 14:59:18 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: summitfb.c,v 1.12 2024/12/06 11:58:56 macallan Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -81,7 +81,6 @@ struct summitfb_softc { struct wsscreen_list sc_screenlist; struct vcons_data vd; int sc_mode; - void (*sc_putchar)(void *, int, int, u_int, long); u_char sc_cmap_red[256]; u_char sc_cmap_green[256]; u_char sc_cmap_blue[256]; @@ -89,8 +88,16 @@ struct summitfb_softc { /* cursor stuff */ int sc_cursor_x, sc_cursor_y; int sc_hot_x, sc_hot_y, sc_enabled; + /* font-in-vram */ + struct wsdisplay_font *sc_font; + int sc_font_start; /* x of font area */ + int sc_cols; /* chars per line in font area */ + int sc_video_on; +#ifdef SUMMITFB_ENABLE_GC + void (*sc_putchar)(void *, int, int, u_int, long); glyphcache sc_gc; +#endif }; CFATTACH_DECL_NEW(summitfb, sizeof(struct summitfb_softc), @@ -142,7 +149,11 @@ static void summitfb_bitblt(void *, int, static void summitfb_cursor(void *, int, int, int); #endif static void summitfb_putchar(void *, int, int, u_int, long); +static void summitfb_putchar_fast(void *, int, int, u_int, long); +static void summitfb_loadfont(struct summitfb_softc *); +#ifdef SUMMITFB_ENABLE_GC static void summitfb_putchar_aa(void *, int, int, u_int, long); +#endif static void summitfb_copycols(void *, int, int, int, int); static void summitfb_erasecols(void *, int, int, int, long); static void summitfb_copyrows(void *, int, int, int); @@ -251,10 +262,10 @@ summitfb_attach(device_t parent, device_ aprint_normal_dev(sc->sc_dev, "%s at %dx%d\n", sc->sc_scr.name, sc->sc_width, sc->sc_height); - summitfb_setup(sc); #ifdef SUMMITFB_DEBUG sc->sc_height -= 200; + sc->sc_width -= 200; #endif sc->sc_defaultscreen_descr = (struct wsscreen_descr){ @@ -275,14 +286,20 @@ summitfb_attach(device_t parent, device_ vcons_init(&sc->vd, sc, &sc->sc_defaultscreen_descr, &summitfb_accessops); sc->vd.init_screen = summitfb_init_screen; +#ifdef SUMMITFB_ENABLE_GC sc->vd.show_screen_cookie = &sc->sc_gc; sc->vd.show_screen_cb = glyphcache_adapt; - +#endif ri = &sc->sc_console_screen.scr_ri; +#ifdef SUMMITFB_ENABLE_GC sc->sc_gc.gc_bitblt = summitfb_bitblt; sc->sc_gc.gc_blitcookie = sc; sc->sc_gc.gc_rop = RopSrc; +#endif + + summitfb_setup(sc); + summitfb_setup_fb(sc); vcons_init_screen(&sc->vd, &sc->sc_console_screen, 1, &defattr); sc->sc_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC; @@ -292,13 +309,25 @@ summitfb_attach(device_t parent, device_ sc->sc_defaultscreen_descr.nrows = ri->ri_rows; sc->sc_defaultscreen_descr.ncols = ri->ri_cols; - glyphcache_init(&sc->sc_gc, sc->sc_height + 5, - sc->sc_scr.fbheight - sc->sc_height - 5, - sc->sc_width/*sc->sc_scr.fbwidth*/, + /* + * STI lies to us - it reports a 2048x2048 framebuffer but blitter + * ops wrap around below 1024 and we seem to have only about 250 + * usable columns to the right. Should still be enough to cache + * a font or four. + * So, the framebuffer seems to be 1536x1024, which is odd since the + * FX4 is supposed to support resolutions higher than 1280x1024. + * I guess video memory is allocated in 512x512 chunks + */ +#ifdef SUMMITFB_ENABLE_GC + glyphcache_init_x(&sc->sc_gc, sc->sc_width, 0, + sc->sc_height, + 1536 - sc->sc_width - 4, ri->ri_font->fontwidth, ri->ri_font->fontheight, defattr); +#endif + summitfb_setup(sc); summitfb_restore_palette(sc); summitfb_rectfill(sc, 0, 0, sc->sc_width, sc->sc_height, ri->ri_devcmap[(defattr >> 16) & 0xff]); @@ -637,6 +666,7 @@ summitfb_setup_fb(struct summitfb_softc { summitfb_write_mode(sc, VISFX_WRITE_MODE_PLAIN); + summitfb_write4(sc, VISFX_VRAM_READ_MODE, VISFX_READ_MODE_COPY); } void @@ -656,6 +686,7 @@ summitfb_setup(struct summitfb_softc *sc summitfb_write4(sc, 0xb08044, 0x1b); summitfb_write4(sc, 0xb08048, 0x1b); + summitfb_write4(sc, 0x920860, 0xe4); summitfb_write4(sc, 0x921110, 0); summitfb_write4(sc, 0x921114, 0); summitfb_write4(sc, 0x9211d8, 0); @@ -664,7 +695,6 @@ summitfb_setup(struct summitfb_softc *sc summitfb_write4(sc, 0xa00818, 0); summitfb_write4(sc, 0xa0081c, 0); /* fx4 */ summitfb_write4(sc, 0xa00850, 0); /* fx4 */ - summitfb_write4(sc, 0x920860, 0xe4); summitfb_write4(sc, 0xa0086c, 0); #endif @@ -739,7 +769,10 @@ summitfb_ioctl(void *v, void *vs, u_long if(new_mode == WSDISPLAYIO_MODE_EMUL) { summitfb_setup(sc); summitfb_restore_palette(sc); +#ifdef SUMMITFB_ENABLE_GC glyphcache_wipe(&sc->sc_gc); +#endif + summitfb_loadfont(sc); summitfb_rectfill(sc, 0, 0, sc->sc_width, sc->sc_height, ms->scr_ri.ri_devcmap[ (ms->scr_defattr >> 16) & 0xff]); @@ -835,8 +868,11 @@ summitfb_init_screen(void *cookie, struc ri->ri_width = sc->sc_width; ri->ri_height = sc->sc_height; ri->ri_stride = 2048; - ri->ri_flg = RI_CENTER | RI_8BIT_IS_RGB /*| - RI_ENABLE_ALPHA | RI_PREFER_ALPHA*/; + ri->ri_flg = RI_CENTER | RI_8BIT_IS_RGB +#ifdef SUMMITFB_ENABLE_GC + | RI_ENABLE_ALPHA | RI_PREFER_ALPHA +#endif + ; ri->ri_bits = (void *)sc->sc_scr.fbaddr; rasops_init(ri, 0, 0); @@ -849,17 +885,31 @@ summitfb_init_screen(void *cookie, struc ri->ri_hw = scr; - sc->sc_putchar = ri->ri_ops.putchar; - ri->ri_ops.copyrows = summitfb_copyrows; ri->ri_ops.copycols = summitfb_copycols; ri->ri_ops.eraserows = summitfb_eraserows; ri->ri_ops.erasecols = summitfb_erasecols; //ri->ri_ops.cursor = summitfb_cursor; +#ifdef SUMMITFB_ENABLE_GC + sc->sc_putchar = ri->ri_ops.putchar; if (FONT_IS_ALPHA(ri->ri_font)) { ri->ri_ops.putchar = summitfb_putchar_aa; } else - ri->ri_ops.putchar = summitfb_putchar; +#endif + { + int fbwidth = (sc->sc_width + 511) & ~511; + int fcols = (fbwidth - sc->sc_width - 2) / ri->ri_font->fontwidth; + int frows = sc->sc_height / ri->ri_font->fontheight; + sc->sc_font_start = sc->sc_width + 2; + if ((fcols * frows) >= ri->ri_font->numchars) { + /* ok, we can do this */ + sc->sc_cols = fcols; + sc->sc_font = ri->ri_font; + summitfb_loadfont(sc); + ri->ri_ops.putchar = summitfb_putchar_fast; + } else + ri->ri_ops.putchar = summitfb_putchar; + } } static int @@ -983,7 +1033,11 @@ summitfb_bitblt(void *cookie, int xs, in struct summitfb_softc *sc = cookie; /* XXX no ROP support yet */ - summitfb_write_mode(sc, VISFX_WRITE_MODE_PLAIN); + if (rop != RopSrc) { + summitfb_write_mode(sc, rop); + } else + summitfb_write_mode(sc, VISFX_WRITE_MODE_PLAIN); + summitfb_write4(sc, VISFX_VRAM_READ_MODE, VISFX_WRITE_MODE_PLAIN); summitfb_write4(sc, VISFX_COPY_SRC, (xs << 16) | ys); summitfb_write4(sc, VISFX_COPY_WH, (wi << 16) | he); summitfb_write4(sc, VISFX_COPY_DST, (xd << 16) | yd); @@ -1048,7 +1102,7 @@ summitfb_putchar(void *cookie, int row, struct vcons_screen *scr = ri->ri_hw; struct summitfb_softc *sc = scr->scr_cookie; void *data; - int i, x, y, wi, he/*, rv = GC_NOPE*/; + int i, x, y, wi, he; uint32_t bg, fg, mask; if (sc->sc_mode != WSDISPLAYIO_MODE_EMUL) @@ -1079,12 +1133,6 @@ summitfb_putchar(void *cookie, int row, fg = ri->ri_devcmap[(attr >> 24) & 0x0f]; -#if 0 - rv = glyphcache_try(&sc->sc_gc, c, x, y, attr); - if (rv == GC_OK) - return; -#endif - summitfb_write_mode(sc, VISFX_WRITE_MODE_EXPAND); summitfb_write4(sc, VISFX_FG_COLOUR, fg); summitfb_write4(sc, VISFX_BG_COLOUR, bg); @@ -1112,12 +1160,109 @@ summitfb_putchar(void *cookie, int row, data16++; } } +} + +static void +summitfb_loadfont(struct summitfb_softc *sc) +{ + int i, c, x, y; + uint8_t *data; + uint16_t *data16; + uint32_t mask; + + summitfb_setup(sc); + summitfb_write_mode(sc, VISFX_WRITE_MODE_EXPAND); + + summitfb_write4(sc, VISFX_FG_COLOUR, 0xffffffff); + summitfb_write4(sc, VISFX_BG_COLOUR, 0); + + mask = 0xffffffff << (32 - sc->sc_font->fontwidth); + summitfb_write4(sc, VISFX_PIXEL_MASK, mask); + + for (c = 0; c < sc->sc_font->numchars; c++) { + x = sc->sc_font_start + (c % sc->sc_cols) * sc->sc_font->fontwidth; + y = (c / sc->sc_cols) * sc->sc_font->fontheight; + data = WSFONT_GLYPH(sc->sc_font->firstchar + c, sc->sc_font); + summitfb_write4(sc, VISFX_VRAM_WRITE_DEST, (y << 16) | x); + if (sc->sc_font->stride == 1) { + for (i = 0; i < sc->sc_font->fontheight; i++) { + mask = *data; + summitfb_write4(sc, VISFX_VRAM_WRITE_DATA_INCRY, + mask << 24); + data++; + } + } else { + data16 = (uint16_t *)data; + for (i = 0; i < sc->sc_font->fontheight; i++) { + mask = *data16; + summitfb_write4(sc, VISFX_VRAM_WRITE_DATA_INCRY, + mask << 16); + data16++; + } + } + } +} + +static void +summitfb_putchar_fast(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 summitfb_softc *sc = scr->scr_cookie; + int i, x, y, wi, he, xs, ys; + uint32_t bg, fg; + + if (sc->sc_mode != WSDISPLAYIO_MODE_EMUL) + return; + + if (!CHAR_IN_FONT(c, font)) + return; + + /* for autogenerated line drawing characters */ + if (font != sc->sc_font) { + summitfb_putchar(cookie, row, col, c, attr); + return; + } + + /* XXX as long as we use putchar() to draw the cursor */ #if 0 - if (rv == GC_ADD) - glyphcache_add(&sc->sc_gc, c, x, y); + if (row == ri->ri_crow && col == ri->ri_ccol) { + ri->ri_flg &= ~RI_CURSOR; + } #endif + wi = font->fontwidth; + he = font->fontheight; + + x = ri->ri_xorigin + col * wi; + y = ri->ri_yorigin + row * he; + + bg = ri->ri_devcmap[(attr >> 16) & 0xf]; + + /* if we're drawing a space we're done here */ + if (c == 0x20) { + summitfb_rectfill(sc, x, y, wi, he, bg); + return; + } + + fg = ri->ri_devcmap[(attr >> 24) & 0x0f]; + + summitfb_write_mode(sc, 0x050000c0); + summitfb_write4(sc, VISFX_VRAM_READ_MODE, 0x05000400); + summitfb_write4(sc, VISFX_FG_COLOUR, fg); + summitfb_write4(sc, VISFX_BG_COLOUR, bg); + + i = c - font->firstchar; + xs = sc->sc_font_start + (i % sc->sc_cols) * sc->sc_font->fontwidth; + ys = (i / sc->sc_cols) * sc->sc_font->fontheight; + + summitfb_write4(sc, VISFX_COPY_SRC, (xs << 16) | ys); + summitfb_write4(sc, VISFX_COPY_WH, (wi << 16) | he); + summitfb_write4(sc, VISFX_COPY_DST, (x << 16) | y); + } +#ifdef SUMMITFB_ENABLE_GC static void summitfb_putchar_aa(void *cookie, int row, int col, u_int c, long attr) { @@ -1162,6 +1307,7 @@ summitfb_putchar_aa(void *cookie, int ro if (rv == GC_ADD) glyphcache_add(&sc->sc_gc, c, x, y); } +#endif static void summitfb_copycols(void *cookie, int row, int srccol, int dstcol, int ncols)