[vulkan] host visible virt: virtualize memory types

bug: 111137294
bug: 121420031

An initial test to see if host visible memory virtualization will work,
is whether or not device memory type indices/heaps can be virtualized.

Change-Id: Ie2eb5c4a6601a0d358abd550cf1685521ed76719
diff --git a/system/vulkan_enc/HostVisibleMemoryVirtualization.cpp b/system/vulkan_enc/HostVisibleMemoryVirtualization.cpp
index 01887a3..88fbc6e 100644
--- a/system/vulkan_enc/HostVisibleMemoryVirtualization.cpp
+++ b/system/vulkan_enc/HostVisibleMemoryVirtualization.cpp
@@ -79,6 +79,10 @@
     bool hasDirectMem,
     HostVisibleMemoryVirtualizationInfo* info_out) {
 
+    if (info_out->initialized) return;
+
+    info_out->initialized = true;
+
     info_out->memoryPropertiesSupported =
         canFitVirtualHostVisibleMemoryInfo(memoryProperties);
 
@@ -92,17 +96,18 @@
 
     info_out->virtualizationSupported = true;
 
+    info_out->physicalDevice = physicalDevice;
+    info_out->hostMemoryProperties = *memoryProperties;
+    info_out->guestMemoryProperties = *memoryProperties;
+
     uint32_t typeCount =
         memoryProperties->memoryTypeCount;
     uint32_t heapCount =
         memoryProperties->memoryHeapCount;
 
-    info_out->physicalDevice = physicalDevice;
-    info_out->hostMemoryProperties = *memoryProperties;
-    info_out->guestMemoryProperties = *memoryProperties;
-
     uint32_t firstFreeTypeIndex = typeCount;
     uint32_t firstFreeHeapIndex = heapCount;
+
     for (uint32_t i = 0; i < typeCount; ++i) {
 
         // Set up identity mapping and not-both
@@ -116,7 +121,9 @@
         info_out->memoryTypeBitsShouldAdvertiseBoth[i] = false;
 
         const auto& type = memoryProperties->memoryTypes[i];
+
         if (type.propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
+            uint32_t heapIndex = type.heapIndex;
 
             auto& guestMemoryType =
                 info_out->guestMemoryProperties.memoryTypes[i];
@@ -127,27 +134,28 @@
             auto& newVirtualMemoryHeap =
                 info_out->guestMemoryProperties.memoryHeaps[firstFreeHeapIndex];
 
+            // Remove all references to host visible in the guest memory type at
+            // index i, while transferring them to the new virtual memory type.
             newVirtualMemoryType = type;
 
             // Set this memory type to have a separate heap.
             newVirtualMemoryType.heapIndex = firstFreeHeapIndex;
 
-            // Remove all references to host visible in the guest memory type at
-            // index i, while transferring them to the new virtual memory type.
+            newVirtualMemoryType.propertyFlags =
+                type.propertyFlags &
+                ~(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
+
             guestMemoryType.propertyFlags =
                 type.propertyFlags & \
                 ~(VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT |
                   VK_MEMORY_PROPERTY_HOST_COHERENT_BIT |
                   VK_MEMORY_PROPERTY_HOST_CACHED_BIT);
 
-            // Remove device local from the new virtual memory type.
-            newVirtualMemoryType.propertyFlags =
-                guestMemoryType.propertyFlags &
-                ~(VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
-
             // In the corresponding new memory heap, copy the information over,
             // remove device local flags, and resize it based on what is
             // supported by the PCI device.
+            newVirtualMemoryHeap =
+                memoryProperties->memoryHeaps[heapIndex];
             newVirtualMemoryHeap.flags =
                 newVirtualMemoryHeap.flags &
                 ~(VK_MEMORY_HEAP_DEVICE_LOCAL_BIT);
@@ -170,6 +178,14 @@
             ++firstFreeHeapIndex;
         }
     }
+
+    info_out->guestMemoryProperties.memoryTypeCount = firstFreeTypeIndex;
+    info_out->guestMemoryProperties.memoryHeapCount = firstFreeHeapIndex;
+
+    for (uint32_t i = info_out->guestMemoryProperties.memoryTypeCount; i < VK_MAX_MEMORY_TYPES; ++i) {
+        memset(&info_out->guestMemoryProperties.memoryTypes[i],
+               0x0, sizeof(VkMemoryType));
+    }
 }
 
-} // namespace goldfish_vk
\ No newline at end of file
+} // namespace goldfish_vk