We should add a new type Timer to the render_device.hpp file, similar to the existing types there (VertexArray, etc).
It should provides the methods:
void begin() - start a region to be timed (glBeginQuery).
void end() - end a region (glEndQuery).
bool done() - whether the result is available.
int result() - returns the result in nanoseconds; blocks until a result is available.
A new render device abstract method createTimer() should be added. Internally it should use glGenQueries.
Additionally, since to obtain results of the Timer's above we must wait until the draw calls have finished, to make this more practical we could add another class, which uses this one internally, named PipelinedTimer.
This class would provide the methods:
void begin() - start a region to be timed (calls active timer's begin method).
int end() - ends a region (calls active timer's end method), returns result of previous frame, or < 0 if this is the first frame.
Internally, it would keep two Timers, one for the past instance, and one for the current.
Each call to end would swap those two timers, so that we never block waiting for results of this frame.
Instances of this class could be created through a non-abstract method in the base RenderDevice class, createPipelinedTimer. Internally it would just call the existing createTimer.
Problem
Currently the RenderDevice doesn't expose OpenGL queries: https://www.khronos.org/opengl/wiki/Query_Object. We specifically need a way to profile sections of rendering code.
Solution
We should add a new type Timer to the render_device.hpp file, similar to the existing types there (VertexArray, etc). It should provides the methods:
void begin()
- start a region to be timed (glBeginQuery
).void end()
- end a region (glEndQuery
).bool done()
- whether the result is available.int result()
- returns the result in nanoseconds; blocks until a result is available.A new render device abstract method
createTimer()
should be added. Internally it should useglGenQueries
.Additionally, since to obtain results of the Timer's above we must wait until the draw calls have finished, to make this more practical we could add another class, which uses this one internally, named PipelinedTimer.
This class would provide the methods:
void begin()
- start a region to be timed (calls active timer's begin method).int end()
- ends a region (calls active timer's end method), returns result of previous frame, or < 0 if this is the first frame.Internally, it would keep two Timers, one for the past instance, and one for the current. Each call to end would swap those two timers, so that we never block waiting for results of this frame.
Instances of this class could be created through a non-abstract method in the base RenderDevice class,
createPipelinedTimer
. Internally it would just call the existingcreateTimer
.