假设我有一个VkBuffer
绑定到每个设备分配,并使用vkCmdCopyBuffer
的适当组合来逐块执行竞技场碎片整理。
假设竞技场可能包含任何适当对齐排列的线性和非线性数据。由于绑定后VkImage
的不变性,碎片整理将涉及在已移动的图像数据的新位置处构建和绑定新的VkImage
。
正在进行碎片整理的竞技场中的任何资源都不会受到任何限制,或者可以被视为"正在使用"。
虽然我有一个问题,但这并不难实现:
UB是否使用vkCmdCopyBuffer
移动图片的数据(以避免冗余布局转换),然后在新位置构建新的VkImage
?
我的想法是,一个实现可能会做一些奇怪的事情,例如依赖于某些内部簿记结构中的绝对设备地址,使其成为UB将图像数据视为POD直到绑定到新对象。
答案 0 :(得分:2)
好吧,让我们系统地看一下。
因此,您可以为图像找到合适的目标区域。您执行vkCmdCopyBuffer
从源区域复制到目标区域。现在为该目标区域创建一个新的VkImage
,您指定的初始布局是......什么?
请参阅initialLayout
中只有两个有效的VkCreateImageInfo
值:未定义或预初始化。并且预初始化仅适用于使用线性平铺的图像,因为没有明确定义的布局以获得最佳平铺图像。
因此您无法使用预初始化的布局。使用未定义的布局意味着您使用的下一个图像转换可能会破坏任何数据。现在,未定义的布局可能在某些实现上起作用。在不关心布局的实现上,它可能会起作用。如果源图像处于一般布局中,它也可能适用于实现。
但这些保证都不符合标准。就标准而言,如果将布局设置为未定义,则不会保留数据。因此,无论缓冲区/图像混叠的问题如何,这都行不通。
您必须在目的地创建VkImage
,然后使用vkCmdCopyImage
从源图像复制到目的地。
还应该注意的是,即使布局问题有效,aliasing rules告诉我们从非主机可访问的内存(即:最佳平铺或非通用/预初始化布局中的图像)复制到主机可访问的内存产生未定义的值。因此,即使布局问题不是问题,副本本身也不起作用。从理论上讲,至少。