hrydgard / ppsspp

A PSP emulator for Android, Windows, Mac and Linux, written in C++. Want to contribute? Join us on Discord at https://discord.gg/5NJB6dD or just send pull requests / issues. For discussion use the forums at forums.ppsspp.org.
https://www.ppsspp.org
Other
11.15k stars 2.16k forks source link

[SDL2] ppsspp fails to start with the KMS/DRM video driver. #13135

Open orbea opened 4 years ago

orbea commented 4 years ago

What happens?

The SDL ppsspp frontend fails to start from an unused tty when using the SDL2 KMS/DRM video driver. I do know this works with some other SDL2 programs so it should be able to work with ppsspp too.

To reproduce this:

  1. Make sure SDL2 is built with the DRM/KMS video driver which is disabled by default. Using the SDL2 autotools build system it requires passing --enable-video-kmsdrm to configure.
  2. Switch to an unused tty.
  3. Start ppsspp.
WARNING: radv is not a conformant vulkan implementation, testing use only.
55:14:608 Core/Config.cpp:1244 I[LOADER]: Loading controller config: /home/username/controls.ini
55:14:618 Core/Config.cpp:1337 I[LOADER]: Config saved (got storage permission): '/home/username/.config/ppsspp/PSP/SYSTEM/ppsspp.ini'
55:14:619 Core/Config.cpp:1350 I[LOADER]: Controller config saved: /home/username/controls.ini
I: VulkanLoader.cpp:268: VulkanMayBeAvailable: Device allowed ('SDL:Linux')
I: VulkanLoader.cpp:275: VulkanMayBeAvailable: Library loaded ('libvulkan.so')
I: VulkanLoader.cpp:328: VulkanMayBeAvailable: Enumerating instance extensions
I: VulkanLoader.cpp:339: VulkanMayBeAvailable: Instance extension count: 17
I: VulkanLoader.cpp:347: VulkanMaybeAvailable: Instance extension found: VK_KHR_device_group_creation (00000001)
I: VulkanLoader.cpp:347: VulkanMaybeAvailable: Instance extension found: VK_KHR_external_fence_capabilities (00000001)
I: VulkanLoader.cpp:347: VulkanMaybeAvailable: Instance extension found: VK_KHR_external_memory_capabilities (00000001)
I: VulkanLoader.cpp:347: VulkanMaybeAvailable: Instance extension found: VK_KHR_external_semaphore_capabilities (00000001)
I: VulkanLoader.cpp:347: VulkanMaybeAvailable: Instance extension found: VK_KHR_get_display_properties2 (00000001)
I: VulkanLoader.cpp:347: VulkanMaybeAvailable: Instance extension found: VK_KHR_get_physical_device_properties2 (00000001)
I: VulkanLoader.cpp:347: VulkanMaybeAvailable: Instance extension found: VK_KHR_get_surface_capabilities2 (00000001)
I: VulkanLoader.cpp:347: VulkanMaybeAvailable: Instance extension found: VK_KHR_surface (00000019)
I: VulkanLoader.cpp:347: VulkanMaybeAvailable: Instance extension found: VK_KHR_surface_protected_capabilities (00000001)
I: VulkanLoader.cpp:347: VulkanMaybeAvailable: Instance extension found: VK_KHR_xcb_surface (00000006)
I: VulkanLoader.cpp:347: VulkanMaybeAvailable: Instance extension found: VK_KHR_xlib_surface (00000006)
I: VulkanLoader.cpp:347: VulkanMaybeAvailable: Instance extension found: VK_KHR_display (00000017)
I: VulkanLoader.cpp:347: VulkanMaybeAvailable: Instance extension found: VK_EXT_direct_mode_display (00000001)
I: VulkanLoader.cpp:347: VulkanMaybeAvailable: Instance extension found: VK_EXT_acquire_xlib_display (00000001)
I: VulkanLoader.cpp:347: VulkanMaybeAvailable: Instance extension found: VK_EXT_display_surface_counter (00000001)
I: VulkanLoader.cpp:347: VulkanMaybeAvailable: Instance extension found: VK_EXT_debug_report (00000009)
I: VulkanLoader.cpp:347: VulkanMaybeAvailable: Instance extension found: VK_EXT_debug_utils (00000002)
I: VulkanLoader.cpp:385: VulkanMayBeAvailable: Calling vkCreateInstance
I: VulkanLoader.cpp:392: VulkanMayBeAvailable: Vulkan test instance created successfully.
I: VulkanLoader.cpp:429: VulkanMayBeAvailable: Found working Vulkan API!
I: VulkanLoader.cpp:436: VulkanMayBeAvailable: Destroying instance
DEBUG: Vulkan might be available.
Info: We compiled against SDL version 2.0.12 and we are linking against SDL version 2.0.12. :)
I: Config.cpp:527: Longest display side: -1 pixels. Choosing scale 1
Pixels: 960 x 544
Virtual pixels: 960 x 544
Failed to initialize glew!
GL init error ''
E: png_load.cpp:48: pngLoad: No such file or directory
I: SDLMain.cpp:117: SDL: Trying a different device
loading control pad mappings from gamecontrollerdb.txt: SUCCESS!
found control pad: boom PSX to PC Converter, loading mapping: SUCCESS, mapping is:
03000000666600006706000000010000,boom PSX to PC Converter,a:b2,b:b1,back:b8,dpdown:b14,dpleft:b15,dpright:b13,dpup:b12,leftshoulder:b6,leftstick:b9,lefttrigger:b4,leftx:a0,lefty:a1,rightshoulder:b7,rightstick:b10,righttrigger:b5,rightx:a2,righty:a3,start:b11,x:b3,y:b0,
pad 1 has been assigned to control pad: boom PSX to PC Converter
55:14:699 Common/MsgHandler.cpp:45 E[SYSTEM]: Critical: No draw context available!

