Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Raspberry Pi support #2837

Closed
wants to merge 6 commits into from
Closed

Raspberry Pi support #2837

wants to merge 6 commits into from

Conversation

hinxx
Copy link

@hinxx hinxx commented Oct 7, 2019

This PR adds support for compiling SDL + opengl3 example on Raspberry Pi (RPi).
RPi uses EGL instead of full openGL. Makefile was adjusted to pull in RPi specific headers and libraries found in /opt/vc through pkg-config.
Since it seems to be no way of automatically detecting compilation for RPi target, it is essentially ARM CPU, a new define called RPI was introduced in the Makefile and passed to the compiler.
The use of opengl ES 2.0 is also forced through -DIMGUI_IMPL_OPENGL_ES2 specified in the Makefile.

The code was compiled natively and the result was successfully tested on the target.

@NeroBurner
Copy link
Contributor

@hinxx would you mind to test the cmakeified version from https://github.com/NeroBurner/imgui/tree/example_sdl_vulkan_cmake of example_sdl_opengl2 or example_sdl_opengl3 on the raspberry pi if the find_package(OpenGL) cmake call finds the right things on the raspberry Pi

cmake -Hexamples/example_sdl_opengl2 -B_build
cmake --build _build

@ocornut ocornut added the opengl label Oct 14, 2019
@hinxx
Copy link
Author

hinxx commented Oct 15, 2019

@NeroBurner here are the results:

SDL1 w/ openGL2:

pi@raspberrypi:~/cmake-imgui $ cmake -Hexamples/example_sdl_opengl2 -B_build
-- The C compiler identification is GNU 8.3.0
-- The CXX compiler identification is GNU 8.3.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- create target SDL2::SDL2 with include dir '/usr/local/include/SDL2' and library '-L/usr/local/lib -Wl,-rpath,/usr/local/lib -Wl,--enable-new-dtags -lSDL2'
-- Could NOT find OpenGL (missing: OPENGL_opengl_LIBRARY OPENGL_glx_LIBRARY OPENGL_INCLUDE_DIR) 
CMake Error at CMakeLists.txt:35 (message):
  OpenGL library was not found)


-- Configuring incomplete, errors occurred!
See also "/home/pi/cmake-imgui/_build/CMakeFiles/CMakeOutput.log".

SDL1 w/ openGL3:

pi@raspberrypi:~/cmake-imgui $ cmake -Hexamples/example_sdl_opengl3 -B_build
-- The C compiler identification is GNU 8.3.0
-- The CXX compiler identification is GNU 8.3.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- create target SDL2::SDL2 with include dir '/usr/local/include/SDL2' and library '-L/usr/local/lib -Wl,-rpath,/usr/local/lib -Wl,--enable-new-dtags -lSDL2'
-- Could NOT find OpenGL (missing: OPENGL_opengl_LIBRARY OPENGL_glx_LIBRARY OPENGL_INCLUDE_DIR) 
CMake Error at CMakeLists.txt:35 (message):
  OpenGL library was not found)


-- Configuring incomplete, errors occurred!
See also "/home/pi/cmake-imgui/_build/CMakeFiles/CMakeOutput.log".

##---------------------------------------------------------------------
## OPENGL LOADER
##---------------------------------------------------------------------

ifndef RPI
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently if new platform flag was introduced this bit will have to be rewritten as it wont really make sense any more. Instead if we had ifdef RPI here we could just append a case of new platform in the future without altering old code.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds like a sane comment, looking into future.


ifndef RPI
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not aware of Makefile conventions, but indentation here does look confusing. Do people treat ifdef/endif in Makefiles as #ifdef or as if in c?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I know, Makefile syntax in this case does not impose the rules about indents (just like C does not). IMO, it is more a matter of convention and what original code uses.
I used indent as they were used before my change. I should have followed this approach for the ifndef on lines 32 and 40 as well to be consistent.

#if defined(IMGUI_IMPL_OPENGL_ES2)
#include <GLES2/gl2.h>
#elif defined(IMGUI_IMPL_OPENGL_ES3)
#if (defined(__APPLE__) && (TARGET_OS_IOS || TARGET_OS_TV))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where do TARGET_OS_IOS and TARGET_OS_TV come from? I do not see them in Makefile. Does platform define them?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They're in <TargetConditionals.h>. Include is missing.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TARGET_OS_XX macros are defined by Apple headers, specifically TargetConditionals.h.
What's not absolutely clear is if that file is included even indirectly from main.cpp, maybe including it explicitely would be good (like imgui_impl_opengl3.cpp does)

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But if we can establish that e.g. SDL.h always include it I'm happy relying on that knowledge.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems that compiler / pre-processor define those. Some insight here: http://nadeausoftware.com/articles/2012/01/c_c_tip_how_use_compiler_predefined_macros_detect_operating_system#OSXiOSandDarwin

