News:

Simutrans Sites
Know our official sites. Find tools and resources for Simutrans.

Runtime-switchable grapics renderer

Started by ceeac, May 01, 2025, 02:16:28 PM

Previous topic - Next topic

0 Members and 3 Guests are viewing this topic.

ceeac

This WIP patch paves the way for the graphics backend (i.e. simgraphXX) to be switchable at runtime, without requiring a re-compile. This makes it possible, for example, to add an OpenGL renderer and use both the software and OpenGL renderer side-by-side (which is the primary motivation for this patch).
I also took the opportunity to clean up the names of the display_* routines a bit since every call to a display_* function needs to be touched anyway, but I am open to suggestions on this matter. :)

The patch may cause the renderer to be slightly slower because of the required indirection for every draw call, but I have not done any performance tests yet. However, the game should look exactly the same as before the patch.

Yona-TYT

Wow, this is impressive, I wonder if this matches Hajo's work of porting Simutrans to OpenGL.

prissi

I think a cleaning up of the display functions is a good think.

But, the only thing the SDL/GDI/OpenGL backend changes is the mapping of the bands onto the screen (apart from the 0 color dummy of course). But that rendering is not part of simgraphicXX.cc. I guess that I missed something here. What does this prepare for?

And, for a single threaded server, I expect a large penalty, as all the empty function calls to simgraph0.cc are optimised (for a normal compiler). Also, for normal display, the clipping rectangles are no longer pointed to fixed places in memory and hence the compiler must reload them each time so the directional clipping may become even slower than it is now.

It feel like this needs some serious benchmarking first, both with single threaded posix and the other ones.

But I could not compile this even on MSVC 2022, as it uses C++ 2020 features. So maybe it needs to become a little more portable as this might not be the common standard yet on less popular platforms. The standard for MSVC is C++14.

Forcing C++20 and SDL2 backend, I get the following errors.
Nicht aufgelöstes externes Symbol ""struct simgraph_t const * const g_simgraph" (?g_simgraph@@3PEBUsimgraph_t@@EB)".
Nicht aufgelöstes externes Symbol ""struct simgraph_t const * __cdecl simgraph_select(enum simgraph_type_t)" (?simgraph_select@@YAPEBUsimgraph_t@@W4simgraph_type_t@@@Z)".

And it does not built with the GDI backend either, there are unconvertable calls for display_flush_buffer().

ceeac

Quote from: prissi on May 02, 2025, 08:19:28 AMBut, the only thing the SDL/GDI/OpenGL backend changes is the mapping of the bands onto the screen (apart from the 0 color dummy of course). But that rendering is not part of simgraphicXX.cc. I guess that I missed something here. What does this prepare for?

The intention is to eventually add a simgraphgl.h/.cc to do the rendering in hardware (GPU) instead of software (simgraph16). For players it is obviously much more convenient be able to switch between simgraph16 and simgraphgl without having to re-compile. The selection logic is in simmain, which calls simgraph_select before simgraph_init to select the renderer (Currently there is only simgraph16, of course).

Quote from: prissi on May 02, 2025, 08:19:28 AMAnd, for a single threaded server, I expect a large penalty,
With r11708, which removes the calls to color_idx_to_rgb from the city info logic, I believe the only performance critical calls to simgraph functions are from inside intr_refresh_display. So the only code that might be affected is the GUI rendering code (win_display_flush). But even this can be #ifdef'd out I think, unless there are calls in there that must be called even on a server?

I have tried to fix the compile errors + Makefile + MSVC project, but there might be still some errors left since everything works fine for me using CMake + GCC/Clang + C++14.

prissi

Sorry, I am this week very busy with writing a big project proposal. I will try to build it and test it later this week.

prissi

Still does not compile, it chokes on the definition of

gsimgraph_t g_simgraph16 = {
.type                      = SIMGRAPH_TYPE_SOFTWARE,
...

"E0029: expected an expression"

The leading dots gives this error.

ceeac

(This is a continuation of this now-locked topic. Feel free to merge the two topics.)

So, I finally did some performance measurements and for simgraph16 on a fully zoomed out yoshi test map, karte_t::display is around 2% slower than trunk due to indirect function call overhead. This is about what I expected. Obviously this a rather extreme case with more than 300k calls to display functions per frame. The numbers for pak128/pak192 will be lower simply because the tile size is bigger and therefore there are less objects to display per frame.

The headless server is less affected by the performance regression because the main view is never drawn (main_view_t::display is empty for COLOUR_DEPTH=0). The only relevant calls to display functions are inside win display_flush, which I believe can also be disabled for COLOUR_DEPTH=0.

Quote from: prissiStill does not compile,

Should be fixed now; C++ does not seem to support designated initializers until C++20.

prissi

Since this touches a lot of routines, and a release is overdue (as soon as the multipak tutorial is approved), I would wait until after the release.