Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pci add hardware acceleration
details: https://anonhg.NetBSD.org/src/rev/1c5905cb8bd1
branches: trunk
changeset: 790434:1c5905cb8bd1
user: macallan <macallan%NetBSD.org@localhost>
date: Wed Oct 09 01:28:33 2013 +0000
description:
add hardware acceleration
For now this supports only GeForce2 MX cards but most NV1x chips should work
once their PCI iDs are added to gffb_match()
Tested only on macppc.
diffstat:
sys/dev/pci/gffb.c | 415 +++++++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 360 insertions(+), 55 deletions(-)
diffs (truncated from 639 to 300 lines):
diff -r f292324752ce -r 1c5905cb8bd1 sys/dev/pci/gffb.c
--- a/sys/dev/pci/gffb.c Tue Oct 08 19:59:49 2013 +0000
+++ b/sys/dev/pci/gffb.c Wed Oct 09 01:28:33 2013 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: gffb.c,v 1.2 2013/10/02 16:35:38 macallan Exp $ */
+/* $NetBSD: gffb.c,v 1.3 2013/10/09 01:28:33 macallan Exp $ */
/*
* Copyright (c) 2007, 2012 Michael Lorenz
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: gffb.c,v 1.2 2013/10/02 16:35:38 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: gffb.c,v 1.3 2013/10/09 01:28:33 macallan Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -96,6 +96,9 @@
u_char sc_cmap_green[256];
u_char sc_cmap_blue[256];
int sc_put, sc_current, sc_free;
+ uint32_t sc_rop;
+ void (*sc_putchar)(void *, int, int, u_int, long);
+ kmutex_t sc_lock;
glyphcache sc_gc;
};
@@ -119,22 +122,20 @@
static void gffb_init(struct gffb_softc *);
static void gffb_make_room(struct gffb_softc *, int);
+static void gffb_sync(struct gffb_softc *);
-#if notyet
-static void gffb_flush_engine(struct gffb_softc *);
static void gffb_rectfill(struct gffb_softc *, int, int, int, int,
uint32_t);
static void gffb_bitblt(void *, int, int, int, int, int,
int, int);
+static void gffb_rop(struct gffb_softc *, int);
static void gffb_cursor(void *, int, int, int);
static void gffb_putchar(void *, int, int, u_int, long);
-static void gffb_putchar_aa(void *, int, int, u_int, long);
static void gffb_copycols(void *, int, int, int, int);
static void gffb_erasecols(void *, int, int, int, long);
static void gffb_copyrows(void *, int, int, int);
static void gffb_eraserows(void *, int, int, long);
-#endif /* notyet */
struct wsdisplay_accessops gffb_accessops = {
gffb_ioctl,
@@ -198,7 +199,7 @@
#ifdef GLYPHCACHE_DEBUG
/* leave some visible VRAM unused so we can see the glyph cache */
- sc->sc_height -= 200;
+ sc->sc_height -= 300;
#endif
if (!prop_dictionary_get_uint32(dict, "depth", &sc->sc_depth)) {
@@ -243,54 +244,59 @@
sc->sc_mode = WSDISPLAYIO_MODE_EMUL;
sc->sc_locked = 0;
- vcons_init(&sc->vd, sc, &sc->sc_defaultscreen_descr,
- &gffb_accessops);
- sc->vd.init_screen = gffb_init_screen;
-
sc->sc_vramsize = bus_space_read_4(sc->sc_memt, sc->sc_regh,
GFFB_VRAM) & 0xfff00000;
printf("vram: %d MB\n", sc->sc_vramsize >> 20);
+#ifdef GFFB_DEBUG
printf("put: %08x\n", bus_space_read_4(sc->sc_memt, sc->sc_regh, GFFB_FIFO_PUT));
printf("get: %08x\n", bus_space_read_4(sc->sc_memt, sc->sc_regh, GFFB_FIFO_GET));
- /* init engine here */
+#endif
+
+ /*
+ * we don't have hardware synchronization so we need a lock to serialize
+ * access to the DMA buffer between normal and kernel output
+ * actually it might be enough to use atomic ops on sc_current, sc_free
+ * etc. but for now we'll play it safe
+ * XXX we will probably deadlock if we take an interrupt while sc_lock
+ * is held and then try to printf()
+ */
+ mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
+
+ /* init engine here */
gffb_init(sc);
- printf("put: %08x\n", bus_space_read_4(sc->sc_memt, sc->sc_regh, GFFB_FIFO_PUT));
- printf("get: %08x\n", bus_space_read_4(sc->sc_memt, sc->sc_regh, GFFB_FIFO_GET));
+
+ vcons_init(&sc->vd, sc, &sc->sc_defaultscreen_descr,
+ &gffb_accessops);
+ sc->vd.init_screen = gffb_init_screen;
+
ri = &sc->sc_console_screen.scr_ri;
-#if notyet
sc->sc_gc.gc_bitblt = gffb_bitblt;
sc->sc_gc.gc_blitcookie = sc;
- sc->sc_gc.gc_rop = R128_ROP3_S;
-#endif
+ sc->sc_gc.gc_rop = 0xcc;
if (is_console) {
vcons_init_screen(&sc->vd, &sc->sc_console_screen, 1,
&defattr);
sc->sc_console_screen.scr_flags |= VCONS_SCREEN_IS_STATIC;
-#if notyet
gffb_rectfill(sc, 0, 0, sc->sc_width, sc->sc_height,
- ri->ri_devcmap[(defattr >> 16) & 0xff]);
-#else
- memset(sc->sc_fbaddr + 0x2000,
- ri->ri_devcmap[(defattr >> 16) & 0xff],
- sc->sc_height * sc->sc_stride);
-#endif
+ ri->ri_devcmap[(defattr >> 16) & 0xf]);
+
sc->sc_defaultscreen_descr.textops = &ri->ri_ops;
sc->sc_defaultscreen_descr.capabilities = ri->ri_caps;
sc->sc_defaultscreen_descr.nrows = ri->ri_rows;
sc->sc_defaultscreen_descr.ncols = ri->ri_cols;
-#if notyet
+
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);
-#endif
+
wsdisplay_cnattach(&sc->sc_defaultscreen_descr, ri, 0, 0,
defattr);
vcons_replay_msgbuf(&sc->sc_console_screen);
@@ -305,14 +311,13 @@
&defattr);
} else
(*ri->ri_ops.allocattr)(ri, 0, 0, 0, &defattr);
-#if notyet
+
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);
-#endif
}
j = 0;
@@ -334,6 +339,30 @@
aa.accesscookie = &sc->vd;
config_found(sc->sc_dev, &aa, wsemuldisplaydevprint);
+
+#ifdef GFFB_DEBUG
+ for (i = 0; i < 40; i++) {
+ for (j = 0; j < 40; j++) {
+ gffb_rectfill(sc, i * 20, j * 20, 20, 20,
+ (i + j ) & 1 ? 0xe0e0e0e0 : 0x03030303);
+ }
+ }
+
+ //gffb_bitblt(sc, 0, 800, 10, 10, 400, 300, 0xcc);
+ gffb_rectfill(sc, 0, 800, 1280, 224, 0x92929292);
+ gffb_bitblt(sc, 0, 10, 10, 810, 200, 20, 0xcc);
+ gffb_bitblt(sc, 0, 10, 10, 840, 300, 20, 0xcc);
+ gffb_bitblt(sc, 0, 10, 10, 870, 400, 20, 0xcc);
+ gffb_bitblt(sc, 0, 10, 10, 900, 500, 20, 0xcc);
+ gffb_bitblt(sc, 0, 10, 10, 930, 600, 20, 0xcc);
+ gffb_bitblt(sc, 0, 10, 610, 810, 200, 20, 0xcc);
+ gffb_bitblt(sc, 0, 10, 610, 840, 300, 20, 0xcc);
+ gffb_bitblt(sc, 0, 10, 610, 870, 400, 20, 0xcc);
+ gffb_bitblt(sc, 0, 10, 610, 900, 500, 20, 0xcc);
+ gffb_bitblt(sc, 0, 10, 610, 930, 600, 20, 0xcc);
+ gffb_sync(sc);
+ printf("put %x current %x\n", sc->sc_put, sc->sc_current);
+#endif
}
static int
@@ -389,12 +418,10 @@
if(new_mode == WSDISPLAYIO_MODE_EMUL) {
gffb_init(sc);
gffb_restore_palette(sc);
-#if notyet
glyphcache_wipe(&sc->sc_gc);
gffb_rectfill(sc, 0, 0, sc->sc_width,
sc->sc_height, ms->scr_ri.ri_devcmap[
- (ms->scr_defattr >> 16) & 0xff]);
-#endif
+ (ms->scr_defattr >> 16) & 0xf]);
vcons_redraw_screen(ms);
}
}
@@ -486,23 +513,22 @@
rasops_init(ri, 0, 0);
ri->ri_caps = WSSCREEN_WSCOLORS;
+#if 0
scr->scr_flags |= VCONS_DONT_READ;
+#endif
rasops_reconfig(ri, sc->sc_height / ri->ri_font->fontheight,
sc->sc_width / ri->ri_font->fontwidth);
ri->ri_hw = scr;
-#if notyet
+
+ sc->sc_putchar = ri->ri_ops.putchar;
ri->ri_ops.copyrows = gffb_copyrows;
ri->ri_ops.copycols = gffb_copycols;
ri->ri_ops.eraserows = gffb_eraserows;
ri->ri_ops.erasecols = gffb_erasecols;
ri->ri_ops.cursor = gffb_cursor;
- if (FONT_IS_ALPHA(ri->ri_font)) {
- ri->ri_ops.putchar = gffb_putchar_aa;
- } else
- ri->ri_ops.putchar = gffb_putchar;
-#endif
+ ri->ri_ops.putchar = gffb_putchar;
}
static int
@@ -514,7 +540,7 @@
int i, error;
u_char rbuf[256], gbuf[256], bbuf[256];
-#ifdef R128FB_DEBUG
+#ifdef GFFB_DEBUG
aprint_debug("putcmap: %d %d\n",index, count);
#endif
if (cm->index >= 256 || cm->count > 256 ||
@@ -619,6 +645,7 @@
scratch = *sc->sc_fbaddr;
bus_space_write_4(sc->sc_memt, sc->sc_regh, GFFB_FIFO_PUT,
sc->sc_put);
+ membar_sync();
}
}
@@ -662,26 +689,26 @@
sc->sc_free = 0x2000 - sc->sc_current;
if (sc->sc_free < size) {
gffb_dmanext(sc, 0x20000000);
- if(get <= SKIPS) {
- if (sc->sc_put <= SKIPS) {
+ if(get <= (SKIPS << 2)) {
+ if (sc->sc_put <= (SKIPS << 2)) {
/* corner case - will be idle */
bus_space_write_4(sc->sc_memt,
sc->sc_regh, GFFB_FIFO_PUT,
- SKIPS + 1);
+ (SKIPS + 1) << 2);
}
do {
get = bus_space_read_4(
sc->sc_memt, sc->sc_regh,
GFFB_FIFO_GET);
- } while (get <= SKIPS);
+ } while (get <= (SKIPS << 2));
}
bus_space_write_4(sc->sc_memt, sc->sc_regh,
- GFFB_FIFO_PUT, SKIPS);
- sc->sc_current = sc->sc_put = SKIPS;
- sc->sc_free = get - (SKIPS + 1);
+ GFFB_FIFO_PUT, SKIPS << 2);
+ sc->sc_current = sc->sc_put = (SKIPS << 2);
+ sc->sc_free = get - ((SKIPS + 1) << 2);
}
} else
- sc->sc_free = get - sc->sc_current - 1;
+ sc->sc_free = get - sc->sc_current - 4;
}
}
@@ -689,28 +716,41 @@
gffb_sync(struct gffb_softc *sc)
{
int bail;
+ int i;
- bail = 100000;
+ gffb_dma_kickoff(sc); /* just in case */
+
+ bail = 100000000;
while ((bus_space_read_4(sc->sc_memt, sc->sc_regh, GFFB_FIFO_GET) !=
sc->sc_put) && (bail > 0)) {
+#if 0
bail--;
- delay(1);
+#endif
}
Home |
Main Index |
Thread Index |
Old Index