4
votes

I am trying to learn Vulkan (mostly from vulkan-tutorial.com) as I write a mixed graphics/compute application (I need to render a depth buffer and perform some computations over it, no display). I am almost rendering my first (depth) image, and all I need to do is figure out how to pass a single vec4 as the sole parameter to my vertex shader (besides the position attribute).

All places I read says push constants are faster than uniforms, so they seemed the obvious choice for my parameter, but it seems that I need to reset the command buffer at every rendered image in order to change my push constants with vkCmdPushConstants(), while with uniforms, I can keep my command buffer fixed, and simply update the mapped memory region (and flush, if not coherent) before submitting my render task with vkQueueSubmit().

Is rewriting the whole command buffer really faster than a mapped memory write? Or people saying push parameters are faster are assuming the command buffer will be rebuilt at every rendered image, so most of the cost would already be paid anyway?

And finally, can I update the push constant in another command buffer, smaller, submitted previously and sync with the other command buffer with a semaphore? (I guess not, but it is not clear to me for how long a constant pushed is valid, nor for how long a pipeline remains bound, for that matter.) If possible, is this a good approach?

EDIT: Not, that is not possible, just found here that:

Each command buffer manages state independently of other command buffers.

and

When a command buffer begins recording, all state in that command buffer is undefined.

thus my problem remains.

1

1 Answers

4
votes

Is rewriting the whole command buffer really faster than a mapped memory write?

That's the wrong question. You are not taking into account what it actually takes to modify memory such that the GPU can use it.

OK, so you've got this command buffer that reads uniforms from some memory. And you want to use it in two separate frames. But you want to change the memory between frames.

Well, you cannot write to that memory until the first frame has finished reading from it. So you need the CB to set an event after the last time it reads the uniform. And after submitting the CB for that frame, you need to wait on that event on the CPU before you can write your data (let alone submit the next frame's worth of data).

So that's CPU/GPU synchronization. That's not good, for GPU performance or CPU performance. The GPU may run out of work because the CPU had to do such synchronization, and the CPU may just be sitting there doing nothing.

Rebuilding most command buffers is the typical way Vulkan applications work.