Staging Buffer with Device Local memory issue

Hi

I have an issue with a specific scenario using a single staging buffer (host visible) to service multiple device local buffers to that multiple inflight frames can be queued.

I have a single staging buffer that I write to once then use the contents to copy to device local memory.

In frame one I fill the staging buffer up (using vkMapMemory) and copy to device local (using vkCmdCopyBuffer) and it works, renderdoc can see the data populated in the buffers defined in the Pipeline window - vertex input section.

In frame two I skip filling the staging buffer and go straight to copying the contents to a new device local location (so that both buffers can be queued on the GPU together). In this case renderdoc doesn’t see the data in the pipeline window. It is just full of zeros. If I change frame 2 so that it fills up the staging buffer again render doc sees the device local memory correctly again.

Question is what happens to the staging buffer after a copy to device local that makes it not visible in render doc when done a second time. I check the staging and device local buffer by doing a copy back to local memory afterward running the commands and they seem to look ok in both cases which is wierd.

When I cycle back to populating the frame ones buffer in a later frame, frame ones buffer updates correctly again.

To foresee certain questions, I do change the vertex buffer IDs and offsets passed to vkCmdBindVertexBuffer and vkCmdBindaindexBuffer. And the do match the IDs passed to the copy command for each frame. The reason I am doing this is not all the vertex data changes each frame, one buffer that does change each frame is correctly updated while the others that don’t change aren’t.

Tough to know with code-as-prose. It always shows author’s intention, but almost never his bugs.

If you are stuck, make a minimal example. 90 % it reveals the problem to you in the process, in 10 % you then have something to show others.

The obvious questions are did you sync it properly, and are you using validation layers.

I realise it’s hard to debug with out code, it would take me too long to provide a simple example. I’ll try and simplify the question as it can be just a general question.

First to answer some of your questions, I do use validation layers and everything is sync’d up with semaphores.

It was working in a previous iteration where I was holding a local buffer copy of everything and then copying to staging then to device local. In my new case I am using the staging buffer as my “local” copy and updating that directly.

  1. does copying a local buffer to a staging buffer reset anything in the staging buffer?

  2. does copying a staging buffer to a device local buffer somehow link it to the device local buffer?

I have a bug somewhere where I have done something wrong, I’m hoping to understand the process a bit better to try and narrow down the places to look.

nope

and nope

Only thing that happens is the copy is a read access that needs to be synchronized (must be ensured there is no writer at the same time). And it must be in a appropriate layout for the jorb (BTW layout change is a write access).