It would be nice to detect 'platforms' like RPi like this but as it happens, to compiler RPi CPU looks just like any other ARM based CPU. While ARM CPU can be distinguished from x86, it is too wide.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If __APPLE__ is defined "TargetConditionals.h" is safe to include and I think it should be. This is the place where all TARGET_XXX macros are defined.
If SDL.h include it it would be for very same reason it should be included here. Those are macros and they are leaking into user code, relying on that does sound like a good idea.

This type of target detection isn't unique to Apple platforms. Windows SDK provide <winapifamily.h> serving very same purpose.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what about grep -o BCM2708 /proc/cpuinfo for RPI detection? (or BCM2709 for the rpi 2 & 3). However this would not work when cross compiling. Perhaps another approach is to check for /opt/vc/include/bcm_host.h

@sphaero
Copy link

sphaero commented Feb 19, 2020

Trying to do this on latest Raspbian and latest master gives the error:

ERROR: ImGui_ImplOpenGL3_CreateDeviceObjects: failed to compile vertex shader!
ERROR: ImGui_ImplOpenGL3_CreateDeviceObjects: failed to compile fragment shader!
ERROR: ImGui_ImplOpenGL3_CreateDeviceObjects: failed to link shader program! (with GLSL '#version 100

@sphaero
Copy link

sphaero commented Feb 19, 2020

Ok, it happens when the linking is wrong. It should link with the GLES libs in /opt/vc not the ones in /usr.

ldd example_sdl_opengl3 
	linux-vdso.so.1 (0x7ed5c000)
	/usr/lib/arm-linux-gnueabihf/libarmmem-${PLATFORM}.so => /usr/lib/arm-linux-gnueabihf/libarmmem-v7l.so (0x76ed4000)
	libbrcmGLESv2.so => /opt/vc/lib/libbrcmGLESv2.so (0x76eaf000)
	libbcm_host.so => /opt/vc/lib/libbcm_host.so (0x76e85000)
	libvcos.so => /opt/vc/lib/libvcos.so (0x76e6c000)
	libvchiq_arm.so => /opt/vc/lib/libvchiq_arm.so (0x76e56000)
	libGL.so.1 => /usr/lib/arm-linux-gnueabihf/libGL.so.1 (0x76dc9000)
	libdl.so.2 => /lib/arm-linux-gnueabihf/libdl.so.2 (0x76db6000)
	libSDL2-2.0.so.0 => /usr/local/lib/libSDL2-2.0.so.0 (0x76c83000)
	libstdc++.so.6 => /usr/lib/arm-linux-gnueabihf/libstdc++.so.6 (0x76b3c000)
	libm.so.6 => /lib/arm-linux-gnueabihf/libm.so.6 (0x76aba000)
	libgcc_s.so.1 => /lib/arm-linux-gnueabihf/libgcc_s.so.1 (0x76a8d000)
	libpthread.so.0 => /lib/arm-linux-gnueabihf/libpthread.so.0 (0x76a63000)
	libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0x76915000)
	libbrcmEGL.so => /opt/vc/lib/libbrcmEGL.so (0x768dc000)
	librt.so.1 => /lib/arm-linux-gnueabihf/librt.so.1 (0x768c5000)
	libGLdispatch.so.0 => /usr/lib/arm-linux-gnueabihf/libGLdispatch.so.0 (0x76846000)
	libGLX.so.0 => /usr/lib/arm-linux-gnueabihf/libGLX.so.0 (0x76827000)
	/lib/ld-linux-armhf.so.3 (0x76ee9000)
	libX11.so.6 => /usr/lib/arm-linux-gnueabihf/libX11.so.6 (0x76705000)
	libxcb.so.1 => /usr/lib/arm-linux-gnueabihf/libxcb.so.1 (0x766d6000)
	libXau.so.6 => /usr/lib/arm-linux-gnueabihf/libXau.so.6 (0x766c3000)
	libXdmcp.so.6 => /usr/lib/arm-linux-gnueabihf/libXdmcp.so.6 (0x766ac000)
	libbsd.so.0 => /usr/lib/arm-linux-gnueabihf/libbsd.so.0 (0x76684000)

