[QUOTE=Alfonse Reinheart;1291510]Well, you can’t.
ARB_bindless_texture does not exempt you from the requirement of dynamically uniform expressions. Every texture you use in a shader must resolve to a dynamically uniform value.
There is nothing in OpenGL 4.5 or 4.6 which removes this prohibition. And I can’t think of any interaction between those versions and ARB_bindless_texture that would help in this regard.
gl_drawID works because it is dynamically uniform by fiat: ARB_shader_draw_parameters says that it is dynamically uniform, therefore it is. So you can use that to index into an array of texture handles or whatever. That does not allow you to pass a texture handle per-vertex; gl_drawID only changes when a new draw command is processed.
Now, you can pass texture handles as vertex shader inputs, and pass them to fragment shaders. But the handles within an invocation group must be the same handle. For example, if your VS input is an instance array of handles, and you draw one instance per drawing command, and you use the base instance to select which handle to pass, then it will work. Each VS invocation gets the same handle, so each FS invocation gets the same handle. And because you’re only drawing a single instance at a time, each instance will live within its own invocation group.
So the VS input based on that instance will be dynamically uniform.
You’re asking your question backwards. You should explain how it is you’re trying to render; then we can give you advice on how to make that work.[/QUOTE]
For what its worth, I have bindless textures working and everything is good but it only works with the nvidia extension. This was my first journey into using bindless textures so I made it work with NV_gpu_shader5 as it was the easiest path for my codebase (and seeing it work was also nice).
My problem:
I want to support GPUs outside of nvidia since not all of my users have nvidia cards, so I figure I’d need to do gl_drawID stuff as that should(?) work on hopefully [almost] all modern GPUs that stay up to date. I don’t know if (for example) AMD cards may support NV_gpu_shader5, I don’t have any cards from them so I can’t find out at the moment, but I assume relying on modern cards to have an nvidia extension is a bad idea.
The reason I asked is because this person who has more experience in this area than myself (who I hope is not trying to feed me misinformation) told me that I don’t need to change any of my code around for doing gl_drawID because it can be done “how I’m currently doing it” with OpenGL 4.5+ somehow and without NV_gpu_shader5. This person did not explain how I was to get around the dynamically uniform limitation without the nvidia extension however. I thought it was not possible based on my research… in essence had the same thoughts as you, but since I’m not as experienced I came to get the confirmation that you provided. My goal of my post is to see if I was told false information to avoid me spending more time digging around for something that does not exist.
What I’m trying to do:
In short, I have a single VBO with 1.2 million triangles and a bunch of texture indices. The data rarely changes, but sometimes a few textures may change over the life of the objects. I could probably even eat synchronization on updating the VBO (or SSBO) because maybe 10 of the triangles might change once every few minutes and I have 30ms to make the update (right now bindless texturing + 1.2 mil triangles gets me 1500+ FPS when indexing some SSBO for the handles).
Some side questions that arise:
1) I don’t know how costly it is for each frame to swap between two UBOs (as in use UBO 0, then use UBO 1, then the draw call ends… never needing to use UBO 0 ever again), or if it’s better to just update some uniform value and do a if/switch
on it or update some uniform between draw calls and branch onto a second UBO.
I was considering UBO’s because my texture handles likely will all fit into a UBO and at first pessimistically assumed they wouldn’t and thus chose one SSBO. I also discovered recently that I’d likely not need more than 64kb (very likely never more than 100-110kb), so the question now is if switching to another UBO is more costly.
2) I was worried that possible incoherent access that may occur due to texture changing might be bad for UBO’s, as I read they are best for sequential access. I can make the original batch of unchanging lines all sequential and index into some UBO with no trouble… but I don’t know how much performance that would get me. I’ve read that AMD cards like SSBO’s whereas nvidia likes sequential UBO access.
3) I am not sure of if there’s any significant overhead from a glMultiDrawArraysIndirect() call instead of one single glDrawArrays() call, since I’d have to move to that to exploit gl_drawID.
The answer to both is obviously profile it, however it would be nice if someone could say for example “It’s very likely that doing option X will be ideal” so I have the highest chance of doing it the right way from the beginning.
For what its worth, I have been debating whether I should just go to Vulkan at this point and spend a few weeks playing around and understanding the API, since it seems like the people I’m targeting with OpenGL 4.4+ and bindless textures and supporting extensions may almost all have Vulkan support (as my plan is to move over at some point in the future anyways).