What should happen?

I should be able to start ppsspp with the OpenGL video driver from an unused tty using the SDL2 DRM/KMS video driver.

What hardware, operating system, and PPSSPP version? On desktop, GPU matters for graphical issues.

OS: Slackware64-current ppsspp: https://github.com/hrydgard/ppsspp/commit/daf0990692f819c0e1e9d1aa52c007b455c7c2d4 SDL2: 2.0.12

konistehrad commented 3 years ago

I've had non-stop work commitments this week but I've started a branch here. Currently limited to exposing the Vulkan bindings to the rest of the system. EDIT: this is libretro-only.

orbea commented 3 years ago

To be clear this should be possible with opengl, opengles and vulkan.

konistehrad commented 3 years ago

I've started work on KMS for SDL here. Currently it will initialize but not show anything, but it's a start! I've had to turn GLEW into EGL mode to get this to work, in somewhat of a coarse method of changing the CMakeLists.txt for GLEW. (I know GLEW is going away at some point, though.) No work on Vulkan side yet.

konistehrad commented 3 years ago

Thanks for everyone's patience while I was digging around in here. Here's my findings so far on the use of SDL's KMS video driver:

As it happens, you can already start the SDL side using KMS, but it depends on both EGL and GLES, despite the following errors bubbling out of PPSSPPSDL:

ERROR: EGL Error EGL_BAD_NATIVE_WINDOW detected in file ../SDL/SDLGLGraphicsContext.cpp at line 264 (0x300B)
EGL ERROR: Unable to create EGL surface!
EGL_Init() failed

https://github.com/hrydgard/ppsspp/blob/291f9fdd70ce8760b78610e356f7c025389cfb2e/SDL/SDLMain.cpp#L608 This line isn't appropriate for KMS, we need to somehow apply SDL_WINDOW_FULLSCREEN_DESKTOP in the event that SDL_GetWindowWMInfo returns SDL_SYSWM_UNKNOWN (which is as close to "none" as I can find), but this occurs later: in the renderer-specific graphics contexts, well after the SDL_Window has been initialized: https://github.com/hrydgard/ppsspp/blob/291f9fdd70ce8760b78610e356f7c025389cfb2e/SDL/SDLGLGraphicsContext.cpp#L93