It runs fine now

@hinxx
Copy link
Author

hinxx commented Mar 6, 2020

@sphaero my pull request explicitly uses /opt libs. I tried with the ones from apt , that end up in /usr back then and did not get far.

@hinxx
Copy link
Author

hinxx commented Mar 6, 2020

BTW, what is the current status of this pull request? Is there something preventing the merge?
I can improve/change the pull request if required.

@sphaero
Copy link

sphaero commented Mar 6, 2020

Yes, the ones in /usr are not hardware accelerated and require a Xorg session.

If I would need to provide feedback to the PR I would question whether it's not using the IMGUI_IMPL_OPENGL_LOADER_CUSTOM approach. I kind of have the feeling this is a bit too hardcoded for the RPI while that's not needed. Why not a specific rpi example then? On the other hand this can work (if resolved) and the RPI is a big tinker platform.

@readblack1234
Copy link

Trying to do this on latest Raspbian and latest master gives the error:

ERROR: ImGui_ImplOpenGL3_CreateDeviceObjects: failed to compile vertex shader!
ERROR: ImGui_ImplOpenGL3_CreateDeviceObjects: failed to compile fragment shader!
ERROR: ImGui_ImplOpenGL3_CreateDeviceObjects: failed to link shader program! (with GLSL '#version 100

I tried now with Rpi branch on raspberry 3b+, and got same error!
I tried with
SDL_VIDEODRIVER=rpi ./example_sdl_opengl3
but then it does not give error however it does not show window or do anything.

I also checked the libs are linking to /opt/vc and see similar to what you have except I am missing few ones, not sure why
linux-vdso.so.1 (0x7eece000)
/usr/lib/arm-linux-gnueabihf/libarmmem-${PLATFORM}.so => /usr/lib/arm-linux-gnueabihf/libarmmem-v7l.so (0x76ee8000)
libdl.so.2 => /lib/arm-linux-gnueabihf/libdl.so.2 (0x76eb3000)
libSDL2-2.0.so.0 => /home/pi/sld2Install/SDL2-2.0.9/sysroot/lib/libSDL2-2.0.so.0 (0x76da9000)
libbrcmGLESv2.so => /opt/vc/lib/libbrcmGLESv2.so (0x76d84000)
libbrcmEGL.so => /opt/vc/lib/libbrcmEGL.so (0x76d4b000)
libbcm_host.so => /opt/vc/lib/libbcm_host.so (0x76d21000)
libvcos.so => /opt/vc/lib/libvcos.so (0x76d08000)
libvchiq_arm.so => /opt/vc/lib/libvchiq_arm.so (0x76cf2000)
libstdc++.so.6 => /usr/lib/arm-linux-gnueabihf/libstdc++.so.6 (0x76bab000)
libm.so.6 => /lib/arm-linux-gnueabihf/libm.so.6 (0x76b29000)
libgcc_s.so.1 => /lib/arm-linux-gnueabihf/libgcc_s.so.1 (0x76afc000)
libpthread.so.0 => /lib/arm-linux-gnueabihf/libpthread.so.0 (0x76ad2000)
libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0x76984000)
/lib/ld-linux-armhf.so.3 (0x76efd000)
librt.so.1 => /lib/arm-linux-gnueabihf/librt.so.1 (0x7696d000)

Question: Is this working pr now?

@hinxx
Copy link
Author

hinxx commented Jul 13, 2020

Question: Is this working pr now?

I noticed there were some updates to the files my PR is also touching. I just updated my PR with the latest upstream master code and re-tested on RPi. Works as expected for me.

Here are some notes about how I did it: NOTES.txt

And the device OS info:

pi@raspberrypi:~ $ uname -a
Linux raspberrypi 4.19.66+ #1253 Thu Aug 15 11:37:30 BST 2019 armv6l GNU/Linux
pi@raspberrypi:~ $ cat /etc/debian_version 
9.11

@geiseri
Copy link

geiseri commented Sep 4, 2020

I can test here, tbh, I think most people using the RPi are going to be building custom so I would have no issue with having hardcoded settings for it.

@hinxx
Copy link
Author

hinxx commented Sep 7, 2020

I think most people using the RPi are going to be building custom so I would have no issue with having hardcoded settings for it.

I guess by 'custom' you mean with the custom folder layout if doing cross compiling? If so then it is pretty much up to the selected tools and placement of the /opt/vc contents on the host.

@hinxx
Copy link
Author

hinxx commented Sep 7, 2020

