patriciogonzalezvivo / glslViewer

Console-based GLSL Sandbox for 2D/3D shaders
BSD 3-Clause "New" or "Revised" License
4.67k stars 351 forks source link

system freeze with Intel graphics on Linux #73

Closed doug-moen closed 6 years ago

doug-moen commented 7 years ago

I switched my Ubuntu 16.04 system to Intel graphics (for testing purposes). Slow, complicated shader programs work fine in glslViewer. But short, simple shader programs cause the desktop UI to freeze, requiring a reboot.

For example, here's the shadertoy.com "hello world" program:

void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec2 uv = fragCoord.xy / iResolution.xy; fragColor = vec4(uv,0.5+0.5*sin(iGlobalTime),1.0); }

This program runs fine on the shadertoy.com website, inside Firefox. But give the same program to glslViewer and we need to reboot. The problem, apparently, is that glslViewer runs shader programs at max frame rate, with no throttling. If the shader program is too simple and fast, then BOOM.

doug-moen commented 7 years ago

Adding a 10 millisecond sleep before calling glfwSwapBuffers() makes the bug go away. This just validates my hypothesis, not saying this is the final fix.

doug-moen commented 7 years ago

@patriciogonzalezvivo: My proposal is to implement a 60 FPS framerate limit. Will you accept that?

patriciogonzalezvivo commented 7 years ago

let's do! I think someone else made that call to https://github.com/patriciogonzalezvivo/glslViewer/issues/66.

Thanks!

patriciogonzalezvivo commented 7 years ago

Any thing I can help with this @doug-moen ?

doug-moen commented 6 years ago

The way I fixed this in Curv was to add a 10ms delay just before swapping buffers, in the OpenGL main loop.

Since this is a kludge that slows down all shaders, I never felt right about submitting the change to the glslVIewer project. And I still haven't implemented a better solution.

Now that I know a little bit more about OpenGL, I can speculate a bit. The problem was caused by the GPU driver running the shader at "full speed", showing FPS values of >100 FPS on a 60 FPS display. To fix this, and sync the shader execution to the monitor's frame rate, maybe we should call glfwSwapInterval(1) after setting up the window and before entering the OpenGL main loop. It's not convenient for me to reproduce the original bug and test this right now, so I'm just putting the idea out there.

On 13 August 2017 at 17:52, Patricio Gonzalez Vivo <notifications@github.com

wrote:

Any thing I can help with this @doug-moen https://github.com/doug-moen ?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/patriciogonzalezvivo/glslViewer/issues/73#issuecomment-322069840, or mute the thread https://github.com/notifications/unsubscribe-auth/AFB6obzZr2EjIMi5v8lKc5ImZ24rsNkcks5sX3ATgaJpZM4OG70E .

doug-moen commented 6 years ago

Calling glfwSwapInterval(n) with n > 1 might be an easy way to slow down the frame rate even further, for people who have requested a way to reduce GPU power consumption on a laptop.

I just tested this. On a shader that normally runs at 60 FPS, glfwSwapInterval(2); slows it down to 30 FPS.

On 17 August 2018 at 12:24, doug moen doug@moens.org wrote:

The way I fixed this in Curv was to add a 10ms delay just before swapping buffers, in the OpenGL main loop.

Since this is a kludge that slows down all shaders, I never felt right about submitting the change to the glslVIewer project. And I still haven't implemented a better solution.

Now that I know a little bit more about OpenGL, I can speculate a bit. The problem was caused by the GPU driver running the shader at "full speed", showing FPS values of >100 FPS on a 60 FPS display. To fix this, and sync the shader execution to the monitor's frame rate, maybe we should call glfwSwapInterval(1) after setting up the window and before entering the OpenGL main loop. It's not convenient for me to reproduce the original bug and test this right now, so I'm just putting the idea out there.

On 13 August 2017 at 17:52, Patricio Gonzalez Vivo < notifications@github.com> wrote:

Any thing I can help with this @doug-moen https://github.com/doug-moen ?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/patriciogonzalezvivo/glslViewer/issues/73#issuecomment-322069840, or mute the thread https://github.com/notifications/unsubscribe-auth/AFB6obzZr2EjIMi5v8lKc5ImZ24rsNkcks5sX3ATgaJpZM4OG70E .

patriciogonzalezvivo commented 6 years ago

