[vukan] Implement GetBufferCollectionPropertiesFUCHSIA

This also fixes the implementation of
GetMemoryZirconHandlePropertiesFUCHSIA.

Change-Id: I2a6ac9132aa591f3410871f3500171a0e8746fd1
diff --git a/system/vulkan/goldfish_vulkan.cpp b/system/vulkan/goldfish_vulkan.cpp
index 18a9424..f133367 100644
--- a/system/vulkan/goldfish_vulkan.cpp
+++ b/system/vulkan/goldfish_vulkan.cpp
@@ -161,6 +161,14 @@
     AEMU_SCOPED_TRACE("vkstubhal::SetBufferCollectionConstraintsFUCHSIA");
     return VK_SUCCESS;
 }
+
+VkResult
+GetBufferCollectionPropertiesFUCHSIA(VkDevice /*device*/,
+                                     VkBufferCollectionFUCHSIA /*collection*/,
+                                     VkBufferCollectionPropertiesFUCHSIA* /*pProperties*/) {
+    AEMU_SCOPED_TRACE("vkstubhal::GetBufferCollectionPropertiesFUCHSIA");
+    return VK_SUCCESS;
+}
 #endif
 
 PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance,
@@ -195,6 +203,8 @@
         return reinterpret_cast<PFN_vkVoidFunction>(DestroyBufferCollectionFUCHSIA);
     if (strcmp(name, "vkSetBufferCollectionConstraintsFUCHSIA") == 0)
         return reinterpret_cast<PFN_vkVoidFunction>(SetBufferCollectionConstraintsFUCHSIA);
+    if (strcmp(name, "vkGetBufferCollectionPropertiesFUCHSIA") == 0)
+        return reinterpret_cast<PFN_vkVoidFunction>(GetBufferCollectionPropertiesFUCHSIA);
 #endif
     // Per the spec, return NULL if instance is NULL.
     if (!instance)
@@ -436,6 +446,26 @@
 
     return res;
 }
