glfwSwapBuffers() doesn't work until the next line

I’d like to report a weird and unpredictable phenomenon about glfwSwapBuffer(). Please look at the following image.


You can see that the glfwSwapBuffer command was probably not executed.
But when the next command (Sleep(1), or printf(…)) was executed, the glfwSwapBuffer worked.
My operating system is Win10.
Nvidia gtx 1080Ti or AMD graphic card.
Visual studio 2015 or 2017.
Acer monitor with 144 Hz.
This problem had happened 2 weeks ago and then returned normal automatically, but now it happened again. Is it because glfwSwapBuffers contains bugs?

glfwSwapBuffers is working correctly here, but you are seeing the effect of pausing all threads and the GPU when undertaking parallel pipelined work.

When the breakpoint is hit all threads are paused, including the driver (and thus any GPU work). Even though the command to swapbuffers has been processed by the OpenGL API, this is pipelined and the OpenGL API doesn’t wait for the effect of this to have a result before the swapbuffers function returns (note that there is some extra complexity here with windowed applications due to the Desktop Window Manager, but this can be ignored here).

To see the result you can open the Threads window (Main Menu->Debug->Windows->Threads in Visual Studio) and Pause the thread your breakpoint is on (Main Thread), then Continue so that all other threads continue allowing the driver to handle the pipelined request and the GPU to display it. You can then Pause the debugger again to Thaw that thread.

Doing this is somewhat complicated and may not always work; if you want to look at frame by frame analysis of the GPU output you are better off using a tool like RenderDoc or one from your GPU vendor.

Thanks, now I see the result by clicking Pause, Continue, and Thaw. But why it became like this? I mean, 2 weeks ago my Visual Studio did’t require me to do these clicking operations. Is it because I modified some attributes of VS unintentionally?

By the way, I have another question: the full screen window (created at another monitor under the full screen mode by glfwCreateWindow) flickers when I click the task bar at the bottom of the primary monitor. And this only happened when I use Nvidia card. Is it possible to solve this annoying problem?

What happens when you hit that breakpoint depends on a number of components - how quickly Visual Studio pauses the other threads, the driver code etc. It isn’t a reliable method to use to view the output of a single frame.

Another approach you can use if you do not want to use a GPU debugging tool is to place a fence after the swap and then wait for it. You shouldn’t use this normally as it will cause stalls in the GPU pipeline, but it can be used to frame-by-frame view the output.

glfwSwapBuffers( window );
GLsync syncID = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
glClientWaitSync( syncID, 0, 33000000 );
glDeleteSync( syncID ); // <- place breakpoint here

I’ve not seen this and am not aware of a solution.

Thank God, I found the answer to unlock glfwSwapBuffer(), just TURN OFF the ‘thread optimization’ on the nVidia Control Panel. I hope this may help those who using nVidia’s products. And also thank you for kind replys.

Glad you have found a solution, and thanks for posting it here for future users.