glGetUniformLocation unexpected result with multiple contexts after NVIDIA driver update

Hi everyone,

I got stuck with a strange situation, that I couldn’t manage to perfectly pin down yet;
I don’t know if this is the most appropriate category, but every piece of advise or hint on how to continue investigating this would be very useful :folded_hands:

I try and list the situation I’m facing:

  1. I create two render contexts, let’s call them A and B, on different surfaces (the system I’m working on could create more than two, but let’s keep the sample simple)
  2. A and B share no elements (i.e. I didn’t use wglShareLists)
  3. I make A the current context (wglMakeCurrent), and compile shader shaderA in order to create a program, for which the numeric handle is X.
  4. glUseProgram(X), then glGetUniformLocation(X, “UniformName”) and I get the location of the uniform (namely, location 13). I can set the uniform’s value, I can proceed with draw calls. So far, so good.
  5. I repeat step 3, but this time I set B as current and compile a different shader shaderB, which program object is referenced by an homonymous value X; since A and B shares nothing, that shouldn’t be an issue.
  6. I repeat step 4 on the newly set context: glUseProgram(X), then glGetUniformLocation(X, “UniformName”) and I get the location of the uniform (namely, location 67), which allows me to set the uniform value as expected (Note: “UniformName” exists both in shaderA and shaderB, so the fact I used the very same dummy string reflects my situation)
  7. Now what I cannot understand: I make A the current context again, I perform glUseProgram(X), but glGetUniformLocation(X, “UniformName”) yields 67, as if I were still in context B. I was expecting 13 again, since it were properly compiled/link during step 3.

Some additional data:

  1. I’m developing on a NVIDIA RTX 2000 Ada Generation GPU
  2. This behavior began after the driver update to version 573.42; with version 553.62 everything seemed to work as expected
  3. When available, I try and force OpenGL 3.3 (core profile) by using wglCreateContextAttribsARB
  4. I tried to describe the test as linear as I could, but the framework I’m working on is quite big: so I double checked that the data retrieved by wglGetCurrentContext and wglGetCurrentDC were the expected ones during steps 3 to 7
  5. On a laptop with Intel UHD graphics I get no issues
  6. On a machine with AMD Radeon Pro W5500 I get no issues
  7. If I omit step 2 by using wglShareLists, everything works: I think that’s due to the fact that shaderA and shaderB cannot both be referenced by the same X handle; however, I would like to avoid this, if possible
  8. I’m working in C#, with an internal mapping of the API calls (this aspect is quite robust, so I don’t think it’s related, but I’m listing all the data I have)
  9. I tried and replicate the very same behavior with a GLFW/C++ program: I created two windows with two separate render contexts, but everything seems to work as expected.

Did any of you experience something like that?
Am I missing some evident piece of information?
At the moment, I’ve got no additional ideas, so every hint would be very welcome!

Thx!

What does that mean? Are the two Xs supposed to have the same value, or are they different values? You can’t force program objects to have any particular value.

Hi Alfonse,

I’m sorry, I tried to be as precise as possible, but I managed not to :sweat_smile:

I used X in my previous message to express that the two programs have the same homonymous handle in the two contexts.
Namely, I used glCreateProgram in the first context, I got as handle 15; then I used it again in the second context and 15 was the return value again.

So, what I expected was (I will use the actual uniform name in the following):

  1. Make context A current → glUseProgram(15) → glGetUniformLocation(15, “MVP”) → yields 15
  2. Make context B current → glUseProgram(15) → glGetUniformLocation(15, “MVP”) → yields 67
  3. Make context A current again → glUseProgram(15) → glGetUniformLocation(15, “MVP”) → yields 15

Instead, what I got was:

  1. Make context A current → glUseProgram(15) → glGetUniformLocation(15, “MVP”) → yields 15
  2. Make context B current → glUseProgram(15) → glGetUniformLocation(15, “MVP”) → yields 67
  3. Make context A current again → glUseProgram(15) → glGetUniformLocation(15, “MVP”) → yields 67 again

I know that I cannot choose any of the values, but that’s ok, I’m not interested in that.
The fact of the matter is I get the wrong uniform location after this ping-pong context switch A→B→A
I was to understand that after a shader is compiled and linked in a given context, its uniform locations would remain the same when this very context is made current again;
even if the locations change (it would not be a great deal for me), I expect them to be reasonable values; instead, I receive a value greater than -1, but that refers to no actual uniform location (glUniformMatrix4fv causes GL_INVALID_OPERATION: I checked for all the other cases that can cause this, the wrong uniform location is the only one I couldn’t sort out).
To me, it smells that I receive the very same uniform location of the program with the same handle value from another context; but I may be wrong: that’s also part of why I’m asking here :slight_smile:

Please, let me know if I managed to better explain myself this time, or if I need to provide more details: thanks! :folded_hands:

Based upon the following, It looks like a driver bug:

Hi GClements,

I managed to finally found this, where they agree with you: I think you’re definitively right and it’s a bug indeed!
In the thread, as a workaround they also suggest to turn off the Thread optimization NVIDIA option: it actually worked on my GPU (and it is a solution that I like more than using wglShareLists :grinning_face_with_smiling_eyes:)

Thank you very much, for giving me a boost that it was a bug, and continue looking for clues!!