title: Profiling OpenGL application - when the driver is blocking the CPU side
body: <p>I made an in-game graphical profiler (CPU and GPU) and there is one strange behavior with the Nvidia driver that I'm not sure how to handle.</p>
  
  <p>Here is a screenshot of what a normal case looks like:
  <img src="https://i.stack.imgur.com/XMeXi.png" alt="GPU Profiler, vysnc on">
  What you can see here is 3 consecutive frames, GPU at the top, CPU at the bottom. Both graphs are synchronized.</p>
  
  <p>The "END FRAME" bar only contains the call to <code>SwapBuffers</code>. It can seem weird that it's blocking until the GPU has done all its work, but that's what the driver chooses to do sometimes when vsync is ON and that all the work (CPU and GPU) can fit in 16ms (AMD does the same). My guess is that it does it to minimize inputs lag.</p>
  
  <p>Now my problem is that it does not always do that. Depending on what happens in the frame, the graph sometimes looks like this:
  <img src="https://i.stack.imgur.com/fYQ9f.png" alt="GPU Profiler, vysnc on, V2">
  What actually happens here, is that the first OpenGL call is blocking, instead of the call to <code>SwapBuffers</code>. In this particular case, the blocking call is <code>glBufferData</code>. It's much more visible if I add a dummy code that does just that (create a uniform buffer, load it with random values and destroy it):</p>
  
  <p><img src="https://i.stack.imgur.com/JT78V.png" alt="GPU Profiler, vysnc on, V2 with dummy code"></p>
  
  <p>This is a problem because it means a bar in the graph may get very big for no apparent reason. People seeing that will probably draw an incorrect conclusion about some code being slow.</p>
  
  <p>So my question is, how can I handle this case? I need a way to display meaningful CPU timings at all time.</p>
  
  <p>Adding a dummy code that loads a uniform buffer is not very elegant and may not work for future version of the driver (what if the driver only blocks on drawcalls instead?).</p>
  
  <p>Synchronizing with a <code>glClientWaitSync</code> does not look like a good thing to do either, because if the frame rate drops, the driver will stop blocking to allow the CPU and GPU frames to be run in parallel and I need to detect that to stop calling <code>glClientWaitSync</code> (but I'm not sure how to do that.)</p>
  
  <p>(Suggestions for a better title are welcome.)</p>
  
  <p>Edit: here is what happens without vsync, when the GPU is the bottleneck:
  <img src="https://i.stack.imgur.com/NZLHe.png" alt="GPU Profiler, vysnc off, V2">
  The GPU frame takes longer than the CPU frame so the driver decided to block the CPU during <code>glBufferData</code> until the GPU has caught up.</p>
  
  <p>The conditions are not the same, but the problem is: the CPU timings are "wrong" because the driver make some of the OpenGL function block. That may actually be a simpler example to understand than the one with vsync on.</p>