来自man page for vkEnumerateDeviceExtensionProperties,
vkEnumerateDeviceExtensionProperties检索的属性 物理设备上的扩展,其句柄在 physicalDevice。确定图层集实现的扩展 pLayerName指向图层的名称和任何返回的扩展名 由该层实现。将pLayerName设置为NULL将返回 可用的非图层扩展。 pPropertyCount必须设置为 pProperties指向的VkExtensionProperties数组的大小。该 pProperties应该指向一个VkExtensionProperties数组 填写或null。 如果为null,则vkEnumerateDeviceExtensionProperties将 使用找到的扩展数更新pPropertyCount。 VkExtensionProperties的定义如下:
(强调我的)。在当前的实现(Window SDK v1.0.13)中,无论pPropertyCount
是否为空,pProperties
都会使用扩展数进行更新。但是,在这种情况下,文档似乎并不明确。
以下是一个例子,为什么有这样一个功能更好':
const uint32_t MaxCount = 1024; // More than you'll ever need
uint32_t ActualCount = MaxCount;
VkLayerProperties layers[MaxCount];
VkResult result = vkEnumerateDeviceLayerProperties(physicalDevice, &ActualCount, layers);
//...
VS
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);
//...
}
我的问题是:我是通过这样做取决于不受支持的功能,还是以某种方式在文档中的其他位置做广告?
答案 0 :(得分:2)
来自latest spec:
对于vkEnumerateInstanceExtensionProperties和vkEnumerateDeviceExtensionProperties,如果pProperties为NULL,则在pPropertyCount中返回可用的扩展属性数。否则,pPropertyCount必须指向用户设置的变量到pProperties数组中的元素数量,并且在返回时,变量将被实际写入pProperties 的结构数覆盖。如果pPropertyCount小于可用的扩展属性数,则最多将写入pPropertyCount结构。如果pPropertyCount小于可用的扩展数,则将返回VK_INCOMPLETE而不是VK_SUCCESS,以指示并未返回所有可用属性。
所以你的方法是正确的,即使它在内存上有点浪费。返回数组的类似函数也表现如下。
另请注意,自1.0.13起,不推荐使用设备层。所有实例层都能够拦截实例和从其创建的设备的命令。
答案 1 :(得分:0)
大多数Vulkan命令在双重调用中进行中继:
如果在第二步中获得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函数的双重调用,这是我的两分钱。 这是一个天真的实现,可能不适用于所有情况!请注意,您必须在调用包装函数之前创建向量。
祝你好运!