7

Is there any way to prevent the shader compiler from removing a uniform/attribute which it detects as not being used? I occassionally comment out parts of my shader for testing, but this causes problems in the rest of my program because suddenly certain names no longer exist (thus causing lookup errors, and errors when trying to set the value).

edA-qa mort-ora-y
  • 30,295
  • 39
  • 137
  • 267
  • i don't think you can do that. instead you should probably add logic to your calling program, that checks whether the uniform/attribute exists before trying to access them. – umläute Aug 21 '12 at 08:22
  • That's the exact logic causing problems. The rest of the program *needs* that attribute to work, otherwise it'd be littered with a bunch of `if` statements -- which I'm trying to avoid. – edA-qa mort-ora-y Aug 21 '12 at 08:30
  • @edA-qamort-ora-y Well, getting the location of a non-existent uniform should just return -1, and calling `glUniform` with -1 won't do any harm, except maybe generating a GL error, but who cares? – Christian Rau Aug 21 '12 at 09:31

2 Answers2

3

No, but it's not strictly necessary, depending on how you wrote your code.

The glUniform* functions will happily take a uniform location of -1. And if you're using program_pack420 and explicit_attrib_location, you can put your attribute indices, fragment shader outputs, UBO bindings, and texture unit bindings all in the shader. So you don't have to query for active attributes, outputs, uniform blocks, or samplers.

Note that we also have ARB_explicit_uniform_location in GL 4.3. So you can specify them in the shader, and they won't be optimized out.

The rest of the program needs that attribute to work, otherwise it'd be littered with a bunch of if statements -- which I'm trying to avoid.

The only reason you would encounter this is if you were not giving OpenGL attribute indices yourself, either with explicit_attrib_location or with calls glBindAttribLocation pre-linking. That's terrible coding, and you shouldn't have been doing it that way.

Always tell OpenGL what your attribute locations are. You should never be querying them unless you're writing a shader introspection tool.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • It will require fairly high OpenGL version, though. – Bartek Banachewicz Aug 21 '12 at 08:34
  • 1
    @Bartek: No. program_pack420 and explicit_attrib_location are available on *OpenGL 2.1* implementations. They work just fine there. NVIDIA exposes them for 2.1-class hardware that they still support. In short, if you can get reasonably recent drivers for it, then they'll be there. – Nicol Bolas Aug 21 '12 at 08:35
  • But they're officialy part of the standard from 3.3 and 4.1, right? – Bartek Banachewicz Aug 21 '12 at 08:39
  • I'm not sure you can bind the uniforms yourself though, only the attributes can be done this way. – edA-qa mort-ora-y Aug 21 '12 at 08:41
  • @NicolBolas, I have a followup question from your answer: http://stackoverflow.com/questions/12051205/why-should-i-use-glbindattriblocation – edA-qa mort-ora-y Aug 21 '12 at 08:46
  • 1
    @edA-qamort-ora-y Yes, and for uniforms it doesn't matter, since calling `glUniform(-1, ...)` (as `glGetUniformLocation` returns `-1` if not existent) is a no-op. – Christian Rau Aug 21 '12 at 09:34
  • 1
    @BartekBanachewicz And even if `explicit_attrib_location` is not there, you still have `glBindAttribLocation`, which is always supported and does effectively the same (though in app instead of shader). And for uniforms it doesn't matter anyway, as Nicol already explained. – Christian Rau Aug 21 '12 at 09:37
  • 1
    @BartekBanachewicz If an extension (even a core extension) is there for your hardware/driver, you can use it. Just because those features are only included in the core versions for GL 3+ doesn't mean you're entering undefined behaviour or black magic when using them in GL 2 when they're perfectly supported (and you don't use desktop GL on non-nVidia hardware, anyway). – Christian Rau Aug 21 '12 at 09:39
-1

I usually use the -1 returned by glGetUniformLocation to detect error. So I think it's not a good idea to just swallow the -1. And I found a tricky solution to this problem. I add up all the uniform varialble to an identifier, and assign this uniform sum to the output color before a if(condition). For example:

if(condition)
{
    outputColor = uniformSum;
}

And if you let the conditioin always be false such as coding if(val < 0) while val is always positive, then you can avoid the compiler optimize the uniform variable away.

doyoubi
  • 133
  • 1
  • 6