powervr-graphics / Native_SDK

C++ cross-platform 3D graphics SDK. Includes demos & helper code (resource loading etc.) to speed up development of Vulkan, OpenGL ES 2.0 & 3.x applications
https://docs.imgtec.com/sdk-documentation/html/introduction.html
MIT License
702 stars 197 forks source link

[Combine different "virtual buffers" into only one buffer using StructuredBufferView] #55

Closed yuyujunjun closed 4 years ago

yuyujunjun commented 4 years ago

Combine different "virtual buffers" into only one buffer using StructuredBufferView

I want to create a buffer which has many subranges, each range for a different SSBOs or UBOs. StructuredBufferView is very easy to use since it avoids potential mistakes. The function:

getDynamicSliceOffset(uint32_t dynamicSliceIndex)

just return the parameter "dynamicSliceIndex" multiply the size of root's structuredBufferView. I think the "Dynamic Slice" is only useful for things that need buffers with the same layout(very convenient for frame resource), but the efficiency would be improved if used a big buffer instead of separate small buffers. Or there are some other ways for doing such things?

Additional Info

just like this: image

yuyujunjun commented 4 years ago

I found I can use StructredBufferView lists for inquiring subranges' offset and size, which all the things I need for update buffers and bind descriptor sets. I might misunderstand the job of dynamic slices.

And finally, I give each "virtual buffer" a unique name, and stored then in a StructedBufferView's children list one by one. When I need to update the buffer's subrange, I get the specific StructuredBufferView by name, and inquiry its size and offset.

I am not trying yet that but I will try soon, sorry for interrupting

graptis commented 4 years ago

Hi @yuyujunjun , what you want to do is definitely currently possible - all you would need to do is add "more structures", and yes you can give each "virtual buffer" its own name. The "dynamic slices" are usually intended to be used with multiple dynamic copies (as you correctly said - multiple slices for frame resources) that you would (in Vulkan specifically) bind with Dynamic buffers, and they are mostly there because dynamic binding has different Alignment restrictions.

Another very easy to do what you want would be to just create multiple StructuredBufferView, and just point them to different parts of your buffer (pass a pointer to different parts of your buffer to each StructuredBufferView's "pointToMappedMemory" function).

yuyujunjun commented 4 years ago

Appropriate your advice! It's much MUCH easier to implement than what I thought yesterday.

But I might found a little bug there at HelperVk.h, line 551. I think the function

updateBufferUsingStagingBuffer(buffer, offset, size);

which "offset+ buffer->mappedMemory()" is the start address of the destination that I would update, and the parameter "size" is the size of data that needs to be updated. Am I wrong?

At line 551, HelperVk updates the staging buffer in which size equals the parameter "size" I passed in by this function:

// 2. map (if required), then update the memory, then finally unmap (if required)
updateHostVisibleBuffer(stagingBuffer, data, offset, size, true);

And I think the parameter "offset" of this function should be 0, like this:

// 2. map (if required), then update the memory, then finally unmap (if required)
updateHostVisibleBuffer(stagingBuffer, data, 0, size, true);

Finally, it copies the data from staging buffer to device local buffer:

const pvrvk::BufferCopy bufferCopy(0, offset, size);
uploadCmdBuffer->copyBuffer(stagingBuffer, buffer, 1, &bufferCopy);
graptis commented 4 years ago

Hi @yuyujunjun , we have implemented a fix for the bug you found and will be updating it in the following days with our 20.1 release, thanks.

graptis commented 4 years ago

Hi @yuyujunjun , the fix is live. Thanks. If you have another issue or if it does not fix your bug, please reopen or add another issue.