I tried to cross compile the SDL opengl3 example and seems that one is free to decide where to put headers and libs from /opt/vc for cross compiling for RPi. In addition there seems to be a large amount of toolchains to choose from; not sure about the compability with the official OS image, though.

I picked the official one at https://github.com/raspberrypi/tools for my tests today.

In order to cross compile I took the official OS image and mounted the rootfs part on host PC; this way I could get a hold of the /opt/vc contents. Maybe there is a better way, but I'm not sure if there exists a package for these files.

Next I needed to get SDL2 cross compiled for RPi and installed on the host (also required on the RPi if doing native build).

Then I got around and tried to revisit the Makefile parts of this PR. It might be enough to have three definitions to make the RPi build go through, either when compiling on the target or when cross compiling. This would have a minimal impact on the Makefile in regards to changes specific to RPi, IMHO.

What would be added is a rpi-build.sh script, that could be executed either on the target or on the host. This script would setup the environment for the cross compilation and native RPi compile and call make. Essentially RPI flag, RPI_CFLAGS and RPI_LIBS would be exported for the make process. This approach would relieve us from figuring out how to detect RPi build in the Makefile since we would explicitly run rpi-build.sh, only for RPi building.

Source main.cpp still needs to check for RPI and setup SDL GL context with SDL_GL_SetAttribute(); this would remain as-is in the PR.

I need to cleanup the changes I have and then I'll update the PR.

@lethal-guitar
Copy link
Contributor

lethal-guitar commented Dec 29, 2020

Hi @hinxx, I just found your PR and was wondering if you'd be open to fix the mouse position detection issue in a slightly different way? I'm referring to this change: 361f68b#diff-62603e3f16b4d34a44a31904aea9bed53b56b01fdba50f9fb84c8c416eeb2e77R235

My suggestion would be that instead of checking for a RPI define, we could extend the code that updates g_MouseCanUseGlobalState (see here):

g_MouseCanUseGlobalState =
  strncmp(SDL_GetCurrentVideoDriver(), "wayland", 7) != 0 &&
  strncmp(SDL_GetCurrentVideoDriver(), "RPI", 3) != 0;

Edit: Thinking about it some more, I decided to check for all known supported backends instead of checking for known not working ones. See lethal-guitar/RigelEngine@597f1b8

With that change, mouse interaction works correctly for me on my Pi 3.

The advantage of this approach is that as a user of Dear ImGui, I don't have to define RPI in my build system in order to get the mouse to work correctly. As you said in the PR description, it's not really easy to automatically and reliably detect that the build target is a Raspberry Pi. This means that if the Pi needs a define to work correctly, then I would also need to add a configuration parameter to my build system to set this define, and I would need to set this flag accordingly when building for the Pi etc. It would be nice if that wasn't necessary, as currently my project builds and runs fine on a Pi without any Pi-specific defines - I only need to specify that I want to build for OpenGL ES, which is used for other platforms as well, so that's not Pi-specific.

Let me know what you think. I'd also be happy to open a follow-up PR of my own after you've merged yours if you'd prefer to leave your solution as is 🙂

@hinxx
Copy link
Author

hinxx commented Jan 5, 2021

@lethal-guitar I would need to remind myself of what the PR does, but I'm in favor of any change that would remove RPI define.

You said that you do not need a RPI define to build it; I presume this is done natively on the Rpi itself. Seems the other code I wrapped in the RPI define can therefore be used as-is, without the RPI define, or am I missing something here?

@lethal-guitar
Copy link
Contributor

@hinxx

You said that you do not need a RPI define to build it

Exactly, in my project, I don't have a RPI define. I only have a define to distinguish between OpenGL ES and Desktop GL. To build for the Pi, I just need to enable the GL ES define, which then defines IMGUI_IMPL_OPENGL_ES2. Everything else works the same as on other platforms.

I should note however that I'm using glad as a loader for OpenGL ES (See here). This has the nice advantage that I don't need to link to any Raspberry Pi specific libraries at build time. I think unless we would do the same in the ImGui examples, we still need some Pi-specific logic in the Makefile, to link against the Broadcom VC stuff.

Seems the other code I wrapped in the RPI define can therefore be used as-is, without the RPI define, or am I missing something here?

I think you'd need to test for IMGUI_IMPL_OPENGL_ES2 instead of RPI here:

https://github.com/ocornut/imgui/pull/2837/files#diff-25d7a3c5c3cf7a9eb9b4ec2f7ca14d633d96b014cd7d6f0b03b410d41ed559a0R69

