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)
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.
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.
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.
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).