Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vulkan: Using buffer aliasing to implement a defragmentation scheme

Tags:

vulkan

Say I have one VkBuffer bound to every device allocation, and use appropriate combinations of vkCmdCopyBuffer to perform defragmentation of an arena block-by-block.

Say an arena may contain linear and non-linear data in any appropriately-aligned arrangement. Due to the immutability of VkImage after binding, defragmentation will involve constructing and binding new VkImages at the new locations of image data that have been moved.

None of the resources within an arena undergoing defragmentation are bound to anything, or could be considered "in-use".

This isn't difficult to implement, though I have a concern:

Is it UB to use vkCmdCopyBuffer to move an image's data (as to avoid redundant layout transitions), then construct a new VkImage at the new location?

My thoughts are that perhaps an implementation would do something strange, like rely on absolute device addresses within some internal bookkeeping structure, making it UB to treat image data as POD until bound to a new object.

like image 387
defube Avatar asked Mar 04 '26 02:03

defube


1 Answers

Well, let's look at this systematically.

So you find a suitable destination area for your image. You do a vkCmdCopyBuffer to copy from the source area to the destination area. Now you create a new VkImage for that destination area, and the initial layout you specify is... what?

See, there are only two valid initialLayout values in VkCreateImageInfo: undefined or preinitialized. And preinitialized is only works for images that use linear tiling, since there is no well-defined layout for optimal tiled images.

So you can't use preinitialized layout. And using undefined layout means that the next image transition you use will potentially mangle whatever data is there. Now, undefined layout might work on some implementations. On implementations that don't care about layout, it might work. It also might work on implementations if the source image was in the general layout.

But none of that is guaranteed to work by the standard. As far as the standard is concerned, if you set the layout to be undefined, then the data will not be preserved. So regardless of questions of buffer/image aliasing, this can't work.

You have to create the VkImage at the destination, then use vkCmdCopyImage to copy from the source image to the destination.

It should also be noted that, even if the layout issue worked, the aliasing rules tell us that copying from non-host-accessible memory (ie: images in optimal tiling or non-general/preinitialized layout) to host-accessible memory yields undefined values. So even if the layout issue weren't a problem, the copy itself doesn't work. In theory, at least.

like image 50
Nicol Bolas Avatar answered Mar 06 '26 20:03

Nicol Bolas



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!