This is awesome finding! Let's use glfwSwapInterval(1) and limit all speed to 60fps. Do you want to make the honors?

doug-moen commented 6 years ago

Still researching this. I found a comment on a forum thread discussing glfwSwapInterval.

I noticed that on a crappy laptop with integrated Intel graphics I can't enable v-sync. Presumably a driver problem, but I've never bothered to update to see if it fixed the problem.

https://www.opengl.org/discussion_boards/showthread.php/177446-glfwSwapInterval()-and-glfwSwapBuffer()-Questions

Here's a comment relating to the Intel driver on Windows: "I actually have this same issue (running a Intel HD 4400 on a Insperion 3542). I can't get vsync to work unless I have it forced in the drivers menu. If I have it set to "Application Settings" I get screen tearing, even though mednafen has it turned on (video.glvsync 1)."

https://forum.fobby.net/index.php?t=msg&goto=4047&

These posts suggest that calling glfwSwapInterval(1) may not fix the bug.

On 17 August 2018 at 12:42, Patricio Gonzalez Vivo <notifications@github.com

wrote:

This is awesome finding! Let's use glfwSwapInterval(1) and limit all speed to 60fps. Do you want to make the honors?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/patriciogonzalezvivo/glslViewer/issues/73#issuecomment-413923012, or mute the thread https://github.com/notifications/unsubscribe-auth/AFB6oamdR2g-kah532M2hpvBTfuRxtnhks5uRvJpgaJpZM4OG70E .

doug-moen commented 6 years ago

I'm not using the glslViewer project any more (I copied and pasted some of your code into my own app instead, because I need OpenGL object sharing between glslViewer contexts and contexts I create in my own code). I'm too busy to contribute code right now, but I'm sharing information that I think you might find useful.

I now realize that I can't make the glslViewer code work correctly on all GPU drivers, because some bugs are too severe to work around. So my new policy is, I'm willing to provide mitigations to work around driver bugs, as long as the code required is simple (eg, numeric parameters that configure GPU driver behaviour). I haven't looked at libstrangle, but it might be too complicated for the value it delivers, at least for me.

What I'm now considering for Curv is: a numeric parameter to configure glfwSwapInterval, and another parameter, # of milliseconds to sleep before calling glfwSwapBuffers.

The real solution to reducing GPU power consumption is to only render a new frame if something changes. If the model isn't animated, then new frames are only rendered if you are interacting with the model, eg rotating a 3D model with the mouse, or manipulating a slider to change a uniform variable. Maybe that could be made to work in glslVIewer as well? Only render a frame if a uniform variable has changed. If the shader doesn't reference any uniform variables that change every frame, like u_time, then power consumption will go way down.

On 17 August 2018 at 13:12, doug moen doug@moens.org wrote:

Still researching this. I found a comment on a forum thread discussing glfwSwapInterval.

I noticed that on a crappy laptop with integrated Intel graphics I can't enable v-sync. Presumably a driver problem, but I've never bothered to update to see if it fixed the problem. https://www.opengl.org/discussion_boards/showthread. php/177446-glfwSwapInterval()-and-glfwSwapBuffer()-Questions

Here's a comment relating to the Intel driver on Windows: "I actually have this same issue (running a Intel HD 4400 on a Insperion 3542). I can't get vsync to work unless I have it forced in the drivers menu. If I have it set to "Application Settings" I get screen tearing, even though mednafen has it turned on (video.glvsync 1)."

https://forum.fobby.net/index.php?t=msg&goto=4047&

These posts suggest that calling glfwSwapInterval(1) may not fix the bug.

On 17 August 2018 at 12:42, Patricio Gonzalez Vivo < notifications@github.com> wrote:

This is awesome finding! Let's use glfwSwapInterval(1) and limit all speed to 60fps. Do you want to make the honors?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/patriciogonzalezvivo/glslViewer/issues/73#issuecomment-413923012, or mute the thread https://github.com/notifications/unsubscribe-auth/AFB6oamdR2g-kah532M2hpvBTfuRxtnhks5uRvJpgaJpZM4OG70E .

patriciogonzalezvivo commented 6 years ago

Hi @doug-moen ! I'm happy to hear that Curv keeps growing healthy. Congratulations.

Yeah.. I'm going to make some core changes to flag changes better... Hopefully that with glfwSwapInterval(1) will help. But generally I agree with your policy.