+
+VKAPI_ATTR
+VkResult GetBufferCollectionPropertiesFUCHSIA(
+    VkDevice device,
+    VkBufferCollectionFUCHSIA collection,
+    VkBufferCollectionPropertiesFUCHSIA* pProperties) {
+    AEMU_SCOPED_TRACE("goldfish_vulkan::GetBufferCollectionPropertiesFUCHSIA");
+
+    VK_HOST_CONNECTION(VK_ERROR_DEVICE_LOST)
+
+    if (!hostSupportsVulkan) {
+        return vkstubhal::GetBufferCollectionPropertiesFUCHSIA(device, collection, pProperties);
+    }
+
+    VkResult res = goldfish_vk::ResourceTracker::get()->
+        on_vkGetBufferCollectionPropertiesFUCHSIA(
+            vkEnc, VK_SUCCESS, device, collection, pProperties);
+
+    return res;
+}
 #endif
 
 static PFN_vkVoidFunction GetDeviceProcAddr(VkDevice device, const char* name) {
@@ -469,6 +499,9 @@
     if (!strcmp(name, "vkSetBufferCollectionConstraintsFUCHSIA")) {
         return (PFN_vkVoidFunction)SetBufferCollectionConstraintsFUCHSIA;
     }
+    if (!strcmp(name, "vkGetBufferCollectionPropertiesFUCHSIA")) {
+        return (PFN_vkVoidFunction)GetBufferCollectionPropertiesFUCHSIA;
+    }
 #endif
     if (!strcmp(name, "vkGetDeviceProcAddr")) {
         return (PFN_vkVoidFunction)(GetDeviceProcAddr);
diff --git a/system/vulkan_enc/ResourceTracker.cpp b/system/vulkan_enc/ResourceTracker.cpp
index d3e476b..36c2a6b 100644
--- a/system/vulkan_enc/ResourceTracker.cpp
+++ b/system/vulkan_enc/ResourceTracker.cpp
@@ -1209,7 +1209,7 @@
         for (uint32_t i = 0; i < info.memProps.memoryTypeCount; ++i) {
             if (info.memProps.memoryTypes[i].propertyFlags &
                 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) {
-                pProperties->memoryTypeBits = 1ull << i;
+                pProperties->memoryTypeBits |= 1ull << i;
             }
         }
         return VK_SUCCESS;
@@ -1363,6 +1363,45 @@
         (*sysmem_collection)->SetConstraints(true, constraints);
         return VK_SUCCESS;
     }
+
+    VkResult on_vkGetBufferCollectionPropertiesFUCHSIA(
+        void*, VkResult,
+        VkDevice device,
+        VkBufferCollectionFUCHSIA collection,
+        VkBufferCollectionPropertiesFUCHSIA* pProperties) {
+        auto sysmem_collection = reinterpret_cast<fuchsia::sysmem::BufferCollectionSyncPtr*>(collection);
+        fuchsia::sysmem::BufferCollectionInfo_2 info;
+        zx_status_t status2;
+        zx_status_t status = (*sysmem_collection)->WaitForBuffersAllocated(&status2, &info);
+        if (status != ZX_OK || status2 != ZX_OK) {
+            ALOGE("Failed wait for allocation: %d %d", status, status2);
+            return VK_ERROR_INITIALIZATION_FAILED;
+        }
+        if (!info.settings.has_image_format_constraints) {
+            return VK_ERROR_INITIALIZATION_FAILED;
+        }
+        pProperties->count = info.buffer_count;
+
+        AutoLock lock(mLock);
+
+        auto deviceIt = info_VkDevice.find(device);
+
+        if (deviceIt == info_VkDevice.end()) {
+            return VK_ERROR_INITIALIZATION_FAILED;
+        }
+
+        auto& deviceInfo = deviceIt->second;
+
+        // Device local memory type supported.
+        pProperties->memoryTypeBits = 0;
+        for (uint32_t i = 0; i < deviceInfo.memProps.memoryTypeCount; ++i) {
+            if (deviceInfo.memProps.memoryTypes[i].propertyFlags &
+                VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) {
+                pProperties->memoryTypeBits |= 1ull << i;
+            }
+        }
+        return VK_SUCCESS;
+    }
 #endif
 
     HostMemBlockIndex getOrAllocateHostMemBlockLocked(
@@ -3699,6 +3738,15 @@
     return mImpl->on_vkSetBufferCollectionConstraintsFUCHSIA(
         context, input_result, device, collection, pImageInfo);
 }
+
+VkResult ResourceTracker::on_vkGetBufferCollectionPropertiesFUCHSIA(
+        void* context, VkResult input_result,
+        VkDevice device,
+        VkBufferCollectionFUCHSIA collection,
+        VkBufferCollectionPropertiesFUCHSIA* pProperties) {
+    return mImpl->on_vkGetBufferCollectionPropertiesFUCHSIA(
+        context, input_result, device, collection, pProperties);
+}
 #endif
 
 VkResult ResourceTracker::on_vkGetAndroidHardwareBufferPropertiesANDROID(
diff --git a/system/vulkan_enc/ResourceTracker.h b/system/vulkan_enc/ResourceTracker.h
index 200bfb6..e3189e4 100644
--- a/system/vulkan_enc/ResourceTracker.h
+++ b/system/vulkan_enc/ResourceTracker.h
@@ -249,6 +249,11 @@
         VkDevice device,
         VkBufferCollectionFUCHSIA collection,
         const VkImageCreateInfo* pImageInfo);
+    VkResult on_vkGetBufferCollectionPropertiesFUCHSIA(
+        void* context, VkResult input_result,
+        VkDevice device,
+        VkBufferCollectionFUCHSIA collection,
+        VkBufferCollectionPropertiesFUCHSIA* pProperties);
 #endif
 
     VkResult on_vkGetAndroidHardwareBufferPropertiesANDROID(