Vulkan规范(1.0.12)在2.4节中介绍了VkDeviceSize:
除了少数例外,Vulkan使用参数的标准C类型(来自stdint.h的int类型等)。例外情况是使用VkResult作为返回值,使用VkBool32作为布尔值,使用VkDeviceSize作为与设备地址空间有关的大小和偏移,使用VkFlags来传递预定义值的位或位组。
但是,它从未告诉我们VkDeviceSize的基本类型实际上是什么。我们怎么知道在VkDeviceSize和size_t之间转换是否安全?
从随SDK提供的标题中,我看到它是对uint64_t的typedef。在未来的任何时候,这种情况有多大可能发生变化?
答案 0 :(得分:6)
为什么Vulkan规范没有定义VkDeviceSize?
请注意,Vulkan规范没有指定任何枚举器的值。为什么?因为它们已在vk.xml
中指定,用于生成vulkan.h
。
同样适用于VkDeviceSize
。就像Vulkan定义的所有其他类型一样。
是的,OpenGL规范为其各种类型指定了特定的大小。但是,Vulkan没有,而且没有。
我们如何知道在
VkDeviceSize
和size_t
之间转换是否安全?
唯一不安全的方法是,如果满足下列条件之一:
您要转换的size_t
类型的值对于VkDeviceSize
来说太大了。
您要转换的VkDeviceSize
的价值对于size_t
来说太大了。
嗯,您指定VkDeviceSize
的绝大多数地方最终都来自对vkAllocateMemory
的调用(映射偏移,缓冲区/图像创建等),所有这些都基于您分配的内存块)。因此,如果您要提供的size_t
无法适应VkDeviceSize
,那么......这意味着什么?
很明显,这意味着您要分配的内存量必须大于实现提供的内存量。毕竟,内存限制本身由VkDeviceSize
指定。因此,如果您的size_t
太大而无法适应该类型,那么您必须尝试分配比存在更多的内存。
我说这是一个比整数转换无法解决的问题更大的问题。
而#2主要对vkGetPhysicalDeviceMemoryProperties
很重要。如果size_t
太小而无法存储您从中获取的值...等等,您为什么要使用size_t
来存储这些值?您是否有某些原因无法使用值的实际类型VkDeviceSize
?
在未来的任何时候,这种情况有多大可能发生变化?
这或多或少无关紧要。为什么?由于Vulkan已经具有兼容性保证。
根据规范,次要版本的Vulkan 无法进行向后兼容的更改。如果您编写的代码对Vulkan 1.0有效,那么它也必须对Vulkan 1.1起作用。并且1.2。等等。
如果VkDeviceSize
版本之间发生了变化,则必须(至少)重新编译代码才能修复它。 Vulkan似乎将向后兼容性定义为二进制兼容性,而不是源兼容性:
如果仅依赖于早期规范定义的有效行为和功能的应用程序能够针对每个版本正确运行而无需任何修改,则API的给定版本向后兼容早期版本。
这表明应用程序应该无需重新编译即可运行。
所以唯一的时间VkDeviceSize
会改变主要版本。如果发生这种情况,就兼容性而言,所有赌注都会被取消。因此,改变这个尺寸的小事可能是无关紧要的。
答案 1 :(得分:2)
它在vk.xml中定义(如uint64_t)。特别引用它的官方地位:
Vulkan API的规范定义保存在名为Vulkan注册表的XML文件中。注册表保存在src / spec / vk.xml [...]
中
它现在相当根深蒂固,你不能期望它在1.0.X补丁版本中发生变化(尽管到目前为止发生了一些轻微的(可以说是)突破性变化,而它是新的)
您可以使用sizeof()
运算符进行查询。你也不知道size_t的大小。