I'm studying OpenGL optimization techniques. What I'd like to achieve is to emulate as closely as possible Mantle/DirectX12 programming patterns (aggressive batching, flexible memory handling, complex pipelines) with current OpenGL API. The assumption I'm making here is that hardware behavior is almost the same, with the OpenGL layer being a bit restrictive and not matching accurately the underlying architecture.
I'm considering the optimization technique proposed here:
http://www.openglsuperbible.com/2013/10/16/the-road-to-one-million-draws/
The article suggests allocating a giant buffer and writing a custom allocator to fill it with vertex, instance and texture data, then drawing it with glMultiDrawElementsIndirect. Immutable storage, triple buffering and persistent mapping can also be used for best streaming performance (see http://www.bfilipek.com/2015/01/persistent-mapped-buffers-in-opengl.html).
That seems pretty close to my goal, however I have some doubts:
I read that it's better not to overuse GPU memory on PC because it's also needed by other applications. However, when using this technique with dynamically loaded, continuously changing scenes (e.g. very large tiled worlds) we end up using much more memory than actually needed because we can't predict how much data we'll need to store. Is this a real concern? If yes, how can I address the problem?
View frustum and occlusion culling force you to continuously rewrite instancing and command data. Is this really good? Does decreased CPU load reward time spent copying around memory chunks? Does memory bandwidth significantly impact performance in this case?
Is the "one shader for all materials" method based on subroutines more efficient (higher frame rate with same input data) than modifying the program pipeline? What's the cost of binding a different pipeline or switching a shader in the current pipeline?