Handle AHB and swapchain info in VkBindImageMemoryInfo

... in order to help handle deferred AHB binding.

Bug: b/286234683
Test: cvd start --gpu_mode=gfxstream_guest_angle
Test: cvd start --gpu_mode=gfxstream_guest_angle_host_swiftshader
Change-Id: I3d5e65be8331980ce544078f81f1937cfbcf520f
Merged-In: I3d5e65be8331980ce544078f81f1937cfbcf520f
diff --git a/guest/vulkan_enc/ResourceTracker.cpp b/guest/vulkan_enc/ResourceTracker.cpp
index f6dec28..4a17d1f 100644
--- a/guest/vulkan_enc/ResourceTracker.cpp
+++ b/guest/vulkan_enc/ResourceTracker.cpp
@@ -5184,28 +5184,34 @@
         void* context, VkResult,
         VkDevice device, uint32_t bindingCount, const VkBindImageMemoryInfo* pBindInfos) {
         VkEncoder* enc = (VkEncoder*)context;
-        // Do not forward calls with invalid handles to host.
-        if (!pBindInfos ||
-            info_VkDeviceMemory.find(pBindInfos->memory) ==
-                info_VkDeviceMemory.end() ||
-            info_VkImage.find(pBindInfos->image) == info_VkImage.end()) {
+
+        if (bindingCount < 1 || !pBindInfos) {
             return VK_ERROR_OUT_OF_DEVICE_MEMORY;
         }
+
+        for (uint32_t i = 0; i < bindingCount; i++) {
+            const VkBindImageMemoryInfo& bimi = pBindInfos[i];
+
+            auto imageIt = info_VkImage.find(bimi.image);
+            if (imageIt == info_VkImage.end()) {
+                return VK_ERROR_OUT_OF_DEVICE_MEMORY;
+            }
+
+            if (bimi.memory != VK_NULL_HANDLE) {
+                auto memoryIt = info_VkDeviceMemory.find(bimi.memory);
+                if (memoryIt == info_VkDeviceMemory.end()) {
+                    return VK_ERROR_OUT_OF_DEVICE_MEMORY;
+                }
+            }
+        }
+
         return enc->vkBindImageMemory2(device, bindingCount, pBindInfos, true /* do lock */);
     }
 
     VkResult on_vkBindImageMemory2KHR(
-        void* context, VkResult,
+        void* context, VkResult result,
         VkDevice device, uint32_t bindingCount, const VkBindImageMemoryInfo* pBindInfos) {
-        VkEncoder* enc = (VkEncoder*)context;
-        // Do not forward calls with invalid handles to host.
-        if (!pBindInfos ||
-            info_VkDeviceMemory.find(pBindInfos->memory) ==
-                info_VkDeviceMemory.end() ||
-            info_VkImage.find(pBindInfos->image) == info_VkImage.end()) {
-            return VK_ERROR_OUT_OF_DEVICE_MEMORY;
-        }
-        return enc->vkBindImageMemory2KHR(device, bindingCount, pBindInfos, true /* do lock */);
+        return on_vkBindImageMemory2(context, result, device, bindingCount, pBindInfos);
     }
 
     VkResult on_vkCreateBuffer(
@@ -6094,33 +6100,36 @@
 
 #ifdef VK_USE_PLATFORM_ANDROID_KHR
     void unwrap_VkNativeBufferANDROID(
-        const VkImageCreateInfo* pCreateInfo,
-        VkImageCreateInfo* local_pCreateInfo) {
+        const VkNativeBufferANDROID* inputNativeInfo,
+        VkNativeBufferANDROID* outputNativeInfo) {
 
-        if (!pCreateInfo->pNext) return;
-
-        const VkNativeBufferANDROID* nativeInfo =
-            vk_find_struct<VkNativeBufferANDROID>(pCreateInfo);
-        if (!nativeInfo) {
+        if (!inputNativeInfo || !inputNativeInfo->handle) {
             return;
         }
 
-        if (!nativeInfo->handle) return;
-
-        VkNativeBufferANDROID* nativeInfoOut =
-            reinterpret_cast<VkNativeBufferANDROID*>(
-                const_cast<void*>(
-                    local_pCreateInfo->pNext));
-
-        if (!nativeInfoOut->handle) {
+        if (!outputNativeInfo || !outputNativeInfo) {
             ALOGE("FATAL: Local native buffer info not properly allocated!");
             abort();
         }
 
-        *(uint32_t*)(nativeInfoOut->handle) =
-            ResourceTracker::threadingCallbacks.hostConnectionGetFunc()->
-                grallocHelper()->getHostHandle(
-                    (const native_handle_t*)nativeInfo->handle);
+        auto* gralloc = ResourceTracker::threadingCallbacks.hostConnectionGetFunc()->grallocHelper();
+
+        *(uint32_t*)(outputNativeInfo->handle) =
+            gralloc->getHostHandle((const native_handle_t*)inputNativeInfo->handle);
+    }
+
+    void unwrap_vkCreateImage_pCreateInfo(
+        const VkImageCreateInfo* pCreateInfo,
+        VkImageCreateInfo* local_pCreateInfo) {
+
+        const VkNativeBufferANDROID* inputNativeInfo =
+            vk_find_struct<VkNativeBufferANDROID>(pCreateInfo);
+
+        VkNativeBufferANDROID* outputNativeInfo =
+            const_cast<VkNativeBufferANDROID*>(
+                vk_find_struct<VkNativeBufferANDROID>(local_pCreateInfo));
+
+        unwrap_VkNativeBufferANDROID(inputNativeInfo, outputNativeInfo);
     }
 
     void unwrap_vkAcquireImageANDROID_nativeFenceFd(int fd, int*) {
@@ -6142,6 +6151,52 @@
             close(fd);
         }
     }
+
+    void unwrap_VkBindImageMemorySwapchainInfoKHR(
+        const VkBindImageMemorySwapchainInfoKHR* inputBimsi,
+        VkBindImageMemorySwapchainInfoKHR* outputBimsi) {
+        if (!inputBimsi || !inputBimsi->swapchain) {
+            return;
+        }
+
+        if (!outputBimsi || !outputBimsi->swapchain) {
+            ALOGE("FATAL: Local VkBindImageMemorySwapchainInfoKHR not properly allocated!");
+            abort();
+        }
+
+        // Android based swapchains are implemented by the Android framework's
+        // libvulkan. The only exist within the guest and should not be sent to
+        // the host.
+        outputBimsi->swapchain = VK_NULL_HANDLE;
+    }
+
+    void unwrap_VkBindImageMemory2_pBindInfos(
+            uint32_t bindInfoCount,
+            const VkBindImageMemoryInfo* inputBindInfos,
+            VkBindImageMemoryInfo* outputBindInfos) {
+        for (uint32_t i = 0; i < bindInfoCount; ++i) {
+            const VkBindImageMemoryInfo* inputBindInfo = &inputBindInfos[i];
+            VkBindImageMemoryInfo* outputBindInfo = &outputBindInfos[i];
+
+            const VkNativeBufferANDROID* inputNativeInfo =
+                vk_find_struct<VkNativeBufferANDROID>(inputBindInfo);
+
+            VkNativeBufferANDROID* outputNativeInfo =
+                const_cast<VkNativeBufferANDROID*>(
+                    vk_find_struct<VkNativeBufferANDROID>(outputBindInfo));
+
+            unwrap_VkNativeBufferANDROID(inputNativeInfo, outputNativeInfo);
+
+            const VkBindImageMemorySwapchainInfoKHR* inputBimsi =
+                vk_find_struct<VkBindImageMemorySwapchainInfoKHR>(inputBindInfo);
+
+            VkBindImageMemorySwapchainInfoKHR* outputBimsi =
+                const_cast<VkBindImageMemorySwapchainInfoKHR*>(
+                    vk_find_struct<VkBindImageMemorySwapchainInfoKHR>(outputBindInfo));
+
+            unwrap_VkBindImageMemorySwapchainInfoKHR(inputBimsi, outputBimsi);
+        }
+    }
 #endif
 
     // Action of vkMapMemoryIntoAddressSpaceGOOGLE:
@@ -7883,11 +7938,11 @@
     return mImpl->on_vkImportSemaphoreFdKHR(context, input_result, device, pImportSemaphoreFdInfo);
 }
 
-void ResourceTracker::unwrap_VkNativeBufferANDROID(
+void ResourceTracker::unwrap_vkCreateImage_pCreateInfo(
     const VkImageCreateInfo* pCreateInfo,
     VkImageCreateInfo* local_pCreateInfo) {
 #ifdef VK_USE_PLATFORM_ANDROID_KHR
-    mImpl->unwrap_VkNativeBufferANDROID(pCreateInfo, local_pCreateInfo);
+    mImpl->unwrap_vkCreateImage_pCreateInfo(pCreateInfo, local_pCreateInfo);
 #endif
 }
 
@@ -7897,6 +7952,15 @@
 #endif
 }
 
+void ResourceTracker::unwrap_VkBindImageMemory2_pBindInfos(
+        uint32_t bindInfoCount,
+        const VkBindImageMemoryInfo* inputBindInfos,
+        VkBindImageMemoryInfo* outputBindInfos) {
+#ifdef VK_USE_PLATFORM_ANDROID_KHR
+    mImpl->unwrap_VkBindImageMemory2_pBindInfos(bindInfoCount, inputBindInfos, outputBindInfos);
+#endif
+}
+
 #ifdef VK_USE_PLATFORM_FUCHSIA
 VkResult ResourceTracker::on_vkGetMemoryZirconHandleFUCHSIA(
     void* context, VkResult input_result,