There's something wrong with the KMS driver in SDL in 2.0.12 (Groovy default) that causes flickering and tearing, but it appears that this was fixed in 2.0.14. Also atomic modesetting fallback was added in 2.0.14, which will restore compatibility for AMD cards.

I'm still investigating Vulkan, but I can confirm that it currently just bombs, almost certainly because SDLVulkanGraphicsContext::Init doesn't currently handle SDL_SYSWM_UNKNOWN.

unknownbrackets commented 3 years ago

Presumably the SDL_SYSWM_UNKNOWN is a bug in SDL, it not knowing/returning a proper value for the window manager?

Is this relevant? https://bugzilla.libsdl.org/show_bug.cgi?id=3690 https://bugzilla.libsdl.org/show_bug.cgi?id=5350

-[Unknown]

konistehrad commented 3 years ago

To my knowledge: SDL_SYSWM_UNKNOWN is expected when using KMS, as it operates outside of both Wayland and X, though it doesn't do anything kind for you like expose the GBM surface. The second link is almost certainly relevant. The first I believe is out of date with the merging of https://bugzilla.libsdl.org/show_bug.cgi?id=5393 .

unknownbrackets commented 3 years ago

It appears this is now fixed, per #14672. Might have been a change in SDL.

I'm going to close, but if there's a misunderstanding or it's still an issue, please comment and we'll reopen.

-[Unknown]

orbea commented 3 years ago

@unknownbrackets This is not fixed.

It now segfaults.

Thread 1 "PPSSPPSDL" received signal SIGSEGV, Segmentation fault.
0x0000000000abf2f6 in GLQueueRunner::CreateDeviceObjects (this=0x7c8) at ../Common/GPU/OpenGL/GLQueueRunner.cpp:37
37      ../Common/GPU/OpenGL/GLQueueRunner.cpp: No such file or directory.
(gdb) bt
#0  0x0000000000abf2f6 in GLQueueRunner::CreateDeviceObjects (this=0x7c8) at ../Common/GPU/OpenGL/GLQueueRunner.cpp:37
#1  0x0000000000ab3de4 in GLRenderManager::ThreadStart (this=0x0, draw=0x0) at ../Common/GPU/OpenGL/GLRenderManager.cpp:129
#2  0x0000000000b7694d in SDLGLGraphicsContext::ThreadStart (this=0x1e49160) at ../SDL/SDLGLGraphicsContext.h:33
#3  0x0000000000b72a77 in main (argc=1, argv=0x7fffffffe438) at ../SDL/SDLMain.cpp:764

Full gdb log: ppsspp-gdb.log

PPSSPP: https://github.com/hrydgard/ppsspp/commit/87723abdebd69e5482c051662b201a3c5d76e16d SDL: 2.0.14

unknownbrackets commented 3 years ago

Well, it's interesting that it worked fine for another person in #14672. Maybe there's another reason than just kmsdrm that glew cannot initialize on your system.

https://github.com/hrydgard/ppsspp/blob/87723abdebd69e5482c051662b201a3c5d76e16d/SDL/SDLGLGraphicsContext.cpp#L397-L398

-[Unknown]

orbea commented 3 years ago

That is a vulkan issue on a rasperrry pi, not opengl with amdgpu. Technically KMS/DRM is opengl only and I'm not sure if SDL2 support the vulkan equivalent?

Fwiw ppsspp doesn't start from a empty tty with vulkan either.