Other than that, I believe yes, this code should work for any OpenGL ES build, Pi or something else.

@ebachard
Copy link

ebachard commented Jan 25, 2021

This PR adds support for compiling SDL + opengl3 example on Raspberry Pi (RPi).
RPi uses EGL instead of full openGL. Makefile was adjusted to pull in RPi specific headers and libraries found in /opt/vc through pkg-config.
Since it seems to be no way of automatically detecting compilation for RPi target, it is essentially ARM CPU, a new define called RPI was introduced in the Makefile and passed to the compiler.
The use of opengl ES 2.0 is also forced through -DIMGUI_IMPL_OPENGL_ES2 specified in the Makefile.

The code was compiled natively and the result was successfully tested on the target.
@hinxx

I got openGL3.0 and OpenGL ES 3.1 on RPi 4 (aarch64), (just in case you are interested) :

https://framagit.org/ericb/ir_thermography/-/commit/1b11a9f31de14db80156c108f0c874dd87fbe8ae

Edit : don't forget RPi3 b+ is armhf, not aarch64 !

@lethal-guitar
Copy link
Contributor

lethal-guitar commented Mar 19, 2021

@ocornut your summary of the three topics sounds right to me.

The mouse position fix does indeed seem like something you could merge right now. My proposal is to do it like here: lethal-guitar/RigelEngine@597f1b8

I also believe that checking for the GL ES define instead of RPI as you suggest should be sufficient. More concretely, there is one place in main.cpp: https://github.com/ocornut/imgui/pull/2837/files#diff-25d7a3c5c3cf7a9eb9b4ec2f7ca14d633d96b014cd7d6f0b03b410d41ed559a0R69

So RPI should be replaced by IMGUI_IMPL_OPENGL_ES2 in that spot.

@lethal-guitar
Copy link
Contributor

lethal-guitar commented Mar 20, 2021

@ocornut I went ahead and opened two PRs, to tackle the first two topics. Let me know what you think.

@hinxx @hippyau I noticed that linking to brcmGLESv2 was enough to get the example to run properly on my Pi 3 model B running Raspbian Buster. I believe the other libraries that were added to the Makefile in this PR (bcm_host and brcmegl) are already pulled in by SDL itself when it is compiled with the RPI backend, so we don't need to link them separately. I also didn't need to set an include path into the /opt/vc dir - which makes sense, since the system provided GL ES header file should be interface compatible with the Broadcom implementation.

@hinxx
Copy link
Author

hinxx commented Mar 22, 2021

Wow, lots happened in the last three days on multiple fronts! I'm a bit out of sync what the status of RPi is ATM, and what still remains to be solved by this PR.
I see #3950 should take case of the mouse detection.
According to @lethal-guitar the Makefile changes should not be required, if I understand correctly. BTW, will it work for both, native and cross compilation?

What remains would be the build script which I volunteered to make a while ago (and never came around to do it). I can look into the script in the coming days, though, in the light of having this PR closed.

Is there a fork/branch of the all RPi changes currently agreed upon that I could test and work of? Or should I just pick up master branch here?

Thank you and apologizes for being slow!

@lethal-guitar
Copy link
Contributor

lethal-guitar commented Mar 23, 2021

@hinxx there is still #3951 which I need to do a bit of work on before it can be merged - but once that's done, all changes aside from the build script will be on master. So the branch from that PR (#3951) would probably be the best basis for working on the build script.

Regarding the Makefile changes: In the end, going with some Rpi specific code in the Makefile seems simpler to me. I mentioned that we could avoid it by using glad as a loader. But thinking more about it I realized that the additional dependency adds more maintenance burden for the project - so I'm now thinking going the other route is maybe better for this example code.

Btw, I've already included the Raspberry Pi specific build flags in the Makefile here, just commented out: 6fedaa1#diff-4f9259d043a5fb813bd661ae7f5d4c61e24b0e645c2c8fc0afb7b2823aa091fdR64

So after that PR is merged, building for RPI should already be possible, but people will need to edit the Makefile manually. So your build script would make it even easier/nicer to use.

Regarding cross compilation, one problem I think would be how to specify the location of the vc libraries. So the glad approach would have the advantage there that it works better for cross compilation.

CXXFLAGS += `sdl2-config --cflags`
else
ECHO_MESSAGE = "Raspberry Pi"
LIBS += `PKG_CONFIG_PATH=/opt/vc/lib/pkgconfig pkg-config --libs bcm_host brcmegl brcmglesv2` -ldl `sdl2-config --libs`
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not required on a Pi4/3 running with the new OpenGL KMS driver.
Standard pkg-config is just enough.

