Merge "Skip snapshotting multi-sample images" into main

GitOrigin-RevId: c3407cd72eab0832c6d2b811ce0479386bf0cc31
Change-Id: Ia9104c7696818780450bc52141ff39e329a98f1f
diff --git a/common/end2end/GfxstreamEnd2EndVkSnapshotImageTests.cpp b/common/end2end/GfxstreamEnd2EndVkSnapshotImageTests.cpp
index 643ff2d..a50e6e4 100644
--- a/common/end2end/GfxstreamEnd2EndVkSnapshotImageTests.cpp
+++ b/common/end2end/GfxstreamEnd2EndVkSnapshotImageTests.cpp
@@ -150,6 +150,51 @@
     SnapshotSaveAndLoad();
 }
 
+TEST_P(GfxstreamEnd2EndVkSnapshotImageTest, MultiSampleImage) {
+    auto [instance, physicalDevice, device, queue, queueFamilyIndex] =
+        VK_ASSERT(SetUpTypicalVkTestEnvironment());
+
+    const uint32_t width = 32;
+    const uint32_t height = 32;
+
+    const vkhpp::ImageCreateInfo imageCreateInfo = {
+        .pNext = nullptr,
+        .imageType = vkhpp::ImageType::e2D,
+        .extent.width = width,
+        .extent.height = height,
+        .extent.depth = 1,
+        .mipLevels = 1,
+        .arrayLayers = 1,
+        .format = vkhpp::Format::eR8G8B8A8Unorm,
+        .tiling = vkhpp::ImageTiling::eOptimal,
+        .initialLayout = vkhpp::ImageLayout::eUndefined,
+        .usage = vkhpp::ImageUsageFlagBits::eColorAttachment |
+                 vkhpp::ImageUsageFlagBits::eTransferDst | vkhpp::ImageUsageFlagBits::eTransferSrc,
+        .sharingMode = vkhpp::SharingMode::eExclusive,
+        .samples = vkhpp::SampleCountFlagBits::e8,
+    };
+    auto image = device->createImageUnique(imageCreateInfo).value;
+    ASSERT_THAT(image, IsValidHandle());
+
+    vkhpp::MemoryRequirements imageMemoryRequirements{};
+    device->getImageMemoryRequirements(*image, &imageMemoryRequirements);
+
+    const uint32_t imageMemoryIndex = GetMemoryType(physicalDevice, imageMemoryRequirements,
+                                                    vkhpp::MemoryPropertyFlagBits::eDeviceLocal);
+    ASSERT_THAT(imageMemoryIndex, Not(Eq(-1)));
+
+    const vkhpp::MemoryAllocateInfo imageMemoryAllocateInfo = {
+        .allocationSize = imageMemoryRequirements.size,
+        .memoryTypeIndex = imageMemoryIndex,
+    };
+
+    auto imageMemory = device->allocateMemoryUnique(imageMemoryAllocateInfo).value;
+    ASSERT_THAT(imageMemory, IsValidHandle());
+
+    // Make sure it doesn't crash on load
+    SnapshotSaveAndLoad();
+}
+
 TEST_P(GfxstreamEnd2EndVkSnapshotImageTest, ImageContent) {
     static constexpr int kWidth = 256;
     static constexpr int kHeight = 256;
diff --git a/host/vulkan/VkDecoderSnapshotUtils.cpp b/host/vulkan/VkDecoderSnapshotUtils.cpp
index f534574..59105c4 100644
--- a/host/vulkan/VkDecoderSnapshotUtils.cpp
+++ b/host/vulkan/VkDecoderSnapshotUtils.cpp
@@ -127,6 +127,10 @@
     if (imageInfo->layout == VK_IMAGE_LAYOUT_UNDEFINED) {
         return;
     }
+    // TODO(b/333936705): snapshot multi-sample images
+    if (imageInfo->imageCreateInfoShallow.samples != VK_SAMPLE_COUNT_1_BIT) {
+        return;
+    }
     VkEmulation* vkEmulation = getGlobalVkEmulation();
     VulkanDispatch* dispatch = vkEmulation->dvk;
     const VkImageCreateInfo& imageCreateInfo = imageInfo->imageCreateInfoShallow;
@@ -163,7 +167,6 @@
     const auto readbackBufferMemoryType =
         GetMemoryType(*stateBlock->physicalDeviceInfo, readbackBufferMemoryRequirements,
                       VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT);
-
     // Staging memory
     // TODO(b/323064243): reuse staging memory
     VkMemoryAllocateInfo readbackBufferMemoryAllocateInfo = {
@@ -217,7 +220,6 @@
             dispatch->vkCmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
                                            VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 0,
                                            nullptr, 1, &imgMemoryBarrier);
-
             VkBufferImageCopy region{
                 .bufferOffset = 0,
                 .bufferRowLength = 0,
@@ -277,6 +279,9 @@
     if (imageInfo->layout == VK_IMAGE_LAYOUT_UNDEFINED) {
         return;
     }
+    if (imageInfo->imageCreateInfoShallow.samples != VK_SAMPLE_COUNT_1_BIT) {
+        return;
+    }
     VkEmulation* vkEmulation = getGlobalVkEmulation();
     VulkanDispatch* dispatch = vkEmulation->dvk;
     const VkImageCreateInfo& imageCreateInfo = imageInfo->imageCreateInfoShallow;