Does anyone have/know a good VBO allocator implementation?

Since I’d not like to reinvent the wheel, I am looking for a good VBO allocator implementation.

An utility that keeps track of allocated meshes and have a couple of parameters to customize, such as:

  • the maximum amount of spare meshes before merging them together in the big vbo
  • the minimum amount of allocated space, before reallocating a smaller version and move the remaining meshes from the old to the new one (gpu to gpu)
  • a sort of value to control the fragmentation and specify when the whole space should get defragmented
  • subdivide meshes in case triangles may be not-contiguous

I’m fairly sure that no such tool generally exists. Not one with the specific features you’re looking for. And since memory allocations are controlled by the driver, there’s no way any tool could control memory fragmentation. Fragmentation within a buffer, perhaps, but not between buffers.

Also, I’m not sure what subdividing meshes has to do with a mesh being “not-contiguous”.

Yep, I meant within a buffer

[QUOTE=Alfonse Reinheart;1281675]
Also, I’m not sure what subdividing meshes has to do with a mesh being “not-contiguous”.[/QUOTE]

In case the vbo has not enough contiguous free space and you can’t compact the used space inside, because there is not enough space to move any of the existing meshes within the buffer without overlapping, you may split the new incoming mesh in the free spaces and threat it as multiple meshes

Mesh data is very small, so it’s basically free to store multiple meshes with gaps in buffers. Create a large enough buffer, and if you really need more space, reallocate with glCopyBufferSubData. If you want to split objects, you will get more draw calls and this will be more costly (I don’t know about glMultiDraw* however).

What’s your target GPU (or GPU generation)?

Nowadays for uploading dynamic content, I’d consider using a Streaming VBO approach based on PERSISTENT+COHERENT maps, or UNSYNCHRONIZED maps. Nicely gets rid of most/all of the buffer bind overhead, even without nVidia bindless. Just fill front-to-back based on order of use.

You can use 2 and do GPU-to-GPU copies to coalesce unused regions when you run out of buffer space, but I’d try without it first to make sure you really need this.

I suspect you don’t really want to go general garbage collection on GPU VBOs…

I work on a cad viewer, we may have from few thousands up to a couple of thousands of milions of triangles.

[QUOTE=Dark Photon;1281700]What’s your target GPU (or GPU generation)?

Nowadays for uploading dynamic content, I’d consider using a Streaming VBO approach based on PERSISTENT+COHERENT maps, or UNSYNCHRONIZED maps. Nicely gets rid of most/all of the buffer bind overhead, even without nVidia bindless. Just fill front-to-back based on order of use.

You can use 2 and do GPU-to-GPU copies to coalesce unused regions when you run out of buffer space, but I’d try without it first to make sure you really need this.

I suspect you don’t really want to go general garbage collection on GPU VBOs…[/QUOTE]

GL 4.5, geometry is essentially static unless the user delete/loads some meshes or we have a process streaming a lot of dynamic geometry.

I think I am going to go to tag the geometry if static or dynamic, if static, I’ll load it inside one vbo + 10% for flexibility purpose.

If the occupancy decreases below 70-80 % I’ll allocate a new smaller one and copy gpu2gpu. Similarly, if the amount of spare meshes exceeds 20/30 of the vbo, I am going to allocate a new bigger one (+10%) and move everything there.

Dynamic geometry will be streamed using persisten-coherent with ring buffer.