Sampler Array Limit with bindless textures?

I had the idea to just output position, normal, tangent, uv and one material id to the gbuffer and then do all the lighting calculation in a single huge shader that gets all the textures, shadow maps, etc. as bindless textures.

Ignoring the issues in your code for a moment, that is a terrible idea. Outputting positions at all is just a waste of bandwidth (a precious resource in any deferred renderer), since you can easily re-generate them in the deferred pass from just the depth.

Also, it means that, for every lighting pass, you have to sample from your various material property textures (colors, normals, etc) in addition to the gbuffers. Sure, you may not need to do much sampling in your geometry pass, but you’re creating a substantial imbalance here. You’ve made your initial passes faster, only to make your lighting passes at least that much slower if not moreso.

Plus, your material texture accesses will lack coherency. Just because there’s no cost in binding a texture does not mean that you can just fetch willy-nilly across all available textures without performance consequences. If two neighboring fragment shaders have to sample from different textures, then they will then their fetches will not be from the same region of memory. Each execution’s fetch will be entirely separate, so they both pay the penalty of a memory access. If the fetches were adjacent to one another, in the same texture, then there would only need to be one memory fetch, not two (or rather, 2 instead of 4 since you’re probably using mipmapping).

The only advantage of this idea is that you only fetch material data from the visible texels. And you could get that with a simple depth pre-pass.

Overall, this is not likely to help your performance.

The problem is, when I raise the sizes of these arrays in the shader, e.g. point_light_shadow_map_uni[16] instead of point_light_shadow_map_uni[8], the code still seems to compile, but it behaves like it did not (same strange behaviour as when I just write some syntactically wrong stuff).

Wait, if you write syntactically invalid code, then it doesn’t “seem to compiler”. Because it doesn’t compile. So you can’t be getting the same behavior.

Are you correctly checking to see if your shader compiles?

Also, be aware that, while bindless texturing allows you to use any number of textures, that doesn’t mean that uniform storage suddenly became infinite. Each sampler in your shader takes up uniform space. So if you cross that limitation, then your code will fail to compile.

This is what UBOs and SSBOs are for.

Also, I am getting a lot of GL_INVALID_OPERATION errors then, which I have not really been able to track yet, because the error message from OpenGL is simply “GL_INVALID_OPERATION error generated. State(s) are invalid: .” and CodeXL, gDebugger and bugle all crash, because they don’t support ARB_bindless_texture.

Try glIntercept, if it’s available for your platform. It gracefully handles extensions that it doesn’t recognize.