GL_ARB_explicit_uniform_location inactive errors

Hello,

Trying to play with this new extension to easily replace some uniform buffers but I got various errors. Any help would be appreciated.

Is it legal to define several continous uniform locations and then set their value with glUniform4fv (as an array). Or an array must be defined.


#version 330 core
#extension GL_ARB_explicit_uniform_location : require

layout(location = 2) vec4 FogColor_AREF;
layout(location = 3) vec4 HalfTexel;
layout(location = 4) vec4 WH;
layout(location = 5) vec4 MinMax;
layout(location = 6) vec4 MinF_TA;
layout(location = 7) vec4 TC_OffsetHack;


glUniform4fv(2, 6, (GLfloat*)data);

On my AMD GPU (linux 13-8 beta), I got some strange errors. The spec seems to imply that it is allowed to call Uniform function on inactive uniform. Am I correct?

Type:Error ID:129 Severity:High Message:glUniform4fv parameter <location> has specified an invalid value ‘2’: not the location of an active uniform in the default uniform block (GL_INVALID_OPERATION)

  1. What happens if Uniform* is called with an explicitly defined
    uniform location, but that uniform is deemed inactive by the
    linker?

    RESOLVED: The call is ignored for inactive uniform variables and
    no error is generated. Uniforms without an explicit location that
    are determined to be inactive return -1 for the the location when
    GetUniformLocation is queried. Calling Uniform* with a location
    of -1 is also ignored. That behavior isn’t changed.

No, you may not attempt to set an array of uniforms on a uniform of non-array type, even if they just so happen to be sequentially allocated. Array setting is for arrays of uniforms. If you want to do quick-and-dirty block copies into uniform data, that’s what uniform buffers are for.

The spec seems to imply that it is allowed to call Uniform function on inactive uniform.

That’s non-normative text. And there’s nothing in the text (or in GL 4.4 for that matter) that actually requires the behavior described in the issue. I’m guessing it’s an oversight of some kind.

Then again, you should get an error for trying to set an array of more than 1 element for a non-array uniform. So if it lets you use glUniform4f just fine, then it’s probably just getting its wires crossed as to the reason for the error.

Hum, I find my issue. I forget to declare the variable uniform…:doh: Yep I got some errors now.

Actually I already use Uniform Buffer but I wanted to benchmark both solution.

Did an update of my code to use pure uniform array.


layout(location = 2) uniform vec4 uni_ps[6];

vec4 FogColor_AREF = uni_ps[0];
vec4 HalfTexel     = uni_ps[1];
vec4 WH            = uni_ps[2];
vec4 MinMax        = uni_ps[3];
vec4 MinF_TA       = uni_ps[4];
vec4 TC_OffsetHack = uni_ps[5];

layout(location = 8) uniform uvec4 MskFix;

Well it still yield at me (note: vertex shader uniforms are fine now) because it optmized aways the uniform.

Type:Error ID:129 Severity:High Message:glUniform4fv parameter <location> has specified an invalid value ‘2’: not the location of an active uniform in the default uniform block (GL_INVALID_OPERATION)

Trying to read the spec, I only find this part which seems to imply that the location is reserved. The extension feels useless if you need to query the location to find that the location is used or not.

A successful link will also generate a location for each active uniform in
the default uniform block which doesn’t already have an explicit location defined
in the shader. The generated locations will never take the location of a uniform
with an explicit location defined in the shader, even if that uniform is determined
to be inactive.

Or… maybe it’s a bug in AMD’s beta Linux drivers?

Also, you can’t initialize a global variable with a uniform like that. At least, I’m pretty sure you can’t.

I only find this part which seems to imply that the location is reserved.

It neither says nor implies anything of the kind.

Also, you can’t initialize a global variable with a uniform like that. At least, I’m pretty sure you can’t.

Thanks for the tip. In this cas would be possible to replace the array with a struct?

Replace it for what purpose? You still can’t upload to the entire thing in one function call.

You have to pick one: the API-side uploading convenience of arrays, or the GLSL-side convenience of having actual names for values. You can’t have them both unless you use a uniform buffer.

Hum that annoying. Guess I have no choice. Thanks for your time.

You could either #define your variables or have little wrapper functions that return the respective element from the uniform buffer.

You mean somethings like that:


#define my_nice_name uni_array[0]

The wrapper function could be a good idea but I want to keep my code as closest possible of HLSL shader.

Anyway, uniform array seems to be a bit faster in my case. But my current benchmark is likely to be the worst case for UBO, I update it nearly every draw call (~3000 by frame). Besides I’m still using glBufferSubData for data upload. It might be a better idea to accelerate UBO with map/unmap (potentially with ARB_buffer_storage/persistent).

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.