[vulkan] Block host visible memory from being external memory

bug: 122080810

Since we currently virtualize all host visible memory,
a different, more complicated mechanism would be required for
host visible external memory support in the guest.

Most likely, that would involve having separate allocations for them
on the host as well, or allocated from a separate external memory arena
that on the host (as in guest/host) is host (as in host/device) visible and external.

Change-Id: Iba6de59e64f6e794ae78d34489d6a659eb51abdd
diff --git a/system/vulkan_enc/ResourceTracker.cpp b/system/vulkan_enc/ResourceTracker.cpp
index 27141a9..0e91925 100644
--- a/system/vulkan_enc/ResourceTracker.cpp
+++ b/system/vulkan_enc/ResourceTracker.cpp
@@ -250,6 +250,8 @@
     struct VkImage_Info {
         VkDevice device;
         VkImageCreateInfo createInfo;
+        bool external = false;
+        VkExternalMemoryImageCreateInfo externalCreateInfo;
         VkDeviceMemory currentBacking = VK_NULL_HANDLE;
         VkDeviceSize currentBackingOffset = 0;
         VkDeviceSize currentBackingSize = 0;
@@ -259,6 +261,8 @@
     struct VkBuffer_Info {
         VkDevice device;
         VkBufferCreateInfo createInfo;
+        bool external = false;
+        VkExternalMemoryBufferCreateInfo externalCreateInfo;
         VkDeviceMemory currentBacking = VK_NULL_HANDLE;
         VkDeviceSize currentBackingOffset = 0;
         VkDeviceSize currentBackingSize = 0;
@@ -1570,6 +1574,58 @@
         // no-op
     }
 
+    uint32_t transformExternalResourceMemoryTypeBitsForGuest(
+        uint32_t normalBits) {
+        uint32_t res = 0;
+        for (uint32_t i = 0; i < VK_MAX_MEMORY_TYPES; ++i) {
+            if (normalBits & (1 << i) &&
+                !isHostVisibleMemoryTypeIndexForGuest(
+                    &mHostVisibleMemoryVirtInfo, i)) {
+                res |= (1 << i);
+            }
+        }
+        return res;
+    }
+
+    void transformExternalResourceMemoryRequirementsForGuest(
+        VkMemoryRequirements* reqs) {
+        reqs->memoryTypeBits =
+            transformExternalResourceMemoryTypeBitsForGuest(
+                reqs->memoryTypeBits);
+    }
+
+    void transformExternalImageMemoryRequirementsForGuest(
+        VkImage image,
+        VkMemoryRequirements* reqs) {
+
+        AutoLock lock(mLock);
+
+        auto it = info_VkImage.find(image);
+        if (it == info_VkImage.end()) return;
+
+        auto& info = it->second;
+        if (!info.external) return;
+        if (!info.externalCreateInfo.handleTypes) return;
+
+        transformExternalResourceMemoryRequirementsForGuest(reqs);
+    }
+
+    void transformExternalBufferMemoryRequirementsForGuest(
+        VkBuffer buffer,
+        VkMemoryRequirements* reqs) {
+
+        AutoLock lock(mLock);
+
+        auto it = info_VkBuffer.find(buffer);
+        if (it == info_VkBuffer.end()) return;
+
+        auto& info = it->second;
+        if (!info.external) return;
+        if (!info.externalCreateInfo.handleTypes) return;
+
+        transformExternalResourceMemoryRequirementsForGuest(reqs);
+    }
+
     VkResult on_vkCreateImage(
         void* context, VkResult,
         VkDevice device, const VkImageCreateInfo *pCreateInfo,
@@ -1624,6 +1680,15 @@
         info.createInfo.pNext = nullptr;
         info.cbHandle = cbHandle;
 
+        VkExternalMemoryImageCreateInfo* extImgCi =
+            (VkExternalMemoryImageCreateInfo*)vk_find_struct((vk_struct_common*)pCreateInfo,
+                VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO);
+
+        if (!extImgCi) return res;
+
+        info.external = true;
+        info.externalCreateInfo = *extImgCi;
+
         return res;
     }
 
@@ -1640,6 +1705,8 @@
         VkEncoder* enc = (VkEncoder*)context;
         enc->vkGetImageMemoryRequirements(
             device, image, pMemoryRequirements);
+        transformExternalImageMemoryRequirementsForGuest(
+            image, pMemoryRequirements);
     }
 
     void on_vkGetImageMemoryRequirements2(
@@ -1648,6 +1715,9 @@
         VkEncoder* enc = (VkEncoder*)context;
         enc->vkGetImageMemoryRequirements2(
             device, pInfo, pMemoryRequirements);
+        transformExternalImageMemoryRequirementsForGuest(
+            pInfo->image,
+            &pMemoryRequirements->memoryRequirements);
     }
 
     void on_vkGetImageMemoryRequirements2KHR(
@@ -1656,6 +1726,9 @@
         VkEncoder* enc = (VkEncoder*)context;
         enc->vkGetImageMemoryRequirements2KHR(
             device, pInfo, pMemoryRequirements);
+        transformExternalImageMemoryRequirementsForGuest(
+            pInfo->image,
+            &pMemoryRequirements->memoryRequirements);
     }
 
     VkResult on_vkBindImageMemory(
@@ -1736,6 +1809,15 @@
         info.createInfo = *pCreateInfo;
         info.createInfo.pNext = nullptr;
 
+        VkExternalMemoryBufferCreateInfo* extBufCi =
+            (VkExternalMemoryBufferCreateInfo*)vk_find_struct((vk_struct_common*)pCreateInfo,
+                VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO);
+
+        if (!extBufCi) return res;
+
+        info.external = true;
+        info.externalCreateInfo = *extBufCi;
+
         return res;
     }
 
@@ -1751,6 +1833,8 @@
         VkEncoder* enc = (VkEncoder*)context;
         enc->vkGetBufferMemoryRequirements(
             device, buffer, pMemoryRequirements);
+        transformExternalBufferMemoryRequirementsForGuest(
+            buffer, pMemoryRequirements);
     }
 
     void on_vkGetBufferMemoryRequirements2(
@@ -1758,6 +1842,9 @@
         VkMemoryRequirements2* pMemoryRequirements) {
         VkEncoder* enc = (VkEncoder*)context;
         enc->vkGetBufferMemoryRequirements2(device, pInfo, pMemoryRequirements);
+        transformExternalBufferMemoryRequirementsForGuest(
+            pInfo->buffer,
+            &pMemoryRequirements->memoryRequirements);
     }
 
     void on_vkGetBufferMemoryRequirements2KHR(
@@ -1765,6 +1852,9 @@
         VkMemoryRequirements2* pMemoryRequirements) {
         VkEncoder* enc = (VkEncoder*)context;
         enc->vkGetBufferMemoryRequirements2KHR(device, pInfo, pMemoryRequirements);
+        transformExternalBufferMemoryRequirementsForGuest(
+            pInfo->buffer,
+            &pMemoryRequirements->memoryRequirements);
     }
 
     VkResult on_vkBindBufferMemory(