05:52:077 Core/Config.cpp:615 I[G3D]: Longest display side: -1 pixels. Choosing scale 1
05:52:087 Core/Config.cpp:1379 I[LOADER]: Loading controller config: /home/orbea/.config/ppsspp/PSP/SYSTEM/controls.ini
05:52:088 Core/Config.cpp:1412 I[LOADER]: Config loaded: '/home/orbea/.config/ppsspp/PSP/SYSTEM/ppsspp.ini'
05:52:092 Thread/ThreadManager.cpp:109 I[SYSTEM]: ThreadManager::Init(compute threads: 6, all: 10)
05:52:092 UI/NativeApp.cpp:381 N[LOADER]: Not checking for failed graphics backends in debug mode
05:52:114 Vulkan/VulkanLoader.cpp:462 I[G3D]: VulkanLoad: Found library 'libvulkan.so'
05:52:114 Vulkan/VulkanLoader.cpp:483 I[G3D]: VulkanLoad: Base functions loaded.
05:52:133 Vulkan/VulkanContext.cpp:133 I[G3D]: Vulkan debug_utils validation enabled.
05:52:148 Vulkan/VulkanLoader.cpp:556 I[G3D]: Vulkan instance functions loaded.
05:52:149 Vulkan/VulkanContext.cpp:673 I[G3D]: Debug callback registered with vkCreateDebugUtilsMessengerEXT.
05:52:149 Vulkan/VulkanContext.cpp:506 I[G3D]: Chose physical device 0: 0x366f470
05:52:149 Vulkan/VulkanContext.cpp:546 I[G3D]: Memory Types (8):
05:52:149 Vulkan/VulkanContext.cpp:555 I[G3D]:   0: Heap 0; Flags: DEVICE_LOCAL   
05:52:149 Vulkan/VulkanContext.cpp:555 I[G3D]:   1: Heap 1; Flags: HOST_VISIBLE HOST_COHERENT   
05:52:149 Vulkan/VulkanContext.cpp:555 I[G3D]:   2: Heap 2; Flags: DEVICE_LOCAL HOST_VISIBLE HOST_COHERENT   
05:52:149 Vulkan/VulkanContext.cpp:555 I[G3D]:   3: Heap 1; Flags: HOST_VISIBLE HOST_CACHED HOST_COHERENT   
05:52:149 Vulkan/VulkanContext.cpp:555 I[G3D]:   4: Heap 0; Flags: DEVICE_LOCAL   
05:52:149 Vulkan/VulkanContext.cpp:555 I[G3D]:   5: Heap 1; Flags: HOST_VISIBLE HOST_COHERENT   
05:52:149 Vulkan/VulkanContext.cpp:555 I[G3D]:   6: Heap 2; Flags: DEVICE_LOCAL HOST_VISIBLE HOST_COHERENT   
05:52:149 Vulkan/VulkanContext.cpp:555 I[G3D]:   7: Heap 1; Flags: HOST_VISIBLE HOST_CACHED HOST_COHERENT   
05:52:163 Vulkan/VulkanLoader.cpp:563 I[G3D]: Vulkan device functions loaded.
05:52:163 Vulkan/VulkanLoader.cpp:579 I[G3D]: Missing (device): vkGetPhysicalDeviceSparseImageFormatProperties
05:52:163 Vulkan/VulkanContext.cpp:650 I[G3D]: Device created.

