Calling vkEnumerateDeviceExtensionProperties “twice” - is it required?

▼魔方 西西 提交于 2019-12-06 05:41:20

From the latest spec:

For both vkEnumerateInstanceExtensionProperties and vkEnumerateDeviceExtensionProperties, if pProperties is NULL, then the number of extensions properties available is returned in pPropertyCount. Otherwise, pPropertyCount must point to a variable set by the user to the number of elements in the pProperties array, and on return the variable is overwritten with the number of structures actually written to pProperties. If pPropertyCount is less than the number of extension properties available, at most pPropertyCount structures will be written. If pPropertyCount is smaller than the number of extensions available, VK_INCOMPLETE will be returned instead of VK_SUCCESS, to indicate that not all the available properties were returned.

So your approach is correct, even though it's a bit wasteful on memory. Similar functions returning arrays also behave like this.

Also note that since 1.0.13, device layers are deprecated. All instance layers are able to intercept commands to both the instance and the devices created from it.

Alex Byrth

Most Vulkan commands relays in double calls:

  1. First call to get count number of returning structures or handles;
  2. Second call to pass an properly sized array to get back requested structures/handle. In this second call, the count parameter tells the size of your array.

If , in second step, you get VkResult::VK_INCOMPLETE result then you passed an array too short to get all objects back. Note VK_INCOMPLETE is not an error, it is a partial success (2.6.2 Return Codes ... "All successful completion codes are non-negative values. ")

Your Question :

Am I depending on unsupported functionality by doing this, or is this somehow advertised somewhere else in the documentation?

You proposed create a big array before calling the function, to avoid a call Vulkan function twice.

My reply: Yes, and you are doing a bad design decision by "guessing" the array size.

Please, don't get me wrong. I strongly agree with you that is annoying to call same function twice, but you can solve it by wrapping those sort functions with a more programmer friendly behaviour.

I'll use another Vulkan function, just to illustrate it. Let say you want to avoid double call to :

VkResult vkEnumeratePhysicalDevices(
VkInstance                                  instance,
uint32_t*                                   pPhysicalDeviceCount,
VkPhysicalDevice*                           pPhysicalDevices);

A possible solution would be write the sweet wrap function:

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        
}

That is my two cents about the double call to Vulkan functions. It is a naive implementation and may not work for all cases! Note you must create the vector BEFORE you call the wrapping function.

Good Luck!

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!