我们说我有280
个字节的数据。如果我要创建一个缓冲区,那么根据VkMemoryRequirements
,分配的大小应该是512
个字节,并且512
的对齐方式是明确的。但是我需要一个主机可见大缓冲区,它可以容纳3个这样的数据(根据nvidia,这比3个缓冲区好)。而且我不清楚 - 我应该指定VkBufferCreateInfo::size
等于280 * 3
还是512 * 3
?如果我把它等于512 * 3
,那就浪费了空间。如果我使它等于280 * 3
,我可以在映射内存时遇到问题吗?规范提到映射范围应该是VkPhysicalDeviceLimits::nonCoherentAtomSize
的倍数,但仅适用于没有VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
分配的内存,这不是我的情况。主机连贯内存是否保证字节粒度内存更新?
答案 0 :(得分:2)
将缓冲区绑定到内存时,memoryOffset
需要是VkMemoryRequirements
中返回的对齐值的倍数。所以你应该有三个VkBuffers
每个280字节,但你将它们绑定为:
// stride = 512 in your example: 512 rounded up to a multiple of 512.
// would still be true if memoryRequirements.size was just 280.
// if 512 < memoryRequirements.size <= 1024, stride would be 1024, etc.
VkDeviceSize stride = round_up(memoryRequirement.size, memoryRequirement.alignment);
vkBindBufferMemory(device, buffer0, memory, 0 * stride);
vkBindBufferMemory(device, buffer1, memory, 1 * stride);
vkBindBufferMemory(device, buffer2, memory, 2 * stride);
因此VkDeviceMemory
的大小必须为3*memoryRequirements.size
,或者示例中为1536字节。
nonCoherentAtomSize
与所有这些无关。它本质上是缓存行或内存事务大小。对于非连贯的内存,如果你在&#34;非相干原子中写入一个字节&#34;,CPU仍然必须将整个原子写入内存,这意味着你将同时写入任何内容。来自GPU的原子。对于连贯的存储器,CPU和GPU协作使得它们每个都可以写入相邻的字节而不会覆盖彼此的数据。但是,如果您正在使用非连贯内存,并希望在GPU可能正在写入同一VkBuffers
中的另一个VkBuffer
时写入VkDeviceMemory
之一。 },您可能希望确保两个VkBuffers
不在缓冲区的同一nonCoherentAtomSize
块内重叠。
答案 1 :(得分:1)
如果要创建一个可容纳3 * 280
字节数据的缓冲区,则需要创建一个可容纳3 * 280
字节数据的缓冲区(需要将此值指定为大小在缓冲区创建期间)。但它需要多少内存(内存对象应该有多大),这取决于驱动程序。您需要创建一个大小等于3 * 280
的缓冲区,然后您需要检查它的内存要求,然后分配必要的内存对象(或从更大的内存对象中进行子分配)并将此内存绑定到缓冲区。
至于对齐 - 如果您想将单个内存对象的部分绑定到多个资源(缓冲区或图像),这很重要。在您的示例中,您可以创建3个缓冲区,可以容纳280个字节的数据。但是(如vkGetBufferMemoryRequirements()
函数所示)每个这样的缓冲区需要512字节的内存与512字节对齐。因此,对于3个单独的缓冲区,您需要3个单独的内存对象,每个大小为512字节,或者单个内存对象,大小为1536字节。然后,来自偏移0的存储器范围可以被绑定到第一缓冲器,从偏移512到第二缓冲器以及从偏移1024到第三缓冲器。但是,尽管你将512字节的内存绑定到缓冲区,但不要忘记你的缓冲区仍然只能容纳280字节的内存。
在此示例中,大小和对齐方式相同(均为512)。想象一下,你的大小为380字节的缓冲区需要386个字节在内存中与512对齐。这种情况不会改变任何东西 - 你的第一个缓冲区必然会偏移0(这个偏移总是满足所有对齐要求),第二个偏移512和第三个缓冲区偏移1024.通常,对齐意味着绑定到资源的内存范围的开始必须是给定对齐值的倍数(从内存对象的开头算起)。
在你的情况下,一个大的缓冲区可能更好(就浪费的内存空间而言):3 * 280
等于840
并且所需的内存大小和你的缓冲区的大小之间的相对差异可能是小。