directfb2 / DirectFB2

Core DirectFB library
GNU Lesser General Public License v2.1
132 stars 15 forks source link

Possible 2D Hardware Acceleration? #94

Open edemirkan opened 1 year ago

edemirkan commented 1 year ago

I know this may be a too generic question, but what are my options to have some sort of 2D hardware acceleration enabled using DirectFB2?

Background; 1 - Trying to port an SDL2 application to my handheld gaming device which uses a quad-core ARM Cortex-A9 CPU 2 - The kernel is unfortunately closed, can't access to GPU. On the device I can only see /dev/fb0 and /dev/fb1 So that I decided to use directfb for SDL_VIDEODRIVER

3 - Here's my .directfbrc

system=fbdev
module-dir=lib/directfb-2.0-0
mode=640x480
hardware
depth=16
pixelformat=RGB16
bg-color=000000
no-cursor
sync

and directfb startup logs..

        (c) 2017-2023  DirectFB2 Open Source Project (fork of DirectFB)
        (c) 2012-2016  DirectFB integrated media GmbH
        (c) 2001-2016  The world wide DirectFB Open Source Community
        (c) 2000-2004  Convergence (integrated media) GmbH
      ----------------------------------------------------------------

(*) DirectFB/Core: Single Application Core. (2023-03-01 22:27) 
(*) DirectFB/Core: Synchronize data on disk with memory
(*) FBDev/System: Using device /dev/fb0 (default)
(*) FBDev/System: Found 'owlfb' (ID 0) with framebuffer at 0x0be0c000, 12000k (MMIO 0x00000000, 0k)
(*) DirectFB/Input: gpio-keys-polled 0.1 (DirectFB)
(*) DirectFB/Input: Hot-plug detection enabled with Linux Input
(*) DirectFB/Genefx: NEON enabled
(*) DirectFB/Graphics: Generic Software Rasterizer 0.7 (DirectFB)
(*) FBDev/Screen: Default mode is 640x480 (0 modes in total)
(*) DirectFB/Core/WM: Default 0.3 (DirectFB)
(*) FBDev/Mode: Setting 640x480 RGB16
(*) FBDev/Mode: Switched to 640x480 (virtual 640x480) at 16 bits (RGB16), pitch 1280

NEON support is enabled using the currently open PR.

Currently, I managed to have Generic Software Rasterizer running, which gives a ~30 fps for my app (By the way, thanks to your work, this is actually much better than DirectFB v1.7.7 which was ~20) and looking for some pointers if I could do/try/test anything more.

caramelli commented 1 year ago

I can see that Anbernic RG35XX has a PowerVR SGX544 GPU. When you say you can't access the GPU, do you mean you don't have libGLESv2 and libEGL userspace libraries?

On this platform, 2D hardware acceleration should be possible using the GFX driver DirectFB2-gles2

edemirkan commented 1 year ago

Yes, you're right. It's the userspace side we're lacking. PowerVR card drivers are split between kernel drivers and userspace libraries and binaries that "talk" to those drivers. The userspace pretty much translates OpenGLES to a language the kernel driver understands and kernel stuff is there, unfortunately not the userspace :(

I'll go ahead and try to compile and add DirectFB2-gles2. Do I need anything like DirectFB2-eglgbm? I'm still new to this and trying to understand how they all fit together.

Once I have the GFX driver, will it be still system=fbdev and driver automatically be detected? or do I need to change anything within directfbrc ?

edemirkan commented 1 year ago

I have the directfb2-gles2 compiled, but getting the following init device error.

I tested this both with the libGLESv2/libEGL generated by my buildroot toolchain, and also using swiftshader ones but no luck.

   ~~~~~~~~~~~~~~~~~~~~~~~~~~| DirectFB 2.0.0  |~~~~~~~~~~~~~~~~~~~~~~~~~~
        (c) 2017-2023  DirectFB2 Open Source Project (fork of DirectFB)
        (c) 2012-2016  DirectFB integrated media GmbH
        (c) 2001-2016  The world wide DirectFB Open Source Community
        (c) 2000-2004  Convergence (integrated media) GmbH
      ----------------------------------------------------------------

(*) DirectFB/Core: Single Application Core. (2023-03-01 22:27) 
(*) FBDev/System: Using device /dev/fb0 (default)
(*) FBDev/System: Found 'owlfb' (ID 0) with framebuffer at 0x0be0c000, 12000k (MMIO 0x00000000, 0k)
(*) DirectFB/Input: gpio-keys-polled 0.1 (DirectFB)
(*) DirectFB/Input: Hot-plug detection enabled with Linux Input
(*) DirectFB/Genefx: NEON enabled
(!) GLES2/Driver: Failed to create draw program!
(!) Core/Graphics: Could not init device!
    --> A general initialization error occurred
(*) FBDev/Screen: Default mode is 640x480 (0 modes in total)
(*) DirectFB/Core/WM: Default 0.3 (DirectFB)
(*) FBDev/Mode: Setting 640x480 RGB16
(*) FBDev/Mode: Switched to 640x480 (virtual 640x480) at 16 bits (RGB16), pitch 1280
(*) Direct/Interface: Loaded 'DGIFF' implementation of 'IDirectFBFont'
(*) Direct/Interface: Loaded 'DFIFF' implementation of 'IDirectFBImageProvider'
(*) FBDev/Mode: Setting 640x480 RGB16
(*) FBDev/Mode: Switched to 640x480 (virtual 640x480) at 16 bits (RGB16), pitch 1280
caramelli commented 1 year ago

Yes, in this case it is necessary to use a system module based on EGL. First, we need to know the underlying native platforms supported by this binary library: GBM platform might be supported, maybe some fbdev platform is also supported (as on the Mali 400 GPU) What output do you get when running readelf -d libEGL.so ?

