[vulkan] Only retrieve host physical devices once

bug: 111137294

The handles need to stay the same between invocations.

This CL takes the codegen that makes vkEnumeratePhysicalDevices
a custom implementation, and only asks the host once
for the physical device handles.

Test: Unit test
Change-Id: Ib07f1f14c41e973fee284a48275d1625941007b9
diff --git a/system/vulkan/func_table.cpp b/system/vulkan/func_table.cpp
index 88d0972..e3079c5 100644
--- a/system/vulkan/func_table.cpp
+++ b/system/vulkan/func_table.cpp
@@ -66,7 +66,8 @@
 {
     auto vkEnc = HostConnection::get()->vkEncoder();
     VkResult vkEnumeratePhysicalDevices_VkResult_return = (VkResult)0;
-    vkEnumeratePhysicalDevices_VkResult_return = vkEnc->vkEnumeratePhysicalDevices(instance, pPhysicalDeviceCount, pPhysicalDevices);
+    auto resources = ResourceTracker::get();
+    vkEnumeratePhysicalDevices_VkResult_return = resources->on_vkEnumeratePhysicalDevices(vkEnc, VK_SUCCESS, instance, pPhysicalDeviceCount, pPhysicalDevices);
     return vkEnumeratePhysicalDevices_VkResult_return;
 }
 static void entry_vkGetPhysicalDeviceFeatures(
diff --git a/system/vulkan_enc/ResourceTracker.cpp b/system/vulkan_enc/ResourceTracker.cpp
index 1434965..c731a05 100644
--- a/system/vulkan_enc/ResourceTracker.cpp
+++ b/system/vulkan_enc/ResourceTracker.cpp
@@ -120,6 +120,8 @@
     struct VkInstance_Info {
         uint32_t highestApiVersion;
         std::set<std::string> enabledExtensions;
+        // Fodder for vkEnumeratePhysicalDevices.
+        std::vector<VkPhysicalDevice> physicalDevices;
     };
 
     struct VkDevice_Info {
@@ -639,6 +641,65 @@
         return VK_SUCCESS;
     }
 
+    VkResult on_vkEnumeratePhysicalDevices(
+        void* context, VkResult,
+        VkInstance instance, uint32_t* pPhysicalDeviceCount,
+        VkPhysicalDevice* pPhysicalDevices) {
+
+        VkEncoder* enc = (VkEncoder*)context;
+
+        if (!instance) return VK_ERROR_INITIALIZATION_FAILED;
+
+        if (!pPhysicalDeviceCount) return VK_ERROR_INITIALIZATION_FAILED;
+
+        AutoLock lock(mLock);
+
+        auto it = info_VkInstance.find(instance);
+
+        if (it == info_VkInstance.end()) return VK_ERROR_INITIALIZATION_FAILED;
+
+        auto& info = it->second;
+
+        if (info.physicalDevices.empty()) {
+            uint32_t physdevCount = 0;
+
+            lock.unlock();
+            VkResult countRes = enc->vkEnumeratePhysicalDevices(
+                instance, &physdevCount, nullptr);
+            lock.lock();
+
+            if (countRes != VK_SUCCESS) {
+                ALOGE("%s: failed: could not count host physical devices. "
+                      "Error %d\n", __func__, countRes);
+                return countRes;
+            }
+
+            info.physicalDevices.resize(physdevCount);
+
+            lock.unlock();
+            VkResult enumRes = enc->vkEnumeratePhysicalDevices(
+                instance, &physdevCount, info.physicalDevices.data());
+            lock.lock();
+
+            if (enumRes != VK_SUCCESS) {
+                ALOGE("%s: failed: could not retrieve host physical devices. "
+                      "Error %d\n", __func__, enumRes);
+                return enumRes;
+            }
+        }
+
+        *pPhysicalDeviceCount = (uint32_t)info.physicalDevices.size();
+
+        if (pPhysicalDevices && *pPhysicalDeviceCount) {
+            memcpy(pPhysicalDevices,
+                   info.physicalDevices.data(),
+                   sizeof(VkPhysicalDevice) *
+                   info.physicalDevices.size());
+        }
+
+        return VK_SUCCESS;
+    }
+
     void on_vkGetPhysicalDeviceMemoryProperties(
         void*,
         VkPhysicalDevice physdev,
@@ -1397,6 +1458,15 @@
         context, input_result, physicalDevice, pLayerName, pPropertyCount, pProperties);
 }
 
+VkResult ResourceTracker::on_vkEnumeratePhysicalDevices(
+    void* context, VkResult input_result,
+    VkInstance instance, uint32_t* pPhysicalDeviceCount,
+    VkPhysicalDevice* pPhysicalDevices) {
+    return mImpl->on_vkEnumeratePhysicalDevices(
+        context, input_result, instance, pPhysicalDeviceCount,
+        pPhysicalDevices);
+}
+
 void ResourceTracker::on_vkGetPhysicalDeviceMemoryProperties(
     void* context,
     VkPhysicalDevice physicalDevice,
diff --git a/system/vulkan_enc/ResourceTracker.h b/system/vulkan_enc/ResourceTracker.h
index c851574..2358ffe 100644
--- a/system/vulkan_enc/ResourceTracker.h
+++ b/system/vulkan_enc/ResourceTracker.h
@@ -62,6 +62,11 @@
         uint32_t* pPropertyCount,
         VkExtensionProperties* pProperties);
 
+    VkResult on_vkEnumeratePhysicalDevices(
+        void* context, VkResult input_result,
+        VkInstance instance, uint32_t* pPhysicalDeviceCount,
+        VkPhysicalDevice* pPhysicalDevices);
+
     void on_vkGetPhysicalDeviceMemoryProperties(
         void* context,
         VkPhysicalDevice physicalDevice,