From 872613d9c5b00b93db0eea1c64765ee1d5c1480e Mon Sep 17 00:00:00 2001
From: David Reveman <reveman@google.com>
Date: Mon, 8 Apr 2019 16:15:50 -0400
Subject: [PATCH] Implement GetBufferCollectionPropertiesFUCHSIA

This also fixes the implementation of
GetMemoryZirconHandlePropertiesFUCHSIA.

Test: none
Bug: 111137294
Change-Id: If862823bf0eb555734e5a4528bc9c83d8071a2ff
Merged-In: I2a6ac9132aa591f3410871f3500171a0e8746fd1
---
 system/vulkan/goldfish_vulkan.cpp     | 33 ++++++++++++++++++
 system/vulkan_enc/ResourceTracker.cpp | 50 ++++++++++++++++++++++++++-
 system/vulkan_enc/ResourceTracker.h   |  5 +++
 3 files changed, 87 insertions(+), 1 deletion(-)

diff --git a/system/vulkan/goldfish_vulkan.cpp b/system/vulkan/goldfish_vulkan.cpp
index 3b38994..4539c1b 100644
--- a/system/vulkan/goldfish_vulkan.cpp
+++ b/system/vulkan/goldfish_vulkan.cpp
@@ -161,6 +161,14 @@ SetBufferCollectionConstraintsFUCHSIA(VkDevice /*device*/,
     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 @@ PFN_vkVoidFunction GetInstanceProcAddr(VkInstance instance,
         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)
@@ -440,6 +450,26 @@ VkResult SetBufferCollectionConstraintsFUCHSIA(
 
     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) {
@@ -473,6 +503,9 @@ static PFN_vkVoidFunction GetDeviceProcAddr(VkDevice device, const char* name) {
     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 @@ public:
         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 @@ public:
         (*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 @@ VkResult ResourceTracker::on_vkSetBufferCollectionConstraintsFUCHSIA(
     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 @@ public:
         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(
-- 
GitLab