Filter guest VK_EXT_device_memory_report structs from host

... as any PFN_vkDeviceMemoryReportCallbackEXT from the guest can
not be called by the host.

Bug: b/336537515
Test: GfxstreamEnd2EndTests
Test: cts -m CtsDeqpTestCases \
      --module-arg CtsDeqpTestCases:include-filter:dEQP-VK.memory.*
Change-Id: I36af0b6a446fb77b1df4e1f503f829f3aeb41984
diff --git a/common/end2end/GfxstreamEnd2EndTests.cpp b/common/end2end/GfxstreamEnd2EndTests.cpp
index 2481034..9786865 100644
--- a/common/end2end/GfxstreamEnd2EndTests.cpp
+++ b/common/end2end/GfxstreamEnd2EndTests.cpp
@@ -498,7 +498,7 @@
 }
 
 VkExpected<GfxstreamEnd2EndTest::TypicalVkTestEnvironment>
-GfxstreamEnd2EndTest::SetUpTypicalVkTestEnvironment(uint32_t apiVersion) {
+GfxstreamEnd2EndTest::SetUpTypicalVkTestEnvironment(const TypicalVkTestEnvironmentOptions& opts) {
     const auto availableInstanceLayers = vkhpp::enumerateInstanceLayerProperties().value;
     ALOGV("Available instance layers:");
     for (const vkhpp::LayerProperties& layer : availableInstanceLayers) {
@@ -518,9 +518,10 @@
         .applicationVersion = 1,
         .pEngineName = "Gfxstream Testing Engine",
         .engineVersion = 1,
-        .apiVersion = apiVersion,
+        .apiVersion = opts.apiVersion,
     };
     const vkhpp::InstanceCreateInfo instanceCreateInfo{
+        .pNext = opts.instanceCreateInfoPNext ? *opts.instanceCreateInfoPNext : nullptr,
         .pApplicationInfo = &applicationInfo,
         .enabledLayerCount = static_cast<uint32_t>(requestedInstanceLayers.size()),
         .ppEnabledLayerNames = requestedInstanceLayers.data(),
@@ -579,11 +580,17 @@
         .queueCount = 1,
         .pQueuePriorities = &queuePriority,
     };
-    const std::vector<const char*> deviceExtensions = {
+    std::vector<const char*> deviceExtensions = {
         VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME,
         VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME,
     };
+    if (opts.deviceExtensions) {
+        for (const std::string& ext : *opts.deviceExtensions) {
+            deviceExtensions.push_back(ext.c_str());
+        }
+    }
     const vkhpp::DeviceCreateInfo deviceCreateInfo = {
+        .pNext = opts.deviceCreateInfoPNext ? *opts.deviceCreateInfoPNext : nullptr,
         .pQueueCreateInfos = &deviceQueueCreateInfo,
         .queueCreateInfoCount = 1,
         .enabledLayerCount = 0,
diff --git a/common/end2end/GfxstreamEnd2EndTests.h b/common/end2end/GfxstreamEnd2EndTests.h
index f06082f..856024d 100644
--- a/common/end2end/GfxstreamEnd2EndTests.h
+++ b/common/end2end/GfxstreamEnd2EndTests.h
@@ -20,6 +20,7 @@
 
 #include <future>
 #include <memory>
+#include <optional>
 #include <string>
 #include <thread>
 #include <unordered_set>
@@ -464,6 +465,13 @@
 std::vector<TestParams> WithAndWithoutFeatures(const std::vector<TestParams>& params,
                                                const std::vector<std::string>& features);
 
+struct TypicalVkTestEnvironmentOptions {
+    uint32_t apiVersion{VK_API_VERSION_1_2};
+    std::optional<const void*> instanceCreateInfoPNext;
+    std::optional<std::vector<std::string>> deviceExtensions;
+    std::optional<const void*> deviceCreateInfoPNext;
+};
+
 class GfxstreamEnd2EndTest : public ::testing::TestWithParam<TestParams> {
    public:
     std::unique_ptr<GuestGlDispatchTable> SetupGuestGl();
@@ -503,7 +511,7 @@
         uint32_t queueFamilyIndex;
     };
     VkExpected<TypicalVkTestEnvironment> SetUpTypicalVkTestEnvironment(
-        uint32_t apiVersion = VK_API_VERSION_1_2);
+        const TypicalVkTestEnvironmentOptions& opts = {});
 
     uint32_t GetMemoryType(const vkhpp::PhysicalDevice& physicalDevice,
                            const vkhpp::MemoryRequirements& memoryRequirements,
diff --git a/common/end2end/GfxstreamEnd2EndVkTests.cpp b/common/end2end/GfxstreamEnd2EndVkTests.cpp
index 87529ea..d77acbf 100644
--- a/common/end2end/GfxstreamEnd2EndVkTests.cpp
+++ b/common/end2end/GfxstreamEnd2EndVkTests.cpp
@@ -719,6 +719,33 @@
     DoAcquireImageAndroidWithSync(/*withFence=*/true, /*withSemaphore=*/true);
 }
 
+VKAPI_ATTR void VKAPI_CALL MemoryReportCallback(const VkDeviceMemoryReportCallbackDataEXT*, void*) {
+    // Unused
+}
+
+TEST_P(GfxstreamEnd2EndVkTest, DeviceMemoryReport) {
+    int userdata = 1;
+    vkhpp::DeviceDeviceMemoryReportCreateInfoEXT deviceDeviceMemoryReportInfo = {
+        .pfnUserCallback = &MemoryReportCallback,
+        .pUserData = &userdata,
+    };
+
+    auto [instance, physicalDevice, device, queue, queueFamilyIndex] =
+        VK_ASSERT(SetUpTypicalVkTestEnvironment({
+            .deviceExtensions = {{
+                VK_EXT_DEVICE_MEMORY_REPORT_EXTENSION_NAME,
+            }},
+            .deviceCreateInfoPNext = &deviceDeviceMemoryReportInfo,
+        }));
+
+    const vkhpp::MemoryAllocateInfo memoryAllocateInfo = {
+        .allocationSize = 1024,
+        .memoryTypeIndex = 0,
+    };
+    auto memory = device->allocateMemoryUnique(memoryAllocateInfo).value;
+    ASSERT_THAT(memory, IsValidHandle());
+}
+
 std::vector<TestParams> GenerateTestCases() {
     std::vector<TestParams> cases = {TestParams{
                                          .with_gl = false,
diff --git a/host/vulkan/VkDecoderGlobalState.cpp b/host/vulkan/VkDecoderGlobalState.cpp
index cbf7037..87fbe3f 100644
--- a/host/vulkan/VkDecoderGlobalState.cpp
+++ b/host/vulkan/VkDecoderGlobalState.cpp
@@ -162,6 +162,7 @@
     "VK_FUCHSIA_buffer_collection",
     "VK_FUCHSIA_external_memory",
     "VK_FUCHSIA_external_semaphore",
+    VK_EXT_DEVICE_MEMORY_REPORT_EXTENSION_NAME,
     VK_EXT_QUEUE_FAMILY_FOREIGN_EXTENSION_NAME,
     VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME,
     VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME,
@@ -1367,14 +1368,10 @@
     VkResult on_vkCreateDevice(android::base::BumpPool* pool, VkPhysicalDevice boxed_physicalDevice,
                                const VkDeviceCreateInfo* pCreateInfo,
                                const VkAllocationCallbacks* pAllocator, VkDevice* pDevice) {
-        if (mLogging) {
-            fprintf(stderr, "%s: begin\n", __func__);
-        }
-
         auto physicalDevice = unbox_VkPhysicalDevice(boxed_physicalDevice);
         auto vk = dispatch_VkPhysicalDevice(boxed_physicalDevice);
 
-        std::vector<const char*> finalExts =
+        const std::vector<const char*> finalExts =
             filteredDeviceExtensionNames(vk, physicalDevice, pCreateInfo->enabledExtensionCount,
                                          pCreateInfo->ppEnabledExtensionNames);
 
@@ -1426,6 +1423,9 @@
             }
         }
 
+        // Filter device memory report as callbacks can not be passed between guest and host.
+        vk_struct_chain_filter<VkDeviceDeviceMemoryReportCreateInfoEXT>(&createInfoFiltered);
+
         createInfoFiltered.enabledExtensionCount = (uint32_t)finalExts.size();
         createInfoFiltered.ppEnabledExtensionNames = finalExts.data();
 
@@ -1437,29 +1437,14 @@
         std::unique_ptr<std::lock_guard<std::recursive_mutex>> lock = nullptr;
 
         if (swiftshader) {
-            if (mLogging) {
-                fprintf(stderr, "%s: acquire lock\n", __func__);
-            }
             lock = std::make_unique<std::lock_guard<std::recursive_mutex>>(mLock);
         }
 
-        if (mLogging) {
-            fprintf(stderr, "%s: got lock, calling host\n", __func__);
-        }
-
         VkResult result =
             vk->vkCreateDevice(physicalDevice, &createInfoFiltered, pAllocator, pDevice);
 
-        if (mLogging) {
-            fprintf(stderr, "%s: host returned. result: %d\n", __func__, result);
-        }
-
         if (result != VK_SUCCESS) return result;
 
-        if (mLogging) {
-            fprintf(stderr, "%s: track the new device (begin)\n", __func__);
-        }
-
         if (!swiftshader) {
             lock = std::make_unique<std::lock_guard<std::recursive_mutex>>(mLock);
         }
diff --git a/host/vulkan/cereal/common/vk_struct_id.h b/host/vulkan/cereal/common/vk_struct_id.h
index 4294459..284fd44 100644
--- a/host/vulkan/cereal/common/vk_struct_id.h
+++ b/host/vulkan/cereal/common/vk_struct_id.h
@@ -105,5 +105,7 @@
 
 REGISTER_VK_STRUCT_ID(VkImportMemoryHostPointerInfoEXT,
                       VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT);
+REGISTER_VK_STRUCT_ID(VkDeviceDeviceMemoryReportCreateInfoEXT,
+                      VK_STRUCTURE_TYPE_DEVICE_DEVICE_MEMORY_REPORT_CREATE_INFO_EXT);
 
 #undef REGISTER_VK_STRUCT_ID
diff --git a/host/vulkan/vk_util.h b/host/vulkan/vk_util.h
index 4064dd3..2815449 100644
--- a/host/vulkan/vk_util.h
+++ b/host/vulkan/vk_util.h
@@ -277,6 +277,19 @@
     }
 }
 
+template <class TypeToFilter, class H>
+void vk_struct_chain_filter(H* head) {
+    (void)vk_get_vk_struct_id<H>::id;
+
+    auto* curr = reinterpret_cast<vk_struct_common*>(head);
+    while (curr != nullptr) {
+        if (curr->pNext != nullptr && curr->pNext->sType == vk_get_vk_struct_id<TypeToFilter>::id) {
+            curr->pNext = curr->pNext->pNext;
+        }
+        curr = curr->pNext;
+    }
+}
+
 #define VK_CHECK(x)                                                                             \
     do {                                                                                        \
         VkResult err = x;                                                                       \