edemirkan commented 1 year ago

Here's the one from my toolchain;

$ readelf -d /opt/rg35xx/arm-buildroot-linux-gnueabihf/sysroot/usr/lib/libEGL.so

Dynamic section at offset 0x15cb8 contains 36 entries:
  Tag        Type                         Name/Value
 0x00000001 (NEEDED)                     Shared library: [libgbm.so.1]
 0x00000001 (NEEDED)                     Shared library: [libglapi.so.0]
 0x00000001 (NEEDED)                     Shared library: [libexpat.so.1]
 0x00000001 (NEEDED)                     Shared library: [libdrm.so.2]
 0x00000001 (NEEDED)                     Shared library: [libm.so.6]
 0x00000001 (NEEDED)                     Shared library: [libgcc_s.so.1]
 0x00000001 (NEEDED)                     Shared library: [libc.so.6]
 0x00000001 (NEEDED)                     Shared library: [ld-linux-armhf.so.3]
 0x0000000e (SONAME)                     Library soname: [libEGL.so.1]
 0x00000010 (SYMBOLIC)                   0x0
 0x0000000c (INIT)                       0x2f8c
 0x0000000d (FINI)                       0x10550
 0x00000019 (INIT_ARRAY)                 0x25388
 0x0000001b (INIT_ARRAYSZ)               4 (bytes)
 0x0000001a (FINI_ARRAY)                 0x2538c
 0x0000001c (FINI_ARRAYSZ)               4 (bytes)
 0x00000004 (HASH)                       0xf4
 0x6ffffef5 (GNU_HASH)                   0x860
 0x00000005 (STRTAB)                     0x14c4
 0x00000006 (SYMTAB)                     0xa84
 0x0000000a (STRSZ)                      2504 (bytes)
 0x0000000b (SYMENT)                     16 (bytes)
 0x00000003 (PLTGOT)                     0x25e00
 0x00000002 (PLTRELSZ)                   864 (bytes)
 0x00000014 (PLTREL)                     REL
 0x00000017 (JMPREL)                     0x2c2c
 0x00000011 (REL)                        0x2094
 0x00000012 (RELSZ)                      2968 (bytes)
 0x00000013 (RELENT)                     8 (bytes)
 0x0000001e (FLAGS)                      SYMBOLIC BIND_NOW STATIC_TLS
 0x6ffffffb (FLAGS_1)                    Flags: NOW
 0x6ffffffe (VERNEED)                    0x1fd4
 0x6fffffff (VERNEEDNUM)                 4
 0x6ffffff0 (VERSYM)                     0x1e8c
 0x6ffffffa (RELCOUNT)                   360
 0x00000000 (NULL)                       0x0

And here's the one I compiled from swiftshader

$ readelf -d ~/code/github/rg35xx/rg35xx-toolchain/workspace/swiftshader/rg35xx/bin/libEGL.so

Dynamic section at offset 0xdd40 contains 34 entries:
  Tag        Type                         Name/Value
 0x00000001 (NEEDED)                     Shared library: [libz.so.1]
 0x00000001 (NEEDED)                     Shared library: [libstdc++.so.6]
 0x00000001 (NEEDED)                     Shared library: [libm.so.6]
 0x00000001 (NEEDED)                     Shared library: [libgcc_s.so.1]
 0x00000001 (NEEDED)                     Shared library: [libc.so.6]
 0x00000001 (NEEDED)                     Shared library: [ld-linux-armhf.so.3]
 0x0000000e (SONAME)                     Library soname: [libEGL.so]
 0x00000010 (SYMBOLIC)                   0x0
 0x0000000c (INIT)                       0x21d8
 0x0000000d (FINI)                       0xc6ec
 0x00000019 (INIT_ARRAY)                 0x1d924
 0x0000001b (INIT_ARRAYSZ)               12 (bytes)
 0x0000001a (FINI_ARRAY)                 0x1d930
 0x0000001c (FINI_ARRAYSZ)               8 (bytes)
 0x00000004 (HASH)                       0xd4
 0x6ffffef5 (GNU_HASH)                   0x3f4
 0x00000005 (STRTAB)                     0xc04
 0x00000006 (SYMTAB)                     0x5b4
 0x0000000a (STRSZ)                      2305 (bytes)
 0x0000000b (SYMENT)                     16 (bytes)
 0x00000003 (PLTGOT)                     0x1de70
 0x00000002 (PLTRELSZ)                   288 (bytes)
 0x00000014 (PLTREL)                     REL
 0x00000017 (JMPREL)                     0x20b8
 0x00000011 (REL)                        0x1690
 0x00000012 (RELSZ)                      2600 (bytes)
 0x00000013 (RELENT)                     8 (bytes)
 0x00000018 (BIND_NOW)
 0x6ffffffb (FLAGS_1)                    Flags: NOW
 0x6ffffffe (VERNEED)                    0x15d0
 0x6fffffff (VERNEEDNUM)                 3
 0x6ffffff0 (VERSYM)                     0x1506
 0x6ffffffa (RELCOUNT)                   299
 0x00000000 (NULL)                       0x0
caramelli commented 1 year ago

OK, I assume you also have a /dev/dri/card0 device file on your embedded filesystem.

As SwiftShader is a CPU-based implementation, I would focus on your toolchain's binary to expect 2D hardware acceleration. We can see the libgbm.so.1 dependency, so we can expect GBM platform support: you can try DirectFB2-eglgbm and set system=eglgbm in your .directfbrc instead of system=fbdev

To get an idea of ​​the performance, you can first test df_andi and df_dok examples.

Note that there are still some issues to resolve when using the DirectFB2-eglgbm system module combined with the DirectFB2-gles2 GFX driver (hardware acceleration).