A mysterious USB device appears.



  • max@max-VirtualBox:~$ ssh root@192.168.1.150
    root@192.168.1.150's password: 
    
    
    BusyBox v1.25.1 () built-in shell (ash)
    
       ____       _             ____
      / __ \___  (_)__  ___    / __ \__ _  ___ ___ ____ _
     / /_/ / _ \/ / _ \/ _ \  / /_/ /  ' \/ -_) _ `/ _ `/
     \____/_//_/_/\___/_//_/  \____/_/_/_/\__/\_, /\_,_/
     W H A T  W I L L  Y O U  I N V E N T ? /___/
     -----------------------------------------------------
       Ω-ware: 0.2.0 b196
     -----------------------------------------------------
    root@Omega-C465:~# dmesg
    [...]
    [ 4128.461155] usb 1-1: new high-speed USB device number 3 using ehci-platform
    [ 4133.581154] usb 1-1: device descriptor read/64, error -145
    [ 4133.842306] usb 1-1: New USB device found, idVendor=17e9, idProduct=0290
    [ 4133.849139] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
    [ 4133.856428] usb 1-1: Product: DL-165 Adapter
    [ 4133.860770] usb 1-1: Manufacturer: DisplayLink
    [ 4133.865303] usb 1-1: SerialNumber: 861145
    [ 4133.889629] [drm] vendor descriptor length:22 data:22 5f 01 00 20 05 00 01 03 04 02
    [ 4134.068033] udl 1-1:1.0: fb0: udldrmfb frame buffer device
    [ 4134.074640] [drm] Supports vblank timestamp caching Rev 2 (21.10.2013).
    [ 4134.081415] [drm] No driver support for vblank timestamp query.
    [ 4134.087415] [drm] Initialized udl on minor 0
    root@Omega-C465:~# ls -l /dev/fb*
    crw-------    1 root     root       29,   0 Jan  1  1970 /dev/fb0
    root@Omega-C465:~# ls -l /dev/dri/
    crw-------    1 root     root      226,   0 Jan  1  1970 card0
    crw-------    1 root     root      226,  64 Jan  1  1970 controlD64
    root@Omega-C465:~# ./modetest -M udl -c
    Connectors:
    id      encoder status          name            size (mm)       modes   encoders
    22      0       connected       DVI-I-1         510x290         13      21
      modes:
            name refresh (Hz) hdisp hss hse htot vdisp vss vse vtot)
      1920x1080 60 1920 1968 2000 2080 1080 1083 1088 1111 flags: phsync, nvsync; type: preferred, driver
      1920x1080 60 1920 2008 2052 2200 1080 1084 1089 1125 flags: phsync, pvsync; type: driver
      1680x1050 60 1680 1728 1760 1840 1050 1053 1059 1080 flags: phsync, nvsync; type: driver
      1280x1024 75 1280 1296 1440 1688 1024 1025 1028 1066 flags: phsync, pvsync; type: driver
      1280x1024 60 1280 1328 1440 1688 1024 1025 1028 1066 flags: phsync, pvsync; type: driver
      1152x864 75 1152 1216 1344 1600 864 865 868 900 flags: phsync, pvsync; type: driver
      1024x768 75 1024 1040 1136 1312 768 769 772 800 flags: phsync, pvsync; type: driver
      1024x768 60 1024 1048 1184 1344 768 771 777 806 flags: nhsync, nvsync; type: driver
      800x600 75 800 816 896 1056 600 601 604 625 flags: phsync, pvsync; type: driver
      800x600 60 800 840 968 1056 600 601 605 628 flags: phsync, pvsync; type: driver
      640x480 75 640 656 720 840 480 481 484 500 flags: nhsync, nvsync; type: driver
      640x480 60 640 656 752 800 480 490 492 525 flags: nhsync, nvsync; type: driver
      720x400 70 720 738 846 900 400 412 414 449 flags: nhsync, pvsync; type: driver
      props:
            1 EDID:
                    flags: immutable blob
                    blobs:
    
                    value:
                            00ffffffffffff001e6d1c57973e0300
                            0a130103ea331d78eaaec5a2574a9c25
                            125054a54b00b300818f8180714f0101
                            0101010101011a3680a070381f403020
                            3500fe221100001a023a801871382d40
                            582c4500fe221100001e000000fd0038
                            4b1e530f000a202020202020000000fc
                            0057323434330a2020202020202000ad
            2 DPMS:
                    flags: enum
                    enums: On=0 Standby=1 Suspend=2 Off=3
                    value: 0
            18 dirty:
                    flags: immutable enum
                    enums: Off=0 On=1 Annotate=2
                    value: 1
    				
    root@Omega-C465:~# ./modetest -M udl -s 22:1920x1080
    setting mode 1920x1080-60Hz@XR24 on connectors 22, crtc 20
    

    0_1538776457403_IMG_20181005_234041.jpg

    Yep, that's an Omega2 outputting a 1920x1080p@60Hz HDMI video signal. With a little help via USB.

    More soon ;).



  • Using kmscon:

    root@Omega-C465:/# kmscon --font-engine unifont --render-engine bbulk
    [0000.000000] NOTICE: kmscon Revision kmscon-8 Oct  6 2018 12:10:18
    [0000.297721] NOTICE: vt: using tty /dev/tty2
    

    0_1538821910062_IMG_20181006_122624.jpg

    A login shell via the HDMI output and a USB keyboard! 🙂

    It's still a bit slow, though. Anyways, I'll now look into how I can write to the framebuffer directly either using the Linux DRI/DRM system or the mirrored /dev/fb0..



  • Okay, all of this Direct Rendering Instrastructure (DRI) and Direct Renderer Manager (DRM) is weird and probably more overhead than needed.

    I got mesa3D (libGL with OpenGL(ES)) support to compile, but the kmscube demo just won't display anything on its output.. A very simple DRM test program seems to recognize the correct resolution but just displays a black screen (not "no signal", but "all pixels are black").

    I'm thinking about compiling X11/Xorg server for the heck of it, just to see if it runs.. Maybe even LXDE on top of it?

    Anyways, on Wikipedia I found libdlo. A libusb-0.1 library to bypass all the kernel drivers and directly talk to the DisplayLink USB device. With the libusb-compat_0.1.4-2_mipsel_24kc.ipk installed on the Omega2 and the library and its test-program cross-compiled, it actually does produce an output! Maybe I'll use this for a small test program until I figure out why writing to /dev/fb0 leaves the video signal on "disconnected" or figure out the right sequence of DRM commands with which the modetest program could output its nice colored test signal.

    root@Omega-C465:~# test1
    test: argv[0]: test1
    test: init...
    
    test: basic graphics tests...
    test: device info: uid &77B93C20
    test: device info: serial 861145
    test: device info: type  &F
    test: native mode info...
      1920x1080 @ 59 Hz 24 bpp base &0
    test: set_mode...
    test: mode info...
      1920x1080 @ 59 Hz 24 bpp base &0
    test: cls... took 40 ms
    test: random white dots... took 41 ms
    test: random rectangles... took 50 ms
    test: central rectangles... took 75 ms
    test: white box outline... took 1 ms
    test: copy central box... took 9 ms
    test: copy central box (off edges of viewport)... took 4 ms
            est: overlapping copy tests...
    
    test: viewport tests...
    test: cls (three banks)... took 117 ms
    test: plot crosses (three banks)... took 29 ms
    test: switching to screen bank 1...
    test: switching to screen bank 2...
    test: switching to screen bank 0...
    
    test: screen scraping tests...
    
    test: bitmap file 'test08.bmp'
    bmp->hdr.magic       4D42
    bmp->hdr.file_sz     00001F8E (8078)
    bmp->hdr.reserved1   0000
    bmp->hdr.reserved2   0000
    bmp->hdr.pix_offset  00000436
    bmp->dib.dib_hdr_sz  00000028
    bmp->dib.width       0000008C (140)
    bmp->dib.height      00000032 (50)
    bmp->dib.col_planes  0001
    bmp->dib.bpp         0008 (8)
    bmp->dib.compression 00000000
    bmp->dib.raw_size    00001B58 (7000)
    bmp->dib.x_pix_meter 00000DD7
    bmp->dib.y_pix_meter 00000DD7
    bmp->dib.pal_entries 00000100 (256)
    bmp->dib.imp_cols    00000000
    
    test: bitmap file 'test16.bmp'
    bmp->hdr.magic       4D42
    bmp->hdr.file_sz     000036E6 (14054)
    bmp->hdr.reserved1   0000
    bmp->hdr.reserved2   0000
    bmp->hdr.pix_offset  00000036
    bmp->dib.dib_hdr_sz  00000028
    bmp->dib.width       0000008C (140)
    bmp->dib.height      00000032 (50)
    bmp->dib.col_planes  0001
    bmp->dib.bpp         0010 (16)
    bmp->dib.compression 00000000
    bmp->dib.raw_size    000036B0 (14000)
    bmp->dib.x_pix_meter 00000DD7
    bmp->dib.y_pix_meter 00000DD7
    bmp->dib.pal_entries 00000000 (0)
    bmp->dib.imp_cols    00000000
    
    test: bitmap file 'test24.bmp'
    bmp->hdr.magic       4D42
    bmp->hdr.file_sz     0000523E (21054)
    bmp->hdr.reserved1   0000
    bmp->hdr.reserved2   0000
    bmp->hdr.pix_offset  00000036
    bmp->dib.dib_hdr_sz  00000028
    bmp->dib.width       0000008C (140)
    bmp->dib.height      00000032 (50)
    bmp->dib.col_planes  0001
    bmp->dib.bpp         0018 (24)
    bmp->dib.compression 00000000
    bmp->dib.raw_size    00005208 (21000)
    bmp->dib.x_pix_meter 00000DD7
    bmp->dib.y_pix_meter 00000DD7
    bmp->dib.pal_entries 00000000 (0)
    bmp->dib.imp_cols    00000000
    
    test: bitmap file 'test32.bmp'
    bmp->hdr.magic       4D42
    bmp->hdr.file_sz     00006D96 (28054)
    bmp->hdr.reserved1   0000
    bmp->hdr.reserved2   0000
    bmp->hdr.pix_offset  00000036
    bmp->dib.dib_hdr_sz  00000028
    bmp->dib.width       0000008C (140)
    bmp->dib.height      00000032 (50)
    bmp->dib.col_planes  0001
    bmp->dib.bpp         0020 (32)
    bmp->dib.compression 00000000
    bmp->dib.raw_size    00006D60 (28000)
    bmp->dib.x_pix_meter 00000DD7
    bmp->dib.y_pix_meter 00000DD7
    bmp->dib.pal_entries 00000000 (0)
    bmp->dib.imp_cols    00000000
    test: bitmap clipping test...
    bmp->hdr.magic       4D42
    bmp->hdr.file_sz     00001F8E (8078)
    bmp->hdr.reserved1   0000
    bmp->hdr.reserved2   0000
    bmp->hdr.pix_offset  00000436
    bmp->dib.dib_hdr_sz  00000028
    bmp->dib.width       0000008C (140)
    bmp->dib.height      00000032 (50)
    bmp->dib.col_planes  0001
    bmp->dib.bpp         0008 (8)
    bmp->dib.compression 00000000
    bmp->dib.raw_size    00001B58 (7000)
    bmp->dib.x_pix_meter 00000DD7
    bmp->dib.y_pix_meter 00000DD7
    bmp->dib.pal_entries 00000100 (256)
    bmp->dib.imp_cols    00000000
    test: release &77B93C20...
    test: final...
    test: finished.
    root@Omega-C465:~# ls
    

    0_1538851342529_IMG_20181006_203336.jpg

    cls... took 40 ms benchmarks the time it takes to fill the entire screen with black pixels and send it to the framebuffer. This should be more or less the time it takes to copy an in-RAM framebuffer via USB to the display. And 40ms on 1920x1080p means 25FPS. Pretty respectable for a USB 2.0 device.

    But my little gameboy emulator doesn't need that many pixels, so switching to a 240p resolution should make this thing waaaaay faster :). Full-Speed emulation for a Game Boy Color, at least. Less CPU time needed for pushing a framebuffer means that also higher console generation tiers (NES, SNES,..) might be possible with this approach.

    Let's see where this goes.



  • So I did compile this libDLO library and the performance was terrible. 23 FPS for copying a 160x144 RGB16 framebuffer over USB to the device. Turns out the above 40ms for filling the entire screen with one color uses a different code path, a way more efficient one, for crafting the USB packet. Will look into that.

    However, it turns out that this library internally converts the given framebuffer to a 24bit RGB framebuffer, pixel-by-pixel, and then tries to send entire rows to the USB device. Also, when make-ing the library, it compiled it without optimizations!

    So I did use CFLAGS="-O3", inserted the optimized library, and tada.. Game Boy Color emulation at ~90FPS. Internally I set the resolution to 640x480 and use the dlo_copy_host_bmp() function to copy the smaller framebuffer to the right position of the device's framebuffer.

    root@Omega-C465:~# ./gnuboy Pokemon\ Gold\ \(G\)\ [C][!].gbc
    test: device info: uid &77B2AC70
    test: device info: serial 861145
    test: device info: type  &F
    test: native mode info...
      1920x1080 @ 59 Hz 24 bpp base &0
    test: set_mode...
    test: mode info...
      640x480 @ 60 Hz 24 bpp base &0
    DisplayLink Init OK
    pcm_init()
    Doing joy_init.
    Init done.
    [-] Skipping data decompression.
    vid_settitle: POKEMON_GLDAAUD.
    FPS: 88.372 delta micros 1357896 for 120 frames
    FPS: 87.144 delta micros 1377025 for 120 frames
    FPS: 81.944 delta micros 1464420 for 120 frames
    

    0_1539030620102_IMG_20181008_222421.jpg

    Will update the repos soon. So now you can play GameBoy and GameBoy Color on a normal monitor with HDMI/DVI/VGA input and this USB graphics card.

    However, this is still way to slow. The to-be-transfered framebuffer was really tiny here and the transfor should have gone even fast than that. The pixel-by-pixel conversion definitely hurts performance. Also I'm completly bypassing the entire Linux by not using the framebuffer device or the DRI/DRM functions, but writing directly to the USB device using libusb.

    I'll look into the performance of these two other methods once I get them working. Right now writing to /dev/fb0 doesn't update the screen and only one out of 2 test programs for the DRI/DRM system are working. Maybe has to do something with the kernel-mode-setting (KMS) routines. Another option would be optimizing the libDLO library to omit some sanity checks and use a more efficient frame buffer format that does not require pixel-by-pixel transforms. I'll see.



  • Here's a link to a demonstration video! GameBoy Color emulation at 60FPS, properly synchronized using the audio. Using a DisplayLink DL-165, a FullHD monitor, a USB audio card and a WiiClassic I²C controller.

    Most of the CPU time is taken up by the routine that sends the framebuffer via USB. If that were not there, the CPU load would go down from 60% to about 26%. Which means that there's a lot of things to optimize here yet...

    Youtube Video

    I'll go the 'X11 Xorg server' route for a while and see where that takes me :).


Log in to reply
 

Looks like your connection to Community was lost, please wait while we try to reconnect.