directfb2 / DirectFB2

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

Invalid argument when using DRM/KMS backend with small display + hw accel #87

Open fifteenhex opened 1 year ago

fifteenhex commented 1 year ago

Notes as I debug this:

Output from scummvm (SDL2 + directfb2 + drm/kms + my hw driver):

# scummvm -p /data/scummvm/monkey/ --auto-detect

   ~~~~~~~~~~~~~~~~~~~~~~~~~~| 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-02-11 11:41) 
(*) DRMKMS/System: Using device /dev/dri/card0 (default)
(*) DRMKMS/System: Using PRIME file descriptor
(*) DRMKMS/System: Found 1 connectors, 1 encoders, 0 planes
(*) DirectFB/Input: Microsoft Xbox Series S|X Contr 0.1 (DirectFB)
(*) DirectFB/Input: Hot-plug detection enabled with Linux Input
(*) DirectFB/Genefx: NEON enabled
driver_probe()
(*) GE/driver: Opened GE, caps 0x1
(*) DirectFB/Graphics: MStar/SigmaStar ge 0.1 (linux-chenxing)
(*) DRMKMS/Screen: Default mode is 320x240 (1 modes in total)
(*) DirectFB/Core/WM: Default 0.3 (DirectFB)
WARNING: FSNode::createReadStream: 'scummvm.ini' does not exist!
Default configuration file missing, creating a new one
WARNING: Engine plugin for SCI not present. Fallback detection is disabled.!
WARNING: Engine plugin for Wintermute not present. Fallback detection is disabled.!
GameID                         Description                                                Full Path
------------------------------ ---------------------------------------------------------- ---------------------------------------------------------
scumm:monkey                   The Secret of Monkey Island (VGA/DOS/English)              /data/scummvm/monkey
Using game controller: Xbox Series X Controller
WARNING: SDL mixer output buffer size: 2048 differs from desired: 1024!
(!) DRMKMS/Surfaces: drmModeAddFB2( 3 ) failed!
    --> Invalid argument
(!) DirectFB/CoreSurface: Buffer allocation failed!
    --> A general or unknown error occurred
(!) DRMKMS/Surfaces: drmModeAddFB2( 3 ) failed!
    --> Invalid argument
WARNING: Could not find theme 'scummremastered' falling back to builtin!
(!) DRMKMS/Surfaces: drmModeAddFB2( 6 ) failed!
    --> Invalid argument
(!) DirectFB/CoreSurface: Buffer allocation failed!
    --> A general or unknown error occurred
(!) DRMKMS/Surfaces: drmModeAddFB2( 6 ) failed!
    --> Invalid argument
(!) DirectFB/CoreSurface: Buffer allocation failed!
    --> A general or unknown error occurred
(!) DRMKMS/Surfaces: drmModeAddFB2( 6 ) failed!
    --> Invalid argument

