# How can I optimize these GLSL bitwise operations?

I need the following part of my vertex shader simplified.

 Sb=Sb|((gl_VertexID&(128+1))<<9);
Sb=Sb|((gl_VertexID&(512+4))<<6);
Sb=Sb|((gl_VertexID&(2048+16))<<3);
Sb=Sb|(gl_VertexID&(8192+64));
Sb=Sb|((gl_VertexID&(256+32768))>>3);
Sb=Sb|((gl_VertexID&(1024+131072))>>6);
Sb=Sb|((gl_VertexID&(4096+524288))>>9);
Sb=Sb|((gl_VertexID&2)<<18);
Sb=Sb|((gl_VertexID&8)<<15);
Sb=Sb|((gl_VertexID&32)<<12);
Sb=Sb|((gl_VertexID&16384)>>12);
Sb=Sb|((gl_VertexID&65536)>>15);
Sb=Sb|((gl_VertexID&262144)>>18);


I have considered using a lookup table in which case it would be at least 2 MB for the best case I can imagine.

What this code needs to do is to reference in to an array. From Sb I use the last 20 bits. the first 10 of them reference the row and the last 10 them the column. I need these to progress as if they were integral numbers counting up from zero, but read backwards.

The output would look like this:

0000000000 0000000000
1000000000 0000000000
0000000000 1000000000
1000000000 1000000000
0100000000 0000000000
1100000000 0000000000
0100000000 1000000000
1100000000 1000000000
0000000000 0100000000


Edit: Speed is key. This needs to happen very fast... ..but should not use up valuable memory.

• Can you give the question some more context. What are you trying to optimize ? what is this shader trying to do? IMO we can't answer the question in its current state. – concept3d Feb 16 '15 at 14:54
• Holy moly... it is not every day you see a vertex shader doing something so bizarre. – Andon M. Coleman Feb 16 '15 at 17:03
• I am using this for procedural rendering. Doing it like this means that the fragment shader of my program gets invoked at a more regular frequency . This is important because my fragment shader contains an atomic counter which means that each consecutive invocation may have to wait for the previous one to complete. Currently the fragment shader is no longer the bottleneck, but now the vertex shader is. – Andreas Feb 16 '15 at 19:09
• Is a 2mb table kept as an integer texture be large at all? It does not sound too big. – EastOfEden Feb 17 '15 at 7:36
• I meant storing it in the uniform buffer may not be possible, but storing it as an integer texture is what I ended up doing. This is still not ideal, because it uses a lot of bandwidth (more than a GigaTexel/s). Currently this is not a problem, but it may become a bottleneck later on. – Andreas Feb 17 '15 at 9:29

You can use two small tables of 16 entries to lookup 4 bits at a time

const int table1[16] = {
0x0,
0x2,
0x0,
0x2,
0x1,
0x3,
0x1,
0x3,
0x0,
...
};

const int table2[16] = {
0x0
0x0
0x2
0x2
0x0
0x0
0x2
0x2
0x1
...
};

x = table1[gl_VertexID & 0xf] << 8;
y = table2[gl_VertexID & 0xf] << 8;
x |= table1[(gl_VertexID >> 4) & 0xf] << 6;
y |= table2[(gl_VertexID >> 4) & 0xf] << 6;
x |= table1[(gl_VertexID >> 8) & 0xf] << 4;
y |= table2[(gl_VertexID >> 8) & 0xf] << 4;
// and so on

Sb = x + (y << 10);


So it turns out that, the solution is to use a TBO for storing the lookup table. The uniform buffer could be faster, but because the uniform buffer can not hold the entire lookup table the added computational cost of the necessary bitwise operations would diminish this advantage. Therefor to my knowledge this would be the fastest solution.