pkg-config glesv2 --libs

It is required if one really wants the legacy driver.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not know much about the the KMS driver.
Do you have any input on what are differences between the legacy vs. KMS driver?
Does the KMS driver postulate use of X11?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@audetto

This is not required on a Pi4/3 running with the new OpenGL KMS driver.
Standard pkg-config is just enough.

pkg-config glesv2 --libs

It is required if one really wants the legacy driver.

I am doing this right now, and getting 60FPS, but seeing 100% usage of all 4 cores. Not really sure why. My earlier pull request does not work on Rpi4 because I am not sure the legacy is even available.

Copy link

@audetto audetto Mar 26, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hippyau

I am doing this right now

Which Pi? Which KMS? It is a pain, but without this info, one cannot understand.

Anyway, this PR, on a Pi4 using Full KMS, gives * failed to add service - already in use?
IIRC, the Pi4 does not have the legacy driver.

On the other hand, if I do this

	LIBS += -lGL -ldl `sdl2-config --libs`
	CXXFLAGS += `sdl2-config --cflags`

It works. Maximised (not fullscreen), about 10% CPU, 60 FPS.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, was talking about Pi4, no X....

I have just seen the weirdest thing...
running example_sdl_opengl3 gets 100% CPU and ~40 FPS...
running sudo example_sdl_opengl3 gets 60FPS solid and 10% CPU.

@audetto
Copy link

audetto commented Mar 23, 2021

I have been trying to follow the Pi discussion.
"Pi" does not mean the same thing to everybody, there are Legacy GL, new GL, Fullscreen, in X, outside X...

But the "standard" case (I know I am a bit arrogant...) of running inside X11 using the new KMS drivers does not need any special handling. The same build script works on Ubuntu 20.10 Haswell OpenGLES2 as well as it does on a Pi3/4, and nowhere one needs to know that it is a Pi.
The same is true for GLES3, but then it only works on a Pi4.

Could it be that for most people this is all they need to know?

These are my cmake scripts

https://github.com/audetto/AppleWin/blob/master/source/frontends/sdl/CMakeLists.txt#L3

Nowhere I check for a Pi.

@Pesc0
Copy link

Pesc0 commented Mar 23, 2021

Not sure how helpful this can be, but i worked on raspberry support recently. I wrote down everything in the readme: https://github.com/Pesc0/imgui-cmake

@audetto
Copy link

audetto commented Mar 23, 2021

Not sure how helpful this can be, but i worked on raspberry support recently. I wrote down everything in the readme: https://github.com/Pesc0/imgui-cmake

Interesting.
My experience is a bit difference. The Pi has got much much better recently. And I did not need to do anything special to support it. Works out of the box.

On a Pi4, using standard SDL, OpenGLES2 ImGui, inside X11, I get

  • with Full KMS: 60 FPS maximised and 100 FPS running fullscreen
  • with Fake KMS : 40 FPS regardless

OpenGLES3 makes no difference.

Goes without saying that a smaller window achieves higher FPS. These are the worst cases.
Haven't got a Pi3 here, but results are similar to Pi4 Fake KMS.

Do you know what FPS you can achieve? I ask because I've read all sort of results about FPS on a Pi, and there is not a clear reference to benchmark.

@lethal-guitar
Copy link
Contributor

@audetto it's true that nothing special is required when using the KMS drivers. But people might still want to use the legacy drivers when running without X on a Pi 3/Zero or earlier. I don't have concrete numbers at hand right now, but I was definitely getting better performance on a Pi 3 B when using the legacy drivers vs when running inside X. I haven't compared to KMS/DRM without X, though.

This might have changed recently, but I also believe that Raspbian Buster still defaults to the legacy driver when running on Pi 3 or older? So the "out of the box" experience you describe would only work if users enable the KMS driver first, or am I misunderatanding something?

As I mentioned, it's also possible to set things up in a way that no special build configuration is required regardless of which driver is used (Legacy or KMS), by loading the GL ES library at run-time using a loader that supports GL ES, like glad. But that would require adding glad to the ImGui repo if we want to make use of that for the examples.

@Pesc0
Copy link

Pesc0 commented Mar 23, 2021

Do you know what FPS you can achieve? I ask because I've read all sort of results about FPS on a Pi, and there is not a clear reference to benchmark.