Backtrace from the `drmModeAddFB2()' line:

Thread 1 "scummvm" hit Breakpoint 4, drmkmsAllocateBuffer (pool=pool@entry=0xd8a200, pool_data=<optimized out>, pool_local=0xd8a2f0, buffer=buffer@entry=0xdf07a0, allocation=0x11948f8, alloc_data=0x1194c00) at ../systems/drmkms/drmkms_surface_pool.c:429
429     ../systems/drmkms/drmkms_surface_pool.c: No such file or directory.
(gdb) bt
#0  drmkmsAllocateBuffer (pool=pool@entry=0xd8a200, pool_data=<optimized out>, pool_local=0xd8a2f0, buffer=buffer@entry=0xdf07a0, allocation=0x11948f8, alloc_data=0x1194c00)
    at ../systems/drmkms/drmkms_surface_pool.c:429
#1  0xb68c9698 in dfb_surface_pool_allocate (pool=0xd8a200, buffer=buffer@entry=0xdf07a0, key=key@entry=0x0, handle=handle@entry=0, ret_allocation=ret_allocation@entry=0xbe9f12a0)
    at ../src/core/surface_pool.c:794
#2  0xb68ca0fc in dfb_surface_pools_allocate (buffer=buffer@entry=0xdf07a0, accessor=accessor@entry=CSAID_GPU, access=access@entry=CSAF_WRITE, ret_allocation=0xbe9f12dc, 
    ret_allocation@entry=0xbe9f12d4) at ../src/core/surface_pool.c:593
#3  0xb68a5da8 in ISurface_Real__PreLockBuffer (obj=0xdf0058, buffer=buffer@entry=0xdf07a0, accessor=accessor@entry=CSAID_GPU, access=access@entry=CSAF_WRITE, ret_allocation=0xbe9f130c)
    at ../src/core/CoreSurface_real.c:178
#4  0xb68983dc in CoreSurface_PreLockBuffer (obj=<optimized out>, buffer=buffer@entry=0xdf07a0, accessor=accessor@entry=CSAID_GPU, access=access@entry=CSAF_WRITE, 
    ret_allocation=0xbe9f130c, ret_allocation@entry=0xbe9f1304) at src/core/CoreSurface.c:196
#5  0xb68c62d4 in dfb_surface_buffer_lock (lock=0xdef2b8, access=CSAF_WRITE, accessor=CSAID_GPU, buffer=0xdf07a0) at ../src/core/surface_buffer.c:380
#6  dfb_surface_buffer_lock (buffer=0xdf07a0, accessor=accessor@entry=CSAID_GPU, access=CSAF_WRITE, lock=lock@entry=0xdef2b8) at ../src/core/surface_buffer.c:304
#7  0xb68ad7b4 in dfb_gfxcard_state_check_acquire (state=state@entry=0xdef1f4, accel=accel@entry=DFXL_FILLRECTANGLE) at ../src/core/gfxcard.c:1272
#8  0xb68ae498 in dfb_gfxcard_fillrectangles (rects=rects@entry=0xdef18c, num=<optimized out>, num@entry=1, state=0xdef1f4) at ../src/core/gfxcard.c:1687
#9  0xb68a49a4 in CoreGraphicsStateClient_FillRectangles (client=client@entry=0xdef508, rects=rects@entry=0xdef18c, num=num@entry=1) at ../src/core/CoreGraphicsStateClient.c:444
#10 0xb68d6dd0 in IDirectFBSurface_Clear (thiz=<optimized out>, r=<optimized out>, g=<optimized out>, b=<optimized out>, a=<optimized out>) at ../src/display/idirectfbsurface.c:929
#11 0xb6eed89c in DirectFB_RunCommandQueue (renderer=0x0, cmd=0xe70870, vertices=0xdea4c8, vertsize=<optimized out>)
    at buildroot/build/sdl2-2.26.2/src/video/directfb/SDL_DirectFB_render.c:754
#12 0xb6e85394 in SDL_uclibc_sin (x=1.2731974745816337e-311) at buildroot/build/sdl2-2.26.2/src/libm/s_sin.c:63
#13 0x001f1d48 in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
(gdb) 

DRM/KMS debug

[ 6038.968940] [drm:drm_ioctl] comm="Fusion Dispatch" pid=292, dev=0xe200, auth=1, DRM_IOCTL_MODE_CREATE_DUMB
[ 6038.970202] [drm:drm_ioctl] comm="Fusion Dispatch" pid=292, dev=0xe200, auth=1, DRM_IOCTL_PRIME_HANDLE_TO_FD
[ 6038.970360] [drm:drm_ioctl] comm="Fusion Dispatch" pid=292, dev=0xe200, auth=1, DRM_IOCTL_GEM_FLINK
[ 6038.970456] [drm:drm_ioctl] comm="Fusion Dispatch" pid=292, dev=0xe200, auth=1, DRM_IOCTL_MODE_ADDFB2
[ 6038.970567] panel-ilitek-ili9341 spi1.0: [drm:drm_internal_framebuffer_create] bad framebuffer width 300, should be >= 320 && <= 320
[ 6038.970656] [drm:drm_ioctl] comm="Fusion Dispatch", pid=292, ret=-22
[ 6038.972168] [drm:drm_ioctl] comm="Fusion Dispatch" pid=292, dev=0xe200, auth=1, DRM_IOCTL_MODE_DESTROY_DUMB
[ 6038.972992] [drm:drm_ioctl] comm="Fusion Dispatch" pid=292, dev=0xe200, auth=1, DRM_IOCTL_MODE_PAGE_FLIP

Seems to be with hw enabled the geometry of the buffer is wrong and DRM/KMS is rejecting it.

caramelli commented 1 year ago

Just to make sure I understand correctly, SDL2 applications:

I know you have size constraints to embed the DirectFB examples, but it might be interesting to be able to run df_andi and df_dok with directfb2-ge ​​hardware acceleration and this ILI9341 TFT screen (this will also give an idea of ​​performance).

SDL2 uses an IDirectFBWindow object: I don't know if the df_window example is able to start on a 320x240 screen but maybe the hardcoded sizes in the example can be updated for a simple test.

fifteenhex commented 1 year ago

Just to make sure I understand correctly, SDL2 applications:

  • are able to start when using the drmkms system module alone, regardless of the screen

With the fix for the pixel format, yes.

  • fail when using drmkms system module + directfb2-ge ​​GFX driver on ILI9341 TFT screen, but are able to start on another screen

I need to recheck this but they used to work on almost the same hardware on a bigger screen. The bigger screen is also 24 bit hence not noticing the pixel format issue before.

On the smaller SPI screen SDL2 applications will run with the hardware acceleration enabled but they constantly output the buffer allocation issue. The screen is being drawn though so it must be falling back to software.

I know you have size constraints to embed the DirectFB examples, but it might be interesting to be able to run df_andi and df_dok with directfb2-ge ​​hardware acceleration and this ILI9341 TFT screen (this will also give an idea of ​​performance).

Going to try that.. I need to change the examples meson file a bit so I can select what to install. I don't think the performance will change that much on the SPI screen. Performance with/without GE on the bigger screen is night and day though.

SDL2 uses an IDirectFBWindow object: I don't know if the df_window example is able to start on a 320x240 screen but maybe the hardcoded sizes in the example can be updated for a simple test.

I'll take a look.

fifteenhex commented 1 year ago

Notes:

fifteenhex commented 1 year ago

This works around the issue and I can see blits being done with the hardware now:

diff --git a/systems/drmkms/drmkms_surface_pool.c b/systems/drmkms/drmkms_surface_pool.c
index d4014027cd23..72f506d19142 100644
--- a/systems/drmkms/drmkms_surface_pool.c
+++ b/systems/drmkms/drmkms_surface_pool.c
@@ -414,7 +414,8 @@ drmkmsAllocateBuffer( CoreSurfacePool       *pool,
      allocation->size   = alloc->size;
      allocation->offset = alloc->prime_fd;

-     if (surface->type & (CSTF_LAYER | CSTF_WINDOW) && Core_GetIdentity() == local->core->fusion_id) {
+     //| CSTF_WINDOW
+     if ((surface->type & (CSTF_LAYER)) && Core_GetIdentity() == local->core->fusion_id) {
           u32 handles[4] = { 0, 0, 0, 0 };
           u32 pitches[4] = { 0, 0, 0, 0 };
           u32 offsets[4] = { 0, 0, 0, 0 };

I'm not sure what this logic is supposed to do. Certain buffers need to be directly added to the CRTC to start scan out? The window layer created by/for SDL2 is getting caught by this and then DRM/KMS says no.

The CPU usage is ~10% lower for the few things I've tried so certainly isn't a waste of time.

caramelli commented 1 year ago

I don't see issues when running DirectFB applications with this change. So if this gets your hardware working, let's push it: can you create a pull request?

fifteenhex commented 1 year ago

let's push it: can you create a pull request?

Sure. I want to quickly test I didn't break my other DFB2 using system and then I'll create a PR.