Sending and accessing a texture of ints in a shader

Hello All

I am doing some work with shaders where I use an array of ints as a lookup index. At present, I do this using:

    buffer_SegWeb.allocate();
    buffer_SegWeb.bind(GL_TEXTURE_BUFFER);
    buffer_SegWeb.setData(data_SegWeb,GL_DYNAMIC_DRAW);
    tex_SegWeb.allocateAsBufferTexture(buffer_SegWeb,GL_R32F);

Where data_SegWeb is just a vector of ints, assigned at the start…
Then sending to the shader, once at the start:

    shaderMeasures.updateShader.begin();
    shaderMeasures.updateShader.setUniformTexture("tex_SegWeb",tex_SegWeb,i);
    shaderMeasures.updateShader.end();

And then in the shader, to read an item from the vector:

int segX = int(texelFetch(tex_SegWeb, i).x);

Is there any way to optimise or improve on this? i.e. I am only sending ints, whereas this reads floats, which then need to be turned back into ints - can I just send ints? And, are there any other improvements I could do, that would help with speed?

Thanks
S

Some updates, no solutions:

  1. Sending as static_draw vs dynamic_draw has no clear effect on performance.

  2. Allocating the buffer as GL_R16I doesn’t seem to work - the shader runs but the index doesn’t read correctly (although I know all the ints are under the 16 limit). So no savings to be had there? Or am I doing something wrong?

  3. Allocating the buffer as GL_R32I as below does work, but when I call the texelfetch in the shader, I still need to convert to int() or the shader doesn’t run. Which I don’t understand, as shouldn’t it be returning an int value from this format?

Allocation:

tex_SegWeb.allocateAsBufferTexture(buffer_SegWeb,GL_R32I);

TexelFetch call still needs the int conversion:

int segX = int(texelFetch(tex_SegWeb, i));

Can anyone help on this? It seems like it should be a simple thing to me, so I’m probably missing something obvious…

S

huh, a version of this seems to be here: Getting int32 into shader

But when I use:

uniform isamplerBuffer tex_SegWeb;

and then allocate:

tex_SegWeb.allocateAsBufferTexture(buffer_SegWeb,GL_R32I);

etc, my shader goes blank

Aha. I was making a stoopid mistake - my data array was declared as floats.
Right now, this works:

vector<int>data_SegWeb;
//etc .....

buffer_SegWeb.allocate();
buffer_SegWeb.bind(GL_TEXTURE_BUFFER);
buffer_SegWeb.setData(data_SegWeb,GL_STATIC_DRAW);
tex_SegWeb.allocateAsBufferTexture(buffer_SegWeb,GL_R32I);

//etc....

shaderMeasures.updateShader.begin();
shaderMeasures.updateShader.setUniformTexture("tex_SegWeb",tex_SegWeb,i);
shaderMeasures.updateShader.end();
//etc....

//and in shader
uniform isamplerBuffer tex_SegWeb;
//etc.....
int segX = texelFetch(tex_SegWeb, i).x;

This works fine! No speed up but it feels better.

However, one last problem. When I use:

tex_SegWeb.allocateAsBufferTexture(buffer_SegWeb,GL_R16I);

With all else the same, the shader runs but is full of errors and distortion issues. I thought maybe the integers were exceeding the limit, but I’ve checked and the biggest is circa 1500, so that’s not it. Any suggestions as to what this might be caused by? I was hoping accessing 16 bit integers might be a bit faster…

oh. It looks like the openGL shader doesn’t recognise the short format, which is what the GL_R16I setting provides? So reading texelFetch to an int maybe distorts the data or something?

Ho hum, if anyone can advise as to improvements I can make I’d be grateful, otherwise I guess I am not much further forward in terms of speed ups

Have you tried using non-texture type buffers? Like packing them in a vbo and defining your own attribute layout? Appreciate that might not play well with other parts. You would at least have options around data types https://www.khronos.org/opengl/wiki/Vertex_Specification#Component_type

OpenGL performance can be a dark art. I found this presentation had some useful info https://www.gdcvault.com/play/1020791/Approaching-Zero-Driver-Overhead-in

Hurmmmmm this is well over my head type stuff! Guess I’ve done what I can.

Thanks anyway!