Dess
Dess

Reputation: 2659

Correctly computing index for offsetting into frame-resource buffers

Lets say, for a rendering setup, that we have a renderer that can be either double or triple buffered, and this buffering can be changed dynamically, at runtime. So, at any time, it's 2 or 3 frames in flight (FIF).

Frame resources, like buffers, are duplicated to match the FIF-count. Buffers are created large enough to hold (frame-data-size * FIF-count), and reading/writing into those buffers are offsetted accordingly.

For the purpose of offsetting into buffers, is it good enough to use a monotonic clycling index which would go like so:

double buffer: 0, 1, 0, 1, 0, 1, ...
triple buffer: 0, 1, 2, 0, 1, 2, ...

Then, if a change is made to the FIF-count a runtime, we first WaitIdle() on the GPU, and then reset this index to 0.

Is this a safe way of offsetting into buffers, such that we don't trample on data still being used by the GPU?

I'm particularly unsure how this may play with a triple-buffer setup with a swapchain mailbox present-mode.

Upvotes: 1

Views: 48

Answers (1)

Nicol Bolas
Nicol Bolas

Reputation: 473447

we first WaitIdle() on the GPU, and then reset this index to 0.

Presumably, you're talking about vkDeviceWaitIdle (which is a function you should almost never use). If so, then as far as non-swapchain assets are concerned, this is safe. vkDeviceWaitIdle will halt the CPU until the GPU device has done all of the work it has been given.

The rules for swapchains don't change just because you waited. You still need to acquire the next image before trying to use it and so forth.

However, waiting doesn't really make sense here. If all you do is just reset the index to 0, that means you didn't reallocate any memory. So if you went from 3 buffers to 2, you still have three buffers worth of storage, and you're only using two of them.

So what did you wait accomplish? You can just keep cycling through your 3 buffers worth of storage even if you only have 2 swapchain images.

The only point in waiting would be if you need to release storage (or allocate more if you're going from 2 to 3 buffers). And even then, the only reason to wait is if it is absolutely imperative to delete your existing memory before allocating new memory.

Upvotes: 1

Related Questions