vk/device: Fix vkEnumeratePhysicalDevices()
authorChad Versace <chad.versace@intel.com>
Thu, 9 Jul 2015 22:51:06 +0000 (15:51 -0700)
committerChad Versace <chad.versace@intel.com>
Thu, 9 Jul 2015 22:53:21 +0000 (15:53 -0700)
The Vulkan spec says that pPhysicalDeviceCount is an out parameter if
pPhysicalDevices is NULL; otherwise it's an inout parameter.

Mesa incorrectly treated it unconditionally as an inout parameter, which
could have lead to reading unitialized data.

src/vulkan/device.c

index bbe4ff1c87e788e476a2db10602c4f80df451d47..85f1cba23dd78763e736a82c2ce5b9f8006e5f7b 100644 (file)
@@ -168,12 +168,34 @@ VkResult anv_EnumeratePhysicalDevices(
       if (result != VK_SUCCESS)
          return result;
 
-      instance->physicalDeviceCount++;
-   }
-
-   if (*pPhysicalDeviceCount >= 1)
+      instance->physicalDeviceCount = 1;
+   }
+
+   /* pPhysicalDeviceCount is an out parameter if pPhysicalDevices is NULL;
+    * otherwise it's an inout parameter.
+    *
+    * The Vulkan spec (git aaed022) says:
+    *
+    *    pPhysicalDeviceCount is a pointer to an unsigned integer variable
+    *    that is initialized with the number of devices the application is
+    *    prepared to receive handles to. pname:pPhysicalDevices is pointer to
+    *    an array of at least this many VkPhysicalDevice handles [...].
+    *
+    *    Upon success, if pPhysicalDevices is NULL, vkEnumeratePhysicalDevices
+    *    overwrites the contents of the variable pointed to by
+    *    pPhysicalDeviceCount with the number of physical devices in in the
+    *    instance; otherwise, vkEnumeratePhysicalDevices overwrites
+    *    pPhysicalDeviceCount with the number of physical handles written to
+    *    pPhysicalDevices.
+    */
+   if (!pPhysicalDevices) {
+      *pPhysicalDeviceCount = instance->physicalDeviceCount;
+   } else if (*pPhysicalDeviceCount >= 1) {
       pPhysicalDevices[0] = (VkPhysicalDevice) &instance->physicalDevice;
-   *pPhysicalDeviceCount = instance->physicalDeviceCount;
+      *pPhysicalDeviceCount = 1;
+   } else {
+      *pPhysicalDeviceCount = 0;
+   }
 
    return VK_SUCCESS;
 }