Frist things first: what im about to say applies to legacy driver, without X (fullscreen 1080p). I couldn't get KMS to work, but havent tried too hard, since for me kms caused some visual glitches even in the raspbian desktop, like the mouse cursor looking like a big square pixelated with random values.
When i run imgui's demo window i get aroutnd 140 fps iirc. BUT that is VERY dependent on what is being displayed: for example just enlarging the demo window to take up a large portion of the screen makes the fps drop to around 100. Even worse, when i start opening stuff (one example is the colored buttons under layout & scrolling -> scrolling) i can get the fps to drop to 30 or so.

@audetto
Copy link

audetto commented Mar 23, 2021

I guess we all have in mind different "standard" cases, and Pi3 != PiZero != Pi4.

@Pesc0 You did not say which Pi you use. I can get the colored buttons at 88 FPS fullscreen. The new Full KMS on a Pi4 is a incredible improvement on anything that was existing before.

@lethal-guitar You are right and I don't know what the default KMS flag is on a Pi3. I know on a Pi4 it default to fkms.

Would probably be worth adding which use case is being considered when one simply says "On Pi you need this".

@lethal-guitar
Copy link
Contributor

@audetto

Would probably be worth adding which use case is being considered when one simply says "On Pi you need this".

Yeah it's a good point, agreed!

@Pesc0
Copy link

Pesc0 commented Mar 23, 2021

@audetto Yeah sorry about that. Its a Pi3. I'm going to update my repos readme as well to include this "benchmark" information.

@hinxx
Copy link
Author

hinxx commented Mar 23, 2021

Thanks @lethal-guitar ! I took your branch from #3951, changed the Makefile a bit, compiled on Pi3 revB, and got it running without any other changes to the C++ code. Good job!

Makefile changes I made:

		# SOURCES += ../libs/gl3w/GL/gl3w.c
		# CXXFLAGS += -I../libs/gl3w -DIMGUI_IMPL_OPENGL_LOADER_GL3W
		CXXFLAGS += -DIMGUI_IMPL_OPENGL_ES2
		LINUX_GL_LIBS = -L/opt/vc/lib -lbrcmGLESv2

For the record, I installed stock libsdl2-dev (including a whole bunch of X11 related dependencies) on freshly installed buster 2021-01-11-raspios-buster-armhf.img image.

@hinxx
Copy link
Author

hinxx commented Mar 23, 2021

In regards to KMS comments above, let me just say what was on my mind at the time when this PR was initially proposed.

