Two-phases render

27 views
Skip to first unread message

iarwain

unread,
Apr 19, 2013, 9:18:11 PM4/19/13
to orx...@googlegroups.com
Hi all,

So lately I wanted to explore a more modern approach for the rendering phase which is often used in big commercial games.

Here's orx's current frame order:

- Update inputs
- Update game logic
- Update physics
- Render + Swap buffers

Which means that the render commands are sent to the GPU toward the end of the frame. As you see, this game loop is very sequential and doesn't allow much parallelism.

Consider the case when VSync is enabled (in FullScreen, in windowed, there's no real VSync, it's only faked by the driver). There are now two case scenarios after sending the buffer swap request:

- Either we continue on our merry way on the CPU without waiting for the GPU and the actual GPU might not even start this frame. All we know if that there won't be any tearing, but the GPU is free to take more time to process the commands we pushed. When the workload is pretty light, the GPU might stack a few frames before actually displaying any. This acts as a buffer in case the CPU will take more time to handle a frame later on, the GPU will already have some data ready for to display for the next frame. If there are too many stacked frame, the GPU might even skip some of those, which results in micro-stuttering from time to time. The stacking also result in perceived input lag, like an object following the mouse (like a custom cursor) feeling sluggish when you move it quickly. These are common issues with current hardware and can be seen in many games when VSync is on. There's an alternative to that, which is the second case scenario below.

- We ask the CPU to explicitly wait for the GPU to be done displaying the frame before continuing. This will force the GPU to work now and display the new frame as soon as possible. In the end, you won't see any input lag or micro-stuttering which leads to a much smoother experience. The issue in this case, however, is that it leaves only a very short amount of time to the GPU to do its work before the next VSync happens: we basically have the CPU working first by itself, then roles are switched and the GPU will work while the CPU is waiting after it. This is sub-optimal to say the least.

The way modern game engine works is by introducing a force 1-frame delay for the actual GPU tasks. Here's the corresponding game loop:

- Render previous frame (ie. send all the GPU commands)
- Update inputs
- Update game logic
- Update physics
- Swap buffers

In this case we'll always have 1 frame of delay (ie. 16.6ms @ 60Hz and 33.3ms @ 30Hz) in addition to the delay due to various pieces of hardware (cf. http://timothylottes.blogspot.com/2013/04/repost-understand-speed-of-light-of.html). But it'll also give a much bigger chunk of time for the GPU to render the previous frame while still being on 1:1 sync between CPU & GPU at the end of the frame (ie. no lag nor stuttering).


At the moment the code is only set up for the CPU/GPU sync for computers but I'll modify iOS tonight by adding a glFinish() call after the buffer swap request (not sure how to do Android as it's not orx that handles the swap there). I'll probably make this sync optional using a config property at some point.

If you're curious to try this branch, please do and let me know of what you can observe on your machines: a good comparison is trying both versions in *fullscreen + vsync only*.

If you have any comments/questions, please let me know!

Cheers,

Rom

Message has been deleted

iarwain

unread,
Apr 26, 2013, 5:56:21 AM4/26/13
to orx...@googlegroups.com
I also did some changes in this branch, after using gDebugger (http://www.gremedy.com/), to remove any duplicate calls to gl* functions that wouldn't change the internal OpenGL states (mainly calls to glScissor and glClearColor).
I'll make the same modifications in the iOS plugin soon and will let Lydesik do its magic in the Android one. :)

I'm pretty happy with the results of this branch so far and will probably merge it back to trunk soon-ish unless someone finds a blocking issue with it.

Cheers,

Rom
Reply all
Reply to author
Forward
0 new messages