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