Merge changes I8b7245aa,If228f644 into main
* changes:
Fix meson build
Revert^2 "Add snapshot support for vkBindImageMemory2"
diff --git a/codegen/vulkan/vulkan-docs-next/scripts/cereal/decodersnapshot.py b/codegen/vulkan/vulkan-docs-next/scripts/cereal/decodersnapshot.py
index d40b95e..2a5ef47 100644
--- a/codegen/vulkan/vulkan-docs-next/scripts/cereal/decodersnapshot.py
+++ b/codegen/vulkan/vulkan-docs-next/scripts/cereal/decodersnapshot.py
@@ -187,6 +187,38 @@
"vkBindBufferMemory": VkObjectState("buffer", "VkReconstruction::BOUND_MEMORY"),
}
+def api_special_implementation_vkBindImageMemory2(api, cgen):
+ childType = "VkImage"
+ parentType = "VkDeviceMemory"
+ childObj = "boxed_%s" % childType
+ parentObj = "boxed_%s" % parentType
+ cgen.stmt("android::base::AutoLock lock(mLock)")
+ cgen.beginFor("uint32_t i = 0", "i < bindInfoCount", "++i")
+ cgen.stmt("%s boxed_%s = unboxed_to_boxed_non_dispatchable_%s(pBindInfos[i].image)"
+ % (childType, childType, childType))
+ cgen.stmt("%s boxed_%s = unboxed_to_boxed_non_dispatchable_%s(pBindInfos[i].memory)"
+ % (parentType, parentType, parentType))
+ cgen.stmt("mReconstruction.addHandleDependency((const uint64_t*)&%s, %s, (uint64_t)(uintptr_t)%s, VkReconstruction::BOUND_MEMORY)" % \
+ (childObj, "1", parentObj))
+ cgen.stmt("mReconstruction.addHandleDependency((const uint64_t*)&%s, %s, (uint64_t)(uintptr_t)%s, VkReconstruction::BOUND_MEMORY)" % \
+ (childObj, "1", childObj))
+ cgen.endFor()
+
+ cgen.stmt("auto apiHandle = mReconstruction.createApiInfo()")
+ cgen.stmt("auto apiInfo = mReconstruction.getApiInfo(apiHandle)")
+ cgen.stmt("mReconstruction.setApiTrace(apiInfo, OP_%s, snapshotTraceBegin, snapshotTraceBytes)" % api.name)
+ cgen.line("// Note: the implementation does not work with bindInfoCount > 1");
+ cgen.beginFor("uint32_t i = 0", "i < bindInfoCount", "++i")
+ cgen.stmt("%s boxed_%s = unboxed_to_boxed_non_dispatchable_%s(pBindInfos[i].image)"
+ % (childType, childType, childType))
+ cgen.stmt(f"mReconstruction.forEachHandleAddApi((const uint64_t*)&{childObj}, {1}, apiHandle, VkReconstruction::BOUND_MEMORY)")
+ cgen.endFor()
+
+apiSpecialImplementation = {
+ "vkBindImageMemory2": api_special_implementation_vkBindImageMemory2,
+ "vkBindImageMemory2KHR": api_special_implementation_vkBindImageMemory2,
+}
+
apiModifies = {
"vkMapMemoryIntoAddressSpaceGOOGLE" : ["memory"],
"vkGetBlobGOOGLE" : ["memory"],
@@ -240,6 +272,8 @@
def emit_impl(typeInfo, api, cgen):
+ if api.name in apiSpecialImplementation:
+ apiSpecialImplementation[api.name](api, cgen)
for p in api.parameters:
if not (p.isHandleType):
continue
diff --git a/common/end2end/GfxstreamEnd2EndVkSnapshotImageTests.cpp b/common/end2end/GfxstreamEnd2EndVkSnapshotImageTests.cpp
index eb6483d..370b48c 100644
--- a/common/end2end/GfxstreamEnd2EndVkSnapshotImageTests.cpp
+++ b/common/end2end/GfxstreamEnd2EndVkSnapshotImageTests.cpp
@@ -234,6 +234,89 @@
SnapshotSaveAndLoad();
}
+// Use vkBindImageMemory2 instead of vkBindImageMemory
+TEST_P(GfxstreamEnd2EndVkSnapshotImageTest, ImageViewDependency2) {
+ 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::eSampled | vkhpp::ImageUsageFlagBits::eTransferDst |
+ vkhpp::ImageUsageFlagBits::eTransferSrc,
+ .sharingMode = vkhpp::SharingMode::eExclusive,
+ .samples = vkhpp::SampleCountFlagBits::e1,
+ };
+ auto image = device->createImageUnique(imageCreateInfo).value;
+ ASSERT_THAT(image, IsValidHandle());
+
+ vkhpp::MemoryRequirements imageMemoryRequirements{};
+ device->getImageMemoryRequirements(*image, &imageMemoryRequirements);
+
+ const uint32_t imageMemoryIndex = utils::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());
+
+ const vkhpp::BindImageMemoryInfo imageBindMemoryInfo = {
+ .pNext = nullptr,
+ .image = *image,
+ .memory = *imageMemory,
+ .memoryOffset = 0,
+ };
+
+ ASSERT_THAT(device->bindImageMemory2({imageBindMemoryInfo}), IsVkSuccess());
+
+ // b/331677615
+ // Create and delete a buffer handle right before creating image view.
+ // Gfxstream recycle handles. We trick the VkImageView handle to collide with
+ // a destroyed buffer handle and verify there is no bug snapshotting recycled
+ // handles.
+ const vkhpp::BufferCreateInfo bufferCreateInfo = {
+ .size = 1024,
+ .usage = vkhpp::BufferUsageFlagBits::eTransferSrc,
+ };
+ auto buffer = device->createBufferUnique(bufferCreateInfo).value;
+ ASSERT_THAT(buffer, IsValidHandle());
+ buffer.reset();
+
+ const vkhpp::ImageViewCreateInfo imageViewCreateInfo = {
+ .image = *image,
+ .viewType = vkhpp::ImageViewType::e2D,
+ .format = vkhpp::Format::eR8G8B8A8Unorm,
+ .subresourceRange =
+ {
+ .aspectMask = vkhpp::ImageAspectFlagBits::eColor,
+ .baseMipLevel = 0,
+ .levelCount = 1,
+ .baseArrayLayer = 0,
+ .layerCount = 1,
+ },
+ };
+ auto imageView = device->createImageViewUnique(imageViewCreateInfo).value;
+ ASSERT_THAT(imageView, IsValidHandle());
+ // Make sure it doesn't crash on load
+ SnapshotSaveAndLoad();
+}
+
TEST_P(GfxstreamEnd2EndVkSnapshotImageTest, MultiSampleImage) {
auto [instance, physicalDevice, device, queue, queueFamilyIndex] =
VK_ASSERT(SetUpTypicalVkTestEnvironment());
diff --git a/host/vulkan/VkDecoderGlobalState.cpp b/host/vulkan/VkDecoderGlobalState.cpp
index 9b0454b..014eda1 100644
--- a/host/vulkan/VkDecoderGlobalState.cpp
+++ b/host/vulkan/VkDecoderGlobalState.cpp
@@ -2347,6 +2347,17 @@
VkResult on_vkBindImageMemory2(android::base::BumpPool* pool, VkDevice boxed_device,
uint32_t bindInfoCount,
const VkBindImageMemoryInfo* pBindInfos) {
+#ifdef GFXSTREAM_ENABLE_HOST_VK_SNAPSHOT
+ if (bindInfoCount > 1 && snapshotsEnabled()) {
+ if (mVerbosePrints) {
+ fprintf(stderr,
+ "vkBindImageMemory2 with more than 1 bindInfoCount not supporting snapshot");
+ }
+ get_emugl_vm_operations().setSkipSnapshotSave(true);
+ get_emugl_vm_operations().setSkipSnapshotSaveReason(SNAPSHOT_SKIP_UNSUPPORTED_VK_API);
+ }
+#endif
+
auto device = unbox_VkDevice(boxed_device);
auto vk = dispatch_VkDevice(boxed_device);
bool needEmulation = false;
diff --git a/host/vulkan/VkDecoderSnapshot.cpp b/host/vulkan/VkDecoderSnapshot.cpp
index bc0ea04..370c9a9 100644
--- a/host/vulkan/VkDecoderSnapshot.cpp
+++ b/host/vulkan/VkDecoderSnapshot.cpp
@@ -1628,7 +1628,30 @@
uint32_t bindInfoCount, const VkBindBufferMemoryInfo* pBindInfos) {}
void vkBindImageMemory2(const uint8_t* snapshotTraceBegin, size_t snapshotTraceBytes,
android::base::BumpPool* pool, VkResult input_result, VkDevice device,
- uint32_t bindInfoCount, const VkBindImageMemoryInfo* pBindInfos) {}
+ uint32_t bindInfoCount, const VkBindImageMemoryInfo* pBindInfos) {
+ android::base::AutoLock lock(mLock);
+ for (uint32_t i = 0; i < bindInfoCount; ++i) {
+ VkImage boxed_VkImage = unboxed_to_boxed_non_dispatchable_VkImage(pBindInfos[i].image);
+ VkDeviceMemory boxed_VkDeviceMemory =
+ unboxed_to_boxed_non_dispatchable_VkDeviceMemory(pBindInfos[i].memory);
+ mReconstruction.addHandleDependency((const uint64_t*)&boxed_VkImage, 1,
+ (uint64_t)(uintptr_t)boxed_VkDeviceMemory,
+ VkReconstruction::BOUND_MEMORY);
+ mReconstruction.addHandleDependency((const uint64_t*)&boxed_VkImage, 1,
+ (uint64_t)(uintptr_t)boxed_VkImage,
+ VkReconstruction::BOUND_MEMORY);
+ }
+ auto apiHandle = mReconstruction.createApiInfo();
+ auto apiInfo = mReconstruction.getApiInfo(apiHandle);
+ mReconstruction.setApiTrace(apiInfo, OP_vkBindImageMemory2, snapshotTraceBegin,
+ snapshotTraceBytes);
+ // Note: the implementation does not work with bindInfoCount > 1
+ for (uint32_t i = 0; i < bindInfoCount; ++i) {
+ VkImage boxed_VkImage = unboxed_to_boxed_non_dispatchable_VkImage(pBindInfos[i].image);
+ mReconstruction.forEachHandleAddApi((const uint64_t*)&boxed_VkImage, 1, apiHandle,
+ VkReconstruction::BOUND_MEMORY);
+ }
+ }
void vkGetDeviceGroupPeerMemoryFeatures(const uint8_t* snapshotTraceBegin,
size_t snapshotTraceBytes,
android::base::BumpPool* pool, VkDevice device,
@@ -2711,7 +2734,30 @@
void vkBindImageMemory2KHR(const uint8_t* snapshotTraceBegin, size_t snapshotTraceBytes,
android::base::BumpPool* pool, VkResult input_result,
VkDevice device, uint32_t bindInfoCount,
- const VkBindImageMemoryInfo* pBindInfos) {}
+ const VkBindImageMemoryInfo* pBindInfos) {
+ android::base::AutoLock lock(mLock);
+ for (uint32_t i = 0; i < bindInfoCount; ++i) {
+ VkImage boxed_VkImage = unboxed_to_boxed_non_dispatchable_VkImage(pBindInfos[i].image);
+ VkDeviceMemory boxed_VkDeviceMemory =
+ unboxed_to_boxed_non_dispatchable_VkDeviceMemory(pBindInfos[i].memory);
+ mReconstruction.addHandleDependency((const uint64_t*)&boxed_VkImage, 1,
+ (uint64_t)(uintptr_t)boxed_VkDeviceMemory,
+ VkReconstruction::BOUND_MEMORY);
+ mReconstruction.addHandleDependency((const uint64_t*)&boxed_VkImage, 1,
+ (uint64_t)(uintptr_t)boxed_VkImage,
+ VkReconstruction::BOUND_MEMORY);
+ }
+ auto apiHandle = mReconstruction.createApiInfo();
+ auto apiInfo = mReconstruction.getApiInfo(apiHandle);
+ mReconstruction.setApiTrace(apiInfo, OP_vkBindImageMemory2KHR, snapshotTraceBegin,
+ snapshotTraceBytes);
+ // Note: the implementation does not work with bindInfoCount > 1
+ for (uint32_t i = 0; i < bindInfoCount; ++i) {
+ VkImage boxed_VkImage = unboxed_to_boxed_non_dispatchable_VkImage(pBindInfos[i].image);
+ mReconstruction.forEachHandleAddApi((const uint64_t*)&boxed_VkImage, 1, apiHandle,
+ VkReconstruction::BOUND_MEMORY);
+ }
+ }
#endif
#ifdef VK_KHR_maintenance3
void vkGetDescriptorSetLayoutSupportKHR(const uint8_t* snapshotTraceBegin,