Reputation: 14346
It's generally recommended to reuse command buffers. So let's say I keep a list of command buffers that are ready to be used, so I do:
CmdBuffer cmd_buffer = getCmdBuffer();
/* start recording*/
/* Record 10,000 commands */
CmdBuffer cmd_buffer2 = getCmdBuffer();
/* start recording */
/* Record 10 commands */
These command buffers are executed and then eventually returned to the available list. The first command buffer (having recorded 10,000 commands) takes up more memory in the pool than the second one. When the command buffer is reset it doesn't return the memory to the pool, that memory is still occupied. Then at another point, I need to record 50,000 commands, so I call getCmdBuffer() and the command buffer that's returned is the one that I had previously recorded only 10 commands in. As I'm recording into this command buffer (I issue command 11, 12... etc) the command buffer grows and more memory is occupied/allocated in the pool as required.
The above method results in likely every command buffer, eventually, having enough memory allocated for the highest number of commands that your program consistently records over and over again in your loop. ie., If on average your program records 100,000 commands into a buffer, then eventually every buffer will be big enough to hold that many.
Conceptually I think this is like storing things in vectors. You get one and you start pushing back, it resized according to requirement. The reset command buffer in Vulkan is equivalent to calling clear(), but it still holds onto the memory allocated. If you decide to 'free' the command buffer as opposed to resetting it, then this is similar to clearing the vector so that its size is 0, then calling vector::shrink_to_fit() so that any memory isn't wasted. The problem with this is that then the vector/command buffer has to allocate new memory a whole bunch of times.
Upvotes: 1
Views: 1133
Reputation: 12229
Allocate command buffers with a similar life-time from the same pool, and then call vkResetCommandPool()
to reset all of them and re-pool the memory for future allocations. Pipeline pool allocation using multiple pools to ensure that you can do this with minimal management overhead.
In the grand scheme of graphics memory requirements the command stream is tiny (i.e. 100K commands is probably less than 1MB) so don't get too concerned about a small amount of overallocation.
In reality the driver pool implementation is likely caching memory allocations anyway, because allocations on the critical path for a frame are terrible for performance, so even if you clear the tail of a command buffer or clear a pool the memory is still likely tied up by the pool.
Upvotes: 3