bgfx icon indicating copy to clipboard operation
bgfx copied to clipboard

Out of uniform buffer space on Metal?

Open leeziyu opened this issue 4 years ago • 7 comments

I have program with a huge amount of passes and each pass will upload around 5KB of uniform data. This seems okay when the number of passes are low, but it will cause the program crashes when the number of passes are high. Uploading 5KB of uniforms is probably not the most efficient way to do it. But it seems will eventually run out 8MB uniform buffer per frame on Metal which has been hardcoded in the renderer_mtl.mm.

The error message I got is look like this:

[MTLDebugRenderCommandEncoder setFragmentBuffer:offset:atIndex:]:1687: failed assertion offset(8392192) must be < [buffer length](8388608))

Maybe it will be better to have a function to change the maximum uniform buffer allocation size for Metal?

leeziyu avatar Aug 28 '20 15:08 leeziyu

@attilaz Is there way to resize this buffer in runtime?

bkaradzic avatar Aug 28 '20 20:08 bkaradzic

@bkaradzic AFAIK MTLBuffer cannot be resized. But A: we can allocate a larger buffer when needed and release current one when the current frame is finished processing (using CommandQueueMtl::release) B: Currently we are using 3 (MTL_MAX_FRAMES_IN_FLIGHT) uniform buffers. One for each frame that can be processed at the same time. We can expand this to have more uniform buffers. They could be created on demand when the current one is full and reused when processing is finished.

I guess it should work similarly to what other renderers (d3d12/vk) does.

attilaz avatar Aug 29 '20 10:08 attilaz

Just checked D3D12 and it's 64MiB (BGFX_CONFIG_MAX_DRAW_CALLS*1024 per backbuffer) for all descriptors.

@leeziyu Can you test it with D3D12? Do you have same issue?

bkaradzic avatar Aug 29 '20 16:08 bkaradzic

Thanks for your prompt response. Currently, I don’t have an test environment with D3D12 compatible. So I tested on D3D11 and it doesn’t run out of uniform buffer as quick as Metal. But eventually it still overloads the buffer under some certain cases with huge amount of passes.

leeziyu avatar Aug 30 '20 20:08 leeziyu

D3D11 is different. D3D12, VK, and Metal are similar.

bkaradzic avatar Aug 30 '20 21:08 bkaradzic

I was wondering do you plan to add support to expanding the uniform buffer on demands in the future? Any suggestions for solving this issue if the uniform buffer remains a fixed size? Thanks.

leeziyu avatar Aug 30 '20 22:08 leeziyu

You can change size yourself.

In the future probably there would be some chunked allocator of 1MiB uniform block...

bkaradzic avatar Aug 31 '20 04:08 bkaradzic