Merge "Fix Vulkan snapshot with -guest-angle" into main
diff --git a/codegen/vulkan/vulkan-docs-next/scripts/cereal/decodersnapshot.py b/codegen/vulkan/vulkan-docs-next/scripts/cereal/decodersnapshot.py
index b63345d..d40b95e 100644
--- a/codegen/vulkan/vulkan-docs-next/scripts/cereal/decodersnapshot.py
+++ b/codegen/vulkan/vulkan-docs-next/scripts/cereal/decodersnapshot.py
@@ -59,6 +59,7 @@
     }
 
     void createExtraHandlesForNextApi(const uint64_t* created, uint32_t count) {
+        mLock.lock();
         mReconstruction.createExtraHandlesForNextApi(created, count);
     }
 """
@@ -170,6 +171,11 @@
     "vkAllocateMemory" : ["vkAllocateMemory", "vkMapMemoryIntoAddressSpaceGOOGLE"]
 }
 
+apiCrreateExtraHandles = [
+    "vkCreateDevice",
+    "vkCreateDescriptorPool",
+]
+
 @dataclass(frozen=True)
 class VkObjectState:
     vk_object : str
@@ -259,7 +265,9 @@
                 boxed_access = "&boxed_%s" % p.typeName
             if p.pointerIndirectionLevels > 0:
                 cgen.stmt("if (!%s) return" % access)
-            cgen.stmt("android::base::AutoLock lock(mLock)")
+            isCreateExtraHandleApi = api.name in apiCrreateExtraHandles
+            if not isCreateExtraHandleApi:
+                cgen.stmt("android::base::AutoLock lock(mLock)")
             cgen.line("// %s create" % p.paramName)
             if p.isCreatedBy(api):
                 cgen.stmt("mReconstruction.addHandles((const uint64_t*)%s, %s)" % (boxed_access, lenExpr));
@@ -282,6 +290,8 @@
                 cgen.stmt("mReconstruction.setCreatedHandlesForApi(apiHandle, (const uint64_t*)%s, %s)" % (boxed_access, lenExpr))
             if lenAccessGuard is not None:
                 cgen.endIf()
+            if isCreateExtraHandleApi:
+                cgen.stmt("mLock.unlock()")
 
         if p.isDestroyedBy(api):
             cgen.stmt("android::base::AutoLock lock(mLock)")
diff --git a/host/vulkan/VkDecoderGlobalState.cpp b/host/vulkan/VkDecoderGlobalState.cpp
index bb6fd16..9b0454b 100644
--- a/host/vulkan/VkDecoderGlobalState.cpp
+++ b/host/vulkan/VkDecoderGlobalState.cpp
@@ -2109,7 +2109,8 @@
 
     VkResult on_vkCreateImage(android::base::BumpPool* pool, VkDevice boxed_device,
                               const VkImageCreateInfo* pCreateInfo,
-                              const VkAllocationCallbacks* pAllocator, VkImage* pImage) {
+                              const VkAllocationCallbacks* pAllocator, VkImage* pImage,
+                              bool boxImage = true) {
         auto device = unbox_VkDevice(boxed_device);
         auto vk = dispatch_VkDevice(boxed_device);
 
@@ -2205,7 +2206,9 @@
         imageInfo.layout = pCreateInfo->initialLayout;
         if (nativeBufferANDROID) imageInfo.anbInfo = std::move(anbInfo);
 
-        *pImage = new_boxed_non_dispatchable_VkImage(*pImage);
+        if (boxImage) {
+            *pImage = new_boxed_non_dispatchable_VkImage(*pImage);
+        }
         return createRes;
     }
 
@@ -2260,8 +2263,9 @@
                 << "Missing VkNativeBufferANDROID for deferred AHB bind.";
         }
 
-        VkImage boxed_replacement_image = VK_NULL_HANDLE;
-        VkResult result = on_vkCreateImage(pool, boxed_device, &ici, nullptr, &boxed_replacement_image);
+        VkImage underlying_replacement_image = VK_NULL_HANDLE;
+        VkResult result = on_vkCreateImage(pool, boxed_device, &ici, nullptr,
+                                           &underlying_replacement_image, false);
         if (result != VK_SUCCESS) {
             ERR("Failed to create image for deferred AHB bind.");
             return VK_ERROR_OUT_OF_HOST_MEMORY;
@@ -2272,9 +2276,9 @@
         {
             std::lock_guard<std::recursive_mutex> lock(mLock);
 
-            auto underlying_replacement_image = unbox_VkImage(boxed_replacement_image);
-            delete_VkImage(boxed_replacement_image);
             set_boxed_non_dispatchable_VkImage(original_boxed_image, underlying_replacement_image);
+            const_cast<VkBindImageMemoryInfo*>(bimi)->image = underlying_replacement_image;
+            const_cast<VkBindImageMemoryInfo*>(bimi)->memory = nullptr;
         }
 
         return VK_SUCCESS;
@@ -9206,6 +9210,9 @@
         return (type)elt->underlying;                                                             \
     }                                                                                             \
     type unboxed_to_boxed_non_dispatchable_##type(type unboxed) {                                 \
+        if (!unboxed) {                                                                           \
+            return nullptr;                                                                       \
+        }                                                                                         \
         AutoLock lock(sBoxedHandleManager.lock);                                                  \
         return (type)sBoxedHandleManager.getBoxedFromUnboxedLocked((uint64_t)(uintptr_t)unboxed); \
     }
diff --git a/host/vulkan/VkDecoderGlobalState.h b/host/vulkan/VkDecoderGlobalState.h
index bbdcb4d..705c077 100644
--- a/host/vulkan/VkDecoderGlobalState.h
+++ b/host/vulkan/VkDecoderGlobalState.h
@@ -232,8 +232,10 @@
 
     VkResult on_vkBindImageMemory(android::base::BumpPool* pool, VkDevice device, VkImage image,
                                   VkDeviceMemory memory, VkDeviceSize memoryOffset);
+    // It might modify pBindInfos to support snapshot.
     VkResult on_vkBindImageMemory2(android::base::BumpPool* pool, VkDevice device,
                                    uint32_t bindInfoCount, const VkBindImageMemoryInfo* pBindInfos);
+    // It might modify pBindInfos to support snapshot.
     VkResult on_vkBindImageMemory2KHR(android::base::BumpPool* pool, VkDevice device,
                                       uint32_t bindInfoCount,
                                       const VkBindImageMemoryInfo* pBindInfos);
diff --git a/host/vulkan/VkDecoderSnapshot.cpp b/host/vulkan/VkDecoderSnapshot.cpp
index 7ee1e8e..bc0ea04 100644
--- a/host/vulkan/VkDecoderSnapshot.cpp
+++ b/host/vulkan/VkDecoderSnapshot.cpp
@@ -53,6 +53,7 @@
     }
 
     void createExtraHandlesForNextApi(const uint64_t* created, uint32_t count) {
+        mLock.lock();
         mReconstruction.createExtraHandlesForNextApi(created, count);
     }
 #ifdef VK_VERSION_1_0
@@ -142,7 +143,6 @@
                         VkPhysicalDevice physicalDevice, const VkDeviceCreateInfo* pCreateInfo,
                         const VkAllocationCallbacks* pAllocator, VkDevice* pDevice) {
         if (!pDevice) return;
-        android::base::AutoLock lock(mLock);
         // pDevice create
         mReconstruction.addHandles((const uint64_t*)pDevice, 1);
         mReconstruction.addHandleDependency((const uint64_t*)pDevice, 1,
@@ -154,6 +154,7 @@
         mReconstruction.forEachHandleAddApi((const uint64_t*)pDevice, 1, apiHandle,
                                             VkReconstruction::CREATED);
         mReconstruction.setCreatedHandlesForApi(apiHandle, (const uint64_t*)pDevice, 1);
+        mLock.unlock();
     }
     void vkDestroyDevice(const uint8_t* snapshotTraceBegin, size_t snapshotTraceBytes,
                          android::base::BumpPool* pool, VkDevice device,
@@ -750,7 +751,6 @@
                                 const VkAllocationCallbacks* pAllocator,
                                 VkDescriptorPool* pDescriptorPool) {
         if (!pDescriptorPool) return;
-        android::base::AutoLock lock(mLock);
         // pDescriptorPool create
         mReconstruction.addHandles((const uint64_t*)pDescriptorPool, 1);
         mReconstruction.addHandleDependency((const uint64_t*)pDescriptorPool, 1,
@@ -762,6 +762,7 @@
         mReconstruction.forEachHandleAddApi((const uint64_t*)pDescriptorPool, 1, apiHandle,
                                             VkReconstruction::CREATED);
         mReconstruction.setCreatedHandlesForApi(apiHandle, (const uint64_t*)pDescriptorPool, 1);
+        mLock.unlock();
     }
     void vkDestroyDescriptorPool(const uint8_t* snapshotTraceBegin, size_t snapshotTraceBytes,
                                  android::base::BumpPool* pool, VkDevice device,
diff --git a/host/vulkan/VkDecoderSnapshotUtils.cpp b/host/vulkan/VkDecoderSnapshotUtils.cpp
index 2359fe8..7d75cfe 100644
--- a/host/vulkan/VkDecoderSnapshotUtils.cpp
+++ b/host/vulkan/VkDecoderSnapshotUtils.cpp
@@ -57,6 +57,7 @@
         case VK_FORMAT_R8G8_UINT:
         case VK_FORMAT_R8G8_SINT:
         case VK_FORMAT_R8G8_SRGB:
+        case VK_FORMAT_D16_UNORM:
             return 2;
         case VK_FORMAT_R8G8B8_UNORM:
         case VK_FORMAT_R8G8B8_SNORM:
@@ -95,8 +96,30 @@
         case VK_FORMAT_A8B8G8R8_UINT_PACK32:
         case VK_FORMAT_A8B8G8R8_SINT_PACK32:
         case VK_FORMAT_A8B8G8R8_SRGB_PACK32:
+        case VK_FORMAT_A2R10G10B10_UNORM_PACK32:
+        case VK_FORMAT_A2R10G10B10_SNORM_PACK32:
+        case VK_FORMAT_A2R10G10B10_USCALED_PACK32:
+        case VK_FORMAT_A2R10G10B10_SSCALED_PACK32:
+        case VK_FORMAT_A2R10G10B10_UINT_PACK32:
+        case VK_FORMAT_A2R10G10B10_SINT_PACK32:
+        case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
+        case VK_FORMAT_A2B10G10R10_SNORM_PACK32:
+        case VK_FORMAT_A2B10G10R10_USCALED_PACK32:
+        case VK_FORMAT_A2B10G10R10_SSCALED_PACK32:
+        case VK_FORMAT_A2B10G10R10_UINT_PACK32:
+        case VK_FORMAT_A2B10G10R10_SINT_PACK32:
         case VK_FORMAT_D24_UNORM_S8_UINT:
+        case VK_FORMAT_R16G16_SFLOAT:
+        case VK_FORMAT_B10G11R11_UFLOAT_PACK32:
+        case VK_FORMAT_E5B9G9R9_UFLOAT_PACK32:
+        case VK_FORMAT_X8_D24_UNORM_PACK32:
             return 4;
+        case VK_FORMAT_R16G16B16A16_SINT:
+        case VK_FORMAT_R16G16B16A16_SFLOAT:
+            return 8;
+        case VK_FORMAT_R32G32B32A32_SINT:
+        case VK_FORMAT_R32G32B32A32_SFLOAT:
+            return 16;
         default:
             GFXSTREAM_ABORT(emugl::FatalError(emugl::ABORT_REASON_OTHER))
                 << "Unsupported VkFormat on snapshot save " << format << " " << __func__ << " ("
@@ -106,8 +129,8 @@
 
 VkExtent3D getMipmapExtent(VkExtent3D baseExtent, uint32_t mipLevel) {
     return VkExtent3D{
-        .width = (baseExtent.width + (1 << mipLevel) - 1) >> mipLevel,
-        .height = (baseExtent.height + (1 << mipLevel) - 1) >> mipLevel,
+        .width = baseExtent.width >> mipLevel,
+        .height = baseExtent.height >> mipLevel,
         .depth = baseExtent.depth,
     };
 }
diff --git a/host/vulkan/VkReconstruction.cpp b/host/vulkan/VkReconstruction.cpp
index d1604f8..88c2a04 100644
--- a/host/vulkan/VkReconstruction.cpp
+++ b/host/vulkan/VkReconstruction.cpp
@@ -446,6 +446,8 @@
                                            HandleState parentState) {
     if (!handles) return;
 
+    if (!parentHandle) return;
+
     auto parentItem = mHandleReconstructions.get(parentHandle);
 
     if (!parentItem) {