Optimizing uniform buffers

Hello again!

I’m here with another question about the optimization of uniform buffers.

I’m really fine with my actual solution, but there is an idea in my mind that I would like to speak about.

The solution for now is to create a set of VkDeviceMemory, VkBuffer and VkDescriptorBufferInfo per object to render. That’s fine so far.

But if you think about the VkDescriptorBufferInfo it contains:

  1. projectionMatrix
  2. viewMatrix
  3. modelMatrix

The better solution would be maybe to extract the projectionMatrix and the viewMatrix and use it from memory because it makes no sence pushing it into the gpu foreach object.

I don’t know if that is possible. I hope there are some suggestions to work with.

Thanks in advance!

Just use one uniform buffer that stores the projection and view matrix that is only updated if the camera changes and then either use one (additional and separate) uniform buffer for each object (that contains only the model matrix) or do a dynamic uniform buffer that has all the model’s matrices. There are multiple ways of solving this.

One of the options is using push constants for the model matrices.

model matrix is tiny (only 16 floats) and changes each draw call so push constants are perfect for it. Otherwise you can put all model matrices inside a single uniform buffer and use dynamic offsets.

[QUOTE=ratchet freak;42001]One of the options is using push constants for the model matrices.

model matrix is tiny (only 16 floats)[/quote]

16 floats is not “tiny”. That’s 64 bytes in a push-constant storage space that in most implementations only has room for 128.

I’m not saying it’s a bad idea. But it is taking up a lot of a limited resource.

[QUOTE=.black;41993]But if you think about the VkDescriptorBufferInfo it contains:

  1. projectionMatrix
  2. viewMatrix
  3. modelMatrix

The better solution would be maybe to extract the projectionMatrix and the viewMatrix and use it from memory because it makes no sence pushing it into the gpu foreach object.[/QUOTE]

Just to make things more complicated, it often makes sense to concatenate your model, view and projection matrices into just a single matrix. That way you only have to upload one matrix and only have to do one matrix-vector multiply in your vertex shader instead of three.

It’s usually good to push work from the CPU onto the GPU, but in this case a couple of extra matrix multiplies per model on the CPU is a small price to pay for a couple of fewer matrix-vector multiplies on the GPU for every single vertex in the model. Plus you get smaller uniform buffers.

That said, sometimes you need other matrices anyway, like if you’re doing lighting in world-space you might need a modelMatrix anyway. It’s all a great balancing act.