Sort and dedup physical device extensions
... to avoid issues when running dEQP. The Vulkan Loader's trampoline
functions will remove duplicates as well but this can lead to lead
errors if Gfxstream's function returns VK_SUCCESS with N elements
(including a duplicate) but the Vulkan Loader's trampoline function
returns N-1 when querying the extension count. Then, Gfxstream will
return VK_INCOMPLETE the second time the application queries for
the actual structs with an array sized N-1.
Bug: b/315317383
Test: deqp-vk w/ Gfxstream ICD
Change-Id: I684b6aeef40e025a90fa687f4a2d902b13d84bdf
diff --git a/guest/vulkan_enc/ResourceTracker.cpp b/guest/vulkan_enc/ResourceTracker.cpp
index fd89d73..e8ff76b 100644
--- a/guest/vulkan_enc/ResourceTracker.cpp
+++ b/guest/vulkan_enc/ResourceTracker.cpp
@@ -35,6 +35,7 @@
#include <stdlib.h>
#include <vndk/hardware_buffer.h>
+#include <algorithm>
#include <set>
#include <string>
#include <unordered_map>
@@ -1864,6 +1865,24 @@
#endif
}
+ // NOTE: the Vulkan Loader's trampoline functions will remove duplicates. This can lead
+ // to lead errors if this function returns VK_SUCCESS with N elements (including a duplicate)
+ // but the Vulkan Loader's trampoline function returns VK_INCOMPLETE with N-1 elements
+ // (without the duplicate).
+ std::sort(filteredExts.begin(),
+ filteredExts.end(),
+ [](const VkExtensionProperties& a,
+ const VkExtensionProperties& b) {
+ return strcmp(a.extensionName, b.extensionName) < 0;
+ });
+ filteredExts.erase(std::unique(filteredExts.begin(),
+ filteredExts.end(),
+ [](const VkExtensionProperties& a,
+ const VkExtensionProperties& b) {
+ return strcmp(a.extensionName, b.extensionName) == 0;
+ }),
+ filteredExts.end());
+
// Spec:
//
// https://www.khronos.org/registry/vulkan/specs/1.1-extensions/man/html/vkEnumerateDeviceExtensionProperties.html