bigwheels icon indicating copy to clipboard operation
bigwheels copied to clipboard

Geometry: add buffer_view concept to bigwheels

Open Keenuts opened this issue 2 years ago • 3 comments

GLTF file format has this concept of buffer views. https://kcoley.github.io/glTF/specification/2.0/figures/gltfOverview-2.0.0a.png

(assuming vulkan concepts) The idea is that you get a single memory allocation for all the mesh data (indices, vertices, attributes), and load it as once. Then, you setup your buffers on top to access defined sub-ranges indices and vertex data.

Right now, the Geometry & mesh object is setup with the following API:

GetIndexBuffer()
GetVertexBuffer(uint32_t index);

This means loading a model requires doing the following:

geometry = parse_input_file("my_model.obj");
mesh = create_gpu_object();
staging_buffer = create_staging_buffer();
cpu_to_gpu(geometry.index_buffer(), staging_buffer);
gpu_to_gpu(staging_buffer, mesh.index_buffer());
cpu_to_gpu(geometry.vertex_buffer(0), staging_buffer);
gpu_to_gpu(staging_buffer, mesh.vertex_buffer(0));
cpu_to_gpu(geometry.vertex_buffer(1), staging_buffer);
gpu_to_gpu(staging_buffer, mesh.vertex_buffer(1));

The API might benefit from adding this buffer_view concept to bigwheels. This way, we would have only 1 buffer to copy for such models.

Keenuts avatar Feb 06 '23 15:02 Keenuts

@chaoticbob worked on the mesh stuff historically

vettoreldaniele avatar Feb 06 '23 19:02 vettoreldaniele

I'm gonna take a wild guess and assume that Buffer View in GLTF probably doesn't mean the same thing as Vulkans VkBufferView (this is for texel buffers IIRC).

This change may involve some non-trivial design changes. Currently, all the APIs use "committed" buffer objects - meaning that they're kinda locked into a chunk of memory for a buffer - via VMA and D3D12MA. For buffer_view to work we would need to rework these to use pools or be placed resources. NOTE: VMA already does pooling under the hood to get around Vulkan's 4096 allocation limit.

chaoticbob avatar Apr 14 '23 06:04 chaoticbob

Yes, it's not related to textures.

TL;DR: do like vulkan, buffer != memory. Probably not worth it, as it adds complexity to BigWheels for no clear benefit.

My understanding of BigWheels and mesh management is that a buffer owns the memory allocation it is backed by. And we have no way to say "Buffer X and Y as using the same memory allocation, just at different offsets". Or to create a mesh saying "here are 2 buffers, don't create them yourself"

This was a suggestion to allow decoupling the memory allocation from the buffer (similar to Vulkan when we bind a memory allocation to a buffer). And then allow creating a mesh by providing the buffers. So the "mesh" object becomes just a struct linking some attributes to some buffers, but not handling any allocation.

On Vulkan, I can do the following:

  • create 1 staging buffer w/ 1 memory allocation
  • copy data from disk to buffer
  • create 1 large gpu-only allocation (1 allocation, then bind a buffer to the whole memory)
  • copy staging to gpu-only
  • destroy the staging buffer + memory, and destroy the gpu-only buffer (but keep memory)
  • create multiple buffers, binding to different offsets of this memory allocation (a bit similar to GLTF's "views")

But as you say, this adds complexity. If I don't sync between each copy, it's possible copying 3 smaller buffers is similar in perf as copying 1 large buffer. And allowing a mesh not to own its allocation means we now have to manage them.

Looking at the GLTF sample (using large models), the time is clearly not spent uploading geometry or textures, but decoding PNG files and generating mipmaps. So the cost of decoupling buffers & memory might not be worth it.

Keenuts avatar Apr 15 '23 11:04 Keenuts