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

[Draft] - Test Pioneer running on Raspberry Pi 5 #5700

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

fluffyfreak
Copy link
Contributor

@fluffyfreak fluffyfreak commented Dec 29, 2023

I got a Raspberry Pi 5 just before Xmas and whilst doing something completely unrelated to Pioneer discovered that it now supports OpenGL 3.1!
In theory this might also work on RPi 4.

Technically Pioneer requires 3.2 however a quick downgrade to 3.1 and it runs with caveats.

  • 20fps on LOW detail, Mars start,1280x720
  • Some rendering issues, possibly z-buffer related
  • planet/terrain rendering is expensive
  • No crash encountered yet!

Creating this as a DRAFT for visibility and to jog some discussion

Commit description:

  • Downgrade to OpenGL 3.1 and in CMakeLists.txt check for arm CPU

  • test on Raspberry Pi 4

  • investigate graphical issues

  • test gameplay further (Gas Giants, saving & loading, sgm models, etc)

  • is requesting 3.1 safe for other platforms or should this be Pi only?

@impaktor
Copy link
Member

impaktor commented Jan 2, 2024

Isn't there some reason we had 3.2 and not 3.1? Would there not be negative consequences when downgrading?

With 20 FPS is this something we would like to provide to a PI? Can the window resolution be made even smaller (like when playing Doom on a 386, with stamp-sized window)

@fluffyfreak
Copy link
Contributor Author

I honestly do not recall why we required 3.2, need to check the commit logs.
My preference to this would be for the Pi to request 3.1 and everything else asks for 3.2 like now. RPi5 builds would all have to be done from code at the moment, I'm not proposing that we add a regular build.

This PR is just to make it build and run on the RPi5 & 4 so that others, Raspberry Pi has a large developer community, can take a look if they're interested.

As for the 20 fps, that appears to be caused by terrain and City rendering exclusively. Get into space and I'm getting a solid 60 fps with VSync on. I haven't tried with it off. In my opinion this means there's possibly some optimisation to be done for Terrain and City rendering.

The resolution could be reduced, that 20 fps was windowed, and there's other tweaks but I think it will be interesting to do some profiling and optimisation.

@fluffyfreak
Copy link
Contributor Author

The update to OpenGL 3.1 --> 3.2 was in #4974 which is probably required for the offscreen rendertarget stuff but I'm not 100% sure. Either way I don't think we should revert to 3.1 for all platforms, but just for Raspberry Pi to allow the RPi4 & 5 to run.

@Web-eWorks
Copy link
Member

This is excellent news!

...I'll lead with the (perhaps unnecessary) negatives since I'm that kind of person. I don't think we should attempt to officially support the Pi while Pioneer is still using OpenGL. AFAIK, the Vulkan driver for the Pi's GPU hardware has marginally better performance and is significantly more feature-rich than the GL implementation shipping on the Pi.

I'd rather not maintain additional GL-version backends, especially given the overall progress towards modernizing the rendering architecture and design of Pioneer. Additional hardware quirks and considerations have the potential to be very detrimental friction given the current scope of work needed to achieve compatibility with a more "sane" API like Vulkan. I'm aware I'm preaching to the choir on this one. 😉

That being said, I do want to eventually officially support the Pi or a platform like it once the rendering code in Pioneer is more sane and there's less overhead/waste contributing to the low performance.

Depth buffer issues are most likely related to the GL-on-RPI implementation not supporting the pile of reverse-Z floating-point depth buffer tricks we use. IIRC, part of the move to GL 3.2 was better support for MSAA render targets including the float depth buffer.

The performance of pushing 100k+ terrain vertices through a tile-based rasterizer is unsurprising to me. There may be a few options to improve that in the future (e.g. better horizon culling taking the "real feature height" of a GeoPatch into account), though I'm not fully read in on the literature to know if a Z-prepass style renderer would achieve better performance there.

Off the top of my head, city rendering has a potential to be CPU-bound rather than GPU bound. There's a huge inefficiency there in preparing the instanced transform data which unfortunately can't be easily resolved at the moment without some invasive changes to the SceneGraph API. It's not a problem on modern desktop platforms, but on a platform with low memory bandwidth it will be more pronounced.

The main reason for upgrading to GL 3.2 (more specifically GLSL version 1.50) was the ability to sample from an MSAA texture (e.g. the primary render target) for use in post-processing effects. This will primarily show up in the HDR->LDR tonemap+resolve step of the planned rendering pipeline, but is not currently used at this time.

