diff --git a/stream-servers/vulkan/VkCommonOperations.cpp b/stream-servers/vulkan/VkCommonOperations.cpp
new file mode 100644
index 0000000..56d6066
--- /dev/null
+++ b/stream-servers/vulkan/VkCommonOperations.cpp
@@ -0,0 +1,1816 @@
+// Copyright 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expresso or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+#include "VkCommonOperations.h"
+
+#include "android/base/containers/Lookup.h"
+#include "android/base/containers/StaticMap.h"
+#include "android/base/memory/LazyInstance.h"
+#include "android/base/synchronization/Lock.h"
+#include "android/base/Log.h"
+
+#include "FrameBuffer.h"
+#include "VulkanDispatch.h"
+
+#include "common/goldfish_vk_dispatch.h"
+
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <vulkan/vk_enum_string_helper.h>
+
+#include <iomanip>
+#include <ostream>
+#include <sstream>
+
+#include <stdio.h>
+#include <string.h>
+
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include <fcntl.h>
+#endif
+
+#ifdef __APPLE__
+#include <CoreFoundation/CoreFoundation.h>
+#endif
+
+using android::base::AutoLock;
+using android::base::LazyInstance;
+using android::base::StaticLock;
+using android::base::StaticMap;
+
+namespace goldfish_vk {
+
+static LazyInstance<StaticMap<VkDevice, uint32_t>>
+sKnownStagingTypeIndices = LAZY_INSTANCE_INIT;
+
+static android::base::StaticLock sVkEmulationLock;
+
+VK_EXT_MEMORY_HANDLE dupExternalMemory(VK_EXT_MEMORY_HANDLE h) {
+#ifdef _WIN32
+    auto myProcessHandle = GetCurrentProcess();
+    VK_EXT_MEMORY_HANDLE res;
+    DuplicateHandle(
+        myProcessHandle, h, // source process and handle
+        myProcessHandle, &res, // target process and pointer to handle
+        0 /* desired access (ignored) */,
+        true /* inherit */,
+        DUPLICATE_SAME_ACCESS /* same access option */);
+    return res;
+#else
+    return dup(h);
+#endif
+}
+
+bool getStagingMemoryTypeIndex(
+    VulkanDispatch* vk,
+    VkDevice device,
+    const VkPhysicalDeviceMemoryProperties* memProps,
+    uint32_t* typeIndex) {
+
+    auto res = sKnownStagingTypeIndices->get(device);
+
+    if (res) {
+        *typeIndex = *res;
+        return true;
+    }
+
+    VkBufferCreateInfo testCreateInfo = {
+        VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, 0, 0,
+        4096,
+        // To be a staging buffer, it must support being
+        // both a transfer src and dst.
+        VK_BUFFER_USAGE_TRANSFER_DST_BIT |
+        VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
+        // TODO: See if buffers over shared queues need to be
+        // considered separately
+        VK_SHARING_MODE_EXCLUSIVE,
+        0, nullptr,
+    };
+
+    VkBuffer testBuffer;
+    VkResult testBufferCreateRes =
+        vk->vkCreateBuffer(device, &testCreateInfo, nullptr, &testBuffer);
+
+    if (testBufferCreateRes != VK_SUCCESS) {
+        LOG(ERROR) <<
+            "Could not create test buffer "
+            "for staging buffer query. VkResult: " <<
+                testBufferCreateRes;
+        return false;
+    }
+
+    VkMemoryRequirements memReqs;
+    vk->vkGetBufferMemoryRequirements(device, testBuffer, &memReqs);
+
+    // To be a staging buffer, we need to allow CPU read/write access.
+    // Thus, we need the memory type index both to be host visible
+    // and to be supported in the memory requirements of the buffer.
+    bool foundSuitableStagingMemoryType = false;
+    uint32_t stagingMemoryTypeIndex = 0;
+
+    for (uint32_t i = 0; i < VK_MAX_MEMORY_TYPES; ++i) {
+        const auto& typeInfo = memProps->memoryTypes[i];
+        bool hostVisible =
+            typeInfo.propertyFlags & VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
+        bool hostCached =
+            typeInfo.propertyFlags & VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
+        bool allowedInBuffer = (1 << i) & memReqs.memoryTypeBits;
+        if (hostVisible && hostCached && allowedInBuffer) {
+            foundSuitableStagingMemoryType = true;
+            stagingMemoryTypeIndex = i;
+            break;
+        }
+    }
+
+    vk->vkDestroyBuffer(device, testBuffer, nullptr);
+
+    if (!foundSuitableStagingMemoryType) {
+        std::stringstream ss;
+        ss <<
+            "Could not find suitable memory type index " <<
+            "for staging buffer. Memory type bits: " <<
+            std::hex << memReqs.memoryTypeBits << "\n" <<
+            "Available host visible memory type indices:" << "\n";
+        for (uint32_t i = 0; i < VK_MAX_MEMORY_TYPES; ++i) {
+            if (memProps->memoryTypes[i].propertyFlags &
+                VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
+                ss << "Host visible memory type index: %u" << i << "\n";
+            }
+            if (memProps->memoryTypes[i].propertyFlags &
+                VK_MEMORY_PROPERTY_HOST_CACHED_BIT) {
+                ss << "Host cached memory type index: %u" << i << "\n";
+            }
+        }
+
+        LOG(ERROR) << ss.str();
+
+        return false;
+    }
+
+    sKnownStagingTypeIndices->set(device, stagingMemoryTypeIndex);
+    *typeIndex = stagingMemoryTypeIndex;
+
+    return true;
+}
+
+static VkEmulation* sVkEmulation = nullptr;
+
+static bool extensionsSupported(
+    const std::vector<VkExtensionProperties>& currentProps,
+    const std::vector<const char*>& wantedExtNames) {
+
+    std::vector<bool> foundExts(wantedExtNames.size(), false);
+
+    for (uint32_t i = 0; i < currentProps.size(); ++i) {
+        LOG(VERBOSE) << "has extension: " << currentProps[i].extensionName;
+        for (size_t j = 0; j < wantedExtNames.size(); ++j) {
+            if (!strcmp(wantedExtNames[j], currentProps[i].extensionName)) {
+                foundExts[j] = true;
+            }
+        }
+    }
+
+    for (size_t i = 0; i < wantedExtNames.size(); ++i) {
+        bool found = foundExts[i];
+        LOG(VERBOSE) << "needed extension: " << wantedExtNames[i]
+                     << " found: " << found;
+        if (!found) {
+            LOG(VERBOSE) << wantedExtNames[i] << " not found, bailing.";
+            return false;
+        }
+    }
+
+    return true;
+}
+
+// For a given ImageSupportInfo, populates usageWithExternalHandles and
+// requiresDedicatedAllocation. memoryTypeBits are populated later once the
+// device is created, beacuse that needs a test image to be created.
+// If we don't support external memory, it's assumed dedicated allocations are
+// not needed.
+// Precondition: sVkEmulation instance has been created and ext memory caps known.
+// Returns false if the query failed.
+static bool getImageFormatExternalMemorySupportInfo(
+    VulkanDispatch* vk,
+    VkPhysicalDevice physdev,
+    VkEmulation::ImageSupportInfo* info) {
+
+    // Currently there is nothing special we need to do about
+    // VkFormatProperties2, so just use the normal version
+    // and put it in the format2 struct.
+    VkFormatProperties outFormatProps;
+    vk->vkGetPhysicalDeviceFormatProperties(
+            physdev, info->format, &outFormatProps);
+
+    info->formatProps2 = {
+        VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2, 0,
+        outFormatProps,
+    };
+
+    if (!sVkEmulation->instanceSupportsExternalMemoryCapabilities) {
+        info->supportsExternalMemory = false;
+        info->requiresDedicatedAllocation = false;
+
+        VkImageFormatProperties outImageFormatProps;
+        VkResult res = vk->vkGetPhysicalDeviceImageFormatProperties(
+                physdev, info->format, info->type, info->tiling,
+                info->usageFlags, info->createFlags, &outImageFormatProps);
+
+        if (res != VK_SUCCESS) {
+            if (res == VK_ERROR_FORMAT_NOT_SUPPORTED) {
+                info->supported = false;
+                return true;
+            } else {
+                fprintf(stderr,
+                        "%s: vkGetPhysicalDeviceImageFormatProperties query "
+                        "failed with %d "
+                        "for format 0x%x type 0x%x usage 0x%x flags 0x%x\n",
+                        __func__, res, info->format, info->type,
+                        info->usageFlags, info->createFlags);
+                return false;
+            }
+        }
+
+        info->supported = true;
+
+        info->imageFormatProps2 = {
+            VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2, 0,
+            outImageFormatProps,
+        };
+
+        LOG(VERBOSE) << "Supported (not externally): "
+            << string_VkFormat(info->format) << " "
+            << string_VkImageType(info->type) << " "
+            << string_VkImageTiling(info->tiling) << " "
+            << string_VkImageUsageFlagBits(
+                   (VkImageUsageFlagBits)info->usageFlags);
+
+        return true;
+    }
+
+    VkPhysicalDeviceExternalImageFormatInfo extInfo = {
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO, 0,
+        VK_EXT_MEMORY_HANDLE_TYPE_BIT,
+    };
+
+    VkPhysicalDeviceImageFormatInfo2 formatInfo2 = {
+        VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, &extInfo,
+        info->format, info->type, info->tiling,
+        info->usageFlags, info->createFlags,
+    };
+
+    VkExternalImageFormatProperties outExternalProps = {
+        VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES,
+        0,
+        {
+            (VkExternalMemoryFeatureFlags)0,
+            (VkExternalMemoryHandleTypeFlags)0,
+            (VkExternalMemoryHandleTypeFlags)0,
+        },
+    };
+
+    VkImageFormatProperties2 outProps2 = {
+        VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2, &outExternalProps,
+        {
+            { 0, 0, 0},
+            0, 0,
+            1, 0,
+        }
+    };
+
+    VkResult res = sVkEmulation->getImageFormatProperties2Func(
+        physdev,
+        &formatInfo2,
+        &outProps2);
+
+    if (res != VK_SUCCESS) {
+        if (res == VK_ERROR_FORMAT_NOT_SUPPORTED) {
+            info->supported = false;
+            return true;
+        } else {
+            fprintf(stderr,
+                    "%s: vkGetPhysicalDeviceImageFormatProperties2KHR query "
+                    "failed "
+                    "for format 0x%x type 0x%x usage 0x%x flags 0x%x\n",
+                    __func__, info->format, info->type, info->usageFlags,
+                    info->createFlags);
+            return false;
+        }
+    }
+
+    info->supported = true;
+
+    VkExternalMemoryFeatureFlags featureFlags =
+        outExternalProps.externalMemoryProperties.externalMemoryFeatures;
+
+    VkExternalMemoryHandleTypeFlags exportImportedFlags =
+        outExternalProps.externalMemoryProperties.exportFromImportedHandleTypes;
+
+    // Don't really care about export form imported handle types yet
+    (void)exportImportedFlags;
+
+    VkExternalMemoryHandleTypeFlags compatibleHandleTypes =
+        outExternalProps.externalMemoryProperties.compatibleHandleTypes;
+
+    info->supportsExternalMemory =
+        (VK_EXT_MEMORY_HANDLE_TYPE_BIT & compatibleHandleTypes) &&
+        (VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT & featureFlags) &&
+        (VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT & featureFlags);
+
+    info->requiresDedicatedAllocation =
+        (VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT & featureFlags);
+
+    info->imageFormatProps2 = outProps2;
+    info->extFormatProps = outExternalProps;
+    info->imageFormatProps2.pNext = &info->extFormatProps;
+
+    LOG(VERBOSE) << "Supported: "
+                 << string_VkFormat(info->format) << " "
+                 << string_VkImageType(info->type) << " "
+                 << string_VkImageTiling(info->tiling) << " "
+                 << string_VkImageUsageFlagBits(
+                            (VkImageUsageFlagBits)info->usageFlags)
+                 << " "
+                 << "supportsExternalMemory? " << info->supportsExternalMemory
+                 << " "
+                 << "requiresDedicated? " << info->requiresDedicatedAllocation;
+
+    return true;
+}
+
+static std::vector<VkEmulation::ImageSupportInfo> getBasicImageSupportList() {
+    std::vector<VkFormat> formats = {
+        // Cover all the gralloc formats
+        VK_FORMAT_R8G8B8A8_UNORM,
+        VK_FORMAT_R8G8B8_UNORM,
+
+        VK_FORMAT_R5G6B5_UNORM_PACK16,
+
+        VK_FORMAT_R16G16B16A16_SFLOAT,
+        VK_FORMAT_R16G16B16_SFLOAT,
+
+        VK_FORMAT_B8G8R8A8_UNORM,
+
+        VK_FORMAT_R8_UNORM,
+
+        VK_FORMAT_A2R10G10B10_UINT_PACK32,
+        VK_FORMAT_A2R10G10B10_UNORM_PACK32,
+
+        // Compressed texture formats
+        VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
+        VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
+
+        // TODO: YUV formats used in Android
+        // Fails on Mac
+        // VK_FORMAT_G8_B8R8_2PLANE_420_UNORM,
+        // VK_FORMAT_G8_B8R8_2PLANE_422_UNORM,
+    };
+
+    std::vector<VkImageType> types = {
+        VK_IMAGE_TYPE_2D,
+    };
+
+    std::vector<VkImageTiling> tilings = {
+        VK_IMAGE_TILING_LINEAR,
+        VK_IMAGE_TILING_OPTIMAL,
+    };
+
+    std::vector<VkImageUsageFlags> usageFlags = {
+        VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
+        VK_IMAGE_USAGE_SAMPLED_BIT,
+        VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
+        VK_IMAGE_USAGE_TRANSFER_DST_BIT,
+    };
+
+    std::vector<VkImageCreateFlags> createFlags = {
+        0,
+    };
+
+    std::vector<VkEmulation::ImageSupportInfo> res;
+
+    // Currently: 12 formats, 2 tilings, 4 usage flags -> 96 cases
+    // to check
+    for (auto f : formats) {
+        for (auto t : types) {
+            for (auto ti : tilings) {
+                for (auto u : usageFlags) {
+                    for (auto c : createFlags) {
+                        VkEmulation::ImageSupportInfo info;
+                        info.format = f;
+                        info.type = t;
+                        info.tiling = ti;
+                        info.usageFlags = u;
+                        info.createFlags = c;
+                        res.push_back(info);
+                    }
+                }
+            }
+        }
+    }
+
+    return res;
+}
+
+VkEmulation* createOrGetGlobalVkEmulation(VulkanDispatch* vk) {
+    AutoLock lock(sVkEmulationLock);
+
+    if (sVkEmulation) return sVkEmulation;
+
+    if (!emugl::vkDispatchValid(vk)) {
+        return nullptr;
+    }
+
+    sVkEmulation = new VkEmulation;
+
+    sVkEmulation->gvk = vk;
+    auto gvk = vk;
+
+    std::vector<const char*> externalMemoryInstanceExtNames = {
+        "VK_KHR_external_memory_capabilities",
+        "VK_KHR_get_physical_device_properties2",
+    };
+
+    std::vector<const char*> moltenVKInstanceExtNames = {
+        "VK_MVK_moltenvk",
+    };
+
+    std::vector<const char*> externalMemoryDeviceExtNames = {
+        "VK_KHR_dedicated_allocation",
+        "VK_KHR_get_memory_requirements2",
+        "VK_KHR_external_memory",
+#ifdef _WIN32
+        "VK_KHR_external_memory_win32",
+#else
+        "VK_KHR_external_memory_fd",
+#endif
+    };
+
+    uint32_t extCount = 0;
+    gvk->vkEnumerateInstanceExtensionProperties(nullptr, &extCount, nullptr);
+    std::vector<VkExtensionProperties> exts(extCount);
+    gvk->vkEnumerateInstanceExtensionProperties(nullptr, &extCount, exts.data());
+
+    bool externalMemoryCapabilitiesSupported =
+        extensionsSupported(exts, externalMemoryInstanceExtNames);
+    bool moltenVKSupported =
+        extensionsSupported(exts, moltenVKInstanceExtNames);
+
+    VkInstanceCreateInfo instCi = {
+        VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
+        0, 0, nullptr, 0, nullptr,
+        0, nullptr,
+    };
+
+    if (externalMemoryCapabilitiesSupported) {
+        instCi.enabledExtensionCount =
+            externalMemoryInstanceExtNames.size();
+        instCi.ppEnabledExtensionNames =
+            externalMemoryInstanceExtNames.data();
+    }
+
+    if (moltenVKSupported) {
+        // We don't need both moltenVK and external memory. Disable
+        // external memory if moltenVK is supported.
+        externalMemoryCapabilitiesSupported = false;
+        instCi.enabledExtensionCount =
+            moltenVKInstanceExtNames.size();
+        instCi.ppEnabledExtensionNames =
+            moltenVKInstanceExtNames.data();
+   }
+
+    VkResult res = gvk->vkCreateInstance(&instCi, nullptr, &sVkEmulation->instance);
+
+    if (res != VK_SUCCESS) {
+        LOG(ERROR) << "Failed to create Vulkan instance.";
+        return sVkEmulation;
+    }
+
+    sVkEmulation->instanceSupportsExternalMemoryCapabilities =
+        externalMemoryCapabilitiesSupported;
+    sVkEmulation->instanceSupportsMoltenVK = moltenVKSupported;
+
+    // Postcondition: sVkEmulation instance has been created and ext memory caps known.
+
+    // Create instance level dispatch.
+    sVkEmulation->ivk = new VulkanDispatch;
+    init_vulkan_dispatch_from_instance(
+        vk, sVkEmulation->instance, sVkEmulation->ivk);
+
+    auto ivk = sVkEmulation->ivk;
+
+    if (!vulkan_dispatch_check_instance_VK_VERSION_1_0(ivk)) {
+        fprintf(stderr, "%s: Warning: Vulkan 1.0 APIs missing from instance\n", __func__);
+    }
+
+    if (ivk->vkEnumerateInstanceVersion) {
+        uint32_t instanceVersion;
+        VkResult enumInstanceRes = ivk->vkEnumerateInstanceVersion(&instanceVersion);
+        if (enumInstanceRes >= VK_MAKE_VERSION(1, 1, 0)) {
+            if (!vulkan_dispatch_check_instance_VK_VERSION_1_1(ivk)) {
+                fprintf(stderr, "%s: Warning: Vulkan 1.1 APIs missing from instance\n", __func__);
+            }
+        }
+    }
+
+    if (sVkEmulation->instanceSupportsExternalMemoryCapabilities) {
+        sVkEmulation->getImageFormatProperties2Func = reinterpret_cast<
+                PFN_vkGetPhysicalDeviceImageFormatProperties2KHR>(
+                ivk->vkGetInstanceProcAddr(
+                        sVkEmulation->instance,
+                        "vkGetPhysicalDeviceImageFormatProperties2KHR"));
+    }
+
+    if (sVkEmulation->instanceSupportsMoltenVK) {
+        sVkEmulation->useIOSurfaceFunc = reinterpret_cast<PFN_vkUseIOSurfaceMVK>(
+                vk->vkGetInstanceProcAddr(
+                        sVkEmulation->instance, "vkUseIOSurfaceMVK"));
+        if (!sVkEmulation->useIOSurfaceFunc) {
+            LOG(ERROR) << "Cannot find vkUseIOSurfaceMVK";
+            return sVkEmulation;
+        }
+        sVkEmulation->getIOSurfaceFunc = reinterpret_cast<PFN_vkGetIOSurfaceMVK>(
+                ivk->vkGetInstanceProcAddr(
+                        sVkEmulation->instance, "vkGetIOSurfaceMVK"));
+        if (!sVkEmulation->getIOSurfaceFunc) {
+            LOG(ERROR) << "Cannot find vkGetIOSurfaceMVK";
+            return sVkEmulation;
+        }
+        LOG(VERBOSE) << "Instance supports VK_MVK_moltenvk.";
+    }
+
+    uint32_t physdevCount = 0;
+    ivk->vkEnumeratePhysicalDevices(sVkEmulation->instance, &physdevCount,
+                                   nullptr);
+    std::vector<VkPhysicalDevice> physdevs(physdevCount);
+    ivk->vkEnumeratePhysicalDevices(sVkEmulation->instance, &physdevCount,
+                                   physdevs.data());
+
+    LOG(VERBOSE) << "Found " << physdevCount << " Vulkan physical devices.";
+
+    if (physdevCount == 0) {
+        LOG(VERBOSE) << "No physical devices available.";
+        return sVkEmulation;
+    }
+
+    std::vector<VkEmulation::DeviceSupportInfo> deviceInfos(physdevCount);
+
+    for (int i = 0; i < physdevCount; ++i) {
+        ivk->vkGetPhysicalDeviceProperties(physdevs[i],
+                                           &deviceInfos[i].physdevProps);
+
+        LOG(VERBOSE) << "Considering Vulkan physical device " << i << ": "
+                     << deviceInfos[i].physdevProps.deviceName;
+
+        // It's easier to figure out the staging buffer along with
+        // external memories if we have the memory properties on hand.
+        ivk->vkGetPhysicalDeviceMemoryProperties(physdevs[i],
+                                                &deviceInfos[i].memProps);
+
+        uint32_t deviceExtensionCount = 0;
+        ivk->vkEnumerateDeviceExtensionProperties(
+            physdevs[i], nullptr, &deviceExtensionCount, nullptr);
+        std::vector<VkExtensionProperties> deviceExts(deviceExtensionCount);
+        ivk->vkEnumerateDeviceExtensionProperties(
+            physdevs[i], nullptr, &deviceExtensionCount, deviceExts.data());
+
+        deviceInfos[i].supportsExternalMemory = false;
+        deviceInfos[i].glInteropSupported =
+            FrameBuffer::getFB()->isVulkanInteropSupported();
+
+        if (sVkEmulation->instanceSupportsExternalMemoryCapabilities) {
+            deviceInfos[i].supportsExternalMemory = extensionsSupported(
+                    deviceExts, externalMemoryDeviceExtNames);
+        }
+
+        uint32_t queueFamilyCount = 0;
+        ivk->vkGetPhysicalDeviceQueueFamilyProperties(
+                physdevs[i], &queueFamilyCount, nullptr);
+        std::vector<VkQueueFamilyProperties> queueFamilyProps(queueFamilyCount);
+        ivk->vkGetPhysicalDeviceQueueFamilyProperties(
+                physdevs[i], &queueFamilyCount, queueFamilyProps.data());
+
+        for (uint32_t j = 0; j < queueFamilyCount; ++j) {
+            auto count = queueFamilyProps[j].queueCount;
+            auto flags = queueFamilyProps[j].queueFlags;
+
+            bool hasGraphicsQueueFamily =
+                (count > 0 && (flags & VK_QUEUE_GRAPHICS_BIT));
+            bool hasComputeQueueFamily =
+                (count > 0 && (flags & VK_QUEUE_COMPUTE_BIT));
+
+            deviceInfos[i].hasGraphicsQueueFamily =
+                deviceInfos[i].hasGraphicsQueueFamily ||
+                hasGraphicsQueueFamily;
+
+            deviceInfos[i].hasComputeQueueFamily =
+                deviceInfos[i].hasComputeQueueFamily ||
+                hasComputeQueueFamily;
+
+            if (hasGraphicsQueueFamily) {
+                deviceInfos[i].graphicsQueueFamilyIndices.push_back(j);
+                LOG(VERBOSE) << "Graphics queue family index: " << j;
+            }
+
+            if (hasComputeQueueFamily) {
+                deviceInfos[i].computeQueueFamilyIndices.push_back(j);
+                LOG(VERBOSE) << "Compute queue family index: " << j;
+            }
+        }
+    }
+
+    // Of all the devices enumerated, find the best one. Try to find a device
+    // with graphics queue as the highest priority, then ext memory, then
+    // compute.
+
+    // Graphics queue is highest priority since without that, we really
+    // shouldn't be using the driver. Although, one could make a case for doing
+    // some sorts of things if only a compute queue is available (such as for
+    // AI), that's not really the priority yet.
+
+    // As for external memory, we really should not be running on any driver
+    // without external memory support, but we might be able to pull it off, and
+    // single Vulkan apps might work via CPU transfer of the rendered frames.
+
+    // Compute support is treated as icing on the cake and not relied upon yet
+    // for anything critical to emulation. However, we might potentially use it
+    // to perform image format conversion on GPUs where that's not natively
+    // supported.
+
+    // Another implicit choice is to select only one Vulkan device. This makes
+    // things simple for now, but we could consider utilizing multiple devices
+    // in use cases that make sense, if/when they come up.
+
+    std::vector<uint32_t> deviceScores(physdevCount, 0);
+
+    for (uint32_t i = 0; i < physdevCount; ++i) {
+        uint32_t deviceScore = 0;
+        if (deviceInfos[i].hasGraphicsQueueFamily) deviceScore += 100;
+        if (deviceInfos[i].supportsExternalMemory) deviceScore += 10;
+        if (deviceInfos[i].hasComputeQueueFamily) deviceScore += 1;
+        deviceScores[i] = deviceScore;
+    }
+
+    uint32_t maxScoringIndex = 0;
+    uint32_t maxScore = 0;
+
+    for (uint32_t i = 0; i < physdevCount; ++i) {
+        if (deviceScores[i] > maxScore) {
+            maxScoringIndex = i;
+            maxScore = deviceScores[i];
+        }
+    }
+
+    sVkEmulation->physdev = physdevs[maxScoringIndex];
+    sVkEmulation->deviceInfo = deviceInfos[maxScoringIndex];
+
+    // Postcondition: sVkEmulation has valid device support info
+
+    // Ask about image format support here.
+    // TODO: May have to first ask when selecting physical devices
+    // (e.g., choose between Intel or NVIDIA GPU for certain image format
+    // support)
+    sVkEmulation->imageSupportInfo = getBasicImageSupportList();
+    for (size_t i = 0; i < sVkEmulation->imageSupportInfo.size(); ++i) {
+        getImageFormatExternalMemorySupportInfo(
+                ivk, sVkEmulation->physdev, &sVkEmulation->imageSupportInfo[i]);
+    }
+
+    if (!sVkEmulation->deviceInfo.hasGraphicsQueueFamily) {
+        LOG(VERBOSE) << "No Vulkan devices with graphics queues found.";
+        return sVkEmulation;
+    }
+
+    auto deviceVersion = sVkEmulation->deviceInfo.physdevProps.apiVersion;
+
+    LOG(VERBOSE) << "Vulkan device found: "
+                 << sVkEmulation->deviceInfo.physdevProps.deviceName;
+    LOG(VERBOSE) << "Version: "
+                 << VK_VERSION_MAJOR(deviceVersion) << "." << VK_VERSION_MINOR(deviceVersion) << "." << VK_VERSION_PATCH(deviceVersion);
+    LOG(VERBOSE) << "Has graphics queue? "
+                 << sVkEmulation->deviceInfo.hasGraphicsQueueFamily;
+    LOG(VERBOSE) << "Has external memory support? "
+                 << sVkEmulation->deviceInfo.supportsExternalMemory;
+    LOG(VERBOSE) << "Has compute queue? "
+                 << sVkEmulation->deviceInfo.hasComputeQueueFamily;
+
+    float priority = 1.0f;
+    VkDeviceQueueCreateInfo dqCi = {
+        VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, 0, 0,
+        sVkEmulation->deviceInfo.graphicsQueueFamilyIndices[0],
+        1, &priority,
+    };
+
+    uint32_t selectedDeviceExtensionCount = 0;
+    const char* const* selectedDeviceExtensionNames = nullptr;
+
+    if (sVkEmulation->deviceInfo.supportsExternalMemory) {
+        selectedDeviceExtensionCount = externalMemoryDeviceExtNames.size();
+        selectedDeviceExtensionNames = externalMemoryDeviceExtNames.data();
+    }
+
+    VkDeviceCreateInfo dCi = {
+        VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, 0, 0,
+        // TODO: add compute queue as well if appropriate
+        1, &dqCi,
+        0, nullptr, // no layers
+        selectedDeviceExtensionCount,
+        selectedDeviceExtensionNames, // no layers
+        nullptr, // no features
+    };
+
+    ivk->vkCreateDevice(sVkEmulation->physdev, &dCi, nullptr,
+                        &sVkEmulation->device);
+
+    if (res != VK_SUCCESS) {
+        LOG(ERROR) << "Failed to create Vulkan device.";
+        return sVkEmulation;
+    }
+
+    // device created; populate dispatch table
+    sVkEmulation->dvk = new VulkanDispatch;
+    init_vulkan_dispatch_from_device(
+        ivk, sVkEmulation->device, sVkEmulation->dvk);
+
+    auto dvk = sVkEmulation->dvk;
+
+    // Check if the dispatch table has everything 1.1 related
+    if (!vulkan_dispatch_check_device_VK_VERSION_1_0(dvk)) {
+        fprintf(stderr, "%s: Warning: Vulkan 1.0 APIs missing from device.\n", __func__);
+    }
+    if (deviceVersion >= VK_MAKE_VERSION(1, 1, 0)) {
+        if (!vulkan_dispatch_check_device_VK_VERSION_1_1(dvk)) {
+            fprintf(stderr, "%s: Warning: Vulkan 1.1 APIs missing from device\n", __func__);
+        }
+    }
+
+    if (sVkEmulation->deviceInfo.supportsExternalMemory) {
+        sVkEmulation->deviceInfo.getImageMemoryRequirements2Func =
+            reinterpret_cast<PFN_vkGetImageMemoryRequirements2KHR>(
+                dvk->vkGetDeviceProcAddr(
+                    sVkEmulation->device, "vkGetImageMemoryRequirements2KHR"));
+        if (!sVkEmulation->deviceInfo.getImageMemoryRequirements2Func) {
+            LOG(ERROR) << "Cannot find vkGetImageMemoryRequirements2KHR";
+            return sVkEmulation;
+        }
+        sVkEmulation->deviceInfo.getBufferMemoryRequirements2Func =
+            reinterpret_cast<PFN_vkGetBufferMemoryRequirements2KHR>(
+                dvk->vkGetDeviceProcAddr(
+                    sVkEmulation->device, "vkGetBufferMemoryRequirements2KHR"));
+        if (!sVkEmulation->deviceInfo.getBufferMemoryRequirements2Func) {
+            LOG(ERROR) << "Cannot find vkGetBufferMemoryRequirements2KHR";
+            return sVkEmulation;
+        }
+#ifdef _WIN32
+        sVkEmulation->deviceInfo.getMemoryHandleFunc =
+                reinterpret_cast<PFN_vkGetMemoryWin32HandleKHR>(
+                        dvk->vkGetDeviceProcAddr(sVkEmulation->device,
+                                                "vkGetMemoryWin32HandleKHR"));
+#else
+        sVkEmulation->deviceInfo.getMemoryHandleFunc =
+                reinterpret_cast<PFN_vkGetMemoryFdKHR>(
+                        dvk->vkGetDeviceProcAddr(sVkEmulation->device,
+                                                "vkGetMemoryFdKHR"));
+#endif
+        if (!sVkEmulation->deviceInfo.getMemoryHandleFunc) {
+            LOG(ERROR) << "Cannot find vkGetMemory(Fd|Win32Handle)KHR";
+            return sVkEmulation;
+        }
+    }
+
+    LOG(VERBOSE) << "Vulkan logical device created and extension functions obtained.\n";
+
+    dvk->vkGetDeviceQueue(
+            sVkEmulation->device,
+            sVkEmulation->deviceInfo.graphicsQueueFamilyIndices[0], 0,
+            &sVkEmulation->queue);
+
+    sVkEmulation->queueFamilyIndex =
+            sVkEmulation->deviceInfo.graphicsQueueFamilyIndices[0];
+
+    LOG(VERBOSE) << "Vulkan device queue obtained.";
+
+    VkCommandPoolCreateInfo poolCi = {
+        VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, 0,
+        VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT,
+        sVkEmulation->queueFamilyIndex,
+    };
+
+    VkResult poolCreateRes = dvk->vkCreateCommandPool(
+            sVkEmulation->device, &poolCi, nullptr, &sVkEmulation->commandPool);
+
+    if (poolCreateRes != VK_SUCCESS) {
+        LOG(ERROR) << "Failed to create command pool. Error: " << poolCreateRes;
+        return sVkEmulation;
+    }
+
+    VkCommandBufferAllocateInfo cbAi = {
+        VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, 0,
+        sVkEmulation->commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY, 1,
+    };
+
+    VkResult cbAllocRes = dvk->vkAllocateCommandBuffers(
+            sVkEmulation->device, &cbAi, &sVkEmulation->commandBuffer);
+
+    if (cbAllocRes != VK_SUCCESS) {
+        LOG(ERROR) << "Failed to allocate command buffer. Error: " << cbAllocRes;
+        return sVkEmulation;
+    }
+
+    VkFenceCreateInfo fenceCi = {
+        VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, 0, 0,
+    };
+
+    VkResult fenceCreateRes = dvk->vkCreateFence(
+        sVkEmulation->device, &fenceCi, nullptr,
+        &sVkEmulation->commandBufferFence);
+
+    if (fenceCreateRes != VK_SUCCESS) {
+        LOG(ERROR) << "Failed to create fence for command buffer. Error: " << fenceCreateRes;
+        return sVkEmulation;
+    }
+
+    // At this point, the global emulation state's logical device can alloc
+    // memory and send commands. However, it can't really do much yet to
+    // communicate the results without the staging buffer. Set that up here.
+    // Note that the staging buffer is meant to use external memory, with a
+    // non-external-memory fallback.
+
+    VkBufferCreateInfo bufCi = {
+        VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, 0, 0,
+        sVkEmulation->staging.size,
+        VK_BUFFER_USAGE_TRANSFER_DST_BIT |
+        VK_BUFFER_USAGE_TRANSFER_SRC_BIT,
+        VK_SHARING_MODE_EXCLUSIVE,
+        0, nullptr,
+    };
+
+    VkResult bufCreateRes =
+            dvk->vkCreateBuffer(sVkEmulation->device, &bufCi, nullptr,
+                               &sVkEmulation->staging.buffer);
+
+    if (bufCreateRes != VK_SUCCESS) {
+        LOG(ERROR) << "Failed to create staging buffer index";
+        return sVkEmulation;
+    }
+
+    VkMemoryRequirements memReqs;
+    dvk->vkGetBufferMemoryRequirements(sVkEmulation->device,
+                                      sVkEmulation->staging.buffer, &memReqs);
+
+    sVkEmulation->staging.memory.size = memReqs.size;
+
+    bool gotStagingTypeIndex = getStagingMemoryTypeIndex(
+            dvk, sVkEmulation->device, &sVkEmulation->deviceInfo.memProps,
+            &sVkEmulation->staging.memory.typeIndex);
+
+    if (!gotStagingTypeIndex) {
+        LOG(ERROR) << "Failed to determine staging memory type index";
+        return sVkEmulation;
+    }
+
+    if (!((1 << sVkEmulation->staging.memory.typeIndex) &
+          memReqs.memoryTypeBits)) {
+        LOG(ERROR) << "Failed: Inconsistent determination of memory type "
+                        "index for staging buffer";
+        return sVkEmulation;
+    }
+
+    if (!allocExternalMemory(dvk, &sVkEmulation->staging.memory, false /* not external */)) {
+        LOG(ERROR) << "Failed to allocate memory for staging buffer";
+        return sVkEmulation;
+    }
+
+    VkResult stagingBufferBindRes = dvk->vkBindBufferMemory(
+        sVkEmulation->device,
+        sVkEmulation->staging.buffer,
+        sVkEmulation->staging.memory.memory, 0);
+
+    if (stagingBufferBindRes != VK_SUCCESS) {
+        LOG(ERROR) << "Failed to bind memory for staging buffer";
+        return sVkEmulation;
+    }
+
+    LOG(VERBOSE) << "Vulkan global emulation state successfully initialized.";
+    sVkEmulation->live = true;
+
+    return sVkEmulation;
+}
+
+void setUseDeferredCommands(VkEmulation* emu, bool useDeferredCommands) {
+    if (!emu) return;
+    if (!emu->live) return;
+
+    LOG(VERBOSE) << "Using deferred Vulkan commands: " << useDeferredCommands;
+    emu->useDeferredCommands = useDeferredCommands;
+}
+
+void setUseCreateResourcesWithRequirements(VkEmulation* emu, bool useCreateResourcesWithRequirements) {
+    if (!emu) return;
+    if (!emu->live) return;
+
+    LOG(VERBOSE) << "Using deferred Vulkan commands: " << useCreateResourcesWithRequirements;
+    emu->useCreateResourcesWithRequirements = useCreateResourcesWithRequirements;
+}
+
+VkEmulation* getGlobalVkEmulation() {
+    if (sVkEmulation && !sVkEmulation->live) return nullptr;
+    return sVkEmulation;
+}
+
+void teardownGlobalVkEmulation() {
+    if (!sVkEmulation) return;
+
+    // Don't try to tear down something that did not set up completely; too risky
+    if (!sVkEmulation->live) return;
+
+    freeExternalMemory(sVkEmulation->dvk, &sVkEmulation->staging.memory);
+
+    sVkEmulation->ivk->vkDestroyDevice(sVkEmulation->device, nullptr);
+    sVkEmulation->gvk->vkDestroyInstance(sVkEmulation->instance, nullptr);
+}
+
+// Precondition: sVkEmulation has valid device support info
+bool allocExternalMemory(
+    VulkanDispatch* vk, VkEmulation::ExternalMemoryInfo* info,
+    bool actuallyExternal) {
+
+    VkExportMemoryAllocateInfo exportAi = {
+        VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO, 0,
+        VK_EXT_MEMORY_HANDLE_TYPE_BIT,
+    };
+
+    VkExportMemoryAllocateInfo* exportAiPtr = nullptr;
+
+    if (sVkEmulation->deviceInfo.supportsExternalMemory &&
+        actuallyExternal) {
+        exportAiPtr = &exportAi;
+    }
+
+    VkMemoryAllocateInfo allocInfo = {
+        VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
+        exportAiPtr,
+        info->size,
+        info->typeIndex,
+    };
+
+    VkResult allocRes = vk->vkAllocateMemory(
+        sVkEmulation->device,
+        &allocInfo, nullptr,
+        &info->memory);
+
+    if (allocRes != VK_SUCCESS) {
+        LOG(VERBOSE) << "allocExternalMemory: failed in vkAllocateMemory: "
+                     << allocRes;
+        return false;
+    }
+
+    if (sVkEmulation->deviceInfo
+            .memProps
+            .memoryTypes[info->typeIndex]
+            .propertyFlags &
+        VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
+        VkResult mapRes = vk->vkMapMemory(sVkEmulation->device, info->memory, 0,
+                                          info->size, 0, &info->mappedPtr);
+        if (mapRes != VK_SUCCESS) {
+            LOG(VERBOSE) << "allocExternalMemory: failed in vkMapMemory: "
+                         << mapRes;
+            return false;
+        }
+    }
+
+    if (!sVkEmulation->deviceInfo.supportsExternalMemory ||
+        !actuallyExternal) {
+        return true;
+    }
+
+#ifdef _WIN32
+    VkMemoryGetWin32HandleInfoKHR getWin32HandleInfo = {
+        VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR, 0,
+        info->memory, VK_EXT_MEMORY_HANDLE_TYPE_BIT,
+    };
+    VkResult exportRes =
+        sVkEmulation->deviceInfo.getMemoryHandleFunc(
+            sVkEmulation->device, &getWin32HandleInfo,
+            &info->exportedHandle);
+#else
+    VkMemoryGetFdInfoKHR getFdInfo = {
+        VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR, 0,
+        info->memory, VK_EXT_MEMORY_HANDLE_TYPE_BIT,
+    };
+    VkResult exportRes =
+        sVkEmulation->deviceInfo.getMemoryHandleFunc(
+            sVkEmulation->device, &getFdInfo,
+            &info->exportedHandle);
+#endif
+
+    if (exportRes != VK_SUCCESS) {
+        LOG(VERBOSE) << "allocExternalMemory: Failed to get external memory "
+                        "native handle: "
+                     << exportRes;
+        return false;
+    }
+
+    info->actuallyExternal = true;
+
+    return true;
+}
+
+void freeExternalMemory(VulkanDispatch* vk,
+                        VkEmulation::ExternalMemoryInfo* info) {
+    if (!info->memory)
+        return;
+
+    if (sVkEmulation->deviceInfo.memProps.memoryTypes[info->typeIndex]
+                .propertyFlags &
+        VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT) {
+        vk->vkUnmapMemory(sVkEmulation->device, info->memory);
+        info->mappedPtr = nullptr;
+    }
+
+    vk->vkFreeMemory(sVkEmulation->device, info->memory, nullptr);
+
+    info->memory = VK_NULL_HANDLE;
+
+    if (info->exportedHandle != VK_EXT_MEMORY_HANDLE_INVALID) {
+#ifdef _WIN32
+        CloseHandle(info->exportedHandle);
+#else
+        close(info->exportedHandle);
+#endif
+        info->exportedHandle = VK_EXT_MEMORY_HANDLE_INVALID;
+    }
+}
+
+bool importExternalMemory(VulkanDispatch* vk,
+                          VkDevice targetDevice,
+                          const VkEmulation::ExternalMemoryInfo* info,
+                          VkDeviceMemory* out) {
+#ifdef _WIN32
+    VkImportMemoryWin32HandleInfoKHR importInfo = {
+        VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR, 0,
+        VK_EXT_MEMORY_HANDLE_TYPE_BIT,
+        info->exportedHandle,
+        0,
+    };
+#else
+    VkImportMemoryFdInfoKHR importInfo = {
+        VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR, 0,
+        VK_EXT_MEMORY_HANDLE_TYPE_BIT,
+        dupExternalMemory(info->exportedHandle),
+    };
+#endif
+    VkMemoryAllocateInfo allocInfo = {
+        VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
+        &importInfo,
+        info->size,
+        info->typeIndex,
+    };
+
+    VkResult res = vk->vkAllocateMemory(targetDevice, &allocInfo, nullptr, out);
+
+    if (res != VK_SUCCESS) {
+        LOG(ERROR) << "importExternalMemory: Failed with " << res;
+        return false;
+    }
+
+    return true;
+}
+
+bool importExternalMemoryDedicatedImage(
+    VulkanDispatch* vk,
+    VkDevice targetDevice,
+    const VkEmulation::ExternalMemoryInfo* info,
+    VkImage image,
+    VkDeviceMemory* out) {
+
+    VkMemoryDedicatedAllocateInfo dedicatedInfo = {
+        VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO, 0,
+        image,
+        VK_NULL_HANDLE,
+    };
+
+#ifdef _WIN32
+    VkImportMemoryWin32HandleInfoKHR importInfo = {
+        VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR,
+        &dedicatedInfo,
+        VK_EXT_MEMORY_HANDLE_TYPE_BIT,
+        info->exportedHandle,
+        0,
+    };
+#else
+    VkImportMemoryFdInfoKHR importInfo = {
+        VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR,
+        &dedicatedInfo,
+        VK_EXT_MEMORY_HANDLE_TYPE_BIT,
+        info->exportedHandle,
+    };
+#endif
+    VkMemoryAllocateInfo allocInfo = {
+        VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO,
+        &importInfo,
+        info->size,
+        info->typeIndex,
+    };
+
+    VkResult res = vk->vkAllocateMemory(targetDevice, &allocInfo, nullptr, out);
+
+    if (res != VK_SUCCESS) {
+        LOG(ERROR) << "importExternalMemoryDedicatedImage: Failed with " << res;
+        return false;
+    }
+
+    return true;
+}
+
+static VkFormat glFormat2VkFormat(GLint internalformat) {
+    switch (internalformat) {
+        case GL_LUMINANCE:
+            return VK_FORMAT_R8_UNORM;
+        case GL_RGB:
+        case GL_RGB8:
+            return VK_FORMAT_R8G8B8_UNORM;
+        case GL_RGB565:
+            return VK_FORMAT_R5G6B5_UNORM_PACK16;
+        case GL_RGB16F:
+            return VK_FORMAT_R16G16B16_SFLOAT;
+        case GL_RGBA:
+        case GL_RGBA8:
+            return VK_FORMAT_R8G8B8A8_UNORM;
+        case GL_RGB5_A1_OES:
+            return VK_FORMAT_A1R5G5B5_UNORM_PACK16;
+        case GL_RGBA4_OES:
+            return VK_FORMAT_R4G4B4A4_UNORM_PACK16;
+        case GL_RGB10_A2:
+        case GL_UNSIGNED_INT_10_10_10_2_OES:
+            return VK_FORMAT_A2R10G10B10_UNORM_PACK32;
+        case GL_RGBA16F:
+            return VK_FORMAT_R16G16B16A16_SFLOAT;
+        case GL_BGRA_EXT:
+        case GL_BGRA8_EXT:
+            return VK_FORMAT_B8G8R8A8_UNORM;;
+        default:
+            return VK_FORMAT_R8G8B8A8_UNORM;
+    }
+};
+
+bool isColorBufferVulkanCompatible(uint32_t colorBufferHandle) {
+    auto fb = FrameBuffer::getFB();
+
+    int width;
+    int height;
+    GLint internalformat;
+
+    if (!fb->getColorBufferInfo(colorBufferHandle, &width, &height,
+                                &internalformat)) {
+        return false;
+    }
+
+    VkFormat vkFormat = glFormat2VkFormat(internalformat);
+
+    for (const auto& supportInfo : sVkEmulation->imageSupportInfo) {
+        if (supportInfo.format == vkFormat && supportInfo.supported) {
+            return true;
+        }
+    }
+
+    return false;
+}
+
+static uint32_t lastGoodTypeIndex(uint32_t indices) {
+    for (uint32_t i = 31; i >= 0; --i) {
+        if (indices & (1 << i)) {
+            return i;
+        }
+    }
+    return 0;
+}
+
+bool setupVkColorBuffer(uint32_t colorBufferHandle, bool vulkanOnly, bool* exported, VkDeviceSize* allocSize) {
+    if (!isColorBufferVulkanCompatible(colorBufferHandle)) return false;
+
+    auto vk = sVkEmulation->dvk;
+
+    auto fb = FrameBuffer::getFB();
+
+    int width;
+    int height;
+    GLint internalformat;
+
+    if (!fb->getColorBufferInfo(colorBufferHandle, &width, &height,
+                                &internalformat)) {
+        return false;
+    }
+
+    AutoLock lock(sVkEmulationLock);
+
+    auto infoPtr = android::base::find(sVkEmulation->colorBuffers, colorBufferHandle);
+
+    // Already setup
+    if (infoPtr) {
+        // Update the allocation size to what the host driver wanted, or we
+        // might get VK_ERROR_OUT_OF_DEVICE_MEMORY and a host crash
+        if (allocSize) *allocSize = infoPtr->memory.size;
+        return true;
+    }
+
+    VkFormat vkFormat = glFormat2VkFormat(internalformat);
+
+    VkEmulation::ColorBufferInfo res;
+
+    res.handle = colorBufferHandle;
+
+    // TODO
+    res.frameworkFormat = 0;
+    res.frameworkStride = 0;
+
+    res.extent = { (uint32_t)width, (uint32_t)height, 1 };
+    res.format = vkFormat;
+    res.type = VK_IMAGE_TYPE_2D;
+    res.tiling = VK_IMAGE_TILING_OPTIMAL;
+    res.usageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
+                     VK_IMAGE_USAGE_SAMPLED_BIT |
+                     VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
+                     VK_IMAGE_USAGE_TRANSFER_DST_BIT;
+    res.createFlags = 0;
+
+    res.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
+
+    // Create the image. If external memory is supported, make it external.
+    VkExternalMemoryImageCreateInfo extImageCi = {
+        VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO, 0,
+        VK_EXT_MEMORY_HANDLE_TYPE_BIT,
+    };
+
+    VkExternalMemoryImageCreateInfo* extImageCiPtr = nullptr;
+
+    if (sVkEmulation->deviceInfo.supportsExternalMemory) {
+        extImageCiPtr = &extImageCi;
+    }
+
+    VkImageCreateInfo imageCi = {
+         VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, extImageCiPtr,
+         res.createFlags,
+         res.type,
+         res.format,
+         res.extent,
+         1, 1,
+         VK_SAMPLE_COUNT_1_BIT,
+         res.tiling,
+         res.usageFlags,
+         VK_SHARING_MODE_EXCLUSIVE, 0, nullptr,
+         VK_IMAGE_LAYOUT_UNDEFINED,
+    };
+
+    VkResult createRes = vk->vkCreateImage(sVkEmulation->device, &imageCi,
+                                           nullptr, &res.image);
+    if (createRes != VK_SUCCESS) {
+        LOG(VERBOSE) << "Failed to create Vulkan image for ColorBuffer "
+                     << colorBufferHandle;
+        return false;
+    }
+
+    vk->vkGetImageMemoryRequirements(sVkEmulation->device, res.image,
+                                     &res.memReqs);
+
+    res.memory.size = res.memReqs.size;
+    res.memory.typeIndex = lastGoodTypeIndex(res.memReqs.memoryTypeBits);
+
+    LOG(VERBOSE) << "ColorBuffer " << colorBufferHandle
+                 << "allocation size and type index: " << res.memory.size
+                 << ", " << res.memory.typeIndex;
+
+    bool allocRes = allocExternalMemory(vk, &res.memory);
+
+    if (!allocRes) {
+        LOG(VERBOSE) << "Failed to allocate ColorBuffer with Vulkan backing.";
+    }
+
+    VkResult bindImageMemoryRes =
+        vk->vkBindImageMemory(sVkEmulation->device, res.image, res.memory.memory, 0);
+
+    if (bindImageMemoryRes != VK_SUCCESS) {
+        fprintf(stderr, "%s: Failed to bind image memory. %d\n", __func__,
+        bindImageMemoryRes);
+        return bindImageMemoryRes;
+    }
+
+    if (sVkEmulation->instanceSupportsMoltenVK) {
+        // Create IOSurface by passing null surface argument.
+        VkResult useIOSurfaceRes = sVkEmulation->useIOSurfaceFunc(res.image, nullptr);
+        if (useIOSurfaceRes != VK_SUCCESS) {
+            fprintf(stderr, "%s: Failed to create IOSurface. %d\n", __func__,
+                    useIOSurfaceRes);
+            return false;
+        }
+        // Retrieve a reference to the IOSurface created above.
+        sVkEmulation->getIOSurfaceFunc(res.image, &res.ioSurface);
+        if (!res.ioSurface) {
+            fprintf(stderr, "%s: Failed to get IOSurface.\n", __func__);
+            return false;
+        }
+#ifdef __APPLE__
+        CFRetain(res.ioSurface);
+#endif
+    }
+
+    if (sVkEmulation->deviceInfo.supportsExternalMemory &&
+        sVkEmulation->deviceInfo.glInteropSupported &&
+        FrameBuffer::getFB()->importMemoryToColorBuffer(
+            dupExternalMemory(res.memory.exportedHandle),
+            res.memory.size,
+            false /* dedicated */,
+            res.tiling == VK_IMAGE_TILING_LINEAR,
+            vulkanOnly,
+            colorBufferHandle)) {
+        res.glExported = true;
+    }
+
+    if (exported) *exported = res.glExported;
+    if (allocSize) *allocSize = res.memory.size;
+
+    sVkEmulation->colorBuffers[colorBufferHandle] = res;
+
+    return allocRes;
+}
+
+bool teardownVkColorBuffer(uint32_t colorBufferHandle) {
+    if (!sVkEmulation || !sVkEmulation->live) return false;
+
+    auto vk = sVkEmulation->dvk;
+
+    AutoLock lock(sVkEmulationLock);
+
+    auto infoPtr = android::base::find(sVkEmulation->colorBuffers, colorBufferHandle);
+
+    if (!infoPtr) return false;
+
+    auto& info = *infoPtr;
+
+    vk->vkDestroyImage(sVkEmulation->device, info.image, nullptr);
+    freeExternalMemory(vk, &info.memory);
+
+#ifdef __APPLE__
+    if (info.ioSurface) {
+        CFRelease(info.ioSurface);
+    }
+#endif
+
+    sVkEmulation->colorBuffers.erase(colorBufferHandle);
+
+    return true;
+}
+
+VkEmulation::ColorBufferInfo getColorBufferInfo(uint32_t colorBufferHandle) {
+    VkEmulation::ColorBufferInfo res;
+
+    AutoLock lock(sVkEmulationLock);
+
+    auto infoPtr = android::base::find(sVkEmulation->colorBuffers, colorBufferHandle);
+
+    if (!infoPtr) return res;
+
+    res = *infoPtr;
+    return res;
+}
+
+bool updateColorBufferFromVkImage(uint32_t colorBufferHandle) {
+    if (!sVkEmulation || !sVkEmulation->live) return false;
+
+    auto vk = sVkEmulation->dvk;
+
+    AutoLock lock(sVkEmulationLock);
+
+    auto infoPtr = android::base::find(sVkEmulation->colorBuffers, colorBufferHandle);
+
+    if (!infoPtr) {
+        // Color buffer not found; this is usually OK.
+        return false;
+    }
+
+    if (!infoPtr->image) {
+        fprintf(stderr, "%s: error: ColorBuffer 0x%x has no VkImage\n", __func__, colorBufferHandle);
+        return false;
+    }
+
+    if (infoPtr->glExported ||
+        (infoPtr->vulkanMode == VkEmulation::ColorBufferInfo::VulkanMode::VulkanOnly)) {
+        // No sync needed if exported to GL or in Vulkan-only mode
+        return true;
+    }
+
+    // Record our synchronization commands.
+    VkCommandBufferBeginInfo beginInfo = {
+        VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, 0,
+        VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
+        nullptr /* no inheritance info */,
+    };
+
+    vk->vkBeginCommandBuffer(
+        sVkEmulation->commandBuffer,
+        &beginInfo);
+
+    // From the spec: If an application does not need the contents of a resource
+    // to remain valid when transferring from one queue family to another, then
+    // the ownership transfer should be skipped.
+
+    // We definitely need to transition the image to
+    // VK_TRANSFER_SRC_OPTIMAL and back.
+
+    VkImageMemoryBarrier presentToTransferSrc = {
+        VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, 0,
+        0,
+        VK_ACCESS_HOST_READ_BIT,
+        infoPtr->currentLayout,
+        VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+        VK_QUEUE_FAMILY_IGNORED,
+        VK_QUEUE_FAMILY_IGNORED,
+        infoPtr->image,
+        {
+            VK_IMAGE_ASPECT_COLOR_BIT,
+            0, 1, 0, 1,
+        },
+    };
+
+    vk->vkCmdPipelineBarrier(
+        sVkEmulation->commandBuffer,
+        VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
+        VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
+        0,
+        0, nullptr,
+        0, nullptr,
+        1, &presentToTransferSrc);
+
+    infoPtr->currentLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
+
+    // Copy to staging buffer
+    uint32_t bpp = 4; /* format always rgba8...not */
+    switch (infoPtr->format) {
+        case VK_FORMAT_R5G6B5_UNORM_PACK16:
+            bpp = 2;
+            break;
+        case VK_FORMAT_R8G8B8_UNORM:
+            bpp = 3;
+            break;
+        default:
+        case VK_FORMAT_R8G8B8A8_UNORM:
+            bpp = 4;
+            break;
+    }
+    VkBufferImageCopy region = {
+        0 /* buffer offset */,
+        infoPtr->extent.width,
+        infoPtr->extent.height,
+        {
+            VK_IMAGE_ASPECT_COLOR_BIT,
+            0, 0, 1,
+        },
+        { 0, 0, 0 },
+        infoPtr->extent,
+    };
+
+    vk->vkCmdCopyImageToBuffer(
+        sVkEmulation->commandBuffer,
+        infoPtr->image,
+        VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+        sVkEmulation->staging.buffer,
+        1, &region);
+
+    vk->vkEndCommandBuffer(sVkEmulation->commandBuffer);
+
+    VkSubmitInfo submitInfo = {
+        VK_STRUCTURE_TYPE_SUBMIT_INFO, 0,
+        0, nullptr,
+        nullptr,
+        1, &sVkEmulation->commandBuffer,
+        0, nullptr,
+    };
+
+    vk->vkQueueSubmit(
+        sVkEmulation->queue,
+        1, &submitInfo,
+        sVkEmulation->commandBufferFence);
+
+    static constexpr uint64_t ANB_MAX_WAIT_NS =
+        5ULL * 1000ULL * 1000ULL * 1000ULL;
+
+    vk->vkWaitForFences(
+        sVkEmulation->device, 1, &sVkEmulation->commandBufferFence,
+        VK_TRUE, ANB_MAX_WAIT_NS);
+    vk->vkResetFences(
+        sVkEmulation->device, 1, &sVkEmulation->commandBufferFence);
+
+    VkMappedMemoryRange toInvalidate = {
+        VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, 0,
+        sVkEmulation->staging.memory.memory,
+        0, VK_WHOLE_SIZE,
+    };
+
+    vk->vkInvalidateMappedMemoryRanges(
+        sVkEmulation->device, 1, &toInvalidate);
+
+    FrameBuffer::getFB()->
+        replaceColorBufferContents(
+            colorBufferHandle,
+            sVkEmulation->staging.memory.mappedPtr,
+            bpp * infoPtr->extent.width * infoPtr->extent.height);
+
+    return true;
+}
+
+bool updateVkImageFromColorBuffer(uint32_t colorBufferHandle) {
+    if (!sVkEmulation || !sVkEmulation->live) return false;
+
+    auto vk = sVkEmulation->dvk;
+
+    AutoLock lock(sVkEmulationLock);
+
+    auto infoPtr = android::base::find(sVkEmulation->colorBuffers, colorBufferHandle);
+
+    if (!infoPtr) {
+        // Color buffer not found; this is usually OK.
+        return false;
+    }
+
+    if (infoPtr->glExported ||
+        (infoPtr->vulkanMode == VkEmulation::ColorBufferInfo::VulkanMode::VulkanOnly)) {
+        // No sync needed if exported to GL or in Vulkan-only mode
+        return true;
+    }
+
+    size_t cbNumBytes = 0;
+    bool readRes = FrameBuffer::getFB()->
+        readColorBufferContents(
+            colorBufferHandle, &cbNumBytes, nullptr);
+
+    if (!readRes) {
+        fprintf(stderr, "%s: Failed to read color buffer 0x%x\n",
+                __func__, colorBufferHandle);
+        return false;
+    }
+
+    if (cbNumBytes > sVkEmulation->staging.memory.size) {
+        fprintf(stderr,
+            "%s: Not enough space to read to staging buffer. "
+            "Wanted: 0x%llx Have: 0x%llx\n", __func__,
+            (unsigned long long)cbNumBytes,
+            (unsigned long long)(sVkEmulation->staging.memory.size));
+        return false;
+    }
+
+    readRes = FrameBuffer::getFB()->
+        readColorBufferContents(
+            colorBufferHandle, &cbNumBytes,
+            sVkEmulation->staging.memory.mappedPtr);
+
+    if (!readRes) {
+        fprintf(stderr, "%s: Failed to read color buffer 0x%x (at glReadPixels)\n",
+                __func__, colorBufferHandle);
+        return false;
+    }
+
+    // Record our synchronization commands.
+    VkCommandBufferBeginInfo beginInfo = {
+        VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, 0,
+        VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT,
+        nullptr /* no inheritance info */,
+    };
+
+    vk->vkBeginCommandBuffer(
+        sVkEmulation->commandBuffer,
+        &beginInfo);
+
+    // From the spec: If an application does not need the contents of a resource
+    // to remain valid when transferring from one queue family to another, then
+    // the ownership transfer should be skipped.
+
+    // We definitely need to transition the image to
+    // VK_TRANSFER_SRC_OPTIMAL and back.
+
+    VkImageMemoryBarrier presentToTransferSrc = {
+        VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, 0,
+        0,
+        VK_ACCESS_HOST_READ_BIT,
+        infoPtr->currentLayout,
+        VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+        VK_QUEUE_FAMILY_IGNORED,
+        VK_QUEUE_FAMILY_IGNORED,
+        infoPtr->image,
+        {
+            VK_IMAGE_ASPECT_COLOR_BIT,
+            0, 1, 0, 1,
+        },
+    };
+
+    infoPtr->currentLayout =
+        VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL;
+
+    vk->vkCmdPipelineBarrier(
+        sVkEmulation->commandBuffer,
+        VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
+        VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
+        0,
+        0, nullptr,
+        0, nullptr,
+        1, &presentToTransferSrc);
+
+    // Copy to staging buffer
+    uint32_t bpp = 4; /* format always rgba8...not */
+    switch (infoPtr->format) {
+        case VK_FORMAT_R5G6B5_UNORM_PACK16:
+            bpp = 2;
+            break;
+        case VK_FORMAT_R8G8B8_UNORM:
+            bpp = 3;
+            break;
+        default:
+        case VK_FORMAT_R8G8B8A8_UNORM:
+            bpp = 4;
+            break;
+    }
+    VkBufferImageCopy region = {
+        0 /* buffer offset */,
+        infoPtr->extent.width,
+        infoPtr->extent.height,
+        {
+            VK_IMAGE_ASPECT_COLOR_BIT,
+            0, 0, 1,
+        },
+        { 0, 0, 0 },
+        infoPtr->extent,
+    };
+
+    vk->vkCmdCopyBufferToImage(
+        sVkEmulation->commandBuffer,
+        sVkEmulation->staging.buffer,
+        infoPtr->image,
+        VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
+        1, &region);
+
+    vk->vkEndCommandBuffer(sVkEmulation->commandBuffer);
+
+    VkSubmitInfo submitInfo = {
+        VK_STRUCTURE_TYPE_SUBMIT_INFO, 0,
+        0, nullptr,
+        nullptr,
+        1, &sVkEmulation->commandBuffer,
+        0, nullptr,
+    };
+
+    vk->vkQueueSubmit(
+        sVkEmulation->queue,
+        1, &submitInfo,
+        sVkEmulation->commandBufferFence);
+
+    static constexpr uint64_t ANB_MAX_WAIT_NS =
+        5ULL * 1000ULL * 1000ULL * 1000ULL;
+
+    vk->vkWaitForFences(
+        sVkEmulation->device, 1, &sVkEmulation->commandBufferFence,
+        VK_TRUE, ANB_MAX_WAIT_NS);
+    vk->vkResetFences(
+        sVkEmulation->device, 1, &sVkEmulation->commandBufferFence);
+
+    VkMappedMemoryRange toInvalidate = {
+        VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE, 0,
+        sVkEmulation->staging.memory.memory,
+        0, VK_WHOLE_SIZE,
+    };
+
+    vk->vkInvalidateMappedMemoryRanges(
+        sVkEmulation->device, 1, &toInvalidate);
+    return true;
+}
+
+VK_EXT_MEMORY_HANDLE getColorBufferExtMemoryHandle(uint32_t colorBuffer) {
+    if (!sVkEmulation || !sVkEmulation->live) return VK_EXT_MEMORY_HANDLE_INVALID;
+
+    auto vk = sVkEmulation->dvk;
+
+    AutoLock lock(sVkEmulationLock);
+
+    auto infoPtr = android::base::find(sVkEmulation->colorBuffers, colorBuffer);
+
+    if (!infoPtr) {
+        // Color buffer not found; this is usually OK.
+        return VK_EXT_MEMORY_HANDLE_INVALID;
+    }
+
+    return infoPtr->memory.exportedHandle;
+}
+
+bool setColorBufferVulkanMode(uint32_t colorBuffer, uint32_t vulkanMode) {
+    if (!sVkEmulation || !sVkEmulation->live) return VK_EXT_MEMORY_HANDLE_INVALID;
+
+    auto vk = sVkEmulation->dvk;
+
+    AutoLock lock(sVkEmulationLock);
+
+    auto infoPtr = android::base::find(sVkEmulation->colorBuffers, colorBuffer);
+
+    if (!infoPtr) {
+        return false;
+    }
+
+    infoPtr->vulkanMode = static_cast<VkEmulation::ColorBufferInfo::VulkanMode>(vulkanMode);
+
+    return true;
+}
+
+IOSurfaceRef getColorBufferIOSurface(uint32_t colorBuffer) {
+    if (!sVkEmulation || !sVkEmulation->live) return nullptr;
+
+    AutoLock lock(sVkEmulationLock);
+
+    auto infoPtr = android::base::find(sVkEmulation->colorBuffers, colorBuffer);
+
+    if (!infoPtr) {
+        // Color buffer not found; this is usually OK.
+        return nullptr;
+    }
+
+#ifdef __APPLE__
+    CFRetain(infoPtr->ioSurface);
+#endif
+    return infoPtr->ioSurface;
+}
+
+VkExternalMemoryHandleTypeFlags
+transformExternalMemoryHandleTypeFlags_tohost(
+    VkExternalMemoryHandleTypeFlags bits) {
+
+    VkExternalMemoryHandleTypeFlags res = bits;
+
+    // Transform Android/Fuchsia/Linux bits to host bits.
+    if (bits & VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT) {
+        res &= ~VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT;
+    }
+
+    if (bits & VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID) {
+        res &= ~VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
+        res |= VK_EXT_MEMORY_HANDLE_TYPE_BIT;
+    }
+
+    if (bits & VK_EXTERNAL_MEMORY_HANDLE_TYPE_TEMP_ZIRCON_VMO_BIT_FUCHSIA) {
+        res &= ~VK_EXTERNAL_MEMORY_HANDLE_TYPE_TEMP_ZIRCON_VMO_BIT_FUCHSIA;
+        res |= VK_EXT_MEMORY_HANDLE_TYPE_BIT;
+    }
+    return res;
+}
+
+VkExternalMemoryHandleTypeFlags
+transformExternalMemoryHandleTypeFlags_fromhost(
+    VkExternalMemoryHandleTypeFlags hostBits,
+    VkExternalMemoryHandleTypeFlags wantedGuestHandleType) {
+
+    VkExternalMemoryHandleTypeFlags res = hostBits;
+
+    if (res & VK_EXT_MEMORY_HANDLE_TYPE_BIT) {
+        res &= ~VK_EXT_MEMORY_HANDLE_TYPE_BIT;
+        res |= wantedGuestHandleType;
+    }
+
+    return res;
+}
+
+VkExternalMemoryProperties
+transformExternalMemoryProperties_tohost(
+    VkExternalMemoryProperties props) {
+    VkExternalMemoryProperties res = props;
+    res.exportFromImportedHandleTypes =
+        transformExternalMemoryHandleTypeFlags_tohost(
+            props.exportFromImportedHandleTypes);
+    res.compatibleHandleTypes =
+        transformExternalMemoryHandleTypeFlags_tohost(
+            props.compatibleHandleTypes);
+    return res;
+}
+
+VkExternalMemoryProperties
+transformExternalMemoryProperties_fromhost(
+    VkExternalMemoryProperties props,
+    VkExternalMemoryHandleTypeFlags wantedGuestHandleType) {
+    VkExternalMemoryProperties res = props;
+    res.exportFromImportedHandleTypes =
+        transformExternalMemoryHandleTypeFlags_fromhost(
+            props.exportFromImportedHandleTypes,
+            wantedGuestHandleType);
+    res.compatibleHandleTypes =
+        transformExternalMemoryHandleTypeFlags_fromhost(
+            props.compatibleHandleTypes,
+            wantedGuestHandleType);
+    return res;
+}
+
+} // namespace goldfish_vk
