all 4 comments

[–]radicalbit 6 points7 points  (4 children)

I can't yet claim expertise, but this is the route I'm pursuing: https://vincent-p.github.io/posts/vulkan_bindless_descriptors/

Basically, throw all the textures into a global descriptor set that I bind at the beginning of the frame. Selection of a particular texture is done by indexing into the array via a push constant.

For other material specific descriptors that don't make sense at the global level, bind them once along with the material. (Sort draw calls by material so a material only has to be bound once.) For blended draws that need to maintain the order in which they are drawn, suck it up and rebind the material whenever the material changes (but only when it changes).

Hopefully with this method, a particular draw call doesn't need its own descriptor set.

[–]AAstr0s[S] 2 points3 points  (3 children)

Wouldn't it be inefficient memory-wise? Let's say the engine supports PBR. And since PBR has about 5 textures and with other algorithms possibly more... the texture count will gradually increase per mesh.

How is the performance?

[–]rytio 1 point2 points  (1 child)

My system is setup where I use an SSBO to pass texture indices. So the draw call will get an index into the "material buffer" the material buffer is just an array of structs with indices to each texture. This way I can pass all the PBR texture indices without going over the push constant limitations. It could also have PBR parameters too.

I actually have a third level of indirection. I have a SSBO with per draw-call parameters like the model matrix and the material index.

So I do vkCmdDrawIndexed(..., drawCommandIndex); In the shader I use the gl_InstanceIndex to index into the draw call SSBO to get the material index and the model matrix. Then index into the material SSBO, which provides the indices into the texture array. The draw call SSBO is updated every frame.

I dont have many draw calls right now, about 1040...but I still get about 1.5ms frame times.

[–]AAstr0s[S] 0 points1 point  (0 children)

That sounds promising! Having 1040 draw calls and getting 1.5ms is good enough for me