Vulkan中动态统一缓冲区的缓冲区内存分配
Buffer memory allocation for Dynamic uniform buffer in Vulkan
我想把这个问题分成三部分:-
-
限制的概念是什么。minUniformBufferOffsetAlignment为什么我们需要使用它来获得所需的对齐,并从中导出缓冲区的偏移量?Vulkan不能自动区分不同的数据类型和它们各自的对齐方式吗?
-
在Sascha-Willems的例子中,他计算了一个4X4矩阵的动态排列,如下
size_t uboAlignment = vulkanDevice->properties.limits.minUniformBufferOffsetAlignment dynamicAlignment = (sizeof(glm::mat4) / uboAlignment) * uboAlignment + ((sizeof(glm::mat4) % uboAlignment) > 0 ? uboAlignment : 0);
一个4X4矩阵是64字节,允许的最小对齐大小是256字节,但据我所知,他的动态对齐计算结果是(64+256=320//,我认为这在vulkan中是不允许的),我不太明白这种动态对齐计算是如何工作的
-
这个dynamicAlign变量如何反映到
VkBufferCreateInfo bufferInfo = {}; bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; bufferInfo.size = size;
以及类似的内存映射
void * data; vkMapMemory(device, uniformStagingBufferMemory, 0, sizeof(matrix), 0, &data); memcpy(data, &matrix, sizeof(matrix)); vkUnmapMemory(device, uniformStagingBufferMemory); copyBuffer(uniformStagingBuffer, uniformBuffer, sizeof(matrix));
-
最小UBO对齐是对您的限制。也就是说,它告诉你每个UBO的开始都必须是该对齐的倍数。它告诉您必须将数据放入内存中的何处,以便系统使用该数据。
这不是Vulkan可以自动让你做的事情。Vulkan是一个明确的API:你生活在其限制范围内,反之亦然。请注意,OpenGL对UBO数据有同样的限制。
-
这个代码被破坏得很厉害,但它是意外工作的。
(sizeof(glm::mat4) / uboAlignment)
的结果是零,因为整数的除法总是会导致整数。由于标准要求minUniformBufferOffsetAlignment
不小于256,因此将64除以该值将始终产生零,向下取整。并且CCD_ 3仍然为零。所以剩下的代码只有一部分是
((sizeof(glm::mat4) % uboAlignment) > 0 ? uboAlignment : 0)
64%256是192,大于0,所以结果是uboAlignment
。所以它是有效的,但只是偶然的。他可能只是直接使用了
minUniformBufferOffsetAlignment
。 -
首先,内存映射是一个非常重要的操作。你不应该仅仅为了设置矩阵而映射内存,然后立即取消映射。如果你打算通过映射修改内存,你应该保持它的映射,直到你准备删除它。这不会抑制性能,阻止你按照允许的使用方法使用内存,或其他任何事情。
其次,正如规范中明确概述的那样,如果您创建了一个可以用作统一缓冲区的
VkBuffer
,那么您指定的偏移量必须符合minUniformBufferOffsetAlignment
。类似地,当使用这样的缓冲区作为UBO资源时,您提供的偏移量也必须与minUniformBufferOffsetAlignment
对齐,无论偏移量是动态的还是静态的。
1.:缓冲区大小需要是它的倍数。你需要意识到你实际上在缓冲区的哪个部分存储了一些东西,而你没有在哪里存储。如果你的数据不完全适合你的缓冲区,它需要以倍数放大。
2.:你的计算失败了。整数运算。结果只有256。
3.:无需复制缓冲区中实际上不包含数据的部分。允许部分复制,只是缓冲区本身更大。
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- 如何分配适合容纳 T 类型对象的缓冲区(可能过度对齐、可能有运算符 new 等)
- char p[0]表示自动分配的缓冲区还是安全指针
- 有没有办法自动实现 sprintf 的缓冲区分配?
- 线程函数无法从堆上分配的缓冲区中读取字符
- 如何正确分配Fuse ReadDir()的缓冲区
- 将数据分配给了数组分配,但程序显示了以缓冲区超支的输出
- C++:当我将值分配给缓冲区时,它不起作用
- 如何在 OpenCL 中使用缓冲区分配和映射内存机制
- 从C 中的函数中动态分配的缓冲区返回的最佳模式是什么?
- 了解循环缓冲区实现的内存分配性质
- 尝试为图像缓冲区分配内存时 ptr 值错误
- Sprintf 缓冲区问题,错误分配给字符数组
- Vulkan中动态统一缓冲区的缓冲区内存分配
- 如何分配可执行的内存缓冲区
- C - 分配一个未签名的炭缓冲区,然后用字符串填充
- 包含溢出缓冲区的堆栈分配变量,也称为缓冲区
- 使用 sprintf 分配给字符数组并将字符指针作为输入之一时缓冲区溢出
- 静态数组缓冲区分配
- OpenCL缓冲区分配和映射最佳实践