Vulkan subsystem 0 not supported
VulkanMayBeAvailable: Device allowed ('SDL:Linux')
VulkanMayBeAvailable: Library loaded ('libvulkan.so')
VulkanMayBeAvailable: Enumerating instance extensions
VulkanMayBeAvailable: Instance extension count: 17
VulkanMaybeAvailable: Instance extension found: VK_KHR_device_group_creation (00000001)
VulkanMaybeAvailable: Instance extension found: VK_KHR_display (00000017)
VulkanMaybeAvailable: Instance extension found: VK_KHR_external_fence_capabilities (00000001)
VulkanMaybeAvailable: Instance extension found: VK_KHR_external_memory_capabilities (00000001)
VulkanMaybeAvailable: Instance extension found: VK_KHR_external_semaphore_capabilities (00000001)
VulkanMaybeAvailable: Instance extension found: VK_KHR_get_display_properties2 (00000001)
VulkanMaybeAvailable: Instance extension found: VK_KHR_get_physical_device_properties2 (00000002)
VulkanMaybeAvailable: Instance extension found: VK_KHR_get_surface_capabilities2 (00000001)
VulkanMaybeAvailable: Instance extension found: VK_KHR_surface (00000019)
VulkanMaybeAvailable: Instance extension found: VK_KHR_surface_protected_capabilities (00000001)
VulkanMaybeAvailable: Instance extension found: VK_KHR_xcb_surface (00000006)
VulkanMaybeAvailable: Instance extension found: VK_KHR_xlib_surface (00000006)
VulkanMaybeAvailable: Instance extension found: VK_EXT_acquire_xlib_display (00000001)
VulkanMaybeAvailable: Instance extension found: VK_EXT_debug_report (0000000a)
VulkanMaybeAvailable: Instance extension found: VK_EXT_direct_mode_display (00000001)
VulkanMaybeAvailable: Instance extension found: VK_EXT_display_surface_counter (00000001)
VulkanMaybeAvailable: Instance extension found: VK_EXT_debug_utils (00000002)
VulkanMayBeAvailable: Calling vkCreateInstance
VulkanMayBeAvailable: Vulkan test instance created successfully.
VulkanMayBeAvailable: Found working Vulkan API!
VulkanMayBeAvailable: Destroying instance
DEBUG: Vulkan might be available.
Info: We compiled against SDL version 2.0.14 and we are linking against SDL version 2.0.14. :)
Registered VFS for prefix : /usr/share/games/ppsspp/assets
Registered VFS for prefix : /usr/games/assets
Registered VFS for prefix : /usr/games
Registered VFS for prefix : /usr/local/share/ppsspp/assets
Registered VFS for prefix : /usr/local/share/games/ppsspp/assets
Registered VFS for prefix : /usr/share/ppsspp/assets
Registered VFS for prefix : /usr/share/games/ppsspp/assets
Registered VFS for prefix : assets
Registered VFS for prefix : /home/orbea
Pixels: 960 x 544
Virtual pixels: 960 x 544
vanfanel commented 3 years ago

@orbea SDL2 KMS/DRM is NOT OpenGL only, it also supports Vulkan. I made it work last year: https://github.com/libsdl-org/SDL/blob/main/src/video/kmsdrm/SDL_kmsdrmvulkan.c In other words: SDL2 supports Vulkan on the TTY, no X11 needed.

As for OpenGL on TTY on a Pi4: This issue is fixed. Are you using latest SDL2 GIT code? It works here for OpenGL, that's for sure.

unknownbrackets commented 3 years ago

I noticed in the other issue a note about using SDL2 git, is it possible OpenGL would only work with the latest git of SDL2 and that's why it's not working for orbea?

-[Unknown]

vanfanel commented 3 years ago

@unknownbrackets That's very possible. Latest SDL2 GIT sure works with PPSSPP in OpenGL mode on the TTY (KMS/DRM backend). It works here, that's for sure.

orbea commented 3 years ago

The latest SDL2 git doesn't currently build for me, I'll have to spend time figuring that out first...

vanfanel commented 3 years ago

@orbea Builds here, both on X86_64 and aarch64, using GCC 8.3.0 and 9.3.0.

orbea commented 3 years ago

The build issue: https://github.com/libsdl-org/SDL/pull/4583

