Bindable buffer

I’m not sure how to use this feature.
If I have


bindable vec4 MyValue0;
bindable vec4 MyValue1;
bindable vec4 MyValue2;

Do I get the position of each individualy and make a BO for each?

I’m wondering if I must make an array instead


bindable vec4 MyValue[3];

Just create a buffer with the right size (GetUniformBufferSizeEXT), then attach it to your uniform with UniformBufferEXT. Otherwise it’s a lot like a regular uniform. You can use the buffer API (BufferSubData and friends) or the Uniform* flavors to update stuff.

There’s no way to determine whether a uniform is bindable at runtime with the API (although I think calling GetUniformBufferSize generates an error if it’s not).

Do I get the position of each individualy and make a BO for each?

Yes. If you want to put multiple variables in the same buffer object, use a struct:


struct SomeStruct
{
  vec4 MyValue0;
  vec4 MyValue1;
  vec4 MyValue2;
}

bindable SomeStruct MyValues;

What I’m worried about is if these variables are in sequence in the memory or not.
What if I want to have 2 pairs of BO for 1 shader? 1 BO where values are not updated as often and another BO that is very dynamic. Or must I have a BO for the entire shader.

struct?

What if I want to have 2 pairs of BO for 1 shader? 1 BO where values are not updated as often and another BO that is very dynamic. Or must I have a BO for the entire shader.

Each bindable uniform variable must have its own buffer object. Note that “glUniformBufferEXT” does not take an offset into a buffer object. So it is assumed to be the entire buffer object.

So to make the best use of bindable uniforms, you must use structs as I showed.

BTW, as I read over the bindable_uniform extension, it’s really clear that this is a terrible extension. It is poorly specified and doesn’t even go far enough to actually tell you how structs (for example) are laid out in memory, which makes using the extension in any real manner basically useless.

What about

intptr GetUniformOffsetEXT(uint program, int location)

It should be pssible to call

GLint location=glGetUniformLocation(program, "SomeStruct.MyValue1");
GLintptr offset=glGetUniformOffsetEXT(program, location);

The problems are:
a) glGetUniformLocation only returns locations for uniforms that are actually used by the program. In order to circumvent this, I have to write a pseudo-shader which is accessing all struct members, just to force the compiler to tell me their offsets in the buffer.
b) the whole approach somehow implies that the result is specific to “program”, which is clearly not.

That’s a good reason for a default packing rule to be spec’d. You need to know something about the buffers you’re binding, anyway, as they’re not really discoverable in their entirety through shader reflection, or what there is of it. If you have a packing rule and a buffer size, that’s all you really need to know.

For now on NV hw, if you pack vec4s, it’s all gravy.

the whole approach somehow implies that the result is specific to “program”, which is clearly not.

No. The poorly-written spec does state that the layout for structs/arrays of bindable uniforms is the same for all programs that use that uniform specified in the same way. All you need is one program to get it started.

I’m not sure WTF is going on.

VS


#version 110

#extension GL_EXT_bindable_uniform: enable

bindable uniform mat4 ProjectionModelviewMatrix;
bindable uniform vec4 TexMatrix0_a;
bindable uniform vec4 TexMatrix0_b;





void main()
{
	gl_Position = ProjectionModelviewMatrix * gl_Vertex;
	gl_TexCoord[0].x = dot(TexMatrix0_a, gl_MultiTexCoord0);
	gl_TexCoord[0].y = dot(TexMatrix0_b, gl_MultiTexCoord0);
}

FS


#version 110


#extension GL_EXT_bindable_uniform: enable



bindable uniform vec4 MaterialDiffuse0;


void main()
{
	//TEMP
	vec4 ColorSum;


	ColorSum = MaterialDiffuse0;

	if(MaterialDiffuse0.z==1.0)
		gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
	else
		gl_FragColor = clamp(ColorSum, 0.0, 1.0);
}

glGetUniformLocation(“ProjectionModelviewMatrix”) returns 1
glGetUniformLocation(“MaterialDiffuse0”) returns 0
glGetUniformLocation(“TexMatrix0_a”) returns -1
glGetUniformLocation(“TexMatrix0_b”) returns -1
I guess these last 2 got optimized out.

If I call glGetUniformOffsetEXT(“MaterialDiffuse0”) it returns 0
glGetUniformOffsetEXT(“ProjectionModelviewMatrix”) it returns -1
Yes, I use the uniform location of course when I call glGetUniformOffsetEXT.

Try a #pragma optimize(off) and see what happens.

I changed it so that they get actually used so that is fine.
I’m still not sure how to use this extension. Can’t find a decent example.

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