That being said, I'd strongly prefer not to downgrade to GL 3.1 on any platform other than in an experimental build configuration for the Pi. Eventually I'd like to fully bump the GL version we use to 3.3, to have support for separate samplers and some GLSL improvements (explicit attribute location, floatBitsToInt et. al), as that is slightly closer to the programming model of Vulkan.

Overall, I'm very excited to see proof that Pioneer can run on the Pi. However, I have some strong cautions about targeting it "too early" and creating a dragging anchor which would prevent our adoption of a more performant rendering architecture.

@fluffyfreak
Copy link
Contributor Author

fluffyfreak commented Jan 5, 2024

@Web-eWorks I totally agree, this isn't to give the Raspberry Pi a build, it's just to make it easier for that development work to begin.

A Vulkan renderer is the future for all platforms, either a custom one written for Pioneer, or using BGFX/LLGL or some other wrapper/optimising library.

Seeing the legacy OpenGL renderer move to 3.3, or even all the way upto 4.6 which is still almost 7 years old (July 31, 2017!!!), would completely eliminate the Raspberry Pi OpenGL support and that's a natural progression which I'd be fine with.

Like I say, this just allows us to run it, try some optimisations, and figure out some issues whilst the Pi supports 3.1 and we've not updated the renderer yet that it causes a problem.

Also resolving these build problems with the CMake are necessary regardless of the renderer for compiling on Pi. Having it actually run and RENDER was an actual "Holy shit!" moment when it ran 😆

@fluffyfreak
Copy link
Contributor Author

So given everything said above:

  • this isn't to add a Raspberry Pi build
  • necessary for Pi to compile at all
  • just as a prototype for research

What needs to change in this for it to become a PR?

Copy link
Member

@Web-eWorks Web-eWorks left a comment

Choose a reason for hiding this comment

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

what needs to change in this for it to become a PR?

Change the current #ifdefs to an opt-in model set via a CMake option() call of some sort, and provide a CMake build preset setting the appropriate cache variables for the target hardware.

This is mostly concerned with ensuring we build "out of the box" for distros crazy enough to be shipping a desktop/laptop AArch64 build of Pioneer (where GL3.2+ is presumed to be available.)

I forgot to mention it due to lack of sleep in my previous comment, but despite all of the negatives I listed I'm definitely in favor of providing a build config for Raspberry Pi as long as it's understood by the end user to be experimental and potentially subject to breakage. 😄

Comment on lines +55 to +58
if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm" OR CMAKE_SYSTEM_PROCESSOR MATCHES "aarch")
# maybe for performance we can add options here?
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mcpu=cortex-a76 -ffast-math")
else()
Copy link
Member

Choose a reason for hiding this comment

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

Instead of wrapping the USE_SSE42 etc. if-defs, prefer adding a new option(PIONEER_TARGET_RASPBERRY_PI) declaration with the compile flags and adding a preset definition to either CMakePresets.json or a new scripts/CMakeExperimentalPresets.json which sets the appropriate options:

"cacheVariables": {
     "USE_SSE42": false,
     "USE_AVX2": false,
     "PIONEER_TARGET_RASPBERRY_PI": true
}

If added to scripts/CMakeExperimentalPresets.json (preferred), you'll have to manually cp scripts/CMakeExperimentalPresets.json CMakeUserPresets.json before running e.g. cmake --preset linux-arm-raspberry-pi.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My only problem with that is defaulting to USE_SSE42 is only correct for x86/64 and wrong for PPC, Arm, RiscV etc so we should guard it somehow

Copy link
Member

Choose a reason for hiding this comment

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

If there's a way to default that option to off on non-x86 style platforms I'm all for it. Otherwise, it's assumed the options are managed via a CMake preset or explicit build flag set from a distribution build harness of some sort.

...which now that I think about it blindly omits Windows ARM64 builds, but I don't think I've seen anyone yet who's tried to build Pioneer on that platform.

SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
#if (defined(__arm__) || defined(__aarch64__) || defined(__PPC64__) || defined(__riscv))
Copy link
Member

Choose a reason for hiding this comment

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

Instead of testing for platform feature flags here, prefer adding an explicit PIONEER_TARGET_RASPBERRY_PI define in buildopts.h and testing for that define. If we're doing legacy backwards-compatibility hacks like this, it should be opt-in at build time, rather than automatic based on CPU architecture.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I will try to work this out but I detest CMake, it's the worst possible build system and I can barely hack around in it at the best of times 🤷

Copy link
Member

Choose a reason for hiding this comment

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

I'd probably consider Autotools to be worse, but I completely understand where you're coming from.

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.

None yet

3 participants