What causes GLSL recompilation of vertex shader based on state?
Asked Answered
D

2

5

I am using the ARB_debug_output extension. The driver gives me this warning:

Program/shader state performance warning: Vertex shader in program 16 is being recompiled based on GL state.

So, I tried setting various GL state before I compile my shader, including:

  • GL_BLEND
  • GL_CULL_FACE
  • GL_DEPTH_TEST
  • polygon-offset
  • blendfunc

...but it still recompiles upon first draw.

What are the typical pieces of state that could cause the driver to recompile a vertex shader?

Desegregate answered 12/8, 2019 at 2:1 Comment(4)
"But it still recompiles upon first draw." What do you mean "upon first draw"? Is it the first time you're rendering with that shader at all? "I tried setting various GL state before I compile my shader" No shader compiler/linker is going to assume that the OpenGL state at the time of compilation/linking accurately reflects the OpenGL state that will be present at the time of use. So it really doesn't matter.Misbeliever
Yes, at first render. I want to avoid a re-compile at that time. And I expect the driver to not recompile if state at compile-time is the same as the state at render-time.Desegregate
"I expect the driver to not recompile if state at compile-time is the same as the state at render-time." You shouldn't expect that. Driver writers certainly don't expect it, so neither should you.Misbeliever
@NicolBolas Those same 'driver writers' also put in the performance warning, though. If the re-compile could not be avoided, the warning makes no sense.Desegregate
E
3

I also got this message and found the solution in a Reddit post. The problem was as follows:

I am using Direct State Access (DSA) to setup all my VBOs and VAOs. So during the setup process, I never bind anything to the state machine.

My vertex shader contains some inputs like layout (location=0) in vec3 VertexPosition. But the corresponding attribute wasn't enabled yet in the state machine. So the driver compiles a program version for a state where no Attribute is enabled. Now, if I bind my first VAO for drawing, all the necessary attributes get enabled and the driver detects a mismatch between the state of my first draw call and the state when I compiled the shader. So he has to recompile it.

In this case, the warning can be fixed by binding a correctly setup VAO before compiling the program (see remarks below). Alternatively, you can just set the state directly by enabling all required attributes with glEnableVertexAttribArray, as suggested in the linked Reddit post.

Finally, you can decide to ignore or filter the message, if it occurs only once after the first draw call. But I would advise against it, since the warning might also be caused by other problems in your code that can cause serious problems. So fixing it should be the way to go.

Remarks:

I am not entirely sure, when the program (not the shaders) is actually compiled (not linked). For me it was sufficient to configure the state machine correctly just before I first called glUseProgram. I don't know if the Spec says something about it or if it is left to the driver to decide it. I had a look at the documentation of glUseProgram, but it only talks about "installing" the program to current state. Maybe someone else can clarify this.

Enterotomy answered 5/4, 2024 at 8:1 Comment(0)
S
3

I've run across this problem recently. It occurred that unbinding Vertex Array Objects caused this warning to appear. After deleting the lines with glBindVertexArray(0) the warning message disappeared.

Sestina answered 18/5, 2021 at 12:34 Comment(1)
Why does this fix the error? I encountered it after refactoring my shader code according to the Cherno's tutorials. The error is fired from the debug message callback system from OpenGL 4.3. Furthermore, the error also disappears if you call glUseProgram(0) before drawing so you don't need to delete the line with glBindVertexArray(0).Ephesian
E
3

I also got this message and found the solution in a Reddit post. The problem was as follows:

I am using Direct State Access (DSA) to setup all my VBOs and VAOs. So during the setup process, I never bind anything to the state machine.

My vertex shader contains some inputs like layout (location=0) in vec3 VertexPosition. But the corresponding attribute wasn't enabled yet in the state machine. So the driver compiles a program version for a state where no Attribute is enabled. Now, if I bind my first VAO for drawing, all the necessary attributes get enabled and the driver detects a mismatch between the state of my first draw call and the state when I compiled the shader. So he has to recompile it.

In this case, the warning can be fixed by binding a correctly setup VAO before compiling the program (see remarks below). Alternatively, you can just set the state directly by enabling all required attributes with glEnableVertexAttribArray, as suggested in the linked Reddit post.

Finally, you can decide to ignore or filter the message, if it occurs only once after the first draw call. But I would advise against it, since the warning might also be caused by other problems in your code that can cause serious problems. So fixing it should be the way to go.

Remarks:

I am not entirely sure, when the program (not the shaders) is actually compiled (not linked). For me it was sufficient to configure the state machine correctly just before I first called glUseProgram. I don't know if the Spec says something about it or if it is left to the driver to decide it. I had a look at the documentation of glUseProgram, but it only talks about "installing" the program to current state. Maybe someone else can clarify this.

Enterotomy answered 5/4, 2024 at 8:1 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.