I have now tested the latest SDL2 (https://github.com/libsdl-org/SDL/commit/1907463a7e876d0aec1d2a87839ec8b9b30d64d2) and the crash has not changed.

orbea commented 3 years ago

I can reproduce this on a second system with gentoo installed.

vanfanel commented 3 years ago

@orbea That's really strange... I have PPSSPP working fine on KMS/DRM here, using OpenGL...

orbea commented 3 years ago

What distro are you using? How about GPU?

vanfanel commented 3 years ago

@orbea I use Debian 10 aarch64, wich is the same as using Raspberry Pi OS 64. I use KMS. DispmanX is not installed on my system (DispmanX is legacy by now, KMSDRM is the way forward as it's the Linux graphics standard). So you must be able to build SDL2 with --enable-video-kmsdrm

orbea commented 3 years ago

Could this be something that only works on arm platforms? I only have x86_64 to test.

So you must be able to build SDL2 with --enable-video-kmsdrm

I did do that, but its now enabled by default in the SDL2 git repo. :)

I also reconfirmed that kms does work with other SDL2 programs, not sure why ppsspp is special?

vanfanel commented 3 years ago

@orbea Just to get an exact idea on what's going on there: Did you finally get latest SDL2 GIT sources to build finally? What MESA GL implementation are you using on that X86_64 system? (AMDGPU, Intel, Nouveau...?) Are you using MESA GL or a vendor-closed solution?

orbea commented 3 years ago

Did you finally get latest SDL2 GIT sources to build finally?

Yes, as documented in this earlier comment. https://github.com/hrydgard/ppsspp/issues/13135#issuecomment-891982342

What MESA GL implementation are you using on that X86_64 system? (AMDGPU, Intel, Nouveau...?) Are you using MESA GL or a vendor-closed solution?

Both of my systems have AMDGPU and I am using the open source GL implementation.

vanfanel commented 3 years ago

@orbea I am running Lubuntu 20.04, latest SDL2 GIT on stock MESA on my X86_64 laptop. So I went and built PPSSPP on it, and it works fine using on KMSDRM using SDL2, really. I also have AMDGPU graphics on this system.

orbea commented 3 years ago

Maybe there is a distro patch for something like SDL2, mesa or maybe even glew that fixes this on your end? Are you doing anything special to run ppsspp other than running the PPSSPPSDL binary in an unused tty?

Otherwise there must be some other difference?

For reference I have glew-2.2.0.

vanfanel commented 3 years ago

@orbea No, I haven't done anything special on my system. I am configuring SDL2 like this: ./configure --enable-video-x11 --disable-video-wayland --disable-dbus --disable-diskaudio --disable-oss --disable-pulseaudio --disable-dummyaudio --disable-video-dummy --enable-video-opengles --enable-video-opengl --enable-libudev --disable-dbus --disable-ime --enable-video-kmsdrm

And PPSSPP like this: cmake .. -DUSING_X11_VULKAN=OFF -DUSING_GLES2=ON -DUSE_DISCORD=OFF -DCMAKE_C_FLAGS="-DEGL_NO_X11" -DCMAKE_CXX_FLAGS="-DEGL_NO_X11"

orbea commented 3 years ago

@vanfanel I recompiled PPSSPP with -DUSING_GLES2=ON and now it works when using OpenGLES. Can you reproduce my issue if you compile ppsspp with -DUSING_GLES2=OFF (The default on x86_64) and use regular OpenGL?

orbea commented 3 years ago

Building PPSSPP with -DUSING_EGL=ON -DUSING_GLES2=OFF also fails to start from an unused tty with KMS.

vanfanel commented 3 years ago

@orbea Yes, I can replicate your issue if I do -DUSING_GLES2=OFF

I hadn't though about disabling GLES and using OpenGL instead... Ok, the problem could to be that GLEW is trying to use the old GLX, instead of the modern GLVND. GLX won't (in general) work on a TTY, but GLVND will.

It's possible to tell GLEW to use GLVND instead of GLX, but I don't know the details in PPSSPP building.

@unknownbrackets Where do you pass defines to GLEW? Can you please tell it to use GLVND instead of GLX?

orbea commented 3 years ago

That is not the problem, I do not have have GLVND and other SDL2 programs work just fine with KMS and OpenGL.

Edit: An example of a program using OpenGL, SDL2 and works with KMS is Solarus.

https://solarus-games.org/

vanfanel commented 3 years ago

@orbea Ah, well, then I don't know what the problem is. I can see "failed to initialize glew!" so GLEW seems to be the problem.

Also, Solarus doesn't seem to use GLEW. And... well, look at the error message.