调用 vkEnumerateDeviceExtensionProperties "twice" - 是否需要?
Calling vkEnumerateDeviceExtensionProperties "twice" - is it required?
从vkEnumerateDeviceExtensionProperties的手册页,
vkEnumerateDeviceExtensionProperties检索的属性中给定句柄的物理设备上的扩展物理设备。确定图层集实现的扩展pLayerName指向层的名称和任何返回的扩展名由该层实现。将pLayerName设置为NULL将返回可用的非层扩展。pPropertyCount必须设置为pProperties指向的VkExtensionProperties数组的大小。这个pProperties应该指向要填写或为空如果为null,vkEnumerateDeviceExtensionProperties将使用找到的扩展数更新pPropertyCountVkExtensionProperties的定义如下:
(强调矿)。在当前的实现(Window SDK v1.0.13)中,无论pProperties
是否为null,pPropertyCount
都会随扩展的数量而更新。然而,文档似乎没有明确说明在这种情况下会发生什么。
以下是一个例子,说明为什么拥有这样的功能"更好":
const uint32_t MaxCount = 1024; // More than you'll ever need
uint32_t ActualCount = MaxCount;
VkLayerProperties layers[MaxCount];
VkResult result = vkEnumerateDeviceLayerProperties(physicalDevice, &ActualCount, layers);
//...
与。
uint32_t ActualCount = 0;
VkLayerProperties* layers;
VkResult result = vkEnumerateDeviceLayerProperties(physicalDevice, &ActualCount, nullptr);
if (ActualCount > 0)
{
extensions = alloca(ActualCount * sizeof(VkLayerProperties));
result = vkEnumerateDeviceLayerProperties(physicalDevice, &ActualCount, layers);
//...
}
我的问题是:我这样做是依赖于不受支持的功能,还是在文档中的其他地方做了广告?
来自最新规范:
对于vkEnumerateInstanceExtensionProperties和vkEnuerateDeviceExtensionProperties,如果pProperties为NULL,则在pPropertyCount中返回可用的扩展属性数。否则,pPropertyCount必须指向一个变量,该变量由用户设置为pProperties数组中的元素数,,返回时,该变量将被实际写入pProperties的结构数覆盖。如果pPropertyCount小于可用的扩展属性数,则最多将写入pPropertyCount结构。如果pPropertyCount小于可用扩展的数量,则将返回VK_INCOMPLETE而不是VK_SUCCESS,以表明并非所有可用属性都已返回。
所以您的方法是正确的,尽管它在内存上有点浪费。返回数组的类似函数也有类似的行为。
还要注意的是,自1.0.13以来,设备层已被弃用。所有实例层都能够拦截对实例和从中创建的设备的命令
大多数Vulkan命令在双重调用中中继:
- 第一个调用,获取返回结构或句柄的计数
- 第二个调用,传递一个大小合适的数组,以返回请求的结构/句柄。在第二个调用中,count参数告诉数组的大小
如果在第二步中获得VkResult::VK_INCOMPLETE结果,则传递的数组太短,无法取回所有对象。注意VK_INCOMPLETE不是错误,它是部分成功(2.6.2返回代码…"所有成功的完成代码都是非负值。")
您的问题:
我是否依赖于不受支持的功能这个,或者这是在《文档
您建议在调用函数之前创建一个大数组,以避免两次调用Vulkan函数。
我的回答:是的,你"猜测"是在做一个糟糕的设计决定数组大小。
请不要误解我的意思我非常同意您的观点,两次调用同一个函数是很烦人的,但您可以通过用更友好的程序员行为包装这些排序函数来解决这个问题。
我将使用另一个Vulkan函数来说明它。假设你想避免双重调用:
VkResult vkEnumeratePhysicalDevices(
VkInstance instance,
uint32_t* pPhysicalDeviceCount,
VkPhysicalDevice* pPhysicalDevices);
一个可能的解决方案是编写甜包装函数:
VkResult getPhysicalDevices(VkInstance instance, std::vector<VkPhysicalDevice>& container){
uint32_t count = 0;
VkResult res = vkEnumeratePhysicalDevices(instance, &count, NULL); // get #count
container.resize(count); //Removes extra entries or allocates more.
if (res < 0) // something goes wrong here
return res;
res = vkEnumeratePhysicalDevices(instance, &count, container.data()); // all entries overwritten.
return res; // possible OK
}
这是我对Vulkan函数的双重调用的两美分这是一个幼稚的实现,可能不适用于所有情况请注意,在调用包装函数之前,必须创建向量。
祝你好运!
- 在提升multi_index容器中,是否定义了"default index"?
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- 检查输入是否不是整数或数字
- 是否可以初始化不可复制类型的成员变量(或基类)
- 在C++中,是否可以基于给定的标识符创建基类的新实例,反之亦然
- 是否可以通过C++扩展强制多个python进程共享同一内存
- 此代码是否违反一个定义规则
- 是否需要删除包含对象的"pair"?
- 是否可以从int转换为enum类类型
- 无论条件是否为true,if总是在c++中执行
- 如何找到大小'x'数组是否完全填充,在C++?
- 检查值是否在集合p1和p2中,但不在p3中
- 是否可以在编译时初始化数组,以便在运行时不会花费时间?
- 检查 std::shared_ptr<> 的当前底层类型是否为 T
- 在c++中检查长方体是否尽可能快地重叠(无迭代)
- GL_SHADERSTORAGE_BUFFER位置是否与其他着色器位置冲突
- 子目录是否继承属性,例如add_definitions,include_directories和父Cmakelist.t
- 标准是否使用多余的大括号(例如 T{{{10}}})定义列表初始化?
- C/C++预处理器是否可以检测一些编译器选项
- 是否可以用"iostream"包装现有的TCP/OOpenSSL会话