My goal was to use what was available and considered stable (what today can be called legacy BRCM GLES driver). I did not have Pi4 at that point (as it was released on June '19 at a hefty price tag). AFAICT, KMS was something introduced with Pi4.

My goal was (and still is) to make ImGui available on Pi, no matter what hardware release. This is possible even with Pi4 on the table. Legacy GLES driver works on all of them and having ImGui running on all of them is what makes most sense to me. Driver is proven to work, exists for years and has a lot of history, and example code outside SDL, too. Even with the KMS in town, RPi folks have not dumped the legacy one, and it might still be available for years to come.

Going through this thread of messages I can see lots of people did they work as well and today there seems to be many of us that have interest in ImGui running on PiX. This is good. I would like to avoid narrowing the scope of my initial intent in order to cater to a today's hit (Pi4) and trash the rest.

One way of going forward might be putting up a repo/wiki/??? where all of our ideas and different approaches can be collected and presented. This would allow a random internet wanderer to choose an approach of her liking in getting the ImGui integrated into a project at hand. There are so many dimensions to this, like different hardware, different GLES drivers, different loader, cross compiling, native compiling, .. I feel that we can not support all of it in a way that this upstream ImGui repo remains maintainable. If we can keep bulk of code and guidance out of this repo, but still keep a bare minimum here, we all win, including @ocornut that would not have to deal with hardware support / maintenance of a niche platform.

That being said, I probably can not contribute more than I had already in this PR. If you guys feel we can somehow concentrate our knowledge and work for others to benefit from, I will surely try to do my part to the best of my abilities (and time).

@Pesc0
Copy link

Pesc0 commented Mar 24, 2021

Well, i think what i have is already a functional solution. Granted, you have to use cmake, which is not inline with what ImGui does. Anyway i would love to see raspberry support added in the main branch, and i think that it wouldnt be that hard for Omar, since the only imgui code i had to modify was in the main files, thats it. The hard part would be to deal with the modified gl3w, maybe extending support to KMS drivers, or having the code run in an X window. I think a dedicaed wiki section is appropriate.

Edit: To clarify: what i mean is that the main library code is untouched. Getting everything to work on raspberry is quite doable. The hard part would be extending support by adding the above features, which may introduce further modifications. With that said those features are possibly outside of imgui's scope.

@lethal-guitar
Copy link
Contributor

lethal-guitar commented Mar 26, 2021

Once #3951 is merged, both the legacy driver as well as the KMS driver (with or without X) should be supported. Although using KMS without X requires building SDL from source AFAIK, as the packaged version doesn't have the KMSDRM backend apparently.

I've added commented out lines along with a bit of explanation to the Makefile, so it's only a matter of uncommenting the appropriate lines:

e979ddc#diff-4f9259d043a5fb813bd661ae7f5d4c61e24b0e645c2c8fc0afb7b2823aa091fdR63

With that, having a dedicated wiki page or some other easily found documentation, that explains how to edit the Makefile, might already be enough in the end? What do you think, @hinxx @Pesc0 @audetto ?

@hinxx
Copy link
Author

hinxx commented Mar 26, 2021

Once #3951 is merged, both the legacy driver as well as the KMS driver (with or without X) should be supported

That covers a lot of ground!

With that, having a dedicated wiki page or some other easily found documentation, that explains how to edit the Makefile, might already be enough in the end?

For me, comments in the Makefile look enough if all boils down to commenting out two lines, and uncommenting the other two. Essentially you made it so simple that I can not see a need for the script I was signing up for for this PR to come through.

The cross compilation of ImGui also involves SDL crosscompile (since its dev pakage is not in the image by default) and process is outlined on one of the SDL wiki pages (https://github.com/libsdl-org/SDL/blob/main/docs/README-raspberrypi.md). It might be enough for the end user of ImGui to follow that process to cross compile ImGui, too.

@audetto
Copy link

audetto commented Mar 26, 2021

With that, having a dedicated wiki page or some other easily found documentation, that explains how to edit the Makefile, might already be enough in the end? What do you think, @hinxx @Pesc0 @audetto ?

Definitely. I am still puzzled that the Raspberry Foundation does not have a clear page documenting this.

These are my attempts at getting some clarity around it:

https://www.raspberrypi.org/forums/viewtopic.php?f=68&t=304534
https://www.raspberrypi.org/forums/viewtopic.php?f=68&t=303201

And a couple of dummy apps, doing nothing, just to check maximum FPS.

https://github.com/audetto/SDL_Demo
https://github.com/audetto/GLFW-Pi4-Demo

It is very important to report maximum FPS, so people can quickly check if they are getting the right speed or not.

@Pesc0
Copy link

Pesc0 commented Mar 26, 2021

@lethal-guitar I just looked at #3951, looks real good. One thing: does the SDL example run in an X window? or only fullscreen? Because one quirk i found out is that when running outside X the SDL_window resolution must match the monitor resolution, otherwise the mouse position is all distorted. I achieved this simply by setting the fullscreen flag when initializing the window, this way the specified resolution doesn't matter.

Other than that i think a dedicated wiki section would be plenty, since the changes are minimal. Good work!

@lethal-guitar
Copy link
Contributor

@Pesc0 I tested two cases:

  • Fullscreen, without X, legacy driver
  • Windowed, in X Desktop, KMS driver

In both cases, the mouse worked fine as far as I could tell. But there was another PR that was recently merged which addresses an issue with the mouse (#3950), could that be related?

@Pesc0
Copy link

Pesc0 commented Mar 26, 2021

When I was working on it I couldn't narrow down the issue to the imgui backend, instead I found that weird resolution fix. That looks really close though! Unfortunately right now I can't really try it out, but I'm quite sure that #3950 solved the problem.

@hinxx
Copy link
Author

hinxx commented Mar 30, 2021

While on the course of providing the script, I promised to help building the ImGui for RPi, I realized that it is not something we need anymore given all the recent work by the contributors on this PR that went into the ImGui already.
With inclusion of the PR #3951 last week I can natively build ImGui on my RPi. With the small change to the example Makefile (#3951 (comment)) I can also cross compile it. Cross compiling involves a bit more than the Makefile change, but it is probably not ImGui material.

With that being said, I'm not looking into providing any script for compiling ImGui for RPi.

At the same time I feel that this PR can be considered as obsolete and can be closed for that matter.

@hinxx
Copy link
Author

hinxx commented Apr 7, 2021

Closing this PR as the solution was provided elsewhere. Thank you all.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.