Merge "gfxstream: guest: enable virtio-gpu kumquat" into main
diff --git a/host/vulkan/VkCommonOperations.cpp b/host/vulkan/VkCommonOperations.cpp
index 9f2724a..9643bc3 100644
--- a/host/vulkan/VkCommonOperations.cpp
+++ b/host/vulkan/VkCommonOperations.cpp
@@ -25,6 +25,7 @@
 #include <sstream>
 #include <unordered_set>
 
+#include "BlobManager.h"
 #include "VkDecoderGlobalState.h"
 #include "VkEmulatedPhysicalDeviceMemory.h"
 #include "VkFormatUtils.h"
@@ -812,6 +813,9 @@
             // External memory export not supported on QNX
             deviceInfos[i].supportsExternalMemoryExport = false;
 #endif
+
+            deviceInfos[i].supportsDmaBuf =
+                extensionsSupported(deviceExts, {VK_EXT_EXTERNAL_MEMORY_DMA_BUF_EXTENSION_NAME});
             deviceInfos[i].supportsIdProperties =
                 sVkEmulation->getPhysicalDeviceProperties2Func != nullptr;
             deviceInfos[i].supportsDriverProperties =
@@ -1057,6 +1061,12 @@
         }
     }
 
+#if defined(__linux__)
+    if (sVkEmulation->deviceInfo.supportsDmaBuf) {
+        selectedDeviceExtensionNames_.emplace(VK_EXT_EXTERNAL_MEMORY_DMA_BUF_EXTENSION_NAME);
+    }
+#endif
+
     // We need to always enable swapchain extensions to be able to use this device
     // to do VK_IMAGE_LAYOUT_PRESENT_SRC_KHR transition operations done
     // in releaseColorBufferForGuestUse for the apps using Vulkan swapchain
@@ -1529,6 +1539,9 @@
             vk_append_struct(&allocInfoChain, &metalBufferExport);
         }
 #endif
+        if (sVkEmulation->deviceInfo.supportsDmaBuf && actuallyExternal) {
+            exportAi.handleTypes |= VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
+        }
 
         vk_append_struct(&allocInfoChain, &exportAi);
     }
@@ -1613,6 +1626,8 @@
         return true;
     }
 
+    VkExternalMemoryHandleTypeFlagBits vkHandleType = VK_EXT_MEMORY_HANDLE_TYPE_BIT;
+    uint32_t streamHandleType = 0;
     VkResult exportRes = VK_SUCCESS;
     bool validHandle = false;
 #ifdef _WIN32
@@ -1620,14 +1635,18 @@
         VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR,
         0,
         info->memory,
-        VK_EXT_MEMORY_HANDLE_TYPE_BIT,
+        vkHandleType,
     };
+
     exportRes = sVkEmulation->deviceInfo.getMemoryHandleFunc(
         sVkEmulation->device, &getWin32HandleInfo, &info->externalHandle);
     validHandle = (VK_EXT_MEMORY_HANDLE_INVALID != info->externalHandle);
+    info->streamHandleType = STREAM_MEM_HANDLE_TYPE_OPAQUE_WIN32;
 #elif !defined(__QNX__)
-#ifdef __APPLE__
+    bool opaque_fd = true;
     if (sVkEmulation->instanceSupportsMoltenVK) {
+        opaque_fd = false;
+#if defined(__APPLE__)
         info->externalMetalHandle = getMtlBufferFromVkDeviceMemory(vk, info->memory);
         validHandle = (nullptr != info->externalMetalHandle);
         if (validHandle) {
@@ -1636,14 +1655,21 @@
         } else {
             exportRes = VK_ERROR_INVALID_EXTERNAL_HANDLE;
         }
-    } else
 #endif
