ppy / osu-framework

A game framework written with osu! in mind.
MIT License
1.67k stars 420 forks source link

Use PBOs for texture loading #918

Open peppy opened 7 years ago

peppy commented 7 years ago

Texture loading continues to be a point of contention for large textures (2732x1536) loaded in a single call. The overhead of TexSubImage2D is still significant, especially as we load textures in osu! in a very dynamic way, where we cannot predict which textures are going to be loaded far ahead of time.

OpenGL ES 3.0 introduced pixel buffers and glBufferData / glCopyBufferSubData, which can be used to gain performance improvements in such scenarios, basically allowing asynchronous data transfer without using multiple GL contexts (which we've found to be flaky in the past).

Also worth investigating glMapBuffer and pinning memory, rather than creating a second copy via above commands.

Note that as this is ES3.0, we will need to support fallback to the current behaviour where hardware doesn't support the more efficient methods.

This document makes for good reading on the subject.

Tom94 commented 7 years ago

I don't think PBOs and off-thread population of textures will help in the general case. As you say, "osu! in a very dynamic way, where we cannot predict which textures are going to be loaded far ahead of time". We often can't pre-load textures, and pre-loading is precisely the scenario where PBOs would help.

There may be some opportunity to delay displaying of certain textures until they are uploaded to the GPU (e.g. backgrounds), though. This could be relatively easily added to the draw node machinery, but there would be no easy way to delay the fade in of the drawable in question by the time the upload takes since information doesn't flow back from the draw thread to the update thread currently.