-    {
+    }
+    if (opaque_fd) {
+        if (sVkEmulation->deviceInfo.supportsDmaBuf) {
+            vkHandleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT;
+            info->streamHandleType = STREAM_MEM_HANDLE_TYPE_DMABUF;
+        } else {
+            info->streamHandleType = STREAM_MEM_HANDLE_TYPE_OPAQUE_FD;
+        }
+
         VkMemoryGetFdInfoKHR getFdInfo = {
             VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR,
             0,
             info->memory,
-            VK_EXT_MEMORY_HANDLE_TYPE_BIT,
+            vkHandleType,
         };
         exportRes = sVkEmulation->deviceInfo.getMemoryHandleFunc(sVkEmulation->device, &getFdInfo,
                                                                  &info->externalHandle);
@@ -2430,6 +2456,7 @@
     return VkColorBufferMemoryExport{
         .descriptor = std::move(descriptor),
         .size = info->memory.size,
+        .streamHandleType = info->memory.streamHandleType,
         .linearTiling = info->imageCreateInfoShallow.tiling == VK_IMAGE_TILING_LINEAR,
         .dedicatedAllocation = info->memory.dedicatedAllocation,
     };
@@ -3310,7 +3337,8 @@
     return true;
 }
 
-VK_EXT_MEMORY_HANDLE getBufferExtMemoryHandle(uint32_t bufferHandle) {
+VK_EXT_MEMORY_HANDLE getBufferExtMemoryHandle(uint32_t bufferHandle,
+                                              uint32_t* outStreamHandleType) {
     if (!sVkEmulation || !sVkEmulation->live) return VK_EXT_MEMORY_HANDLE_INVALID;
 
     AutoLock lock(sVkEmulationLock);
@@ -3321,6 +3349,7 @@
         return VK_EXT_MEMORY_HANDLE_INVALID;
     }
 
+    *outStreamHandleType = infoPtr->memory.streamHandleType;
     return infoPtr->memory.externalHandle;
 }
 
diff --git a/host/vulkan/VkCommonOperations.h b/host/vulkan/VkCommonOperations.h
index b5fa61a..430233b 100644
--- a/host/vulkan/VkCommonOperations.h
+++ b/host/vulkan/VkCommonOperations.h
@@ -198,6 +198,7 @@
         bool hasComputeQueueFamily = false;
         bool supportsExternalMemoryImport = false;
         bool supportsExternalMemoryExport = false;
+        bool supportsDmaBuf = false;
         bool supportsIdProperties = false;
         bool supportsDriverProperties = false;
         bool hasSamplerYcbcrConversionExtension = false;
@@ -254,6 +255,7 @@
         // This is used as an external handle when MoltenVK is enabled
         MTLBufferRef externalMetalHandle = nullptr;
 #endif
+        uint32_t streamHandleType;
 
         bool dedicatedAllocation = false;
     };
@@ -501,6 +503,7 @@
 struct VkColorBufferMemoryExport {
     android::base::ManagedDescriptor descriptor;
     uint64_t size = 0;
+    uint32_t streamHandleType = 0;
     bool linearTiling = false;
     bool dedicatedAllocation = false;
 };
@@ -528,7 +531,8 @@
 bool setupVkBuffer(uint64_t size, uint32_t bufferHandle, bool vulkanOnly = false,
                    uint32_t memoryProperty = 0);
 bool teardownVkBuffer(uint32_t bufferHandle);
-VK_EXT_MEMORY_HANDLE getBufferExtMemoryHandle(uint32_t bufferHandle);
+
+VK_EXT_MEMORY_HANDLE getBufferExtMemoryHandle(uint32_t bufferHandle, uint32_t* outStreamHandleType);
 #ifdef __APPLE__
 MTLBufferRef getBufferMetalMemoryHandle(uint32_t bufferHandle);
 #endif
diff --git a/host/vulkan/VkDecoderGlobalState.cpp b/host/vulkan/VkDecoderGlobalState.cpp
index 014eda1..3022974 100644
--- a/host/vulkan/VkDecoderGlobalState.cpp
+++ b/host/vulkan/VkDecoderGlobalState.cpp
@@ -4504,8 +4504,9 @@
             } else
 #endif
             if (m_emu->deviceInfo.supportsExternalMemoryImport) {
+                uint32_t outStreamHandleType;
                 VK_EXT_MEMORY_HANDLE bufferExtMemoryHandle =
-                    getBufferExtMemoryHandle(importBufferInfoPtr->buffer);
+                    getBufferExtMemoryHandle(importBufferInfoPtr->buffer, &outStreamHandleType);
 
                 if (bufferExtMemoryHandle == VK_EXT_MEMORY_HANDLE_INVALID) {
                     fprintf(stderr,